X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FPowerPC%2FPPCCodeEmitter.cpp;h=76dc349b50c7b87948ad1742a32f652d4ac7ba49;hb=ba4733d901b1c2b994f66707657342b8c81c92bc;hp=efa32d7331a651278661f958b707021d836aabfe;hpb=369503f8412bba4a0138074c97107c09cc4513e0;p=oota-llvm.git diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index efa32d7331a..76dc349b50c 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -22,20 +22,19 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Visibility.h" #include "llvm/Target/TargetOptions.h" #include using namespace llvm; namespace { - class PPCCodeEmitter : public MachineFunctionPass { + class VISIBILITY_HIDDEN PPCCodeEmitter : public MachineFunctionPass { TargetMachine &TM; MachineCodeEmitter &MCE; // Tracks which instruction references which BasicBlock std::vector > BBRefs; - // Tracks where each BasicBlock starts - std::map BBLocations; - + /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr /// int getMachineOpValue(MachineInstr &MI, MachineOperand &MO); @@ -54,10 +53,6 @@ namespace { /// void emitBasicBlock(MachineBasicBlock &MBB); - /// emitWord - write a 32-bit word to memory at the current PC - /// - void emitWord(unsigned w) { MCE.emitWord(w); } - /// getValueBit - return the particular bit of Val /// unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; } @@ -89,15 +84,17 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { assert((MF.getTarget().getRelocationModel() != Reloc::Default || MF.getTarget().getRelocationModel() != Reloc::Static) && "JIT relocation model must be set to static or default!"); - MCE.startFunction(MF); - MCE.emitConstantPool(MF.getConstantPool()); - for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) - emitBasicBlock(*BB); - MCE.finishFunction(MF); + do { + BBRefs.clear(); + + MCE.startFunction(MF); + for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) + emitBasicBlock(*BB); + } while (MCE.finishFunction(MF)); // Resolve branches to BasicBlocks for the entire function for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { - intptr_t Location = BBLocations[BBRefs[i].first]; + intptr_t Location = MCE.getMachineBasicBlockAddress(BBRefs[i].first); unsigned *Ref = BBRefs[i].second; DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location << "\n"); @@ -115,21 +112,22 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { } } BBRefs.clear(); - BBLocations.clear(); return false; } void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { - BBLocations[&MBB] = MCE.getCurrentPCValue(); + MCE.StartMachineBasicBlock(&MBB); + for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ MachineInstr &MI = *I; unsigned Opcode = MI.getOpcode(); switch (MI.getOpcode()) { default: - emitWord(getBinaryCodeForInstr(*I)); + MCE.emitWordBE(getBinaryCodeForInstr(*I)); break; - case PPC::IMPLICIT_DEF_GPR: + case PPC::IMPLICIT_DEF_GPRC: + case PPC::IMPLICIT_DEF_G8RC: case PPC::IMPLICIT_DEF_F8: case PPC::IMPLICIT_DEF_F4: case PPC::IMPLICIT_DEF_VRRC: @@ -143,8 +141,8 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { - int rv = 0; // Return value; defaults to 0 for unhandled cases - // or things that get fixed up later by the JIT. + intptr_t rv = 0; // Return value; defaults to 0 for unhandled cases + // or things that get fixed up later by the JIT. if (MO.isRegister()) { rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg()); @@ -157,69 +155,76 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { } else if (MO.isImmediate()) { rv = MO.getImmedValue(); } else if (MO.isGlobalAddress() || MO.isExternalSymbol()) { - bool isExternal = MO.isExternalSymbol() || - MO.getGlobal()->hasWeakLinkage() || - MO.getGlobal()->hasLinkOnceLinkage() || - (MO.getGlobal()->isExternal() && - !MO.getGlobal()->hasNotBeenReadFromBytecode()); unsigned Reloc = 0; if (MI.getOpcode() == PPC::BL) Reloc = PPC::reloc_pcrel_bx; else { switch (MI.getOpcode()) { - default: MI.dump(); assert(0 && "Unknown instruction for relocation!"); + default: DEBUG(MI.dump()); assert(0 && "Unknown instruction for relocation!"); case PPC::LIS: - if (isExternal) - Reloc = PPC::reloc_absolute_ptr_high; // Pointer to stub - else - Reloc = PPC::reloc_absolute_high; // Pointer to symbol + case PPC::LIS8: + case PPC::ADDIS8: + Reloc = PPC::reloc_absolute_high; // Pointer to symbol break; + case PPC::LI: + case PPC::LI8: case PPC::LA: - assert(!isExternal && "Something in the ISEL changed\n"); - Reloc = PPC::reloc_absolute_low; - break; + // Loads. case PPC::LBZ: case PPC::LHA: case PPC::LHZ: case PPC::LWZ: case PPC::LFS: case PPC::LFD: + case PPC::LWZ8: + + // Stores. case PPC::STB: case PPC::STH: case PPC::STW: case PPC::STFS: case PPC::STFD: - if (isExternal) - Reloc = PPC::reloc_absolute_ptr_low; - else - Reloc = PPC::reloc_absolute_low; + Reloc = PPC::reloc_absolute_low; + break; + + case PPC::LWA: + case PPC::LD: + case PPC::STD: + case PPC::STD_32: + Reloc = PPC::reloc_absolute_low_ix; break; } } if (MO.isGlobalAddress()) - MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(), + MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, MO.getGlobal(), 0)); else - MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(), + MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, MO.getSymbolName(), 0)); } else if (MO.isMachineBasicBlock()) { unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue(); BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC)); - } else if (MO.isConstantPoolIndex()) { - unsigned index = MO.getConstantPoolIndex(); + } else if (MO.isConstantPoolIndex() || MO.isJumpTableIndex()) { + if (MO.isConstantPoolIndex()) + rv = MCE.getConstantPoolEntryAddress(MO.getConstantPoolIndex()); + else + rv = MCE.getJumpTableEntryAddress(MO.getJumpTableIndex()); + unsigned Opcode = MI.getOpcode(); - rv = MCE.getConstantPoolEntryAddress(index); - if (Opcode == PPC::LIS || Opcode == PPC::ADDIS) { + if (Opcode == PPC::LIS || Opcode == PPC::LIS8 || + Opcode == PPC::ADDIS || Opcode == PPC::ADDIS8) { // lis wants hi16(addr) if ((short)rv < 0) rv += 1 << 16; rv >>= 16; - } else if (Opcode == PPC::LWZ || Opcode == PPC::LA || - Opcode == PPC::LI || + } else if (Opcode == PPC::LWZ || Opcode == PPC::LWZ8 || + Opcode == PPC::LA || + Opcode == PPC::LI || Opcode == PPC::LI8 || Opcode == PPC::LFS || Opcode == PPC::LFD) { // These load opcodes want lo16(addr) rv &= 0xffff; } else { - assert(0 && "Unknown constant pool using instruction!"); + MI.dump(); + assert(0 && "Unknown constant pool or jump table using instruction!"); } } else { std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";