From 6bc105a7b9282a0b5beb9d06267b31a3054fb3fa Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 17 Nov 2010 00:45:23 +0000 Subject: [PATCH] Add binary emission stuff for VLDM/VSTM. This reuses the "getRegisterListOpValue" logic. If the registers are double or single precision, the value returned is suitable for VLDM/VSTM. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119435 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrFormats.td | 24 +++++++++++++++++++++- lib/Target/ARM/ARMMCCodeEmitter.cpp | 31 ++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 4abb567f9f4..6308bc53de1 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1125,7 +1125,7 @@ class T1DataProcessing opcode> : Encoding16 { // A6.2.3 Special data instructions and branch and exchange encoding. class T1Special opcode> : Encoding16 { let Inst{15-10} = 0b010001; - let Inst{9-6} = opcode; + let Inst{9-6} = opcode; } // A6.2.4 Load/store single data item encoding. @@ -1321,6 +1321,8 @@ class VFPXI pattern> : InstARM { + bits<4> p; + let Inst{31-28} = p; let OutOperandList = oops; let InOperandList = iops; let AsmString = asm; @@ -1399,6 +1401,16 @@ class AXDI4 pattern> : VFPXI { + // Instruction operands. + bits<4> Rn; + bits<13> regs; + + // Encode instruction operands. + let Inst{19-16} = Rn; + let Inst{22} = regs{12}; + let Inst{15-12} = regs{11-8}; + let Inst{7-0} = regs{7-0}; + // TODO: Mark the instructions with the appropriate subtarget info. let Inst{27-25} = 0b110; let Inst{11-9} = 0b101; @@ -1412,6 +1424,16 @@ class AXSI4 pattern> : VFPXI { + // Instruction operands. + bits<4> Rn; + bits<13> regs; + + // Encode instruction operands. + let Inst{19-16} = Rn; + let Inst{22} = regs{8}; + let Inst{15-12} = regs{12-9}; + let Inst{7-0} = regs{7-0}; + // TODO: Mark the instructions with the appropriate subtarget info. let Inst{27-25} = 0b110; let Inst{11-9} = 0b101; diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 273ca991d29..cbb41021ddb 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -661,13 +661,34 @@ getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, unsigned ARMMCCodeEmitter:: getRegisterListOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl &Fixups) const { - // Convert a list of GPRs into a bitfield (R0 -> bit 0). For each - // register in the list, set the corresponding bit. + // VLDM/VSTM: + // {12-8} = Vd + // {7-0} = Number of registers + // + // LDM/STM: + // {15-0} = Bitfield of GPRs. + unsigned Reg = MI.getOperand(Op).getReg(); + bool SPRRegs = ARM::SPRRegClass.contains(Reg); + bool DPRRegs = ARM::DPRRegClass.contains(Reg); + unsigned Binary = 0; - for (unsigned i = Op, e = MI.getNumOperands(); i < e; ++i) { - unsigned regno = getARMRegisterNumbering(MI.getOperand(i).getReg()); - Binary |= 1 << regno; + + if (SPRRegs || DPRRegs) { + // VLDM/VSTM + unsigned RegNo = getARMRegisterNumbering(Reg); + unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff; + Binary |= (RegNo & 0x1f) << 8; + if (SPRRegs) + Binary |= NumRegs; + else + Binary |= NumRegs * 2; + } else { + for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { + unsigned RegNo = getARMRegisterNumbering(MI.getOperand(I).getReg()); + Binary |= 1 << RegNo; + } } + return Binary; } -- 2.34.1