1//===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains a printer that converts from our internal representation 11// of machine-dependent LLVM code to X86 machine code. 12// 13//===----------------------------------------------------------------------===// 14 15#include "X86AsmPrinter.h" 16#include "InstPrinter/X86ATTInstPrinter.h" 17#include "X86.h" 18#include "X86COFFMachineModuleInfo.h" 19#include "X86MachineFunctionInfo.h" 20#include "X86TargetMachine.h" 21#include "llvm/ADT/SmallString.h" 22#include "llvm/Assembly/Writer.h" 23#include "llvm/CodeGen/MachineJumpTableInfo.h" 24#include "llvm/CodeGen/MachineModuleInfoImpls.h" 25#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 26#include "llvm/DebugInfo.h" 27#include "llvm/IR/CallingConv.h" 28#include "llvm/IR/DerivedTypes.h" 29#include "llvm/IR/Module.h" 30#include "llvm/IR/Type.h" 31#include "llvm/MC/MCAsmInfo.h" 32#include "llvm/MC/MCContext.h" 33#include "llvm/MC/MCExpr.h" 34#include "llvm/MC/MCSectionMachO.h" 35#include "llvm/MC/MCStreamer.h" 36#include "llvm/MC/MCSymbol.h" 37#include "llvm/Support/COFF.h" 38#include "llvm/Support/Debug.h" 39#include "llvm/Support/ErrorHandling.h" 40#include "llvm/Support/TargetRegistry.h" 41#include "llvm/Target/Mangler.h" 42#include "llvm/Target/TargetOptions.h" 43using namespace llvm; 44 45//===----------------------------------------------------------------------===// 46// Primitive Helper Functions. 47//===----------------------------------------------------------------------===// 48 49/// runOnMachineFunction - Emit the function body. 50/// 51bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 52 SetupMachineFunction(MF); 53 54 if (Subtarget->isTargetCOFF() && !Subtarget->isTargetEnvMacho()) { 55 bool Intrn = MF.getFunction()->hasInternalLinkage(); 56 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 57 OutStreamer.EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC 58 : COFF::IMAGE_SYM_CLASS_EXTERNAL); 59 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION 60 << COFF::SCT_COMPLEX_TYPE_SHIFT); 61 OutStreamer.EndCOFFSymbolDef(); 62 } 63 64 // Have common code print out the function header with linkage info etc. 65 EmitFunctionHeader(); 66 67 // Emit the rest of the function body. 68 EmitFunctionBody(); 69 70 // We didn't modify anything. 71 return false; 72} 73 74/// printSymbolOperand - Print a raw symbol reference operand. This handles 75/// jump tables, constant pools, global address and external symbols, all of 76/// which print to a label with various suffixes for relocation types etc. 77void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO, 78 raw_ostream &O) { 79 switch (MO.getType()) { 80 default: llvm_unreachable("unknown symbol type!"); 81 case MachineOperand::MO_JumpTableIndex: 82 O << *GetJTISymbol(MO.getIndex()); 83 break; 84 case MachineOperand::MO_ConstantPoolIndex: 85 O << *GetCPISymbol(MO.getIndex()); 86 printOffset(MO.getOffset(), O); 87 break; 88 case MachineOperand::MO_GlobalAddress: { 89 const GlobalValue *GV = MO.getGlobal(); 90 91 MCSymbol *GVSym; 92 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) 93 GVSym = GetSymbolWithGlobalValueBase(GV, "$stub"); 94 else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 95 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || 96 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) 97 GVSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 98 else 99 GVSym = getSymbol(GV); 100 101 // Handle dllimport linkage. 102 if (MO.getTargetFlags() == X86II::MO_DLLIMPORT) 103 GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName()); 104 105 if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 106 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) { 107 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 108 MachineModuleInfoImpl::StubValueTy &StubSym = 109 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym); 110 if (StubSym.getPointer() == 0) 111 StubSym = MachineModuleInfoImpl:: 112 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 113 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){ 114 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 115 MachineModuleInfoImpl::StubValueTy &StubSym = 116 MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(Sym); 117 if (StubSym.getPointer() == 0) 118 StubSym = MachineModuleInfoImpl:: 119 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 120 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { 121 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub"); 122 MachineModuleInfoImpl::StubValueTy &StubSym = 123 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 124 if (StubSym.getPointer() == 0) 125 StubSym = MachineModuleInfoImpl:: 126 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 127 } 128 129 // If the name begins with a dollar-sign, enclose it in parens. We do this 130 // to avoid having it look like an integer immediate to the assembler. 131 if (GVSym->getName()[0] != '$') 132 O << *GVSym; 133 else 134 O << '(' << *GVSym << ')'; 135 printOffset(MO.getOffset(), O); 136 break; 137 } 138 case MachineOperand::MO_ExternalSymbol: { 139 const MCSymbol *SymToPrint; 140 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { 141 SmallString<128> TempNameStr; 142 TempNameStr += StringRef(MO.getSymbolName()); 143 TempNameStr += StringRef("$stub"); 144 145 MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str()); 146 MachineModuleInfoImpl::StubValueTy &StubSym = 147 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 148 if (StubSym.getPointer() == 0) { 149 TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end()); 150 StubSym = MachineModuleInfoImpl:: 151 StubValueTy(OutContext.GetOrCreateSymbol(TempNameStr.str()), 152 true); 153 } 154 SymToPrint = StubSym.getPointer(); 155 } else { 156 SymToPrint = GetExternalSymbolSymbol(MO.getSymbolName()); 157 } 158 159 // If the name begins with a dollar-sign, enclose it in parens. We do this 160 // to avoid having it look like an integer immediate to the assembler. 161 if (SymToPrint->getName()[0] != '$') 162 O << *SymToPrint; 163 else 164 O << '(' << *SymToPrint << '('; 165 break; 166 } 167 } 168 169 switch (MO.getTargetFlags()) { 170 default: 171 llvm_unreachable("Unknown target flag on GV operand"); 172 case X86II::MO_NO_FLAG: // No flag. 173 break; 174 case X86II::MO_DARWIN_NONLAZY: 175 case X86II::MO_DLLIMPORT: 176 case X86II::MO_DARWIN_STUB: 177 // These affect the name of the symbol, not any suffix. 178 break; 179 case X86II::MO_GOT_ABSOLUTE_ADDRESS: 180 O << " + [.-" << *MF->getPICBaseSymbol() << ']'; 181 break; 182 case X86II::MO_PIC_BASE_OFFSET: 183 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 184 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: 185 O << '-' << *MF->getPICBaseSymbol(); 186 break; 187 case X86II::MO_TLSGD: O << "@TLSGD"; break; 188 case X86II::MO_TLSLD: O << "@TLSLD"; break; 189 case X86II::MO_TLSLDM: O << "@TLSLDM"; break; 190 case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break; 191 case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break; 192 case X86II::MO_TPOFF: O << "@TPOFF"; break; 193 case X86II::MO_DTPOFF: O << "@DTPOFF"; break; 194 case X86II::MO_NTPOFF: O << "@NTPOFF"; break; 195 case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break; 196 case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break; 197 case X86II::MO_GOT: O << "@GOT"; break; 198 case X86II::MO_GOTOFF: O << "@GOTOFF"; break; 199 case X86II::MO_PLT: O << "@PLT"; break; 200 case X86II::MO_TLVP: O << "@TLVP"; break; 201 case X86II::MO_TLVP_PIC_BASE: 202 O << "@TLVP" << '-' << *MF->getPICBaseSymbol(); 203 break; 204 case X86II::MO_SECREL: O << "@SECREL32"; break; 205 } 206} 207 208/// printPCRelImm - This is used to print an immediate value that ends up 209/// being encoded as a pc-relative value. These print slightly differently, for 210/// example, a $ is not emitted. 211void X86AsmPrinter::printPCRelImm(const MachineInstr *MI, unsigned OpNo, 212 raw_ostream &O) { 213 const MachineOperand &MO = MI->getOperand(OpNo); 214 switch (MO.getType()) { 215 default: llvm_unreachable("Unknown pcrel immediate operand"); 216 case MachineOperand::MO_Register: 217 // pc-relativeness was handled when computing the value in the reg. 218 printOperand(MI, OpNo, O); 219 return; 220 case MachineOperand::MO_Immediate: 221 O << MO.getImm(); 222 return; 223 case MachineOperand::MO_MachineBasicBlock: 224 O << *MO.getMBB()->getSymbol(); 225 return; 226 case MachineOperand::MO_GlobalAddress: 227 case MachineOperand::MO_ExternalSymbol: 228 printSymbolOperand(MO, O); 229 return; 230 } 231} 232 233 234void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 235 raw_ostream &O, const char *Modifier, 236 unsigned AsmVariant) { 237 const MachineOperand &MO = MI->getOperand(OpNo); 238 switch (MO.getType()) { 239 default: llvm_unreachable("unknown operand type!"); 240 case MachineOperand::MO_Register: { 241 // FIXME: Enumerating AsmVariant, so we can remove magic number. 242 if (AsmVariant == 0) O << '%'; 243 unsigned Reg = MO.getReg(); 244 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { 245 MVT::SimpleValueType VT = (strcmp(Modifier+6,"64") == 0) ? 246 MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 : 247 ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8)); 248 Reg = getX86SubSuperRegister(Reg, VT); 249 } 250 O << X86ATTInstPrinter::getRegisterName(Reg); 251 return; 252 } 253 254 case MachineOperand::MO_Immediate: 255 if (AsmVariant == 0) O << '$'; 256 O << MO.getImm(); 257 return; 258 259 case MachineOperand::MO_JumpTableIndex: 260 case MachineOperand::MO_ConstantPoolIndex: 261 case MachineOperand::MO_GlobalAddress: 262 case MachineOperand::MO_ExternalSymbol: { 263 if (AsmVariant == 0) O << '$'; 264 printSymbolOperand(MO, O); 265 break; 266 } 267 } 268} 269 270void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op, 271 raw_ostream &O, const char *Modifier) { 272 const MachineOperand &BaseReg = MI->getOperand(Op); 273 const MachineOperand &IndexReg = MI->getOperand(Op+2); 274 const MachineOperand &DispSpec = MI->getOperand(Op+3); 275 276 // If we really don't want to print out (rip), don't. 277 bool HasBaseReg = BaseReg.getReg() != 0; 278 if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") && 279 BaseReg.getReg() == X86::RIP) 280 HasBaseReg = false; 281 282 // HasParenPart - True if we will print out the () part of the mem ref. 283 bool HasParenPart = IndexReg.getReg() || HasBaseReg; 284 285 if (DispSpec.isImm()) { 286 int DispVal = DispSpec.getImm(); 287 if (DispVal || !HasParenPart) 288 O << DispVal; 289 } else { 290 assert(DispSpec.isGlobal() || DispSpec.isCPI() || 291 DispSpec.isJTI() || DispSpec.isSymbol()); 292 printSymbolOperand(MI->getOperand(Op+3), O); 293 } 294 295 if (Modifier && strcmp(Modifier, "H") == 0) 296 O << "+8"; 297 298 if (HasParenPart) { 299 assert(IndexReg.getReg() != X86::ESP && 300 "X86 doesn't allow scaling by ESP"); 301 302 O << '('; 303 if (HasBaseReg) 304 printOperand(MI, Op, O, Modifier); 305 306 if (IndexReg.getReg()) { 307 O << ','; 308 printOperand(MI, Op+2, O, Modifier); 309 unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 310 if (ScaleVal != 1) 311 O << ',' << ScaleVal; 312 } 313 O << ')'; 314 } 315} 316 317void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, 318 raw_ostream &O, const char *Modifier) { 319 assert(isMem(MI, Op) && "Invalid memory reference!"); 320 const MachineOperand &Segment = MI->getOperand(Op+4); 321 if (Segment.getReg()) { 322 printOperand(MI, Op+4, O, Modifier); 323 O << ':'; 324 } 325 printLeaMemReference(MI, Op, O, Modifier); 326} 327 328void X86AsmPrinter::printIntelMemReference(const MachineInstr *MI, unsigned Op, 329 raw_ostream &O, const char *Modifier, 330 unsigned AsmVariant){ 331 const MachineOperand &BaseReg = MI->getOperand(Op); 332 unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 333 const MachineOperand &IndexReg = MI->getOperand(Op+2); 334 const MachineOperand &DispSpec = MI->getOperand(Op+3); 335 const MachineOperand &SegReg = MI->getOperand(Op+4); 336 337 // If this has a segment register, print it. 338 if (SegReg.getReg()) { 339 printOperand(MI, Op+4, O, Modifier, AsmVariant); 340 O << ':'; 341 } 342 343 O << '['; 344 345 bool NeedPlus = false; 346 if (BaseReg.getReg()) { 347 printOperand(MI, Op, O, Modifier, AsmVariant); 348 NeedPlus = true; 349 } 350 351 if (IndexReg.getReg()) { 352 if (NeedPlus) O << " + "; 353 if (ScaleVal != 1) 354 O << ScaleVal << '*'; 355 printOperand(MI, Op+2, O, Modifier, AsmVariant); 356 NeedPlus = true; 357 } 358 359 if (!DispSpec.isImm()) { 360 if (NeedPlus) O << " + "; 361 printOperand(MI, Op+3, O, Modifier, AsmVariant); 362 } else { 363 int64_t DispVal = DispSpec.getImm(); 364 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) { 365 if (NeedPlus) { 366 if (DispVal > 0) 367 O << " + "; 368 else { 369 O << " - "; 370 DispVal = -DispVal; 371 } 372 } 373 O << DispVal; 374 } 375 } 376 O << ']'; 377} 378 379bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode, 380 raw_ostream &O) { 381 unsigned Reg = MO.getReg(); 382 switch (Mode) { 383 default: return true; // Unknown mode. 384 case 'b': // Print QImode register 385 Reg = getX86SubSuperRegister(Reg, MVT::i8); 386 break; 387 case 'h': // Print QImode high register 388 Reg = getX86SubSuperRegister(Reg, MVT::i8, true); 389 break; 390 case 'w': // Print HImode register 391 Reg = getX86SubSuperRegister(Reg, MVT::i16); 392 break; 393 case 'k': // Print SImode register 394 Reg = getX86SubSuperRegister(Reg, MVT::i32); 395 break;
| 1//===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains a printer that converts from our internal representation 11// of machine-dependent LLVM code to X86 machine code. 12// 13//===----------------------------------------------------------------------===// 14 15#include "X86AsmPrinter.h" 16#include "InstPrinter/X86ATTInstPrinter.h" 17#include "X86.h" 18#include "X86COFFMachineModuleInfo.h" 19#include "X86MachineFunctionInfo.h" 20#include "X86TargetMachine.h" 21#include "llvm/ADT/SmallString.h" 22#include "llvm/Assembly/Writer.h" 23#include "llvm/CodeGen/MachineJumpTableInfo.h" 24#include "llvm/CodeGen/MachineModuleInfoImpls.h" 25#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 26#include "llvm/DebugInfo.h" 27#include "llvm/IR/CallingConv.h" 28#include "llvm/IR/DerivedTypes.h" 29#include "llvm/IR/Module.h" 30#include "llvm/IR/Type.h" 31#include "llvm/MC/MCAsmInfo.h" 32#include "llvm/MC/MCContext.h" 33#include "llvm/MC/MCExpr.h" 34#include "llvm/MC/MCSectionMachO.h" 35#include "llvm/MC/MCStreamer.h" 36#include "llvm/MC/MCSymbol.h" 37#include "llvm/Support/COFF.h" 38#include "llvm/Support/Debug.h" 39#include "llvm/Support/ErrorHandling.h" 40#include "llvm/Support/TargetRegistry.h" 41#include "llvm/Target/Mangler.h" 42#include "llvm/Target/TargetOptions.h" 43using namespace llvm; 44 45//===----------------------------------------------------------------------===// 46// Primitive Helper Functions. 47//===----------------------------------------------------------------------===// 48 49/// runOnMachineFunction - Emit the function body. 50/// 51bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 52 SetupMachineFunction(MF); 53 54 if (Subtarget->isTargetCOFF() && !Subtarget->isTargetEnvMacho()) { 55 bool Intrn = MF.getFunction()->hasInternalLinkage(); 56 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 57 OutStreamer.EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC 58 : COFF::IMAGE_SYM_CLASS_EXTERNAL); 59 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION 60 << COFF::SCT_COMPLEX_TYPE_SHIFT); 61 OutStreamer.EndCOFFSymbolDef(); 62 } 63 64 // Have common code print out the function header with linkage info etc. 65 EmitFunctionHeader(); 66 67 // Emit the rest of the function body. 68 EmitFunctionBody(); 69 70 // We didn't modify anything. 71 return false; 72} 73 74/// printSymbolOperand - Print a raw symbol reference operand. This handles 75/// jump tables, constant pools, global address and external symbols, all of 76/// which print to a label with various suffixes for relocation types etc. 77void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO, 78 raw_ostream &O) { 79 switch (MO.getType()) { 80 default: llvm_unreachable("unknown symbol type!"); 81 case MachineOperand::MO_JumpTableIndex: 82 O << *GetJTISymbol(MO.getIndex()); 83 break; 84 case MachineOperand::MO_ConstantPoolIndex: 85 O << *GetCPISymbol(MO.getIndex()); 86 printOffset(MO.getOffset(), O); 87 break; 88 case MachineOperand::MO_GlobalAddress: { 89 const GlobalValue *GV = MO.getGlobal(); 90 91 MCSymbol *GVSym; 92 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) 93 GVSym = GetSymbolWithGlobalValueBase(GV, "$stub"); 94 else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 95 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || 96 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) 97 GVSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 98 else 99 GVSym = getSymbol(GV); 100 101 // Handle dllimport linkage. 102 if (MO.getTargetFlags() == X86II::MO_DLLIMPORT) 103 GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName()); 104 105 if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 106 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) { 107 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 108 MachineModuleInfoImpl::StubValueTy &StubSym = 109 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym); 110 if (StubSym.getPointer() == 0) 111 StubSym = MachineModuleInfoImpl:: 112 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 113 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){ 114 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 115 MachineModuleInfoImpl::StubValueTy &StubSym = 116 MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(Sym); 117 if (StubSym.getPointer() == 0) 118 StubSym = MachineModuleInfoImpl:: 119 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 120 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { 121 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub"); 122 MachineModuleInfoImpl::StubValueTy &StubSym = 123 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 124 if (StubSym.getPointer() == 0) 125 StubSym = MachineModuleInfoImpl:: 126 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 127 } 128 129 // If the name begins with a dollar-sign, enclose it in parens. We do this 130 // to avoid having it look like an integer immediate to the assembler. 131 if (GVSym->getName()[0] != '$') 132 O << *GVSym; 133 else 134 O << '(' << *GVSym << ')'; 135 printOffset(MO.getOffset(), O); 136 break; 137 } 138 case MachineOperand::MO_ExternalSymbol: { 139 const MCSymbol *SymToPrint; 140 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { 141 SmallString<128> TempNameStr; 142 TempNameStr += StringRef(MO.getSymbolName()); 143 TempNameStr += StringRef("$stub"); 144 145 MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str()); 146 MachineModuleInfoImpl::StubValueTy &StubSym = 147 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 148 if (StubSym.getPointer() == 0) { 149 TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end()); 150 StubSym = MachineModuleInfoImpl:: 151 StubValueTy(OutContext.GetOrCreateSymbol(TempNameStr.str()), 152 true); 153 } 154 SymToPrint = StubSym.getPointer(); 155 } else { 156 SymToPrint = GetExternalSymbolSymbol(MO.getSymbolName()); 157 } 158 159 // If the name begins with a dollar-sign, enclose it in parens. We do this 160 // to avoid having it look like an integer immediate to the assembler. 161 if (SymToPrint->getName()[0] != '$') 162 O << *SymToPrint; 163 else 164 O << '(' << *SymToPrint << '('; 165 break; 166 } 167 } 168 169 switch (MO.getTargetFlags()) { 170 default: 171 llvm_unreachable("Unknown target flag on GV operand"); 172 case X86II::MO_NO_FLAG: // No flag. 173 break; 174 case X86II::MO_DARWIN_NONLAZY: 175 case X86II::MO_DLLIMPORT: 176 case X86II::MO_DARWIN_STUB: 177 // These affect the name of the symbol, not any suffix. 178 break; 179 case X86II::MO_GOT_ABSOLUTE_ADDRESS: 180 O << " + [.-" << *MF->getPICBaseSymbol() << ']'; 181 break; 182 case X86II::MO_PIC_BASE_OFFSET: 183 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 184 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: 185 O << '-' << *MF->getPICBaseSymbol(); 186 break; 187 case X86II::MO_TLSGD: O << "@TLSGD"; break; 188 case X86II::MO_TLSLD: O << "@TLSLD"; break; 189 case X86II::MO_TLSLDM: O << "@TLSLDM"; break; 190 case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break; 191 case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break; 192 case X86II::MO_TPOFF: O << "@TPOFF"; break; 193 case X86II::MO_DTPOFF: O << "@DTPOFF"; break; 194 case X86II::MO_NTPOFF: O << "@NTPOFF"; break; 195 case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break; 196 case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break; 197 case X86II::MO_GOT: O << "@GOT"; break; 198 case X86II::MO_GOTOFF: O << "@GOTOFF"; break; 199 case X86II::MO_PLT: O << "@PLT"; break; 200 case X86II::MO_TLVP: O << "@TLVP"; break; 201 case X86II::MO_TLVP_PIC_BASE: 202 O << "@TLVP" << '-' << *MF->getPICBaseSymbol(); 203 break; 204 case X86II::MO_SECREL: O << "@SECREL32"; break; 205 } 206} 207 208/// printPCRelImm - This is used to print an immediate value that ends up 209/// being encoded as a pc-relative value. These print slightly differently, for 210/// example, a $ is not emitted. 211void X86AsmPrinter::printPCRelImm(const MachineInstr *MI, unsigned OpNo, 212 raw_ostream &O) { 213 const MachineOperand &MO = MI->getOperand(OpNo); 214 switch (MO.getType()) { 215 default: llvm_unreachable("Unknown pcrel immediate operand"); 216 case MachineOperand::MO_Register: 217 // pc-relativeness was handled when computing the value in the reg. 218 printOperand(MI, OpNo, O); 219 return; 220 case MachineOperand::MO_Immediate: 221 O << MO.getImm(); 222 return; 223 case MachineOperand::MO_MachineBasicBlock: 224 O << *MO.getMBB()->getSymbol(); 225 return; 226 case MachineOperand::MO_GlobalAddress: 227 case MachineOperand::MO_ExternalSymbol: 228 printSymbolOperand(MO, O); 229 return; 230 } 231} 232 233 234void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 235 raw_ostream &O, const char *Modifier, 236 unsigned AsmVariant) { 237 const MachineOperand &MO = MI->getOperand(OpNo); 238 switch (MO.getType()) { 239 default: llvm_unreachable("unknown operand type!"); 240 case MachineOperand::MO_Register: { 241 // FIXME: Enumerating AsmVariant, so we can remove magic number. 242 if (AsmVariant == 0) O << '%'; 243 unsigned Reg = MO.getReg(); 244 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { 245 MVT::SimpleValueType VT = (strcmp(Modifier+6,"64") == 0) ? 246 MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 : 247 ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8)); 248 Reg = getX86SubSuperRegister(Reg, VT); 249 } 250 O << X86ATTInstPrinter::getRegisterName(Reg); 251 return; 252 } 253 254 case MachineOperand::MO_Immediate: 255 if (AsmVariant == 0) O << '$'; 256 O << MO.getImm(); 257 return; 258 259 case MachineOperand::MO_JumpTableIndex: 260 case MachineOperand::MO_ConstantPoolIndex: 261 case MachineOperand::MO_GlobalAddress: 262 case MachineOperand::MO_ExternalSymbol: { 263 if (AsmVariant == 0) O << '$'; 264 printSymbolOperand(MO, O); 265 break; 266 } 267 } 268} 269 270void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op, 271 raw_ostream &O, const char *Modifier) { 272 const MachineOperand &BaseReg = MI->getOperand(Op); 273 const MachineOperand &IndexReg = MI->getOperand(Op+2); 274 const MachineOperand &DispSpec = MI->getOperand(Op+3); 275 276 // If we really don't want to print out (rip), don't. 277 bool HasBaseReg = BaseReg.getReg() != 0; 278 if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") && 279 BaseReg.getReg() == X86::RIP) 280 HasBaseReg = false; 281 282 // HasParenPart - True if we will print out the () part of the mem ref. 283 bool HasParenPart = IndexReg.getReg() || HasBaseReg; 284 285 if (DispSpec.isImm()) { 286 int DispVal = DispSpec.getImm(); 287 if (DispVal || !HasParenPart) 288 O << DispVal; 289 } else { 290 assert(DispSpec.isGlobal() || DispSpec.isCPI() || 291 DispSpec.isJTI() || DispSpec.isSymbol()); 292 printSymbolOperand(MI->getOperand(Op+3), O); 293 } 294 295 if (Modifier && strcmp(Modifier, "H") == 0) 296 O << "+8"; 297 298 if (HasParenPart) { 299 assert(IndexReg.getReg() != X86::ESP && 300 "X86 doesn't allow scaling by ESP"); 301 302 O << '('; 303 if (HasBaseReg) 304 printOperand(MI, Op, O, Modifier); 305 306 if (IndexReg.getReg()) { 307 O << ','; 308 printOperand(MI, Op+2, O, Modifier); 309 unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 310 if (ScaleVal != 1) 311 O << ',' << ScaleVal; 312 } 313 O << ')'; 314 } 315} 316 317void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, 318 raw_ostream &O, const char *Modifier) { 319 assert(isMem(MI, Op) && "Invalid memory reference!"); 320 const MachineOperand &Segment = MI->getOperand(Op+4); 321 if (Segment.getReg()) { 322 printOperand(MI, Op+4, O, Modifier); 323 O << ':'; 324 } 325 printLeaMemReference(MI, Op, O, Modifier); 326} 327 328void X86AsmPrinter::printIntelMemReference(const MachineInstr *MI, unsigned Op, 329 raw_ostream &O, const char *Modifier, 330 unsigned AsmVariant){ 331 const MachineOperand &BaseReg = MI->getOperand(Op); 332 unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 333 const MachineOperand &IndexReg = MI->getOperand(Op+2); 334 const MachineOperand &DispSpec = MI->getOperand(Op+3); 335 const MachineOperand &SegReg = MI->getOperand(Op+4); 336 337 // If this has a segment register, print it. 338 if (SegReg.getReg()) { 339 printOperand(MI, Op+4, O, Modifier, AsmVariant); 340 O << ':'; 341 } 342 343 O << '['; 344 345 bool NeedPlus = false; 346 if (BaseReg.getReg()) { 347 printOperand(MI, Op, O, Modifier, AsmVariant); 348 NeedPlus = true; 349 } 350 351 if (IndexReg.getReg()) { 352 if (NeedPlus) O << " + "; 353 if (ScaleVal != 1) 354 O << ScaleVal << '*'; 355 printOperand(MI, Op+2, O, Modifier, AsmVariant); 356 NeedPlus = true; 357 } 358 359 if (!DispSpec.isImm()) { 360 if (NeedPlus) O << " + "; 361 printOperand(MI, Op+3, O, Modifier, AsmVariant); 362 } else { 363 int64_t DispVal = DispSpec.getImm(); 364 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) { 365 if (NeedPlus) { 366 if (DispVal > 0) 367 O << " + "; 368 else { 369 O << " - "; 370 DispVal = -DispVal; 371 } 372 } 373 O << DispVal; 374 } 375 } 376 O << ']'; 377} 378 379bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode, 380 raw_ostream &O) { 381 unsigned Reg = MO.getReg(); 382 switch (Mode) { 383 default: return true; // Unknown mode. 384 case 'b': // Print QImode register 385 Reg = getX86SubSuperRegister(Reg, MVT::i8); 386 break; 387 case 'h': // Print QImode high register 388 Reg = getX86SubSuperRegister(Reg, MVT::i8, true); 389 break; 390 case 'w': // Print HImode register 391 Reg = getX86SubSuperRegister(Reg, MVT::i16); 392 break; 393 case 'k': // Print SImode register 394 Reg = getX86SubSuperRegister(Reg, MVT::i32); 395 break;
|
399 break; 400 } 401 402 O << '%' << X86ATTInstPrinter::getRegisterName(Reg); 403 return false; 404} 405 406/// PrintAsmOperand - Print out an operand for an inline asm expression. 407/// 408bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 409 unsigned AsmVariant, 410 const char *ExtraCode, raw_ostream &O) { 411 // Does this asm operand have a single letter operand modifier? 412 if (ExtraCode && ExtraCode[0]) { 413 if (ExtraCode[1] != 0) return true; // Unknown modifier. 414 415 const MachineOperand &MO = MI->getOperand(OpNo); 416 417 switch (ExtraCode[0]) { 418 default: 419 // See if this is a generic print operand 420 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 421 case 'a': // This is an address. Currently only 'i' and 'r' are expected. 422 if (MO.isImm()) { 423 O << MO.getImm(); 424 return false; 425 } 426 if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) { 427 printSymbolOperand(MO, O); 428 if (Subtarget->isPICStyleRIPRel()) 429 O << "(%rip)"; 430 return false; 431 } 432 if (MO.isReg()) { 433 O << '('; 434 printOperand(MI, OpNo, O); 435 O << ')'; 436 return false; 437 } 438 return true; 439 440 case 'c': // Don't print "$" before a global var name or constant. 441 if (MO.isImm()) 442 O << MO.getImm(); 443 else if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) 444 printSymbolOperand(MO, O); 445 else 446 printOperand(MI, OpNo, O); 447 return false; 448 449 case 'A': // Print '*' before a register (it must be a register) 450 if (MO.isReg()) { 451 O << '*'; 452 printOperand(MI, OpNo, O); 453 return false; 454 } 455 return true; 456 457 case 'b': // Print QImode register 458 case 'h': // Print QImode high register 459 case 'w': // Print HImode register 460 case 'k': // Print SImode register 461 case 'q': // Print DImode register 462 if (MO.isReg()) 463 return printAsmMRegister(MO, ExtraCode[0], O); 464 printOperand(MI, OpNo, O); 465 return false; 466 467 case 'P': // This is the operand of a call, treat specially. 468 printPCRelImm(MI, OpNo, O); 469 return false; 470 471 case 'n': // Negate the immediate or print a '-' before the operand. 472 // Note: this is a temporary solution. It should be handled target 473 // independently as part of the 'MC' work. 474 if (MO.isImm()) { 475 O << -MO.getImm(); 476 return false; 477 } 478 O << '-'; 479 } 480 } 481 482 printOperand(MI, OpNo, O, /*Modifier*/ 0, AsmVariant); 483 return false; 484} 485 486bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 487 unsigned OpNo, unsigned AsmVariant, 488 const char *ExtraCode, 489 raw_ostream &O) { 490 if (AsmVariant) { 491 printIntelMemReference(MI, OpNo, O); 492 return false; 493 } 494 495 if (ExtraCode && ExtraCode[0]) { 496 if (ExtraCode[1] != 0) return true; // Unknown modifier. 497 498 switch (ExtraCode[0]) { 499 default: return true; // Unknown modifier. 500 case 'b': // Print QImode register 501 case 'h': // Print QImode high register 502 case 'w': // Print HImode register 503 case 'k': // Print SImode register 504 case 'q': // Print SImode register 505 // These only apply to registers, ignore on mem. 506 break; 507 case 'H': 508 printMemReference(MI, OpNo, O, "H"); 509 return false; 510 case 'P': // Don't print @PLT, but do print as memory. 511 printMemReference(MI, OpNo, O, "no-rip"); 512 return false; 513 } 514 } 515 printMemReference(MI, OpNo, O); 516 return false; 517} 518 519void X86AsmPrinter::EmitStartOfAsmFile(Module &M) { 520 if (Subtarget->isTargetEnvMacho()) 521 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 522 523 if (Subtarget->isTargetCOFF()) { 524 // Emit an absolute @feat.00 symbol. This appears to be some kind of 525 // compiler features bitfield read by link.exe. 526 if (!Subtarget->is64Bit()) { 527 MCSymbol *S = MMI->getContext().GetOrCreateSymbol(StringRef("@feat.00")); 528 OutStreamer.BeginCOFFSymbolDef(S); 529 OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); 530 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL); 531 OutStreamer.EndCOFFSymbolDef(); 532 // According to the PE-COFF spec, the LSB of this value marks the object 533 // for "registered SEH". This means that all SEH handler entry points 534 // must be registered in .sxdata. Use of any unregistered handlers will 535 // cause the process to terminate immediately. LLVM does not know how to 536 // register any SEH handlers, so its object files should be safe. 537 S->setAbsolute(); 538 OutStreamer.EmitSymbolAttribute(S, MCSA_Global); 539 OutStreamer.EmitAssignment( 540 S, MCConstantExpr::Create(int64_t(1), MMI->getContext())); 541 } 542 } 543} 544 545 546void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { 547 if (Subtarget->isTargetEnvMacho()) { 548 // All darwin targets use mach-o. 549 MachineModuleInfoMachO &MMIMacho = 550 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 551 552 // Output stubs for dynamically-linked functions. 553 MachineModuleInfoMachO::SymbolListTy Stubs; 554 555 Stubs = MMIMacho.GetFnStubList(); 556 if (!Stubs.empty()) { 557 const MCSection *TheSection = 558 OutContext.getMachOSection("__IMPORT", "__jump_table", 559 MCSectionMachO::S_SYMBOL_STUBS | 560 MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE | 561 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 562 5, SectionKind::getMetadata()); 563 OutStreamer.SwitchSection(TheSection); 564 565 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 566 // L_foo$stub: 567 OutStreamer.EmitLabel(Stubs[i].first); 568 // .indirect_symbol _foo 569 OutStreamer.EmitSymbolAttribute(Stubs[i].second.getPointer(), 570 MCSA_IndirectSymbol); 571 // hlt; hlt; hlt; hlt; hlt hlt = 0xf4. 572 const char HltInsts[] = "\xf4\xf4\xf4\xf4\xf4"; 573 OutStreamer.EmitBytes(StringRef(HltInsts, 5)); 574 } 575 576 Stubs.clear(); 577 OutStreamer.AddBlankLine(); 578 } 579 580 // Output stubs for external and common global variables. 581 Stubs = MMIMacho.GetGVStubList(); 582 if (!Stubs.empty()) { 583 const MCSection *TheSection = 584 OutContext.getMachOSection("__IMPORT", "__pointers", 585 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 586 SectionKind::getMetadata()); 587 OutStreamer.SwitchSection(TheSection); 588 589 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 590 // L_foo$non_lazy_ptr: 591 OutStreamer.EmitLabel(Stubs[i].first); 592 // .indirect_symbol _foo 593 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 594 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), 595 MCSA_IndirectSymbol); 596 // .long 0 597 if (MCSym.getInt()) 598 // External to current translation unit. 599 OutStreamer.EmitIntValue(0, 4/*size*/); 600 else 601 // Internal to current translation unit. 602 // 603 // When we place the LSDA into the TEXT section, the type info 604 // pointers need to be indirect and pc-rel. We accomplish this by 605 // using NLPs. However, sometimes the types are local to the file. So 606 // we need to fill in the value for the NLP in those cases. 607 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 608 OutContext), 4/*size*/); 609 } 610 Stubs.clear(); 611 OutStreamer.AddBlankLine(); 612 } 613 614 Stubs = MMIMacho.GetHiddenGVStubList(); 615 if (!Stubs.empty()) { 616 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 617 EmitAlignment(2); 618 619 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 620 // L_foo$non_lazy_ptr: 621 OutStreamer.EmitLabel(Stubs[i].first); 622 // .long _foo 623 OutStreamer.EmitValue(MCSymbolRefExpr:: 624 Create(Stubs[i].second.getPointer(), 625 OutContext), 4/*size*/); 626 } 627 Stubs.clear(); 628 OutStreamer.AddBlankLine(); 629 } 630 631 SM.serializeToStackMapSection(); 632 633 // Funny Darwin hack: This flag tells the linker that no global symbols 634 // contain code that falls through to other global symbols (e.g. the obvious 635 // implementation of multiple entry points). If this doesn't occur, the 636 // linker can safely perform dead code stripping. Since LLVM never 637 // generates code that does this, it is always safe to set. 638 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 639 } 640 641 if (Subtarget->isTargetWindows() && !Subtarget->isTargetCygMing() && 642 MMI->usesVAFloatArgument()) { 643 StringRef SymbolName = Subtarget->is64Bit() ? "_fltused" : "__fltused"; 644 MCSymbol *S = MMI->getContext().GetOrCreateSymbol(SymbolName); 645 OutStreamer.EmitSymbolAttribute(S, MCSA_Global); 646 } 647 648 if (Subtarget->isTargetCOFF() && !Subtarget->isTargetEnvMacho()) { 649 X86COFFMachineModuleInfo &COFFMMI = 650 MMI->getObjFileInfo<X86COFFMachineModuleInfo>(); 651 652 // Emit type information for external functions 653 typedef X86COFFMachineModuleInfo::externals_iterator externals_iterator; 654 for (externals_iterator I = COFFMMI.externals_begin(), 655 E = COFFMMI.externals_end(); 656 I != E; ++I) { 657 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 658 OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL); 659 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION 660 << COFF::SCT_COMPLEX_TYPE_SHIFT); 661 OutStreamer.EndCOFFSymbolDef(); 662 } 663 664 // Necessary for dllexport support 665 std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals; 666 667 const TargetLoweringObjectFileCOFF &TLOFCOFF = 668 static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering()); 669 670 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) 671 if (I->hasDLLExportLinkage()) 672 DLLExportedFns.push_back(getSymbol(I)); 673 674 for (Module::const_global_iterator I = M.global_begin(), 675 E = M.global_end(); I != E; ++I) 676 if (I->hasDLLExportLinkage()) 677 DLLExportedGlobals.push_back(getSymbol(I)); 678 679 // Output linker support code for dllexported globals on windows. 680 if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) { 681 OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection()); 682 SmallString<128> name; 683 for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) { 684 if (Subtarget->isTargetWindows()) 685 name = " /EXPORT:"; 686 else 687 name = " -export:"; 688 name += DLLExportedGlobals[i]->getName(); 689 if (Subtarget->isTargetWindows()) 690 name += ",DATA"; 691 else 692 name += ",data"; 693 OutStreamer.EmitBytes(name); 694 } 695 696 for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i) { 697 if (Subtarget->isTargetWindows()) 698 name = " /EXPORT:"; 699 else 700 name = " -export:"; 701 name += DLLExportedFns[i]->getName(); 702 OutStreamer.EmitBytes(name); 703 } 704 } 705 } 706 707 if (Subtarget->isTargetELF()) { 708 const TargetLoweringObjectFileELF &TLOFELF = 709 static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); 710 711 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 712 713 // Output stubs for external and common global variables. 714 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 715 if (!Stubs.empty()) { 716 OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); 717 const DataLayout *TD = TM.getDataLayout(); 718 719 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 720 OutStreamer.EmitLabel(Stubs[i].first); 721 OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(), 722 TD->getPointerSize()); 723 } 724 Stubs.clear(); 725 } 726 } 727} 728 729//===----------------------------------------------------------------------===// 730// Target Registry Stuff 731//===----------------------------------------------------------------------===// 732 733// Force static initialization. 734extern "C" void LLVMInitializeX86AsmPrinter() { 735 RegisterAsmPrinter<X86AsmPrinter> X(TheX86_32Target); 736 RegisterAsmPrinter<X86AsmPrinter> Y(TheX86_64Target); 737}
| 401 break; 402 } 403 404 O << '%' << X86ATTInstPrinter::getRegisterName(Reg); 405 return false; 406} 407 408/// PrintAsmOperand - Print out an operand for an inline asm expression. 409/// 410bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 411 unsigned AsmVariant, 412 const char *ExtraCode, raw_ostream &O) { 413 // Does this asm operand have a single letter operand modifier? 414 if (ExtraCode && ExtraCode[0]) { 415 if (ExtraCode[1] != 0) return true; // Unknown modifier. 416 417 const MachineOperand &MO = MI->getOperand(OpNo); 418 419 switch (ExtraCode[0]) { 420 default: 421 // See if this is a generic print operand 422 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 423 case 'a': // This is an address. Currently only 'i' and 'r' are expected. 424 if (MO.isImm()) { 425 O << MO.getImm(); 426 return false; 427 } 428 if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) { 429 printSymbolOperand(MO, O); 430 if (Subtarget->isPICStyleRIPRel()) 431 O << "(%rip)"; 432 return false; 433 } 434 if (MO.isReg()) { 435 O << '('; 436 printOperand(MI, OpNo, O); 437 O << ')'; 438 return false; 439 } 440 return true; 441 442 case 'c': // Don't print "$" before a global var name or constant. 443 if (MO.isImm()) 444 O << MO.getImm(); 445 else if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) 446 printSymbolOperand(MO, O); 447 else 448 printOperand(MI, OpNo, O); 449 return false; 450 451 case 'A': // Print '*' before a register (it must be a register) 452 if (MO.isReg()) { 453 O << '*'; 454 printOperand(MI, OpNo, O); 455 return false; 456 } 457 return true; 458 459 case 'b': // Print QImode register 460 case 'h': // Print QImode high register 461 case 'w': // Print HImode register 462 case 'k': // Print SImode register 463 case 'q': // Print DImode register 464 if (MO.isReg()) 465 return printAsmMRegister(MO, ExtraCode[0], O); 466 printOperand(MI, OpNo, O); 467 return false; 468 469 case 'P': // This is the operand of a call, treat specially. 470 printPCRelImm(MI, OpNo, O); 471 return false; 472 473 case 'n': // Negate the immediate or print a '-' before the operand. 474 // Note: this is a temporary solution. It should be handled target 475 // independently as part of the 'MC' work. 476 if (MO.isImm()) { 477 O << -MO.getImm(); 478 return false; 479 } 480 O << '-'; 481 } 482 } 483 484 printOperand(MI, OpNo, O, /*Modifier*/ 0, AsmVariant); 485 return false; 486} 487 488bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 489 unsigned OpNo, unsigned AsmVariant, 490 const char *ExtraCode, 491 raw_ostream &O) { 492 if (AsmVariant) { 493 printIntelMemReference(MI, OpNo, O); 494 return false; 495 } 496 497 if (ExtraCode && ExtraCode[0]) { 498 if (ExtraCode[1] != 0) return true; // Unknown modifier. 499 500 switch (ExtraCode[0]) { 501 default: return true; // Unknown modifier. 502 case 'b': // Print QImode register 503 case 'h': // Print QImode high register 504 case 'w': // Print HImode register 505 case 'k': // Print SImode register 506 case 'q': // Print SImode register 507 // These only apply to registers, ignore on mem. 508 break; 509 case 'H': 510 printMemReference(MI, OpNo, O, "H"); 511 return false; 512 case 'P': // Don't print @PLT, but do print as memory. 513 printMemReference(MI, OpNo, O, "no-rip"); 514 return false; 515 } 516 } 517 printMemReference(MI, OpNo, O); 518 return false; 519} 520 521void X86AsmPrinter::EmitStartOfAsmFile(Module &M) { 522 if (Subtarget->isTargetEnvMacho()) 523 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 524 525 if (Subtarget->isTargetCOFF()) { 526 // Emit an absolute @feat.00 symbol. This appears to be some kind of 527 // compiler features bitfield read by link.exe. 528 if (!Subtarget->is64Bit()) { 529 MCSymbol *S = MMI->getContext().GetOrCreateSymbol(StringRef("@feat.00")); 530 OutStreamer.BeginCOFFSymbolDef(S); 531 OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); 532 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL); 533 OutStreamer.EndCOFFSymbolDef(); 534 // According to the PE-COFF spec, the LSB of this value marks the object 535 // for "registered SEH". This means that all SEH handler entry points 536 // must be registered in .sxdata. Use of any unregistered handlers will 537 // cause the process to terminate immediately. LLVM does not know how to 538 // register any SEH handlers, so its object files should be safe. 539 S->setAbsolute(); 540 OutStreamer.EmitSymbolAttribute(S, MCSA_Global); 541 OutStreamer.EmitAssignment( 542 S, MCConstantExpr::Create(int64_t(1), MMI->getContext())); 543 } 544 } 545} 546 547 548void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { 549 if (Subtarget->isTargetEnvMacho()) { 550 // All darwin targets use mach-o. 551 MachineModuleInfoMachO &MMIMacho = 552 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 553 554 // Output stubs for dynamically-linked functions. 555 MachineModuleInfoMachO::SymbolListTy Stubs; 556 557 Stubs = MMIMacho.GetFnStubList(); 558 if (!Stubs.empty()) { 559 const MCSection *TheSection = 560 OutContext.getMachOSection("__IMPORT", "__jump_table", 561 MCSectionMachO::S_SYMBOL_STUBS | 562 MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE | 563 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 564 5, SectionKind::getMetadata()); 565 OutStreamer.SwitchSection(TheSection); 566 567 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 568 // L_foo$stub: 569 OutStreamer.EmitLabel(Stubs[i].first); 570 // .indirect_symbol _foo 571 OutStreamer.EmitSymbolAttribute(Stubs[i].second.getPointer(), 572 MCSA_IndirectSymbol); 573 // hlt; hlt; hlt; hlt; hlt hlt = 0xf4. 574 const char HltInsts[] = "\xf4\xf4\xf4\xf4\xf4"; 575 OutStreamer.EmitBytes(StringRef(HltInsts, 5)); 576 } 577 578 Stubs.clear(); 579 OutStreamer.AddBlankLine(); 580 } 581 582 // Output stubs for external and common global variables. 583 Stubs = MMIMacho.GetGVStubList(); 584 if (!Stubs.empty()) { 585 const MCSection *TheSection = 586 OutContext.getMachOSection("__IMPORT", "__pointers", 587 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 588 SectionKind::getMetadata()); 589 OutStreamer.SwitchSection(TheSection); 590 591 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 592 // L_foo$non_lazy_ptr: 593 OutStreamer.EmitLabel(Stubs[i].first); 594 // .indirect_symbol _foo 595 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 596 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), 597 MCSA_IndirectSymbol); 598 // .long 0 599 if (MCSym.getInt()) 600 // External to current translation unit. 601 OutStreamer.EmitIntValue(0, 4/*size*/); 602 else 603 // Internal to current translation unit. 604 // 605 // When we place the LSDA into the TEXT section, the type info 606 // pointers need to be indirect and pc-rel. We accomplish this by 607 // using NLPs. However, sometimes the types are local to the file. So 608 // we need to fill in the value for the NLP in those cases. 609 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 610 OutContext), 4/*size*/); 611 } 612 Stubs.clear(); 613 OutStreamer.AddBlankLine(); 614 } 615 616 Stubs = MMIMacho.GetHiddenGVStubList(); 617 if (!Stubs.empty()) { 618 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 619 EmitAlignment(2); 620 621 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 622 // L_foo$non_lazy_ptr: 623 OutStreamer.EmitLabel(Stubs[i].first); 624 // .long _foo 625 OutStreamer.EmitValue(MCSymbolRefExpr:: 626 Create(Stubs[i].second.getPointer(), 627 OutContext), 4/*size*/); 628 } 629 Stubs.clear(); 630 OutStreamer.AddBlankLine(); 631 } 632 633 SM.serializeToStackMapSection(); 634 635 // Funny Darwin hack: This flag tells the linker that no global symbols 636 // contain code that falls through to other global symbols (e.g. the obvious 637 // implementation of multiple entry points). If this doesn't occur, the 638 // linker can safely perform dead code stripping. Since LLVM never 639 // generates code that does this, it is always safe to set. 640 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 641 } 642 643 if (Subtarget->isTargetWindows() && !Subtarget->isTargetCygMing() && 644 MMI->usesVAFloatArgument()) { 645 StringRef SymbolName = Subtarget->is64Bit() ? "_fltused" : "__fltused"; 646 MCSymbol *S = MMI->getContext().GetOrCreateSymbol(SymbolName); 647 OutStreamer.EmitSymbolAttribute(S, MCSA_Global); 648 } 649 650 if (Subtarget->isTargetCOFF() && !Subtarget->isTargetEnvMacho()) { 651 X86COFFMachineModuleInfo &COFFMMI = 652 MMI->getObjFileInfo<X86COFFMachineModuleInfo>(); 653 654 // Emit type information for external functions 655 typedef X86COFFMachineModuleInfo::externals_iterator externals_iterator; 656 for (externals_iterator I = COFFMMI.externals_begin(), 657 E = COFFMMI.externals_end(); 658 I != E; ++I) { 659 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 660 OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL); 661 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION 662 << COFF::SCT_COMPLEX_TYPE_SHIFT); 663 OutStreamer.EndCOFFSymbolDef(); 664 } 665 666 // Necessary for dllexport support 667 std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals; 668 669 const TargetLoweringObjectFileCOFF &TLOFCOFF = 670 static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering()); 671 672 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) 673 if (I->hasDLLExportLinkage()) 674 DLLExportedFns.push_back(getSymbol(I)); 675 676 for (Module::const_global_iterator I = M.global_begin(), 677 E = M.global_end(); I != E; ++I) 678 if (I->hasDLLExportLinkage()) 679 DLLExportedGlobals.push_back(getSymbol(I)); 680 681 // Output linker support code for dllexported globals on windows. 682 if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) { 683 OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection()); 684 SmallString<128> name; 685 for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) { 686 if (Subtarget->isTargetWindows()) 687 name = " /EXPORT:"; 688 else 689 name = " -export:"; 690 name += DLLExportedGlobals[i]->getName(); 691 if (Subtarget->isTargetWindows()) 692 name += ",DATA"; 693 else 694 name += ",data"; 695 OutStreamer.EmitBytes(name); 696 } 697 698 for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i) { 699 if (Subtarget->isTargetWindows()) 700 name = " /EXPORT:"; 701 else 702 name = " -export:"; 703 name += DLLExportedFns[i]->getName(); 704 OutStreamer.EmitBytes(name); 705 } 706 } 707 } 708 709 if (Subtarget->isTargetELF()) { 710 const TargetLoweringObjectFileELF &TLOFELF = 711 static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); 712 713 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 714 715 // Output stubs for external and common global variables. 716 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 717 if (!Stubs.empty()) { 718 OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); 719 const DataLayout *TD = TM.getDataLayout(); 720 721 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 722 OutStreamer.EmitLabel(Stubs[i].first); 723 OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(), 724 TD->getPointerSize()); 725 } 726 Stubs.clear(); 727 } 728 } 729} 730 731//===----------------------------------------------------------------------===// 732// Target Registry Stuff 733//===----------------------------------------------------------------------===// 734 735// Force static initialization. 736extern "C" void LLVMInitializeX86AsmPrinter() { 737 RegisterAsmPrinter<X86AsmPrinter> X(TheX86_32Target); 738 RegisterAsmPrinter<X86AsmPrinter> Y(TheX86_64Target); 739}
|