LLVM API Documentation
00001 //===-- X86/X86CodeEmitter.cpp - Convert X86 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 X86 machine instructions into 00011 // relocatable machine code. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "X86TargetMachine.h" 00016 #include "X86Relocations.h" 00017 #include "X86.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/ADT/Statistic.h" 00025 #include "llvm/Target/TargetOptions.h" 00026 #include <iostream> 00027 using namespace llvm; 00028 00029 namespace { 00030 Statistic<> 00031 NumEmitted("x86-emitter", "Number of machine instructions emitted"); 00032 } 00033 00034 namespace { 00035 class Emitter : public MachineFunctionPass { 00036 const X86InstrInfo *II; 00037 MachineCodeEmitter &MCE; 00038 std::map<const MachineBasicBlock*, unsigned> BasicBlockAddrs; 00039 std::vector<std::pair<const MachineBasicBlock *, unsigned> > BBRefs; 00040 public: 00041 explicit Emitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {} 00042 Emitter(MachineCodeEmitter &mce, const X86InstrInfo& ii) 00043 : II(&ii), MCE(mce) {} 00044 00045 bool runOnMachineFunction(MachineFunction &MF); 00046 00047 virtual const char *getPassName() const { 00048 return "X86 Machine Code Emitter"; 00049 } 00050 00051 void emitInstruction(const MachineInstr &MI); 00052 00053 private: 00054 void emitBasicBlock(const MachineBasicBlock &MBB); 00055 00056 void emitPCRelativeBlockAddress(const MachineBasicBlock *BB); 00057 void emitPCRelativeValue(unsigned Address); 00058 void emitGlobalAddressForCall(GlobalValue *GV, bool isTailCall); 00059 void emitGlobalAddressForPtr(GlobalValue *GV, int Disp = 0); 00060 void emitExternalSymbolAddress(const char *ES, bool isPCRelative, 00061 bool isTailCall); 00062 00063 void emitRegModRMByte(unsigned ModRMReg, unsigned RegOpcodeField); 00064 void emitSIBByte(unsigned SS, unsigned Index, unsigned Base); 00065 void emitConstant(unsigned Val, unsigned Size); 00066 00067 void emitMemModRMByte(const MachineInstr &MI, 00068 unsigned Op, unsigned RegOpcodeField); 00069 00070 }; 00071 } 00072 00073 /// createX86CodeEmitterPass - Return a pass that emits the collected X86 code 00074 /// to the specified MCE object. 00075 FunctionPass *llvm::createX86CodeEmitterPass(MachineCodeEmitter &MCE) { 00076 return new Emitter(MCE); 00077 } 00078 00079 bool Emitter::runOnMachineFunction(MachineFunction &MF) { 00080 assert((MF.getTarget().getRelocationModel() != Reloc::Default || 00081 MF.getTarget().getRelocationModel() != Reloc::Static) && 00082 "JIT relocation model must be set to static or default!"); 00083 II = ((X86TargetMachine&)MF.getTarget()).getInstrInfo(); 00084 00085 MCE.startFunction(MF); 00086 MCE.emitConstantPool(MF.getConstantPool()); 00087 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) 00088 emitBasicBlock(*I); 00089 MCE.finishFunction(MF); 00090 00091 // Resolve all forward branches now... 00092 for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { 00093 unsigned Location = BasicBlockAddrs[BBRefs[i].first]; 00094 unsigned Ref = BBRefs[i].second; 00095 MCE.emitWordAt(Location-Ref-4, (unsigned*)(intptr_t)Ref); 00096 } 00097 BBRefs.clear(); 00098 BasicBlockAddrs.clear(); 00099 return false; 00100 } 00101 00102 void Emitter::emitBasicBlock(const MachineBasicBlock &MBB) { 00103 if (uint64_t Addr = MCE.getCurrentPCValue()) 00104 BasicBlockAddrs[&MBB] = Addr; 00105 00106 for (MachineBasicBlock::const_iterator I = MBB.begin(), E = MBB.end(); 00107 I != E; ++I) 00108 emitInstruction(*I); 00109 } 00110 00111 /// emitPCRelativeValue - Emit a 32-bit PC relative address. 00112 /// 00113 void Emitter::emitPCRelativeValue(unsigned Address) { 00114 MCE.emitWord(Address-MCE.getCurrentPCValue()-4); 00115 } 00116 00117 /// emitPCRelativeBlockAddress - This method emits the PC relative address of 00118 /// the specified basic block, or if the basic block hasn't been emitted yet 00119 /// (because this is a forward branch), it keeps track of the information 00120 /// necessary to resolve this address later (and emits a dummy value). 00121 /// 00122 void Emitter::emitPCRelativeBlockAddress(const MachineBasicBlock *MBB) { 00123 // If this is a backwards branch, we already know the address of the target, 00124 // so just emit the value. 00125 std::map<const MachineBasicBlock*, unsigned>::iterator I = 00126 BasicBlockAddrs.find(MBB); 00127 if (I != BasicBlockAddrs.end()) { 00128 emitPCRelativeValue(I->second); 00129 } else { 00130 // Otherwise, remember where this reference was and where it is to so we can 00131 // deal with it later. 00132 BBRefs.push_back(std::make_pair(MBB, MCE.getCurrentPCValue())); 00133 MCE.emitWord(0); 00134 } 00135 } 00136 00137 /// emitGlobalAddressForCall - Emit the specified address to the code stream 00138 /// assuming this is part of a function call, which is PC relative. 00139 /// 00140 void Emitter::emitGlobalAddressForCall(GlobalValue *GV, bool isTailCall) { 00141 MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(), 00142 X86::reloc_pcrel_word, GV, 0, 00143 !isTailCall /*Doesn'tNeedStub*/)); 00144 MCE.emitWord(0); 00145 } 00146 00147 /// emitGlobalAddress - Emit the specified address to the code stream assuming 00148 /// this is part of a "take the address of a global" instruction, which is not 00149 /// PC relative. 00150 /// 00151 void Emitter::emitGlobalAddressForPtr(GlobalValue *GV, int Disp /* = 0 */) { 00152 MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(), 00153 X86::reloc_absolute_word, GV)); 00154 MCE.emitWord(Disp); // The relocated value will be added to the displacement 00155 } 00156 00157 /// emitExternalSymbolAddress - Arrange for the address of an external symbol to 00158 /// be emitted to the current location in the function, and allow it to be PC 00159 /// relative. 00160 void Emitter::emitExternalSymbolAddress(const char *ES, bool isPCRelative, 00161 bool isTailCall) { 00162 MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(), 00163 isPCRelative ? X86::reloc_pcrel_word : X86::reloc_absolute_word, ES)); 00164 MCE.emitWord(0); 00165 } 00166 00167 /// N86 namespace - Native X86 Register numbers... used by X86 backend. 00168 /// 00169 namespace N86 { 00170 enum { 00171 EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7 00172 }; 00173 } 00174 00175 00176 // getX86RegNum - This function maps LLVM register identifiers to their X86 00177 // specific numbering, which is used in various places encoding instructions. 00178 // 00179 static unsigned getX86RegNum(unsigned RegNo) { 00180 switch(RegNo) { 00181 case X86::EAX: case X86::AX: case X86::AL: return N86::EAX; 00182 case X86::ECX: case X86::CX: case X86::CL: return N86::ECX; 00183 case X86::EDX: case X86::DX: case X86::DL: return N86::EDX; 00184 case X86::EBX: case X86::BX: case X86::BL: return N86::EBX; 00185 case X86::ESP: case X86::SP: case X86::AH: return N86::ESP; 00186 case X86::EBP: case X86::BP: case X86::CH: return N86::EBP; 00187 case X86::ESI: case X86::SI: case X86::DH: return N86::ESI; 00188 case X86::EDI: case X86::DI: case X86::BH: return N86::EDI; 00189 00190 case X86::ST0: case X86::ST1: case X86::ST2: case X86::ST3: 00191 case X86::ST4: case X86::ST5: case X86::ST6: case X86::ST7: 00192 return RegNo-X86::ST0; 00193 00194 case X86::XMM0: case X86::XMM1: case X86::XMM2: case X86::XMM3: 00195 case X86::XMM4: case X86::XMM5: case X86::XMM6: case X86::XMM7: 00196 return RegNo-X86::XMM0; 00197 00198 default: 00199 assert(MRegisterInfo::isVirtualRegister(RegNo) && 00200 "Unknown physical register!"); 00201 assert(0 && "Register allocator hasn't allocated reg correctly yet!"); 00202 return 0; 00203 } 00204 } 00205 00206 inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode, 00207 unsigned RM) { 00208 assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!"); 00209 return RM | (RegOpcode << 3) | (Mod << 6); 00210 } 00211 00212 void Emitter::emitRegModRMByte(unsigned ModRMReg, unsigned RegOpcodeFld){ 00213 MCE.emitByte(ModRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg))); 00214 } 00215 00216 void Emitter::emitSIBByte(unsigned SS, unsigned Index, unsigned Base) { 00217 // SIB byte is in the same format as the ModRMByte... 00218 MCE.emitByte(ModRMByte(SS, Index, Base)); 00219 } 00220 00221 void Emitter::emitConstant(unsigned Val, unsigned Size) { 00222 // Output the constant in little endian byte order... 00223 for (unsigned i = 0; i != Size; ++i) { 00224 MCE.emitByte(Val & 255); 00225 Val >>= 8; 00226 } 00227 } 00228 00229 static bool isDisp8(int Value) { 00230 return Value == (signed char)Value; 00231 } 00232 00233 void Emitter::emitMemModRMByte(const MachineInstr &MI, 00234 unsigned Op, unsigned RegOpcodeField) { 00235 const MachineOperand &Op3 = MI.getOperand(Op+3); 00236 GlobalValue *GV = 0; 00237 int DispVal = 0; 00238 00239 if (Op3.isGlobalAddress()) { 00240 GV = Op3.getGlobal(); 00241 DispVal = Op3.getOffset(); 00242 } else if (Op3.isConstantPoolIndex()) { 00243 DispVal += MCE.getConstantPoolEntryAddress(Op3.getConstantPoolIndex()); 00244 DispVal += Op3.getOffset(); 00245 } else { 00246 DispVal = Op3.getImmedValue(); 00247 } 00248 00249 const MachineOperand &Base = MI.getOperand(Op); 00250 const MachineOperand &Scale = MI.getOperand(Op+1); 00251 const MachineOperand &IndexReg = MI.getOperand(Op+2); 00252 00253 unsigned BaseReg = Base.getReg(); 00254 00255 // Is a SIB byte needed? 00256 if (IndexReg.getReg() == 0 && BaseReg != X86::ESP) { 00257 if (BaseReg == 0) { // Just a displacement? 00258 // Emit special case [disp32] encoding 00259 MCE.emitByte(ModRMByte(0, RegOpcodeField, 5)); 00260 if (GV) 00261 emitGlobalAddressForPtr(GV, DispVal); 00262 else 00263 emitConstant(DispVal, 4); 00264 } else { 00265 unsigned BaseRegNo = getX86RegNum(BaseReg); 00266 if (GV) { 00267 // Emit the most general non-SIB encoding: [REG+disp32] 00268 MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo)); 00269 emitGlobalAddressForPtr(GV, DispVal); 00270 } else if (DispVal == 0 && BaseRegNo != N86::EBP) { 00271 // Emit simple indirect register encoding... [EAX] f.e. 00272 MCE.emitByte(ModRMByte(0, RegOpcodeField, BaseRegNo)); 00273 } else if (isDisp8(DispVal)) { 00274 // Emit the disp8 encoding... [REG+disp8] 00275 MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo)); 00276 emitConstant(DispVal, 1); 00277 } else { 00278 // Emit the most general non-SIB encoding: [REG+disp32] 00279 MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo)); 00280 emitConstant(DispVal, 4); 00281 } 00282 } 00283 00284 } else { // We need a SIB byte, so start by outputting the ModR/M byte first 00285 assert(IndexReg.getReg() != X86::ESP && "Cannot use ESP as index reg!"); 00286 00287 bool ForceDisp32 = false; 00288 bool ForceDisp8 = false; 00289 if (BaseReg == 0) { 00290 // If there is no base register, we emit the special case SIB byte with 00291 // MOD=0, BASE=5, to JUST get the index, scale, and displacement. 00292 MCE.emitByte(ModRMByte(0, RegOpcodeField, 4)); 00293 ForceDisp32 = true; 00294 } else if (GV) { 00295 // Emit the normal disp32 encoding... 00296 MCE.emitByte(ModRMByte(2, RegOpcodeField, 4)); 00297 ForceDisp32 = true; 00298 } else if (DispVal == 0 && BaseReg != X86::EBP) { 00299 // Emit no displacement ModR/M byte 00300 MCE.emitByte(ModRMByte(0, RegOpcodeField, 4)); 00301 } else if (isDisp8(DispVal)) { 00302 // Emit the disp8 encoding... 00303 MCE.emitByte(ModRMByte(1, RegOpcodeField, 4)); 00304 ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP 00305 } else { 00306 // Emit the normal disp32 encoding... 00307 MCE.emitByte(ModRMByte(2, RegOpcodeField, 4)); 00308 } 00309 00310 // Calculate what the SS field value should be... 00311 static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 }; 00312 unsigned SS = SSTable[Scale.getImmedValue()]; 00313 00314 if (BaseReg == 0) { 00315 // Handle the SIB byte for the case where there is no base. The 00316 // displacement has already been output. 00317 assert(IndexReg.getReg() && "Index register must be specified!"); 00318 emitSIBByte(SS, getX86RegNum(IndexReg.getReg()), 5); 00319 } else { 00320 unsigned BaseRegNo = getX86RegNum(BaseReg); 00321 unsigned IndexRegNo; 00322 if (IndexReg.getReg()) 00323 IndexRegNo = getX86RegNum(IndexReg.getReg()); 00324 else 00325 IndexRegNo = 4; // For example [ESP+1*<noreg>+4] 00326 emitSIBByte(SS, IndexRegNo, BaseRegNo); 00327 } 00328 00329 // Do we need to output a displacement? 00330 if (DispVal != 0 || ForceDisp32 || ForceDisp8) { 00331 if (!ForceDisp32 && isDisp8(DispVal)) 00332 emitConstant(DispVal, 1); 00333 else if (GV) 00334 emitGlobalAddressForPtr(GV, DispVal); 00335 else 00336 emitConstant(DispVal, 4); 00337 } 00338 } 00339 } 00340 00341 static unsigned sizeOfImm(const TargetInstrDescriptor &Desc) { 00342 switch (Desc.TSFlags & X86II::ImmMask) { 00343 case X86II::Imm8: return 1; 00344 case X86II::Imm16: return 2; 00345 case X86II::Imm32: return 4; 00346 default: assert(0 && "Immediate size not set!"); 00347 return 0; 00348 } 00349 } 00350 00351 void Emitter::emitInstruction(const MachineInstr &MI) { 00352 NumEmitted++; // Keep track of the # of mi's emitted 00353 00354 unsigned Opcode = MI.getOpcode(); 00355 const TargetInstrDescriptor &Desc = II->get(Opcode); 00356 00357 // Emit the repeat opcode prefix as needed. 00358 if ((Desc.TSFlags & X86II::Op0Mask) == X86II::REP) MCE.emitByte(0xF3); 00359 00360 // Emit the operand size opcode prefix as needed. 00361 if (Desc.TSFlags & X86II::OpSize) MCE.emitByte(0x66); 00362 00363 switch (Desc.TSFlags & X86II::Op0Mask) { 00364 case X86II::TB: 00365 MCE.emitByte(0x0F); // Two-byte opcode prefix 00366 break; 00367 case X86II::REP: break; // already handled. 00368 case X86II::XS: // F3 0F 00369 MCE.emitByte(0xF3); 00370 MCE.emitByte(0x0F); 00371 break; 00372 case X86II::XD: // F2 0F 00373 MCE.emitByte(0xF2); 00374 MCE.emitByte(0x0F); 00375 break; 00376 case X86II::D8: case X86II::D9: case X86II::DA: case X86II::DB: 00377 case X86II::DC: case X86II::DD: case X86II::DE: case X86II::DF: 00378 MCE.emitByte(0xD8+ 00379 (((Desc.TSFlags & X86II::Op0Mask)-X86II::D8) 00380 >> X86II::Op0Shift)); 00381 break; // Two-byte opcode prefix 00382 default: assert(0 && "Invalid prefix!"); 00383 case 0: break; // No prefix! 00384 } 00385 00386 unsigned char BaseOpcode = II->getBaseOpcodeFor(Opcode); 00387 switch (Desc.TSFlags & X86II::FormMask) { 00388 default: assert(0 && "Unknown FormMask value in X86 MachineCodeEmitter!"); 00389 case X86II::Pseudo: 00390 #ifndef NDEBUG 00391 switch (Opcode) { 00392 default: 00393 assert(0 && "psuedo instructions should be removed before code emission"); 00394 case X86::IMPLICIT_USE: 00395 case X86::IMPLICIT_DEF: 00396 case X86::IMPLICIT_DEF_R8: 00397 case X86::IMPLICIT_DEF_R16: 00398 case X86::IMPLICIT_DEF_R32: 00399 case X86::IMPLICIT_DEF_FR32: 00400 case X86::IMPLICIT_DEF_FR64: 00401 case X86::IMPLICIT_DEF_VR64: 00402 case X86::IMPLICIT_DEF_VR128: 00403 case X86::FP_REG_KILL: 00404 break; 00405 } 00406 #endif 00407 break; 00408 00409 case X86II::RawFrm: 00410 MCE.emitByte(BaseOpcode); 00411 if (MI.getNumOperands() == 1) { 00412 const MachineOperand &MO = MI.getOperand(0); 00413 if (MO.isMachineBasicBlock()) { 00414 emitPCRelativeBlockAddress(MO.getMachineBasicBlock()); 00415 } else if (MO.isGlobalAddress()) { 00416 bool isTailCall = Opcode == X86::TAILJMPd || 00417 Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm; 00418 emitGlobalAddressForCall(MO.getGlobal(), isTailCall); 00419 } else if (MO.isExternalSymbol()) { 00420 bool isTailCall = Opcode == X86::TAILJMPd || 00421 Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm; 00422 emitExternalSymbolAddress(MO.getSymbolName(), true, isTailCall); 00423 } else if (MO.isImmediate()) { 00424 emitConstant(MO.getImmedValue(), sizeOfImm(Desc)); 00425 } else { 00426 assert(0 && "Unknown RawFrm operand!"); 00427 } 00428 } 00429 break; 00430 00431 case X86II::AddRegFrm: 00432 MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg())); 00433 if (MI.getNumOperands() == 2) { 00434 const MachineOperand &MO1 = MI.getOperand(1); 00435 if (Value *V = MO1.getVRegValueOrNull()) { 00436 assert(sizeOfImm(Desc) == 4 && 00437 "Don't know how to emit non-pointer values!"); 00438 emitGlobalAddressForPtr(cast<GlobalValue>(V)); 00439 } else if (MO1.isGlobalAddress()) { 00440 assert(sizeOfImm(Desc) == 4 && 00441 "Don't know how to emit non-pointer values!"); 00442 assert(!MO1.isPCRelative() && "Function pointer ref is PC relative?"); 00443 emitGlobalAddressForPtr(MO1.getGlobal(), MO1.getOffset()); 00444 } else if (MO1.isExternalSymbol()) { 00445 assert(sizeOfImm(Desc) == 4 && 00446 "Don't know how to emit non-pointer values!"); 00447 emitExternalSymbolAddress(MO1.getSymbolName(), false, false); 00448 } else { 00449 emitConstant(MO1.getImmedValue(), sizeOfImm(Desc)); 00450 } 00451 } 00452 break; 00453 00454 case X86II::MRMDestReg: { 00455 MCE.emitByte(BaseOpcode); 00456 emitRegModRMByte(MI.getOperand(0).getReg(), 00457 getX86RegNum(MI.getOperand(1).getReg())); 00458 if (MI.getNumOperands() == 3) 00459 emitConstant(MI.getOperand(2).getImmedValue(), sizeOfImm(Desc)); 00460 break; 00461 } 00462 case X86II::MRMDestMem: 00463 MCE.emitByte(BaseOpcode); 00464 emitMemModRMByte(MI, 0, getX86RegNum(MI.getOperand(4).getReg())); 00465 if (MI.getNumOperands() == 6) 00466 emitConstant(MI.getOperand(5).getImmedValue(), sizeOfImm(Desc)); 00467 break; 00468 00469 case X86II::MRMSrcReg: 00470 MCE.emitByte(BaseOpcode); 00471 emitRegModRMByte(MI.getOperand(1).getReg(), 00472 getX86RegNum(MI.getOperand(0).getReg())); 00473 if (MI.getNumOperands() == 3) 00474 emitConstant(MI.getOperand(2).getImmedValue(), sizeOfImm(Desc)); 00475 break; 00476 00477 case X86II::MRMSrcMem: 00478 MCE.emitByte(BaseOpcode); 00479 emitMemModRMByte(MI, 1, getX86RegNum(MI.getOperand(0).getReg())); 00480 if (MI.getNumOperands() == 2+4) 00481 emitConstant(MI.getOperand(5).getImmedValue(), sizeOfImm(Desc)); 00482 break; 00483 00484 case X86II::MRM0r: case X86II::MRM1r: 00485 case X86II::MRM2r: case X86II::MRM3r: 00486 case X86II::MRM4r: case X86II::MRM5r: 00487 case X86II::MRM6r: case X86II::MRM7r: 00488 MCE.emitByte(BaseOpcode); 00489 emitRegModRMByte(MI.getOperand(0).getReg(), 00490 (Desc.TSFlags & X86II::FormMask)-X86II::MRM0r); 00491 00492 if (MI.getOperand(MI.getNumOperands()-1).isImmediate()) { 00493 emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), 00494 sizeOfImm(Desc)); 00495 } 00496 break; 00497 00498 case X86II::MRM0m: case X86II::MRM1m: 00499 case X86II::MRM2m: case X86II::MRM3m: 00500 case X86II::MRM4m: case X86II::MRM5m: 00501 case X86II::MRM6m: case X86II::MRM7m: 00502 MCE.emitByte(BaseOpcode); 00503 emitMemModRMByte(MI, 0, (Desc.TSFlags & X86II::FormMask)-X86II::MRM0m); 00504 00505 if (MI.getNumOperands() == 5) { 00506 if (MI.getOperand(4).isImmediate()) 00507 emitConstant(MI.getOperand(4).getImmedValue(), sizeOfImm(Desc)); 00508 else if (MI.getOperand(4).isGlobalAddress()) 00509 emitGlobalAddressForPtr(MI.getOperand(4).getGlobal(), 00510 MI.getOperand(4).getOffset()); 00511 else 00512 assert(0 && "Unknown operand!"); 00513 } 00514 break; 00515 00516 case X86II::MRMInitReg: 00517 MCE.emitByte(BaseOpcode); 00518 emitRegModRMByte(MI.getOperand(0).getReg(), 00519 getX86RegNum(MI.getOperand(0).getReg())); 00520 break; 00521 } 00522 }