summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
authorMichal Sciubidlo <[email protected]>2012-09-12 08:57:01 +0200
committerTom Stellard <[email protected]>2012-09-19 13:17:41 -0400
commit0e0c21e00ee80bcff67e37ec86b97d6c25db066a (patch)
treeb274df6453672bc6a6a6bbb836398a553d17a775 /src/gallium/drivers/r600
parentd525ed1a84fb889ddf380d967b3097fce298f8d4 (diff)
radeon/llvm: Emit ISA for ALU instructions in the R600 code emitter
Signed-off-by: Tom Stellard <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/r600_asm.c43
-rw-r--r--src/gallium/drivers/r600/r600_asm.h2
-rw-r--r--src/gallium/drivers/r600/r600_llvm.c1
-rw-r--r--src/gallium/drivers/r600/r600_shader.c60
-rw-r--r--src/gallium/drivers/r600/r700_asm.c43
5 files changed, 121 insertions, 28 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 03ded6c5877..648e8b6ed5d 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -2874,3 +2874,46 @@ int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r6
return 0;
}
+
+void r600_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1)
+{
+ /* WORD0 */
+ alu->src[0].sel = G_SQ_ALU_WORD0_SRC0_SEL(word0);
+ alu->src[0].rel = G_SQ_ALU_WORD0_SRC0_REL(word0);
+ alu->src[0].chan = G_SQ_ALU_WORD0_SRC0_CHAN(word0);
+ alu->src[0].neg = G_SQ_ALU_WORD0_SRC0_NEG(word0);
+ alu->src[1].sel = G_SQ_ALU_WORD0_SRC1_SEL(word0);
+ alu->src[1].rel = G_SQ_ALU_WORD0_SRC1_REL(word0);
+ alu->src[1].chan = G_SQ_ALU_WORD0_SRC1_CHAN(word0);
+ alu->src[1].neg = G_SQ_ALU_WORD0_SRC1_NEG(word0);
+ alu->index_mode = G_SQ_ALU_WORD0_INDEX_MODE(word0);
+ alu->pred_sel = G_SQ_ALU_WORD0_PRED_SEL(word0);
+ alu->last = G_SQ_ALU_WORD0_LAST(word0);
+
+ /* WORD1 */
+ alu->bank_swizzle = G_SQ_ALU_WORD1_BANK_SWIZZLE(word1);
+ alu->dst.sel = G_SQ_ALU_WORD1_DST_GPR(word1);
+ alu->dst.rel = G_SQ_ALU_WORD1_DST_REL(word1);
+ alu->dst.chan = G_SQ_ALU_WORD1_DST_CHAN(word1);
+ alu->dst.clamp = G_SQ_ALU_WORD1_CLAMP(word1);
+ if (G_SQ_ALU_WORD1_ENCODING(word1)) /*ALU_DWORD1_OP3*/
+ {
+ alu->is_op3 = 1;
+ alu->src[2].sel = G_SQ_ALU_WORD1_OP3_SRC2_SEL(word1);
+ alu->src[2].rel = G_SQ_ALU_WORD1_OP3_SRC2_REL(word1);
+ alu->src[2].chan = G_SQ_ALU_WORD1_OP3_SRC2_CHAN(word1);
+ alu->src[2].neg = G_SQ_ALU_WORD1_OP3_SRC2_NEG(word1);
+ alu->inst = G_SQ_ALU_WORD1_OP3_ALU_INST(word1);
+ }
+ else /*ALU_DWORD1_OP2*/
+ {
+ alu->src[0].abs = G_SQ_ALU_WORD1_OP2_SRC0_ABS(word1);
+ alu->src[1].abs = G_SQ_ALU_WORD1_OP2_SRC1_ABS(word1);
+ alu->inst = G_SQ_ALU_WORD1_OP2_ALU_INST(word1);
+ alu->omod = G_SQ_ALU_WORD1_OP2_OMOD(word1);
+ alu->dst.write = G_SQ_ALU_WORD1_OP2_WRITE_MASK(word1);
+ alu->update_pred = G_SQ_ALU_WORD1_OP2_UPDATE_PRED(word1);
+ alu->execute_mask =
+ G_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(word1);
+ }
+}
diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h
index 87e751adc78..403365ba07b 100644
--- a/src/gallium/drivers/r600/r600_asm.h
+++ b/src/gallium/drivers/r600/r600_asm.h
@@ -233,6 +233,7 @@ int r600_bytecode_add_cfinst(struct r600_bytecode *bc, int inst);
int r600_bytecode_add_alu_type(struct r600_bytecode *bc, const struct r600_bytecode_alu *alu, int type);
void r600_bytecode_special_constants(uint32_t value, unsigned *sel, unsigned *neg);
void r600_bytecode_dump(struct r600_bytecode *bc);
+void r600_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
int cm_bytecode_add_cf_end(struct r600_bytecode *bc);
@@ -241,5 +242,6 @@ int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r6
/* r700_asm.c */
void r700_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_cf *cf);
int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *alu, unsigned id);
+void r700_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
#endif
diff --git a/src/gallium/drivers/r600/r600_llvm.c b/src/gallium/drivers/r600/r600_llvm.c
index e77758b3a77..776f47b6bff 100644
--- a/src/gallium/drivers/r600/r600_llvm.c
+++ b/src/gallium/drivers/r600/r600_llvm.c
@@ -259,6 +259,7 @@ const char * r600_llvm_gpu_string(enum radeon_family family)
case CHIP_RV630:
case CHIP_RV620:
case CHIP_RV635:
+ gpu_family = "r600";
case CHIP_RS780:
case CHIP_RS880:
case CHIP_RV710:
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 736165b8083..3e746e5e2e2 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -293,32 +293,37 @@ static unsigned r600_alu_from_byte_stream(struct r600_shader_ctx *ctx,
unsigned char * bytes, unsigned bytes_read)
{
unsigned src_idx;
- unsigned inst0, inst1;
- unsigned push_modifier;
struct r600_bytecode_alu alu;
+ unsigned src_const_reg[3];
+ uint32_t word0, word1;
+
memset(&alu, 0, sizeof(alu));
for(src_idx = 0; src_idx < 3; src_idx++) {
- bytes_read = r600_src_from_byte_stream(bytes, bytes_read,
- &alu, src_idx);
- }
-
- alu.dst.sel = bytes[bytes_read++];
- alu.dst.chan = bytes[bytes_read++];
- alu.dst.clamp = bytes[bytes_read++];
- alu.dst.write = bytes[bytes_read++];
- alu.dst.rel = bytes[bytes_read++];
- inst0 = bytes[bytes_read++];
- inst1 = bytes[bytes_read++];
- alu.inst = inst0 | (inst1 << 8);
- alu.last = bytes[bytes_read++];
- alu.is_op3 = bytes[bytes_read++];
- push_modifier = bytes[bytes_read++];
- alu.pred_sel = bytes[bytes_read++];
- alu.bank_swizzle = bytes[bytes_read++];
- alu.bank_swizzle_force = bytes[bytes_read++];
- alu.omod = bytes[bytes_read++];
- alu.index_mode = bytes[bytes_read++];
+ unsigned i;
+ src_const_reg[src_idx] = bytes[bytes_read++];
+ for (i = 0; i < 4; i++) {
+ alu.src[src_idx].value |= bytes[bytes_read++] << (i * 8);
+ }
+ }
+ word0 = i32_from_byte_stream(bytes, &bytes_read);
+ word1 = i32_from_byte_stream(bytes, &bytes_read);
+
+ switch(ctx->bc->chip_class) {
+ case R600:
+ r600_bytecode_alu_read(&alu, word0, word1);
+ break;
+ case R700:
+ case EVERGREEN:
+ case CAYMAN:
+ r700_bytecode_alu_read(&alu, word0, word1);
+ break;
+ }
+
+ for(src_idx = 0; src_idx < 3; src_idx++) {
+ if (src_const_reg[src_idx])
+ alu.src[src_idx].sel += 512;
+ }
if (alu.inst == CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE) ||
alu.inst == CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE) ||
@@ -329,15 +334,14 @@ static unsigned r600_alu_from_byte_stream(struct r600_shader_ctx *ctx,
alu.src[1].sel = V_SQ_ALU_SRC_0;
alu.src[1].chan = 0;
alu.last = 1;
- }
+ }
- if (push_modifier) {
- alu.pred_sel = 0;
- alu.execute_mask = 1;
+ if (alu.execute_mask) {
+ alu.pred_sel = 0;
r600_bytecode_add_alu_type(ctx->bc, &alu, CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE));
- } else
+ } else {
r600_bytecode_add_alu(ctx->bc, &alu);
-
+ }
/* XXX: Handle other KILL instructions */
if (alu.inst == CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT)) {
diff --git a/src/gallium/drivers/r600/r700_asm.c b/src/gallium/drivers/r600/r700_asm.c
index ea37c63525f..818933a4dbd 100644
--- a/src/gallium/drivers/r600/r700_asm.c
+++ b/src/gallium/drivers/r600/r700_asm.c
@@ -74,3 +74,46 @@ int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *
}
return 0;
}
+
+void r700_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1)
+{
+ /* WORD0 */
+ alu->src[0].sel = G_SQ_ALU_WORD0_SRC0_SEL(word0);
+ alu->src[0].rel = G_SQ_ALU_WORD0_SRC0_REL(word0);
+ alu->src[0].chan = G_SQ_ALU_WORD0_SRC0_CHAN(word0);
+ alu->src[0].neg = G_SQ_ALU_WORD0_SRC0_NEG(word0);
+ alu->src[1].sel = G_SQ_ALU_WORD0_SRC1_SEL(word0);
+ alu->src[1].rel = G_SQ_ALU_WORD0_SRC1_REL(word0);
+ alu->src[1].chan = G_SQ_ALU_WORD0_SRC1_CHAN(word0);
+ alu->src[1].neg = G_SQ_ALU_WORD0_SRC1_NEG(word0);
+ alu->index_mode = G_SQ_ALU_WORD0_INDEX_MODE(word0);
+ alu->pred_sel = G_SQ_ALU_WORD0_PRED_SEL(word0);
+ alu->last = G_SQ_ALU_WORD0_LAST(word0);
+
+ /* WORD1 */
+ alu->bank_swizzle = G_SQ_ALU_WORD1_BANK_SWIZZLE(word1);
+ alu->dst.sel = G_SQ_ALU_WORD1_DST_GPR(word1);
+ alu->dst.rel = G_SQ_ALU_WORD1_DST_REL(word1);
+ alu->dst.chan = G_SQ_ALU_WORD1_DST_CHAN(word1);
+ alu->dst.clamp = G_SQ_ALU_WORD1_CLAMP(word1);
+ if (G_SQ_ALU_WORD1_ENCODING(word1)) /*ALU_DWORD1_OP3*/
+ {
+ alu->is_op3 = 1;
+ alu->src[2].sel = G_SQ_ALU_WORD1_OP3_SRC2_SEL(word1);
+ alu->src[2].rel = G_SQ_ALU_WORD1_OP3_SRC2_REL(word1);
+ alu->src[2].chan = G_SQ_ALU_WORD1_OP3_SRC2_CHAN(word1);
+ alu->src[2].neg = G_SQ_ALU_WORD1_OP3_SRC2_NEG(word1);
+ alu->inst = G_SQ_ALU_WORD1_OP3_ALU_INST(word1);
+ }
+ else /*ALU_DWORD1_OP2*/
+ {
+ alu->src[0].abs = G_SQ_ALU_WORD1_OP2_SRC0_ABS(word1);
+ alu->src[1].abs = G_SQ_ALU_WORD1_OP2_SRC1_ABS(word1);
+ alu->inst = G_SQ_ALU_WORD1_OP2_ALU_INST(word1);
+ alu->omod = G_SQ_ALU_WORD1_OP2_OMOD(word1);
+ alu->dst.write = G_SQ_ALU_WORD1_OP2_WRITE_MASK(word1);
+ alu->update_pred = G_SQ_ALU_WORD1_OP2_UPDATE_PRED(word1);
+ alu->execute_mask =
+ G_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(word1);
+ }
+}