diff options
author | Bill Wendling <isanbard@gmail.com> | 2010-11-17 04:32:08 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2010-11-17 04:32:08 +0000 |
commit | 0f6307561359fac4425a0b9e512931cf96c1ec5b (patch) | |
tree | 03e2b707d388830e52030c7176de2374fd0c9350 /lib | |
parent | ff10341183adf74760e6118a55cbd1debf50f90f (diff) | |
download | external_llvm-0f6307561359fac4425a0b9e512931cf96c1ec5b.zip external_llvm-0f6307561359fac4425a0b9e512931cf96c1ec5b.tar.gz external_llvm-0f6307561359fac4425a0b9e512931cf96c1ec5b.tar.bz2 |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 22 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrVFP.td | 16 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 30 |
3 files changed, 57 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<i32> { let EncoderMethod = "getRegisterListOpValue"; let ParserMatchClass = RegListAsmOperand; let PrintMethod = "printRegisterList"; } +def dpr_reglist : Operand<i32> { + let EncoderMethod = "getRegisterListOpValue"; + let ParserMatchClass = DPRRegListAsmOperand; + let PrintMethod = "printRegisterList"; +} + +def spr_reglist : Operand<i32> { + let EncoderMethod = "getRegisterListOpValue"; + let ParserMatchClass = SPRRegListAsmOperand; + let PrintMethod = "printRegisterList"; +} + // An operand for the CONSTPOOL_ENTRY pseudo-instruction. def cpinst_operand : Operand<i32> { 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<string asm, bit L_bit, InstrItinClass itin, InstrItinClass itin_upd> { // 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<string asm, bit L_bit, let Inst{20} = L_bit; } def DIA_UPD : - AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), + AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), IndexModeUpd, itin_upd, !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> { let Inst{24-23} = 0b01; // Increment After @@ -94,7 +94,7 @@ multiclass vfp_ldst_mult<string asm, bit L_bit, let Inst{20} = L_bit; } def DDB : - 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, "db${p}\t$Rn, $regs"), "", []> { let Inst{24-23} = 0b10; // Decrement Before @@ -102,7 +102,7 @@ multiclass vfp_ldst_mult<string asm, bit L_bit, let Inst{20} = L_bit; } def DDB_UPD : - AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), + AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), IndexModeUpd, itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { let Inst{24-23} = 0b10; // Decrement Before @@ -112,7 +112,7 @@ multiclass vfp_ldst_mult<string asm, bit L_bit, // Single Precision def SIA : - AXSI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), + AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), IndexModeNone, itin, !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> { let Inst{24-23} = 0b01; // Increment After @@ -120,7 +120,7 @@ multiclass vfp_ldst_mult<string asm, bit L_bit, let Inst{20} = L_bit; } def SIA_UPD : - AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), + AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), IndexModeUpd, itin_upd, !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> { let Inst{24-23} = 0b01; // Increment After @@ -128,7 +128,7 @@ multiclass vfp_ldst_mult<string asm, bit L_bit, let Inst{20} = L_bit; } def SDB : - AXSI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), + AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), IndexModeNone, itin, !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> { let Inst{24-23} = 0b10; // Decrement Before @@ -136,7 +136,7 @@ multiclass vfp_ldst_mult<string asm, bit L_bit, let Inst{20} = L_bit; } def SDB_UPD : - AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), + AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), IndexModeUpd, itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 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<unsigned> &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<std::pair<unsigned, SMLoc> > &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<unsigned, 32>(); for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::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 << "<register " << getReg() << (!Reg.Writeback ? ">" : "!>"); break; - case RegisterList: { + case RegisterList: + case DPRRegisterList: + case SPRRegisterList: { OS << "<register_list "; const SmallVectorImpl<unsigned> &RegList = getRegList(); |