diff options
author | Jim Grosbach <grosbach@apple.com> | 2011-11-15 23:19:15 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2011-11-15 23:19:15 +0000 |
commit | e43862b6a6130ec29ee4e9e6c6c30b5607c9a728 (patch) | |
tree | 33c0b81c6656718548bcfd552a49c38bb481f2e6 | |
parent | 6ac5b165d471fa1d1e6a266c4566a5605c38ba9a (diff) |
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
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 36 | ||||
-rw-r--r-- | test/MC/ARM/neon-vld-encoding.s | 8 |
2 files changed, 42 insertions, 2 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index ede71da575..64c913fbb8 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2420,7 +2420,7 @@ parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { while (Parser.getTok().is(AsmToken::Comma) || 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(); int EndReg = tryParseRegister(); if (EndReg == -1) @@ -2530,7 +2530,39 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { ++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. RegLoc = Parser.getTok().getLoc(); int OldReg = Reg; diff --git a/test/MC/ARM/neon-vld-encoding.s b/test/MC/ARM/neon-vld-encoding.s index 03a3cea37c..503b1ec360 100644 --- a/test/MC/ARM/neon-vld-encoding.s +++ b/test/MC/ARM/neon-vld-encoding.s @@ -251,3 +251,11 @@ @ 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.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] |