PPCCodeEmitter.cpp revision 00b16889ab461b7ecef1c91ade101186b7f1fce2
13d9a6c2842599b9d8659ae97e19c413d435d7b34Misha Brukman//===-- PPC32CodeEmitter.cpp - JIT Code Emitter for PowerPC32 -----*- C++ -*-=//
2b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
35dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//                     The LLVM Compiler Infrastructure
45dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//
55dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman// This file was developed by the LLVM research group and is distributed under
65dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman// the University of Illinois Open Source License. See LICENSE.TXT for details.
7b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
85dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//===----------------------------------------------------------------------===//
9b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
10d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman// This file defines the PowerPC 32-bit CodeEmitter and associated machinery to
11d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman// JIT-compile bytecode to native PowerPC.
125dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//
135dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman//===----------------------------------------------------------------------===//
145dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
153d9a6c2842599b9d8659ae97e19c413d435d7b34Misha Brukman#include "PPC32TargetMachine.h"
16e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner#include "PPC32Relocations.h"
17a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman#include "PowerPC.h"
183070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman#include "llvm/Module.h"
19b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman#include "llvm/CodeGen/MachineCodeEmitter.h"
20b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman#include "llvm/CodeGen/MachineFunctionPass.h"
21d4b4a99587a0856473b9334455f6cebcb4fe2583Misha Brukman#include "llvm/CodeGen/MachineInstrBuilder.h"
22b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman#include "llvm/CodeGen/Passes.h"
23551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h"
24eea9b134fcd97aa6c11277864fecf2d30640d27fChris Lattnerusing namespace llvm;
255dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
26b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukmannamespace {
273d9a6c2842599b9d8659ae97e19c413d435d7b34Misha Brukman  class PPC32CodeEmitter : public MachineFunctionPass {
28b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    TargetMachine &TM;
29b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    MachineCodeEmitter &MCE;
30b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
313070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    // Tracks which instruction references which BasicBlock
32b752a97ca41de789434fa792b6de01f6c04fe13eChris Lattner    std::vector<std::pair<MachineBasicBlock*, unsigned*> > BBRefs;
333070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    // Tracks where each BasicBlock starts
34b752a97ca41de789434fa792b6de01f6c04fe13eChris Lattner    std::map<MachineBasicBlock*, long> BBLocations;
353070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman
363070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
373070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    ///
38e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
393070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman
40b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  public:
41b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman    PPC32CodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
42b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman      : TM(T), MCE(M) {}
43b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
44b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
45b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
46b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    /// runOnMachineFunction - emits the given MachineFunction to memory
47b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    ///
48b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    bool runOnMachineFunction(MachineFunction &MF);
49b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
50b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    /// emitBasicBlock - emits the given MachineBasicBlock to memory
51b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    ///
52b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    void emitBasicBlock(MachineBasicBlock &MBB);
53b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
54b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    /// emitWord - write a 32-bit word to memory at the current PC
55b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    ///
56b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    void emitWord(unsigned w) { MCE.emitWord(w); }
57b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
58d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman    /// getValueBit - return the particular bit of Val
59d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman    ///
60d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman    unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
61b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
623070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    /// getBinaryCodeForInstr - This function, generated by the
633070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    /// CodeEmitterGenerator using TableGen, produces the binary encoding for
643070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    /// machine instructions.
65b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    ///
66d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman    unsigned getBinaryCodeForInstr(MachineInstr &MI);
67b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  };
68b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman}
69b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
705dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
715dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// machine code emitted.  This uses a MachineCodeEmitter object to handle
725dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// actually outputting the machine code and resolving things like the address
735dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// of functions.  This method should returns true if machine code emission is
745dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// not supported.
755dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman///
763d9a6c2842599b9d8659ae97e19c413d435d7b34Misha Brukmanbool PPC32TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
773d9a6c2842599b9d8659ae97e19c413d435d7b34Misha Brukman                                                    MachineCodeEmitter &MCE) {
78b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  // Machine code emitter pass for PowerPC
79b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  PM.add(new PPC32CodeEmitter(*this, MCE));
80d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman  // Delete machine code for this function after emitting it
81b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  PM.add(createMachineCodeDeleter());
82c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  return false;
83b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman}
84b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
853d9a6c2842599b9d8659ae97e19c413d435d7b34Misha Brukmanbool PPC32CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
86b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  MCE.startFunction(MF);
87b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  MCE.emitConstantPool(MF.getConstantPool());
883070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
893070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    emitBasicBlock(*BB);
90b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  MCE.finishFunction(MF);
913070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman
923070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  // Resolve branches to BasicBlocks for the entire function
933070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
94e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    intptr_t Location = BBLocations[BBRefs[i].first];
958599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    unsigned *Ref = BBRefs[i].second;
96e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location
978599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner                    << "\n");
988599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    unsigned Instr = *Ref;
998599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    intptr_t BranchTargetDisp = (Location - (intptr_t)Ref) >> 2;
100b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
1018599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    switch (Instr >> 26) {
1028599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    default: assert(0 && "Unknown branch user!");
1038599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    case 18:  // This is B or BL
1048599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner      *Ref |= (BranchTargetDisp & ((1 << 24)-1)) << 2;
1058599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner      break;
1068599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    case 16:  // This is BLT,BLE,BEQ,BGE,BGT,BNE, or other bcx instruction
1078599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner      *Ref |= (BranchTargetDisp & ((1 << 14)-1)) << 2;
1088599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner      break;
1093070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    }
1103070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  }
1113070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  BBRefs.clear();
1123070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  BBLocations.clear();
1133070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman
114b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  return false;
115b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman}
116b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
1173d9a6c2842599b9d8659ae97e19c413d435d7b34Misha Brukmanvoid PPC32CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
1182497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman  assert(!PICEnabled && "CodeEmitter does not support PIC!");
119b752a97ca41de789434fa792b6de01f6c04fe13eChris Lattner  BBLocations[&MBB] = MCE.getCurrentPCValue();
120a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
121a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    MachineInstr &MI = *I;
122a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    unsigned Opcode = MI.getOpcode();
123e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    switch (MI.getOpcode()) {
124e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    default:
125d4b4a99587a0856473b9334455f6cebcb4fe2583Misha Brukman      emitWord(getBinaryCodeForInstr(*I));
126e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      break;
127e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    case PPC::IMPLICIT_DEF:
128e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      break; // pseudo opcode, no side effects
129e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    case PPC::MovePCtoLR:
1302497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
131e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      break;
132e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    }
133a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  }
134b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman}
135b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
136a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukmanstatic unsigned enumRegToMachineReg(unsigned enumReg) {
137a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  switch (enumReg) {
138b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R0 :  case PPC::F0 :  case PPC::CR0:  return  0;
139b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R1 :  case PPC::F1 :  case PPC::CR1:  return  1;
1409ba12359e3b4ca5bce5469d86ae38eb1237752eeChris Lattner  case PPC::R2 :  case PPC::F2 :  case PPC::CR2:  return  2;
141b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R3 :  case PPC::F3 :  case PPC::CR3:  return  3;
142b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R4 :  case PPC::F4 :  case PPC::CR4:  return  4;
1439ba12359e3b4ca5bce5469d86ae38eb1237752eeChris Lattner  case PPC::R5 :  case PPC::F5 :  case PPC::CR5:  return  5;
144b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R6 :  case PPC::F6 :  case PPC::CR6:  return  6;
145b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R7 :  case PPC::F7 :  case PPC::CR7:  return  7;
146a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R8 :  case PPC::F8 :  return  8;
147b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R9 :  case PPC::F9 :  return  9;
148b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R10:  case PPC::F10:  return 10;
149a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R11:  case PPC::F11:  return 11;
150b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R12:  case PPC::F12:  return 12;
151b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R13:  case PPC::F13:  return 13;
152a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R14:  case PPC::F14:  return 14;
153b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R15:  case PPC::F15:  return 15;
154b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R16:  case PPC::F16:  return 16;
155a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R17:  case PPC::F17:  return 17;
156b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R18:  case PPC::F18:  return 18;
157b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R19:  case PPC::F19:  return 19;
158a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R20:  case PPC::F20:  return 20;
159a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R21:  case PPC::F21:  return 21;
160b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R22:  case PPC::F22:  return 22;
161b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R23:  case PPC::F23:  return 23;
162a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R24:  case PPC::F24:  return 24;
163b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R25:  case PPC::F25:  return 25;
164b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R26:  case PPC::F26:  return 26;
165a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R27:  case PPC::F27:  return 27;
166b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R28:  case PPC::F28:  return 28;
167b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R29:  case PPC::F29:  return 29;
168a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R30:  case PPC::F30:  return 30;
169a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R31:  case PPC::F31:  return 31;
170a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  default:
171a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    std::cerr << "Unhandled reg in enumRegToRealReg!\n";
172a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    abort();
173a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  }
174a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman}
175a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman
176e94c517bb52095f1ad070bb029617d532af405b8Chris Lattnerint PPC32CodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
177b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
178e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner  int rv = 0; // Return value; defaults to 0 for unhandled cases
179c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman                  // or things that get fixed up later by the JIT.
1803070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  if (MO.isRegister()) {
181a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    rv = enumRegToMachineReg(MO.getReg());
182f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner
183adeb43ddf4eac9e75b7c8e79fa832f72922a2926Nate Begeman    // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the
184f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner    // register, not the register number directly.
185adeb43ddf4eac9e75b7c8e79fa832f72922a2926Nate Begeman    if ((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) &&
186f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner        (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)) {
187f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner      rv = 0x80 >> rv;
188f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner    }
189c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  } else if (MO.isImmediate()) {
190c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman    rv = MO.getImmedValue();
191477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner  } else if (MO.isGlobalAddress() || MO.isExternalSymbol()) {
192477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner    bool isExternal = MO.isExternalSymbol() ||
193477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner                      MO.getGlobal()->hasWeakLinkage() ||
194477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner                      MO.getGlobal()->isExternal();
195d7fa35c6d2acc2fe95346b1b9eaa3c0a30342c85Chris Lattner    unsigned Reloc = 0;
196e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    if (MI.getOpcode() == PPC::CALLpcrel)
197e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      Reloc = PPC::reloc_pcrel_bx;
1985efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner    else {
1992497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      switch (MI.getOpcode()) {
2002497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      default: MI.dump(); assert(0 && "Unknown instruction for relocation!");
2012497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LIS:
202477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner        if (isExternal)
2035efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner          Reloc = PPC::reloc_absolute_ptr_high;   // Pointer to stub
20400b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen        else
2055efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner          Reloc = PPC::reloc_absolute_high;       // Pointer to symbol
2062497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman        break;
2072497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LA:
208477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner        assert(!isExternal && "Something in the ISEL changed\n");
2095efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner        Reloc = PPC::reloc_absolute_low;
2102497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman        break;
2112497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LBZ:
2122497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LHA:
2132497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LHZ:
2142497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LWZ:
2152497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LFS:
2162497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LFD:
2172497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STB:
2182497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STH:
2192497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STW:
2202497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STFS:
2212497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STFD:
2222497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman        if (isExternal)
2232497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman          Reloc = PPC::reloc_absolute_ptr_low;
22400b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen        else
2252497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman          Reloc = PPC::reloc_absolute_low;
2262497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman        break;
2275efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner      }
228e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    }
229477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner    if (MO.isGlobalAddress())
230477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner      MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
2312497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman                                          Reloc, MO.getGlobal(), 0));
232477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner    else
233477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner      MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
2342497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman                                          Reloc, MO.getSymbolName(), 0));
235c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  } else if (MO.isMachineBasicBlock()) {
2363070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();
237b752a97ca41de789434fa792b6de01f6c04fe13eChris Lattner    BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC));
238c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  } else if (MO.isConstantPoolIndex()) {
2393070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    unsigned index = MO.getConstantPoolIndex();
240b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner    unsigned Opcode = MI.getOpcode();
2412497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman    rv = MCE.getConstantPoolEntryAddress(index);
2422497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman    if (Opcode == PPC::LIS) {
2432497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      // lis wants hi16(addr)
244b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner      if ((short)rv < 0) rv += 1 << 16;
245e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      rv >>= 16;
246a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    } else if (Opcode == PPC::LWZ || Opcode == PPC::LA ||
247a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman               Opcode == PPC::LFS || Opcode == PPC::LFD) {
2482497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      // These load opcodes want lo16(addr)
249e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      rv &= 0xffff;
250b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner    } else {
251b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner      assert(0 && "Unknown constant pool using instruction!");
252a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    }
253b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner  } else {
254b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner    std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
255b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner    abort();
256a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  }
257b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner
258c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  return rv;
2595dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman}
2605dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
261d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman#include "PPC32GenCodeEmitter.inc"
262b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
263