diff options
author | Michal Sciubidlo <[email protected]> | 2012-09-12 08:57:01 +0200 |
---|---|---|
committer | Tom Stellard <[email protected]> | 2012-09-19 13:17:41 -0400 |
commit | 0e0c21e00ee80bcff67e37ec86b97d6c25db066a (patch) | |
tree | b274df6453672bc6a6a6bbb836398a553d17a775 /src/gallium/drivers/r600 | |
parent | d525ed1a84fb889ddf380d967b3097fce298f8d4 (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.c | 43 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_asm.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_llvm.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 60 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r700_asm.c | 43 |
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); + } +} |