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