forked from OSchip/llvm-project
ARM NEON two-register double spaced register list parsing support.
llvm-svn: 146685
This commit is contained in:
parent
75ed9dcbc6
commit
2f50e92f40
|
@ -336,6 +336,7 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||||
unsigned RegNum;
|
unsigned RegNum;
|
||||||
unsigned Count;
|
unsigned Count;
|
||||||
unsigned LaneIndex;
|
unsigned LaneIndex;
|
||||||
|
bool isDoubleSpaced;
|
||||||
} VectorList;
|
} VectorList;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -1074,31 +1075,35 @@ public:
|
||||||
bool isProcIFlags() const { return Kind == k_ProcIFlags; }
|
bool isProcIFlags() const { return Kind == k_ProcIFlags; }
|
||||||
|
|
||||||
// NEON operands.
|
// NEON operands.
|
||||||
|
bool isSingleSpacedVectorList() const {
|
||||||
|
return Kind == k_VectorList && !VectorList.isDoubleSpaced;
|
||||||
|
}
|
||||||
|
bool isDoubleSpacedVectorList() const {
|
||||||
|
return Kind == k_VectorList && VectorList.isDoubleSpaced;
|
||||||
|
}
|
||||||
bool isVecListOneD() const {
|
bool isVecListOneD() const {
|
||||||
if (Kind != k_VectorList) return false;
|
if (!isSingleSpacedVectorList()) return false;
|
||||||
return VectorList.Count == 1;
|
return VectorList.Count == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVecListTwoD() const {
|
bool isVecListTwoD() const {
|
||||||
if (Kind != k_VectorList) return false;
|
if (!isSingleSpacedVectorList()) return false;
|
||||||
return VectorList.Count == 2;
|
return VectorList.Count == 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVecListThreeD() const {
|
bool isVecListThreeD() const {
|
||||||
if (Kind != k_VectorList) return false;
|
if (!isSingleSpacedVectorList()) return false;
|
||||||
return VectorList.Count == 3;
|
return VectorList.Count == 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVecListFourD() const {
|
bool isVecListFourD() const {
|
||||||
if (Kind != k_VectorList) return false;
|
if (!isSingleSpacedVectorList()) return false;
|
||||||
return VectorList.Count == 4;
|
return VectorList.Count == 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVecListTwoQ() const {
|
bool isVecListTwoQ() const {
|
||||||
if (Kind != k_VectorList) return false;
|
if (!isDoubleSpacedVectorList()) return false;
|
||||||
//FIXME: We haven't taught the parser to handle by-two register lists
|
return VectorList.Count == 2;
|
||||||
// yet, so don't pretend to know one.
|
|
||||||
return VectorList.Count == 2 && false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVecListOneDAllLanes() const {
|
bool isVecListOneDAllLanes() const {
|
||||||
|
@ -1948,10 +1953,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
|
static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
|
||||||
SMLoc S, SMLoc E) {
|
bool isDoubleSpaced, SMLoc S, SMLoc E) {
|
||||||
ARMOperand *Op = new ARMOperand(k_VectorList);
|
ARMOperand *Op = new ARMOperand(k_VectorList);
|
||||||
Op->VectorList.RegNum = RegNum;
|
Op->VectorList.RegNum = RegNum;
|
||||||
Op->VectorList.Count = Count;
|
Op->VectorList.Count = Count;
|
||||||
|
Op->VectorList.isDoubleSpaced = isDoubleSpaced;
|
||||||
Op->StartLoc = S;
|
Op->StartLoc = S;
|
||||||
Op->EndLoc = E;
|
Op->EndLoc = E;
|
||||||
return Op;
|
return Op;
|
||||||
|
@ -2774,7 +2780,7 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
assert(0 && "unexpected lane kind!");
|
assert(0 && "unexpected lane kind!");
|
||||||
case NoLanes:
|
case NoLanes:
|
||||||
E = Parser.getTok().getLoc();
|
E = Parser.getTok().getLoc();
|
||||||
Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, S, E));
|
Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
|
||||||
break;
|
break;
|
||||||
case AllLanes:
|
case AllLanes:
|
||||||
E = Parser.getTok().getLoc();
|
E = Parser.getTok().getLoc();
|
||||||
|
@ -2797,7 +2803,7 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
assert(0 && "unexpected lane kind!");
|
assert(0 && "unexpected lane kind!");
|
||||||
case NoLanes:
|
case NoLanes:
|
||||||
E = Parser.getTok().getLoc();
|
E = Parser.getTok().getLoc();
|
||||||
Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, S, E));
|
Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
|
||||||
break;
|
break;
|
||||||
case AllLanes:
|
case AllLanes:
|
||||||
E = Parser.getTok().getLoc();
|
E = Parser.getTok().getLoc();
|
||||||
|
@ -2826,11 +2832,14 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
return MatchOperand_ParseFail;
|
return MatchOperand_ParseFail;
|
||||||
}
|
}
|
||||||
unsigned Count = 1;
|
unsigned Count = 1;
|
||||||
|
unsigned Spacing = 0;
|
||||||
unsigned FirstReg = Reg;
|
unsigned FirstReg = Reg;
|
||||||
// The list is of D registers, but we also allow Q regs and just interpret
|
// The list is of D registers, but we also allow Q regs and just interpret
|
||||||
// them as the two D sub-registers.
|
// them as the two D sub-registers.
|
||||||
if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
|
if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
|
||||||
FirstReg = Reg = getDRegFromQReg(Reg);
|
FirstReg = Reg = getDRegFromQReg(Reg);
|
||||||
|
Spacing = 1; // double-spacing requires explicit D registers, otherwise
|
||||||
|
// it's ambiguous with four-register single spaced.
|
||||||
++Reg;
|
++Reg;
|
||||||
++Count;
|
++Count;
|
||||||
}
|
}
|
||||||
|
@ -2840,6 +2849,13 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
while (Parser.getTok().is(AsmToken::Comma) ||
|
while (Parser.getTok().is(AsmToken::Comma) ||
|
||||||
Parser.getTok().is(AsmToken::Minus)) {
|
Parser.getTok().is(AsmToken::Minus)) {
|
||||||
if (Parser.getTok().is(AsmToken::Minus)) {
|
if (Parser.getTok().is(AsmToken::Minus)) {
|
||||||
|
if (!Spacing)
|
||||||
|
Spacing = 1; // Register range implies a single spaced list.
|
||||||
|
else if (Spacing == 2) {
|
||||||
|
Error(Parser.getTok().getLoc(),
|
||||||
|
"sequential registers in double spaced list");
|
||||||
|
return MatchOperand_ParseFail;
|
||||||
|
}
|
||||||
Parser.Lex(); // Eat the minus.
|
Parser.Lex(); // Eat the minus.
|
||||||
SMLoc EndLoc = Parser.getTok().getLoc();
|
SMLoc EndLoc = Parser.getTok().getLoc();
|
||||||
int EndReg = tryParseRegister();
|
int EndReg = tryParseRegister();
|
||||||
|
@ -2895,6 +2911,13 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
// The list is of D registers, but we also allow Q regs and just interpret
|
// The list is of D registers, but we also allow Q regs and just interpret
|
||||||
// them as the two D sub-registers.
|
// them as the two D sub-registers.
|
||||||
if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
|
if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
|
||||||
|
if (!Spacing)
|
||||||
|
Spacing = 1; // Register range implies a single spaced list.
|
||||||
|
else if (Spacing == 2) {
|
||||||
|
Error(RegLoc,
|
||||||
|
"invalid register in double-spaced list (must be 'D' register')");
|
||||||
|
return MatchOperand_ParseFail;
|
||||||
|
}
|
||||||
Reg = getDRegFromQReg(Reg);
|
Reg = getDRegFromQReg(Reg);
|
||||||
if (Reg != OldReg + 1) {
|
if (Reg != OldReg + 1) {
|
||||||
Error(RegLoc, "non-contiguous register range");
|
Error(RegLoc, "non-contiguous register range");
|
||||||
|
@ -2914,8 +2937,14 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Normal D register. Just check that it's contiguous and keep going.
|
// Normal D register.
|
||||||
if (Reg != OldReg + 1) {
|
// Figure out the register spacing (single or double) of the list if
|
||||||
|
// we don't know it already.
|
||||||
|
if (!Spacing)
|
||||||
|
Spacing = 1 + (Reg == OldReg + 2);
|
||||||
|
|
||||||
|
// Just check that it's contiguous and keep going.
|
||||||
|
if (Reg != OldReg + Spacing) {
|
||||||
Error(RegLoc, "non-contiguous register range");
|
Error(RegLoc, "non-contiguous register range");
|
||||||
return MatchOperand_ParseFail;
|
return MatchOperand_ParseFail;
|
||||||
}
|
}
|
||||||
|
@ -2930,6 +2959,11 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
Error(EndLoc, "mismatched lane index in register list");
|
Error(EndLoc, "mismatched lane index in register list");
|
||||||
return MatchOperand_ParseFail;
|
return MatchOperand_ParseFail;
|
||||||
}
|
}
|
||||||
|
if (Spacing == 2 && LaneKind != NoLanes) {
|
||||||
|
Error(EndLoc,
|
||||||
|
"lane index specfier invalid in double spaced register list");
|
||||||
|
return MatchOperand_ParseFail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SMLoc E = Parser.getTok().getLoc();
|
SMLoc E = Parser.getTok().getLoc();
|
||||||
|
@ -2943,7 +2977,8 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
default:
|
default:
|
||||||
assert(0 && "unexpected lane kind in register list.");
|
assert(0 && "unexpected lane kind in register list.");
|
||||||
case NoLanes:
|
case NoLanes:
|
||||||
Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E));
|
Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
|
||||||
|
(Spacing == 2), S, E));
|
||||||
break;
|
break;
|
||||||
case AllLanes:
|
case AllLanes:
|
||||||
Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
|
Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
|
||||||
|
|
Loading…
Reference in New Issue