diff options
author | Sam Kolton <Sam.Kolton@amd.com> | 2016-04-26 13:33:56 +0000 |
---|---|---|
committer | Sam Kolton <Sam.Kolton@amd.com> | 2016-04-26 13:33:56 +0000 |
commit | 3025e7f25f7b0ea5c78e31a15c172182c82958d9 (patch) | |
tree | 32d373d40223acc39b55ea4243973bc6084344e6 /llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | |
parent | 323ab3975b6005f963cf152a5b0f4f014ef43be1 (diff) | |
download | llvm-3025e7f25f7b0ea5c78e31a15c172182c82958d9.zip llvm-3025e7f25f7b0ea5c78e31a15c172182c82958d9.tar.gz llvm-3025e7f25f7b0ea5c78e31a15c172182c82958d9.tar.bz2 |
[AMDGPU] Assembler: basic support for SDWA instructions
Support for SDWA instructions for VOP1 and VOP2 encoding.
Not done yet:
- converters for support optional operands and modifiers
- VOPC
- sext() modifier
- intrinsics
- VOP2b (see vop_dpp.s)
- V_MAC_F32 (see vop_dpp.s)
Differential Revision: http://reviews.llvm.org/D19360
llvm-svn: 267553
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index c099c9b..500a3aa 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -74,6 +74,8 @@ public: ImmTyDppRowMask, ImmTyDppBankMask, ImmTyDppBoundCtrl, + ImmTySdwaSel, + ImmTySdwaDstUnused, ImmTyDMask, ImmTyUNorm, ImmTyDA, @@ -253,6 +255,14 @@ public: return isImmTy(ImmTyDppBoundCtrl); } + bool isSDWASel() const { + return isImmTy(ImmTySdwaSel); + } + + bool isSDWADstUnused() const { + return isImmTy(ImmTySdwaDstUnused); + } + void setModifiers(unsigned Mods) { assert(isReg() || (isImm() && Imm.Modifiers == 0)); if (isReg()) @@ -522,6 +532,7 @@ public: OperandMatchResultTy parseOptionalOps( const ArrayRef<OptionalOperand> &OptionalOps, OperandVector &Operands); + OperandMatchResultTy parseStringWithPrefix(const char *Prefix, StringRef &Value); void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands); @@ -569,6 +580,9 @@ public: void cvtDPP_mod(MCInst &Inst, const OperandVector &Operands); void cvtDPP_nomod(MCInst &Inst, const OperandVector &Operands); void cvtDPP(MCInst &Inst, const OperandVector &Operands, bool HasMods); + + OperandMatchResultTy parseSDWASel(OperandVector &Operands); + OperandMatchResultTy parseSDWADstUnused(OperandVector &Operands); }; struct OptionalOperand { @@ -1396,6 +1410,30 @@ AMDGPUAsmParser::parseOptionalOps(const ArrayRef<OptionalOperand> &OptionalOps, return MatchOperand_NoMatch; } +AMDGPUAsmParser::OperandMatchResultTy +AMDGPUAsmParser::parseStringWithPrefix(const char *Prefix, StringRef &Value) { + if (getLexer().isNot(AsmToken::Identifier)) { + return MatchOperand_NoMatch; + } + StringRef Tok = Parser.getTok().getString(); + if (Tok != Prefix) { + return MatchOperand_NoMatch; + } + + Parser.Lex(); + if (getLexer().isNot(AsmToken::Colon)) { + return MatchOperand_ParseFail; + } + + Parser.Lex(); + if (getLexer().isNot(AsmToken::Identifier)) { + return MatchOperand_ParseFail; + } + + Value = Parser.getTok().getString(); + return MatchOperand_Success; +} + //===----------------------------------------------------------------------===// // ds //===----------------------------------------------------------------------===// @@ -2296,6 +2334,80 @@ void AMDGPUAsmParser::cvtDPP(MCInst &Inst, const OperandVector &Operands, addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBoundCtrl); } +//===----------------------------------------------------------------------===// +// sdwa +//===----------------------------------------------------------------------===// + +AMDGPUAsmParser::OperandMatchResultTy +AMDGPUAsmParser::parseSDWASel(OperandVector &Operands) { + SMLoc S = Parser.getTok().getLoc(); + StringRef Value; + AMDGPUAsmParser::OperandMatchResultTy res; + + res = parseStringWithPrefix("dst_sel", Value); + if (res == MatchOperand_ParseFail) { + return MatchOperand_ParseFail; + } else if (res == MatchOperand_NoMatch) { + res = parseStringWithPrefix("src0_sel", Value); + if (res == MatchOperand_ParseFail) { + return MatchOperand_ParseFail; + } else if (res == MatchOperand_NoMatch) { + res = parseStringWithPrefix("src1_sel", Value); + if (res != MatchOperand_Success) { + return res; + } + } + } + + int64_t Int; + Int = StringSwitch<int64_t>(Value) + .Case("BYTE_0", 0) + .Case("BYTE_1", 1) + .Case("BYTE_2", 2) + .Case("BYTE_3", 3) + .Case("WORD_0", 4) + .Case("WORD_1", 5) + .Case("DWORD", 6) + .Default(0xffffffff); + Parser.Lex(); // eat last token + + if (Int == 0xffffffff) { + return MatchOperand_ParseFail; + } + + Operands.push_back(AMDGPUOperand::CreateImm(Int, S, + AMDGPUOperand::ImmTySdwaSel)); + return MatchOperand_Success; +} + +AMDGPUAsmParser::OperandMatchResultTy +AMDGPUAsmParser::parseSDWADstUnused(OperandVector &Operands) { + SMLoc S = Parser.getTok().getLoc(); + StringRef Value; + AMDGPUAsmParser::OperandMatchResultTy res; + + res = parseStringWithPrefix("dst_unused", Value); + if (res != MatchOperand_Success) { + return res; + } + + int64_t Int; + Int = StringSwitch<int64_t>(Value) + .Case("UNUSED_PAD", 0) + .Case("UNUSED_SEXT", 1) + .Case("UNUSED_PRESERVE", 2) + .Default(0xffffffff); + Parser.Lex(); // eat last token + + if (Int == 0xffffffff) { + return MatchOperand_ParseFail; + } + + Operands.push_back(AMDGPUOperand::CreateImm(Int, S, + AMDGPUOperand::ImmTySdwaDstUnused)); + return MatchOperand_Success; +} + /// Force static initialization. extern "C" void LLVMInitializeAMDGPUAsmParser() { |