LLVM API Documentation
00001 //===-- Alpha/AlphaCodeEmitter.cpp - Convert Alpha code to machine code ---===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the pass that transforms the Alpha machine instructions 00011 // into relocatable machine code. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "AlphaTargetMachine.h" 00016 #include "AlphaRelocations.h" 00017 #include "Alpha.h" 00018 #include "llvm/PassManager.h" 00019 #include "llvm/CodeGen/MachineCodeEmitter.h" 00020 #include "llvm/CodeGen/MachineFunctionPass.h" 00021 #include "llvm/CodeGen/MachineInstr.h" 00022 #include "llvm/CodeGen/Passes.h" 00023 #include "llvm/Function.h" 00024 #include "llvm/Support/Debug.h" 00025 #include "llvm/ADT/Statistic.h" 00026 #include <iostream> 00027 using namespace llvm; 00028 00029 namespace { 00030 Statistic<> 00031 NumEmitted("alpha-emitter", "Number of machine instructions emitted"); 00032 } 00033 00034 namespace { 00035 class AlphaCodeEmitter : public MachineFunctionPass { 00036 const AlphaInstrInfo *II; 00037 MachineCodeEmitter &MCE; 00038 std::map<const MachineBasicBlock*, unsigned*> BasicBlockAddrs; 00039 std::vector<std::pair<const MachineBasicBlock *, unsigned*> > BBRefs; 00040 00041 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr 00042 /// 00043 int getMachineOpValue(MachineInstr &MI, MachineOperand &MO); 00044 00045 public: 00046 explicit AlphaCodeEmitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {} 00047 AlphaCodeEmitter(MachineCodeEmitter &mce, const AlphaInstrInfo& ii) 00048 : II(&ii), MCE(mce) {} 00049 00050 bool runOnMachineFunction(MachineFunction &MF); 00051 00052 virtual const char *getPassName() const { 00053 return "Alpha Machine Code Emitter"; 00054 } 00055 00056 void emitInstruction(const MachineInstr &MI); 00057 00058 /// emitWord - write a 32-bit word to memory at the current PC 00059 /// 00060 void emitWord(unsigned w) { MCE.emitWord(w); } 00061 00062 /// getBinaryCodeForInstr - This function, generated by the 00063 /// CodeEmitterGenerator using TableGen, produces the binary encoding for 00064 /// machine instructions. 00065 /// 00066 unsigned getBinaryCodeForInstr(MachineInstr &MI); 00067 00068 private: 00069 void emitBasicBlock(MachineBasicBlock &MBB); 00070 00071 }; 00072 } 00073 00074 /// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha code 00075 /// to the specified MCE object. 00076 FunctionPass *llvm::createAlphaCodeEmitterPass(MachineCodeEmitter &MCE) { 00077 return new AlphaCodeEmitter(MCE); 00078 } 00079 00080 bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 00081 II = ((AlphaTargetMachine&)MF.getTarget()).getInstrInfo(); 00082 00083 MCE.startFunction(MF); 00084 MCE.emitConstantPool(MF.getConstantPool()); 00085 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) 00086 emitBasicBlock(*I); 00087 MCE.finishFunction(MF); 00088 00089 // Resolve all forward branches now... 00090 for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { 00091 unsigned* Location = (unsigned*)BasicBlockAddrs[BBRefs[i].first]; 00092 unsigned* Ref = (unsigned*)BBRefs[i].second; 00093 intptr_t BranchTargetDisp = 00094 (((unsigned char*)Location - (unsigned char*)Ref) >> 2) - 1; 00095 DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location 00096 << " Disp " << BranchTargetDisp 00097 << " using " << (BranchTargetDisp & ((1 << 22)-1)) << "\n"); 00098 *Ref |= (BranchTargetDisp & ((1 << 21)-1)); 00099 } 00100 BBRefs.clear(); 00101 BasicBlockAddrs.clear(); 00102 00103 return false; 00104 } 00105 00106 void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { 00107 uintptr_t Addr = MCE.getCurrentPCValue(); 00108 BasicBlockAddrs[&MBB] = (unsigned*)Addr; 00109 00110 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); 00111 I != E; ++I) { 00112 MachineInstr &MI = *I; 00113 unsigned Opcode = MI.getOpcode(); 00114 switch(MI.getOpcode()) { 00115 default: 00116 emitWord(getBinaryCodeForInstr(*I)); 00117 break; 00118 case Alpha::ALTENT: 00119 case Alpha::PCLABEL: 00120 case Alpha::MEMLABEL: 00121 case Alpha::IDEF_I: 00122 case Alpha::IDEF_F32: 00123 case Alpha::IDEF_F64: 00124 break; //skip these 00125 } 00126 } 00127 } 00128 00129 static unsigned getAlphaRegNumber(unsigned Reg) { 00130 switch (Reg) { 00131 case Alpha::R0 : case Alpha::F0 : return 0; 00132 case Alpha::R1 : case Alpha::F1 : return 1; 00133 case Alpha::R2 : case Alpha::F2 : return 2; 00134 case Alpha::R3 : case Alpha::F3 : return 3; 00135 case Alpha::R4 : case Alpha::F4 : return 4; 00136 case Alpha::R5 : case Alpha::F5 : return 5; 00137 case Alpha::R6 : case Alpha::F6 : return 6; 00138 case Alpha::R7 : case Alpha::F7 : return 7; 00139 case Alpha::R8 : case Alpha::F8 : return 8; 00140 case Alpha::R9 : case Alpha::F9 : return 9; 00141 case Alpha::R10 : case Alpha::F10 : return 10; 00142 case Alpha::R11 : case Alpha::F11 : return 11; 00143 case Alpha::R12 : case Alpha::F12 : return 12; 00144 case Alpha::R13 : case Alpha::F13 : return 13; 00145 case Alpha::R14 : case Alpha::F14 : return 14; 00146 case Alpha::R15 : case Alpha::F15 : return 15; 00147 case Alpha::R16 : case Alpha::F16 : return 16; 00148 case Alpha::R17 : case Alpha::F17 : return 17; 00149 case Alpha::R18 : case Alpha::F18 : return 18; 00150 case Alpha::R19 : case Alpha::F19 : return 19; 00151 case Alpha::R20 : case Alpha::F20 : return 20; 00152 case Alpha::R21 : case Alpha::F21 : return 21; 00153 case Alpha::R22 : case Alpha::F22 : return 22; 00154 case Alpha::R23 : case Alpha::F23 : return 23; 00155 case Alpha::R24 : case Alpha::F24 : return 24; 00156 case Alpha::R25 : case Alpha::F25 : return 25; 00157 case Alpha::R26 : case Alpha::F26 : return 26; 00158 case Alpha::R27 : case Alpha::F27 : return 27; 00159 case Alpha::R28 : case Alpha::F28 : return 28; 00160 case Alpha::R29 : case Alpha::F29 : return 29; 00161 case Alpha::R30 : case Alpha::F30 : return 30; 00162 case Alpha::R31 : case Alpha::F31 : return 31; 00163 default: 00164 assert(0 && "Unhandled reg"); 00165 abort(); 00166 } 00167 } 00168 00169 int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { 00170 00171 int rv = 0; // Return value; defaults to 0 for unhandled cases 00172 // or things that get fixed up later by the JIT. 00173 00174 if (MO.isRegister()) { 00175 rv = getAlphaRegNumber(MO.getReg()); 00176 } else if (MO.isImmediate()) { 00177 rv = MO.getImmedValue(); 00178 } else if (MO.isGlobalAddress() || MO.isExternalSymbol() 00179 || MO.isConstantPoolIndex()) { 00180 DEBUG(std::cerr << MO << " is a relocated op for " << MI << "\n";); 00181 bool isExternal = MO.isExternalSymbol() || 00182 (MO.isGlobalAddress() && 00183 ( MO.getGlobal()->hasWeakLinkage() || 00184 MO.getGlobal()->isExternal()) ); 00185 unsigned Reloc = 0; 00186 int Offset = 0; 00187 bool useGOT = false; 00188 switch (MI.getOpcode()) { 00189 case Alpha::BSR: 00190 Reloc = Alpha::reloc_bsr; 00191 break; 00192 case Alpha::LDLr: 00193 case Alpha::LDQr: 00194 case Alpha::LDBUr: 00195 case Alpha::LDWUr: 00196 case Alpha::LDSr: 00197 case Alpha::LDTr: 00198 case Alpha::LDAr: 00199 case Alpha::STQr: 00200 case Alpha::STLr: 00201 case Alpha::STWr: 00202 case Alpha::STBr: 00203 case Alpha::STSr: 00204 case Alpha::STTr: 00205 Reloc = Alpha::reloc_gprellow; 00206 break; 00207 case Alpha::LDAHr: 00208 Reloc = Alpha::reloc_gprelhigh; 00209 break; 00210 case Alpha::LDQl: 00211 Reloc = Alpha::reloc_literal; 00212 useGOT = true; 00213 break; 00214 case Alpha::LDAg: 00215 case Alpha::LDAHg: 00216 Reloc = Alpha::reloc_gpdist; 00217 Offset = MI.getOperand(3).getImmedValue(); 00218 break; 00219 default: 00220 assert(0 && "unknown relocatable instruction"); 00221 abort(); 00222 } 00223 if (MO.isGlobalAddress()) 00224 MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(), 00225 Reloc, MO.getGlobal(), Offset, 00226 false, useGOT)); 00227 else if (MO.isExternalSymbol()) 00228 MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(), 00229 Reloc, MO.getSymbolName(), Offset, 00230 true)); 00231 else 00232 MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(), 00233 Reloc, MO.getConstantPoolIndex(), 00234 Offset)); 00235 } else if (MO.isMachineBasicBlock()) { 00236 unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue(); 00237 BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC)); 00238 }else { 00239 std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; 00240 abort(); 00241 } 00242 00243 return rv; 00244 } 00245 00246 00247 #include "AlphaGenCodeEmitter.inc" 00248