aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
diff options
context:
space:
mode:
authorSam Kolton <Sam.Kolton@amd.com>2016-06-03 10:27:37 +0000
committerSam Kolton <Sam.Kolton@amd.com>2016-06-03 10:27:37 +0000
commit05ef1c940fa27615a619e9e945c5867c4c8f0574 (patch)
tree38a24f94d3ce1149659e2f5efe169f7359a81d49 /llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
parent02284541b2e092650933d67aba9382e863a75304 (diff)
downloadllvm-05ef1c940fa27615a619e9e945c5867c4c8f0574.zip
llvm-05ef1c940fa27615a619e9e945c5867c4c8f0574.tar.gz
llvm-05ef1c940fa27615a619e9e945c5867c4c8f0574.tar.bz2
[AMDGPU] Assembler: Custom converters for SDWA instructions. Support for _dpp and _sdwa suffixes in mnemonics.
Summary: Added custom converters for SDWA instruction to support optional operands and modifiers. Support for _dpp and _sdwa suffixes that allows to force DPP or SDWA encoding for instructions. Reviewers: tstellarAMD, vpykhtin, artem.tamazov Subscribers: arsenm, kzhuravl Differential Revision: http://reviews.llvm.org/D20625 llvm-svn: 271655
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp208
1 files changed, 154 insertions, 54 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 8883d25..6ae0f82 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -82,7 +82,9 @@ public:
ImmTyDppRowMask,
ImmTyDppBankMask,
ImmTyDppBoundCtrl,
- ImmTySdwaSel,
+ ImmTySdwaDstSel,
+ ImmTySdwaSrc0Sel,
+ ImmTySdwaSrc1Sel,
ImmTySdwaDstUnused,
ImmTyDMask,
ImmTyUNorm,
@@ -274,8 +276,16 @@ public:
return isImmTy(ImmTyDppBoundCtrl);
}
- bool isSDWASel() const {
- return isImmTy(ImmTySdwaSel);
+ bool isSDWADstSel() const {
+ return isImmTy(ImmTySdwaDstSel);
+ }
+
+ bool isSDWASrc0Sel() const {
+ return isImmTy(ImmTySdwaSrc0Sel);
+ }
+
+ bool isSDWASrc1Sel() const {
+ return isImmTy(ImmTySdwaSrc1Sel);
}
bool isSDWADstUnused() const {
@@ -385,7 +395,9 @@ public:
case ImmTyDppRowMask: OS << "DppRowMask"; break;
case ImmTyDppBankMask: OS << "DppBankMask"; break;
case ImmTyDppBoundCtrl: OS << "DppBoundCtrl"; break;
- case ImmTySdwaSel: OS << "SdwaSel"; break;
+ case ImmTySdwaDstSel: OS << "SdwaDstSel"; break;
+ case ImmTySdwaSrc0Sel: OS << "SdwaSrc0Sel"; break;
+ case ImmTySdwaSrc1Sel: OS << "SdwaSrc1Sel"; break;
case ImmTySdwaDstUnused: OS << "SdwaDstUnused"; break;
case ImmTyDMask: OS << "DMask"; break;
case ImmTyUNorm: OS << "UNorm"; break;
@@ -479,6 +491,8 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
MCAsmParser &Parser;
unsigned ForcedEncodingSize;
+ bool ForcedDPP;
+ bool ForcedSDWA;
bool isSI() const {
return AMDGPU::isSI(getSTI());
@@ -531,7 +545,9 @@ public:
const MCInstrInfo &MII,
const MCTargetOptions &Options)
: MCTargetAsmParser(Options, STI), MII(MII), Parser(_Parser),
- ForcedEncodingSize(0) {
+ ForcedEncodingSize(0),
+ ForcedDPP(false),
+ ForcedSDWA(false) {
MCAsmParserExtension::Initialize(Parser);
if (getSTI().getFeatureBits().none()) {
@@ -546,18 +562,15 @@ public:
MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
return static_cast<AMDGPUTargetStreamer &>(TS);
}
+
+ void setForcedEncodingSize(unsigned Size) { ForcedEncodingSize = Size; }
+ void setForcedDPP(bool ForceDPP_) { ForcedDPP = ForceDPP_; }
+ void setForcedSDWA(bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
- unsigned getForcedEncodingSize() const {
- return ForcedEncodingSize;
- }
-
- void setForcedEncodingSize(unsigned Size) {
- ForcedEncodingSize = Size;
- }
-
- bool isForcedVOP3() const {
- return ForcedEncodingSize == 64;
- }
+ unsigned getForcedEncodingSize() const { return ForcedEncodingSize; }
+ bool isForcedVOP3() const { return ForcedEncodingSize == 64; }
+ bool isForcedDPP() const { return ForcedDPP; }
+ bool isForcedSDWA() const { return ForcedSDWA; }
std::unique_ptr<AMDGPUOperand> parseRegister();
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
@@ -570,6 +583,7 @@ public:
bool MatchingInlineAsm) override;
bool ParseDirective(AsmToken DirectiveID) override;
OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Mnemonic);
+ StringRef parseMnemonicSuffix(StringRef Name);
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) override;
@@ -580,7 +594,7 @@ public:
bool (*ConvertResult)(int64_t&) = 0);
OperandMatchResultTy parseNamedBit(const char *Name, OperandVector &Operands,
enum AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
- OperandMatchResultTy parseStringWithPrefix(const char *Prefix, StringRef &Value);
+ OperandMatchResultTy parseStringWithPrefix(StringRef Prefix, StringRef &Value);
OperandMatchResultTy parseImm(OperandVector &Operands);
OperandMatchResultTy parseRegOrImm(OperandVector &Operands);
@@ -643,10 +657,20 @@ public:
AMDGPUOperand::Ptr defaultBoundCtrl() const;
void cvtDPP(MCInst &Inst, const OperandVector &Operands);
- OperandMatchResultTy parseSDWASel(OperandVector &Operands);
+ OperandMatchResultTy parseSDWASel(OperandVector &Operands, StringRef Prefix,
+ AMDGPUOperand::ImmTy Type);
OperandMatchResultTy parseSDWADstUnused(OperandVector &Operands);
- AMDGPUOperand::Ptr defaultSDWASel() const;
+ AMDGPUOperand::Ptr defaultSDWASel(AMDGPUOperand::ImmTy Type) const;
+ AMDGPUOperand::Ptr defaultSDWADstSel() const;
+ AMDGPUOperand::Ptr defaultSDWASrc0Sel() const;
+ AMDGPUOperand::Ptr defaultSDWASrc1Sel() const;
AMDGPUOperand::Ptr defaultSDWADstUnused() const;
+ void cvtSdwaVop1_mod(MCInst &Inst, const OperandVector &Operands);
+ void cvtSdwaVop1_nomod(MCInst &Inst, const OperandVector &Operands);
+ void cvtSdwaVop2_mod(MCInst &Inst, const OperandVector &Operands);
+ void cvtSdwaVop2_nomod(MCInst &Inst, const OperandVector &Operands);
+ void cvtSDWA(MCInst &Inst, const OperandVector &Operands, bool HasMods,
+ bool IsVOP1);
};
struct OptionalOperand {
@@ -988,7 +1012,9 @@ unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
if ((getForcedEncodingSize() == 32 && (TSFlags & SIInstrFlags::VOP3)) ||
- (getForcedEncodingSize() == 64 && !(TSFlags & SIInstrFlags::VOP3)))
+ (getForcedEncodingSize() == 64 && !(TSFlags & SIInstrFlags::VOP3)) ||
+ (isForcedDPP() && !(TSFlags & SIInstrFlags::DPP)) ||
+ (isForcedSDWA() && !(TSFlags & SIInstrFlags::SDWA)) )
return Match_InvalidOperand;
if ((TSFlags & SIInstrFlags::VOP3) &&
@@ -1323,25 +1349,35 @@ AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
return MatchOperand_NoMatch;
}
-bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
- StringRef Name,
- SMLoc NameLoc, OperandVector &Operands) {
-
+StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
// Clear any forced encodings from the previous instruction.
setForcedEncodingSize(0);
+ setForcedDPP(false);
+ setForcedSDWA(false);
- if (Name.endswith("_e64"))
+ if (Name.endswith("_e64")) {
setForcedEncodingSize(64);
- else if (Name.endswith("_e32"))
+ return Name.substr(0, Name.size() - 4);
+ } else if (Name.endswith("_e32")) {
setForcedEncodingSize(32);
+ return Name.substr(0, Name.size() - 4);
+ } else if (Name.endswith("_dpp")) {
+ setForcedDPP(true);
+ return Name.substr(0, Name.size() - 4);
+ } else if (Name.endswith("_sdwa")) {
+ setForcedSDWA(true);
+ return Name.substr(0, Name.size() - 5);
+ }
+ return Name;
+}
+bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
+ StringRef Name,
+ SMLoc NameLoc, OperandVector &Operands) {
// Add the instruction mnemonic
+ Name = parseMnemonicSuffix(Name);
Operands.push_back(AMDGPUOperand::CreateToken(Name, NameLoc));
-
-
- if (Name.endswith("_e64")) { Name = Name.substr(0, Name.size() - 4); }
- if (Name.endswith("_e32")) { Name = Name.substr(0, Name.size() - 4); }
-
+
while (!getLexer().is(AsmToken::EndOfStatement)) {
AMDGPUAsmParser::OperandMatchResultTy Res = parseOperand(Operands, Name);
@@ -1466,7 +1502,7 @@ void addOptionalImmOperand(MCInst& Inst, const OperandVector& Operands,
}
AMDGPUAsmParser::OperandMatchResultTy
-AMDGPUAsmParser::parseStringWithPrefix(const char *Prefix, StringRef &Value) {
+AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix, StringRef &Value) {
if (getLexer().isNot(AsmToken::Identifier)) {
return MatchOperand_NoMatch;
}
@@ -2196,7 +2232,9 @@ static const OptionalOperand AMDGPUOptionalOperandTable[] = {
{"row_mask", AMDGPUOperand::ImmTyDppRowMask, false, nullptr},
{"bank_mask", AMDGPUOperand::ImmTyDppBankMask, false, nullptr},
{"bound_ctrl", AMDGPUOperand::ImmTyDppBoundCtrl, false, ConvertBoundCtrl},
- {"sdwa_sel", AMDGPUOperand::ImmTySdwaSel, false, nullptr},
+ {"dst_sel", AMDGPUOperand::ImmTySdwaDstSel, false, nullptr},
+ {"src0_sel", AMDGPUOperand::ImmTySdwaSrc0Sel, false, nullptr},
+ {"src1_sel", AMDGPUOperand::ImmTySdwaSrc1Sel, false, nullptr},
{"dst_unused", AMDGPUOperand::ImmTySdwaDstUnused, false, nullptr},
};
@@ -2208,8 +2246,10 @@ AMDGPUAsmParser::OperandMatchResultTy AMDGPUAsmParser::parseOptionalOperand(Oper
res = parseNamedBit(Op.Name, Operands, Op.Type);
} else if (Op.Type == AMDGPUOperand::ImmTyOModSI) {
res = parseOModOperand(Operands);
- } else if (Op.Type == AMDGPUOperand::ImmTySdwaSel) {
- res = parseSDWASel(Operands);
+ } else if (Op.Type == AMDGPUOperand::ImmTySdwaDstSel ||
+ Op.Type == AMDGPUOperand::ImmTySdwaSrc0Sel ||
+ Op.Type == AMDGPUOperand::ImmTySdwaSrc1Sel) {
+ res = parseSDWASel(Operands, Op.Name, Op.Type);
} else if (Op.Type == AMDGPUOperand::ImmTySdwaDstUnused) {
res = parseSDWADstUnused(Operands);
} else {
@@ -2457,7 +2497,6 @@ void AMDGPUAsmParser::cvtDPP(MCInst &Inst, const OperandVector &Operands) {
}
}
- // ToDo: fix default values for row_mask and bank_mask
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppRowMask, 0xf);
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBankMask, 0xf);
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBoundCtrl);
@@ -2468,24 +2507,15 @@ void AMDGPUAsmParser::cvtDPP(MCInst &Inst, const OperandVector &Operands) {
//===----------------------------------------------------------------------===//
AMDGPUAsmParser::OperandMatchResultTy
-AMDGPUAsmParser::parseSDWASel(OperandVector &Operands) {
+AMDGPUAsmParser::parseSDWASel(OperandVector &Operands, StringRef Prefix,
+ AMDGPUOperand::ImmTy Type) {
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;
- }
- }
+ res = parseStringWithPrefix(Prefix, Value);
+ if (res != MatchOperand_Success) {
+ return res;
}
int64_t Int;
@@ -2504,8 +2534,7 @@ AMDGPUAsmParser::parseSDWASel(OperandVector &Operands) {
return MatchOperand_ParseFail;
}
- Operands.push_back(AMDGPUOperand::CreateImm(Int, S,
- AMDGPUOperand::ImmTySdwaSel));
+ Operands.push_back(AMDGPUOperand::CreateImm(Int, S, Type));
return MatchOperand_Success;
}
@@ -2537,14 +2566,85 @@ AMDGPUAsmParser::parseSDWADstUnused(OperandVector &Operands) {
return MatchOperand_Success;
}
-AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSDWASel() const {
- return AMDGPUOperand::CreateImm(6, SMLoc(), AMDGPUOperand::ImmTySdwaSel);
+AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSDWASel(AMDGPUOperand::ImmTy Type) const {
+ return AMDGPUOperand::CreateImm(6, SMLoc(), Type);
+}
+
+AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSDWADstSel() const {
+ return defaultSDWASel(AMDGPUOperand::ImmTySdwaDstSel);
+}
+
+AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSDWASrc0Sel() const {
+ return defaultSDWASel(AMDGPUOperand::ImmTySdwaSrc0Sel);
+}
+
+AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSDWASrc1Sel() const {
+ return defaultSDWASel(AMDGPUOperand::ImmTySdwaSrc1Sel);
}
AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSDWADstUnused() const {
return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTySdwaDstUnused);
}
+void AMDGPUAsmParser::cvtSdwaVop1_mod(MCInst &Inst, const OperandVector &Operands) {
+ cvtSDWA(Inst, Operands, true, true);
+}
+
+void AMDGPUAsmParser::cvtSdwaVop1_nomod(MCInst &Inst, const OperandVector &Operands) {
+ cvtSDWA(Inst, Operands, false, true);
+}
+
+void AMDGPUAsmParser::cvtSdwaVop2_mod(MCInst &Inst, const OperandVector &Operands) {
+ cvtSDWA(Inst, Operands, true, false);
+}
+
+void AMDGPUAsmParser::cvtSdwaVop2_nomod(MCInst &Inst, const OperandVector &Operands) {
+ cvtSDWA(Inst, Operands, false, false);
+}
+
+void AMDGPUAsmParser::cvtSDWA(MCInst &Inst, const OperandVector &Operands,
+ bool HasMods, bool IsVOP1) {
+ OptionalImmIndexMap OptionalIdx;
+
+ unsigned I = 1;
+ const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
+ for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
+ ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
+ }
+
+ for (unsigned E = Operands.size(); I != E; ++I) {
+ AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
+ // Add the register arguments
+ if (!HasMods && Op.isReg()) {
+ Op.addRegOperands(Inst, 1);
+ } else if (HasMods && Op.isRegOrImmWithInputMods()) {
+ Op.addRegOrImmWithInputModsOperands(Inst, 2);
+ } else if (Op.isImm()) {
+ // Handle optional arguments
+ OptionalIdx[Op.getImmTy()] = I;
+ } else {
+ llvm_unreachable("Invalid operand type");
+ }
+ }
+
+ if (HasMods) {
+ addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI, 0);
+ }
+ if (Inst.getOpcode() == AMDGPU::V_NOP_sdwa) {
+ // V_NOP_sdwa has no optional sdwa arguments
+ return;
+ }
+ if (IsVOP1) {
+ addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstSel, 6);
+ addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstUnused, 2);
+ addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc0Sel, 6);
+ } else { // VOP2
+ addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstSel, 6);
+ addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstUnused, 2);
+ addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc0Sel, 6);
+ addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc1Sel, 6);
+ }
+}
/// Force static initialization.
extern "C" void LLVMInitializeAMDGPUAsmParser() {