From 52e4a0a074b758ad3dbf6841b249aaf3baf08f28 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Sat, 26 Jun 2010 04:07:15 +0000 Subject: [PATCH] Add support for encoding NEON VMOV (from scalar to core register) instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106938 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMCodeEmitter.cpp | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 7f3c5d80f1e..49e83c3f8a9 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -139,6 +139,7 @@ namespace { void emitMiscInstruction(const MachineInstr &MI); + void emitNEONGetLaneInstruction(const MachineInstr &MI); void emitNEON1RegModImmInstruction(const MachineInstr &MI); void emitNEON2RegInstruction(const MachineInstr &MI); void emitNEON3RegInstruction(const MachineInstr &MI); @@ -413,6 +414,9 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) { emitMiscInstruction(MI); break; // NEON instructions. + case ARMII::NGetLnFrm: + emitNEONGetLaneInstruction(MI); + break; case ARMII::N1RegModImmFrm: emitNEON1RegModImmInstruction(MI); break; @@ -1581,6 +1585,35 @@ static unsigned encodeNEONRm(const MachineInstr &MI, unsigned OpIdx) { return Binary; } +void ARMCodeEmitter::emitNEONGetLaneInstruction(const MachineInstr &MI) { + unsigned Binary = getBinaryCodeForInstr(MI); + + // Set the conditional execution predicate + Binary |= II->getPredicate(&MI) << ARMII::CondShift; + + unsigned RegT = MI.getOperand(0).getReg(); + RegT = ARMRegisterInfo::getRegisterNumbering(RegT); + Binary |= (RegT << ARMII::RegRdShift); + Binary |= encodeNEONRn(MI, 1); + + unsigned LaneShift; + if ((Binary & (1 << 22)) != 0) + LaneShift = 0; // 8-bit elements + else if ((Binary & (1 << 5)) != 0) + LaneShift = 1; // 16-bit elements + else + LaneShift = 2; // 32-bit elements + + unsigned Lane = MI.getOperand(2).getImm() << LaneShift; + unsigned Opc1 = Lane >> 2; + unsigned Opc2 = Lane & 3; + assert((Opc1 & 3) == 0 && "out-of-range lane number operand"); + Binary |= (Opc1 << 21); + Binary |= (Opc2 << 5); + + emitWordLE(Binary); +} + void ARMCodeEmitter::emitNEON1RegModImmInstruction(const MachineInstr &MI) { unsigned Binary = getBinaryCodeForInstr(MI); // Destination register is encoded in Dd. -- 2.34.1