1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// 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 GAS-format ARM assembly language. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "ARMAsmPrinter.h" 16 #include "ARM.h" 17 #include "ARMConstantPoolValue.h" 18 #include "ARMFPUName.h" 19 #include "ARMMachineFunctionInfo.h" 20 #include "ARMTargetMachine.h" 21 #include "ARMTargetObjectFile.h" 22 #include "InstPrinter/ARMInstPrinter.h" 23 #include "MCTargetDesc/ARMAddressingModes.h" 24 #include "MCTargetDesc/ARMMCExpr.h" 25 #include "llvm/ADT/SetVector.h" 26 #include "llvm/ADT/SmallString.h" 27 #include "llvm/CodeGen/MachineFunctionPass.h" 28 #include "llvm/CodeGen/MachineJumpTableInfo.h" 29 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 30 #include "llvm/IR/Constants.h" 31 #include "llvm/IR/DataLayout.h" 32 #include "llvm/IR/DebugInfo.h" 33 #include "llvm/IR/Mangler.h" 34 #include "llvm/IR/Module.h" 35 #include "llvm/IR/Type.h" 36 #include "llvm/MC/MCAsmInfo.h" 37 #include "llvm/MC/MCAssembler.h" 38 #include "llvm/MC/MCContext.h" 39 #include "llvm/MC/MCELFStreamer.h" 40 #include "llvm/MC/MCInst.h" 41 #include "llvm/MC/MCInstBuilder.h" 42 #include "llvm/MC/MCObjectStreamer.h" 43 #include "llvm/MC/MCSectionMachO.h" 44 #include "llvm/MC/MCStreamer.h" 45 #include "llvm/MC/MCSymbol.h" 46 #include "llvm/Support/ARMBuildAttributes.h" 47 #include "llvm/Support/COFF.h" 48 #include "llvm/Support/CommandLine.h" 49 #include "llvm/Support/Debug.h" 50 #include "llvm/Support/ELF.h" 51 #include "llvm/Support/ErrorHandling.h" 52 #include "llvm/Support/TargetRegistry.h" 53 #include "llvm/Support/raw_ostream.h" 54 #include "llvm/Target/TargetMachine.h" 55 #include <cctype> 56 using namespace llvm; 57 58 #define DEBUG_TYPE "asm-printer" 59 60 void ARMAsmPrinter::EmitFunctionBodyEnd() { 61 // Make sure to terminate any constant pools that were at the end 62 // of the function. 63 if (!InConstantPool) 64 return; 65 InConstantPool = false; 66 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 67 } 68 69 void ARMAsmPrinter::EmitFunctionEntryLabel() { 70 if (AFI->isThumbFunction()) { 71 OutStreamer.EmitAssemblerFlag(MCAF_Code16); 72 OutStreamer.EmitThumbFunc(CurrentFnSym); 73 } 74 75 OutStreamer.EmitLabel(CurrentFnSym); 76 } 77 78 void ARMAsmPrinter::EmitXXStructor(const Constant *CV) { 79 uint64_t Size = TM.getDataLayout()->getTypeAllocSize(CV->getType()); 80 assert(Size && "C++ constructor pointer had zero size!"); 81 82 const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts()); 83 assert(GV && "C++ constructor pointer was not a GlobalValue!"); 84 85 const MCExpr *E = MCSymbolRefExpr::Create(GetARMGVSymbol(GV, 86 ARMII::MO_NO_FLAG), 87 (Subtarget->isTargetELF() 88 ? MCSymbolRefExpr::VK_ARM_TARGET1 89 : MCSymbolRefExpr::VK_None), 90 OutContext); 91 92 OutStreamer.EmitValue(E, Size); 93 } 94 95 /// runOnMachineFunction - This uses the EmitInstruction() 96 /// method to print assembly for each instruction. 97 /// 98 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 99 AFI = MF.getInfo<ARMFunctionInfo>(); 100 MCP = MF.getConstantPool(); 101 102 SetupMachineFunction(MF); 103 104 if (Subtarget->isTargetCOFF()) { 105 bool Internal = MF.getFunction()->hasInternalLinkage(); 106 COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC 107 : COFF::IMAGE_SYM_CLASS_EXTERNAL; 108 int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT; 109 110 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 111 OutStreamer.EmitCOFFSymbolStorageClass(Scl); 112 OutStreamer.EmitCOFFSymbolType(Type); 113 OutStreamer.EndCOFFSymbolDef(); 114 } 115 116 // Have common code print out the function header with linkage info etc. 117 EmitFunctionHeader(); 118 119 // Emit the rest of the function body. 120 EmitFunctionBody(); 121 122 // We didn't modify anything. 123 return false; 124 } 125 126 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 127 raw_ostream &O, const char *Modifier) { 128 const MachineOperand &MO = MI->getOperand(OpNum); 129 unsigned TF = MO.getTargetFlags(); 130 131 switch (MO.getType()) { 132 default: llvm_unreachable("<unknown operand type>"); 133 case MachineOperand::MO_Register: { 134 unsigned Reg = MO.getReg(); 135 assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 136 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 137 if(ARM::GPRPairRegClass.contains(Reg)) { 138 const MachineFunction &MF = *MI->getParent()->getParent(); 139 const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 140 Reg = TRI->getSubReg(Reg, ARM::gsub_0); 141 } 142 O << ARMInstPrinter::getRegisterName(Reg); 143 break; 144 } 145 case MachineOperand::MO_Immediate: { 146 int64_t Imm = MO.getImm(); 147 O << '#'; 148 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 149 (TF == ARMII::MO_LO16)) 150 O << ":lower16:"; 151 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 152 (TF == ARMII::MO_HI16)) 153 O << ":upper16:"; 154 O << Imm; 155 break; 156 } 157 case MachineOperand::MO_MachineBasicBlock: 158 O << *MO.getMBB()->getSymbol(); 159 return; 160 case MachineOperand::MO_GlobalAddress: { 161 const GlobalValue *GV = MO.getGlobal(); 162 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 163 (TF & ARMII::MO_LO16)) 164 O << ":lower16:"; 165 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 166 (TF & ARMII::MO_HI16)) 167 O << ":upper16:"; 168 O << *GetARMGVSymbol(GV, TF); 169 170 printOffset(MO.getOffset(), O); 171 if (TF == ARMII::MO_PLT) 172 O << "(PLT)"; 173 break; 174 } 175 case MachineOperand::MO_ConstantPoolIndex: 176 O << *GetCPISymbol(MO.getIndex()); 177 break; 178 } 179 } 180 181 //===--------------------------------------------------------------------===// 182 183 MCSymbol *ARMAsmPrinter:: 184 GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 185 const DataLayout *DL = TM.getDataLayout(); 186 SmallString<60> Name; 187 raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "JTI" 188 << getFunctionNumber() << '_' << uid << '_' << uid2; 189 return OutContext.GetOrCreateSymbol(Name.str()); 190 } 191 192 193 MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel() const { 194 const DataLayout *DL = TM.getDataLayout(); 195 SmallString<60> Name; 196 raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "SJLJEH" 197 << getFunctionNumber(); 198 return OutContext.GetOrCreateSymbol(Name.str()); 199 } 200 201 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 202 unsigned AsmVariant, const char *ExtraCode, 203 raw_ostream &O) { 204 // Does this asm operand have a single letter operand modifier? 205 if (ExtraCode && ExtraCode[0]) { 206 if (ExtraCode[1] != 0) return true; // Unknown modifier. 207 208 switch (ExtraCode[0]) { 209 default: 210 // See if this is a generic print operand 211 return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O); 212 case 'a': // Print as a memory address. 213 if (MI->getOperand(OpNum).isReg()) { 214 O << "[" 215 << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 216 << "]"; 217 return false; 218 } 219 // Fallthrough 220 case 'c': // Don't print "#" before an immediate operand. 221 if (!MI->getOperand(OpNum).isImm()) 222 return true; 223 O << MI->getOperand(OpNum).getImm(); 224 return false; 225 case 'P': // Print a VFP double precision register. 226 case 'q': // Print a NEON quad precision register. 227 printOperand(MI, OpNum, O); 228 return false; 229 case 'y': // Print a VFP single precision register as indexed double. 230 if (MI->getOperand(OpNum).isReg()) { 231 unsigned Reg = MI->getOperand(OpNum).getReg(); 232 const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 233 // Find the 'd' register that has this 's' register as a sub-register, 234 // and determine the lane number. 235 for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) { 236 if (!ARM::DPRRegClass.contains(*SR)) 237 continue; 238 bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg; 239 O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]"); 240 return false; 241 } 242 } 243 return true; 244 case 'B': // Bitwise inverse of integer or symbol without a preceding #. 245 if (!MI->getOperand(OpNum).isImm()) 246 return true; 247 O << ~(MI->getOperand(OpNum).getImm()); 248 return false; 249 case 'L': // The low 16 bits of an immediate constant. 250 if (!MI->getOperand(OpNum).isImm()) 251 return true; 252 O << (MI->getOperand(OpNum).getImm() & 0xffff); 253 return false; 254 case 'M': { // A register range suitable for LDM/STM. 255 if (!MI->getOperand(OpNum).isReg()) 256 return true; 257 const MachineOperand &MO = MI->getOperand(OpNum); 258 unsigned RegBegin = MO.getReg(); 259 // This takes advantage of the 2 operand-ness of ldm/stm and that we've 260 // already got the operands in registers that are operands to the 261 // inline asm statement. 262 O << "{"; 263 if (ARM::GPRPairRegClass.contains(RegBegin)) { 264 const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 265 unsigned Reg0 = TRI->getSubReg(RegBegin, ARM::gsub_0); 266 O << ARMInstPrinter::getRegisterName(Reg0) << ", "; 267 RegBegin = TRI->getSubReg(RegBegin, ARM::gsub_1); 268 } 269 O << ARMInstPrinter::getRegisterName(RegBegin); 270 271 // FIXME: The register allocator not only may not have given us the 272 // registers in sequence, but may not be in ascending registers. This 273 // will require changes in the register allocator that'll need to be 274 // propagated down here if the operands change. 275 unsigned RegOps = OpNum + 1; 276 while (MI->getOperand(RegOps).isReg()) { 277 O << ", " 278 << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg()); 279 RegOps++; 280 } 281 282 O << "}"; 283 284 return false; 285 } 286 case 'R': // The most significant register of a pair. 287 case 'Q': { // The least significant register of a pair. 288 if (OpNum == 0) 289 return true; 290 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 291 if (!FlagsOP.isImm()) 292 return true; 293 unsigned Flags = FlagsOP.getImm(); 294 295 // This operand may not be the one that actually provides the register. If 296 // it's tied to a previous one then we should refer instead to that one 297 // for registers and their classes. 298 unsigned TiedIdx; 299 if (InlineAsm::isUseOperandTiedToDef(Flags, TiedIdx)) { 300 for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) { 301 unsigned OpFlags = MI->getOperand(OpNum).getImm(); 302 OpNum += InlineAsm::getNumOperandRegisters(OpFlags) + 1; 303 } 304 Flags = MI->getOperand(OpNum).getImm(); 305 306 // Later code expects OpNum to be pointing at the register rather than 307 // the flags. 308 OpNum += 1; 309 } 310 311 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 312 unsigned RC; 313 InlineAsm::hasRegClassConstraint(Flags, RC); 314 if (RC == ARM::GPRPairRegClassID) { 315 if (NumVals != 1) 316 return true; 317 const MachineOperand &MO = MI->getOperand(OpNum); 318 if (!MO.isReg()) 319 return true; 320 const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 321 unsigned Reg = TRI->getSubReg(MO.getReg(), ExtraCode[0] == 'Q' ? 322 ARM::gsub_0 : ARM::gsub_1); 323 O << ARMInstPrinter::getRegisterName(Reg); 324 return false; 325 } 326 if (NumVals != 2) 327 return true; 328 unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1; 329 if (RegOp >= MI->getNumOperands()) 330 return true; 331 const MachineOperand &MO = MI->getOperand(RegOp); 332 if (!MO.isReg()) 333 return true; 334 unsigned Reg = MO.getReg(); 335 O << ARMInstPrinter::getRegisterName(Reg); 336 return false; 337 } 338 339 case 'e': // The low doubleword register of a NEON quad register. 340 case 'f': { // The high doubleword register of a NEON quad register. 341 if (!MI->getOperand(OpNum).isReg()) 342 return true; 343 unsigned Reg = MI->getOperand(OpNum).getReg(); 344 if (!ARM::QPRRegClass.contains(Reg)) 345 return true; 346 const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 347 unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ? 348 ARM::dsub_0 : ARM::dsub_1); 349 O << ARMInstPrinter::getRegisterName(SubReg); 350 return false; 351 } 352 353 // This modifier is not yet supported. 354 case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1. 355 return true; 356 case 'H': { // The highest-numbered register of a pair. 357 const MachineOperand &MO = MI->getOperand(OpNum); 358 if (!MO.isReg()) 359 return true; 360 const MachineFunction &MF = *MI->getParent()->getParent(); 361 const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 362 unsigned Reg = MO.getReg(); 363 if(!ARM::GPRPairRegClass.contains(Reg)) 364 return false; 365 Reg = TRI->getSubReg(Reg, ARM::gsub_1); 366 O << ARMInstPrinter::getRegisterName(Reg); 367 return false; 368 } 369 } 370 } 371 372 printOperand(MI, OpNum, O); 373 return false; 374 } 375 376 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 377 unsigned OpNum, unsigned AsmVariant, 378 const char *ExtraCode, 379 raw_ostream &O) { 380 // Does this asm operand have a single letter operand modifier? 381 if (ExtraCode && ExtraCode[0]) { 382 if (ExtraCode[1] != 0) return true; // Unknown modifier. 383 384 switch (ExtraCode[0]) { 385 case 'A': // A memory operand for a VLD1/VST1 instruction. 386 default: return true; // Unknown modifier. 387 case 'm': // The base register of a memory operand. 388 if (!MI->getOperand(OpNum).isReg()) 389 return true; 390 O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()); 391 return false; 392 } 393 } 394 395 const MachineOperand &MO = MI->getOperand(OpNum); 396 assert(MO.isReg() && "unexpected inline asm memory operand"); 397 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 398 return false; 399 } 400 401 static bool isThumb(const MCSubtargetInfo& STI) { 402 return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 403 } 404 405 void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 406 const MCSubtargetInfo *EndInfo) const { 407 // If either end mode is unknown (EndInfo == NULL) or different than 408 // the start mode, then restore the start mode. 409 const bool WasThumb = isThumb(StartInfo); 410 if (!EndInfo || WasThumb != isThumb(*EndInfo)) { 411 OutStreamer.EmitAssemblerFlag(WasThumb ? MCAF_Code16 : MCAF_Code32); 412 } 413 } 414 415 void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 416 if (Subtarget->isTargetMachO()) { 417 Reloc::Model RelocM = TM.getRelocationModel(); 418 if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 419 // Declare all the text sections up front (before the DWARF sections 420 // emitted by AsmPrinter::doInitialization) so the assembler will keep 421 // them together at the beginning of the object file. This helps 422 // avoid out-of-range branches that are due a fundamental limitation of 423 // the way symbol offsets are encoded with the current Darwin ARM 424 // relocations. 425 const TargetLoweringObjectFileMachO &TLOFMacho = 426 static_cast<const TargetLoweringObjectFileMachO &>( 427 getObjFileLowering()); 428 429 // Collect the set of sections our functions will go into. 430 SetVector<const MCSection *, SmallVector<const MCSection *, 8>, 431 SmallPtrSet<const MCSection *, 8> > TextSections; 432 // Default text section comes first. 433 TextSections.insert(TLOFMacho.getTextSection()); 434 // Now any user defined text sections from function attributes. 435 for (Module::iterator F = M.begin(), e = M.end(); F != e; ++F) 436 if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage()) 437 TextSections.insert(TLOFMacho.SectionForGlobal(F, *Mang, TM)); 438 // Now the coalescable sections. 439 TextSections.insert(TLOFMacho.getTextCoalSection()); 440 TextSections.insert(TLOFMacho.getConstTextCoalSection()); 441 442 // Emit the sections in the .s file header to fix the order. 443 for (unsigned i = 0, e = TextSections.size(); i != e; ++i) 444 OutStreamer.SwitchSection(TextSections[i]); 445 446 if (RelocM == Reloc::DynamicNoPIC) { 447 const MCSection *sect = 448 OutContext.getMachOSection("__TEXT", "__symbol_stub4", 449 MachO::S_SYMBOL_STUBS, 450 12, SectionKind::getText()); 451 OutStreamer.SwitchSection(sect); 452 } else { 453 const MCSection *sect = 454 OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 455 MachO::S_SYMBOL_STUBS, 456 16, SectionKind::getText()); 457 OutStreamer.SwitchSection(sect); 458 } 459 const MCSection *StaticInitSect = 460 OutContext.getMachOSection("__TEXT", "__StaticInit", 461 MachO::S_REGULAR | 462 MachO::S_ATTR_PURE_INSTRUCTIONS, 463 SectionKind::getText()); 464 OutStreamer.SwitchSection(StaticInitSect); 465 } 466 467 // Compiling with debug info should not affect the code 468 // generation. Ensure the cstring section comes before the 469 // optional __DWARF secion. Otherwise, PC-relative loads would 470 // have to use different instruction sequences at "-g" in order to 471 // reach global data in the same object file. 472 OutStreamer.SwitchSection(getObjFileLowering().getCStringSection()); 473 } 474 475 // Use unified assembler syntax. 476 OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 477 478 // Emit ARM Build Attributes 479 if (Subtarget->isTargetELF()) 480 emitAttributes(); 481 } 482 483 static void 484 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, 485 MachineModuleInfoImpl::StubValueTy &MCSym) { 486 // L_foo$stub: 487 OutStreamer.EmitLabel(StubLabel); 488 // .indirect_symbol _foo 489 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 490 491 if (MCSym.getInt()) 492 // External to current translation unit. 493 OutStreamer.EmitIntValue(0, 4/*size*/); 494 else 495 // Internal to current translation unit. 496 // 497 // When we place the LSDA into the TEXT section, the type info 498 // pointers need to be indirect and pc-rel. We accomplish this by 499 // using NLPs; however, sometimes the types are local to the file. 500 // We need to fill in the value for the NLP in those cases. 501 OutStreamer.EmitValue( 502 MCSymbolRefExpr::Create(MCSym.getPointer(), OutStreamer.getContext()), 503 4 /*size*/); 504 } 505 506 507 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 508 if (Subtarget->isTargetMachO()) { 509 // All darwin targets use mach-o. 510 const TargetLoweringObjectFileMachO &TLOFMacho = 511 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 512 MachineModuleInfoMachO &MMIMacho = 513 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 514 515 // Output non-lazy-pointers for external and common global variables. 516 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 517 518 if (!Stubs.empty()) { 519 // Switch with ".non_lazy_symbol_pointer" directive. 520 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 521 EmitAlignment(2); 522 523 for (auto &Stub : Stubs) 524 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); 525 526 Stubs.clear(); 527 OutStreamer.AddBlankLine(); 528 } 529 530 Stubs = MMIMacho.GetHiddenGVStubList(); 531 if (!Stubs.empty()) { 532 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 533 EmitAlignment(2); 534 535 for (auto &Stub : Stubs) 536 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); 537 538 Stubs.clear(); 539 OutStreamer.AddBlankLine(); 540 } 541 542 // Funny Darwin hack: This flag tells the linker that no global symbols 543 // contain code that falls through to other global symbols (e.g. the obvious 544 // implementation of multiple entry points). If this doesn't occur, the 545 // linker can safely perform dead code stripping. Since LLVM never 546 // generates code that does this, it is always safe to set. 547 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 548 } 549 550 // Emit a .data.rel section containing any stubs that were created. 551 if (Subtarget->isTargetELF()) { 552 const TargetLoweringObjectFileELF &TLOFELF = 553 static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); 554 555 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 556 557 // Output stubs for external and common global variables. 558 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 559 if (!Stubs.empty()) { 560 OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); 561 const DataLayout *TD = TM.getDataLayout(); 562 563 for (auto &stub: Stubs) { 564 OutStreamer.EmitLabel(stub.first); 565 OutStreamer.EmitSymbolValue(stub.second.getPointer(), 566 TD->getPointerSize(0)); 567 } 568 Stubs.clear(); 569 } 570 } 571 } 572 573 //===----------------------------------------------------------------------===// 574 // Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 575 // FIXME: 576 // The following seem like one-off assembler flags, but they actually need 577 // to appear in the .ARM.attributes section in ELF. 578 // Instead of subclassing the MCELFStreamer, we do the work here. 579 580 static ARMBuildAttrs::CPUArch getArchForCPU(StringRef CPU, 581 const ARMSubtarget *Subtarget) { 582 if (CPU == "xscale") 583 return ARMBuildAttrs::v5TEJ; 584 585 if (Subtarget->hasV8Ops()) 586 return ARMBuildAttrs::v8; 587 else if (Subtarget->hasV7Ops()) { 588 if (Subtarget->isMClass() && Subtarget->hasThumb2DSP()) 589 return ARMBuildAttrs::v7E_M; 590 return ARMBuildAttrs::v7; 591 } else if (Subtarget->hasV6T2Ops()) 592 return ARMBuildAttrs::v6T2; 593 else if (Subtarget->hasV6MOps()) 594 return ARMBuildAttrs::v6S_M; 595 else if (Subtarget->hasV6Ops()) 596 return ARMBuildAttrs::v6; 597 else if (Subtarget->hasV5TEOps()) 598 return ARMBuildAttrs::v5TE; 599 else if (Subtarget->hasV5TOps()) 600 return ARMBuildAttrs::v5T; 601 else if (Subtarget->hasV4TOps()) 602 return ARMBuildAttrs::v4T; 603 else 604 return ARMBuildAttrs::v4; 605 } 606 607 void ARMAsmPrinter::emitAttributes() { 608 MCTargetStreamer &TS = *OutStreamer.getTargetStreamer(); 609 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 610 611 ATS.switchVendor("aeabi"); 612 613 std::string CPUString = Subtarget->getCPUString(); 614 615 // FIXME: remove krait check when GNU tools support krait cpu 616 if (CPUString != "generic" && CPUString != "krait") 617 ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString); 618 619 ATS.emitAttribute(ARMBuildAttrs::CPU_arch, 620 getArchForCPU(CPUString, Subtarget)); 621 622 // Tag_CPU_arch_profile must have the default value of 0 when "Architecture 623 // profile is not applicable (e.g. pre v7, or cross-profile code)". 624 if (Subtarget->hasV7Ops()) { 625 if (Subtarget->isAClass()) { 626 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile, 627 ARMBuildAttrs::ApplicationProfile); 628 } else if (Subtarget->isRClass()) { 629 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile, 630 ARMBuildAttrs::RealTimeProfile); 631 } else if (Subtarget->isMClass()) { 632 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile, 633 ARMBuildAttrs::MicroControllerProfile); 634 } 635 } 636 637 ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget->hasARMOps() ? 638 ARMBuildAttrs::Allowed : ARMBuildAttrs::Not_Allowed); 639 if (Subtarget->isThumb1Only()) { 640 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use, 641 ARMBuildAttrs::Allowed); 642 } else if (Subtarget->hasThumb2()) { 643 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use, 644 ARMBuildAttrs::AllowThumb32); 645 } 646 647 if (Subtarget->hasNEON()) { 648 /* NEON is not exactly a VFP architecture, but GAS emit one of 649 * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */ 650 if (Subtarget->hasFPARMv8()) { 651 if (Subtarget->hasCrypto()) 652 ATS.emitFPU(ARM::CRYPTO_NEON_FP_ARMV8); 653 else 654 ATS.emitFPU(ARM::NEON_FP_ARMV8); 655 } 656 else if (Subtarget->hasVFP4()) 657 ATS.emitFPU(ARM::NEON_VFPV4); 658 else 659 ATS.emitFPU(ARM::NEON); 660 // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture 661 if (Subtarget->hasV8Ops()) 662 ATS.emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 663 ARMBuildAttrs::AllowNeonARMv8); 664 } else { 665 if (Subtarget->hasFPARMv8()) 666 ATS.emitFPU(ARM::FP_ARMV8); 667 else if (Subtarget->hasVFP4()) 668 ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV4_D16 : ARM::VFPV4); 669 else if (Subtarget->hasVFP3()) 670 ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV3_D16 : ARM::VFPV3); 671 else if (Subtarget->hasVFP2()) 672 ATS.emitFPU(ARM::VFPV2); 673 } 674 675 if (TM.getRelocationModel() == Reloc::PIC_) { 676 // PIC specific attributes. 677 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RW_data, 678 ARMBuildAttrs::AddressRWPCRel); 679 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RO_data, 680 ARMBuildAttrs::AddressROPCRel); 681 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use, 682 ARMBuildAttrs::AddressGOT); 683 } else { 684 // Allow direct addressing of imported data for all other relocation models. 685 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use, 686 ARMBuildAttrs::AddressDirect); 687 } 688 689 // Signal various FP modes. 690 if (!TM.Options.UnsafeFPMath) { 691 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::Allowed); 692 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 693 ARMBuildAttrs::Allowed); 694 } 695 696 if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath) 697 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 698 ARMBuildAttrs::Allowed); 699 else 700 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 701 ARMBuildAttrs::AllowIEE754); 702 703 // FIXME: add more flags to ARMBuildAttributes.h 704 // 8-bytes alignment stuff. 705 ATS.emitAttribute(ARMBuildAttrs::ABI_align_needed, 1); 706 ATS.emitAttribute(ARMBuildAttrs::ABI_align_preserved, 1); 707 708 // ABI_HardFP_use attribute to indicate single precision FP. 709 if (Subtarget->isFPOnlySP()) 710 ATS.emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 711 ARMBuildAttrs::HardFPSinglePrecision); 712 713 // Hard float. Use both S and D registers and conform to AAPCS-VFP. 714 if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard) 715 ATS.emitAttribute(ARMBuildAttrs::ABI_VFP_args, ARMBuildAttrs::HardFPAAPCS); 716 717 // FIXME: Should we signal R9 usage? 718 719 if (Subtarget->hasFP16()) 720 ATS.emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP); 721 722 if (Subtarget->hasMPExtension()) 723 ATS.emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP); 724 725 // Hardware divide in ARM mode is part of base arch, starting from ARMv8. 726 // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M). 727 // It is not possible to produce DisallowDIV: if hwdiv is present in the base 728 // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits. 729 // AllowDIVExt is only emitted if hwdiv isn't available in the base arch; 730 // otherwise, the default value (AllowDIVIfExists) applies. 731 if (Subtarget->hasDivideInARMMode() && !Subtarget->hasV8Ops()) 732 ATS.emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt); 733 734 if (MMI) { 735 if (const Module *SourceModule = MMI->getModule()) { 736 // ABI_PCS_wchar_t to indicate wchar_t width 737 // FIXME: There is no way to emit value 0 (wchar_t prohibited). 738 if (auto WCharWidthValue = cast_or_null<ConstantInt>( 739 SourceModule->getModuleFlag("wchar_size"))) { 740 int WCharWidth = WCharWidthValue->getZExtValue(); 741 assert((WCharWidth == 2 || WCharWidth == 4) && 742 "wchar_t width must be 2 or 4 bytes"); 743 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_wchar_t, WCharWidth); 744 } 745 746 // ABI_enum_size to indicate enum width 747 // FIXME: There is no way to emit value 0 (enums prohibited) or value 3 748 // (all enums contain a value needing 32 bits to encode). 749 if (auto EnumWidthValue = cast_or_null<ConstantInt>( 750 SourceModule->getModuleFlag("min_enum_size"))) { 751 int EnumWidth = EnumWidthValue->getZExtValue(); 752 assert((EnumWidth == 1 || EnumWidth == 4) && 753 "Minimum enum width must be 1 or 4 bytes"); 754 int EnumBuildAttr = EnumWidth == 1 ? 1 : 2; 755 ATS.emitAttribute(ARMBuildAttrs::ABI_enum_size, EnumBuildAttr); 756 } 757 } 758 } 759 760 if (Subtarget->hasTrustZone() && Subtarget->hasVirtualization()) 761 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, 762 ARMBuildAttrs::AllowTZVirtualization); 763 else if (Subtarget->hasTrustZone()) 764 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, 765 ARMBuildAttrs::AllowTZ); 766 else if (Subtarget->hasVirtualization()) 767 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, 768 ARMBuildAttrs::AllowVirtualization); 769 770 ATS.finishAttributeSection(); 771 } 772 773 //===----------------------------------------------------------------------===// 774 775 static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 776 unsigned LabelId, MCContext &Ctx) { 777 778 MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 779 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 780 return Label; 781 } 782 783 static MCSymbolRefExpr::VariantKind 784 getModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 785 switch (Modifier) { 786 case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 787 case ARMCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; 788 case ARMCP::TPOFF: return MCSymbolRefExpr::VK_TPOFF; 789 case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_GOTTPOFF; 790 case ARMCP::GOT: return MCSymbolRefExpr::VK_GOT; 791 case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_GOTOFF; 792 } 793 llvm_unreachable("Invalid ARMCPModifier!"); 794 } 795 796 MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV, 797 unsigned char TargetFlags) { 798 if (Subtarget->isTargetMachO()) { 799 bool IsIndirect = (TargetFlags & ARMII::MO_NONLAZY) && 800 Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 801 802 if (!IsIndirect) 803 return getSymbol(GV); 804 805 // FIXME: Remove this when Darwin transition to @GOT like syntax. 806 MCSymbol *MCSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 807 MachineModuleInfoMachO &MMIMachO = 808 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 809 MachineModuleInfoImpl::StubValueTy &StubSym = 810 GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) 811 : MMIMachO.getGVStubEntry(MCSym); 812 if (!StubSym.getPointer()) 813 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV), 814 !GV->hasInternalLinkage()); 815 return MCSym; 816 } else if (Subtarget->isTargetCOFF()) { 817 assert(Subtarget->isTargetWindows() && 818 "Windows is the only supported COFF target"); 819 820 bool IsIndirect = (TargetFlags & ARMII::MO_DLLIMPORT); 821 if (!IsIndirect) 822 return getSymbol(GV); 823 824 SmallString<128> Name; 825 Name = "__imp_"; 826 getNameWithPrefix(Name, GV); 827 828 return OutContext.GetOrCreateSymbol(Name); 829 } else if (Subtarget->isTargetELF()) { 830 return getSymbol(GV); 831 } 832 llvm_unreachable("unexpected target"); 833 } 834 835 void ARMAsmPrinter:: 836 EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 837 const DataLayout *DL = TM.getDataLayout(); 838 int Size = TM.getDataLayout()->getTypeAllocSize(MCPV->getType()); 839 840 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 841 842 MCSymbol *MCSym; 843 if (ACPV->isLSDA()) { 844 SmallString<128> Str; 845 raw_svector_ostream OS(Str); 846 OS << DL->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 847 MCSym = OutContext.GetOrCreateSymbol(OS.str()); 848 } else if (ACPV->isBlockAddress()) { 849 const BlockAddress *BA = 850 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(); 851 MCSym = GetBlockAddressSymbol(BA); 852 } else if (ACPV->isGlobalValue()) { 853 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV(); 854 855 // On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so 856 // flag the global as MO_NONLAZY. 857 unsigned char TF = Subtarget->isTargetMachO() ? ARMII::MO_NONLAZY : 0; 858 MCSym = GetARMGVSymbol(GV, TF); 859 } else if (ACPV->isMachineBasicBlock()) { 860 const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB(); 861 MCSym = MBB->getSymbol(); 862 } else { 863 assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 864 const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(); 865 MCSym = GetExternalSymbolSymbol(Sym); 866 } 867 868 // Create an MCSymbol for the reference. 869 const MCExpr *Expr = 870 MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 871 OutContext); 872 873 if (ACPV->getPCAdjustment()) { 874 MCSymbol *PCLabel = getPICLabel(DL->getPrivateGlobalPrefix(), 875 getFunctionNumber(), 876 ACPV->getLabelId(), 877 OutContext); 878 const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 879 PCRelExpr = 880 MCBinaryExpr::CreateAdd(PCRelExpr, 881 MCConstantExpr::Create(ACPV->getPCAdjustment(), 882 OutContext), 883 OutContext); 884 if (ACPV->mustAddCurrentAddress()) { 885 // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 886 // label, so just emit a local label end reference that instead. 887 MCSymbol *DotSym = OutContext.CreateTempSymbol(); 888 OutStreamer.EmitLabel(DotSym); 889 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 890 PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 891 } 892 Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 893 } 894 OutStreamer.EmitValue(Expr, Size); 895 } 896 897 void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 898 unsigned Opcode = MI->getOpcode(); 899 int OpNum = 1; 900 if (Opcode == ARM::BR_JTadd) 901 OpNum = 2; 902 else if (Opcode == ARM::BR_JTm) 903 OpNum = 3; 904 905 const MachineOperand &MO1 = MI->getOperand(OpNum); 906 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 907 unsigned JTI = MO1.getIndex(); 908 909 // Emit a label for the jump table. 910 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 911 OutStreamer.EmitLabel(JTISymbol); 912 913 // Mark the jump table as data-in-code. 914 OutStreamer.EmitDataRegion(MCDR_DataRegionJT32); 915 916 // Emit each entry of the table. 917 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 918 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 919 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 920 921 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 922 MachineBasicBlock *MBB = JTBBs[i]; 923 // Construct an MCExpr for the entry. We want a value of the form: 924 // (BasicBlockAddr - TableBeginAddr) 925 // 926 // For example, a table with entries jumping to basic blocks BB0 and BB1 927 // would look like: 928 // LJTI_0_0: 929 // .word (LBB0 - LJTI_0_0) 930 // .word (LBB1 - LJTI_0_0) 931 const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 932 933 if (TM.getRelocationModel() == Reloc::PIC_) 934 Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 935 OutContext), 936 OutContext); 937 // If we're generating a table of Thumb addresses in static relocation 938 // model, we need to add one to keep interworking correctly. 939 else if (AFI->isThumbFunction()) 940 Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext), 941 OutContext); 942 OutStreamer.EmitValue(Expr, 4); 943 } 944 // Mark the end of jump table data-in-code region. 945 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 946 } 947 948 void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 949 unsigned Opcode = MI->getOpcode(); 950 int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 951 const MachineOperand &MO1 = MI->getOperand(OpNum); 952 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 953 unsigned JTI = MO1.getIndex(); 954 955 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 956 OutStreamer.EmitLabel(JTISymbol); 957 958 // Emit each entry of the table. 959 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 960 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 961 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 962 unsigned OffsetWidth = 4; 963 if (MI->getOpcode() == ARM::t2TBB_JT) { 964 OffsetWidth = 1; 965 // Mark the jump table as data-in-code. 966 OutStreamer.EmitDataRegion(MCDR_DataRegionJT8); 967 } else if (MI->getOpcode() == ARM::t2TBH_JT) { 968 OffsetWidth = 2; 969 // Mark the jump table as data-in-code. 970 OutStreamer.EmitDataRegion(MCDR_DataRegionJT16); 971 } 972 973 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 974 MachineBasicBlock *MBB = JTBBs[i]; 975 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 976 OutContext); 977 // If this isn't a TBB or TBH, the entries are direct branch instructions. 978 if (OffsetWidth == 4) { 979 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2B) 980 .addExpr(MBBSymbolExpr) 981 .addImm(ARMCC::AL) 982 .addReg(0)); 983 continue; 984 } 985 // Otherwise it's an offset from the dispatch instruction. Construct an 986 // MCExpr for the entry. We want a value of the form: 987 // (BasicBlockAddr - TableBeginAddr) / 2 988 // 989 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 990 // would look like: 991 // LJTI_0_0: 992 // .byte (LBB0 - LJTI_0_0) / 2 993 // .byte (LBB1 - LJTI_0_0) / 2 994 const MCExpr *Expr = 995 MCBinaryExpr::CreateSub(MBBSymbolExpr, 996 MCSymbolRefExpr::Create(JTISymbol, OutContext), 997 OutContext); 998 Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 999 OutContext); 1000 OutStreamer.EmitValue(Expr, OffsetWidth); 1001 } 1002 // Mark the end of jump table data-in-code region. 32-bit offsets use 1003 // actual branch instructions here, so we don't mark those as a data-region 1004 // at all. 1005 if (OffsetWidth != 4) 1006 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 1007 } 1008 1009 void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { 1010 assert(MI->getFlag(MachineInstr::FrameSetup) && 1011 "Only instruction which are involved into frame setup code are allowed"); 1012 1013 MCTargetStreamer &TS = *OutStreamer.getTargetStreamer(); 1014 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 1015 const MachineFunction &MF = *MI->getParent()->getParent(); 1016 const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 1017 const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); 1018 1019 unsigned FramePtr = RegInfo->getFrameRegister(MF); 1020 unsigned Opc = MI->getOpcode(); 1021 unsigned SrcReg, DstReg; 1022 1023 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { 1024 // Two special cases: 1025 // 1) tPUSH does not have src/dst regs. 1026 // 2) for Thumb1 code we sometimes materialize the constant via constpool 1027 // load. Yes, this is pretty fragile, but for now I don't see better 1028 // way... :( 1029 SrcReg = DstReg = ARM::SP; 1030 } else { 1031 SrcReg = MI->getOperand(1).getReg(); 1032 DstReg = MI->getOperand(0).getReg(); 1033 } 1034 1035 // Try to figure out the unwinding opcode out of src / dst regs. 1036 if (MI->mayStore()) { 1037 // Register saves. 1038 assert(DstReg == ARM::SP && 1039 "Only stack pointer as a destination reg is supported"); 1040 1041 SmallVector<unsigned, 4> RegList; 1042 // Skip src & dst reg, and pred ops. 1043 unsigned StartOp = 2 + 2; 1044 // Use all the operands. 1045 unsigned NumOffset = 0; 1046 1047 switch (Opc) { 1048 default: 1049 MI->dump(); 1050 llvm_unreachable("Unsupported opcode for unwinding information"); 1051 case ARM::tPUSH: 1052 // Special case here: no src & dst reg, but two extra imp ops. 1053 StartOp = 2; NumOffset = 2; 1054 case ARM::STMDB_UPD: 1055 case ARM::t2STMDB_UPD: 1056 case ARM::VSTMDDB_UPD: 1057 assert(SrcReg == ARM::SP && 1058 "Only stack pointer as a source reg is supported"); 1059 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset; 1060 i != NumOps; ++i) { 1061 const MachineOperand &MO = MI->getOperand(i); 1062 // Actually, there should never be any impdef stuff here. Skip it 1063 // temporary to workaround PR11902. 1064 if (MO.isImplicit()) 1065 continue; 1066 RegList.push_back(MO.getReg()); 1067 } 1068 break; 1069 case ARM::STR_PRE_IMM: 1070 case ARM::STR_PRE_REG: 1071 case ARM::t2STR_PRE: 1072 assert(MI->getOperand(2).getReg() == ARM::SP && 1073 "Only stack pointer as a source reg is supported"); 1074 RegList.push_back(SrcReg); 1075 break; 1076 } 1077 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) 1078 ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); 1079 } else { 1080 // Changes of stack / frame pointer. 1081 if (SrcReg == ARM::SP) { 1082 int64_t Offset = 0; 1083 switch (Opc) { 1084 default: 1085 MI->dump(); 1086 llvm_unreachable("Unsupported opcode for unwinding information"); 1087 case ARM::MOVr: 1088 case ARM::tMOVr: 1089 Offset = 0; 1090 break; 1091 case ARM::ADDri: 1092 Offset = -MI->getOperand(2).getImm(); 1093 break; 1094 case ARM::SUBri: 1095 case ARM::t2SUBri: 1096 Offset = MI->getOperand(2).getImm(); 1097 break; 1098 case ARM::tSUBspi: 1099 Offset = MI->getOperand(2).getImm()*4; 1100 break; 1101 case ARM::tADDspi: 1102 case ARM::tADDrSPi: 1103 Offset = -MI->getOperand(2).getImm()*4; 1104 break; 1105 case ARM::tLDRpci: { 1106 // Grab the constpool index and check, whether it corresponds to 1107 // original or cloned constpool entry. 1108 unsigned CPI = MI->getOperand(1).getIndex(); 1109 const MachineConstantPool *MCP = MF.getConstantPool(); 1110 if (CPI >= MCP->getConstants().size()) 1111 CPI = AFI.getOriginalCPIdx(CPI); 1112 assert(CPI != -1U && "Invalid constpool index"); 1113 1114 // Derive the actual offset. 1115 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; 1116 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); 1117 // FIXME: Check for user, it should be "add" instruction! 1118 Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue(); 1119 break; 1120 } 1121 } 1122 1123 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) { 1124 if (DstReg == FramePtr && FramePtr != ARM::SP) 1125 // Set-up of the frame pointer. Positive values correspond to "add" 1126 // instruction. 1127 ATS.emitSetFP(FramePtr, ARM::SP, -Offset); 1128 else if (DstReg == ARM::SP) { 1129 // Change of SP by an offset. Positive values correspond to "sub" 1130 // instruction. 1131 ATS.emitPad(Offset); 1132 } else { 1133 // Move of SP to a register. Positive values correspond to an "add" 1134 // instruction. 1135 ATS.emitMovSP(DstReg, -Offset); 1136 } 1137 } 1138 } else if (DstReg == ARM::SP) { 1139 MI->dump(); 1140 llvm_unreachable("Unsupported opcode for unwinding information"); 1141 } 1142 else { 1143 MI->dump(); 1144 llvm_unreachable("Unsupported opcode for unwinding information"); 1145 } 1146 } 1147 } 1148 1149 // Simple pseudo-instructions have their lowering (with expansion to real 1150 // instructions) auto-generated. 1151 #include "ARMGenMCPseudoLowering.inc" 1152 1153 void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 1154 const DataLayout *DL = TM.getDataLayout(); 1155 1156 // If we just ended a constant pool, mark it as such. 1157 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) { 1158 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 1159 InConstantPool = false; 1160 } 1161 1162 // Emit unwinding stuff for frame-related instructions 1163 if (Subtarget->isTargetEHABICompatible() && 1164 MI->getFlag(MachineInstr::FrameSetup)) 1165 EmitUnwindingInstruction(MI); 1166 1167 // Do any auto-generated pseudo lowerings. 1168 if (emitPseudoExpansionLowering(OutStreamer, MI)) 1169 return; 1170 1171 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) && 1172 "Pseudo flag setting opcode should be expanded early"); 1173 1174 // Check for manual lowerings. 1175 unsigned Opc = MI->getOpcode(); 1176 switch (Opc) { 1177 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass"); 1178 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing"); 1179 case ARM::LEApcrel: 1180 case ARM::tLEApcrel: 1181 case ARM::t2LEApcrel: { 1182 // FIXME: Need to also handle globals and externals 1183 MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex()); 1184 EmitToStreamer(OutStreamer, MCInstBuilder(MI->getOpcode() == 1185 ARM::t2LEApcrel ? ARM::t2ADR 1186 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 1187 : ARM::ADR)) 1188 .addReg(MI->getOperand(0).getReg()) 1189 .addExpr(MCSymbolRefExpr::Create(CPISymbol, OutContext)) 1190 // Add predicate operands. 1191 .addImm(MI->getOperand(2).getImm()) 1192 .addReg(MI->getOperand(3).getReg())); 1193 return; 1194 } 1195 case ARM::LEApcrelJT: 1196 case ARM::tLEApcrelJT: 1197 case ARM::t2LEApcrelJT: { 1198 MCSymbol *JTIPICSymbol = 1199 GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 1200 MI->getOperand(2).getImm()); 1201 EmitToStreamer(OutStreamer, MCInstBuilder(MI->getOpcode() == 1202 ARM::t2LEApcrelJT ? ARM::t2ADR 1203 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 1204 : ARM::ADR)) 1205 .addReg(MI->getOperand(0).getReg()) 1206 .addExpr(MCSymbolRefExpr::Create(JTIPICSymbol, OutContext)) 1207 // Add predicate operands. 1208 .addImm(MI->getOperand(3).getImm()) 1209 .addReg(MI->getOperand(4).getReg())); 1210 return; 1211 } 1212 // Darwin call instructions are just normal call instructions with different 1213 // clobber semantics (they clobber R9). 1214 case ARM::BX_CALL: { 1215 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 1216 .addReg(ARM::LR) 1217 .addReg(ARM::PC) 1218 // Add predicate operands. 1219 .addImm(ARMCC::AL) 1220 .addReg(0) 1221 // Add 's' bit operand (always reg0 for this) 1222 .addReg(0)); 1223 1224 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::BX) 1225 .addReg(MI->getOperand(0).getReg())); 1226 return; 1227 } 1228 case ARM::tBX_CALL: { 1229 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 1230 .addReg(ARM::LR) 1231 .addReg(ARM::PC) 1232 // Add predicate operands. 1233 .addImm(ARMCC::AL) 1234 .addReg(0)); 1235 1236 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX) 1237 .addReg(MI->getOperand(0).getReg()) 1238 // Add predicate operands. 1239 .addImm(ARMCC::AL) 1240 .addReg(0)); 1241 return; 1242 } 1243 case ARM::BMOVPCRX_CALL: { 1244 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 1245 .addReg(ARM::LR) 1246 .addReg(ARM::PC) 1247 // Add predicate operands. 1248 .addImm(ARMCC::AL) 1249 .addReg(0) 1250 // Add 's' bit operand (always reg0 for this) 1251 .addReg(0)); 1252 1253 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 1254 .addReg(ARM::PC) 1255 .addReg(MI->getOperand(0).getReg()) 1256 // Add predicate operands. 1257 .addImm(ARMCC::AL) 1258 .addReg(0) 1259 // Add 's' bit operand (always reg0 for this) 1260 .addReg(0)); 1261 return; 1262 } 1263 case ARM::BMOVPCB_CALL: { 1264 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 1265 .addReg(ARM::LR) 1266 .addReg(ARM::PC) 1267 // Add predicate operands. 1268 .addImm(ARMCC::AL) 1269 .addReg(0) 1270 // Add 's' bit operand (always reg0 for this) 1271 .addReg(0)); 1272 1273 const MachineOperand &Op = MI->getOperand(0); 1274 const GlobalValue *GV = Op.getGlobal(); 1275 const unsigned TF = Op.getTargetFlags(); 1276 MCSymbol *GVSym = GetARMGVSymbol(GV, TF); 1277 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 1278 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::Bcc) 1279 .addExpr(GVSymExpr) 1280 // Add predicate operands. 1281 .addImm(ARMCC::AL) 1282 .addReg(0)); 1283 return; 1284 } 1285 case ARM::MOVi16_ga_pcrel: 1286 case ARM::t2MOVi16_ga_pcrel: { 1287 MCInst TmpInst; 1288 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 1289 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1290 1291 unsigned TF = MI->getOperand(1).getTargetFlags(); 1292 const GlobalValue *GV = MI->getOperand(1).getGlobal(); 1293 MCSymbol *GVSym = GetARMGVSymbol(GV, TF); 1294 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 1295 1296 MCSymbol *LabelSym = getPICLabel(DL->getPrivateGlobalPrefix(), 1297 getFunctionNumber(), 1298 MI->getOperand(2).getImm(), OutContext); 1299 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 1300 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 1301 const MCExpr *PCRelExpr = 1302 ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 1303 MCBinaryExpr::CreateAdd(LabelSymExpr, 1304 MCConstantExpr::Create(PCAdj, OutContext), 1305 OutContext), OutContext), OutContext); 1306 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 1307 1308 // Add predicate operands. 1309 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1310 TmpInst.addOperand(MCOperand::CreateReg(0)); 1311 // Add 's' bit operand (always reg0 for this) 1312 TmpInst.addOperand(MCOperand::CreateReg(0)); 1313 EmitToStreamer(OutStreamer, TmpInst); 1314 return; 1315 } 1316 case ARM::MOVTi16_ga_pcrel: 1317 case ARM::t2MOVTi16_ga_pcrel: { 1318 MCInst TmpInst; 1319 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 1320 ? ARM::MOVTi16 : ARM::t2MOVTi16); 1321 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1322 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1323 1324 unsigned TF = MI->getOperand(2).getTargetFlags(); 1325 const GlobalValue *GV = MI->getOperand(2).getGlobal(); 1326 MCSymbol *GVSym = GetARMGVSymbol(GV, TF); 1327 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 1328 1329 MCSymbol *LabelSym = getPICLabel(DL->getPrivateGlobalPrefix(), 1330 getFunctionNumber(), 1331 MI->getOperand(3).getImm(), OutContext); 1332 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 1333 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 1334 const MCExpr *PCRelExpr = 1335 ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 1336 MCBinaryExpr::CreateAdd(LabelSymExpr, 1337 MCConstantExpr::Create(PCAdj, OutContext), 1338 OutContext), OutContext), OutContext); 1339 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 1340 // Add predicate operands. 1341 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1342 TmpInst.addOperand(MCOperand::CreateReg(0)); 1343 // Add 's' bit operand (always reg0 for this) 1344 TmpInst.addOperand(MCOperand::CreateReg(0)); 1345 EmitToStreamer(OutStreamer, TmpInst); 1346 return; 1347 } 1348 case ARM::tPICADD: { 1349 // This is a pseudo op for a label + instruction sequence, which looks like: 1350 // LPC0: 1351 // add r0, pc 1352 // This adds the address of LPC0 to r0. 1353 1354 // Emit the label. 1355 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(), 1356 getFunctionNumber(), MI->getOperand(2).getImm(), 1357 OutContext)); 1358 1359 // Form and emit the add. 1360 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tADDhirr) 1361 .addReg(MI->getOperand(0).getReg()) 1362 .addReg(MI->getOperand(0).getReg()) 1363 .addReg(ARM::PC) 1364 // Add predicate operands. 1365 .addImm(ARMCC::AL) 1366 .addReg(0)); 1367 return; 1368 } 1369 case ARM::PICADD: { 1370 // This is a pseudo op for a label + instruction sequence, which looks like: 1371 // LPC0: 1372 // add r0, pc, r0 1373 // This adds the address of LPC0 to r0. 1374 1375 // Emit the label. 1376 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(), 1377 getFunctionNumber(), MI->getOperand(2).getImm(), 1378 OutContext)); 1379 1380 // Form and emit the add. 1381 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDrr) 1382 .addReg(MI->getOperand(0).getReg()) 1383 .addReg(ARM::PC) 1384 .addReg(MI->getOperand(1).getReg()) 1385 // Add predicate operands. 1386 .addImm(MI->getOperand(3).getImm()) 1387 .addReg(MI->getOperand(4).getReg()) 1388 // Add 's' bit operand (always reg0 for this) 1389 .addReg(0)); 1390 return; 1391 } 1392 case ARM::PICSTR: 1393 case ARM::PICSTRB: 1394 case ARM::PICSTRH: 1395 case ARM::PICLDR: 1396 case ARM::PICLDRB: 1397 case ARM::PICLDRH: 1398 case ARM::PICLDRSB: 1399 case ARM::PICLDRSH: { 1400 // This is a pseudo op for a label + instruction sequence, which looks like: 1401 // LPC0: 1402 // OP r0, [pc, r0] 1403 // The LCP0 label is referenced by a constant pool entry in order to get 1404 // a PC-relative address at the ldr instruction. 1405 1406 // Emit the label. 1407 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(), 1408 getFunctionNumber(), MI->getOperand(2).getImm(), 1409 OutContext)); 1410 1411 // Form and emit the load 1412 unsigned Opcode; 1413 switch (MI->getOpcode()) { 1414 default: 1415 llvm_unreachable("Unexpected opcode!"); 1416 case ARM::PICSTR: Opcode = ARM::STRrs; break; 1417 case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 1418 case ARM::PICSTRH: Opcode = ARM::STRH; break; 1419 case ARM::PICLDR: Opcode = ARM::LDRrs; break; 1420 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 1421 case ARM::PICLDRH: Opcode = ARM::LDRH; break; 1422 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 1423 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 1424 } 1425 EmitToStreamer(OutStreamer, MCInstBuilder(Opcode) 1426 .addReg(MI->getOperand(0).getReg()) 1427 .addReg(ARM::PC) 1428 .addReg(MI->getOperand(1).getReg()) 1429 .addImm(0) 1430 // Add predicate operands. 1431 .addImm(MI->getOperand(3).getImm()) 1432 .addReg(MI->getOperand(4).getReg())); 1433 1434 return; 1435 } 1436 case ARM::CONSTPOOL_ENTRY: { 1437 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 1438 /// in the function. The first operand is the ID# for this instruction, the 1439 /// second is the index into the MachineConstantPool that this is, the third 1440 /// is the size in bytes of this constant pool entry. 1441 /// The required alignment is specified on the basic block holding this MI. 1442 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 1443 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 1444 1445 // If this is the first entry of the pool, mark it. 1446 if (!InConstantPool) { 1447 OutStreamer.EmitDataRegion(MCDR_DataRegion); 1448 InConstantPool = true; 1449 } 1450 1451 OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 1452 1453 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 1454 if (MCPE.isMachineConstantPoolEntry()) 1455 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 1456 else 1457 EmitGlobalConstant(MCPE.Val.ConstVal); 1458 return; 1459 } 1460 case ARM::t2BR_JT: { 1461 // Lower and emit the instruction itself, then the jump table following it. 1462 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 1463 .addReg(ARM::PC) 1464 .addReg(MI->getOperand(0).getReg()) 1465 // Add predicate operands. 1466 .addImm(ARMCC::AL) 1467 .addReg(0)); 1468 1469 // Output the data for the jump table itself 1470 EmitJump2Table(MI); 1471 return; 1472 } 1473 case ARM::t2TBB_JT: { 1474 // Lower and emit the instruction itself, then the jump table following it. 1475 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2TBB) 1476 .addReg(ARM::PC) 1477 .addReg(MI->getOperand(0).getReg()) 1478 // Add predicate operands. 1479 .addImm(ARMCC::AL) 1480 .addReg(0)); 1481 1482 // Output the data for the jump table itself 1483 EmitJump2Table(MI); 1484 // Make sure the next instruction is 2-byte aligned. 1485 EmitAlignment(1); 1486 return; 1487 } 1488 case ARM::t2TBH_JT: { 1489 // Lower and emit the instruction itself, then the jump table following it. 1490 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2TBH) 1491 .addReg(ARM::PC) 1492 .addReg(MI->getOperand(0).getReg()) 1493 // Add predicate operands. 1494 .addImm(ARMCC::AL) 1495 .addReg(0)); 1496 1497 // Output the data for the jump table itself 1498 EmitJump2Table(MI); 1499 return; 1500 } 1501 case ARM::tBR_JTr: 1502 case ARM::BR_JTr: { 1503 // Lower and emit the instruction itself, then the jump table following it. 1504 // mov pc, target 1505 MCInst TmpInst; 1506 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 1507 ARM::MOVr : ARM::tMOVr; 1508 TmpInst.setOpcode(Opc); 1509 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1510 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1511 // Add predicate operands. 1512 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1513 TmpInst.addOperand(MCOperand::CreateReg(0)); 1514 // Add 's' bit operand (always reg0 for this) 1515 if (Opc == ARM::MOVr) 1516 TmpInst.addOperand(MCOperand::CreateReg(0)); 1517 EmitToStreamer(OutStreamer, TmpInst); 1518 1519 // Make sure the Thumb jump table is 4-byte aligned. 1520 if (Opc == ARM::tMOVr) 1521 EmitAlignment(2); 1522 1523 // Output the data for the jump table itself 1524 EmitJumpTable(MI); 1525 return; 1526 } 1527 case ARM::BR_JTm: { 1528 // Lower and emit the instruction itself, then the jump table following it. 1529 // ldr pc, target 1530 MCInst TmpInst; 1531 if (MI->getOperand(1).getReg() == 0) { 1532 // literal offset 1533 TmpInst.setOpcode(ARM::LDRi12); 1534 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1535 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1536 TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 1537 } else { 1538 TmpInst.setOpcode(ARM::LDRrs); 1539 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1540 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1541 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1542 TmpInst.addOperand(MCOperand::CreateImm(0)); 1543 } 1544 // Add predicate operands. 1545 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1546 TmpInst.addOperand(MCOperand::CreateReg(0)); 1547 EmitToStreamer(OutStreamer, TmpInst); 1548 1549 // Output the data for the jump table itself 1550 EmitJumpTable(MI); 1551 return; 1552 } 1553 case ARM::BR_JTadd: { 1554 // Lower and emit the instruction itself, then the jump table following it. 1555 // add pc, target, idx 1556 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDrr) 1557 .addReg(ARM::PC) 1558 .addReg(MI->getOperand(0).getReg()) 1559 .addReg(MI->getOperand(1).getReg()) 1560 // Add predicate operands. 1561 .addImm(ARMCC::AL) 1562 .addReg(0) 1563 // Add 's' bit operand (always reg0 for this) 1564 .addReg(0)); 1565 1566 // Output the data for the jump table itself 1567 EmitJumpTable(MI); 1568 return; 1569 } 1570 case ARM::TRAP: { 1571 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1572 // FIXME: Remove this special case when they do. 1573 if (!Subtarget->isTargetMachO()) { 1574 //.long 0xe7ffdefe @ trap 1575 uint32_t Val = 0xe7ffdefeUL; 1576 OutStreamer.AddComment("trap"); 1577 OutStreamer.EmitIntValue(Val, 4); 1578 return; 1579 } 1580 break; 1581 } 1582 case ARM::TRAPNaCl: { 1583 //.long 0xe7fedef0 @ trap 1584 uint32_t Val = 0xe7fedef0UL; 1585 OutStreamer.AddComment("trap"); 1586 OutStreamer.EmitIntValue(Val, 4); 1587 return; 1588 } 1589 case ARM::tTRAP: { 1590 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1591 // FIXME: Remove this special case when they do. 1592 if (!Subtarget->isTargetMachO()) { 1593 //.short 57086 @ trap 1594 uint16_t Val = 0xdefe; 1595 OutStreamer.AddComment("trap"); 1596 OutStreamer.EmitIntValue(Val, 2); 1597 return; 1598 } 1599 break; 1600 } 1601 case ARM::t2Int_eh_sjlj_setjmp: 1602 case ARM::t2Int_eh_sjlj_setjmp_nofp: 1603 case ARM::tInt_eh_sjlj_setjmp: { 1604 // Two incoming args: GPR:$src, GPR:$val 1605 // mov $val, pc 1606 // adds $val, #7 1607 // str $val, [$src, #4] 1608 // movs r0, #0 1609 // b 1f 1610 // movs r0, #1 1611 // 1: 1612 unsigned SrcReg = MI->getOperand(0).getReg(); 1613 unsigned ValReg = MI->getOperand(1).getReg(); 1614 MCSymbol *Label = GetARMSJLJEHLabel(); 1615 OutStreamer.AddComment("eh_setjmp begin"); 1616 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 1617 .addReg(ValReg) 1618 .addReg(ARM::PC) 1619 // Predicate. 1620 .addImm(ARMCC::AL) 1621 .addReg(0)); 1622 1623 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tADDi3) 1624 .addReg(ValReg) 1625 // 's' bit operand 1626 .addReg(ARM::CPSR) 1627 .addReg(ValReg) 1628 .addImm(7) 1629 // Predicate. 1630 .addImm(ARMCC::AL) 1631 .addReg(0)); 1632 1633 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tSTRi) 1634 .addReg(ValReg) 1635 .addReg(SrcReg) 1636 // The offset immediate is #4. The operand value is scaled by 4 for the 1637 // tSTR instruction. 1638 .addImm(1) 1639 // Predicate. 1640 .addImm(ARMCC::AL) 1641 .addReg(0)); 1642 1643 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVi8) 1644 .addReg(ARM::R0) 1645 .addReg(ARM::CPSR) 1646 .addImm(0) 1647 // Predicate. 1648 .addImm(ARMCC::AL) 1649 .addReg(0)); 1650 1651 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1652 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tB) 1653 .addExpr(SymbolExpr) 1654 .addImm(ARMCC::AL) 1655 .addReg(0)); 1656 1657 OutStreamer.AddComment("eh_setjmp end"); 1658 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVi8) 1659 .addReg(ARM::R0) 1660 .addReg(ARM::CPSR) 1661 .addImm(1) 1662 // Predicate. 1663 .addImm(ARMCC::AL) 1664 .addReg(0)); 1665 1666 OutStreamer.EmitLabel(Label); 1667 return; 1668 } 1669 1670 case ARM::Int_eh_sjlj_setjmp_nofp: 1671 case ARM::Int_eh_sjlj_setjmp: { 1672 // Two incoming args: GPR:$src, GPR:$val 1673 // add $val, pc, #8 1674 // str $val, [$src, #+4] 1675 // mov r0, #0 1676 // add pc, pc, #0 1677 // mov r0, #1 1678 unsigned SrcReg = MI->getOperand(0).getReg(); 1679 unsigned ValReg = MI->getOperand(1).getReg(); 1680 1681 OutStreamer.AddComment("eh_setjmp begin"); 1682 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDri) 1683 .addReg(ValReg) 1684 .addReg(ARM::PC) 1685 .addImm(8) 1686 // Predicate. 1687 .addImm(ARMCC::AL) 1688 .addReg(0) 1689 // 's' bit operand (always reg0 for this). 1690 .addReg(0)); 1691 1692 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::STRi12) 1693 .addReg(ValReg) 1694 .addReg(SrcReg) 1695 .addImm(4) 1696 // Predicate. 1697 .addImm(ARMCC::AL) 1698 .addReg(0)); 1699 1700 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVi) 1701 .addReg(ARM::R0) 1702 .addImm(0) 1703 // Predicate. 1704 .addImm(ARMCC::AL) 1705 .addReg(0) 1706 // 's' bit operand (always reg0 for this). 1707 .addReg(0)); 1708 1709 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDri) 1710 .addReg(ARM::PC) 1711 .addReg(ARM::PC) 1712 .addImm(0) 1713 // Predicate. 1714 .addImm(ARMCC::AL) 1715 .addReg(0) 1716 // 's' bit operand (always reg0 for this). 1717 .addReg(0)); 1718 1719 OutStreamer.AddComment("eh_setjmp end"); 1720 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVi) 1721 .addReg(ARM::R0) 1722 .addImm(1) 1723 // Predicate. 1724 .addImm(ARMCC::AL) 1725 .addReg(0) 1726 // 's' bit operand (always reg0 for this). 1727 .addReg(0)); 1728 return; 1729 } 1730 case ARM::Int_eh_sjlj_longjmp: { 1731 // ldr sp, [$src, #8] 1732 // ldr $scratch, [$src, #4] 1733 // ldr r7, [$src] 1734 // bx $scratch 1735 unsigned SrcReg = MI->getOperand(0).getReg(); 1736 unsigned ScratchReg = MI->getOperand(1).getReg(); 1737 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12) 1738 .addReg(ARM::SP) 1739 .addReg(SrcReg) 1740 .addImm(8) 1741 // Predicate. 1742 .addImm(ARMCC::AL) 1743 .addReg(0)); 1744 1745 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12) 1746 .addReg(ScratchReg) 1747 .addReg(SrcReg) 1748 .addImm(4) 1749 // Predicate. 1750 .addImm(ARMCC::AL) 1751 .addReg(0)); 1752 1753 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12) 1754 .addReg(ARM::R7) 1755 .addReg(SrcReg) 1756 .addImm(0) 1757 // Predicate. 1758 .addImm(ARMCC::AL) 1759 .addReg(0)); 1760 1761 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::BX) 1762 .addReg(ScratchReg) 1763 // Predicate. 1764 .addImm(ARMCC::AL) 1765 .addReg(0)); 1766 return; 1767 } 1768 case ARM::tInt_eh_sjlj_longjmp: { 1769 // ldr $scratch, [$src, #8] 1770 // mov sp, $scratch 1771 // ldr $scratch, [$src, #4] 1772 // ldr r7, [$src] 1773 // bx $scratch 1774 unsigned SrcReg = MI->getOperand(0).getReg(); 1775 unsigned ScratchReg = MI->getOperand(1).getReg(); 1776 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi) 1777 .addReg(ScratchReg) 1778 .addReg(SrcReg) 1779 // The offset immediate is #8. The operand value is scaled by 4 for the 1780 // tLDR instruction. 1781 .addImm(2) 1782 // Predicate. 1783 .addImm(ARMCC::AL) 1784 .addReg(0)); 1785 1786 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 1787 .addReg(ARM::SP) 1788 .addReg(ScratchReg) 1789 // Predicate. 1790 .addImm(ARMCC::AL) 1791 .addReg(0)); 1792 1793 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi) 1794 .addReg(ScratchReg) 1795 .addReg(SrcReg) 1796 .addImm(1) 1797 // Predicate. 1798 .addImm(ARMCC::AL) 1799 .addReg(0)); 1800 1801 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi) 1802 .addReg(ARM::R7) 1803 .addReg(SrcReg) 1804 .addImm(0) 1805 // Predicate. 1806 .addImm(ARMCC::AL) 1807 .addReg(0)); 1808 1809 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX) 1810 .addReg(ScratchReg) 1811 // Predicate. 1812 .addImm(ARMCC::AL) 1813 .addReg(0)); 1814 return; 1815 } 1816 } 1817 1818 MCInst TmpInst; 1819 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1820 1821 EmitToStreamer(OutStreamer, TmpInst); 1822 } 1823 1824 //===----------------------------------------------------------------------===// 1825 // Target Registry Stuff 1826 //===----------------------------------------------------------------------===// 1827 1828 // Force static initialization. 1829 extern "C" void LLVMInitializeARMAsmPrinter() { 1830 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMLETarget); 1831 RegisterAsmPrinter<ARMAsmPrinter> Y(TheARMBETarget); 1832 RegisterAsmPrinter<ARMAsmPrinter> A(TheThumbLETarget); 1833 RegisterAsmPrinter<ARMAsmPrinter> B(TheThumbBETarget); 1834 } 1835