[llvm] r266865 - AMDGPU/SI: Assembler: improvements to support trap handlers.
Nikolay Haustov via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 20 02:34:48 PDT 2016
Author: nhaustov
Date: Wed Apr 20 04:34:48 2016
New Revision: 266865
URL: http://llvm.org/viewvc/llvm-project?rev=266865&view=rev
Log:
AMDGPU/SI: Assembler: improvements to support trap handlers.
Add ParseAMDGPURegister which can be invoked recursively for parsing lists.
Rename getRegForName to getSpecialRegForName.
Support legacy SP3 register list syntax: [s2,s3,s4,s5] or [flat_scratch_lo,flat_scratch_hi].
Add 64-bit registers TBA, TMA where missing.
Add some tests.
Differential Revision: http://reviews.llvm.org/D19163
Modified:
llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
llvm/trunk/lib/Target/AMDGPU/SIRegisterInfo.td
llvm/trunk/test/MC/AMDGPU/trap.s
Modified: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp?rev=266865&r1=266864&r2=266865&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp Wed Apr 20 04:34:48 2016
@@ -42,6 +42,8 @@ namespace {
struct OptionalOperand;
+enum RegisterKind { IS_UNKNOWN, IS_VGPR, IS_SGPR, IS_TTMP, IS_SPECIAL };
+
class AMDGPUOperand : public MCParsedAsmOperand {
enum KindTy {
Token,
@@ -454,6 +456,8 @@ private:
bool ParseSectionDirectiveHSADataGlobalAgent();
bool ParseSectionDirectiveHSADataGlobalProgram();
bool ParseSectionDirectiveHSARodataReadonlyAgent();
+ bool AddNextRegisterToList(unsigned& Reg, unsigned& RegWidth, RegisterKind RegKind, unsigned Reg1, unsigned RegNum);
+ bool ParseAMDGPURegister(RegisterKind& RegKind, unsigned& Reg, unsigned& RegNum, unsigned& RegWidth);
public:
enum AMDGPUMatchResultTy {
@@ -573,8 +577,6 @@ struct OptionalOperand {
}
-enum RegisterKind { IS_VGPR, IS_SGPR, IS_TTMP };
-
static int getRegClass(RegisterKind Is, unsigned RegWidth) {
if (Is == IS_VGPR) {
switch (RegWidth) {
@@ -605,14 +607,15 @@ static int getRegClass(RegisterKind Is,
return -1;
}
-static unsigned getRegForName(StringRef RegName) {
-
+static unsigned getSpecialRegForName(StringRef RegName) {
return StringSwitch<unsigned>(RegName)
.Case("exec", AMDGPU::EXEC)
.Case("vcc", AMDGPU::VCC)
.Case("flat_scratch", AMDGPU::FLAT_SCR)
.Case("m0", AMDGPU::M0)
.Case("scc", AMDGPU::SCC)
+ .Case("tba", AMDGPU::TBA)
+ .Case("tma", AMDGPU::TMA)
.Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
.Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
.Case("vcc_lo", AMDGPU::VCC_LO)
@@ -636,86 +639,136 @@ bool AMDGPUAsmParser::ParseRegister(unsi
return false;
}
-std::unique_ptr<AMDGPUOperand> AMDGPUAsmParser::parseRegister() {
- const AsmToken &Tok = Parser.getTok();
- SMLoc StartLoc = Tok.getLoc();
- SMLoc EndLoc = Tok.getEndLoc();
- const MCRegisterInfo *TRI = getContext().getRegisterInfo();
-
- StringRef RegName = Tok.getString();
- unsigned RegNo = getRegForName(RegName);
-
- if (RegNo) {
- Parser.Lex();
- if (!subtargetHasRegister(*TRI, RegNo))
- return nullptr;
- return AMDGPUOperand::CreateReg(RegNo, StartLoc, EndLoc,
- TRI, &getSTI(), false);
+bool AMDGPUAsmParser::AddNextRegisterToList(unsigned& Reg, unsigned& RegWidth, RegisterKind RegKind, unsigned Reg1, unsigned RegNum)
+{
+ switch (RegKind) {
+ case IS_SPECIAL:
+ if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) { Reg = AMDGPU::EXEC; RegWidth = 2; return true; }
+ if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) { Reg = AMDGPU::FLAT_SCR; RegWidth = 2; return true; }
+ if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) { Reg = AMDGPU::VCC; RegWidth = 2; return true; }
+ if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) { Reg = AMDGPU::TBA; RegWidth = 2; return true; }
+ if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) { Reg = AMDGPU::TMA; RegWidth = 2; return true; }
+ return false;
+ case IS_VGPR:
+ case IS_SGPR:
+ case IS_TTMP:
+ if (Reg1 != Reg + RegWidth) { return false; }
+ RegWidth++;
+ return true;
+ default:
+ assert(false); return false;
}
+}
- // Match vgprs, sgprs and ttmps
- if (RegName[0] != 's' && RegName[0] != 'v' && !RegName.startswith("ttmp"))
- return nullptr;
-
- const RegisterKind Is = RegName[0] == 'v' ? IS_VGPR : RegName[0] == 's' ? IS_SGPR : IS_TTMP;
- unsigned RegWidth;
- unsigned RegIndexInClass;
- if (RegName.size() > (Is == IS_TTMP ? strlen("ttmp") : 1) ) {
- // We have a single 32-bit register. Syntax: vXX
- RegWidth = 1;
- if (RegName.substr(Is == IS_TTMP ? strlen("ttmp") : 1).getAsInteger(10, RegIndexInClass))
- return nullptr;
- Parser.Lex();
- } else {
- // We have a register greater than 32-bits (a range of single registers). Syntax: v[XX:YY]
-
- int64_t RegLo, RegHi;
- Parser.Lex();
- if (getLexer().isNot(AsmToken::LBrac))
- return nullptr;
-
- Parser.Lex();
- if (getParser().parseAbsoluteExpression(RegLo))
- return nullptr;
-
- if (getLexer().isNot(AsmToken::Colon))
- return nullptr;
+bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind& RegKind, unsigned& Reg, unsigned& RegNum, unsigned& RegWidth)
+{
+ const MCRegisterInfo *TRI = getContext().getRegisterInfo();
+ if (getLexer().is(AsmToken::Identifier)) {
+ StringRef RegName = Parser.getTok().getString();
+ if ((Reg = getSpecialRegForName(RegName))) {
+ Parser.Lex();
+ RegKind = IS_SPECIAL;
+ } else {
+ unsigned RegNumIndex = 0;
+ if (RegName[0] == 'v') { RegNumIndex = 1; RegKind = IS_VGPR; }
+ else if (RegName[0] == 's') { RegNumIndex = 1; RegKind = IS_SGPR; }
+ else if (RegName.startswith("ttmp")) { RegNumIndex = strlen("ttmp"); RegKind = IS_TTMP; }
+ else { return false; }
+ if (RegName.size() > RegNumIndex) {
+ // Single 32-bit register: vXX.
+ if (RegName.substr(RegNumIndex).getAsInteger(10, RegNum)) { return false; }
+ Parser.Lex();
+ RegWidth = 1;
+ } else {
+ // Range of registers: v[XX:YY].
+ Parser.Lex();
+ int64_t RegLo, RegHi;
+ if (getLexer().isNot(AsmToken::LBrac)) { return false; }
+ Parser.Lex();
+
+ if (getParser().parseAbsoluteExpression(RegLo)) { return false; }
+
+ if (getLexer().isNot(AsmToken::Colon)) { return false; }
+ Parser.Lex();
- Parser.Lex();
- if (getParser().parseAbsoluteExpression(RegHi))
- return nullptr;
+ if (getParser().parseAbsoluteExpression(RegHi)) { return false; }
- if (getLexer().isNot(AsmToken::RBrac))
- return nullptr;
+ if (getLexer().isNot(AsmToken::RBrac)) { return false; }
+ Parser.Lex();
+ RegNum = (unsigned) RegLo;
+ RegWidth = (RegHi - RegLo) + 1;
+ }
+ }
+ } else if (getLexer().is(AsmToken::LBrac)) {
+ // List of consecutive registers: [s0,s1,s2,s3]
Parser.Lex();
- RegWidth = (RegHi - RegLo) + 1;
- if (Is == IS_VGPR) {
- // VGPR registers aren't aligned.
- RegIndexInClass = RegLo;
- } else {
+ if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) { return false; }
+ if (RegWidth != 1) { return false; }
+ RegisterKind RegKind1;
+ unsigned Reg1, RegNum1, RegWidth1;
+ do {
+ if (getLexer().is(AsmToken::Comma)) {
+ Parser.Lex();
+ } else if (getLexer().is(AsmToken::RBrac)) {
+ Parser.Lex();
+ break;
+ } else if (ParseAMDGPURegister(RegKind1, Reg1, RegNum1, RegWidth1)) {
+ if (RegWidth1 != 1) { return false; }
+ if (RegKind1 != RegKind) { return false; }
+ if (!AddNextRegisterToList(Reg, RegWidth, RegKind1, Reg1, RegNum1)) { return false; }
+ } else {
+ return false;
+ }
+ } while (true);
+ } else {
+ return false;
+ }
+ switch (RegKind) {
+ case IS_SPECIAL:
+ RegNum = 0;
+ RegWidth = 1;
+ break;
+ case IS_VGPR:
+ case IS_SGPR:
+ case IS_TTMP:
+ {
+ unsigned Size = 1;
+ if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
// SGPR and TTMP registers must be are aligned. Max required alignment is 4 dwords.
- unsigned Size = std::min(RegWidth, 4u);
- if (RegLo % Size != 0)
- return nullptr;
-
- RegIndexInClass = RegLo / Size;
+ Size = std::min(RegWidth, 4u);
}
+ if (RegNum % Size != 0) { return false; }
+ RegNum = RegNum / Size;
+ int RCID = getRegClass(RegKind, RegWidth);
+ if (RCID == -1) { return false; }
+ const MCRegisterClass RC = TRI->getRegClass(RCID);
+ if (RegNum >= RC.getNumRegs()) { return false; }
+ Reg = RC.getRegister(RegNum);
+ break;
}
- int RCID = getRegClass(Is, RegWidth);
- if (RCID == -1)
- return nullptr;
+ default:
+ assert(false); return false;
+ }
- const MCRegisterClass RC = TRI->getRegClass(RCID);
- if (RegIndexInClass >= RC.getNumRegs())
- return nullptr;
+ if (!subtargetHasRegister(*TRI, Reg)) { return false; }
+ return true;
+}
- RegNo = RC.getRegister(RegIndexInClass);
- if (!subtargetHasRegister(*TRI, RegNo))
- return nullptr;
+std::unique_ptr<AMDGPUOperand> AMDGPUAsmParser::parseRegister() {
+ const auto &Tok = Parser.getTok();
+ SMLoc StartLoc = Tok.getLoc();
+ SMLoc EndLoc = Tok.getEndLoc();
+ const MCRegisterInfo *TRI = getContext().getRegisterInfo();
- return AMDGPUOperand::CreateReg(RegNo, StartLoc, EndLoc,
+ RegisterKind RegKind;
+ unsigned Reg, RegNum, RegWidth;
+
+ if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) {
+ return nullptr;
+ }
+ return AMDGPUOperand::CreateReg(Reg, StartLoc, EndLoc,
TRI, &getSTI(), false);
}
@@ -1114,6 +1167,7 @@ AMDGPUAsmParser::parseOperand(OperandVec
AMDGPUOperand::CreateImm(F.bitcastToAPInt().getZExtValue(), S));
return MatchOperand_Success;
}
+ case AsmToken::LBrac:
case AsmToken::Identifier: {
if (auto R = parseRegister()) {
unsigned Modifiers = 0;
Modified: llvm/trunk/lib/Target/AMDGPU/SIRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIRegisterInfo.td?rev=266865&r1=266864&r2=266865&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/SIRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/AMDGPU/SIRegisterInfo.td Wed Apr 20 04:34:48 2016
@@ -262,7 +262,7 @@ def TTMP_64 : RegisterClass<"AMDGPU", [v
}
def SReg_64 : RegisterClass<"AMDGPU", [v2i32, i64, f64, i1], 32,
- (add SGPR_64, VCC, EXEC, FLAT_SCR, TTMP_64)
+ (add SGPR_64, VCC, EXEC, FLAT_SCR, TTMP_64, TBA, TMA)
>;
def SReg_128 : RegisterClass<"AMDGPU", [v4i32, v16i8, v2i64], 32, (add SGPR_128)> {
Modified: llvm/trunk/test/MC/AMDGPU/trap.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/trap.s?rev=266865&r1=266864&r2=266865&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/trap.s (original)
+++ llvm/trunk/test/MC/AMDGPU/trap.s Wed Apr 20 04:34:48 2016
@@ -97,3 +97,19 @@ s_or_b32 ttmp9, ttmp9, 0x00280000
s_mov_b64 ttmp[4:5], exec
// SICI: s_mov_b64 ttmp[4:5], exec ; encoding: [0x7e,0x04,0xf4,0xbe]
// VI: s_mov_b64 ttmp[4:5], exec ; encoding: [0x7e,0x01,0xf4,0xbe]
+
+s_mov_b64 tba, ttmp[4:5]
+// SICI: s_mov_b64 tba, ttmp[4:5] ; encoding: [0x74,0x04,0xec,0xbe]
+// VI: s_mov_b64 tba, ttmp[4:5] ; encoding: [0x74,0x01,0xec,0xbe]
+
+s_mov_b64 ttmp[4:5], tba
+// SICI: s_mov_b64 ttmp[4:5], tba ; encoding: [0x6c,0x04,0xf4,0xbe]
+// VI: s_mov_b64 ttmp[4:5], tba ; encoding: [0x6c,0x01,0xf4,0xbe]
+
+s_mov_b64 tma, ttmp[4:5]
+// SICI: s_mov_b64 tma, ttmp[4:5] ; encoding: [0x74,0x04,0xee,0xbe]
+// VI: s_mov_b64 tma, ttmp[4:5] ; encoding: [0x74,0x01,0xee,0xbe]
+
+s_mov_b64 ttmp[4:5], tma
+// SICI: s_mov_b64 ttmp[4:5], tma ; encoding: [0x6e,0x04,0xf4,0xbe]
+// VI: s_mov_b64 ttmp[4:5], tma ; encoding: [0x6e,0x01,0xf4,0xbe]
More information about the llvm-commits
mailing list