summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2010-06-26 04:07:15 +0000
committerBob Wilson <bob.wilson@apple.com>2010-06-26 04:07:15 +0000
commit0248da9db42bcd4d4039b7af12e40c99702e184b (patch)
treedb23431a9762aa3f96f738c576044a1353125713
parentf4db33cbdf5a9db87b988008b4f23e5312bb3496 (diff)
Add support for encoding NEON VMOV (from scalar to core register) instructions.
llvm-svn: 106938
-rw-r--r--llvm/lib/Target/ARM/ARMCodeEmitter.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp
index 7f3c5d80f1e5..49e83c3f8a96 100644
--- a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/llvm/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.