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