diff options
author | Marek Olšák <[email protected]> | 2011-11-14 16:53:54 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2011-11-15 00:04:43 +0100 |
commit | 4f7c21899ad449be2bc1157ce1d2d99296a34499 (patch) | |
tree | f4ca829d2264317df2a48966b5e1eed6de8db743 /src/gallium/drivers/r600/eg_asm.c | |
parent | fa704cc558ab321792b364dab43f1e960513bed0 (diff) |
r600g: fix the representation of control-flow instructions
We need something that looks like a compiler and not like some hacker
put some functions together. /rant
This is a band-aid for these two problems:
- The R600 and EG control-flow instructions appear in switch statements
next to each other, causing conflicts when adding new instructions.
- The ALU control-flow instructions are bitshifted by 3 (from CF_INST 26:29
to CF_INST 23:29, as is defined by r600 ISA) even for EG, where CF_INST
is 22:29.
To fix this mess, the 'inst' field is bitshifted to the left either by 22, 23,
or 26 (directly in the definitions), such that it can be just or'd when making
bytecode without any shifting. All switch statements have been divided into
two, one for R600 and the other for EG.
Of course, there is a better way to do this, but that is left for future
work.
Tested on RV730 and REDWOOD with no regressions.
v2: minor cleanup as per Alex's comment.
Reviewed-by: Alex Deucher <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/eg_asm.c')
-rw-r--r-- | src/gallium/drivers/r600/eg_asm.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c index ca25b341ffd..f6b8631124f 100644 --- a/src/gallium/drivers/r600/eg_asm.c +++ b/src/gallium/drivers/r600/eg_asm.c @@ -34,15 +34,15 @@ int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf) unsigned id = cf->id; switch (cf->inst) { - case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): - case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3): - case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3): - case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE: bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) | S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) | S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache[0].bank) | S_SQ_CF_ALU_WORD0_KCACHE_BANK1(cf->kcache[1].bank); - bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(cf->inst >> 3) | + bc->bytecode[id++] = cf->inst | S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache[1].mode) | S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache[0].addr) | S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache[1].addr) | @@ -52,7 +52,7 @@ int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf) case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX: case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX: bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1); - bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) | + bc->bytecode[id++] = cf->inst | S_SQ_CF_WORD1_BARRIER(1) | S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1); break; @@ -68,11 +68,10 @@ int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf) S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) | S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) | S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) | - S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst); + cf->output.inst; if (bc->chip_class == EVERGREEN) /* no EOP on cayman */ bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program); id++; - break; case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP: case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE: @@ -85,11 +84,10 @@ int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf) case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN: case CM_V_SQ_CF_WORD1_SQ_CF_INST_END: bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1); - bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) | + bc->bytecode[id++] = cf->inst | S_SQ_CF_WORD1_BARRIER(1) | S_SQ_CF_WORD1_COND(cf->cond) | S_SQ_CF_WORD1_POP_COUNT(cf->pop_count); - break; default: R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); |