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"
30 class VISIBILITY_HIDDEN PPCCodeEmitter : public MachineFunctionPass {
32 MachineCodeEmitter &MCE;
34 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
36 int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
39 PPCCodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
42 const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
44 /// runOnMachineFunction - emits the given MachineFunction to memory
46 bool runOnMachineFunction(MachineFunction &MF);
48 /// emitBasicBlock - emits the given MachineBasicBlock to memory
50 void emitBasicBlock(MachineBasicBlock &MBB);
52 /// getValueBit - return the particular bit of Val
54 unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
56 /// getBinaryCodeForInstr - This function, generated by the
57 /// CodeEmitterGenerator using TableGen, produces the binary encoding for
58 /// machine instructions.
60 unsigned getBinaryCodeForInstr(MachineInstr &MI);
64 /// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code
65 /// to the specified MCE object.
66 FunctionPass *llvm::createPPCCodeEmitterPass(PPCTargetMachine &TM,
67 MachineCodeEmitter &MCE) {
68 return new PPCCodeEmitter(TM, MCE);
72 extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
75 bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
76 assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
77 MF.getTarget().getRelocationModel() != Reloc::Static) &&
78 "JIT relocation model must be set to static or default!");
80 MCE.startFunction(MF);
81 for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
83 } while (MCE.finishFunction(MF));
88 void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
89 MCE.StartMachineBasicBlock(&MBB);
91 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
92 MachineInstr &MI = *I;
93 switch (MI.getOpcode()) {
95 MCE.emitWordBE(getBinaryCodeForInstr(*I));
97 case PPC::IMPLICIT_DEF_GPRC:
98 case PPC::IMPLICIT_DEF_G8RC:
99 case PPC::IMPLICIT_DEF_F8:
100 case PPC::IMPLICIT_DEF_F4:
101 case PPC::IMPLICIT_DEF_VRRC:
102 break; // pseudo opcode, no side effects
103 case PPC::MovePCtoLR:
104 case PPC::MovePCtoLR8:
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 || MI.getOpcode() == PPC::BL8)
130 Reloc = PPC::reloc_pcrel_bx;
132 switch (MI.getOpcode()) {
133 default: 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 cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
202 #include "PPCGenCodeEmitter.inc"