PPCCodeEmitter.cpp revision d2ee218b499fcd364aae7da031819b738f009cd1
121e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman//===-- PPCCodeEmitter.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
1516e71f2f70811c69c56052dd146324fe20e31db5Chris Lattner#include "PPCTargetMachine.h"
1616e71f2f70811c69c56052dd146324fe20e31db5Chris Lattner#include "PPCRelocations.h"
172668959b8879097db368aec7d76c455260abc75bChris Lattner#include "PPC.h"
183070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman#include "llvm/Module.h"
19de123822e5cc9a7d09b12166439cfd35a6c9ed62Chris Lattner#include "llvm/PassManager.h"
20b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman#include "llvm/CodeGen/MachineCodeEmitter.h"
21b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman#include "llvm/CodeGen/MachineFunctionPass.h"
22d4b4a99587a0856473b9334455f6cebcb4fe2583Misha Brukman#include "llvm/CodeGen/MachineInstrBuilder.h"
23b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman#include "llvm/CodeGen/Passes.h"
24551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h"
25d2ee218b499fcd364aae7da031819b738f009cd1Evan Cheng#include "llvm/Target/TargetOptions.h"
2686a5484079abc8a20f24066aaf3f5efcccebb673Chris Lattner#include <iostream>
27eea9b134fcd97aa6c11277864fecf2d30640d27fChris Lattnerusing namespace llvm;
285dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
29b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukmannamespace {
304c7b43b43fdf943c7298718e15ab5d6dfe345be7Chris Lattner  class PPCCodeEmitter : public MachineFunctionPass {
31b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    TargetMachine &TM;
32b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    MachineCodeEmitter &MCE;
33b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
343070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    // Tracks which instruction references which BasicBlock
35b752a97ca41de789434fa792b6de01f6c04fe13eChris Lattner    std::vector<std::pair<MachineBasicBlock*, unsigned*> > BBRefs;
363070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    // Tracks where each BasicBlock starts
37b752a97ca41de789434fa792b6de01f6c04fe13eChris Lattner    std::map<MachineBasicBlock*, long> BBLocations;
383070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman
393070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
403070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    ///
41e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
423070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman
43b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  public:
444c7b43b43fdf943c7298718e15ab5d6dfe345be7Chris Lattner    PPCCodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
45b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman      : TM(T), MCE(M) {}
46b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
47b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
48b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
49b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    /// runOnMachineFunction - emits the given MachineFunction to memory
50b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    ///
51b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    bool runOnMachineFunction(MachineFunction &MF);
52b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
53b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    /// emitBasicBlock - emits the given MachineBasicBlock to memory
54b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    ///
55b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    void emitBasicBlock(MachineBasicBlock &MBB);
56b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
57b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    /// emitWord - write a 32-bit word to memory at the current PC
58b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    ///
59b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    void emitWord(unsigned w) { MCE.emitWord(w); }
60b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
61d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman    /// getValueBit - return the particular bit of Val
62d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman    ///
63d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman    unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
64b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
653070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    /// getBinaryCodeForInstr - This function, generated by the
663070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    /// CodeEmitterGenerator using TableGen, produces the binary encoding for
673070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    /// machine instructions.
68b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman    ///
69d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman    unsigned getBinaryCodeForInstr(MachineInstr &MI);
70b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  };
71b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman}
72b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
735dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
745dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// machine code emitted.  This uses a MachineCodeEmitter object to handle
755dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// actually outputting the machine code and resolving things like the address
765dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// of functions.  This method should returns true if machine code emission is
775dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman/// not supported.
785dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman///
7921e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanbool PPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
8021e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                                  MachineCodeEmitter &MCE) {
81b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  // Machine code emitter pass for PowerPC
824c7b43b43fdf943c7298718e15ab5d6dfe345be7Chris Lattner  PM.add(new PPCCodeEmitter(*this, MCE));
83d37faba5b485eefe94e36e0f88da899b8fec42e5Misha Brukman  // Delete machine code for this function after emitting it
84b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  PM.add(createMachineCodeDeleter());
85c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  return false;
86b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman}
87b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
884c7b43b43fdf943c7298718e15ab5d6dfe345be7Chris Lattnerbool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
89b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  MCE.startFunction(MF);
90b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  MCE.emitConstantPool(MF.getConstantPool());
913070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
923070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    emitBasicBlock(*BB);
93b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  MCE.finishFunction(MF);
943070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman
953070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  // Resolve branches to BasicBlocks for the entire function
963070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
97e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    intptr_t Location = BBLocations[BBRefs[i].first];
988599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    unsigned *Ref = BBRefs[i].second;
99e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location
1008599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner                    << "\n");
1018599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    unsigned Instr = *Ref;
1028599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    intptr_t BranchTargetDisp = (Location - (intptr_t)Ref) >> 2;
103b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
1048599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    switch (Instr >> 26) {
1058599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    default: assert(0 && "Unknown branch user!");
1068599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    case 18:  // This is B or BL
1078599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner      *Ref |= (BranchTargetDisp & ((1 << 24)-1)) << 2;
1088599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner      break;
1098599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner    case 16:  // This is BLT,BLE,BEQ,BGE,BGT,BNE, or other bcx instruction
1108599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner      *Ref |= (BranchTargetDisp & ((1 << 14)-1)) << 2;
1118599d385a2f1fbafaaead903ea5be5a9b33a6509Chris Lattner      break;
1123070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    }
1133070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  }
1143070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  BBRefs.clear();
1153070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  BBLocations.clear();
1163070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman
117b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman  return false;
118b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman}
119b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
1204c7b43b43fdf943c7298718e15ab5d6dfe345be7Chris Lattnervoid PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
1212497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman  assert(!PICEnabled && "CodeEmitter does not support PIC!");
122b752a97ca41de789434fa792b6de01f6c04fe13eChris Lattner  BBLocations[&MBB] = MCE.getCurrentPCValue();
123a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
124a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    MachineInstr &MI = *I;
125a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    unsigned Opcode = MI.getOpcode();
126e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    switch (MI.getOpcode()) {
127e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    default:
128d4b4a99587a0856473b9334455f6cebcb4fe2583Misha Brukman      emitWord(getBinaryCodeForInstr(*I));
129e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      break;
1302b54400f085391a247dd2c3fffc9f36f7b2dc867Chris Lattner    case PPC::IMPLICIT_DEF_GPR:
131919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner    case PPC::IMPLICIT_DEF_F8:
132919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner    case PPC::IMPLICIT_DEF_F4:
133e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      break; // pseudo opcode, no side effects
134e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    case PPC::MovePCtoLR:
1352497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
136e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      break;
137e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    }
138a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  }
139b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman}
140b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
141a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukmanstatic unsigned enumRegToMachineReg(unsigned enumReg) {
142a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  switch (enumReg) {
143b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R0 :  case PPC::F0 :  case PPC::CR0:  return  0;
144b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R1 :  case PPC::F1 :  case PPC::CR1:  return  1;
1459ba12359e3b4ca5bce5469d86ae38eb1237752eeChris Lattner  case PPC::R2 :  case PPC::F2 :  case PPC::CR2:  return  2;
146b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R3 :  case PPC::F3 :  case PPC::CR3:  return  3;
147b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R4 :  case PPC::F4 :  case PPC::CR4:  return  4;
1489ba12359e3b4ca5bce5469d86ae38eb1237752eeChris Lattner  case PPC::R5 :  case PPC::F5 :  case PPC::CR5:  return  5;
149b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R6 :  case PPC::F6 :  case PPC::CR6:  return  6;
150b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R7 :  case PPC::F7 :  case PPC::CR7:  return  7;
151a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R8 :  case PPC::F8 :  return  8;
152b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R9 :  case PPC::F9 :  return  9;
153b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R10:  case PPC::F10:  return 10;
154a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R11:  case PPC::F11:  return 11;
155b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R12:  case PPC::F12:  return 12;
156b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R13:  case PPC::F13:  return 13;
157a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R14:  case PPC::F14:  return 14;
158b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R15:  case PPC::F15:  return 15;
159b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R16:  case PPC::F16:  return 16;
160a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R17:  case PPC::F17:  return 17;
161b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R18:  case PPC::F18:  return 18;
162b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R19:  case PPC::F19:  return 19;
163a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R20:  case PPC::F20:  return 20;
164a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R21:  case PPC::F21:  return 21;
165b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R22:  case PPC::F22:  return 22;
166b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R23:  case PPC::F23:  return 23;
167a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R24:  case PPC::F24:  return 24;
168b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R25:  case PPC::F25:  return 25;
169b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R26:  case PPC::F26:  return 26;
170a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R27:  case PPC::F27:  return 27;
171b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R28:  case PPC::F28:  return 28;
172b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  case PPC::R29:  case PPC::F29:  return 29;
173a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R30:  case PPC::F30:  return 30;
174a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  case PPC::R31:  case PPC::F31:  return 31;
175a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  default:
176a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    std::cerr << "Unhandled reg in enumRegToRealReg!\n";
177a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    abort();
178a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  }
179a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman}
180a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman
1814c7b43b43fdf943c7298718e15ab5d6dfe345be7Chris Lattnerint PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
182b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
183e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner  int rv = 0; // Return value; defaults to 0 for unhandled cases
184c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman                  // or things that get fixed up later by the JIT.
1853070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman  if (MO.isRegister()) {
186a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    rv = enumRegToMachineReg(MO.getReg());
187f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner
188adeb43ddf4eac9e75b7c8e79fa832f72922a2926Nate Begeman    // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the
189f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner    // register, not the register number directly.
190adeb43ddf4eac9e75b7c8e79fa832f72922a2926Nate Begeman    if ((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) &&
191f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner        (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)) {
192f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner      rv = 0x80 >> rv;
193f577c6122f8b51c4e4889f1e1c647ae210c501b8Chris Lattner    }
194c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  } else if (MO.isImmediate()) {
195c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman    rv = MO.getImmedValue();
196477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner  } else if (MO.isGlobalAddress() || MO.isExternalSymbol()) {
197477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner    bool isExternal = MO.isExternalSymbol() ||
198477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner                      MO.getGlobal()->hasWeakLinkage() ||
1995fe0e28650dd49f290fce2b80c0052fbc12d2385Chris Lattner                      MO.getGlobal()->hasLinkOnceLinkage() ||
20037dd6f1b79bd888cb88ced7e5ce5a8ebc7aa44e2Chris Lattner                      (MO.getGlobal()->isExternal() &&
20137dd6f1b79bd888cb88ced7e5ce5a8ebc7aa44e2Chris Lattner                       !MO.getGlobal()->hasNotBeenReadFromBytecode());
202d7fa35c6d2acc2fe95346b1b9eaa3c0a30342c85Chris Lattner    unsigned Reloc = 0;
203422b0cee7a32636303398d8788f98a59bf15381cNate Begeman    if (MI.getOpcode() == PPC::BL)
204e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      Reloc = PPC::reloc_pcrel_bx;
2055efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner    else {
2062497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      switch (MI.getOpcode()) {
2072497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      default: MI.dump(); assert(0 && "Unknown instruction for relocation!");
2082497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LIS:
209477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner        if (isExternal)
2105efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner          Reloc = PPC::reloc_absolute_ptr_high;   // Pointer to stub
21100b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen        else
2125efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner          Reloc = PPC::reloc_absolute_high;       // Pointer to symbol
2132497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman        break;
2142497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LA:
215477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner        assert(!isExternal && "Something in the ISEL changed\n");
2165efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner        Reloc = PPC::reloc_absolute_low;
2172497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman        break;
2182497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LBZ:
2192497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LHA:
2202497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LHZ:
2212497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LWZ:
2222497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LFS:
2232497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::LFD:
2242497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STB:
2252497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STH:
2262497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STW:
2272497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STFS:
2282497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      case PPC::STFD:
2292497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman        if (isExternal)
2302497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman          Reloc = PPC::reloc_absolute_ptr_low;
23100b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen        else
2322497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman          Reloc = PPC::reloc_absolute_low;
2332497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman        break;
2345efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner      }
235e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner    }
236477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner    if (MO.isGlobalAddress())
237477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner      MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
2382497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman                                          Reloc, MO.getGlobal(), 0));
239477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner    else
240477d1de9b2c77455192b6e67dd9496851f4ed8d0Chris Lattner      MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
2412497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman                                          Reloc, MO.getSymbolName(), 0));
242c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  } else if (MO.isMachineBasicBlock()) {
2433070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();
244b752a97ca41de789434fa792b6de01f6c04fe13eChris Lattner    BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC));
245c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  } else if (MO.isConstantPoolIndex()) {
2463070e2ff790e106f5969f503487db5e4b8639ce4Misha Brukman    unsigned index = MO.getConstantPoolIndex();
247b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner    unsigned Opcode = MI.getOpcode();
2482497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman    rv = MCE.getConstantPoolEntryAddress(index);
249e54645a6fb9887b3eccf2eade24531165f84b0edChris Lattner    if (Opcode == PPC::LIS || Opcode == PPC::ADDIS) {
2502497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      // lis wants hi16(addr)
251b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner      if ((short)rv < 0) rv += 1 << 16;
252e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      rv >>= 16;
253a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    } else if (Opcode == PPC::LWZ || Opcode == PPC::LA ||
254e54645a6fb9887b3eccf2eade24531165f84b0edChris Lattner               Opcode == PPC::LI ||
255a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman               Opcode == PPC::LFS || Opcode == PPC::LFD) {
2562497e6391f8df05926fe17b5cf08dad61c4797d2Nate Begeman      // These load opcodes want lo16(addr)
257e94c517bb52095f1ad070bb029617d532af405b8Chris Lattner      rv &= 0xffff;
258b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner    } else {
259b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner      assert(0 && "Unknown constant pool using instruction!");
260a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman    }
261b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner  } else {
262b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner    std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
263b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner    abort();
264a4df350ba1193b2f0421d06a135beb21afb80035Misha Brukman  }
265b9f26da5dd6c404e0a6eabcb60fb3c61ac0ee173Chris Lattner
266c982cfad875f64284ae0fb2f822b0867657171ebMisha Brukman  return rv;
2675dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman}
2685dfe3a9c3bd9091f9adecc909665d52bdd4edd8cMisha Brukman
2694c7b43b43fdf943c7298718e15ab5d6dfe345be7Chris Lattner#include "PPCGenCodeEmitter.inc"
270b05daff7faf694a8d18f00ef00132384c8207cd4Misha Brukman
271