From 0f6307561359fac4425a0b9e512931cf96c1ec5b Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 17 Nov 2010 04:32:08 +0000 Subject: Proper encoding for VLDM and VSTM instructions. The register lists for these instructions have to distinguish between lists of single- and double-precision registers in order for the ASM matcher to do a proper job. In all other respects, a list of single- or double-precision registers are the same as a list of GPR registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119460 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 22 ++++++++++++++++++++++ lib/Target/ARM/ARMInstrVFP.td | 16 ++++++++-------- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 30 +++++++++++++++++++++++++++--- test/MC/ARM/simple-fp-encoding.s | 10 ++++++++++ utils/TableGen/EDEmitter.cpp | 4 ++++ 5 files changed, 71 insertions(+), 11 deletions(-) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index c06208e..6032e21 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -290,12 +290,34 @@ def RegListAsmOperand : AsmOperandClass { let SuperClasses = []; } +def DPRRegListAsmOperand : AsmOperandClass { + let Name = "DPRRegList"; + let SuperClasses = []; +} + +def SPRRegListAsmOperand : AsmOperandClass { + let Name = "SPRRegList"; + let SuperClasses = []; +} + def reglist : Operand { let EncoderMethod = "getRegisterListOpValue"; let ParserMatchClass = RegListAsmOperand; let PrintMethod = "printRegisterList"; } +def dpr_reglist : Operand { + let EncoderMethod = "getRegisterListOpValue"; + let ParserMatchClass = DPRRegListAsmOperand; + let PrintMethod = "printRegisterList"; +} + +def spr_reglist : Operand { + let EncoderMethod = "getRegisterListOpValue"; + let ParserMatchClass = SPRRegListAsmOperand; + let PrintMethod = "printRegisterList"; +} + // An operand for the CONSTPOOL_ENTRY pseudo-instruction. def cpinst_operand : Operand { let PrintMethod = "printCPInstOperand"; diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index 7ca3b39..d622169 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -78,7 +78,7 @@ multiclass vfp_ldst_mult { // Double Precision def DIA : - AXDI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), + AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), IndexModeNone, itin, !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> { let Inst{24-23} = 0b01; // Increment After @@ -86,7 +86,7 @@ multiclass vfp_ldst_mult { let Inst{24-23} = 0b01; // Increment After @@ -94,7 +94,7 @@ multiclass vfp_ldst_mult { let Inst{24-23} = 0b10; // Decrement Before @@ -102,7 +102,7 @@ multiclass vfp_ldst_mult { let Inst{24-23} = 0b10; // Decrement Before @@ -112,7 +112,7 @@ multiclass vfp_ldst_mult { let Inst{24-23} = 0b01; // Increment After @@ -120,7 +120,7 @@ multiclass vfp_ldst_mult { let Inst{24-23} = 0b01; // Increment After @@ -128,7 +128,7 @@ multiclass vfp_ldst_mult { let Inst{24-23} = 0b10; // Decrement Before @@ -136,7 +136,7 @@ multiclass vfp_ldst_mult { let Inst{24-23} = 0b10; // Decrement Before diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index e00ced2..b07fb64 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -107,6 +107,8 @@ class ARMOperand : public MCParsedAsmOperand { Memory, Register, RegisterList, + DPRRegisterList, + SPRRegisterList, Token } Kind; @@ -168,6 +170,8 @@ public: Reg = o.Reg; break; case RegisterList: + case DPRRegisterList: + case SPRRegisterList: RegList = o.RegList; break; case Immediate: @@ -204,7 +208,8 @@ public: } const SmallVectorImpl &getRegList() const { - assert(Kind == RegisterList && "Invalid access!"); + assert((Kind == RegisterList || Kind == DPRRegisterList || + Kind == SPRRegisterList) && "Invalid access!"); return *RegList.Registers; } @@ -217,6 +222,8 @@ public: bool isImm() const { return Kind == Immediate; } bool isReg() const { return Kind == Register; } bool isRegList() const { return Kind == RegisterList; } + bool isDPRRegList() const { return Kind == DPRRegisterList; } + bool isSPRRegList() const { return Kind == SPRRegisterList; } bool isToken() const { return Kind == Token; } bool isMemory() const { return Kind == Memory; } bool isMemMode5() const { @@ -264,6 +271,14 @@ public: Inst.addOperand(MCOperand::CreateReg(*I)); } + void addDPRRegListOperands(MCInst &Inst, unsigned N) const { + addRegListOperands(Inst, N); + } + + void addSPRRegListOperands(MCInst &Inst, unsigned N) const { + addRegListOperands(Inst, N); + } + void addImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); addExpr(Inst, getImm()); @@ -327,7 +342,14 @@ public: static ARMOperand * CreateRegList(const SmallVectorImpl > &Regs, SMLoc StartLoc, SMLoc EndLoc) { - ARMOperand *Op = new ARMOperand(RegisterList); + KindTy Kind = RegisterList; + + if (ARM::DPRRegClass.contains(Regs.front().first)) + Kind = DPRRegisterList; + else if (ARM::SPRRegClass.contains(Regs.front().first)) + Kind = SPRRegisterList; + + ARMOperand *Op = new ARMOperand(Kind); Op->RegList.Registers = new SmallVector(); for (SmallVectorImpl >::const_iterator I = Regs.begin(), E = Regs.end(); I != E; ++I) @@ -387,7 +409,9 @@ void ARMOperand::dump(raw_ostream &OS) const { case Register: OS << "" : "!>"); break; - case RegisterList: { + case RegisterList: + case DPRRegisterList: + case SPRRegisterList: { OS << " &RegList = getRegList(); diff --git a/test/MC/ARM/simple-fp-encoding.s b/test/MC/ARM/simple-fp-encoding.s index 9120fcf..f699b21 100644 --- a/test/MC/ARM/simple-fp-encoding.s +++ b/test/MC/ARM/simple-fp-encoding.s @@ -207,3 +207,13 @@ vstr.32 s4, [r1] vstr.32 s4, [r1, #24] vstr.32 s4, [r1, #-24] + +@ CHECK: vldmia r1, {d2, d3, d4, d5, d6, d7} @ encoding: [0x0c,0x2b,0x91,0xec] +@ CHECK: vldmia r1, {s2, s3, s4, s5, s6, s7} @ encoding: [0x06,0x1a,0x91,0xec] + vldmia r1, {d2,d3-d6,d7} + vldmia r1, {s2,s3-s6,s7} + +@ CHECK: vstmia r1, {d2, d3, d4, d5, d6, d7} @ encoding: [0x0c,0x2b,0x81,0xec] +@ CHECK: vstmia r1, {s2, s3, s4, s5, s6, s7} @ encoding: [0x06,0x1a,0x81,0xec] + vstmia r1, {d2,d3-d6,d7} + vstmia r1, {s2,s3-s6,s7} diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 78d3510..dd09174 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -607,6 +607,8 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("am6offset", "kOperandTypeARMAddrMode6Offset"); // R, I, I MISC("addrmodepc", "kOperandTypeARMAddrModePC"); // R, I MISC("reglist", "kOperandTypeARMRegisterList"); // I, R, ... + MISC("dpr_reglist", "kOperandTypeARMDPRRegisterList"); // I, R, ... + MISC("spr_reglist", "kOperandTypeARMSPRRegisterList"); // I, R, ... MISC("it_mask", "kOperandTypeThumbITMask"); // I MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8"); // R, I MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I @@ -823,6 +825,8 @@ static void emitCommonEnums(raw_ostream &o, unsigned int &i) { operandTypes.addEntry("kOperandTypeARMAddrMode6Offset"); operandTypes.addEntry("kOperandTypeARMAddrModePC"); operandTypes.addEntry("kOperandTypeARMRegisterList"); + operandTypes.addEntry("kOperandTypeARMDPRRegisterList"); + operandTypes.addEntry("kOperandTypeARMSPRRegisterList"); operandTypes.addEntry("kOperandTypeARMTBAddrMode"); operandTypes.addEntry("kOperandTypeThumbITMask"); operandTypes.addEntry("kOperandTypeThumbAddrModeS1"); -- cgit v1.1