[llvm-commits] [llvm] r59084 - in /llvm/trunk/lib/Target/ARM: ARMCodeEmitter.cpp ARMInstrFormats.td ARMInstrInfo.h ARMInstrVFP.td
Evan Cheng
evan.cheng at apple.com
Tue Nov 11 13:48:48 PST 2008
Author: evancheng
Date: Tue Nov 11 15:48:44 2008
New Revision: 59084
URL: http://llvm.org/viewvc/llvm-project?rev=59084&view=rev
Log:
Encode VFP load / store instructions.
Modified:
llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
llvm/trunk/lib/Target/ARM/ARMInstrInfo.h
llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=59084&r1=59083&r2=59084&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue Nov 11 15:48:44 2008
@@ -124,6 +124,12 @@
void emitVFPConversionInstruction(const MachineInstr &MI);
+ void emitVFPLoadStoreInstruction(const MachineInstr &MI);
+
+ void emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI);
+
+ void emitMiscInstruction(const MachineInstr &MI);
+
/// getBinaryCodeForInstr - This function, generated by the
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
/// machine instructions.
@@ -326,6 +332,15 @@
case ARMII::VFPConv2Frm:
emitVFPConversionInstruction(MI);
break;
+ case ARMII::VFPLdStFrm:
+ emitVFPLoadStoreInstruction(MI);
+ break;
+ case ARMII::VFPLdStMulFrm:
+ emitVFPLoadStoreMultipleInstruction(MI);
+ break;
+ case ARMII::VFPMiscFrm:
+ emitMiscInstruction(MI);
+ break;
}
}
@@ -759,23 +774,14 @@
emitWordLE(Binary);
}
-void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
- // Part of binary is determined by TableGn.
- unsigned Binary = getBinaryCodeForInstr(MI);
-
- // Set the conditional execution predicate
- Binary |= II->getPredicate(&MI) << ARMII::CondShift;
-
- // Set first operand
- Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
+static unsigned getAddrModeUPBits(unsigned Mode) {
+ unsigned Binary = 0;
// Set addressing mode by modifying bits U(23) and P(24)
// IA - Increment after - bit U = 1 and bit P = 0
// IB - Increment before - bit U = 1 and bit P = 1
// DA - Decrement after - bit U = 0 and bit P = 0
// DB - Decrement before - bit U = 0 and bit P = 1
- const MachineOperand &MO = MI.getOperand(1);
- ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO.getImm());
switch (Mode) {
default: assert(0 && "Unknown addressing sub-mode!");
case ARM_AM::da: break;
@@ -784,6 +790,23 @@
case ARM_AM::ib: Binary |= 0x3 << ARMII::U_BitShift; break;
}
+ return Binary;
+}
+
+void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
+ // Set the conditional execution predicate
+ Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+ // Set base address operand
+ Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
+
+ // Set addressing mode by modifying bits U(23) and P(24)
+ const MachineOperand &MO = MI.getOperand(1);
+ Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(MO.getImm()));
+
// Set bit W(21)
if (ARM_AM::getAM4WBFlag(MO.getImm()))
Binary |= 0x1 << ARMII::W_BitShift;
@@ -791,8 +814,8 @@
// Set registers
for (unsigned i = 4, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
- if (MO.isReg() && MO.isImplicit())
- continue;
+ if (!MO.isReg() || MO.isImplicit())
+ break;
unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(MO.getReg());
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
RegNum < 16);
@@ -1064,4 +1087,87 @@
emitWordLE(Binary);
}
+void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
+ // Set the conditional execution predicate
+ Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+ unsigned OpIdx = 0;
+
+ // Encode Dd / Sd.
+ unsigned RegD = getMachineOpValue(MI, OpIdx++);
+ Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
+ Binary |= (RegD & 0x10) << ARMII::D_BitShift;
+
+ // Encode address base.
+ const MachineOperand &Base = MI.getOperand(OpIdx++);
+ Binary |= getMachineOpValue(MI, Base) << ARMII::RegRnShift;
+
+ // If there is a non-zero immediate offset, encode it.
+ if (Base.isReg()) {
+ const MachineOperand &Offset = MI.getOperand(OpIdx);
+ if (unsigned ImmOffs = ARM_AM::getAM5Offset(Offset.getImm())) {
+ if (ARM_AM::getAM5Op(Offset.getImm()) == ARM_AM::add)
+ Binary |= 1 << ARMII::U_BitShift;
+ // Immediate offset is multiplied by 4.
+ Binary |= ImmOffs >> 2;
+ emitWordLE(Binary);
+ return;
+ }
+ }
+
+ // If immediate offset is omitted, default to +0.
+ Binary |= 1 << ARMII::U_BitShift;
+
+ emitWordLE(Binary);
+}
+
+void
+ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI) {
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
+ // Set the conditional execution predicate
+ Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+ // Set base address operand
+ Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
+
+ // Set addressing mode by modifying bits U(23) and P(24)
+ const MachineOperand &MO = MI.getOperand(1);
+ Binary |= getAddrModeUPBits(ARM_AM::getAM5SubMode(MO.getImm()));
+
+ // Set bit W(21)
+ if (ARM_AM::getAM5WBFlag(MO.getImm()))
+ Binary |= 0x1 << ARMII::W_BitShift;
+
+ // First register is encoded in Dd.
+ unsigned FirstReg = MI.getOperand(4).getReg();
+ Binary |= ARMRegisterInfo::getRegisterNumbering(FirstReg)<< ARMII::RegRdShift;
+
+ // Number of registers are encoded in offset field.
+ unsigned NumRegs = 1;
+ for (unsigned i = 5, e = MI.getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI.getOperand(i);
+ if (!MO.isReg() || MO.isImplicit())
+ break;
+ ++NumRegs;
+ }
+ Binary |= NumRegs * 2;
+
+ emitWordLE(Binary);
+}
+
+void ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) {
+ // Part of binary is determined by TableGn.
+ unsigned Binary = getBinaryCodeForInstr(MI);
+
+ // Set the conditional execution predicate
+ Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+ emitWordLE(Binary);
+}
+
#include "ARMGenCodeEmitter.inc"
Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=59084&r1=59083&r2=59084&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Tue Nov 11 15:48:44 2008
@@ -19,29 +19,33 @@
bits<5> Value = val;
}
-def Pseudo : Format<1>;
-def MulFrm : Format<2>;
-def BrFrm : Format<3>;
-def BrMiscFrm : Format<4>;
-
-def DPFrm : Format<5>;
-def DPSoRegFrm : Format<6>;
-
-def LdFrm : Format<7>;
-def StFrm : Format<8>;
-def LdMiscFrm : Format<9>;
-def StMiscFrm : Format<10>;
-def LdMulFrm : Format<11>;
-def StMulFrm : Format<12>;
-
-def ArithMiscFrm: Format<13>;
-def ExtFrm : Format<14>;
-def VFPFrm : Format<15>;
-def VFPUnaryFrm : Format<16>;
-def VFPBinaryFrm: Format<17>;
-def VFPConv1Frm : Format<18>;
-def VFPConv2Frm : Format<19>;
-def ThumbFrm : Format<20>;
+def Pseudo : Format<1>;
+def MulFrm : Format<2>;
+def BrFrm : Format<3>;
+def BrMiscFrm : Format<4>;
+
+def DPFrm : Format<5>;
+def DPSoRegFrm : Format<6>;
+
+def LdFrm : Format<7>;
+def StFrm : Format<8>;
+def LdMiscFrm : Format<9>;
+def StMiscFrm : Format<10>;
+def LdMulFrm : Format<11>;
+def StMulFrm : Format<12>;
+
+def ArithMiscFrm : Format<13>;
+def ExtFrm : Format<14>;
+
+def VFPUnaryFrm : Format<15>;
+def VFPBinaryFrm : Format<16>;
+def VFPConv1Frm : Format<17>;
+def VFPConv2Frm : Format<18>;
+def VFPLdStFrm : Format<19>;
+def VFPLdStMulFrm : Format<20>;
+def VFPMiscFrm : Format<21>;
+
+def ThumbFrm : Format<22>;
// Misc flag for data processing instructions that indicates whether
// the instruction has a Rn register operand.
@@ -738,30 +742,45 @@
// ARM VFP Instruction templates.
//
-// ARM Float Instruction
-class ASI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
- : AI<oops, iops, VFPFrm, opc, asm, pattern> {
+// ARM VFP addrmode5 loads and stores
+class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
+ string opc, string asm, list<dag> pattern>
+ : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
+ VFPLdStFrm, opc, asm, "", pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
+ let Inst{27-24} = opcod1;
+ let Inst{21-20} = opcod2;
+ let Inst{11-8} = 0b1011;
}
-class ASI5<dag oops, dag iops, string opc, string asm, list<dag> pattern>
+class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
+ string opc, string asm, list<dag> pattern>
: I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
- VFPFrm, opc, asm, "", pattern> {
+ VFPLdStFrm, opc, asm, "", pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
+ let Inst{27-24} = opcod1;
+ let Inst{21-20} = opcod2;
+ let Inst{11-8} = 0b1010;
}
-// ARM Double Instruction
-class ADI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
- : AI<oops, iops, VFPFrm, opc, asm, pattern> {
+// Load / store multiple
+class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
+ : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
+ VFPLdStMulFrm, asm, "", pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
+ let Inst{27-25} = 0b110;
+ let Inst{11-8} = 0b1011;
}
-class ADI5<dag oops, dag iops, string opc, string asm, list<dag> pattern>
- : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
- VFPFrm, opc, asm, "", pattern> {
+class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
+ : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
+ VFPLdStMulFrm, asm, "", pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
+ let Inst{27-25} = 0b110;
+ let Inst{11-8} = 0b1010;
}
+
// Double precision, unary
class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
string opc, string asm, list<dag> pattern>
@@ -817,32 +836,6 @@
let Inst{6} = 1;
}
-// Special cases.
-class AXSI<dag oops, dag iops, string asm, list<dag> pattern>
- : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone,
- VFPFrm, asm, "", pattern> {
- // TODO: Mark the instructions with the appropriate subtarget info.
-}
-
-class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
- : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
- VFPFrm, asm, "", pattern> {
- // TODO: Mark the instructions with the appropriate subtarget info.
-}
-
-class AXDI<dag oops, dag iops, string asm, list<dag> pattern>
- : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone,
- VFPFrm, asm, "", pattern> {
- // TODO: Mark the instructions with the appropriate subtarget info.
-}
-
-class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
- : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
- VFPFrm, asm, "", pattern> {
- // TODO: Mark the instructions with the appropriate subtarget info.
-}
-
-
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.h?rev=59084&r1=59083&r2=59084&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.h Tue Nov 11 15:48:44 2008
@@ -69,46 +69,48 @@
//===------------------------------------------------------------------===//
// Instruction encoding formats.
//
- FormShift = 10,
- FormMask = 0x1f << FormShift,
+ FormShift = 10,
+ FormMask = 0x1f << FormShift,
// Pseudo instructions
- Pseudo = 1 << FormShift,
+ Pseudo = 1 << FormShift,
// Multiply instructions
- MulFrm = 2 << FormShift,
+ MulFrm = 2 << FormShift,
// Branch instructions
- BrFrm = 3 << FormShift,
- BrMiscFrm = 4 << FormShift,
+ BrFrm = 3 << FormShift,
+ BrMiscFrm = 4 << FormShift,
// Data Processing instructions
- DPFrm = 5 << FormShift,
- DPSoRegFrm = 6 << FormShift,
+ DPFrm = 5 << FormShift,
+ DPSoRegFrm = 6 << FormShift,
// Load and Store
- LdFrm = 7 << FormShift,
- StFrm = 8 << FormShift,
- LdMiscFrm = 9 << FormShift,
- StMiscFrm = 10 << FormShift,
- LdMulFrm = 11 << FormShift,
- StMulFrm = 12 << FormShift,
+ LdFrm = 7 << FormShift,
+ StFrm = 8 << FormShift,
+ LdMiscFrm = 9 << FormShift,
+ StMiscFrm = 10 << FormShift,
+ LdMulFrm = 11 << FormShift,
+ StMulFrm = 12 << FormShift,
// Miscellaneous arithmetic instructions
- ArithMiscFrm= 13 << FormShift,
+ ArithMiscFrm = 13 << FormShift,
// Extend instructions
- ExtFrm = 14 << FormShift,
+ ExtFrm = 14 << FormShift,
// VFP formats
- VPFFrm = 15 << FormShift,
- VFPUnaryFrm = 16 << FormShift,
- VFPBinaryFrm = 17 << FormShift,
- VFPConv1Frm = 18 << FormShift,
- VFPConv2Frm = 19 << FormShift,
+ VFPUnaryFrm = 15 << FormShift,
+ VFPBinaryFrm = 16 << FormShift,
+ VFPConv1Frm = 17 << FormShift,
+ VFPConv2Frm = 18 << FormShift,
+ VFPLdStFrm = 19 << FormShift,
+ VFPLdStMulFrm = 20 << FormShift,
+ VFPMiscFrm = 21 << FormShift,
// Thumb format
- ThumbFrm = 20 << FormShift,
+ ThumbFrm = 22 << FormShift,
//===------------------------------------------------------------------===//
// Field shifts - such shifts are used to set field while generating
Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=59084&r1=59083&r2=59084&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Tue Nov 11 15:48:44 2008
@@ -35,20 +35,20 @@
//
let isSimpleLoad = 1 in {
-def FLDD : ADI5<(outs DPR:$dst), (ins addrmode5:$addr),
+def FLDD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr),
"fldd", " $dst, $addr",
[(set DPR:$dst, (load addrmode5:$addr))]>;
-def FLDS : ASI5<(outs SPR:$dst), (ins addrmode5:$addr),
+def FLDS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
"flds", " $dst, $addr",
[(set SPR:$dst, (load addrmode5:$addr))]>;
} // isSimpleLoad
-def FSTD : ADI5<(outs), (ins DPR:$src, addrmode5:$addr),
+def FSTD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
"fstd", " $src, $addr",
[(store DPR:$src, addrmode5:$addr)]>;
-def FSTS : ASI5<(outs), (ins SPR:$src, addrmode5:$addr),
+def FSTS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
"fsts", " $src, $addr",
[(store SPR:$src, addrmode5:$addr)]>;
@@ -60,24 +60,32 @@
def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
variable_ops),
"fldm${addr:submode}d${p} ${addr:base}, $dst1",
- []>;
+ []> {
+ let Inst{20} = 1;
+}
def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
variable_ops),
"fldm${addr:submode}s${p} ${addr:base}, $dst1",
- []>;
+ []> {
+ let Inst{20} = 1;
+}
}
let mayStore = 1 in {
def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
variable_ops),
"fstm${addr:submode}d${p} ${addr:base}, $src1",
- []>;
+ []> {
+ let Inst{20} = 0;
+}
def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
variable_ops),
"fstm${addr:submode}s${p} ${addr:base}, $src1",
- []>;
+ []> {
+ let Inst{20} = 0;
+}
} // mayStore
// FLDMX, FSTMX - mixing S/D registers for pre-armv6 cores
@@ -384,4 +392,11 @@
//
let Defs = [CPSR] in
-def FMSTAT : ASI<(outs), (ins), "fmstat", "", [(arm_fmstat)]>;
+def FMSTAT : AI<(outs), (ins), VFPMiscFrm, "fmstat", "", [(arm_fmstat)]> {
+ let Inst{27-20} = 0b11101111;
+ let Inst{19-16} = 0b0001;
+ let Inst{15-12} = 0b1111;
+ let Inst{11-8} = 0b1010;
+ let Inst{7} = 0;
+ let Inst{4} = 1;
+}
More information about the llvm-commits
mailing list