/3rd_party/llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp

https://code.google.com/p/softart/ · C++ · 290 lines · 204 code · 49 blank · 37 comment · 40 complexity · 1dd427ecf975cdaa91e64f0e8c57f7e0 MD5 · raw file

  1. //===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC -----------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines the PowerPC 32-bit CodeEmitter and associated machinery to
  11. // JIT-compile bitcode to native PowerPC.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "PPC.h"
  15. #include "PPCRelocations.h"
  16. #include "PPCTargetMachine.h"
  17. #include "llvm/CodeGen/JITCodeEmitter.h"
  18. #include "llvm/CodeGen/MachineFunctionPass.h"
  19. #include "llvm/CodeGen/MachineInstrBuilder.h"
  20. #include "llvm/CodeGen/MachineModuleInfo.h"
  21. #include "llvm/IR/Module.h"
  22. #include "llvm/PassManager.h"
  23. #include "llvm/Support/ErrorHandling.h"
  24. #include "llvm/Support/raw_ostream.h"
  25. #include "llvm/Target/TargetOptions.h"
  26. using namespace llvm;
  27. namespace {
  28. class PPCCodeEmitter : public MachineFunctionPass {
  29. TargetMachine &TM;
  30. JITCodeEmitter &MCE;
  31. MachineModuleInfo *MMI;
  32. void getAnalysisUsage(AnalysisUsage &AU) const {
  33. AU.addRequired<MachineModuleInfo>();
  34. MachineFunctionPass::getAnalysisUsage(AU);
  35. }
  36. static char ID;
  37. /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record
  38. /// its address in the function into this pointer.
  39. void *MovePCtoLROffset;
  40. public:
  41. PPCCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
  42. : MachineFunctionPass(ID), TM(tm), MCE(mce) {}
  43. /// getBinaryCodeForInstr - This function, generated by the
  44. /// CodeEmitterGenerator using TableGen, produces the binary encoding for
  45. /// machine instructions.
  46. uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;
  47. MachineRelocation GetRelocation(const MachineOperand &MO,
  48. unsigned RelocID) const;
  49. /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
  50. unsigned getMachineOpValue(const MachineInstr &MI,
  51. const MachineOperand &MO) const;
  52. unsigned get_crbitm_encoding(const MachineInstr &MI, unsigned OpNo) const;
  53. unsigned getDirectBrEncoding(const MachineInstr &MI, unsigned OpNo) const;
  54. unsigned getCondBrEncoding(const MachineInstr &MI, unsigned OpNo) const;
  55. unsigned getAbsDirectBrEncoding(const MachineInstr &MI,
  56. unsigned OpNo) const;
  57. unsigned getAbsCondBrEncoding(const MachineInstr &MI, unsigned OpNo) const;
  58. unsigned getImm16Encoding(const MachineInstr &MI, unsigned OpNo) const;
  59. unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const;
  60. unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const;
  61. unsigned getTLSRegEncoding(const MachineInstr &MI, unsigned OpNo) const;
  62. unsigned getTLSCallEncoding(const MachineInstr &MI, unsigned OpNo) const;
  63. const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
  64. /// runOnMachineFunction - emits the given MachineFunction to memory
  65. ///
  66. bool runOnMachineFunction(MachineFunction &MF);
  67. /// emitBasicBlock - emits the given MachineBasicBlock to memory
  68. ///
  69. void emitBasicBlock(MachineBasicBlock &MBB);
  70. };
  71. }
  72. char PPCCodeEmitter::ID = 0;
  73. /// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code
  74. /// to the specified MCE object.
  75. FunctionPass *llvm::createPPCJITCodeEmitterPass(PPCTargetMachine &TM,
  76. JITCodeEmitter &JCE) {
  77. return new PPCCodeEmitter(TM, JCE);
  78. }
  79. bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
  80. assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
  81. MF.getTarget().getRelocationModel() != Reloc::Static) &&
  82. "JIT relocation model must be set to static or default!");
  83. MMI = &getAnalysis<MachineModuleInfo>();
  84. MCE.setModuleInfo(MMI);
  85. do {
  86. MovePCtoLROffset = 0;
  87. MCE.startFunction(MF);
  88. for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
  89. emitBasicBlock(*BB);
  90. } while (MCE.finishFunction(MF));
  91. return false;
  92. }
  93. void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
  94. MCE.StartMachineBasicBlock(&MBB);
  95. for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
  96. const MachineInstr &MI = *I;
  97. MCE.processDebugLoc(MI.getDebugLoc(), true);
  98. switch (MI.getOpcode()) {
  99. default:
  100. MCE.emitWordBE(getBinaryCodeForInstr(MI));
  101. break;
  102. case TargetOpcode::PROLOG_LABEL:
  103. case TargetOpcode::EH_LABEL:
  104. MCE.emitLabel(MI.getOperand(0).getMCSymbol());
  105. break;
  106. case TargetOpcode::IMPLICIT_DEF:
  107. case TargetOpcode::KILL:
  108. break; // pseudo opcode, no side effects
  109. case PPC::MovePCtoLR:
  110. case PPC::MovePCtoLR8:
  111. assert(TM.getRelocationModel() == Reloc::PIC_);
  112. MovePCtoLROffset = (void*)MCE.getCurrentPCValue();
  113. MCE.emitWordBE(0x48000005); // bl 1
  114. break;
  115. }
  116. MCE.processDebugLoc(MI.getDebugLoc(), false);
  117. }
  118. }
  119. unsigned PPCCodeEmitter::get_crbitm_encoding(const MachineInstr &MI,
  120. unsigned OpNo) const {
  121. const MachineOperand &MO = MI.getOperand(OpNo);
  122. assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
  123. MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
  124. (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
  125. return 0x80 >> TM.getRegisterInfo()->getEncodingValue(MO.getReg());
  126. }
  127. MachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO,
  128. unsigned RelocID) const {
  129. // If in PIC mode, we need to encode the negated address of the
  130. // 'movepctolr' into the unrelocated field. After relocation, we'll have
  131. // &gv-&movepctolr-4 in the imm field. Once &movepctolr is added to the imm
  132. // field, we get &gv. This doesn't happen for branch relocations, which are
  133. // always implicitly pc relative.
  134. intptr_t Cst = 0;
  135. if (TM.getRelocationModel() == Reloc::PIC_) {
  136. assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
  137. Cst = -(intptr_t)MovePCtoLROffset - 4;
  138. }
  139. if (MO.isGlobal())
  140. return MachineRelocation::getGV(MCE.getCurrentPCOffset(), RelocID,
  141. const_cast<GlobalValue *>(MO.getGlobal()),
  142. Cst, isa<Function>(MO.getGlobal()));
  143. if (MO.isSymbol())
  144. return MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
  145. RelocID, MO.getSymbolName(), Cst);
  146. if (MO.isCPI())
  147. return MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
  148. RelocID, MO.getIndex(), Cst);
  149. if (MO.isMBB())
  150. return MachineRelocation::getBB(MCE.getCurrentPCOffset(),
  151. RelocID, MO.getMBB());
  152. assert(MO.isJTI());
  153. return MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
  154. RelocID, MO.getIndex(), Cst);
  155. }
  156. unsigned PPCCodeEmitter::getDirectBrEncoding(const MachineInstr &MI,
  157. unsigned OpNo) const {
  158. const MachineOperand &MO = MI.getOperand(OpNo);
  159. if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
  160. MCE.addRelocation(GetRelocation(MO, PPC::reloc_pcrel_bx));
  161. return 0;
  162. }
  163. unsigned PPCCodeEmitter::getCondBrEncoding(const MachineInstr &MI,
  164. unsigned OpNo) const {
  165. const MachineOperand &MO = MI.getOperand(OpNo);
  166. MCE.addRelocation(GetRelocation(MO, PPC::reloc_pcrel_bcx));
  167. return 0;
  168. }
  169. unsigned PPCCodeEmitter::getAbsDirectBrEncoding(const MachineInstr &MI,
  170. unsigned OpNo) const {
  171. const MachineOperand &MO = MI.getOperand(OpNo);
  172. if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
  173. llvm_unreachable("Absolute branch relocations unsupported on the old JIT.");
  174. }
  175. unsigned PPCCodeEmitter::getAbsCondBrEncoding(const MachineInstr &MI,
  176. unsigned OpNo) const {
  177. llvm_unreachable("Absolute branch relocations unsupported on the old JIT.");
  178. }
  179. unsigned PPCCodeEmitter::getImm16Encoding(const MachineInstr &MI,
  180. unsigned OpNo) const {
  181. const MachineOperand &MO = MI.getOperand(OpNo);
  182. if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
  183. unsigned RelocID;
  184. switch (MO.getTargetFlags() & PPCII::MO_ACCESS_MASK) {
  185. default: llvm_unreachable("Unsupported target operand flags!");
  186. case PPCII::MO_LO: RelocID = PPC::reloc_absolute_low; break;
  187. case PPCII::MO_HA: RelocID = PPC::reloc_absolute_high; break;
  188. }
  189. MCE.addRelocation(GetRelocation(MO, RelocID));
  190. return 0;
  191. }
  192. unsigned PPCCodeEmitter::getMemRIEncoding(const MachineInstr &MI,
  193. unsigned OpNo) const {
  194. // Encode (imm, reg) as a memri, which has the low 16-bits as the
  195. // displacement and the next 5 bits as the register #.
  196. assert(MI.getOperand(OpNo+1).isReg());
  197. unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 16;
  198. const MachineOperand &MO = MI.getOperand(OpNo);
  199. if (MO.isImm())
  200. return (getMachineOpValue(MI, MO) & 0xFFFF) | RegBits;
  201. // Add a fixup for the displacement field.
  202. MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low));
  203. return RegBits;
  204. }
  205. unsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI,
  206. unsigned OpNo) const {
  207. // Encode (imm, reg) as a memrix, which has the low 14-bits as the
  208. // displacement and the next 5 bits as the register #.
  209. assert(MI.getOperand(OpNo+1).isReg());
  210. unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 14;
  211. const MachineOperand &MO = MI.getOperand(OpNo);
  212. if (MO.isImm())
  213. return ((getMachineOpValue(MI, MO) >> 2) & 0x3FFF) | RegBits;
  214. MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low_ix));
  215. return RegBits;
  216. }
  217. unsigned PPCCodeEmitter::getTLSRegEncoding(const MachineInstr &MI,
  218. unsigned OpNo) const {
  219. llvm_unreachable("TLS not supported on the old JIT.");
  220. return 0;
  221. }
  222. unsigned PPCCodeEmitter::getTLSCallEncoding(const MachineInstr &MI,
  223. unsigned OpNo) const {
  224. llvm_unreachable("TLS not supported on the old JIT.");
  225. return 0;
  226. }
  227. unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
  228. const MachineOperand &MO) const {
  229. if (MO.isReg()) {
  230. // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
  231. // The GPR operand should come through here though.
  232. assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
  233. MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
  234. MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
  235. return TM.getRegisterInfo()->getEncodingValue(MO.getReg());
  236. }
  237. assert(MO.isImm() &&
  238. "Relocation required in an instruction that we cannot encode!");
  239. return MO.getImm();
  240. }
  241. #include "PPCGenCodeEmitter.inc"