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