summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_asm.c
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2011-11-14 16:53:54 +0100
committerMarek Olšák <[email protected]>2011-11-15 00:04:43 +0100
commit4f7c21899ad449be2bc1157ce1d2d99296a34499 (patch)
treef4ca829d2264317df2a48966b5e1eed6de8db743 /src/gallium/drivers/r600/r600_asm.c
parentfa704cc558ab321792b364dab43f1e960513bed0 (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/r600_asm.c')
-rw-r--r--src/gallium/drivers/r600/r600_asm.c577
1 files changed, 376 insertions, 201 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 72c11dc44eb..6b1ad65b60f 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -1160,7 +1160,7 @@ static int r600_bytecode_alloc_kcache_lines(struct r600_bytecode *bc, struct r60
if ((r = r600_bytecode_add_cf(bc))) {
return r;
}
- bc->cf_last->inst = (type << 3);
+ bc->cf_last->inst = type;
kcache = bc->cf_last->kcache;
}
@@ -1248,10 +1248,10 @@ int r600_bytecode_add_alu_type(struct r600_bytecode *bc, const struct r600_bytec
return -ENOMEM;
memcpy(nalu, alu, sizeof(struct r600_bytecode_alu));
- if (bc->cf_last != NULL && bc->cf_last->inst != (type << 3)) {
+ if (bc->cf_last != NULL && bc->cf_last->inst != type) {
/* check if we could add it anyway */
- if (bc->cf_last->inst == (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) &&
- type == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE) {
+ if (bc->cf_last->inst == BC_INST(bc, V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) &&
+ type == BC_INST(bc, V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE)) {
LIST_FOR_EACH_ENTRY(lalu, &bc->cf_last->alu, list) {
if (lalu->predicate) {
bc->force_add_cf = 1;
@@ -1270,7 +1270,7 @@ int r600_bytecode_add_alu_type(struct r600_bytecode *bc, const struct r600_bytec
return r;
}
}
- bc->cf_last->inst = (type << 3);
+ bc->cf_last->inst = type;
/* Check AR usage and load it if required */
for (i = 0; i < 3; i++)
@@ -1377,17 +1377,21 @@ static unsigned r600_bytecode_num_tex_and_vtx_instructions(const struct r600_byt
}
}
-static inline boolean last_inst_was_vtx_fetch(struct r600_bytecode *bc)
+static inline boolean last_inst_was_not_vtx_fetch(struct r600_bytecode *bc)
{
- if (bc->chip_class == CAYMAN) {
- if (bc->cf_last->inst != CM_V_SQ_CF_WORD1_SQ_CF_INST_TC)
- return TRUE;
- } else {
- if (bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX &&
- bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC)
- return TRUE;
+ switch (bc->chip_class) {
+ case R700:
+ case R600:
+ return bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX &&
+ bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC;
+ case EVERGREEN:
+ return bc->cf_last->inst != EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX;
+ case CAYMAN:
+ return bc->cf_last->inst != CM_V_SQ_CF_WORD1_SQ_CF_INST_TC;
+ default:
+ R600_ERR("Unknown chip class %d.\n", bc->chip_class);
+ return FALSE;
}
- return FALSE;
}
int r600_bytecode_add_vtx(struct r600_bytecode *bc, const struct r600_bytecode_vtx *vtx)
@@ -1401,17 +1405,28 @@ int r600_bytecode_add_vtx(struct r600_bytecode *bc, const struct r600_bytecode_v
/* cf can contains only alu or only vtx or only tex */
if (bc->cf_last == NULL ||
- last_inst_was_vtx_fetch(bc) ||
+ last_inst_was_not_vtx_fetch(bc) ||
bc->force_add_cf) {
r = r600_bytecode_add_cf(bc);
if (r) {
free(nvtx);
return r;
}
- if (bc->chip_class == CAYMAN)
- bc->cf_last->inst = CM_V_SQ_CF_WORD1_SQ_CF_INST_TC;
- else
+ switch (bc->chip_class) {
+ case R600:
+ case R700:
bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_VTX;
+ break;
+ case EVERGREEN:
+ bc->cf_last->inst = EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX;
+ break;
+ case CAYMAN:
+ bc->cf_last->inst = CM_V_SQ_CF_WORD1_SQ_CF_INST_TC;
+ break;
+ default:
+ R600_ERR("Unknown chip class %d.\n", bc->chip_class);
+ return -EINVAL;
+ }
}
LIST_ADDTAIL(&nvtx->list, &bc->cf_last->vtx);
/* each fetch use 4 dwords */
@@ -1433,7 +1448,7 @@ int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_t
/* we can't fetch data und use it as texture lookup address in the same TEX clause */
if (bc->cf_last != NULL &&
- bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_TEX) {
+ bc->cf_last->inst == BC_INST(bc, V_SQ_CF_WORD1_SQ_CF_INST_TEX)) {
struct r600_bytecode_tex *ttex;
LIST_FOR_EACH_ENTRY(ttex, &bc->cf_last->tex, list) {
if (ttex->dst_gpr == ntex->src_gpr) {
@@ -1448,14 +1463,14 @@ int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_t
/* cf can contains only alu or only vtx or only tex */
if (bc->cf_last == NULL ||
- bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_TEX ||
+ bc->cf_last->inst != BC_INST(bc, V_SQ_CF_WORD1_SQ_CF_INST_TEX) ||
bc->force_add_cf) {
r = r600_bytecode_add_cf(bc);
if (r) {
free(ntex);
return r;
}
- bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_TEX;
+ bc->cf_last->inst = BC_INST(bc, V_SQ_CF_WORD1_SQ_CF_INST_TEX);
}
if (ntex->src_gpr >= bc->ngpr) {
bc->ngpr = ntex->src_gpr + 1;
@@ -1593,7 +1608,7 @@ static int r600_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecod
static void r600_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_cf *cf)
{
*bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
- *bytecode++ = S_SQ_CF_WORD1_CF_INST(cf->inst) |
+ *bytecode++ = cf->inst |
S_SQ_CF_WORD1_BARRIER(1) |
S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
}
@@ -1604,16 +1619,16 @@ static int r600_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode
unsigned id = cf->id;
switch (cf->inst) {
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER:
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) |
@@ -1641,7 +1656,7 @@ static int r600_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode
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 |
S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
break;
case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
@@ -1654,7 +1669,7 @@ static int r600_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode
case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
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);
@@ -1688,38 +1703,64 @@ int r600_bytecode_build(struct r600_bytecode *bc)
/* addr start after all the CF instructions */
addr = bc->cf_last->id + 2;
LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
- switch (cf->inst) {
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
- break;
- case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
- case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
- case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
- /* fetch node need to be 16 bytes aligned*/
- addr += 3;
- addr &= 0xFFFFFFFCUL;
- break;
- case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
- case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
- case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
- case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
- break;
- case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
- case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
- case V_SQ_CF_WORD1_SQ_CF_INST_POP:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
- case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
- case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
- case CM_V_SQ_CF_WORD1_SQ_CF_INST_END:
- break;
- default:
- R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
- return -EINVAL;
+ if (bc->chip_class >= EVERGREEN) {
+ switch (cf->inst) {
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ /* fetch node need to be 16 bytes aligned*/
+ addr += 3;
+ addr &= 0xFFFFFFFCUL;
+ break;
+ 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:
+ case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_POP:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+ case CM_V_SQ_CF_WORD1_SQ_CF_INST_END:
+ break;
+ default:
+ R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+ return -EINVAL;
+ }
+ } else {
+ switch (cf->inst) {
+ case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+ /* fetch node need to be 16 bytes aligned*/
+ addr += 3;
+ addr &= 0xFFFFFFFCUL;
+ break;
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE:
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
+ case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
+ case V_SQ_CF_WORD1_SQ_CF_INST_POP:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
+ case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
+ case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+ break;
+ default:
+ R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+ return -EINVAL;
+ }
}
cf->addr = addr;
addr += cf->ndw;
@@ -1731,92 +1772,158 @@ int r600_bytecode_build(struct r600_bytecode *bc)
return -ENOMEM;
LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
addr = cf->addr;
- if (bc->chip_class >= EVERGREEN)
+ if (bc->chip_class >= EVERGREEN) {
r = eg_bytecode_cf_build(bc, cf);
- else
- r = r600_bytecode_cf_build(bc, cf);
- if (r)
- return r;
- switch (cf->inst) {
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
- nliteral = 0;
- memset(literal, 0, sizeof(literal));
- LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) {
- r = r600_bytecode_alu_nliterals(bc, alu, literal, &nliteral);
- if (r)
- return r;
- r600_bytecode_alu_adjust_literals(bc, alu, literal, nliteral);
- switch(bc->chip_class) {
- case R600:
- r = r600_bytecode_alu_build(bc, alu, addr);
- break;
- case R700:
- case EVERGREEN: /* eg alu is same encoding as r700 */
- case CAYMAN: /* eg alu is same encoding as r700 */
- r = r700_bytecode_alu_build(bc, alu, addr);
- break;
- default:
- R600_ERR("unknown chip class %d.\n", bc->chip_class);
- return -EINVAL;
+ if (r)
+ return r;
+
+ switch (cf->inst) {
+ 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:
+ nliteral = 0;
+ memset(literal, 0, sizeof(literal));
+ LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) {
+ r = r600_bytecode_alu_nliterals(bc, alu, literal, &nliteral);
+ if (r)
+ return r;
+ r600_bytecode_alu_adjust_literals(bc, alu, literal, nliteral);
+ switch(bc->chip_class) {
+ case EVERGREEN: /* eg alu is same encoding as r700 */
+ case CAYMAN:
+ r = r700_bytecode_alu_build(bc, alu, addr);
+ break;
+ default:
+ R600_ERR("unknown chip class %d.\n", bc->chip_class);
+ return -EINVAL;
+ }
+ if (r)
+ return r;
+ addr += 2;
+ if (alu->last) {
+ for (i = 0; i < align(nliteral, 2); ++i) {
+ bc->bytecode[addr++] = literal[i];
+ }
+ nliteral = 0;
+ memset(literal, 0, sizeof(literal));
+ }
}
- if (r)
- return r;
- addr += 2;
- if (alu->last) {
- for (i = 0; i < align(nliteral, 2); ++i) {
- bc->bytecode[addr++] = literal[i];
+ break;
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
+ r = r600_bytecode_vtx_build(bc, vtx, addr);
+ if (r)
+ return r;
+ addr += 4;
+ }
+ break;
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+ if (bc->chip_class == CAYMAN) {
+ LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
+ r = r600_bytecode_vtx_build(bc, vtx, addr);
+ if (r)
+ return r;
+ addr += 4;
}
- nliteral = 0;
- memset(literal, 0, sizeof(literal));
}
+ LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) {
+ r = r600_bytecode_tex_build(bc, tex, addr);
+ if (r)
+ return r;
+ addr += 4;
+ }
+ break;
+ case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_POP:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+ case CM_V_SQ_CF_WORD1_SQ_CF_INST_END:
+ break;
+ default:
+ R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+ return -EINVAL;
}
- break;
- case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
- case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
- LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
- r = r600_bytecode_vtx_build(bc, vtx, addr);
- if (r)
- return r;
- addr += 4;
- }
- break;
- case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
- if (bc->chip_class == CAYMAN) {
+ } else {
+ r = r600_bytecode_cf_build(bc, cf);
+ if (r)
+ return r;
+
+ switch (cf->inst) {
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE:
+ nliteral = 0;
+ memset(literal, 0, sizeof(literal));
+ LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) {
+ r = r600_bytecode_alu_nliterals(bc, alu, literal, &nliteral);
+ if (r)
+ return r;
+ r600_bytecode_alu_adjust_literals(bc, alu, literal, nliteral);
+ switch(bc->chip_class) {
+ case R600:
+ r = r600_bytecode_alu_build(bc, alu, addr);
+ break;
+ case R700:
+ r = r700_bytecode_alu_build(bc, alu, addr);
+ break;
+ default:
+ R600_ERR("unknown chip class %d.\n", bc->chip_class);
+ return -EINVAL;
+ }
+ if (r)
+ return r;
+ addr += 2;
+ if (alu->last) {
+ for (i = 0; i < align(nliteral, 2); ++i) {
+ bc->bytecode[addr++] = literal[i];
+ }
+ nliteral = 0;
+ memset(literal, 0, sizeof(literal));
+ }
+ }
+ break;
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
r = r600_bytecode_vtx_build(bc, vtx, addr);
if (r)
return r;
addr += 4;
}
+ break;
+ case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+ LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) {
+ r = r600_bytecode_tex_build(bc, tex, addr);
+ if (r)
+ return r;
+ addr += 4;
+ }
+ break;
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
+ case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
+ case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
+ case V_SQ_CF_WORD1_SQ_CF_INST_POP:
+ case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
+ case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+ break;
+ default:
+ R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+ return -EINVAL;
}
- LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) {
- r = r600_bytecode_tex_build(bc, tex, addr);
- if (r)
- return r;
- addr += 4;
- }
- break;
- case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
- case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
- case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
- case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
- case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
- case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
- case V_SQ_CF_WORD1_SQ_CF_INST_POP:
- case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
- case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
- case CM_V_SQ_CF_WORD1_SQ_CF_INST_END:
- break;
- default:
- R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
- return -EINVAL;
}
}
return 0;
@@ -1891,72 +1998,140 @@ void r600_bytecode_dump(struct r600_bytecode *bc)
LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
id = cf->id;
- switch (cf->inst) {
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
- case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
- fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]);
- fprintf(stderr, "ADDR:%d ", cf->addr);
- fprintf(stderr, "KCACHE_MODE0:%X ", cf->kcache[0].mode);
- fprintf(stderr, "KCACHE_BANK0:%X ", cf->kcache[0].bank);
- fprintf(stderr, "KCACHE_BANK1:%X\n", cf->kcache[1].bank);
- id++;
- fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]);
- fprintf(stderr, "INST:0x%x ", cf->inst);
- fprintf(stderr, "KCACHE_MODE1:%X ", cf->kcache[1].mode);
- fprintf(stderr, "KCACHE_ADDR0:%X ", cf->kcache[0].addr);
- fprintf(stderr, "KCACHE_ADDR1:%X ", cf->kcache[1].addr);
- fprintf(stderr, "COUNT:%d\n", cf->ndw / 2);
- break;
- case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
- case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
- case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
- fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]);
- fprintf(stderr, "ADDR:%d\n", cf->addr);
- id++;
- fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]);
- fprintf(stderr, "INST:0x%x ", cf->inst);
- fprintf(stderr, "COUNT:%d\n", cf->ndw / 4);
- break;
- case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
- case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
- case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
- case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
- fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]);
- fprintf(stderr, "GPR:%X ", cf->output.gpr);
- fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size);
- fprintf(stderr, "ARRAY_BASE:%X ", cf->output.array_base);
- fprintf(stderr, "TYPE:%X\n", cf->output.type);
- id++;
- fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]);
- fprintf(stderr, "SWIZ_X:%X ", cf->output.swizzle_x);
- fprintf(stderr, "SWIZ_Y:%X ", cf->output.swizzle_y);
- fprintf(stderr, "SWIZ_Z:%X ", cf->output.swizzle_z);
- fprintf(stderr, "SWIZ_W:%X ", cf->output.swizzle_w);
- fprintf(stderr, "BARRIER:%X ", cf->output.barrier);
- fprintf(stderr, "INST:0x%x ", cf->output.inst);
- fprintf(stderr, "BURST_COUNT:%d ", cf->output.burst_count);
- fprintf(stderr, "EOP:%X\n", cf->output.end_of_program);
- break;
- case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
- case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
- case V_SQ_CF_WORD1_SQ_CF_INST_POP:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
- case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
- case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
- case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
- case CM_V_SQ_CF_WORD1_SQ_CF_INST_END:
- fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]);
- fprintf(stderr, "ADDR:%d\n", cf->cf_addr);
- id++;
- fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]);
- fprintf(stderr, "INST:0x%x ", cf->inst);
- fprintf(stderr, "COND:%X ", cf->cond);
- fprintf(stderr, "POP_COUNT:%X\n", cf->pop_count);
- break;
+ if (bc->chip_class >= EVERGREEN) {
+ switch (cf->inst) {
+ 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:
+ fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]);
+ fprintf(stderr, "ADDR:%d ", cf->addr);
+ fprintf(stderr, "KCACHE_MODE0:%X ", cf->kcache[0].mode);
+ fprintf(stderr, "KCACHE_BANK0:%X ", cf->kcache[0].bank);
+ fprintf(stderr, "KCACHE_BANK1:%X\n", cf->kcache[1].bank);
+ id++;
+ fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]);
+ fprintf(stderr, "INST:0x%x ", EG_G_SQ_CF_ALU_WORD1_CF_INST(cf->inst));
+ fprintf(stderr, "KCACHE_MODE1:%X ", cf->kcache[1].mode);
+ fprintf(stderr, "KCACHE_ADDR0:%X ", cf->kcache[0].addr);
+ fprintf(stderr, "KCACHE_ADDR1:%X ", cf->kcache[1].addr);
+ fprintf(stderr, "COUNT:%d\n", cf->ndw / 2);
+ break;
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]);
+ fprintf(stderr, "ADDR:%d\n", cf->addr);
+ id++;
+ fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]);
+ fprintf(stderr, "INST:0x%x ", EG_G_SQ_CF_WORD1_CF_INST(cf->inst));
+ fprintf(stderr, "COUNT:%d\n", cf->ndw / 4);
+ break;
+ case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]);
+ fprintf(stderr, "GPR:%X ", cf->output.gpr);
+ fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size);
+ fprintf(stderr, "ARRAY_BASE:%X ", cf->output.array_base);
+ fprintf(stderr, "TYPE:%X\n", cf->output.type);
+ id++;
+ fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]);
+ fprintf(stderr, "SWIZ_X:%X ", cf->output.swizzle_x);
+ fprintf(stderr, "SWIZ_Y:%X ", cf->output.swizzle_y);
+ fprintf(stderr, "SWIZ_Z:%X ", cf->output.swizzle_z);
+ fprintf(stderr, "SWIZ_W:%X ", cf->output.swizzle_w);
+ fprintf(stderr, "BARRIER:%X ", cf->output.barrier);
+ fprintf(stderr, "INST:0x%x ", EG_G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst));
+ fprintf(stderr, "BURST_COUNT:%d ", cf->output.burst_count);
+ fprintf(stderr, "EOP:%X\n", cf->output.end_of_program);
+ break;
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_POP:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
+ case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+ case CM_V_SQ_CF_WORD1_SQ_CF_INST_END:
+ fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]);
+ fprintf(stderr, "ADDR:%d\n", cf->cf_addr);
+ id++;
+ fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]);
+ fprintf(stderr, "INST:0x%x ", EG_G_SQ_CF_WORD1_CF_INST(cf->inst));
+ fprintf(stderr, "COND:%X ", cf->cond);
+ fprintf(stderr, "POP_COUNT:%X\n", cf->pop_count);
+ break;
+ default:
+ R600_ERR("Unknown instruction %0x\n", cf->inst);
+ }
+ } else {
+ switch (cf->inst) {
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER:
+ case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE:
+ fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]);
+ fprintf(stderr, "ADDR:%d ", cf->addr);
+ fprintf(stderr, "KCACHE_MODE0:%X ", cf->kcache[0].mode);
+ fprintf(stderr, "KCACHE_BANK0:%X ", cf->kcache[0].bank);
+ fprintf(stderr, "KCACHE_BANK1:%X\n", cf->kcache[1].bank);
+ id++;
+ fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]);
+ fprintf(stderr, "INST:0x%x ", R600_G_SQ_CF_ALU_WORD1_CF_INST(cf->inst));
+ fprintf(stderr, "KCACHE_MODE1:%X ", cf->kcache[1].mode);
+ fprintf(stderr, "KCACHE_ADDR0:%X ", cf->kcache[0].addr);
+ fprintf(stderr, "KCACHE_ADDR1:%X ", cf->kcache[1].addr);
+ fprintf(stderr, "COUNT:%d\n", cf->ndw / 2);
+ break;
+ case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+ case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+ fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]);
+ fprintf(stderr, "ADDR:%d\n", cf->addr);
+ id++;
+ fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]);
+ fprintf(stderr, "INST:0x%x ", R600_G_SQ_CF_WORD1_CF_INST(cf->inst));
+ fprintf(stderr, "COUNT:%d\n", cf->ndw / 4);
+ break;
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]);
+ fprintf(stderr, "GPR:%X ", cf->output.gpr);
+ fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size);
+ fprintf(stderr, "ARRAY_BASE:%X ", cf->output.array_base);
+ fprintf(stderr, "TYPE:%X\n", cf->output.type);
+ id++;
+ fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]);
+ fprintf(stderr, "SWIZ_X:%X ", cf->output.swizzle_x);
+ fprintf(stderr, "SWIZ_Y:%X ", cf->output.swizzle_y);
+ fprintf(stderr, "SWIZ_Z:%X ", cf->output.swizzle_z);
+ fprintf(stderr, "SWIZ_W:%X ", cf->output.swizzle_w);
+ fprintf(stderr, "BARRIER:%X ", cf->output.barrier);
+ fprintf(stderr, "INST:0x%x ", R600_G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst));
+ fprintf(stderr, "BURST_COUNT:%d ", cf->output.burst_count);
+ fprintf(stderr, "EOP:%X\n", cf->output.end_of_program);
+ break;
+ case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
+ case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
+ case V_SQ_CF_WORD1_SQ_CF_INST_POP:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
+ case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
+ case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
+ case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+ fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]);
+ fprintf(stderr, "ADDR:%d\n", cf->cf_addr);
+ id++;
+ fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]);
+ fprintf(stderr, "INST:0x%x ", R600_G_SQ_CF_WORD1_CF_INST(cf->inst));
+ fprintf(stderr, "COND:%X ", cf->cond);
+ fprintf(stderr, "POP_COUNT:%X\n", cf->pop_count);
+ break;
+ default:
+ R600_ERR("Unknown instruction %0x\n", cf->inst);
+ }
}
id = cf->addr;