summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600/r600_asm.c')
-rw-r--r--src/gallium/drivers/r600/r600_asm.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 61de24b31ae..54e339fbefe 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -602,26 +602,24 @@ static int reserve_gpr(struct alu_bank_swizzle *bs, unsigned sel, unsigned chan,
return 0;
}
-static int reserve_cfile(struct alu_bank_swizzle *bs, unsigned sel, unsigned chan)
+static int reserve_cfile(struct r600_bc *bc, struct alu_bank_swizzle *bs, unsigned sel, unsigned chan)
{
- int res, resmatch = -1, resempty = -1;
- for (res = 3; res >= 0; --res) {
- if (bs->hw_cfile_addr[res] == -1)
- resempty = res;
- else if (bs->hw_cfile_addr[res] == sel &&
- bs->hw_cfile_elem[res] == chan)
- resmatch = res;
+ int res, num_res = 4;
+ if (bc->chiprev >= CHIPREV_R700) {
+ num_res = 2;
+ chan /= 2;
}
- if (resmatch != -1)
- return 0; // Read for this scalar element already reserved, nothing to do here.
- else if (resempty != -1) {
- bs->hw_cfile_addr[resempty] = sel;
- bs->hw_cfile_elem[resempty] = chan;
- } else {
- // All cfile read ports are used, cannot reference vector element
- return -1;
+ for (res = 0; res < num_res; ++res) {
+ if (bs->hw_cfile_addr[res] == -1) {
+ bs->hw_cfile_addr[res] = sel;
+ bs->hw_cfile_elem[res] = chan;
+ return 0;
+ } else if (bs->hw_cfile_addr[res] == sel &&
+ bs->hw_cfile_elem[res] == chan)
+ return 0; // Read for this scalar element already reserved, nothing to do here.
}
- return 0;
+ // All cfile read ports are used, cannot reference vector element
+ return -1;
}
static int is_gpr(unsigned sel)
@@ -667,7 +665,7 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu,
return r;
}
} else if (is_cfile(sel)) {
- r = reserve_cfile(bs, sel, elem);
+ r = reserve_cfile(bc, bs, sel, elem);
if (r)
return r;
}
@@ -694,7 +692,7 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu,
const_count++;
}
if (is_cfile(sel)) {
- r = reserve_cfile(bs, sel, elem);
+ r = reserve_cfile(bc, bs, sel, elem);
if (r)
return r;
}
@@ -915,6 +913,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5],
int i, j, r, src, num_src;
int num_once_inst = 0;
+ int have_mova = 0, have_rel = 0;
r = assign_alu_units(bc, alu_prev, prev);
if (r)
@@ -929,6 +928,12 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5],
return 0;
if (r600_bc_alu_nliterals(bc, prev[i], prev_literal, &prev_nliteral))
return 0;
+ if (is_alu_mova_inst(bc, prev[i])) {
+ if (have_rel)
+ return 0;
+ have_mova = 1;
+ }
+ num_once_inst += is_alu_once_inst(bc, prev[i]);
}
if (slots[i] && r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral))
return 0;
@@ -936,7 +941,6 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5],
// let's check used slots
if (prev[i] && !slots[i]) {
result[i] = prev[i];
- num_once_inst += is_alu_once_inst(bc, prev[i]);
continue;
} else if (prev[i] && slots[i]) {
if (result[4] == NULL && prev[4] == NULL && slots[4] == NULL) {
@@ -962,6 +966,12 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5],
num_src = r600_bc_get_num_operands(bc, alu);
for (src = 0; src < num_src; ++src) {
+ if (alu->src[src].rel) {
+ if (have_mova)
+ return 0;
+ have_rel = 1;
+ }
+
// constants doesn't matter
if (!is_gpr(alu->src[src].sel))
continue;