diff options
| author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-12-15 20:40:20 +0000 |
|---|---|---|
| committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-12-15 20:40:20 +0000 |
| commit | 0e8a299f190ba206fb58f1bf06c9b195b42734e0 (patch) | |
| tree | 757c80ebf478777131727c697251f043172d5439 /llvm/lib | |
| parent | 391f221df68cdb3ba0a2d2ab5f9d71204f77ceea (diff) | |
| download | bcm5719-llvm-0e8a299f190ba206fb58f1bf06c9b195b42734e0.tar.gz bcm5719-llvm-0e8a299f190ba206fb58f1bf06c9b195b42734e0.zip | |
AMDGPU: Assembler support for vintrp instructions
llvm-svn: 289866
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 78 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIInstrInfo.td | 24 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIInstructions.td | 12 |
3 files changed, 108 insertions, 6 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 55eee67a9ee..ef3f502f5f2 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -155,6 +155,9 @@ public: ImmTyHwreg, ImmTyOff, ImmTySendMsg, + ImmTyInterpSlot, + ImmTyInterpAttr, + ImmTyAttrChan }; struct TokOp { @@ -279,6 +282,9 @@ public: bool isSDWASrc0Sel() const { return isImmTy(ImmTySdwaSrc0Sel); } bool isSDWASrc1Sel() const { return isImmTy(ImmTySdwaSrc1Sel); } bool isSDWADstUnused() const { return isImmTy(ImmTySdwaDstUnused); } + bool isInterpSlot() const { return isImmTy(ImmTyInterpSlot); } + bool isInterpAttr() const { return isImmTy(ImmTyInterpAttr); } + bool isAttrChan() const { return isImmTy(ImmTyAttrChan); } bool isMod() const { return isClampSI() || isOModSI(); @@ -568,6 +574,9 @@ public: case ImmTyExpVM: OS << "ExpVM"; break; case ImmTyHwreg: OS << "Hwreg"; break; case ImmTySendMsg: OS << "SendMsg"; break; + case ImmTyInterpSlot: OS << "InterpSlot"; break; + case ImmTyInterpAttr: OS << "InterpAttr"; break; + case ImmTyAttrChan: OS << "AttrChan"; break; } } @@ -823,6 +832,8 @@ public: OperandMatchResultTy parseExpTgt(OperandVector &Operands); OperandMatchResultTy parseSendMsgOp(OperandVector &Operands); + OperandMatchResultTy parseInterpSlot(OperandVector &Operands); + OperandMatchResultTy parseInterpAttr(OperandVector &Operands); OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands); void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false); } @@ -2487,6 +2498,67 @@ bool AMDGPUAsmParser::parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &O return false; } +OperandMatchResultTy AMDGPUAsmParser::parseInterpSlot(OperandVector &Operands) { + if (getLexer().getKind() != AsmToken::Identifier) + return MatchOperand_NoMatch; + + StringRef Str = Parser.getTok().getString(); + int Slot = StringSwitch<int>(Str) + .Case("p10", 0) + .Case("p20", 1) + .Case("p0", 2) + .Default(-1); + + SMLoc S = Parser.getTok().getLoc(); + if (Slot == -1) + return MatchOperand_ParseFail; + + Parser.Lex(); + Operands.push_back(AMDGPUOperand::CreateImm(this, Slot, S, + AMDGPUOperand::ImmTyInterpSlot)); + return MatchOperand_Success; +} + +OperandMatchResultTy AMDGPUAsmParser::parseInterpAttr(OperandVector &Operands) { + if (getLexer().getKind() != AsmToken::Identifier) + return MatchOperand_NoMatch; + + StringRef Str = Parser.getTok().getString(); + if (!Str.startswith("attr")) + return MatchOperand_NoMatch; + + StringRef Chan = Str.take_back(2); + int AttrChan = StringSwitch<int>(Chan) + .Case(".x", 0) + .Case(".y", 1) + .Case(".z", 2) + .Case(".w", 3) + .Default(-1); + if (AttrChan == -1) + return MatchOperand_ParseFail; + + Str = Str.drop_back(2).drop_front(4); + + uint8_t Attr; + if (Str.getAsInteger(10, Attr)) + return MatchOperand_ParseFail; + + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); + if (Attr > 63) { + Error(S, "out of bounds attr"); + return MatchOperand_Success; + } + + SMLoc SChan = SMLoc::getFromPointer(Chan.data()); + + Operands.push_back(AMDGPUOperand::CreateImm(this, Attr, S, + AMDGPUOperand::ImmTyInterpAttr)); + Operands.push_back(AMDGPUOperand::CreateImm(this, AttrChan, SChan, + AMDGPUOperand::ImmTyAttrChan)); + return MatchOperand_Success; +} + void AMDGPUAsmParser::errorExpTgt() { Error(Parser.getTok().getLoc(), "invalid exp target"); } @@ -3423,6 +3495,12 @@ unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op, return Operand.isSoppBrTarget() ? Match_Success : Match_InvalidOperand; case MCK_VReg32OrOff: return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand; + case MCK_InterpSlot: + return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand; + case MCK_Attr: + return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand; + case MCK_AttrChan: + return Operand.isAttrChan() ? Match_Success : Match_InvalidOperand; default: return Match_InvalidOperand; } diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td index be0466b7753..0074bca25fc 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -304,19 +304,43 @@ def sopp_brtarget : Operand<OtherVT> { def si_ga : Operand<iPTR>; +def InterpSlotMatchClass : AsmOperandClass { + let Name = "InterpSlot"; + let PredicateMethod = "isInterpSlot"; + let ParserMethod = "parseInterpSlot"; + let RenderMethod = "addImmOperands"; +} + def InterpSlot : Operand<i32> { let PrintMethod = "printInterpSlot"; + let ParserMatchClass = InterpSlotMatchClass; + let OperandType = "OPERAND_IMMEDIATE"; +} + +def AttrMatchClass : AsmOperandClass { + let Name = "Attr"; + let PredicateMethod = "isInterpAttr"; + let ParserMethod = "parseInterpAttr"; + let RenderMethod = "addImmOperands"; } // It appears to be necessary to create a separate operand for this to // be able to parse attr<num> with no space. def Attr : Operand<i32> { let PrintMethod = "printInterpAttr"; + let ParserMatchClass = AttrMatchClass; let OperandType = "OPERAND_IMMEDIATE"; } +def AttrChanMatchClass : AsmOperandClass { + let Name = "AttrChan"; + let PredicateMethod = "isAttrChan"; + let RenderMethod = "addImmOperands"; +} + def AttrChan : Operand<i32> { let PrintMethod = "printInterpAttrChan"; + let ParserMatchClass = AttrChanMatchClass; let OperandType = "OPERAND_IMMEDIATE"; } diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td index 250fe8a5632..f107f545dc6 100644 --- a/llvm/lib/Target/AMDGPU/SIInstructions.td +++ b/llvm/lib/Target/AMDGPU/SIInstructions.td @@ -51,8 +51,8 @@ let Uses = [M0, EXEC] in { multiclass V_INTERP_P1_F32_m : VINTRP_m < 0x00000000, (outs VGPR_32:$vdst), - (ins VGPR_32:$vsrc, i32imm:$attr, AttrChan:$attrchan), - "v_interp_p1_f32 $vdst, $vsrc, attr${attr}$attrchan", + (ins VGPR_32:$vsrc, Attr:$attr, AttrChan:$attrchan), + "v_interp_p1_f32 $vdst, $vsrc, $attr$attrchan", [(set f32:$vdst, (AMDGPUinterp_p1 f32:$vsrc, (i32 imm:$attrchan), (i32 imm:$attr)))] >; @@ -74,8 +74,8 @@ let DisableEncoding = "$src0", Constraints = "$src0 = $vdst" in { defm V_INTERP_P2_F32 : VINTRP_m < 0x00000001, (outs VGPR_32:$vdst), - (ins VGPR_32:$src0, VGPR_32:$vsrc, i32imm:$attr, AttrChan:$attrchan), - "v_interp_p2_f32 $vdst, $vsrc, attr${attr}$attrchan", + (ins VGPR_32:$src0, VGPR_32:$vsrc, Attr:$attr, AttrChan:$attrchan), + "v_interp_p2_f32 $vdst, $vsrc, $attr$attrchan", [(set f32:$vdst, (AMDGPUinterp_p2 f32:$src0, f32:$vsrc, (i32 imm:$attrchan), (i32 imm:$attr)))]>; @@ -84,8 +84,8 @@ defm V_INTERP_P2_F32 : VINTRP_m < defm V_INTERP_MOV_F32 : VINTRP_m < 0x00000002, (outs VGPR_32:$vdst), - (ins InterpSlot:$vsrc, i32imm:$attr, AttrChan:$attrchan), - "v_interp_mov_f32 $vdst, $vsrc, attr${attr}$attrchan", + (ins InterpSlot:$vsrc, Attr:$attr, AttrChan:$attrchan), + "v_interp_mov_f32 $vdst, $vsrc, $attr$attrchan", [(set f32:$vdst, (AMDGPUinterp_mov (i32 imm:$vsrc), (i32 imm:$attrchan), (i32 imm:$attr)))]>; |

