aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2010-11-17 00:45:23 +0000
committerBill Wendling <isanbard@gmail.com>2010-11-17 00:45:23 +0000
commit6bc105a7b9282a0b5beb9d06267b31a3054fb3fa (patch)
treee69e323d520d42ad3d23b03720d68522426858d9
parentb1a33c4a598d67a9b911bb3b45b379e36fb9396c (diff)
downloadexternal_llvm-6bc105a7b9282a0b5beb9d06267b31a3054fb3fa.zip
external_llvm-6bc105a7b9282a0b5beb9d06267b31a3054fb3fa.tar.gz
external_llvm-6bc105a7b9282a0b5beb9d06267b31a3054fb3fa.tar.bz2
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
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td24
-rw-r--r--lib/Target/ARM/ARMMCCodeEmitter.cpp31
2 files changed, 49 insertions, 6 deletions
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 4abb567..6308bc5 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -1125,7 +1125,7 @@ class T1DataProcessing<bits<4> opcode> : Encoding16 {
// A6.2.3 Special data instructions and branch and exchange encoding.
class T1Special<bits<4> 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<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
IndexMode im, Format f, InstrItinClass itin,
string asm, string cstr, list<dag> pattern>
: InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
+ bits<4> p;
+ let Inst{31-28} = p;
let OutOperandList = oops;
let InOperandList = iops;
let AsmString = asm;
@@ -1399,6 +1401,16 @@ class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
string asm, string cstr, list<dag> pattern>
: VFPXI<oops, iops, AddrMode4, Size4Bytes, im,
VFPLdStMulFrm, itin, asm, cstr, pattern> {
+ // 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<dag oops, dag iops, IndexMode im, InstrItinClass itin,
string asm, string cstr, list<dag> pattern>
: VFPXI<oops, iops, AddrMode4, Size4Bytes, im,
VFPLdStMulFrm, itin, asm, cstr, pattern> {
+ // 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 273ca99..cbb4102 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<MCFixup> &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;
}