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