From 862019c37f5b5d76e34eeb0d5686e617d544059f Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Tue, 18 Oct 2011 23:02:30 +0000 Subject: [PATCH] ARM VTBL (one register) assembly parsing and encoding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142441 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrNEON.td | 14 +++- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 84 +++++++++++++++++++ lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 5 ++ lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 1 + utils/TableGen/EDEmitter.cpp | 1 + 5 files changed, 102 insertions(+), 3 deletions(-) diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 19c36553af9..412b3ca5f93 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -70,6 +70,14 @@ def VectorIndex32 : Operand, ImmLeaf { + let ParserMatchClass = VecListOneDAsmOperand; +} + //===----------------------------------------------------------------------===// // NEON-specific DAG Nodes. //===----------------------------------------------------------------------===// @@ -4869,9 +4877,9 @@ def VZIPq32 : N2VQShuffle<0b10, 0b00011, IIC_VPERMQ3, "vzip", "32">; let DecoderMethod = "DecodeTBLInstruction" in { def VTBL1 : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$Vd), - (ins DPR:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1, - "vtbl", "8", "$Vd, \\{$Vn\\}, $Vm", "", - [(set DPR:$Vd, (v8i8 (int_arm_neon_vtbl1 DPR:$Vn, DPR:$Vm)))]>; + (ins VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1, + "vtbl", "8", "$Vd, $Vn, $Vm", "", + [(set DPR:$Vd, (v8i8 (int_arm_neon_vtbl1 VecListOneD:$Vn, DPR:$Vm)))]>; let hasExtraSrcRegAllocReq = 1 in { def VTBL2 : N3V<1,1,0b11,0b1001,0,0, (outs DPR:$Vd), diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 4f904aa219f..203a3118917 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -161,6 +161,7 @@ class ARMAsmParser : public MCTargetAsmParser { OperandMatchResultTy parsePostIdxReg(SmallVectorImpl&); OperandMatchResultTy parseAM3Offset(SmallVectorImpl&); OperandMatchResultTy parseFPImm(SmallVectorImpl&); + OperandMatchResultTy parseVectorList(SmallVectorImpl&); // Asm Match Converter Methods bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, @@ -262,6 +263,7 @@ class ARMOperand : public MCParsedAsmOperand { k_RegisterList, k_DPRRegisterList, k_SPRRegisterList, + k_VectorList, k_ShiftedRegister, k_ShiftedImmediate, k_ShifterImmediate, @@ -311,6 +313,12 @@ class ARMOperand : public MCParsedAsmOperand { unsigned RegNum; } Reg; + // A vector register list is a sequential list of 1 to 4 registers. + struct { + unsigned RegNum; + unsigned Count; + } VectorList; + struct { unsigned Val; } VectorIndex; @@ -393,6 +401,9 @@ public: case k_SPRRegisterList: Registers = o.Registers; break; + case k_VectorList: + VectorList = o.VectorList; + break; case k_CoprocNum: case k_CoprocReg: Cop = o.Cop; @@ -899,6 +910,11 @@ public: bool isProcIFlags() const { return Kind == k_ProcIFlags; } // NEON operands. + bool isVecListOneD() const { + if (Kind != k_VectorList) return false; + return VectorList.Count == 1; + } + bool isVectorIndex8() const { if (Kind != k_VectorIndex) return false; return VectorIndex.Val < 8; @@ -1486,6 +1502,11 @@ public: Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); } + void addVecListOneDOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); + } + void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); @@ -1705,6 +1726,16 @@ public: return Op; } + static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count, + SMLoc S, SMLoc E) { + ARMOperand *Op = new ARMOperand(k_VectorList); + Op->VectorList.RegNum = RegNum; + Op->VectorList.Count = Count; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; + } + static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) { ARMOperand *Op = new ARMOperand(k_VectorIndex); @@ -1896,6 +1927,10 @@ void ARMOperand::print(raw_ostream &OS) const { OS << ">"; break; } + case k_VectorList: + OS << ""; + break; case k_Token: OS << "'" << getToken() << "'"; break; @@ -2387,6 +2422,55 @@ parseRegisterList(SmallVectorImpl &Operands) { return false; } +// parse a vector register list +ARMAsmParser::OperandMatchResultTy ARMAsmParser:: +parseVectorList(SmallVectorImpl &Operands) { + if(Parser.getTok().isNot(AsmToken::LCurly)) + return MatchOperand_NoMatch; + + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat '{' token. + SMLoc RegLoc = Parser.getTok().getLoc(); + + int Reg = tryParseRegister(); + if (Reg == -1) { + Error(RegLoc, "register expected"); + return MatchOperand_ParseFail; + } + + unsigned FirstReg = Reg; + unsigned Count = 1; + while (Parser.getTok().is(AsmToken::Comma)) { + Parser.Lex(); // Eat the comma. + RegLoc = Parser.getTok().getLoc(); + int OldReg = Reg; + Reg = tryParseRegister(); + if (Reg == -1) { + Error(RegLoc, "register expected"); + return MatchOperand_ParseFail; + } + // vector register lists must also be contiguous. + // It's OK to use the enumeration values directly here rather, as the + // VFP register classes have the enum sorted properly. + if (Reg != OldReg + 1) { + Error(RegLoc, "non-contiguous register range"); + return MatchOperand_ParseFail; + } + + ++Count; + } + + SMLoc E = Parser.getTok().getLoc(); + if (Parser.getTok().isNot(AsmToken::RCurly)) { + Error(E, "'}' expected"); + return MatchOperand_ParseFail; + } + Parser.Lex(); // Eat '}' token. + + Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E)); + return MatchOperand_Success; +} + /// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. ARMAsmParser::OperandMatchResultTy ARMAsmParser:: parseMemBarrierOptOperand(SmallVectorImpl &Operands) { diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index ccdac3ebeb4..eadd77e43ad 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -990,3 +990,8 @@ void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum, raw_ostream &O) { O << "[" << MI->getOperand(OpNum).getImm() << "]"; } + +void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum, + raw_ostream &O) { + O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "}"; +} diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index 5c2173fcde6..3b5e8668b8b 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -129,6 +129,7 @@ public: void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printT2LdrLabelOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printVectorIndex(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printVectorListOne(const MCInst *MI, unsigned OpNum, raw_ostream &O); }; } // end namespace llvm diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index e9edfe4adfa..1a9a9c47f3e 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -571,6 +571,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, REG("QPR"); REG("QQPR"); REG("QQQQPR"); + REG("VecListOneD"); IMM("i32imm"); IMM("i32imm_hilo16"); -- 2.34.1