summaryrefslogtreecommitdiff
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.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 0ed177c66b..4664105263 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -146,6 +146,13 @@ int r600_bc_init(struct r600_bc *bc, enum radeon_family family)
case CHIP_RV740:
bc->chiprev = 1;
break;
+ case CHIP_CEDAR:
+ case CHIP_REDWOOD:
+ case CHIP_JUNIPER:
+ case CHIP_CYPRESS:
+ case CHIP_HEMLOCK:
+ bc->chiprev = 2;
+ break;
default:
R600_ERR("unknown family %d\n", bc->family);
return -EINVAL;
@@ -345,6 +352,10 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu)
{
unsigned swizzle_key;
+ if (alu->bank_swizzle_force) {
+ alu->bank_swizzle = alu->bank_swizzle_force;
+ return;
+ }
swizzle_key = (is_const(alu->src[0].sel) ? 4 : 0 ) +
(is_const(alu->src[1].sel) ? 2 : 0 ) +
(is_const(alu->src[2].sel) ? 1 : 0 );
@@ -357,6 +368,10 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu)
{
unsigned swizzle_key;
+ if (alu->bank_swizzle_force) {
+ alu->bank_swizzle = alu->bank_swizzle_force;
+ return;
+ }
swizzle_key = (is_const(alu->src[0].sel) ? 4 : 0 ) +
(is_const(alu->src[1].sel) ? 2 : 0 ) +
(is_const(alu->src[2].sel) ? 1 : 0 );
@@ -462,7 +477,7 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int
int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu)
{
- return r600_bc_add_alu_type(bc, alu, V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU);
+ return r600_bc_add_alu_type(bc, alu, BC_INST(bc, V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU));
}
int r600_bc_add_literal(struct r600_bc *bc, const u32 *value)
@@ -475,6 +490,7 @@ int r600_bc_add_literal(struct r600_bc *bc, const u32 *value)
if (bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_TEX) {
return 0;
}
+ /* all same on EG */
if (bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_JUMP ||
bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_ELSE ||
bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL ||
@@ -484,6 +500,7 @@ int r600_bc_add_literal(struct r600_bc *bc, const u32 *value)
bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_POP) {
return 0;
}
+ /* same on EG */
if (((bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3)) &&
(bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3))) ||
LIST_IS_EMPTY(&bc->cf_last->alu)) {
@@ -566,6 +583,7 @@ int r600_bc_add_cfinst(struct r600_bc *bc, int inst)
return 0;
}
+/* common to all 3 families */
static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id)
{
bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) |
@@ -583,6 +601,7 @@ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsign
return 0;
}
+/* common to all 3 families */
static int r600_bc_tex_build(struct r600_bc *bc, struct r600_bc_tex *tex, unsigned id)
{
bc->bytecode[id++] = S_SQ_TEX_WORD0_TEX_INST(tex->inst) |
@@ -612,6 +631,7 @@ static int r600_bc_tex_build(struct r600_bc *bc, struct r600_bc_tex *tex, unsign
return 0;
}
+/* r600 only, r700/eg bits in r700_asm.c */
static int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id)
{
unsigned i;
@@ -662,6 +682,7 @@ static int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsign
return 0;
}
+/* common for r600/r700 - eg in eg_asm.c */
static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
{
unsigned id = cf->id;
@@ -748,6 +769,8 @@ int r600_bc_build(struct r600_bc *bc)
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:
@@ -771,7 +794,10 @@ int r600_bc_build(struct r600_bc *bc)
return -ENOMEM;
LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
addr = cf->addr;
- r = r600_bc_cf_build(bc, cf);
+ if (bc->chiprev == 2)
+ r = eg_bc_cf_build(bc, cf);
+ else
+ r = r600_bc_cf_build(bc, cf);
if (r)
return r;
switch (cf->inst) {
@@ -783,6 +809,7 @@ int r600_bc_build(struct r600_bc *bc)
r = r600_bc_alu_build(bc, alu, addr);
break;
case 1:
+ case 2: /* eg alu is same encoding as r700 */
r = r700_bc_alu_build(bc, alu, addr);
break;
default:
@@ -816,6 +843,8 @@ int r600_bc_build(struct r600_bc *bc)
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: