aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
diff options
context:
space:
mode:
authorSam Kolton <Sam.Kolton@amd.com>2016-04-26 13:33:56 +0000
committerSam Kolton <Sam.Kolton@amd.com>2016-04-26 13:33:56 +0000
commit3025e7f25f7b0ea5c78e31a15c172182c82958d9 (patch)
tree32d373d40223acc39b55ea4243973bc6084344e6 /llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
parent323ab3975b6005f963cf152a5b0f4f014ef43be1 (diff)
downloadllvm-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.cpp112
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() {