summaryrefslogtreecommitdiffstats
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
commit1a913ed17875d1a0fb490e1266b74c057c76a94b (patch)
treea648092b732097f3b77b9ae0ec492beb091493f6 /lib/Target/ARM/ARMCodeEmitter.cpp
parent215aa15a0d0df75af8d9cef6ef49026dcc3258a8 (diff)
downloadexternal_llvm-1a913ed17875d1a0fb490e1266b74c057c76a94b.zip
external_llvm-1a913ed17875d1a0fb490e1266b74c057c76a94b.tar.gz
external_llvm-1a913ed17875d1a0fb490e1266b74c057c76a94b.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"