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