1 //===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC32 -------*- C++ -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the PowerPC 32-bit CodeEmitter and associated machinery to
11 // JIT-compile bytecode to native PowerPC.
13 //===----------------------------------------------------------------------===//
15 #include "PPCTargetMachine.h"
16 #include "PPCRelocations.h"
18 #include "llvm/Module.h"
19 #include "llvm/PassManager.h"
20 #include "llvm/CodeGen/MachineCodeEmitter.h"
21 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/Compiler.h"
26 #include "llvm/Target/TargetOptions.h"
31 class VISIBILITY_HIDDEN PPCCodeEmitter : public MachineFunctionPass {
33 MachineCodeEmitter &MCE;
35 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
37 int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
40 PPCCodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
43 const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
45 /// runOnMachineFunction - emits the given MachineFunction to memory
47 bool runOnMachineFunction(MachineFunction &MF);
49 /// emitBasicBlock - emits the given MachineBasicBlock to memory
51 void emitBasicBlock(MachineBasicBlock &MBB);
53 /// getValueBit - return the particular bit of Val
55 unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
57 /// getBinaryCodeForInstr - This function, generated by the
58 /// CodeEmitterGenerator using TableGen, produces the binary encoding for
59 /// machine instructions.
61 unsigned getBinaryCodeForInstr(MachineInstr &MI);
65 /// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code
66 /// to the specified MCE object.
67 FunctionPass *llvm::createPPCCodeEmitterPass(PPCTargetMachine &TM,
68 MachineCodeEmitter &MCE) {
69 return new PPCCodeEmitter(TM, MCE);
73 extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
76 bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
77 assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
78 MF.getTarget().getRelocationModel() != Reloc::Static) &&
79 "JIT relocation model must be set to static or default!");
81 MCE.startFunction(MF);
82 for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
84 } while (MCE.finishFunction(MF));
89 void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
90 MCE.StartMachineBasicBlock(&MBB);
92 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
93 MachineInstr &MI = *I;
94 switch (MI.getOpcode()) {
96 MCE.emitWordBE(getBinaryCodeForInstr(*I));
98 case PPC::IMPLICIT_DEF_GPRC:
99 case PPC::IMPLICIT_DEF_G8RC:
100 case PPC::IMPLICIT_DEF_F8:
101 case PPC::IMPLICIT_DEF_F4:
102 case PPC::IMPLICIT_DEF_VRRC:
103 break; // pseudo opcode, no side effects
104 case PPC::MovePCtoLR:
105 assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
111 int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
113 intptr_t rv = 0; // Return value; defaults to 0 for unhandled cases
114 // or things that get fixed up later by the JIT.
115 if (MO.isRegister()) {
116 rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg());
118 // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the
119 // register, not the register number directly.
120 if ((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) &&
121 (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)) {
124 } else if (MO.isImmediate()) {
125 rv = MO.getImmedValue();
126 } else if (MO.isGlobalAddress() || MO.isExternalSymbol() ||
127 MO.isConstantPoolIndex() || MO.isJumpTableIndex()) {
129 if (MI.getOpcode() == PPC::BL)
130 Reloc = PPC::reloc_pcrel_bx;
132 switch (MI.getOpcode()) {
133 default: DEBUG(MI.dump()); assert(0 && "Unknown instruction for relocation!");
138 Reloc = PPC::reloc_absolute_high; // Pointer to symbol
158 Reloc = PPC::reloc_absolute_low;
165 Reloc = PPC::reloc_absolute_low_ix;
169 if (MO.isGlobalAddress())
170 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(),
171 Reloc, MO.getGlobal(), 0));
172 else if (MO.isExternalSymbol())
173 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
174 Reloc, MO.getSymbolName(), 0));
175 else if (MO.isConstantPoolIndex())
176 MCE.addRelocation(MachineRelocation::getConstPool(
177 MCE.getCurrentPCOffset(),
178 Reloc, MO.getConstantPoolIndex(), 0));
179 else // isJumpTableIndex
180 MCE.addRelocation(MachineRelocation::getJumpTable(
181 MCE.getCurrentPCOffset(),
182 Reloc, MO.getJumpTableIndex(), 0));
183 } else if (MO.isMachineBasicBlock()) {
185 unsigned Opcode = MI.getOpcode();
186 if (Opcode == PPC::B || Opcode == PPC::BL || Opcode == PPC::BLA)
187 Reloc = PPC::reloc_pcrel_bx;
189 // BLT,BLE,BEQ,BGE,BGT,BNE, or other bcx instruction
190 Reloc = PPC::reloc_pcrel_bcx;
191 MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
193 MO.getMachineBasicBlock()));
195 std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
202 #include "PPCGenCodeEmitter.inc"