From fc207d8f57d3bd27aa0dc2dd40ecd344229477d3 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 7 Feb 2013 19:39:40 +0000 Subject: [PATCH] R600/SI: simplify and fix SMRD encoding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The _SGPR variants where wrong. Patch by: Christian König Signed-off-by: Christian König Reviewed-by: Tom Stellard git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174653 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/AMDGPUCodeEmitter.h | 4 - lib/Target/R600/AMDILISelDAGToDAG.cpp | 53 ----------- .../R600/MCTargetDesc/AMDGPUMCCodeEmitter.h | 4 - .../R600/MCTargetDesc/SIMCCodeEmitter.cpp | 34 ------- lib/Target/R600/SIInstrInfo.td | 90 +++++++------------ lib/Target/R600/SIInstructions.td | 39 +++++++- 6 files changed, 70 insertions(+), 154 deletions(-) diff --git a/lib/Target/R600/AMDGPUCodeEmitter.h b/lib/Target/R600/AMDGPUCodeEmitter.h index 84f35884966..5d61cd0de62 100644 --- a/lib/Target/R600/AMDGPUCodeEmitter.h +++ b/lib/Target/R600/AMDGPUCodeEmitter.h @@ -38,10 +38,6 @@ public: unsigned OpNo) const { return 0; } - virtual uint32_t SMRDmemriEncode(const MachineInstr &MI, unsigned OpNo) - const { - return 0; - } }; } // End namespace llvm diff --git a/lib/Target/R600/AMDILISelDAGToDAG.cpp b/lib/Target/R600/AMDILISelDAGToDAG.cpp index 26994090643..a88e8c7fc64 100644 --- a/lib/Target/R600/AMDILISelDAGToDAG.cpp +++ b/lib/Target/R600/AMDILISelDAGToDAG.cpp @@ -72,8 +72,6 @@ private: bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue& IntPtr); bool SelectGlobalValueVariableOffset(SDValue Addr, SDValue &BaseReg, SDValue& Offset); - bool SelectADDR8BitOffset(SDValue Addr, SDValue& Base, SDValue& Offset); - bool SelectADDRReg(SDValue Addr, SDValue& Base, SDValue& Offset); bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset); bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset); @@ -527,43 +525,6 @@ bool AMDGPUDAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr, return false; } -bool AMDGPUDAGToDAGISel::SelectADDR8BitOffset(SDValue Addr, SDValue& Base, - SDValue& Offset) { - if (Addr.getOpcode() == ISD::TargetExternalSymbol || - Addr.getOpcode() == ISD::TargetGlobalAddress) { - return false; - } - - - if (Addr.getOpcode() == ISD::ADD) { - bool Match = false; - - // Find the base ptr and the offset - for (unsigned i = 0; i < Addr.getNumOperands(); i++) { - SDValue Arg = Addr.getOperand(i); - ConstantSDNode * OffsetNode = dyn_cast(Arg); - // This arg isn't a constant so it must be the base PTR. - if (!OffsetNode) { - Base = Addr.getOperand(i); - continue; - } - // Check if the constant argument fits in 8-bits. The offset is in bytes - // so we need to convert it to dwords. - if (isUInt<8>(OffsetNode->getZExtValue() >> 2)) { - Match = true; - Offset = CurDAG->getTargetConstant(OffsetNode->getZExtValue() >> 2, - MVT::i32); - } - } - return Match; - } - - // Default case, no offset - Base = Addr; - Offset = CurDAG->getTargetConstant(0, MVT::i32); - return true; -} - bool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset) { ConstantSDNode * IMMOffset; @@ -591,20 +552,6 @@ bool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, return true; } -bool AMDGPUDAGToDAGISel::SelectADDRReg(SDValue Addr, SDValue& Base, - SDValue& Offset) { - if (Addr.getOpcode() == ISD::TargetExternalSymbol || - Addr.getOpcode() == ISD::TargetGlobalAddress || - Addr.getOpcode() != ISD::ADD) { - return false; - } - - Base = Addr.getOperand(0); - Offset = Addr.getOperand(1); - - return true; -} - bool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset) { ConstantSDNode *C; diff --git a/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h b/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h index 9d0d6cf6fd9..3b3816a5107 100644 --- a/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h +++ b/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h @@ -49,10 +49,6 @@ public: SmallVectorImpl &Fixups) const { return 0; } - virtual uint32_t SMRDmemriEncode(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups) const { - return 0; - } }; } // End namespace llvm diff --git a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp index b4bdb252895..8acc78fdbc5 100644 --- a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp +++ b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp @@ -92,10 +92,6 @@ public: virtual unsigned GPR4AlignEncode(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixup) const; - /// \brief Encoding for SMRD indexed loads - virtual uint32_t SMRDmemriEncode(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixup) const; - /// \brief Post-Encoder method for VOP instructions virtual uint64_t VOPPostEncode(const MCInst &MI, uint64_t Value) const; @@ -183,36 +179,6 @@ unsigned SIMCCodeEmitter::GPR4AlignEncode(const MCInst &MI, return GPRAlign(MI, OpNo, 2); } -#define SMRD_OFFSET_MASK 0xff -#define SMRD_IMM_SHIFT 8 -#define SMRD_SBASE_MASK 0x3f -#define SMRD_SBASE_SHIFT 9 -/// This function is responsibe for encoding the offset -/// and the base ptr for SMRD instructions it should return a bit string in -/// this format: -/// -/// OFFSET = bits{7-0} -/// IMM = bits{8} -/// SBASE = bits{14-9} -/// -uint32_t SIMCCodeEmitter::SMRDmemriEncode(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixup) const { - uint32_t Encoding; - - const MCOperand &OffsetOp = MI.getOperand(OpNo + 1); - - //XXX: Use this function for SMRD loads with register offsets - assert(OffsetOp.isImm()); - - Encoding = - (getMachineOpValue(MI, OffsetOp, Fixup) & SMRD_OFFSET_MASK) - | (1 << SMRD_IMM_SHIFT) //XXX If the Offset is a register we shouldn't set this bit - | ((GPR2AlignEncode(MI, OpNo, Fixup) & SMRD_SBASE_MASK) << SMRD_SBASE_SHIFT) - ; - - return Encoding; -} - //===----------------------------------------------------------------------===// // Post Encoder Callbacks //===----------------------------------------------------------------------===// diff --git a/lib/Target/R600/SIInstrInfo.td b/lib/Target/R600/SIInstrInfo.td index 83ee2cffb4a..13cf9f70e1c 100644 --- a/lib/Target/R600/SIInstrInfo.td +++ b/lib/Target/R600/SIInstrInfo.td @@ -38,6 +38,11 @@ def SIvcc_bitcast : SDNode<"SIISD::VCC_BITCAST", SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]> >; +// SMRD takes a 64bit memory address and can only add an 32bit offset +def SIadd64bit32bit : SDNode<"ISD::ADD", + SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVT<0, i64>, SDTCisVT<2, i32>]> +>; + // Transformation function, extract the lower 32bit of a 64bit immediate def LO32 : SDNodeXFormgetTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32); @@ -48,6 +53,20 @@ def HI32 : SDNodeXFormgetTargetConstant(N->getZExtValue() >> 32, MVT::i32); }]>; +def IMM8bitDWORD : ImmLeaf < + i32, [{ + return (Imm & ~0x3FC) == 0; + }], SDNodeXFormgetTargetConstant( + N->getZExtValue() >> 2, MVT::i32); + }]> +>; + +def IMM12bit : ImmLeaf < + i16, + [{return isUInt<12>(Imm);}] +>; + class InstSI pattern> : AMDGPUInst { @@ -79,49 +98,16 @@ class SIOperand : Operand { let MIOperandInfo = opInfo; } -def IMM16bit : ImmLeaf < - i16, - [{return isInt<16>(Imm);}] ->; - -def IMM8bit : ImmLeaf < - i32, - [{return (int32_t)Imm >= 0 && (int32_t)Imm <= 0xff;}] ->; - -def IMM12bit : ImmLeaf < - i16, - [{return (int16_t)Imm >= 0 && (int16_t)Imm <= 0xfff;}] ->; - -def IMM32bitIn64bit : ImmLeaf < - i64, - [{return isInt<32>(Imm);}] ->; - class GPR4Align : Operand { let EncoderMethod = "GPR4AlignEncode"; let MIOperandInfo = (ops rc:$reg); } -class GPR2Align : Operand { +class GPR2Align : Operand { let EncoderMethod = "GPR2AlignEncode"; let MIOperandInfo = (ops rc:$reg); } -def SMRDmemrr : Operand { - let MIOperandInfo = (ops SReg_64, SReg_32); - let EncoderMethod = "GPR2AlignEncode"; -} - -def SMRDmemri : Operand { - let MIOperandInfo = (ops SReg_64, i32imm); - let EncoderMethod = "SMRDmemriEncode"; -} - -def ADDR_Reg : ComplexPattern; -def ADDR_Offset8 : ComplexPattern; - let Uses = [EXEC] in { def EXP : Enc64< @@ -272,17 +258,15 @@ class MUBUF op, dag outs, dag ins, string asm, list pattern> : } // End Uses = [EXEC] -class SMRD op, dag outs, dag ins, string asm, list pattern> : - Enc32 { +class SMRD op, bits<1> imm, dag outs, dag ins, string asm, + list pattern> : Enc32 { bits<7> SDST; - bits<15> PTR; - bits<8> OFFSET = PTR{7-0}; - bits<1> IMM = PTR{8}; - bits<6> SBASE = PTR{14-9}; + bits<6> SBASE; + bits<8> OFFSET; let Inst{7-0} = OFFSET; - let Inst{8} = IMM; + let Inst{8} = imm; let Inst{14-9} = SBASE; let Inst{21-15} = SDST; let Inst{26-22} = op; @@ -573,29 +557,23 @@ class MTBUF_Store_Helper op, string asm, RegisterClass regClass> : MTBU let mayLoad = 0; } -multiclass SMRD_Helper op, string asm, RegisterClass dstClass, - ValueType vt> { +multiclass SMRD_Helper op, string asm, RegisterClass dstClass> { def _IMM : SMRD < - op, - (outs dstClass:$dst), - (ins SMRDmemri:$src0), - asm, - [(set (vt dstClass:$dst), (constant_load ADDR_Offset8:$src0))] + op, 1, + (outs dstClass:$dst), + (ins GPR2Align:$sbase, i32imm:$offset), + asm, + [] >; def _SGPR : SMRD < - op, + op, 0, (outs dstClass:$dst), - (ins SMRDmemrr:$src0), + (ins GPR2Align:$sbase, SReg_32:$soff), asm, - [(set (vt dstClass:$dst), (constant_load ADDR_Reg:$src0))] + [] >; } -multiclass SMRD_32 op, string asm, RegisterClass dstClass> { - defm _F32 : SMRD_Helper ; - defm _I32 : SMRD_Helper ; -} - include "SIInstrFormats.td" include "SIInstructions.td" diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td index 7d35561e9b8..fc98e4fd975 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -461,11 +461,13 @@ def TBUFFER_LOAD_FORMAT_XYZW : MTBUF_Load_Helper <0x00000003, "TBUFFER_LOAD_FORM //def TBUFFER_STORE_FORMAT_XYZ : MTBUF_ <0x00000006, "TBUFFER_STORE_FORMAT_XYZ", []>; //def TBUFFER_STORE_FORMAT_XYZW : MTBUF_ <0x00000007, "TBUFFER_STORE_FORMAT_XYZW", []>; -defm S_LOAD_DWORD : SMRD_32 <0x00000000, "S_LOAD_DWORD", SReg_32>; +let mayLoad = 1 in { + +defm S_LOAD_DWORD : SMRD_Helper <0x00000000, "S_LOAD_DWORD", SReg_32>; //def S_LOAD_DWORDX2 : SMRD_DWORDX2 <0x00000001, "S_LOAD_DWORDX2", []>; -defm S_LOAD_DWORDX4 : SMRD_Helper <0x00000002, "S_LOAD_DWORDX4", SReg_128, v4i32>; -defm S_LOAD_DWORDX8 : SMRD_Helper <0x00000003, "S_LOAD_DWORDX8", SReg_256, v8i32>; +defm S_LOAD_DWORDX4 : SMRD_Helper <0x00000002, "S_LOAD_DWORDX4", SReg_128>; +defm S_LOAD_DWORDX8 : SMRD_Helper <0x00000003, "S_LOAD_DWORDX8", SReg_256>; //def S_LOAD_DWORDX16 : SMRD_DWORDX16 <0x00000004, "S_LOAD_DWORDX16", []>; //def S_BUFFER_LOAD_DWORD : SMRD_ <0x00000008, "S_BUFFER_LOAD_DWORD", []>; //def S_BUFFER_LOAD_DWORDX2 : SMRD_DWORDX2 <0x00000009, "S_BUFFER_LOAD_DWORDX2", []>; @@ -473,6 +475,8 @@ defm S_LOAD_DWORDX8 : SMRD_Helper <0x00000003, "S_LOAD_DWORDX8", SReg_256, v8i32 //def S_BUFFER_LOAD_DWORDX8 : SMRD_DWORDX8 <0x0000000b, "S_BUFFER_LOAD_DWORDX8", []>; //def S_BUFFER_LOAD_DWORDX16 : SMRD_DWORDX16 <0x0000000c, "S_BUFFER_LOAD_DWORDX16", []>; +} // mayLoad = 1 + //def S_MEMTIME : SMRD_ <0x0000001e, "S_MEMTIME", []>; //def S_DCACHE_INV : SMRD_ <0x0000001f, "S_DCACHE_INV", []>; //def IMAGE_LOAD : MIMG_NoPattern_ <"IMAGE_LOAD", 0x00000000>; @@ -1419,4 +1423,33 @@ def : Pat <(f32 (IL_mad AllReg_32:$src0, VReg_32:$src1, VReg_32:$src2)), (V_MAD_LEGACY_F32 AllReg_32:$src0, VReg_32:$src1, VReg_32:$src2, 0, 0, 0, 0)>; +/********** ================== **********/ +/********** SMRD Patterns **********/ +/********** ================== **********/ + +multiclass SMRD_Pattern { + // 1. Offset as 8bit DWORD immediate + def : Pat < + (constant_load (SIadd64bit32bit SReg_64:$sbase, IMM8bitDWORD:$offset)), + (vt (Instr_IMM SReg_64:$sbase, IMM8bitDWORD:$offset)) + >; + + // 2. Offset loaded in an 32bit SGPR + def : Pat < + (constant_load (SIadd64bit32bit SReg_64:$sbase, imm:$offset)), + (vt (Instr_SGPR SReg_64:$sbase, (S_MOV_IMM_I32 imm:$offset))) + >; + + // 3. No offset at all + def : Pat < + (constant_load SReg_64:$sbase), + (vt (Instr_IMM SReg_64:$sbase, 0)) + >; +} + +defm : SMRD_Pattern ; +defm : SMRD_Pattern ; +defm : SMRD_Pattern ; +defm : SMRD_Pattern ; + } // End isSI predicate