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 TargetMachine &TM; 00038 MachineCodeEmitter &MCE; 00039 00040 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr 00041 /// 00042 int getMachineOpValue(MachineInstr &MI, MachineOperand &MO); 00043 00044 public: 00045 explicit AlphaCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce) 00046 : II(0), TM(tm), MCE(mce) {} 00047 AlphaCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce, 00048 const AlphaInstrInfo& ii) 00049 : II(&ii), TM(tm), MCE(mce) {} 00050 00051 bool runOnMachineFunction(MachineFunction &MF); 00052 00053 virtual const char *getPassName() const { 00054 return "Alpha Machine Code Emitter"; 00055 } 00056 00057 void emitInstruction(const MachineInstr &MI); 00058 00059 /// getBinaryCodeForInstr - This function, generated by the 00060 /// CodeEmitterGenerator using TableGen, produces the binary encoding for 00061 /// machine instructions. 00062 /// 00063 unsigned getBinaryCodeForInstr(MachineInstr &MI); 00064 00065 private: 00066 void emitBasicBlock(MachineBasicBlock &MBB); 00067 00068 }; 00069 } 00070 00071 /// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha code 00072 /// to the specified MCE object. 00073 FunctionPass *llvm::createAlphaCodeEmitterPass(AlphaTargetMachine &TM, 00074 MachineCodeEmitter &MCE) { 00075 return new AlphaCodeEmitter(TM, MCE); 00076 } 00077 00078 bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 00079 II = ((AlphaTargetMachine&)MF.getTarget()).getInstrInfo(); 00080 00081 do { 00082 MCE.startFunction(MF); 00083 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) 00084 emitBasicBlock(*I); 00085 } while (MCE.finishFunction(MF)); 00086 00087 return false; 00088 } 00089 00090 void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { 00091 MCE.StartMachineBasicBlock(&MBB); 00092 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); 00093 I != E; ++I) { 00094 MachineInstr &MI = *I; 00095 unsigned Opcode = MI.getOpcode(); 00096 switch(MI.getOpcode()) { 00097 default: 00098 MCE.emitWordLE(getBinaryCodeForInstr(*I)); 00099 break; 00100 case Alpha::ALTENT: 00101 case Alpha::PCLABEL: 00102 case Alpha::MEMLABEL: 00103 case Alpha::IDEF_I: 00104 case Alpha::IDEF_F32: 00105 case Alpha::IDEF_F64: 00106 break; //skip these 00107 } 00108 } 00109 } 00110 00111 static unsigned getAlphaRegNumber(unsigned Reg) { 00112 switch (Reg) { 00113 case Alpha::R0 : case Alpha::F0 : return 0; 00114 case Alpha::R1 : case Alpha::F1 : return 1; 00115 case Alpha::R2 : case Alpha::F2 : return 2; 00116 case Alpha::R3 : case Alpha::F3 : return 3; 00117 case Alpha::R4 : case Alpha::F4 : return 4; 00118 case Alpha::R5 : case Alpha::F5 : return 5; 00119 case Alpha::R6 : case Alpha::F6 : return 6; 00120 case Alpha::R7 : case Alpha::F7 : return 7; 00121 case Alpha::R8 : case Alpha::F8 : return 8; 00122 case Alpha::R9 : case Alpha::F9 : return 9; 00123 case Alpha::R10 : case Alpha::F10 : return 10; 00124 case Alpha::R11 : case Alpha::F11 : return 11; 00125 case Alpha::R12 : case Alpha::F12 : return 12; 00126 case Alpha::R13 : case Alpha::F13 : return 13; 00127 case Alpha::R14 : case Alpha::F14 : return 14; 00128 case Alpha::R15 : case Alpha::F15 : return 15; 00129 case Alpha::R16 : case Alpha::F16 : return 16; 00130 case Alpha::R17 : case Alpha::F17 : return 17; 00131 case Alpha::R18 : case Alpha::F18 : return 18; 00132 case Alpha::R19 : case Alpha::F19 : return 19; 00133 case Alpha::R20 : case Alpha::F20 : return 20; 00134 case Alpha::R21 : case Alpha::F21 : return 21; 00135 case Alpha::R22 : case Alpha::F22 : return 22; 00136 case Alpha::R23 : case Alpha::F23 : return 23; 00137 case Alpha::R24 : case Alpha::F24 : return 24; 00138 case Alpha::R25 : case Alpha::F25 : return 25; 00139 case Alpha::R26 : case Alpha::F26 : return 26; 00140 case Alpha::R27 : case Alpha::F27 : return 27; 00141 case Alpha::R28 : case Alpha::F28 : return 28; 00142 case Alpha::R29 : case Alpha::F29 : return 29; 00143 case Alpha::R30 : case Alpha::F30 : return 30; 00144 case Alpha::R31 : case Alpha::F31 : return 31; 00145 default: 00146 assert(0 && "Unhandled reg"); 00147 abort(); 00148 } 00149 } 00150 00151 int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { 00152 00153 int rv = 0; // Return value; defaults to 0 for unhandled cases 00154 // or things that get fixed up later by the JIT. 00155 00156 if (MO.isRegister()) { 00157 rv = getAlphaRegNumber(MO.getReg()); 00158 } else if (MO.isImmediate()) { 00159 rv = MO.getImmedValue(); 00160 } else if (MO.isGlobalAddress() || MO.isExternalSymbol() 00161 || MO.isConstantPoolIndex()) { 00162 DEBUG(std::cerr << MO << " is a relocated op for " << MI << "\n";); 00163 bool isExternal = MO.isExternalSymbol() || 00164 (MO.isGlobalAddress() && 00165 ( MO.getGlobal()->hasWeakLinkage() || 00166 MO.getGlobal()->isExternal()) ); 00167 unsigned Reloc = 0; 00168 int Offset = 0; 00169 bool useGOT = false; 00170 switch (MI.getOpcode()) { 00171 case Alpha::BSR: 00172 Reloc = Alpha::reloc_bsr; 00173 break; 00174 case Alpha::LDLr: 00175 case Alpha::LDQr: 00176 case Alpha::LDBUr: 00177 case Alpha::LDWUr: 00178 case Alpha::LDSr: 00179 case Alpha::LDTr: 00180 case Alpha::LDAr: 00181 case Alpha::STQr: 00182 case Alpha::STLr: 00183 case Alpha::STWr: 00184 case Alpha::STBr: 00185 case Alpha::STSr: 00186 case Alpha::STTr: 00187 Reloc = Alpha::reloc_gprellow; 00188 break; 00189 case Alpha::LDAHr: 00190 Reloc = Alpha::reloc_gprelhigh; 00191 break; 00192 case Alpha::LDQl: 00193 Reloc = Alpha::reloc_literal; 00194 useGOT = true; 00195 break; 00196 case Alpha::LDAg: 00197 case Alpha::LDAHg: 00198 Reloc = Alpha::reloc_gpdist; 00199 Offset = MI.getOperand(3).getImmedValue(); 00200 break; 00201 default: 00202 assert(0 && "unknown relocatable instruction"); 00203 abort(); 00204 } 00205 if (MO.isGlobalAddress()) 00206 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), 00207 Reloc, MO.getGlobal(), Offset, 00208 false, useGOT)); 00209 else if (MO.isExternalSymbol()) 00210 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 00211 Reloc, MO.getSymbolName(), Offset, 00212 true)); 00213 else 00214 MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 00215 Reloc, MO.getConstantPoolIndex(), 00216 Offset)); 00217 } else if (MO.isMachineBasicBlock()) { 00218 TM.getJITInfo()->addBBRef(MO.getMachineBasicBlock(), 00219 MCE.getCurrentPCValue()); 00220 }else { 00221 std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; 00222 abort(); 00223 } 00224 00225 return rv; 00226 } 00227 00228 00229 #include "AlphaGenCodeEmitter.inc" 00230