aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2010-06-25 22:40:46 +0000
committerBob Wilson <bob.wilson@apple.com>2010-06-25 22:40:46 +0000
commit5e7b607f725e5c07aacd1d0cfe5fefb6b3900ae2 (patch)
tree2ed0de1a9793ba8ab0d804956772cd1ece60e939
parent3e3f15bb09eaca4d259e531c9a1ecafb5710b57b (diff)
Add support for encoding 3-register NEON instructions, and fix
emitNEON2RegInstruction's handling of 2-address operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106900 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp39
1 files changed, 36 insertions, 3 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 0269afa3d4..7f3c5d80f1 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -141,6 +141,7 @@ namespace {
void emitNEON1RegModImmInstruction(const MachineInstr &MI);
void emitNEON2RegInstruction(const MachineInstr &MI);
+ void emitNEON3RegInstruction(const MachineInstr &MI);
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
@@ -418,6 +419,9 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
case ARMII::N2RegFrm:
emitNEON2RegInstruction(MI);
break;
+ case ARMII::N3RegFrm:
+ emitNEON3RegInstruction(MI);
+ break;
}
MCE.processDebugLoc(MI.getDebugLoc(), false);
}
@@ -1559,6 +1563,15 @@ static unsigned encodeNEONRd(const MachineInstr &MI, unsigned OpIdx) {
return Binary;
}
+static unsigned encodeNEONRn(const MachineInstr &MI, unsigned OpIdx) {
+ unsigned RegN = MI.getOperand(OpIdx).getReg();
+ unsigned Binary = 0;
+ RegN = ARMRegisterInfo::getRegisterNumbering(RegN);
+ Binary |= (RegN & 0xf) << ARMII::RegRnShift;
+ Binary |= ((RegN >> 4) & 1) << ARMII::N_BitShift;
+ return Binary;
+}
+
static unsigned encodeNEONRm(const MachineInstr &MI, unsigned OpIdx) {
unsigned RegM = MI.getOperand(OpIdx).getReg();
unsigned Binary = 0;
@@ -1588,12 +1601,32 @@ void ARMCodeEmitter::emitNEON1RegModImmInstruction(const MachineInstr &MI) {
}
void ARMCodeEmitter::emitNEON2RegInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
unsigned Binary = getBinaryCodeForInstr(MI);
- // Destination register is encoded in Dd.
- Binary |= encodeNEONRd(MI, 0);
- Binary |= encodeNEONRm(MI, 1);
+ // Destination register is encoded in Dd; source register in Dm.
+ unsigned OpIdx = 0;
+ Binary |= encodeNEONRd(MI, OpIdx++);
+ if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
+ ++OpIdx;
+ Binary |= encodeNEONRm(MI, OpIdx);
// FIXME: This does not handle VDUPfdf or VDUPfqf.
emitWordLE(Binary);
}
+void ARMCodeEmitter::emitNEON3RegInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+ unsigned Binary = getBinaryCodeForInstr(MI);
+ // Destination register is encoded in Dd; source registers in Dn and Dm.
+ unsigned OpIdx = 0;
+ Binary |= encodeNEONRd(MI, OpIdx++);
+ if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
+ ++OpIdx;
+ Binary |= encodeNEONRn(MI, OpIdx++);
+ if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
+ ++OpIdx;
+ Binary |= encodeNEONRm(MI, OpIdx);
+ // FIXME: This does not handle VMOVDneon or VMOVQ.
+ emitWordLE(Binary);
+}
+
#include "ARMGenCodeEmitter.inc"