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.

llvm-svn: 107167
This commit is contained in:
Bob Wilson 2010-06-29 17:34:07 +00:00
parent 21a9433e9e
commit ab0819e10d
1 changed files with 19 additions and 6 deletions

View File

@ -140,7 +140,7 @@ namespace {
void emitMiscInstruction(const MachineInstr &MI); void emitMiscInstruction(const MachineInstr &MI);
void emitNEONGetLaneInstruction(const MachineInstr &MI); void emitNEONLaneInstruction(const MachineInstr &MI);
void emitNEON1RegModImmInstruction(const MachineInstr &MI); void emitNEON1RegModImmInstruction(const MachineInstr &MI);
void emitNEON2RegInstruction(const MachineInstr &MI); void emitNEON2RegInstruction(const MachineInstr &MI);
void emitNEON3RegInstruction(const MachineInstr &MI); void emitNEON3RegInstruction(const MachineInstr &MI);
@ -417,7 +417,8 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
break; break;
// NEON instructions. // NEON instructions.
case ARMII::NGetLnFrm: case ARMII::NGetLnFrm:
emitNEONGetLaneInstruction(MI); case ARMII::NSetLnFrm:
emitNEONLaneInstruction(MI);
break; break;
case ARMII::N1RegModImmFrm: case ARMII::N1RegModImmFrm:
emitNEON1RegModImmInstruction(MI); emitNEON1RegModImmInstruction(MI);
@ -1596,16 +1597,28 @@ static unsigned convertNEONDataProcToThumb(unsigned Binary) {
return 0xef000000 | (UBit << 28) | (Binary & 0xffffff); return 0xef000000 | (UBit << 28) | (Binary & 0xffffff);
} }
void ARMCodeEmitter::emitNEONGetLaneInstruction(const MachineInstr &MI) { void ARMCodeEmitter::emitNEONLaneInstruction(const MachineInstr &MI) {
unsigned Binary = getBinaryCodeForInstr(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 // Set the conditional execution predicate
Binary |= (IsThumb ? ARMCC::AL : II->getPredicate(&MI)) << ARMII::CondShift; 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); RegT = ARMRegisterInfo::getRegisterNumbering(RegT);
Binary |= (RegT << ARMII::RegRdShift); Binary |= (RegT << ARMII::RegRdShift);
Binary |= encodeNEONRn(MI, 1); Binary |= encodeNEONRn(MI, RegNOpIdx);
unsigned LaneShift; unsigned LaneShift;
if ((Binary & (1 << 22)) != 0) if ((Binary & (1 << 22)) != 0)
@ -1615,7 +1628,7 @@ void ARMCodeEmitter::emitNEONGetLaneInstruction(const MachineInstr &MI) {
else else
LaneShift = 2; // 32-bit elements LaneShift = 2; // 32-bit elements
unsigned Lane = MI.getOperand(2).getImm() << LaneShift; unsigned Lane = MI.getOperand(LnOpIdx).getImm() << LaneShift;
unsigned Opc1 = Lane >> 2; unsigned Opc1 = Lane >> 2;
unsigned Opc2 = Lane & 3; unsigned Opc2 = Lane & 3;
assert((Opc1 & 3) == 0 && "out-of-range lane number operand"); assert((Opc1 & 3) == 0 && "out-of-range lane number operand");