diff options
author | Bob Wilson <bob.wilson@apple.com> | 2010-06-11 21:34:50 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2010-06-11 21:34:50 +0000 |
commit | 1a913ed17875d1a0fb490e1266b74c057c76a94b (patch) | |
tree | a648092b732097f3b77b9ae0ec492beb091493f6 /lib/Target/ARM/ARMCodeEmitter.cpp | |
parent | 215aa15a0d0df75af8d9cef6ef49026dcc3258a8 (diff) | |
download | external_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.cpp | 34 |
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" |