X86MCInstLower.cpp revision 14c38ec2afeaf25c53a50c2c65116aca8c889401
1bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner//===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===// 2bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// 3bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// The LLVM Compiler Infrastructure 4bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// 5bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// This file is distributed under the University of Illinois Open Source 6bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// License. See LICENSE.TXT for details. 7bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// 8bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner//===----------------------------------------------------------------------===// 9bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// 10bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// This file contains code to lower X86 MachineInstrs to their corresponding 11bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// MCInst records. 12bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner// 13bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner//===----------------------------------------------------------------------===// 14bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 15bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "X86MCInstLower.h" 16bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "X86AsmPrinter.h" 17bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "X86MCAsmInfo.h" 18bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "X86COFFMachineModuleInfo.h" 19bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "llvm/Analysis/DebugInfo.h" 20bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h" 21bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "llvm/MC/MCContext.h" 22bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "llvm/MC/MCExpr.h" 23bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "llvm/MC/MCInst.h" 24bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "llvm/MC/MCStreamer.h" 25bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "llvm/Target/Mangler.h" 26bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "llvm/Support/FormattedStream.h" 27bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner#include "llvm/ADT/SmallString.h" 28bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattnerusing namespace llvm; 29bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 30bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 31bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattnerconst X86Subtarget &X86MCInstLower::getSubtarget() const { 32bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner return AsmPrinter.getSubtarget(); 33bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner} 34bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 35bc40e898e153c9b81f246a7971eaac7b14446c49Chris LattnerMachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const { 36bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner assert(getSubtarget().isTargetDarwin() &&"Can only get MachO info on darwin"); 37bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner return AsmPrinter.MMI->getObjFileInfo<MachineModuleInfoMachO>(); 38bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner} 39bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 40bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 41bc40e898e153c9b81f246a7971eaac7b14446c49Chris LattnerMCSymbol *X86MCInstLower::GetPICBaseSymbol() const { 42bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner const TargetLowering *TLI = AsmPrinter.TM.getTargetLowering(); 43bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner return static_cast<const X86TargetLowering*>(TLI)-> 44bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner getPICBaseSymbol(AsmPrinter.MF, Ctx); 45bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner} 46bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 47bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner/// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an 48bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner/// MCOperand. 49bc40e898e153c9b81f246a7971eaac7b14446c49Chris LattnerMCSymbol *X86MCInstLower:: 50bc40e898e153c9b81f246a7971eaac7b14446c49Chris LattnerGetGlobalAddressSymbol(const MachineOperand &MO) const { 51bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner const GlobalValue *GV = MO.getGlobal(); 52bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 53bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner bool isImplicitlyPrivate = false; 54bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB || 55bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 56bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || 57bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) 58bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner isImplicitlyPrivate = true; 59bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 60bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner SmallString<128> Name; 61bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate); 62bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 63bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner if (getSubtarget().isTargetCygMing()) { 64bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner X86COFFMachineModuleInfo &COFFMMI = 65bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner AsmPrinter.MMI->getObjFileInfo<X86COFFMachineModuleInfo>(); 66bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner COFFMMI.DecorateCygMingName(Name, GV, *AsmPrinter.TM.getTargetData()); 67bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner } 68bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 69bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner switch (MO.getTargetFlags()) { 70bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner default: llvm_unreachable("Unknown target flag on GV operand"); 71bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_NO_FLAG: // No flag. 72bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_PIC_BASE_OFFSET: // Doesn't modify symbol name. 73bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner break; 74bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_DLLIMPORT: { 75bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner // Handle dllimport linkage. 76bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner const char *Prefix = "__imp_"; 77bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix)); 78bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner break; 79bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner } 80bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_DARWIN_NONLAZY: 81bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_DARWIN_NONLAZY_PIC_BASE: { 82bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner Name += "$non_lazy_ptr"; 83bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 84bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 85bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner const MCSymbol *&StubSym = getMachOMMI().getGVStubEntry(Sym); 86bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner if (StubSym == 0) 87bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner StubSym = AsmPrinter.GetGlobalValueSymbol(GV); 88bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner return Sym; 89bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner } 90bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: { 91bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner Name += "$non_lazy_ptr"; 92bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 93bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner const MCSymbol *&StubSym = getMachOMMI().getHiddenGVStubEntry(Sym); 94bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner if (StubSym == 0) 95bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner StubSym = AsmPrinter.GetGlobalValueSymbol(GV); 96bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner return Sym; 97bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner } 98bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_DARWIN_STUB: { 99bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner Name += "$stub"; 100bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 101bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner const MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym); 102bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner if (StubSym == 0) 103bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner StubSym = AsmPrinter.GetGlobalValueSymbol(GV); 104bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner return Sym; 105bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner } 106bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner // FIXME: These probably should be a modifier on the symbol or something?? 107bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_TLSGD: Name += "@TLSGD"; break; 108bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break; 109bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break; 110bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_TPOFF: Name += "@TPOFF"; break; 111bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_NTPOFF: Name += "@NTPOFF"; break; 112bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break; 113bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_GOT: Name += "@GOT"; break; 114bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_GOTOFF: Name += "@GOTOFF"; break; 115bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_PLT: Name += "@PLT"; break; 116bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner } 117bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 118bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner return Ctx.GetOrCreateSymbol(Name.str()); 119bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner} 120bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 121bc40e898e153c9b81f246a7971eaac7b14446c49Chris LattnerMCSymbol *X86MCInstLower:: 122bc40e898e153c9b81f246a7971eaac7b14446c49Chris LattnerGetExternalSymbolSymbol(const MachineOperand &MO) const { 123bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner SmallString<128> Name; 124bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner Name += AsmPrinter.MAI->getGlobalPrefix(); 125bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner Name += MO.getSymbolName(); 126bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner 127bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner switch (MO.getTargetFlags()) { 128bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner default: llvm_unreachable("Unknown target flag on GV operand"); 129bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_NO_FLAG: // No flag. 130bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_GOT_ABSOLUTE_ADDRESS: // Doesn't modify symbol name. 131bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_PIC_BASE_OFFSET: // Doesn't modify symbol name. 132bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner break; 133bc40e898e153c9b81f246a7971eaac7b14446c49Chris Lattner case X86II::MO_DLLIMPORT: { 134 // Handle dllimport linkage. 135 const char *Prefix = "__imp_"; 136 Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix)); 137 break; 138 } 139 case X86II::MO_DARWIN_STUB: { 140 Name += "$stub"; 141 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 142 const MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym); 143 144 if (StubSym == 0) { 145 Name.erase(Name.end()-5, Name.end()); 146 StubSym = Ctx.GetOrCreateSymbol(Name.str()); 147 } 148 return Sym; 149 } 150 // FIXME: These probably should be a modifier on the symbol or something?? 151 case X86II::MO_TLSGD: Name += "@TLSGD"; break; 152 case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break; 153 case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break; 154 case X86II::MO_TPOFF: Name += "@TPOFF"; break; 155 case X86II::MO_NTPOFF: Name += "@NTPOFF"; break; 156 case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break; 157 case X86II::MO_GOT: Name += "@GOT"; break; 158 case X86II::MO_GOTOFF: Name += "@GOTOFF"; break; 159 case X86II::MO_PLT: Name += "@PLT"; break; 160 } 161 162 return Ctx.GetOrCreateSymbol(Name.str()); 163} 164 165MCSymbol *X86MCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const { 166 SmallString<256> Name; 167 // FIXME: Use AsmPrinter.GetJTISymbol. @TLSGD shouldn't be part of the symbol 168 // name! 169 raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "JTI" 170 << AsmPrinter.getFunctionNumber() << '_' << MO.getIndex(); 171 172 switch (MO.getTargetFlags()) { 173 default: 174 llvm_unreachable("Unknown target flag on GV operand"); 175 case X86II::MO_NO_FLAG: // No flag. 176 case X86II::MO_PIC_BASE_OFFSET: 177 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 178 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: 179 break; 180 // FIXME: These probably should be a modifier on the symbol or something?? 181 case X86II::MO_TLSGD: Name += "@TLSGD"; break; 182 case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break; 183 case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break; 184 case X86II::MO_TPOFF: Name += "@TPOFF"; break; 185 case X86II::MO_NTPOFF: Name += "@NTPOFF"; break; 186 case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break; 187 case X86II::MO_GOT: Name += "@GOT"; break; 188 case X86II::MO_GOTOFF: Name += "@GOTOFF"; break; 189 case X86II::MO_PLT: Name += "@PLT"; break; 190 } 191 192 // Create a symbol for the name. 193 return Ctx.GetOrCreateSymbol(Name.str()); 194} 195 196 197MCSymbol *X86MCInstLower:: 198GetConstantPoolIndexSymbol(const MachineOperand &MO) const { 199 SmallString<256> Name; 200 // FIXME: USe AsmPrinter.GetCPISymbol. @TLSGD shouldn't be part of the symbol 201 // name! 202 raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "CPI" 203 << AsmPrinter.getFunctionNumber() << '_' << MO.getIndex(); 204 205 switch (MO.getTargetFlags()) { 206 default: 207 llvm_unreachable("Unknown target flag on GV operand"); 208 case X86II::MO_NO_FLAG: // No flag. 209 case X86II::MO_PIC_BASE_OFFSET: 210 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 211 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: 212 break; 213 // FIXME: These probably should be a modifier on the symbol or something?? 214 case X86II::MO_TLSGD: Name += "@TLSGD"; break; 215 case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break; 216 case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break; 217 case X86II::MO_TPOFF: Name += "@TPOFF"; break; 218 case X86II::MO_NTPOFF: Name += "@NTPOFF"; break; 219 case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break; 220 case X86II::MO_GOT: Name += "@GOT"; break; 221 case X86II::MO_GOTOFF: Name += "@GOTOFF"; break; 222 case X86II::MO_PLT: Name += "@PLT"; break; 223 } 224 225 // Create a symbol for the name. 226 return Ctx.GetOrCreateSymbol(Name.str()); 227} 228 229MCSymbol *X86MCInstLower:: 230GetBlockAddressSymbol(const MachineOperand &MO) const { 231 const char *Suffix = ""; 232 switch (MO.getTargetFlags()) { 233 default: llvm_unreachable("Unknown target flag on BA operand"); 234 case X86II::MO_NO_FLAG: break; // No flag. 235 case X86II::MO_PIC_BASE_OFFSET: break; // Doesn't modify symbol name. 236 case X86II::MO_GOTOFF: Suffix = "@GOTOFF"; break; 237 } 238 239 return AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress(), Suffix); 240} 241 242MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, 243 MCSymbol *Sym) const { 244 // FIXME: We would like an efficient form for this, so we don't have to do a 245 // lot of extra uniquing. 246 const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx); 247 248 switch (MO.getTargetFlags()) { 249 default: llvm_unreachable("Unknown target flag on GV operand"); 250 case X86II::MO_NO_FLAG: // No flag. 251 252 // These affect the name of the symbol, not any suffix. 253 case X86II::MO_DARWIN_NONLAZY: 254 case X86II::MO_DLLIMPORT: 255 case X86II::MO_DARWIN_STUB: 256 case X86II::MO_TLSGD: 257 case X86II::MO_GOTTPOFF: 258 case X86II::MO_INDNTPOFF: 259 case X86II::MO_TPOFF: 260 case X86II::MO_NTPOFF: 261 case X86II::MO_GOTPCREL: 262 case X86II::MO_GOT: 263 case X86II::MO_GOTOFF: 264 case X86II::MO_PLT: 265 break; 266 case X86II::MO_PIC_BASE_OFFSET: 267 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 268 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: 269 // Subtract the pic base. 270 Expr = MCBinaryExpr::CreateSub(Expr, 271 MCSymbolRefExpr::Create(GetPICBaseSymbol(), Ctx), 272 Ctx); 273 break; 274 } 275 276 if (!MO.isJTI() && MO.getOffset()) 277 Expr = MCBinaryExpr::CreateAdd(Expr, 278 MCConstantExpr::Create(MO.getOffset(), Ctx), 279 Ctx); 280 return MCOperand::CreateExpr(Expr); 281} 282 283 284 285static void lower_subreg32(MCInst *MI, unsigned OpNo) { 286 // Convert registers in the addr mode according to subreg32. 287 unsigned Reg = MI->getOperand(OpNo).getReg(); 288 if (Reg != 0) 289 MI->getOperand(OpNo).setReg(getX86SubSuperRegister(Reg, MVT::i32)); 290} 291 292static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) { 293 // Convert registers in the addr mode according to subreg64. 294 for (unsigned i = 0; i != 4; ++i) { 295 if (!MI->getOperand(OpNo+i).isReg()) continue; 296 297 unsigned Reg = MI->getOperand(OpNo+i).getReg(); 298 if (Reg == 0) continue; 299 300 MI->getOperand(OpNo+i).setReg(getX86SubSuperRegister(Reg, MVT::i64)); 301 } 302} 303 304 305 306void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 307 OutMI.setOpcode(MI->getOpcode()); 308 309 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 310 const MachineOperand &MO = MI->getOperand(i); 311 312 MCOperand MCOp; 313 switch (MO.getType()) { 314 default: 315 MI->dump(); 316 llvm_unreachable("unknown operand type"); 317 case MachineOperand::MO_Register: 318 // Ignore all implicit register operands. 319 if (MO.isImplicit()) continue; 320 MCOp = MCOperand::CreateReg(MO.getReg()); 321 break; 322 case MachineOperand::MO_Immediate: 323 MCOp = MCOperand::CreateImm(MO.getImm()); 324 break; 325 case MachineOperand::MO_MachineBasicBlock: 326 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 327 MO.getMBB()->getSymbol(Ctx), Ctx)); 328 break; 329 case MachineOperand::MO_GlobalAddress: 330 MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); 331 break; 332 case MachineOperand::MO_ExternalSymbol: 333 MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); 334 break; 335 case MachineOperand::MO_JumpTableIndex: 336 MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO)); 337 break; 338 case MachineOperand::MO_ConstantPoolIndex: 339 MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); 340 break; 341 case MachineOperand::MO_BlockAddress: 342 MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO)); 343 break; 344 } 345 346 OutMI.addOperand(MCOp); 347 } 348 349 // Handle a few special cases to eliminate operand modifiers. 350 switch (OutMI.getOpcode()) { 351 case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand. 352 lower_lea64_32mem(&OutMI, 1); 353 break; 354 case X86::MOVZX16rr8: 355 OutMI.setOpcode(X86::MOVZX32rr8); 356 lower_subreg32(&OutMI, 0); 357 break; 358 case X86::MOVZX16rm8: 359 OutMI.setOpcode(X86::MOVZX32rm8); 360 lower_subreg32(&OutMI, 0); 361 break; 362 case X86::MOVSX16rr8: 363 OutMI.setOpcode(X86::MOVSX32rr8); 364 lower_subreg32(&OutMI, 0); 365 break; 366 case X86::MOVSX16rm8: 367 OutMI.setOpcode(X86::MOVSX32rm8); 368 lower_subreg32(&OutMI, 0); 369 break; 370 case X86::MOVZX64rr32: 371 OutMI.setOpcode(X86::MOV32rr); 372 lower_subreg32(&OutMI, 0); 373 break; 374 case X86::MOVZX64rm32: 375 OutMI.setOpcode(X86::MOV32rm); 376 lower_subreg32(&OutMI, 0); 377 break; 378 case X86::MOV64ri64i32: 379 OutMI.setOpcode(X86::MOV32ri); 380 lower_subreg32(&OutMI, 0); 381 break; 382 case X86::MOVZX64rr8: 383 OutMI.setOpcode(X86::MOVZX32rr8); 384 lower_subreg32(&OutMI, 0); 385 break; 386 case X86::MOVZX64rm8: 387 OutMI.setOpcode(X86::MOVZX32rm8); 388 lower_subreg32(&OutMI, 0); 389 break; 390 case X86::MOVZX64rr16: 391 OutMI.setOpcode(X86::MOVZX32rr16); 392 lower_subreg32(&OutMI, 0); 393 break; 394 case X86::MOVZX64rm16: 395 OutMI.setOpcode(X86::MOVZX32rm16); 396 lower_subreg32(&OutMI, 0); 397 break; 398 case X86::MOV16r0: 399 OutMI.setOpcode(X86::MOV32r0); 400 lower_subreg32(&OutMI, 0); 401 break; 402 case X86::MOV64r0: 403 OutMI.setOpcode(X86::MOV32r0); 404 lower_subreg32(&OutMI, 0); 405 break; 406 } 407} 408 409 410 411void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { 412 X86MCInstLower MCInstLowering(OutContext, Mang, *this); 413 switch (MI->getOpcode()) { 414 case TargetInstrInfo::DBG_LABEL: 415 case TargetInstrInfo::EH_LABEL: 416 case TargetInstrInfo::GC_LABEL: 417 printLabel(MI); 418 return; 419 case TargetInstrInfo::DEBUG_VALUE: { 420 // FIXME: if this is implemented for another target before it goes 421 // away completely, the common part should be moved into AsmPrinter. 422 if (!VerboseAsm) 423 return; 424 O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 425 unsigned NOps = MI->getNumOperands(); 426 // cast away const; DIetc do not take const operands for some reason. 427 DIVariable V((MDNode*)(MI->getOperand(NOps-1).getMetadata())); 428 O << V.getName(); 429 O << " <- "; 430 if (NOps==3) { 431 // Register or immediate value. Register 0 means undef. 432 assert(MI->getOperand(0).getType()==MachineOperand::MO_Register || 433 MI->getOperand(0).getType()==MachineOperand::MO_Immediate); 434 if (MI->getOperand(0).getType()==MachineOperand::MO_Register && 435 MI->getOperand(0).getReg()==0) { 436 // Suppress offset in this case, it is not meaningful. 437 O << "undef"; 438 return; 439 } else 440 printOperand(MI, 0); 441 } else { 442 // Frame address. Currently handles register +- offset only. 443 assert(MI->getOperand(0).getType()==MachineOperand::MO_Register); 444 assert(MI->getOperand(3).getType()==MachineOperand::MO_Immediate); 445 O << '['; printOperand(MI, 0); O << '+'; printOperand(MI, 3); O << ']'; 446 } 447 O << "+"; 448 printOperand(MI, NOps-2); 449 return; 450 } 451 case TargetInstrInfo::INLINEASM: 452 printInlineAsm(MI); 453 return; 454 case TargetInstrInfo::IMPLICIT_DEF: 455 printImplicitDef(MI); 456 return; 457 case TargetInstrInfo::KILL: 458 printKill(MI); 459 return; 460 case X86::MOVPC32r: { 461 MCInst TmpInst; 462 // This is a pseudo op for a two instruction sequence with a label, which 463 // looks like: 464 // call "L1$pb" 465 // "L1$pb": 466 // popl %esi 467 468 // Emit the call. 469 MCSymbol *PICBase = MCInstLowering.GetPICBaseSymbol(); 470 TmpInst.setOpcode(X86::CALLpcrel32); 471 // FIXME: We would like an efficient form for this, so we don't have to do a 472 // lot of extra uniquing. 473 TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase, 474 OutContext))); 475 printMCInst(&TmpInst); 476 O << '\n'; 477 478 // Emit the label. 479 OutStreamer.EmitLabel(PICBase); 480 481 // popl $reg 482 TmpInst.setOpcode(X86::POP32r); 483 TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg()); 484 printMCInst(&TmpInst); 485 return; 486 } 487 488 case X86::ADD32ri: { 489 // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri. 490 if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS) 491 break; 492 493 // Okay, we have something like: 494 // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL) 495 496 // For this, we want to print something like: 497 // MYGLOBAL + (. - PICBASE) 498 // However, we can't generate a ".", so just emit a new label here and refer 499 // to it. We know that this operand flag occurs at most once per function. 500 const char *Prefix = MAI->getPrivateGlobalPrefix(); 501 MCSymbol *DotSym = OutContext.GetOrCreateSymbol(Twine(Prefix)+"picbaseref"+ 502 Twine(getFunctionNumber())); 503 OutStreamer.EmitLabel(DotSym); 504 505 // Now that we have emitted the label, lower the complex operand expression. 506 MCSymbol *OpSym = MCInstLowering.GetExternalSymbolSymbol(MI->getOperand(2)); 507 508 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 509 const MCExpr *PICBase = 510 MCSymbolRefExpr::Create(MCInstLowering.GetPICBaseSymbol(), OutContext); 511 DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext); 512 513 DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext), 514 DotExpr, OutContext); 515 516 MCInst TmpInst; 517 TmpInst.setOpcode(X86::ADD32ri); 518 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 519 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 520 TmpInst.addOperand(MCOperand::CreateExpr(DotExpr)); 521 printMCInst(&TmpInst); 522 return; 523 } 524 } 525 526 MCInst TmpInst; 527 MCInstLowering.Lower(MI, TmpInst); 528 529 530 printMCInst(&TmpInst); 531} 532 533