aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMCodeEmitter.cpp
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2010-06-11 21:34:50 +0000
committerBob Wilson <bob.wilson@apple.com>2010-06-11 21:34:50 +0000
commit73e9f2e91b86c25a1b908e7dc9a65c2d84339e81 (patch)
treea648092b732097f3b77b9ae0ec492beb091493f6 /lib/Target/ARM/ARMCodeEmitter.cpp
parentaa685d67d6746a64b517beb1b5c485e8285840d2 (diff)
downloadexternal_llvm-73e9f2e91b86c25a1b908e7dc9a65c2d84339e81.zip
external_llvm-73e9f2e91b86c25a1b908e7dc9a65c2d84339e81.tar.gz
external_llvm-73e9f2e91b86c25a1b908e7dc9a65c2d84339e81.tar.bz2
Add instruction encoding for the Neon VMOV immediate instruction. This changes
the machine instruction representation of the immediate value to be encoded into an integer with similar fields as the actual VMOV instruction. This makes things easier for the disassembler, since it can just stuff the bits into the immediate operand, but harder for the asm printer since it has to decode the value to be printed. Testcase for the encoding will follow later when MC has more support for ARM. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105836 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMCodeEmitter.cpp')
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 18de198..8344000 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -139,6 +139,8 @@ namespace {
void emitMiscInstruction(const MachineInstr &MI);
+ void emitNEON1RegModImm(const MachineInstr &MI);
+
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned getMachineOpValue(const MachineInstr &MI,const MachineOperand &MO);
@@ -408,6 +410,10 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
case ARMII::VFPMiscFrm:
emitMiscInstruction(MI);
break;
+ // NEON instructions.
+ case ARMII::N1RegModImmFrm:
+ emitNEON1RegModImm(MI);
+ break;
}
MCE.processDebugLoc(MI.getDebugLoc(), false);
}
@@ -1540,4 +1546,32 @@ void ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
+static unsigned encodeNEONRd(const MachineInstr &MI, unsigned OpIdx) {
+ unsigned RegD = MI.getOperand(OpIdx).getReg();
+ unsigned Binary = 0;
+ RegD = ARMRegisterInfo::getRegisterNumbering(RegD);
+ Binary |= (RegD & 0xf) << ARMII::RegRdShift;
+ Binary |= ((RegD >> 4) & 1) << ARMII::D_BitShift;
+ return Binary;
+}
+
+void ARMCodeEmitter::emitNEON1RegModImm(const MachineInstr &MI) {
+ unsigned Binary = getBinaryCodeForInstr(MI);
+ // Destination register is encoded in Dd.
+ Binary |= encodeNEONRd(MI, 0);
+ // Immediate fields: Op, Cmode, I, Imm3, Imm4
+ unsigned Imm = MI.getOperand(1).getImm();
+ unsigned Op = (Imm >> 12) & 1;
+ Binary |= (Op << 5);
+ unsigned Cmode = (Imm >> 8) & 0xf;
+ Binary |= (Cmode << 8);
+ unsigned I = (Imm >> 7) & 1;
+ Binary |= (I << 24);
+ unsigned Imm3 = (Imm >> 4) & 0x7;
+ Binary |= (Imm3 << 16);
+ unsigned Imm4 = Imm & 0xf;
+ Binary |= Imm4;
+ emitWordLE(Binary);
+}
+
#include "ARMGenCodeEmitter.inc"