1 //===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC32 -------*- C++ -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the PowerPC 32-bit CodeEmitter and associated machinery to
11 // JIT-compile bitcode 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/MachineModuleInfo.h"
24 #include "llvm/CodeGen/Passes.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Target/TargetOptions.h"
31 class VISIBILITY_HIDDEN PPCCodeEmitter
: public MachineFunctionPass
{
33 MachineCodeEmitter
&MCE
;
35 /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record
36 /// its address in the function into this pointer.
37 void *MovePCtoLROffset
;
39 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
41 unsigned getMachineOpValue(const MachineInstr
&MI
, const MachineOperand
&MO
);
43 void getAnalysisUsage(AnalysisUsage
&AU
) const {
44 AU
.addRequired
<MachineModuleInfo
>();
45 MachineFunctionPass::getAnalysisUsage(AU
);
50 PPCCodeEmitter(TargetMachine
&T
, MachineCodeEmitter
&M
)
51 : MachineFunctionPass(&ID
), TM(T
), MCE(M
) {}
53 const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
55 /// runOnMachineFunction - emits the given MachineFunction to memory
57 bool runOnMachineFunction(MachineFunction
&MF
);
59 /// emitBasicBlock - emits the given MachineBasicBlock to memory
61 void emitBasicBlock(MachineBasicBlock
&MBB
);
63 /// getValueBit - return the particular bit of Val
65 unsigned getValueBit(int64_t Val
, unsigned bit
) { return (Val
>> bit
) & 1; }
67 /// getBinaryCodeForInstr - This function, generated by the
68 /// CodeEmitterGenerator using TableGen, produces the binary encoding for
69 /// machine instructions.
71 unsigned getBinaryCodeForInstr(const MachineInstr
&MI
);
73 char PPCCodeEmitter::ID
= 0;
76 /// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code
77 /// to the specified MCE object.
78 FunctionPass
*llvm::createPPCCodeEmitterPass(PPCTargetMachine
&TM
,
79 MachineCodeEmitter
&MCE
) {
80 return new PPCCodeEmitter(TM
, MCE
);
83 bool PPCCodeEmitter::runOnMachineFunction(MachineFunction
&MF
) {
84 assert((MF
.getTarget().getRelocationModel() != Reloc::Default
||
85 MF
.getTarget().getRelocationModel() != Reloc::Static
) &&
86 "JIT relocation model must be set to static or default!");
88 MCE
.setModuleInfo(&getAnalysis
<MachineModuleInfo
>());
91 MCE
.startFunction(MF
);
92 for (MachineFunction::iterator BB
= MF
.begin(), E
= MF
.end(); BB
!= E
; ++BB
)
94 } while (MCE
.finishFunction(MF
));
99 void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock
&MBB
) {
100 MCE
.StartMachineBasicBlock(&MBB
);
102 for (MachineBasicBlock::iterator I
= MBB
.begin(), E
= MBB
.end(); I
!= E
; ++I
){
103 const MachineInstr
&MI
= *I
;
104 switch (MI
.getOpcode()) {
106 MCE
.emitWordBE(getBinaryCodeForInstr(MI
));
108 case TargetInstrInfo::DBG_LABEL
:
109 case TargetInstrInfo::EH_LABEL
:
110 MCE
.emitLabel(MI
.getOperand(0).getImm());
112 case TargetInstrInfo::IMPLICIT_DEF
:
113 break; // pseudo opcode, no side effects
114 case PPC::MovePCtoLR
:
115 case PPC::MovePCtoLR8
:
116 assert(TM
.getRelocationModel() == Reloc::PIC_
);
117 MovePCtoLROffset
= (void*)MCE
.getCurrentPCValue();
118 MCE
.emitWordBE(0x48000005); // bl 1
124 unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr
&MI
,
125 const MachineOperand
&MO
) {
127 unsigned rv
= 0; // Return value; defaults to 0 for unhandled cases
128 // or things that get fixed up later by the JIT.
130 rv
= PPCRegisterInfo::getRegisterNumbering(MO
.getReg());
132 // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the
133 // register, not the register number directly.
134 if ((MI
.getOpcode() == PPC::MTCRF
|| MI
.getOpcode() == PPC::MFOCRF
) &&
135 (MO
.getReg() >= PPC::CR0
&& MO
.getReg() <= PPC::CR7
)) {
138 } else if (MO
.isImm()) {
140 } else if (MO
.isGlobal() || MO
.isSymbol() ||
141 MO
.isCPI() || MO
.isJTI()) {
143 if (MI
.getOpcode() == PPC::BL_Macho
|| MI
.getOpcode() == PPC::BL8_Macho
||
144 MI
.getOpcode() == PPC::BL_ELF
|| MI
.getOpcode() == PPC::BL8_ELF
||
145 MI
.getOpcode() == PPC::TAILB
|| MI
.getOpcode() == PPC::TAILB8
)
146 Reloc
= PPC::reloc_pcrel_bx
;
148 if (TM
.getRelocationModel() == Reloc::PIC_
) {
149 assert(MovePCtoLROffset
&& "MovePCtoLR not seen yet?");
151 switch (MI
.getOpcode()) {
152 default: MI
.dump(); assert(0 && "Unknown instruction for relocation!");
157 Reloc
= PPC::reloc_absolute_high
; // Pointer to symbol
183 Reloc
= PPC::reloc_absolute_low
;
190 Reloc
= PPC::reloc_absolute_low_ix
;
197 R
= MachineRelocation::getGV(MCE
.getCurrentPCOffset(), Reloc
,
199 isa
<Function
>(MO
.getGlobal()));
200 } else if (MO
.isSymbol()) {
201 R
= MachineRelocation::getExtSym(MCE
.getCurrentPCOffset(),
202 Reloc
, MO
.getSymbolName(), 0);
203 } else if (MO
.isCPI()) {
204 R
= MachineRelocation::getConstPool(MCE
.getCurrentPCOffset(),
205 Reloc
, MO
.getIndex(), 0);
208 R
= MachineRelocation::getJumpTable(MCE
.getCurrentPCOffset(),
209 Reloc
, MO
.getIndex(), 0);
212 // If in PIC mode, we need to encode the negated address of the
213 // 'movepctolr' into the unrelocated field. After relocation, we'll have
214 // &gv-&movepctolr-4 in the imm field. Once &movepctolr is added to the imm
215 // field, we get &gv. This doesn't happen for branch relocations, which are
216 // always implicitly pc relative.
217 if (TM
.getRelocationModel() == Reloc::PIC_
&& Reloc
!= PPC::reloc_pcrel_bx
){
218 assert(MovePCtoLROffset
&& "MovePCtoLR not seen yet?");
219 R
.setConstantVal(-(intptr_t)MovePCtoLROffset
- 4);
221 MCE
.addRelocation(R
);
223 } else if (MO
.isMBB()) {
225 unsigned Opcode
= MI
.getOpcode();
226 if (Opcode
== PPC::B
|| Opcode
== PPC::BL_Macho
||
227 Opcode
== PPC::BLA_Macho
|| Opcode
== PPC::BL_ELF
||
228 Opcode
== PPC::BLA_ELF
)
229 Reloc
= PPC::reloc_pcrel_bx
;
230 else // BCC instruction
231 Reloc
= PPC::reloc_pcrel_bcx
;
232 MCE
.addRelocation(MachineRelocation::getBB(MCE
.getCurrentPCOffset(),
233 Reloc
, MO
.getMBB()));
235 cerr
<< "ERROR: Unknown type of MachineOperand: " << MO
<< "\n";
242 #include "PPCGenCodeEmitter.inc"