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