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