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