From a956255ebf51a48b8528b520eafcdfb5f1049a28 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 14 Nov 2008 20:09:11 +0000 Subject: [PATCH] Fix MOVrx, MOVsrl_flag, and MOVsra_flag encodings. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59314 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMCodeEmitter.cpp | 50 ++++++++++++++++++++++++++++++- lib/Target/ARM/ARMInstrInfo.td | 6 ++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 4d87efed8b7..4bc50ff6ca3 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -83,6 +83,8 @@ namespace { void emitLEApcrelJTInstruction(const MachineInstr &MI); + void emitPseudoMoveInstruction(const MachineInstr &MI); + void addPCLabel(unsigned LabelID); void emitPseudoInstruction(const MachineInstr &MI); @@ -499,6 +501,45 @@ void ARMCodeEmitter::emitLEApcrelJTInstruction(const MachineInstr &MI) { emitWordLE(Binary); } +void ARMCodeEmitter::emitPseudoMoveInstruction(const MachineInstr &MI) { + unsigned Opcode = MI.getDesc().Opcode; + + // Part of binary is determined by TableGn. + unsigned Binary = getBinaryCodeForInstr(MI); + + // Set the conditional execution predicate + Binary |= II->getPredicate(&MI) << ARMII::CondShift; + + // Encode S bit if MI modifies CPSR. + if (Opcode == ARM::MOVsrl_flag || Opcode == ARM::MOVsra_flag) + Binary |= 1 << ARMII::S_BitShift; + + // Encode register def if there is one. + Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift; + + // Encode the shift operation. + switch (Opcode) { + default: break; + case ARM::MOVrx: + // rrx + Binary |= 0x6 << 4; + break; + case ARM::MOVsrl_flag: + // lsr #1 + Binary |= (0x2 << 4) | (1 << 7); + break; + case ARM::MOVsra_flag: + // asr #1 + Binary |= (0x4 << 4) | (1 << 7); + break; + } + + // Encode register Rm. + Binary |= getMachineOpValue(MI, 1); + + emitWordLE(Binary); +} + void ARMCodeEmitter::addPCLabel(unsigned LabelID) { DOUT << " ** LPC" << LabelID << " @ " << (void*)MCE.getCurrentPCValue() << '\n'; @@ -564,6 +605,11 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) { // Materialize jumptable address. emitLEApcrelJTInstruction(MI); break; + case ARM::MOVrx: + case ARM::MOVsrl_flag: + case ARM::MOVsra_flag: + emitPseudoMoveInstruction(MI); + break; } } @@ -638,7 +684,9 @@ unsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) { unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI, const TargetInstrDesc &TID) const { - for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){ + unsigned e = TID.getNumOperands(); + if (e) --e; // Looks at the last non-implicit operand as well. + for (unsigned i = MI.getNumOperands(); i != e; --i) { const MachineOperand &MO = MI.getOperand(i-1); if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) return 1 << ARMII::S_BitShift; diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index a437ca7b14c..dd39fd6ec69 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -777,7 +777,7 @@ let isReMaterializable = 1 in def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP; -def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, +def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, "mov", " $dst, $src, rrx", [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP; @@ -785,10 +785,10 @@ def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, // due to flag operands. let Defs = [CPSR] in { -def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, +def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, "mov", "s $dst, $src, lsr #1", [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP; -def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, +def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, "mov", "s $dst, $src, asr #1", [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP; } -- 2.34.1