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