diff options
author | Tom Stellard <[email protected]> | 2012-06-29 16:41:32 +0000 |
---|---|---|
committer | Tom Stellard <[email protected]> | 2012-06-29 18:46:18 +0000 |
commit | 2c485cda2062ca2b9af89ea62618515d960c7904 (patch) | |
tree | d5a8cb0c0542ec395e50bc46819c725ff4523cad /src/gallium/drivers/radeon | |
parent | 16e0ebccb61b65a58db4b3bb1a25a953515eab90 (diff) |
radeon/llvm: Emit raw ISA for vertex fetch instructions
Diffstat (limited to 'src/gallium/drivers/radeon')
-rw-r--r-- | src/gallium/drivers/radeon/R600CodeEmitter.cpp | 58 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/R600Instructions.td | 102 |
2 files changed, 99 insertions, 61 deletions
diff --git a/src/gallium/drivers/radeon/R600CodeEmitter.cpp b/src/gallium/drivers/radeon/R600CodeEmitter.cpp index 3042f38af8a..99964d4beb1 100644 --- a/src/gallium/drivers/radeon/R600CodeEmitter.cpp +++ b/src/gallium/drivers/radeon/R600CodeEmitter.cpp @@ -206,60 +206,12 @@ bool R600CodeEmitter::runOnMachineFunction(MachineFunction &MF) { case AMDIL::VTX_READ_PARAM_eg: case AMDIL::VTX_READ_GLOBAL_eg: { - emitByte(INSTR_VTX); - // inst - emitByte(0); - - // fetch_type - emitByte(2); - - // buffer_id - emitByte(MI.getOpcode() == AMDIL::VTX_READ_PARAM_eg ? 0 : 1); - - // src_gpr - emitByte(getHWReg(MI.getOperand(1).getReg())); - - // src_sel_x - emitByte(TRI->getHWRegChan(MI.getOperand(1).getReg())); - - // mega_fetch_count - emitByte(3); - - // dst_gpr - emitByte(getHWReg(MI.getOperand(0).getReg())); - - // dst_sel_x - emitByte(0); - - // dst_sel_y - emitByte(7); + uint64_t InstWord01 = getBinaryCodeForInstr(MI); + uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset - // dst_sel_z - emitByte(7); - - // dst_sel_w - emitByte(7); - - // use_const_fields - emitByte(1); - - // data_format - emitByte(0); - - // num_format_all - emitByte(0); - - // format_comp_all - emitByte(0); - - // srf_mode_all - emitByte(0); - - // offset - emitTwoBytes(MI.getOperand(2).getImm()); - - // endian - emitByte(0); + emitByte(INSTR_VTX); + emit(InstWord01); + emit(InstWord2); break; } diff --git a/src/gallium/drivers/radeon/R600Instructions.td b/src/gallium/drivers/radeon/R600Instructions.td index 6c74c6cd7bd..d42e74cfae2 100644 --- a/src/gallium/drivers/radeon/R600Instructions.td +++ b/src/gallium/drivers/radeon/R600Instructions.td @@ -922,18 +922,104 @@ def RAT_WRITE_CACHELESS_eg : EG_CF_RAT <0x57, 0x2, 0, (outs), } // End usesCustomInserter = 1 -class VTX_READ_eg <int buffer_id, list<dag> pattern> : InstR600ISA < - (outs R600_TReg32_X:$dst), - (ins MEMxi:$ptr), - "VTX_READ_eg $dst, $ptr", - pattern ->; +class VTX_READ_eg <bits<8> buffer_id, dag outs, list<dag> pattern> + : InstR600ISA <outs, (ins MEMxi:$ptr), "VTX_READ_eg $dst, $ptr", pattern> { + + // Operands + bits<7> DST_GPR; + bits<7> SRC_GPR; + + // Static fields + bits<5> VC_INST = 0; + bits<2> FETCH_TYPE = 2; + bits<1> FETCH_WHOLE_QUAD = 0; + bits<8> BUFFER_ID = buffer_id; + bits<1> SRC_REL = 0; + // XXX: We can infer this field based on the SRC_GPR. This would allow us + // to store vertex addresses in any channel, not just X. + bits<2> SRC_SEL_X = 0; + bits<6> MEGA_FETCH_COUNT; + bits<1> DST_REL = 0; + bits<3> DST_SEL_X; + bits<3> DST_SEL_Y; + bits<3> DST_SEL_Z; + bits<3> DST_SEL_W; + // The docs say that if this bit is set, then DATA_FORMAT, NUM_FORMAT_ALL, + // FORMAT_COMP_ALL, SRF_MODE_ALL, and ENDIAN_SWAP fields will be ignored, + // however, based on my testing if USE_CONST_FIELDS is set, then all + // these fields need to be set to 0. + bits<1> USE_CONST_FIELDS = 0; + bits<6> DATA_FORMAT; + bits<2> NUM_FORMAT_ALL = 1; + bits<1> FORMAT_COMP_ALL = 0; + bits<1> SRF_MODE_ALL = 0; + + // LLVM can only encode 64-bit instructions, so these fields are manually + // encoded in R600CodeEmitter + // + // bits<16> OFFSET; + // bits<2> ENDIAN_SWAP = 0; + // bits<1> CONST_BUF_NO_STRIDE = 0; + // bits<1> MEGA_FETCH = 0; + // bits<1> ALT_CONST = 0; + // bits<2> BUFFER_INDEX_MODE = 0; + + // VTX_WORD0 + let Inst{4-0} = VC_INST; + let Inst{6-5} = FETCH_TYPE; + let Inst{7} = FETCH_WHOLE_QUAD; + let Inst{15-8} = BUFFER_ID; + let Inst{22-16} = SRC_GPR; + let Inst{23} = SRC_REL; + let Inst{25-24} = SRC_SEL_X; + let Inst{31-26} = MEGA_FETCH_COUNT; + + // VTX_WORD1_GPR + let Inst{38-32} = DST_GPR; + let Inst{39} = DST_REL; + let Inst{40} = 0; // Reserved + let Inst{43-41} = DST_SEL_X; + let Inst{46-44} = DST_SEL_Y; + let Inst{49-47} = DST_SEL_Z; + let Inst{52-50} = DST_SEL_W; + let Inst{53} = USE_CONST_FIELDS; + let Inst{59-54} = DATA_FORMAT; + let Inst{61-60} = NUM_FORMAT_ALL; + let Inst{62} = FORMAT_COMP_ALL; + let Inst{63} = SRF_MODE_ALL; + + // VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding + // is done in R600CodeEmitter + // + // Inst{79-64} = OFFSET; + // Inst{81-80} = ENDIAN_SWAP; + // Inst{82} = CONST_BUF_NO_STRIDE; + // Inst{83} = MEGA_FETCH; + // Inst{84} = ALT_CONST; + // Inst{86-85} = BUFFER_INDEX_MODE; + // Inst{95-86} = 0; Reserved + + // VTX_WORD3 (Padding) + // + // Inst{127-96} = 0; +} + +class VTX_READ_32_eg <bits<8> buffer_id, list<dag> pattern> + : VTX_READ_eg <buffer_id, (outs R600_TReg32_X:$dst), pattern> { + + let MEGA_FETCH_COUNT = 4; + let DST_SEL_X = 0; + let DST_SEL_Y = 7; // Masked + let DST_SEL_Z = 7; // Masked + let DST_SEL_W = 7; // Masked + let DATA_FORMAT = 0xD; // COLOR_32 +} -def VTX_READ_PARAM_eg : VTX_READ_eg <0, +def VTX_READ_PARAM_eg : VTX_READ_32_eg <0, [(set (i32 R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))] >; -def VTX_READ_GLOBAL_eg : VTX_READ_eg <1, +def VTX_READ_GLOBAL_eg : VTX_READ_32_eg <1, [(set (i32 R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))] >; |