X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FAlpha%2FAlphaCodeEmitter.cpp;h=a6c6f52704f6bf522a6186c99c6653a187e68a4a;hb=9f2cda73e470673ab63509adc9d096b0a1d13c54;hp=f198883fdf98bbcec22dae9608209a5fa87f2e84;hpb=0934ae02af2e4d295951cea7e4567b065e183451;p=oota-llvm.git diff --git a/lib/Target/Alpha/AlphaCodeEmitter.cpp b/lib/Target/Alpha/AlphaCodeEmitter.cpp index f198883fdf9..a6c6f52704f 100644 --- a/lib/Target/Alpha/AlphaCodeEmitter.cpp +++ b/lib/Target/Alpha/AlphaCodeEmitter.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -12,111 +12,94 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "alpha-emitter" #include "AlphaTargetMachine.h" #include "AlphaRelocations.h" #include "Alpha.h" #include "llvm/PassManager.h" -#include "llvm/CodeGen/MachineCodeEmitter.h" +#include "llvm/CodeGen/JITCodeEmitter.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Function.h" #include "llvm/Support/Debug.h" -#include "llvm/ADT/Statistic.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; -namespace { - Statistic<> - NumEmitted("alpha-emitter", "Number of machine instructions emitted"); -} - namespace { class AlphaCodeEmitter : public MachineFunctionPass { - const AlphaInstrInfo *II; - MachineCodeEmitter &MCE; - std::map BasicBlockAddrs; - std::vector > BBRefs; - - /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr - /// - int getMachineOpValue(MachineInstr &MI, MachineOperand &MO); - + JITCodeEmitter &MCE; + const AlphaInstrInfo *II; public: - explicit AlphaCodeEmitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {} - AlphaCodeEmitter(MachineCodeEmitter &mce, const AlphaInstrInfo& ii) - : II(&ii), MCE(mce) {} + static char ID; - bool runOnMachineFunction(MachineFunction &MF); - - virtual const char *getPassName() const { - return "Alpha Machine Code Emitter"; - } - - void emitInstruction(const MachineInstr &MI); - - /// emitWord - write a 32-bit word to memory at the current PC - /// - void emitWord(unsigned w) { MCE.emitWord(w); } + AlphaCodeEmitter(JITCodeEmitter &mce) : MachineFunctionPass(&ID), + MCE(mce) {} /// getBinaryCodeForInstr - This function, generated by the /// CodeEmitterGenerator using TableGen, produces the binary encoding for /// machine instructions. - /// - unsigned getBinaryCodeForInstr(MachineInstr &MI); + unsigned getBinaryCodeForInstr(const MachineInstr &MI); + + /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr + + unsigned getMachineOpValue(const MachineInstr &MI, + const MachineOperand &MO); + + bool runOnMachineFunction(MachineFunction &MF); + + virtual const char *getPassName() const { + return "Alpha Machine Code Emitter"; + } + private: void emitBasicBlock(MachineBasicBlock &MBB); - }; } -/// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha code -/// to the specified MCE object. -FunctionPass *llvm::createAlphaCodeEmitterPass(MachineCodeEmitter &MCE) { - return new AlphaCodeEmitter(MCE); +char AlphaCodeEmitter::ID = 0; + + +/// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha +/// code to the specified MCE object. + +FunctionPass *llvm::createAlphaJITCodeEmitterPass(AlphaTargetMachine &TM, + JITCodeEmitter &JCE) { + return new AlphaCodeEmitter(JCE); } bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) { II = ((AlphaTargetMachine&)MF.getTarget()).getInstrInfo(); - MCE.startFunction(MF); - MCE.emitConstantPool(MF.getConstantPool()); - for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) - emitBasicBlock(*I); - MCE.finishFunction(MF); - - // Resolve all forward branches now... - for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { - unsigned* Location = (unsigned*)BasicBlockAddrs[BBRefs[i].first]; - unsigned* Ref = (unsigned*)BBRefs[i].second; - intptr_t BranchTargetDisp = (((unsigned char*)Location - (unsigned char*)Ref) >> 2) - 1; - DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location - << " Disp " << BranchTargetDisp << " using " << (BranchTargetDisp & ((1 << 22)-1)) << "\n"); - *Ref |= (BranchTargetDisp & ((1 << 21)-1)); - } - BBRefs.clear(); - BasicBlockAddrs.clear(); + do { + MCE.startFunction(MF); + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) + emitBasicBlock(*I); + } while (MCE.finishFunction(MF)); return false; } void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { - uint64_t Addr = MCE.getCurrentPCValue(); - BasicBlockAddrs[&MBB] = (unsigned*)Addr; - + MCE.StartMachineBasicBlock(&MBB); for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) { - MachineInstr &MI = *I; - unsigned Opcode = MI.getOpcode(); + const MachineInstr &MI = *I; + MCE.processDebugLoc(MI.getDebugLoc(), true); switch(MI.getOpcode()) { default: - emitWord(getBinaryCodeForInstr(*I)); + MCE.emitWordLE(getBinaryCodeForInstr(*I)); break; case Alpha::ALTENT: case Alpha::PCLABEL: case Alpha::MEMLABEL: + case TargetOpcode::IMPLICIT_DEF: + case TargetOpcode::KILL: break; //skip these } + MCE.processDebugLoc(MI.getDebugLoc(), false); } } @@ -155,30 +138,29 @@ static unsigned getAlphaRegNumber(unsigned Reg) { case Alpha::R30 : case Alpha::F30 : return 30; case Alpha::R31 : case Alpha::F31 : return 31; default: - assert(0 && "Unhandled reg"); - abort(); + llvm_unreachable("Unhandled reg"); } } -int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { +unsigned AlphaCodeEmitter::getMachineOpValue(const MachineInstr &MI, + const MachineOperand &MO) { - int rv = 0; // Return value; defaults to 0 for unhandled cases - // or things that get fixed up later by the JIT. + unsigned rv = 0; // Return value; defaults to 0 for unhandled cases + // or things that get fixed up later by the JIT. - if (MO.isRegister()) { + if (MO.isReg()) { rv = getAlphaRegNumber(MO.getReg()); - } else if (MO.isImmediate()) { - rv = MO.getImmedValue(); - } else if (MO.isGlobalAddress() || MO.isExternalSymbol() - || MO.isConstantPoolIndex()) { - DEBUG(std::cerr << MO << " is a relocated op for " << MI << "\n";); - bool isExternal = MO.isExternalSymbol() || - (MO.isGlobalAddress() && - ( MO.getGlobal()->hasWeakLinkage() || - MO.getGlobal()->isExternal()) ); + } else if (MO.isImm()) { + rv = MO.getImm(); + } else if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) { + DEBUG(errs() << MO << " is a relocated op for " << MI << "\n"); unsigned Reloc = 0; int Offset = 0; + bool useGOT = false; switch (MI.getOpcode()) { + case Alpha::BSR: + Reloc = Alpha::reloc_bsr; + break; case Alpha::LDLr: case Alpha::LDQr: case Alpha::LDBUr: @@ -186,6 +168,12 @@ int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { case Alpha::LDSr: case Alpha::LDTr: case Alpha::LDAr: + case Alpha::STQr: + case Alpha::STLr: + case Alpha::STWr: + case Alpha::STBr: + case Alpha::STSr: + case Alpha::STTr: Reloc = Alpha::reloc_gprellow; break; case Alpha::LDAHr: @@ -193,39 +181,42 @@ int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { break; case Alpha::LDQl: Reloc = Alpha::reloc_literal; + useGOT = true; break; case Alpha::LDAg: case Alpha::LDAHg: Reloc = Alpha::reloc_gpdist; - Offset = MI.getOperand(3).getImmedValue(); + Offset = MI.getOperand(3).getImm(); break; default: - assert(0 && "unknown relocatable instruction"); - abort(); + llvm_unreachable("unknown relocatable instruction"); } - if (MO.isGlobalAddress()) - MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(), - Reloc, MO.getGlobal(), Offset, - true, true)); - else if (MO.isExternalSymbol()) - MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(), - Reloc, MO.getSymbolName(), Offset, - true)); + if (MO.isGlobal()) + MCE.addRelocation(MachineRelocation::getGV( + MCE.getCurrentPCOffset(), + Reloc, + const_cast(MO.getGlobal()), + Offset, + isa(MO.getGlobal()), + useGOT)); + else if (MO.isSymbol()) + MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), + Reloc, MO.getSymbolName(), + Offset, true)); else - MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(), - Reloc, MO.getConstantPoolIndex(), - Offset)); - } else if (MO.isMachineBasicBlock()) { - unsigned* CurrPC = (unsigned*)MCE.getCurrentPCValue(); - BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC)); - }else { - std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; - abort(); + MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), + Reloc, MO.getIndex(), Offset)); + } else if (MO.isMBB()) { + MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), + Alpha::reloc_bsr, MO.getMBB())); + } else { +#ifndef NDEBUG + errs() << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; +#endif + llvm_unreachable(0); } return rv; } - #include "AlphaGenCodeEmitter.inc" -