From c73d73eb881ebe7493e934c00ca1c474ffd0ed2d Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Fri, 28 Oct 2011 00:06:50 +0000 Subject: [PATCH] ARM Allow 'q' registers in VLD/VST vector lists. Just treat it as if the constituent D registers where specified. rdar://10348896 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143167 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 51 ++++++++++++++++++++++++++++--- test/MC/ARM/neon-vld-encoding.s | 9 ++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 8803b687782..dbdce29e107 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2440,6 +2440,29 @@ parseRegisterList(SmallVectorImpl &Operands) { return false; } +// Return the low-subreg of a given Q register. +static unsigned getDRegFromQReg(unsigned QReg) { + switch (QReg) { + default: llvm_unreachable("expected a Q register!"); + case ARM::Q0: return ARM::D0; + case ARM::Q1: return ARM::D2; + case ARM::Q2: return ARM::D4; + case ARM::Q3: return ARM::D6; + case ARM::Q4: return ARM::D8; + case ARM::Q5: return ARM::D10; + case ARM::Q6: return ARM::D12; + case ARM::Q7: return ARM::D14; + case ARM::Q8: return ARM::D16; + case ARM::Q9: return ARM::D19; + case ARM::Q10: return ARM::D20; + case ARM::Q11: return ARM::D22; + case ARM::Q12: return ARM::D24; + case ARM::Q13: return ARM::D26; + case ARM::Q14: return ARM::D28; + case ARM::Q15: return ARM::D30; + } +} + // parse a vector register list ARMAsmParser::OperandMatchResultTy ARMAsmParser:: parseVectorList(SmallVectorImpl &Operands) { @@ -2455,9 +2478,16 @@ parseVectorList(SmallVectorImpl &Operands) { Error(RegLoc, "register expected"); return MatchOperand_ParseFail; } - - unsigned FirstReg = Reg; unsigned Count = 1; + unsigned FirstReg = Reg; + // The list is of D registers, but we also allow Q regs and just interpret + // them as the two D sub-registers. + if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { + FirstReg = Reg = getDRegFromQReg(Reg); + ++Reg; + ++Count; + } + while (Parser.getTok().is(AsmToken::Comma)) { Parser.Lex(); // Eat the comma. RegLoc = Parser.getTok().getLoc(); @@ -2467,14 +2497,27 @@ parseVectorList(SmallVectorImpl &Operands) { Error(RegLoc, "register expected"); return MatchOperand_ParseFail; } - // vector register lists must also be contiguous. + // vector register lists must be contiguous. // It's OK to use the enumeration values directly here rather, as the // VFP register classes have the enum sorted properly. + // + // The list is of D registers, but we also allow Q regs and just interpret + // them as the two D sub-registers. + if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { + Reg = getDRegFromQReg(Reg); + if (Reg != OldReg + 1) { + Error(RegLoc, "non-contiguous register range"); + return MatchOperand_ParseFail; + } + ++Reg; + Count += 2; + continue; + } + // Normal D register. Just check that it's contiguous and keep going. if (Reg != OldReg + 1) { Error(RegLoc, "non-contiguous register range"); return MatchOperand_ParseFail; } - ++Count; } diff --git a/test/MC/ARM/neon-vld-encoding.s b/test/MC/ARM/neon-vld-encoding.s index 1a77966bca0..6577b2d2ed6 100644 --- a/test/MC/ARM/neon-vld-encoding.s +++ b/test/MC/ARM/neon-vld-encoding.s @@ -214,3 +214,12 @@ @ FIXME: vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] @ encoding: [0xaf,0x0b,0xe0,0xf4] @ FIXME: vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [r0, :64] @ encoding: [0x7f,0x07,0xe0,0xf4] @ FIXME: vld4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] @ encoding: [0x4f,0x1b,0xe0,0xf4] + + +@ Handle 'Q' registers in register lists as if the sub-reg D regs were +@ specified instead. + vld1.8 {q3}, [r9] + vld1.8 {q3, q4}, [r9] + +@ CHECK: vld1.8 {d6, d7}, [r9] @ encoding: [0x0f,0x6a,0x29,0xf4] +@ CHECK: vld1.8 {d6, d7, d8, d9}, [r9] @ encoding: [0x0f,0x62,0x29,0xf4] -- 2.11.0