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 +++++++++++++++++++++++++++--- 3 files changed, 57 insertions(+), 11 deletions(-) (limited to 'lib') 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(); -- cgit v1.1