diff options
Diffstat (limited to 'src/gallium/drivers/r600/r600_asm.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_asm.c | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 066fb67aba4..5ef611993ff 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -475,6 +475,23 @@ static int is_alu_mova_inst(struct r600_bytecode *bc, struct r600_bytecode_alu * } } +static int alu_uses_rel(struct r600_bytecode *bc, struct r600_bytecode_alu *alu) +{ + unsigned num_src = r600_bytecode_get_num_operands(bc, alu); + unsigned src; + + if (alu->dst.rel) { + return 1; + } + + for (src = 0; src < num_src; ++src) { + if (alu->src[src].rel) { + return 1; + } + } + return 0; +} + static int is_opcode_in_range(unsigned opcode, unsigned min, unsigned max) { return min <= opcode && opcode <= max; @@ -1047,20 +1064,24 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu if (r) return r; +// fprintf(stderr, "*** Begin List ***\n"); for (i = 0; i < max_slots; ++i) { if (prev[i]) { +// fprintf(stderr, "prev[%i] = %x\n", i, prev[i]->inst); if (prev[i]->pred_sel) return 0; if (is_alu_once_inst(bc, prev[i])) return 0; } if (slots[i]) { +// fprintf(stderr, "slots[%i] = %x\n", i, slots[i]->inst); if (slots[i]->pred_sel) return 0; if (is_alu_once_inst(bc, slots[i])) return 0; } } +// fprintf(stderr, "*** End List ***\n"); for (i = 0; i < max_slots; ++i) { struct r600_bytecode_alu *alu; @@ -1075,10 +1096,22 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu if (r600_bytecode_alu_nliterals(bc, prev[i], prev_literal, &prev_nliteral)) return 0; if (is_alu_mova_inst(bc, prev[i])) { - if (have_rel) +// fprintf(stderr, "Prev[%u] is mova\n", i); + if (have_rel) { +// fprintf(stderr, "slots contins a rel, so cannot merge\n"); return 0; + } have_mova = 1; } + + if (alu_uses_rel(bc, prev[i])) { +// fprintf(stderr, "Prev[%u] has rel\n", i); + if (have_mova) { + return 0; + } + have_rel = 1; + } + num_once_inst += is_alu_once_inst(bc, prev[i]); } if (slots[i] && r600_bytecode_alu_nliterals(bc, slots[i], literal, &nliteral)) @@ -1126,21 +1159,25 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu if (is_nop_inst(bc, alu)) return 0; - /* Let's check dst gpr. */ - if (alu->dst.rel) { - if (have_mova) + if (is_alu_mova_inst(bc, alu)) { +// fprintf(stderr, "Slots[%u] is mova\n", i); + if (have_rel) { return 0; + } + have_mova = 1; + } + + if (alu_uses_rel(bc, alu)) { +// fprintf(stderr, "Slots[%u] has rel\n", i); + if (have_mova) { + return 0; + } have_rel = 1; } /* Let's check source gprs */ num_src = r600_bytecode_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 don't matter. */ if (!is_gpr(alu->src[src].sel)) @@ -1169,6 +1206,7 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu return 0; /* looks like everything worked out right, apply the changes */ +// fprintf(stderr, "Can merge\n"); /* undo adding previus literals */ bc->cf_last->ndw -= align(prev_nliteral, 2); |