summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc.h2
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc_builder.cpp31
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc_decoder.cpp55
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc_dump.cpp26
4 files changed, 105 insertions, 9 deletions
diff --git a/src/gallium/drivers/r600/sb/sb_bc.h b/src/gallium/drivers/r600/sb/sb_bc.h
index b0b12ce11c7..b23d4820b19 100644
--- a/src/gallium/drivers/r600/sb/sb_bc.h
+++ b/src/gallium/drivers/r600/sb/sb_bc.h
@@ -518,6 +518,8 @@ struct bc_alu {
unsigned slot:3;
+ unsigned lds_idx_offset:6;
+
alu_op_flags slot_flags;
void set_op(unsigned op) {
diff --git a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp
index 55e2a8508ec..5dec169bac9 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp
@@ -371,6 +371,37 @@ int bc_builder::build_alu(alu_node* n) {
const bc_alu &bc = n->bc;
const alu_op_info *aop = bc.op_ptr;
+ if (n->bc.op_ptr->flags & AF_LDS) {
+ assert(ctx.is_egcm());
+ bb << ALU_WORD0_LDS_IDX_OP_EGCM()
+ .SRC0_SEL(bc.src[0].sel)
+ .SRC0_REL(bc.src[0].rel)
+ .SRC0_CHAN(bc.src[0].chan)
+ .IDX_OFFSET_4((bc.lds_idx_offset >> 4) & 1)
+ .SRC1_SEL(bc.src[1].sel)
+ .SRC1_REL(bc.src[1].rel)
+ .SRC1_CHAN(bc.src[1].chan)
+ .IDX_OFFSET_5((bc.lds_idx_offset >> 5) & 1)
+ .INDEX_MODE(bc.index_mode)
+ .PRED_SEL(bc.pred_sel)
+ .LAST(bc.last);
+
+ bb << ALU_WORD1_LDS_IDX_OP_EGCM()
+ .SRC2_SEL(bc.src[2].sel)
+ .SRC2_REL(bc.src[2].rel)
+ .SRC2_CHAN(bc.src[2].chan)
+ .IDX_OFFSET_1((bc.lds_idx_offset >> 1) & 1)
+ .ALU_INST(ctx.alu_opcode(ALU_OP3_LDS_IDX_OP))
+ .BANK_SWIZZLE(bc.bank_swizzle)
+ .LDS_OP((bc.op_ptr->opcode[1] >> 8) & 0xff)
+ .IDX_OFFSET_0((bc.lds_idx_offset >> 0) & 1)
+ .IDX_OFFSET_2((bc.lds_idx_offset >> 2) & 1)
+ .DST_CHAN(bc.dst_chan)
+ .IDX_OFFSET_3((bc.lds_idx_offset >> 3) & 1);
+
+ return 0;
+ }
+
bb << ALU_WORD0_ALL()
.INDEX_MODE(bc.index_mode)
.LAST(bc.last)
diff --git a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
index 48cbb33153f..1832e2d3e6a 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
@@ -310,16 +310,53 @@ int bc_decoder::decode_alu(unsigned & i, bc_alu& bc) {
ALU_WORD1_OP3_ALL w1(dw1);
bc.set_op(r600_isa_alu_by_opcode(ctx.isa, w1.get_ALU_INST(), 1));
- bc.bank_swizzle = w1.get_BANK_SWIZZLE();
- bc.clamp = w1.get_CLAMP();
- bc.dst_chan = w1.get_DST_CHAN();
- bc.dst_gpr = w1.get_DST_GPR();
- bc.dst_rel = w1.get_DST_REL();
+ if (bc.op == ALU_OP3_LDS_IDX_OP) {
+ ALU_WORD0_LDS_IDX_OP_EGCM iw0(dw0);
+ ALU_WORD1_LDS_IDX_OP_EGCM iw1(dw1);
+ bc.index_mode = iw0.get_INDEX_MODE();
+ bc.last = iw0.get_LAST();
+ bc.pred_sel = iw0.get_PRED_SEL();
+ bc.src[0].chan = iw0.get_SRC0_CHAN();
+ bc.src[0].sel = iw0.get_SRC0_SEL();
+ bc.src[0].rel = iw0.get_SRC0_REL();
+
+ bc.src[1].chan = iw0.get_SRC1_CHAN();
+ bc.src[1].sel = iw0.get_SRC1_SEL();
+ bc.src[1].rel = iw0.get_SRC1_REL();
+
+ bc.bank_swizzle = iw1.get_BANK_SWIZZLE();
+ bc.src[2].chan = iw1.get_SRC2_CHAN();
+ bc.src[2].sel = iw1.get_SRC2_SEL();
+ bc.src[2].rel = iw1.get_SRC2_REL();
+ bc.dst_chan = iw1.get_DST_CHAN();
+ // TODO: clean up
+ for (size_t k = 0; k < sizeof(alu_op_table) / sizeof(alu_op_table[0]); k++) {
+ if (((alu_op_table[k].opcode[1] >> 8) & 0xff) == iw1.get_LDS_OP()) {
+ bc.op_ptr = &alu_op_table[k];
+ bc.op = k;
+ break;
+ }
+ }
+ bc.lds_idx_offset =
+ (iw0.get_IDX_OFFSET_4() << 4) |
+ (iw0.get_IDX_OFFSET_5() << 5) |
+ (iw1.get_IDX_OFFSET_1() << 1) |
+ (iw1.get_IDX_OFFSET_0() << 0) |
+ (iw1.get_IDX_OFFSET_2() << 2) |
+ (iw1.get_IDX_OFFSET_3() << 3);
+ }
+ else {
+ bc.bank_swizzle = w1.get_BANK_SWIZZLE();
+ bc.clamp = w1.get_CLAMP();
+ bc.dst_chan = w1.get_DST_CHAN();
+ bc.dst_gpr = w1.get_DST_GPR();
+ bc.dst_rel = w1.get_DST_REL();
- bc.src[2].chan = w1.get_SRC2_CHAN();
- bc.src[2].sel = w1.get_SRC2_SEL();
- bc.src[2].neg = w1.get_SRC2_NEG();
- bc.src[2].rel = w1.get_SRC2_REL();
+ bc.src[2].chan = w1.get_SRC2_CHAN();
+ bc.src[2].sel = w1.get_SRC2_SEL();
+ bc.src[2].neg = w1.get_SRC2_NEG();
+ bc.src[2].rel = w1.get_SRC2_REL();
+ }
} else { // op2
if (ctx.is_r600()) {
diff --git a/src/gallium/drivers/r600/sb/sb_bc_dump.cpp b/src/gallium/drivers/r600/sb/sb_bc_dump.cpp
index 3c051adf309..788450b3c9c 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_dump.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_dump.cpp
@@ -280,6 +280,28 @@ static void print_src(sb_ostream &s, bc_alu &alu, unsigned idx)
need_sel = 0;
need_chan = 0;
switch (sel) {
+ case ALU_SRC_LDS_OQ_A:
+ s << "LDS_OQ_A";
+ need_chan = 1;
+ break;
+ case ALU_SRC_LDS_OQ_B:
+ s << "LDS_OQ_B";
+ need_chan = 1;
+ break;
+ case ALU_SRC_LDS_OQ_A_POP:
+ s << "LDS_OQ_A_POP";
+ need_chan = 1;
+ break;
+ case ALU_SRC_LDS_OQ_B_POP:
+ s << "LDS_OQ_B_POP";
+ need_chan = 1;
+ break;
+ case ALU_SRC_LDS_DIRECT_A:
+ s << "LDS_A["; s.print_zw_hex(src->value.u, 8); s << "]";
+ break;
+ case ALU_SRC_LDS_DIRECT_B:
+ s << "LDS_B["; s.print_zw_hex(src->value.u, 8); s << "]";
+ break;
case ALU_SRC_PS:
s << "PS";
break;
@@ -363,6 +385,10 @@ void bc_dump::dump(alu_node& n) {
}
}
+ if (n.bc.lds_idx_offset) {
+ s << " IDX_OFFSET:" << n.bc.lds_idx_offset;
+ }
+
sblog << s.str() << "\n";
}