mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-07 12:28:24 +00:00
ARM assembly parsing for register range syntax for VLD/VST register lists.
For example, vld1.f64 {d2-d5}, [r2,:128]! Should be equivalent to: vld1.f64 {d2,d3,d4,d5}, [r2,:128]! It's not documented syntax in the ARM ARM, but it is consistent with what's accepted for VLDM/VSTM and is unambiguous in meaning, so it's a good thing to support. rdar://10451128 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144727 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -2420,7 +2420,7 @@ parseRegisterList(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)) {
|
||||||
Parser.Lex(); // Eat the comma.
|
Parser.Lex(); // Eat the minus.
|
||||||
SMLoc EndLoc = Parser.getTok().getLoc();
|
SMLoc EndLoc = Parser.getTok().getLoc();
|
||||||
int EndReg = tryParseRegister();
|
int EndReg = tryParseRegister();
|
||||||
if (EndReg == -1)
|
if (EndReg == -1)
|
||||||
@@ -2530,7 +2530,39 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
|||||||
++Count;
|
++Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (Parser.getTok().is(AsmToken::Comma)) {
|
while (Parser.getTok().is(AsmToken::Comma) ||
|
||||||
|
Parser.getTok().is(AsmToken::Minus)) {
|
||||||
|
if (Parser.getTok().is(AsmToken::Minus)) {
|
||||||
|
Parser.Lex(); // Eat the minus.
|
||||||
|
SMLoc EndLoc = Parser.getTok().getLoc();
|
||||||
|
int EndReg = tryParseRegister();
|
||||||
|
if (EndReg == -1) {
|
||||||
|
Error(EndLoc, "register expected");
|
||||||
|
return MatchOperand_ParseFail;
|
||||||
|
}
|
||||||
|
// Allow Q regs and just interpret them as the two D sub-registers.
|
||||||
|
if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
|
||||||
|
EndReg = getDRegFromQReg(EndReg) + 1;
|
||||||
|
// If the register is the same as the start reg, there's nothing
|
||||||
|
// more to do.
|
||||||
|
if (Reg == EndReg)
|
||||||
|
continue;
|
||||||
|
// The register must be in the same register class as the first.
|
||||||
|
if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
|
||||||
|
Error(EndLoc, "invalid register in register list");
|
||||||
|
return MatchOperand_ParseFail;
|
||||||
|
}
|
||||||
|
// Ranges must go from low to high.
|
||||||
|
if (Reg > EndReg) {
|
||||||
|
Error(EndLoc, "bad range in register list");
|
||||||
|
return MatchOperand_ParseFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add all the registers in the range to the register list.
|
||||||
|
Count += EndReg - Reg;
|
||||||
|
Reg = EndReg;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Parser.Lex(); // Eat the comma.
|
Parser.Lex(); // Eat the comma.
|
||||||
RegLoc = Parser.getTok().getLoc();
|
RegLoc = Parser.getTok().getLoc();
|
||||||
int OldReg = Reg;
|
int OldReg = Reg;
|
||||||
|
@@ -251,3 +251,11 @@
|
|||||||
@ CHECK: vld1.8 {d2, d3, d4}, [r2] @ encoding: [0x0f,0x26,0x22,0xf4]
|
@ CHECK: vld1.8 {d2, d3, d4}, [r2] @ encoding: [0x0f,0x26,0x22,0xf4]
|
||||||
@ CHECK: vld1.32 {d2, d3, d4}, [r2] @ encoding: [0x8f,0x26,0x22,0xf4]
|
@ CHECK: vld1.32 {d2, d3, d4}, [r2] @ encoding: [0x8f,0x26,0x22,0xf4]
|
||||||
@ CHECK: vld1.64 {d2, d3, d4}, [r2] @ encoding: [0xcf,0x26,0x22,0xf4]
|
@ CHECK: vld1.64 {d2, d3, d4}, [r2] @ encoding: [0xcf,0x26,0x22,0xf4]
|
||||||
|
|
||||||
|
|
||||||
|
@ Register lists can use the range syntax, just like VLDM
|
||||||
|
vld1.f64 {d2-d5}, [r2,:128]!
|
||||||
|
vld1.f64 {d2,d3,d4,d5}, [r2,:128]!
|
||||||
|
|
||||||
|
@ CHECK: vld1.64 {d2, d3, d4, d5}, [r2, :128]! @ encoding: [0xed,0x22,0x22,0xf4]
|
||||||
|
@ CHECK: vld1.64 {d2, d3, d4, d5}, [r2, :128]! @ encoding: [0xed,0x22,0x22,0xf4]
|
||||||
|
Reference in New Issue
Block a user