diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 28 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIDefines.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIInstrInfo.td | 124 |
5 files changed, 124 insertions, 65 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 53be8741503..41d8947efc1 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -267,7 +267,11 @@ public: return isOff() || isRegClass(AMDGPU::VGPR_32RegClassID); } - bool isSDWARegKind() const; + bool isSDWAOperand(MVT type) const; + bool isSDWAFP16Operand() const; + bool isSDWAFP32Operand() const; + bool isSDWAInt16Operand() const; + bool isSDWAInt32Operand() const; bool isImmTy(ImmTy ImmT) const { return isImm() && Imm.Type == ImmT; @@ -1285,15 +1289,31 @@ bool AMDGPUOperand::isRegClass(unsigned RCID) const { return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(getReg()); } -bool AMDGPUOperand::isSDWARegKind() const { +bool AMDGPUOperand::isSDWAOperand(MVT type) const { if (AsmParser->isVI()) return isVReg(); else if (AsmParser->isGFX9()) - return isRegKind(); + return isRegKind() || isInlinableImm(type); else return false; } +bool AMDGPUOperand::isSDWAFP16Operand() const { + return isSDWAOperand(MVT::f16); +} + +bool AMDGPUOperand::isSDWAFP32Operand() const { + return isSDWAOperand(MVT::f32); +} + +bool AMDGPUOperand::isSDWAInt16Operand() const { + return isSDWAOperand(MVT::i16); +} + +bool AMDGPUOperand::isSDWAInt32Operand() const { + return isSDWAOperand(MVT::i32); +} + uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val, unsigned Size) const { assert(isImmTy(ImmTyNone) && Imm.Mods.hasFPModifiers()); @@ -4799,7 +4819,7 @@ void AMDGPUAsmParser::cvtSDWA(MCInst &Inst, const OperandVector &Operands, } } if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) { - Op.addRegWithInputModsOperands(Inst, 2); + Op.addRegOrImmWithInputModsOperands(Inst, 2); } else if (Op.isImm()) { // Handle optional arguments OptionalIdx[Op.getImmTy()] = I; diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index ca7f2d1c9e6..6ea9367f270 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -732,8 +732,9 @@ MCOperand AMDGPUDisassembler::decodeSpecialReg64(unsigned Val) const { } MCOperand AMDGPUDisassembler::decodeSDWASrc(const OpWidthTy Width, - unsigned Val) const { + const unsigned Val) const { using namespace AMDGPU::SDWA; + using namespace AMDGPU::EncValues; if (STI.getFeatureBits()[AMDGPU::FeatureGFX9]) { // XXX: static_cast<int> is needed to avoid stupid warning: @@ -754,7 +755,15 @@ MCOperand AMDGPUDisassembler::decodeSDWASrc(const OpWidthTy Width, Val - SDWA9EncValues::SRC_TTMP_MIN); } - return decodeSpecialReg32(Val - SDWA9EncValues::SRC_SGPR_MIN); + const unsigned SVal = Val - SDWA9EncValues::SRC_SGPR_MIN; + + if (INLINE_INTEGER_C_MIN <= SVal && SVal <= INLINE_INTEGER_C_MAX) + return decodeIntImmed(SVal); + + if (INLINE_FLOATING_C_MIN <= SVal && SVal <= INLINE_FLOATING_C_MAX) + return decodeFPImmed(Width, SVal); + + return decodeSpecialReg32(SVal); } else if (STI.getFeatureBits()[AMDGPU::FeatureVolcanicIslands]) { return createRegOperand(getVgprClassId(Width), Val); } diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp index 94c0157edeb..0d917a192fd 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp @@ -335,13 +335,24 @@ SIMCCodeEmitter::getSDWASrcEncoding(const MCInst &MI, unsigned OpNo, const MCOperand &MO = MI.getOperand(OpNo); - unsigned Reg = MO.getReg(); - RegEnc |= MRI.getEncodingValue(Reg); - RegEnc &= SDWA9EncValues::SRC_VGPR_MASK; - if (AMDGPU::isSGPR(AMDGPU::mc2PseudoReg(Reg), &MRI)) { - RegEnc |= SDWA9EncValues::SRC_SGPR_MASK; + if (MO.isReg()) { + unsigned Reg = MO.getReg(); + RegEnc |= MRI.getEncodingValue(Reg); + RegEnc &= SDWA9EncValues::SRC_VGPR_MASK; + if (AMDGPU::isSGPR(AMDGPU::mc2PseudoReg(Reg), &MRI)) { + RegEnc |= SDWA9EncValues::SRC_SGPR_MASK; + } + return RegEnc; + } else { + const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); + uint32_t Enc = getLitEncoding(MO, Desc.OpInfo[OpNo], STI); + if (Enc != ~0U && Enc != 255) { + return Enc | SDWA9EncValues::SRC_SGPR_MASK; + } } - return RegEnc; + + llvm_unreachable("Unsupported operand kind"); + return 0; } unsigned diff --git a/llvm/lib/Target/AMDGPU/SIDefines.h b/llvm/lib/Target/AMDGPU/SIDefines.h index b4a8529568b..bf8d88bf4fa 100644 --- a/llvm/lib/Target/AMDGPU/SIDefines.h +++ b/llvm/lib/Target/AMDGPU/SIDefines.h @@ -137,7 +137,6 @@ namespace AMDGPU { OPERAND_INPUT_MODS, // Operand for SDWA instructions - OPERAND_SDWA_SRC, OPERAND_SDWA_VOPC_DST, /// Operand with 32-bit immediate that uses the constant bus. diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td index 88ee6a963d6..e232bc88f11 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -169,6 +169,36 @@ def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET", >; //===----------------------------------------------------------------------===// +// ValueType helpers +//===----------------------------------------------------------------------===// + +// Returns 1 if the source arguments have modifiers, 0 if they do not. +// XXX - do f16 instructions? +class isFloatType<ValueType SrcVT> { + bit ret = + !if(!eq(SrcVT.Value, f16.Value), 1, + !if(!eq(SrcVT.Value, f32.Value), 1, + !if(!eq(SrcVT.Value, f64.Value), 1, + !if(!eq(SrcVT.Value, v2f16.Value), 1, + 0)))); +} + +class isIntType<ValueType SrcVT> { + bit ret = + !if(!eq(SrcVT.Value, i16.Value), 1, + !if(!eq(SrcVT.Value, i32.Value), 1, + !if(!eq(SrcVT.Value, i64.Value), 1, + 0))); +} + +class isPackedType<ValueType SrcVT> { + bit ret = + !if(!eq(SrcVT.Value, v2i16.Value), 1, + !if(!eq(SrcVT.Value, v2f16.Value), 1, 0) + ); +} + +//===----------------------------------------------------------------------===// // PatFrags for global memory operations //===----------------------------------------------------------------------===// @@ -566,19 +596,18 @@ def ExpSrc3 : RegisterOperand<VGPR_32> { let ParserMatchClass = VReg32OrOffClass; } -class SDWASrc : RegisterOperand<VS_32> { +class SDWASrc<ValueType vt> : RegisterOperand<VS_32> { let OperandNamespace = "AMDGPU"; - let OperandType = "OPERAND_SDWA_SRC"; + string Type = !if(isFloatType<vt>.ret, "FP", "INT"); + let OperandType = "OPERAND_REG_INLINE_C_"#Type#vt.Size; + let DecoderMethod = "decodeSDWASrc"#vt.Size; let EncoderMethod = "getSDWASrcEncoding"; } -def SDWASrc32 : SDWASrc { - let DecoderMethod = "decodeSDWASrc32"; -} - -def SDWASrc16 : SDWASrc { - let DecoderMethod = "decodeSDWASrc16"; -} +def SDWASrc_i32 : SDWASrc<i32>; +def SDWASrc_i16 : SDWASrc<i16>; +def SDWASrc_f32 : SDWASrc<f32>; +def SDWASrc_f16 : SDWASrc<f16>; def SDWAVopcDst : VOPDstOperand<SReg_64> { let OperandNamespace = "AMDGPU"; @@ -761,16 +790,23 @@ class OpSelModsMatchClass : AsmOperandClass { def IntOpSelModsMatchClass : OpSelModsMatchClass; def IntOpSelMods : InputMods<IntOpSelModsMatchClass>; -def FPRegSDWAInputModsMatchClass : AsmOperandClass { - let Name = "SDWARegWithFPInputMods"; - let ParserMethod = "parseRegWithFPInputMods"; - let PredicateMethod = "isSDWARegKind"; +class FPSDWAInputModsMatchClass <int opSize> : AsmOperandClass { + let Name = "SDWAWithFP"#opSize#"InputMods"; + let ParserMethod = "parseRegOrImmWithFPInputMods"; + let PredicateMethod = "isSDWAFP"#opSize#"Operand"; } -def FPRegSDWAInputMods : InputMods <FPRegSDWAInputModsMatchClass> { +def FP16SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<16>; +def FP32SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<32>; + +class FPSDWAInputMods <FPSDWAInputModsMatchClass matchClass> : + InputMods <matchClass> { let PrintMethod = "printOperandAndFPInputMods"; } +def FP16SDWAInputMods : FPSDWAInputMods<FP16SDWAInputModsMatchClass>; +def FP32SDWAInputMods : FPSDWAInputMods<FP32SDWAInputModsMatchClass>; + def FPVRegInputModsMatchClass : AsmOperandClass { let Name = "VRegWithFPInputMods"; let ParserMethod = "parseRegWithFPInputMods"; @@ -781,17 +817,23 @@ def FPVRegInputMods : InputMods <FPVRegInputModsMatchClass> { let PrintMethod = "printOperandAndFPInputMods"; } - -def IntRegSDWAInputModsMatchClass : AsmOperandClass { - let Name = "SDWARegWithIntInputMods"; - let ParserMethod = "parseRegWithIntInputMods"; - let PredicateMethod = "isSDWARegKind"; +class IntSDWAInputModsMatchClass <int opSize> : AsmOperandClass { + let Name = "SDWAWithInt"#opSize#"InputMods"; + let ParserMethod = "parseRegOrImmWithIntInputMods"; + let PredicateMethod = "isSDWAInt"#opSize#"Operand"; } -def IntRegSDWAInputMods : InputMods <IntRegSDWAInputModsMatchClass> { +def Int16SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<16>; +def Int32SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<32>; + +class IntSDWAInputMods <IntSDWAInputModsMatchClass matchClass> : + InputMods <matchClass> { let PrintMethod = "printOperandAndIntInputMods"; } +def Int16SDWAInputMods : IntSDWAInputMods<Int16SDWAInputModsMatchClass>; +def Int32SDWAInputMods : IntSDWAInputMods<Int32SDWAInputModsMatchClass>; + def IntVRegInputModsMatchClass : AsmOperandClass { let Name = "VRegWithIntInputMods"; let ParserMethod = "parseRegWithIntInputMods"; @@ -1037,7 +1079,12 @@ class getVregSrcForVT<ValueType VT> { } class getSDWASrcForVT <ValueType VT> { - RegisterOperand ret = !if(!eq(VT.Size, 16), SDWASrc16, SDWASrc32); + bit isFP = !if(!eq(VT.Value, f16.Value), 1, + !if(!eq(VT.Value, f32.Value), 1, + 0)); + RegisterOperand retFlt = !if(!eq(VT.Size, 16), SDWASrc_f16, SDWASrc_f32); + RegisterOperand retInt = !if(!eq(VT.Size, 16), SDWASrc_i16, SDWASrc_i32); + RegisterOperand ret = !if(isFP, retFlt, retInt); } // Returns the register class to use for sources of VOP3 instructions for the @@ -1078,32 +1125,6 @@ class getVOP3SrcForVT<ValueType VT> { ); } -// Returns 1 if the source arguments have modifiers, 0 if they do not. -// XXX - do f16 instructions? -class isFloatType<ValueType SrcVT> { - bit ret = - !if(!eq(SrcVT.Value, f16.Value), 1, - !if(!eq(SrcVT.Value, f32.Value), 1, - !if(!eq(SrcVT.Value, f64.Value), 1, - !if(!eq(SrcVT.Value, v2f16.Value), 1, - 0)))); -} - -class isIntType<ValueType SrcVT> { - bit ret = - !if(!eq(SrcVT.Value, i16.Value), 1, - !if(!eq(SrcVT.Value, i32.Value), 1, - !if(!eq(SrcVT.Value, i64.Value), 1, - 0))); -} - -class isPackedType<ValueType SrcVT> { - bit ret = - !if(!eq(SrcVT.Value, v2i16.Value), 1, - !if(!eq(SrcVT.Value, v2f16.Value), 1, 0) - ); -} - // Float or packed int class isModifierType<ValueType SrcVT> { bit ret = @@ -1148,11 +1169,10 @@ class getSrcModExt <ValueType VT> { // Return type of input modifiers operand specified input operand for SDWA class getSrcModSDWA <ValueType VT> { - bit isFP = !if(!eq(VT.Value, f16.Value), 1, - !if(!eq(VT.Value, f32.Value), 1, - !if(!eq(VT.Value, f64.Value), 1, - 0))); - Operand ret = !if(isFP, FPRegSDWAInputMods, IntRegSDWAInputMods); + Operand ret = !if(!eq(VT.Value, f16.Value), FP16SDWAInputMods, + !if(!eq(VT.Value, f32.Value), FP32SDWAInputMods, + !if(!eq(VT.Value, i16.Value), Int16SDWAInputMods, + Int32SDWAInputMods))); } // Returns the input arguments for VOP[12C] instructions for the given SrcVT. |