aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/llvm/llvm2.7/r104587-MOVimm32.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/llvm/llvm2.7/r104587-MOVimm32.patch')
-rw-r--r--recipes/llvm/llvm2.7/r104587-MOVimm32.patch190
1 files changed, 190 insertions, 0 deletions
diff --git a/recipes/llvm/llvm2.7/r104587-MOVimm32.patch b/recipes/llvm/llvm2.7/r104587-MOVimm32.patch
new file mode 100644
index 0000000000..76cbfe8376
--- /dev/null
+++ b/recipes/llvm/llvm2.7/r104587-MOVimm32.patch
@@ -0,0 +1,190 @@
+Index: llvm2.7/lib/Target/ARM/ARMJITInfo.cpp
+===================================================================
+--- llvm2.7.org/lib/Target/ARM/ARMJITInfo.cpp (revision 104586)
++++ llvm2.7/lib/Target/ARM/ARMJITInfo.cpp (revision 104587)
+@@ -318,6 +318,18 @@
+ *((intptr_t*)RelocPos) |= ResultPtr;
+ break;
+ }
++ case ARM::reloc_arm_movw: {
++ ResultPtr = ResultPtr & 0xFFFF;
++ *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF;
++ *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16;
++ break;
+ }
++ case ARM::reloc_arm_movt: {
++ ResultPtr = (ResultPtr >> 16) & 0xFFFF;
++ *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF;
++ *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16;
++ break;
++ }
++ }
+ }
+ }
+Index: llvm2.7/lib/Target/ARM/ARMCodeEmitter.cpp
+===================================================================
+--- llvm2.7.org/lib/Target/ARM/ARMCodeEmitter.cpp (revision 104586)
++++ llvm2.7/lib/Target/ARM/ARMCodeEmitter.cpp (revision 104587)
+@@ -88,6 +88,7 @@
+ void emitWordLE(unsigned Binary);
+ void emitDWordLE(uint64_t Binary);
+ void emitConstPoolInstruction(const MachineInstr &MI);
++ void emitMOVi32immInstruction(const MachineInstr &MI);
+ void emitMOVi2piecesInstruction(const MachineInstr &MI);
+ void emitLEApcrelJTInstruction(const MachineInstr &MI);
+ void emitPseudoMoveInstruction(const MachineInstr &MI);
+@@ -145,6 +146,15 @@
+ return getMachineOpValue(MI, MI.getOperand(OpIdx));
+ }
+
++ /// getMovi32Value - Return binary encoding of operand for movw/movt. If the
++ /// machine operand requires relocation, record the relocation and return zero.
++ unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO,
++ unsigned Reloc);
++ unsigned getMovi32Value(const MachineInstr &MI, unsigned OpIdx,
++ unsigned Reloc) {
++ return getMovi32Value(MI, MI.getOperand(OpIdx), Reloc);
++ }
++
+ /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
+ ///
+ unsigned getShiftOp(unsigned Imm) const ;
+@@ -217,6 +227,31 @@
+ return 0;
+ }
+
++/// getMovi32Value - Return binary encoding of operand for movw/movt. If the
++/// machine operand requires relocation, record the relocation and return zero.
++unsigned ARMCodeEmitter::getMovi32Value(const MachineInstr &MI,
++ const MachineOperand &MO,
++ unsigned Reloc) {
++ assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw))
++ && "Relocation to this function should be for movt or movw");
++
++ if (MO.isImm())
++ return static_cast<unsigned>(MO.getImm());
++ else if (MO.isGlobal())
++ emitGlobalAddress(MO.getGlobal(), Reloc, true, false);
++ else if (MO.isSymbol())
++ emitExternalSymbolAddress(MO.getSymbolName(), Reloc);
++ else if (MO.isMBB())
++ emitMachineBasicBlock(MO.getMBB(), Reloc);
++ else {
++#ifndef NDEBUG
++ errs() << MO;
++#endif
++ llvm_unreachable("Unsupported operand type for movw/movt");
++ }
++ return 0;
++}
++
+ /// getMachineOpValue - Return binary encoding of operand. If the machine
+ /// operand requires relocation, record the relocation and return zero.
+ unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
+@@ -438,6 +473,42 @@
+ }
+ }
+
++void ARMCodeEmitter::emitMOVi32immInstruction(const MachineInstr &MI) {
++ const MachineOperand &MO0 = MI.getOperand(0);
++ const MachineOperand &MO1 = MI.getOperand(1);
++
++ // Emit the 'movw' instruction.
++ unsigned Binary = 0x30 << 20; // mov: Insts{27-20} = 0b00110000
++
++ unsigned Lo16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movw) & 0xFFFF;
++
++ // Set the conditional execution predicate.
++ Binary |= II->getPredicate(&MI) << ARMII::CondShift;
++
++ // Encode Rd.
++ Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
++
++ // Encode imm16 as imm4:imm12
++ Binary |= Lo16 & 0xFFF; // Insts{11-0} = imm12
++ Binary |= ((Lo16 >> 12) & 0xF) << 16; // Insts{19-16} = imm4
++ emitWordLE(Binary);
++
++ unsigned Hi16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movt) >> 16;
++ // Emit the 'movt' instruction.
++ Binary = 0x34 << 20; // movt: Insts{27-20} = 0b00110100
++
++ // Set the conditional execution predicate.
++ Binary |= II->getPredicate(&MI) << ARMII::CondShift;
++
++ // Encode Rd.
++ Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
++
++ // Encode imm16 as imm4:imm1, same as movw above.
++ Binary |= Hi16 & 0xFFF;
++ Binary |= ((Hi16 >> 12) & 0xF) << 16;
++ emitWordLE(Binary);
++}
++
+ void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
+ const MachineOperand &MO0 = MI.getOperand(0);
+ const MachineOperand &MO1 = MI.getOperand(1);
+@@ -557,7 +628,6 @@
+ switch (Opcode) {
+ default:
+ llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
+- // FIXME: Add support for MOVimm32.
+ case TargetOpcode::INLINEASM: {
+ // We allow inline assembler nodes with empty bodies - they can
+ // implicitly define registers, which is ok for JIT.
+@@ -604,6 +674,11 @@
+ emitMiscLoadStoreInstruction(MI, ARM::PC);
+ break;
+ }
++
++ case ARM::MOVi32imm:
++ emitMOVi32immInstruction(MI);
++ break;
++
+ case ARM::MOVi2pieces:
+ // Two instructions to materialize a constant.
+ emitMOVi2piecesInstruction(MI);
+@@ -729,6 +804,24 @@
+ Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd)
+ << ARMII::RegRdShift);
+
++ if (TID.Opcode == ARM::MOVi16) {
++ // Get immediate from MI.
++ unsigned Lo16 = getMovi32Value(MI, MI.getOperand(OpIdx),
++ ARM::reloc_arm_movw);
++ // Encode imm which is the same as in emitMOVi32immInstruction().
++ Binary |= Lo16 & 0xFFF;
++ Binary |= ((Lo16 >> 12) & 0xF) << 16;
++ emitWordLE(Binary);
++ return;
++ } else if(TID.Opcode == ARM::MOVTi16) {
++ unsigned Hi16 = (getMovi32Value(MI, MI.getOperand(OpIdx),
++ ARM::reloc_arm_movt) >> 16);
++ Binary |= Hi16 & 0xFFF;
++ Binary |= ((Hi16 >> 12) & 0xF) << 16;
++ emitWordLE(Binary);
++ return;
++ }
++
+ // If this is a two-address operand, skip it. e.g. MOVCCr operand 1.
+ if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
+ ++OpIdx;
+Index: llvm2.7/lib/Target/ARM/ARMRelocations.h
+===================================================================
+--- llvm2.7.org/lib/Target/ARM/ARMRelocations.h (revision 104586)
++++ llvm2.7/lib/Target/ARM/ARMRelocations.h (revision 104587)
+@@ -47,7 +47,13 @@
+ reloc_arm_pic_jt,
+
+ // reloc_arm_branch - Branch address relocation.
+- reloc_arm_branch
++ reloc_arm_branch,
++
++ // reloc_arm_movt - MOVT immediate relocation.
++ reloc_arm_movt,
++
++ // reloc_arm_movw - MOVW immediate relocation.
++ reloc_arm_movw
+ };
+ }
+ }