aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2010-06-29 17:34:07 +0000
committerBob Wilson <bob.wilson@apple.com>2010-06-29 17:34:07 +0000
commitd5a563de07b7479c6c69b35a81d48bb8002580fb (patch)
tree55b5aea90e222777650c7cd13ba240e310d5b6f2
parentea86423cbd3cc71a2ee2d261c25ab6c0eea0c7e0 (diff)
Add support for encoding NEON VMOV (from core register to scalar) instructions.
The encoding is the same as VMOV (from scalar to core register) except that the operands are in different places. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107167 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp25
1 files changed, 19 insertions, 6 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index f26074d358..2c8939fdf0 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -140,7 +140,7 @@ namespace {
void emitMiscInstruction(const MachineInstr &MI);
- void emitNEONGetLaneInstruction(const MachineInstr &MI);
+ void emitNEONLaneInstruction(const MachineInstr &MI);
void emitNEON1RegModImmInstruction(const MachineInstr &MI);
void emitNEON2RegInstruction(const MachineInstr &MI);
void emitNEON3RegInstruction(const MachineInstr &MI);
@@ -417,7 +417,8 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
break;
// NEON instructions.
case ARMII::NGetLnFrm:
- emitNEONGetLaneInstruction(MI);
+ case ARMII::NSetLnFrm:
+ emitNEONLaneInstruction(MI);
break;
case ARMII::N1RegModImmFrm:
emitNEON1RegModImmInstruction(MI);
@@ -1596,16 +1597,28 @@ static unsigned convertNEONDataProcToThumb(unsigned Binary) {
return 0xef000000 | (UBit << 28) | (Binary & 0xffffff);
}
-void ARMCodeEmitter::emitNEONGetLaneInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitNEONLaneInstruction(const MachineInstr &MI) {
unsigned Binary = getBinaryCodeForInstr(MI);
+ unsigned RegTOpIdx, RegNOpIdx, LnOpIdx;
+ const TargetInstrDesc &TID = MI.getDesc();
+ if ((TID.TSFlags & ARMII::FormMask) == ARMII::NGetLnFrm) {
+ RegTOpIdx = 0;
+ RegNOpIdx = 1;
+ LnOpIdx = 2;
+ } else { // ARMII::NSetLnFrm
+ RegTOpIdx = 2;
+ RegNOpIdx = 0;
+ LnOpIdx = 3;
+ }
+
// Set the conditional execution predicate
Binary |= (IsThumb ? ARMCC::AL : II->getPredicate(&MI)) << ARMII::CondShift;
- unsigned RegT = MI.getOperand(0).getReg();
+ unsigned RegT = MI.getOperand(RegTOpIdx).getReg();
RegT = ARMRegisterInfo::getRegisterNumbering(RegT);
Binary |= (RegT << ARMII::RegRdShift);
- Binary |= encodeNEONRn(MI, 1);
+ Binary |= encodeNEONRn(MI, RegNOpIdx);
unsigned LaneShift;
if ((Binary & (1 << 22)) != 0)
@@ -1615,7 +1628,7 @@ void ARMCodeEmitter::emitNEONGetLaneInstruction(const MachineInstr &MI) {
else
LaneShift = 2; // 32-bit elements
- unsigned Lane = MI.getOperand(2).getImm() << LaneShift;
+ unsigned Lane = MI.getOperand(LnOpIdx).getImm() << LaneShift;
unsigned Opc1 = Lane >> 2;
unsigned Opc2 = Lane & 3;
assert((Opc1 & 3) == 0 && "out-of-range lane number operand");