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 case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 821 case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD; 822 case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF; 823 case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF; 824 case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT; 825 case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF; 826 } 827 return MCSymbolRefExpr::VK_None; 828 } 829 830 MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) { 831 bool isIndirect = Subtarget->isTargetDarwin() && 832 Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 833 if (!isIndirect) 834 return Mang->getSymbol(GV); 835 836 // FIXME: Remove this when Darwin transition to @GOT like syntax. 837 MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 838 MachineModuleInfoMachO &MMIMachO = 839 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 840 MachineModuleInfoImpl::StubValueTy &StubSym = 841 GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : 842 MMIMachO.getGVStubEntry(MCSym); 843 if (StubSym.getPointer() == 0) 844 StubSym = MachineModuleInfoImpl:: 845 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 846 return MCSym; 847 } 848 849 void ARMAsmPrinter:: 850 EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 851 int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType()); 852 853 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 854 855 MCSymbol *MCSym; 856 if (ACPV->isLSDA()) { 857 SmallString<128> Str; 858 raw_svector_ostream OS(Str); 859 OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 860 MCSym = OutContext.GetOrCreateSymbol(OS.str()); 861 } else if (ACPV->isBlockAddress()) { 862 const BlockAddress *BA = 863 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(); 864 MCSym = GetBlockAddressSymbol(BA); 865 } else if (ACPV->isGlobalValue()) { 866 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV(); 867 MCSym = GetARMGVSymbol(GV); 868 } else if (ACPV->isMachineBasicBlock()) { 869 const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB(); 870 MCSym = MBB->getSymbol(); 871 } else { 872 assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 873 const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(); 874 MCSym = GetExternalSymbolSymbol(Sym); 875 } 876 877 // Create an MCSymbol for the reference. 878 const MCExpr *Expr = 879 MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 880 OutContext); 881 882 if (ACPV->getPCAdjustment()) { 883 MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), 884 getFunctionNumber(), 885 ACPV->getLabelId(), 886 OutContext); 887 const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 888 PCRelExpr = 889 MCBinaryExpr::CreateAdd(PCRelExpr, 890 MCConstantExpr::Create(ACPV->getPCAdjustment(), 891 OutContext), 892 OutContext); 893 if (ACPV->mustAddCurrentAddress()) { 894 // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 895 // label, so just emit a local label end reference that instead. 896 MCSymbol *DotSym = OutContext.CreateTempSymbol(); 897 OutStreamer.EmitLabel(DotSym); 898 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 899 PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 900 } 901 Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 902 } 903 OutStreamer.EmitValue(Expr, Size); 904 } 905 906 void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 907 unsigned Opcode = MI->getOpcode(); 908 int OpNum = 1; 909 if (Opcode == ARM::BR_JTadd) 910 OpNum = 2; 911 else if (Opcode == ARM::BR_JTm) 912 OpNum = 3; 913 914 const MachineOperand &MO1 = MI->getOperand(OpNum); 915 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 916 unsigned JTI = MO1.getIndex(); 917 918 // Tag the jump table appropriately for precise disassembly. 919 OutStreamer.EmitJumpTable32Region(); 920 921 // Emit a label for the jump table. 922 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 923 OutStreamer.EmitLabel(JTISymbol); 924 925 // Emit each entry of the table. 926 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 927 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 928 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 929 930 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 931 MachineBasicBlock *MBB = JTBBs[i]; 932 // Construct an MCExpr for the entry. We want a value of the form: 933 // (BasicBlockAddr - TableBeginAddr) 934 // 935 // For example, a table with entries jumping to basic blocks BB0 and BB1 936 // would look like: 937 // LJTI_0_0: 938 // .word (LBB0 - LJTI_0_0) 939 // .word (LBB1 - LJTI_0_0) 940 const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 941 942 if (TM.getRelocationModel() == Reloc::PIC_) 943 Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 944 OutContext), 945 OutContext); 946 // If we're generating a table of Thumb addresses in static relocation 947 // model, we need to add one to keep interworking correctly. 948 else if (AFI->isThumbFunction()) 949 Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext), 950 OutContext); 951 OutStreamer.EmitValue(Expr, 4); 952 } 953 } 954 955 void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 956 unsigned Opcode = MI->getOpcode(); 957 int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 958 const MachineOperand &MO1 = MI->getOperand(OpNum); 959 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 960 unsigned JTI = MO1.getIndex(); 961 962 // Emit a label for the jump table. 963 if (MI->getOpcode() == ARM::t2TBB_JT) { 964 OutStreamer.EmitJumpTable8Region(); 965 } else if (MI->getOpcode() == ARM::t2TBH_JT) { 966 OutStreamer.EmitJumpTable16Region(); 967 } else { 968 OutStreamer.EmitJumpTable32Region(); 969 } 970 971 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 972 OutStreamer.EmitLabel(JTISymbol); 973 974 // Emit each entry of the table. 975 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 976 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 977 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 978 unsigned OffsetWidth = 4; 979 if (MI->getOpcode() == ARM::t2TBB_JT) 980 OffsetWidth = 1; 981 else if (MI->getOpcode() == ARM::t2TBH_JT) 982 OffsetWidth = 2; 983 984 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 985 MachineBasicBlock *MBB = JTBBs[i]; 986 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 987 OutContext); 988 // If this isn't a TBB or TBH, the entries are direct branch instructions. 989 if (OffsetWidth == 4) { 990 MCInst BrInst; 991 BrInst.setOpcode(ARM::t2B); 992 BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 993 BrInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 994 BrInst.addOperand(MCOperand::CreateReg(0)); 995 OutStreamer.EmitInstruction(BrInst); 996 continue; 997 } 998 // Otherwise it's an offset from the dispatch instruction. Construct an 999 // MCExpr for the entry. We want a value of the form: 1000 // (BasicBlockAddr - TableBeginAddr) / 2 1001 // 1002 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 1003 // would look like: 1004 // LJTI_0_0: 1005 // .byte (LBB0 - LJTI_0_0) / 2 1006 // .byte (LBB1 - LJTI_0_0) / 2 1007 const MCExpr *Expr = 1008 MCBinaryExpr::CreateSub(MBBSymbolExpr, 1009 MCSymbolRefExpr::Create(JTISymbol, OutContext), 1010 OutContext); 1011 Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 1012 OutContext); 1013 OutStreamer.EmitValue(Expr, OffsetWidth); 1014 } 1015 } 1016 1017 void ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 1018 raw_ostream &OS) { 1019 unsigned NOps = MI->getNumOperands(); 1020 assert(NOps==4); 1021 OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 1022 // cast away const; DIetc do not take const operands for some reason. 1023 DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 1024 OS << V.getName(); 1025 OS << " <- "; 1026 // Frame address. Currently handles register +- offset only. 1027 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 1028 OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 1029 OS << ']'; 1030 OS << "+"; 1031 printOperand(MI, NOps-2, OS); 1032 } 1033 1034 static void populateADROperands(MCInst &Inst, unsigned Dest, 1035 const MCSymbol *Label, 1036 unsigned pred, unsigned ccreg, 1037 MCContext &Ctx) { 1038 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx); 1039 Inst.addOperand(MCOperand::CreateReg(Dest)); 1040 Inst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1041 // Add predicate operands. 1042 Inst.addOperand(MCOperand::CreateImm(pred)); 1043 Inst.addOperand(MCOperand::CreateReg(ccreg)); 1044 } 1045 1046 void ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI, 1047 unsigned Opcode) { 1048 MCInst TmpInst; 1049 1050 // Emit the instruction as usual, just patch the opcode. 1051 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1052 TmpInst.setOpcode(Opcode); 1053 OutStreamer.EmitInstruction(TmpInst); 1054 } 1055 1056 void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { 1057 assert(MI->getFlag(MachineInstr::FrameSetup) && 1058 "Only instruction which are involved into frame setup code are allowed"); 1059 1060 const MachineFunction &MF = *MI->getParent()->getParent(); 1061 const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 1062 const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); 1063 1064 unsigned FramePtr = RegInfo->getFrameRegister(MF); 1065 unsigned Opc = MI->getOpcode(); 1066 unsigned SrcReg, DstReg; 1067 1068 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { 1069 // Two special cases: 1070 // 1) tPUSH does not have src/dst regs. 1071 // 2) for Thumb1 code we sometimes materialize the constant via constpool 1072 // load. Yes, this is pretty fragile, but for now I don't see better 1073 // way... :( 1074 SrcReg = DstReg = ARM::SP; 1075 } else { 1076 SrcReg = MI->getOperand(1).getReg(); 1077 DstReg = MI->getOperand(0).getReg(); 1078 } 1079 1080 // Try to figure out the unwinding opcode out of src / dst regs. 1081 if (MI->mayStore()) { 1082 // Register saves. 1083 assert(DstReg == ARM::SP && 1084 "Only stack pointer as a destination reg is supported"); 1085 1086 SmallVector<unsigned, 4> RegList; 1087 // Skip src & dst reg, and pred ops. 1088 unsigned StartOp = 2 + 2; 1089 // Use all the operands. 1090 unsigned NumOffset = 0; 1091 1092 switch (Opc) { 1093 default: 1094 MI->dump(); 1095 assert(0 && "Unsupported opcode for unwinding information"); 1096 case ARM::tPUSH: 1097 // Special case here: no src & dst reg, but two extra imp ops. 1098 StartOp = 2; NumOffset = 2; 1099 case ARM::STMDB_UPD: 1100 case ARM::t2STMDB_UPD: 1101 case ARM::VSTMDDB_UPD: 1102 assert(SrcReg == ARM::SP && 1103 "Only stack pointer as a source reg is supported"); 1104 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset; 1105 i != NumOps; ++i) 1106 RegList.push_back(MI->getOperand(i).getReg()); 1107 break; 1108 case ARM::STR_PRE_IMM: 1109 case ARM::STR_PRE_REG: 1110 assert(MI->getOperand(2).getReg() == ARM::SP && 1111 "Only stack pointer as a source reg is supported"); 1112 RegList.push_back(SrcReg); 1113 break; 1114 } 1115 OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); 1116 } else { 1117 // Changes of stack / frame pointer. 1118 if (SrcReg == ARM::SP) { 1119 int64_t Offset = 0; 1120 switch (Opc) { 1121 default: 1122 MI->dump(); 1123 assert(0 && "Unsupported opcode for unwinding information"); 1124 case ARM::MOVr: 1125 Offset = 0; 1126 break; 1127 case ARM::ADDri: 1128 Offset = -MI->getOperand(2).getImm(); 1129 break; 1130 case ARM::SUBri: 1131 Offset = MI->getOperand(2).getImm(); 1132 break; 1133 case ARM::tSUBspi: 1134 Offset = MI->getOperand(2).getImm()*4; 1135 break; 1136 case ARM::tADDspi: 1137 case ARM::tADDrSPi: 1138 Offset = -MI->getOperand(2).getImm()*4; 1139 break; 1140 case ARM::tLDRpci: { 1141 // Grab the constpool index and check, whether it corresponds to 1142 // original or cloned constpool entry. 1143 unsigned CPI = MI->getOperand(1).getIndex(); 1144 const MachineConstantPool *MCP = MF.getConstantPool(); 1145 if (CPI >= MCP->getConstants().size()) 1146 CPI = AFI.getOriginalCPIdx(CPI); 1147 assert(CPI != -1U && "Invalid constpool index"); 1148 1149 // Derive the actual offset. 1150 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; 1151 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); 1152 // FIXME: Check for user, it should be "add" instruction! 1153 Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue(); 1154 break; 1155 } 1156 } 1157 1158 if (DstReg == FramePtr && FramePtr != ARM::SP) 1159 // Set-up of the frame pointer. Positive values correspond to "add" 1160 // instruction. 1161 OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset); 1162 else if (DstReg == ARM::SP) { 1163 // Change of SP by an offset. Positive values correspond to "sub" 1164 // instruction. 1165 OutStreamer.EmitPad(Offset); 1166 } else { 1167 MI->dump(); 1168 assert(0 && "Unsupported opcode for unwinding information"); 1169 } 1170 } else if (DstReg == ARM::SP) { 1171 // FIXME: .movsp goes here 1172 MI->dump(); 1173 assert(0 && "Unsupported opcode for unwinding information"); 1174 } 1175 else { 1176 MI->dump(); 1177 assert(0 && "Unsupported opcode for unwinding information"); 1178 } 1179 } 1180 } 1181 1182 extern cl::opt<bool> EnableARMEHABI; 1183 1184 // Simple pseudo-instructions have their lowering (with expansion to real 1185 // instructions) auto-generated. 1186 #include "ARMGenMCPseudoLowering.inc" 1187 1188 void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 1189 if (MI->getOpcode() != ARM::CONSTPOOL_ENTRY) 1190 OutStreamer.EmitCodeRegion(); 1191 1192 // Emit unwinding stuff for frame-related instructions 1193 if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup)) 1194 EmitUnwindingInstruction(MI); 1195 1196 // Do any auto-generated pseudo lowerings. 1197 if (emitPseudoExpansionLowering(OutStreamer, MI)) 1198 return; 1199 1200 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) && 1201 "Pseudo flag setting opcode should be expanded early"); 1202 1203 // Check for manual lowerings. 1204 unsigned Opc = MI->getOpcode(); 1205 switch (Opc) { 1206 case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass"); 1207 case ARM::DBG_VALUE: { 1208 if (isVerbose() && OutStreamer.hasRawTextSupport()) { 1209 SmallString<128> TmpStr; 1210 raw_svector_ostream OS(TmpStr); 1211 PrintDebugValueComment(MI, OS); 1212 OutStreamer.EmitRawText(StringRef(OS.str())); 1213 } 1214 return; 1215 } 1216 case ARM::LEApcrel: 1217 case ARM::tLEApcrel: 1218 case ARM::t2LEApcrel: { 1219 // FIXME: Need to also handle globals and externals 1220 MCInst TmpInst; 1221 TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR 1222 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 1223 : ARM::ADR)); 1224 populateADROperands(TmpInst, MI->getOperand(0).getReg(), 1225 GetCPISymbol(MI->getOperand(1).getIndex()), 1226 MI->getOperand(2).getImm(), MI->getOperand(3).getReg(), 1227 OutContext); 1228 OutStreamer.EmitInstruction(TmpInst); 1229 return; 1230 } 1231 case ARM::LEApcrelJT: 1232 case ARM::tLEApcrelJT: 1233 case ARM::t2LEApcrelJT: { 1234 MCInst TmpInst; 1235 TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR 1236 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 1237 : ARM::ADR)); 1238 populateADROperands(TmpInst, MI->getOperand(0).getReg(), 1239 GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 1240 MI->getOperand(2).getImm()), 1241 MI->getOperand(3).getImm(), MI->getOperand(4).getReg(), 1242 OutContext); 1243 OutStreamer.EmitInstruction(TmpInst); 1244 return; 1245 } 1246 // Darwin call instructions are just normal call instructions with different 1247 // clobber semantics (they clobber R9). 1248 case ARM::BXr9_CALL: 1249 case ARM::BX_CALL: { 1250 { 1251 MCInst TmpInst; 1252 TmpInst.setOpcode(ARM::MOVr); 1253 TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1254 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1255 // Add predicate operands. 1256 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1257 TmpInst.addOperand(MCOperand::CreateReg(0)); 1258 // Add 's' bit operand (always reg0 for this) 1259 TmpInst.addOperand(MCOperand::CreateReg(0)); 1260 OutStreamer.EmitInstruction(TmpInst); 1261 } 1262 { 1263 MCInst TmpInst; 1264 TmpInst.setOpcode(ARM::BX); 1265 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1266 OutStreamer.EmitInstruction(TmpInst); 1267 } 1268 return; 1269 } 1270 case ARM::tBXr9_CALL: 1271 case ARM::tBX_CALL: { 1272 { 1273 MCInst TmpInst; 1274 TmpInst.setOpcode(ARM::tMOVr); 1275 TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1276 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1277 // Add predicate operands. 1278 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1279 TmpInst.addOperand(MCOperand::CreateReg(0)); 1280 OutStreamer.EmitInstruction(TmpInst); 1281 } 1282 { 1283 MCInst TmpInst; 1284 TmpInst.setOpcode(ARM::tBX); 1285 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1286 // Add predicate operands. 1287 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1288 TmpInst.addOperand(MCOperand::CreateReg(0)); 1289 OutStreamer.EmitInstruction(TmpInst); 1290 } 1291 return; 1292 } 1293 case ARM::BMOVPCRXr9_CALL: 1294 case ARM::BMOVPCRX_CALL: { 1295 { 1296 MCInst TmpInst; 1297 TmpInst.setOpcode(ARM::MOVr); 1298 TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1299 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1300 // Add predicate operands. 1301 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1302 TmpInst.addOperand(MCOperand::CreateReg(0)); 1303 // Add 's' bit operand (always reg0 for this) 1304 TmpInst.addOperand(MCOperand::CreateReg(0)); 1305 OutStreamer.EmitInstruction(TmpInst); 1306 } 1307 { 1308 MCInst TmpInst; 1309 TmpInst.setOpcode(ARM::MOVr); 1310 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1311 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1312 // Add predicate operands. 1313 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1314 TmpInst.addOperand(MCOperand::CreateReg(0)); 1315 // Add 's' bit operand (always reg0 for this) 1316 TmpInst.addOperand(MCOperand::CreateReg(0)); 1317 OutStreamer.EmitInstruction(TmpInst); 1318 } 1319 return; 1320 } 1321 case ARM::MOVi16_ga_pcrel: 1322 case ARM::t2MOVi16_ga_pcrel: { 1323 MCInst TmpInst; 1324 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 1325 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1326 1327 unsigned TF = MI->getOperand(1).getTargetFlags(); 1328 bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC; 1329 const GlobalValue *GV = MI->getOperand(1).getGlobal(); 1330 MCSymbol *GVSym = GetARMGVSymbol(GV); 1331 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 1332 if (isPIC) { 1333 MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 1334 getFunctionNumber(), 1335 MI->getOperand(2).getImm(), OutContext); 1336 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 1337 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 1338 const MCExpr *PCRelExpr = 1339 ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 1340 MCBinaryExpr::CreateAdd(LabelSymExpr, 1341 MCConstantExpr::Create(PCAdj, OutContext), 1342 OutContext), OutContext), OutContext); 1343 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 1344 } else { 1345 const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext); 1346 TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 1347 } 1348 1349 // Add predicate operands. 1350 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1351 TmpInst.addOperand(MCOperand::CreateReg(0)); 1352 // Add 's' bit operand (always reg0 for this) 1353 TmpInst.addOperand(MCOperand::CreateReg(0)); 1354 OutStreamer.EmitInstruction(TmpInst); 1355 return; 1356 } 1357 case ARM::MOVTi16_ga_pcrel: 1358 case ARM::t2MOVTi16_ga_pcrel: { 1359 MCInst TmpInst; 1360 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 1361 ? ARM::MOVTi16 : ARM::t2MOVTi16); 1362 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1363 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1364 1365 unsigned TF = MI->getOperand(2).getTargetFlags(); 1366 bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC; 1367 const GlobalValue *GV = MI->getOperand(2).getGlobal(); 1368 MCSymbol *GVSym = GetARMGVSymbol(GV); 1369 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 1370 if (isPIC) { 1371 MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 1372 getFunctionNumber(), 1373 MI->getOperand(3).getImm(), OutContext); 1374 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 1375 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 1376 const MCExpr *PCRelExpr = 1377 ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 1378 MCBinaryExpr::CreateAdd(LabelSymExpr, 1379 MCConstantExpr::Create(PCAdj, OutContext), 1380 OutContext), OutContext), OutContext); 1381 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 1382 } else { 1383 const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext); 1384 TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 1385 } 1386 // Add predicate operands. 1387 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1388 TmpInst.addOperand(MCOperand::CreateReg(0)); 1389 // Add 's' bit operand (always reg0 for this) 1390 TmpInst.addOperand(MCOperand::CreateReg(0)); 1391 OutStreamer.EmitInstruction(TmpInst); 1392 return; 1393 } 1394 case ARM::tPICADD: { 1395 // This is a pseudo op for a label + instruction sequence, which looks like: 1396 // LPC0: 1397 // add r0, pc 1398 // This adds the address of LPC0 to r0. 1399 1400 // Emit the label. 1401 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1402 getFunctionNumber(), MI->getOperand(2).getImm(), 1403 OutContext)); 1404 1405 // Form and emit the add. 1406 MCInst AddInst; 1407 AddInst.setOpcode(ARM::tADDhirr); 1408 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1409 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1410 AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1411 // Add predicate operands. 1412 AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1413 AddInst.addOperand(MCOperand::CreateReg(0)); 1414 OutStreamer.EmitInstruction(AddInst); 1415 return; 1416 } 1417 case ARM::PICADD: { 1418 // This is a pseudo op for a label + instruction sequence, which looks like: 1419 // LPC0: 1420 // add r0, pc, r0 1421 // This adds the address of LPC0 to r0. 1422 1423 // Emit the label. 1424 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1425 getFunctionNumber(), MI->getOperand(2).getImm(), 1426 OutContext)); 1427 1428 // Form and emit the add. 1429 MCInst AddInst; 1430 AddInst.setOpcode(ARM::ADDrr); 1431 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1432 AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1433 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1434 // Add predicate operands. 1435 AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 1436 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 1437 // Add 's' bit operand (always reg0 for this) 1438 AddInst.addOperand(MCOperand::CreateReg(0)); 1439 OutStreamer.EmitInstruction(AddInst); 1440 return; 1441 } 1442 case ARM::PICSTR: 1443 case ARM::PICSTRB: 1444 case ARM::PICSTRH: 1445 case ARM::PICLDR: 1446 case ARM::PICLDRB: 1447 case ARM::PICLDRH: 1448 case ARM::PICLDRSB: 1449 case ARM::PICLDRSH: { 1450 // This is a pseudo op for a label + instruction sequence, which looks like: 1451 // LPC0: 1452 // OP r0, [pc, r0] 1453 // The LCP0 label is referenced by a constant pool entry in order to get 1454 // a PC-relative address at the ldr instruction. 1455 1456 // Emit the label. 1457 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1458 getFunctionNumber(), MI->getOperand(2).getImm(), 1459 OutContext)); 1460 1461 // Form and emit the load 1462 unsigned Opcode; 1463 switch (MI->getOpcode()) { 1464 default: 1465 llvm_unreachable("Unexpected opcode!"); 1466 case ARM::PICSTR: Opcode = ARM::STRrs; break; 1467 case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 1468 case ARM::PICSTRH: Opcode = ARM::STRH; break; 1469 case ARM::PICLDR: Opcode = ARM::LDRrs; break; 1470 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 1471 case ARM::PICLDRH: Opcode = ARM::LDRH; break; 1472 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 1473 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 1474 } 1475 MCInst LdStInst; 1476 LdStInst.setOpcode(Opcode); 1477 LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1478 LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1479 LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1480 LdStInst.addOperand(MCOperand::CreateImm(0)); 1481 // Add predicate operands. 1482 LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 1483 LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 1484 OutStreamer.EmitInstruction(LdStInst); 1485 1486 return; 1487 } 1488 case ARM::CONSTPOOL_ENTRY: { 1489 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 1490 /// in the function. The first operand is the ID# for this instruction, the 1491 /// second is the index into the MachineConstantPool that this is, the third 1492 /// is the size in bytes of this constant pool entry. 1493 /// The required alignment is specified on the basic block holding this MI. 1494 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 1495 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 1496 1497 // Mark the constant pool entry as data if we're not already in a data 1498 // region. 1499 OutStreamer.EmitDataRegion(); 1500 OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 1501 1502 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 1503 if (MCPE.isMachineConstantPoolEntry()) 1504 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 1505 else 1506 EmitGlobalConstant(MCPE.Val.ConstVal); 1507 return; 1508 } 1509 case ARM::t2BR_JT: { 1510 // Lower and emit the instruction itself, then the jump table following it. 1511 MCInst TmpInst; 1512 TmpInst.setOpcode(ARM::tMOVr); 1513 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1514 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1515 // Add predicate operands. 1516 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1517 TmpInst.addOperand(MCOperand::CreateReg(0)); 1518 OutStreamer.EmitInstruction(TmpInst); 1519 // Output the data for the jump table itself 1520 EmitJump2Table(MI); 1521 return; 1522 } 1523 case ARM::t2TBB_JT: { 1524 // Lower and emit the instruction itself, then the jump table following it. 1525 MCInst TmpInst; 1526 1527 TmpInst.setOpcode(ARM::t2TBB); 1528 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1529 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1530 // Add predicate operands. 1531 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1532 TmpInst.addOperand(MCOperand::CreateReg(0)); 1533 OutStreamer.EmitInstruction(TmpInst); 1534 // Output the data for the jump table itself 1535 EmitJump2Table(MI); 1536 // Make sure the next instruction is 2-byte aligned. 1537 EmitAlignment(1); 1538 return; 1539 } 1540 case ARM::t2TBH_JT: { 1541 // Lower and emit the instruction itself, then the jump table following it. 1542 MCInst TmpInst; 1543 1544 TmpInst.setOpcode(ARM::t2TBH); 1545 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1546 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1547 // Add predicate operands. 1548 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1549 TmpInst.addOperand(MCOperand::CreateReg(0)); 1550 OutStreamer.EmitInstruction(TmpInst); 1551 // Output the data for the jump table itself 1552 EmitJump2Table(MI); 1553 return; 1554 } 1555 case ARM::tBR_JTr: 1556 case ARM::BR_JTr: { 1557 // Lower and emit the instruction itself, then the jump table following it. 1558 // mov pc, target 1559 MCInst TmpInst; 1560 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 1561 ARM::MOVr : ARM::tMOVr; 1562 TmpInst.setOpcode(Opc); 1563 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1564 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1565 // Add predicate operands. 1566 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1567 TmpInst.addOperand(MCOperand::CreateReg(0)); 1568 // Add 's' bit operand (always reg0 for this) 1569 if (Opc == ARM::MOVr) 1570 TmpInst.addOperand(MCOperand::CreateReg(0)); 1571 OutStreamer.EmitInstruction(TmpInst); 1572 1573 // Make sure the Thumb jump table is 4-byte aligned. 1574 if (Opc == ARM::tMOVr) 1575 EmitAlignment(2); 1576 1577 // Output the data for the jump table itself 1578 EmitJumpTable(MI); 1579 return; 1580 } 1581 case ARM::BR_JTm: { 1582 // Lower and emit the instruction itself, then the jump table following it. 1583 // ldr pc, target 1584 MCInst TmpInst; 1585 if (MI->getOperand(1).getReg() == 0) { 1586 // literal offset 1587 TmpInst.setOpcode(ARM::LDRi12); 1588 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1589 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1590 TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 1591 } else { 1592 TmpInst.setOpcode(ARM::LDRrs); 1593 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1594 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1595 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1596 TmpInst.addOperand(MCOperand::CreateImm(0)); 1597 } 1598 // Add predicate operands. 1599 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1600 TmpInst.addOperand(MCOperand::CreateReg(0)); 1601 OutStreamer.EmitInstruction(TmpInst); 1602 1603 // Output the data for the jump table itself 1604 EmitJumpTable(MI); 1605 return; 1606 } 1607 case ARM::BR_JTadd: { 1608 // Lower and emit the instruction itself, then the jump table following it. 1609 // add pc, target, idx 1610 MCInst TmpInst; 1611 TmpInst.setOpcode(ARM::ADDrr); 1612 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1613 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1614 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1615 // Add predicate operands. 1616 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1617 TmpInst.addOperand(MCOperand::CreateReg(0)); 1618 // Add 's' bit operand (always reg0 for this) 1619 TmpInst.addOperand(MCOperand::CreateReg(0)); 1620 OutStreamer.EmitInstruction(TmpInst); 1621 1622 // Output the data for the jump table itself 1623 EmitJumpTable(MI); 1624 return; 1625 } 1626 case ARM::TRAP: { 1627 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1628 // FIXME: Remove this special case when they do. 1629 if (!Subtarget->isTargetDarwin()) { 1630 //.long 0xe7ffdefe @ trap 1631 uint32_t Val = 0xe7ffdefeUL; 1632 OutStreamer.AddComment("trap"); 1633 OutStreamer.EmitIntValue(Val, 4); 1634 return; 1635 } 1636 break; 1637 } 1638 case ARM::tTRAP: { 1639 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1640 // FIXME: Remove this special case when they do. 1641 if (!Subtarget->isTargetDarwin()) { 1642 //.short 57086 @ trap 1643 uint16_t Val = 0xdefe; 1644 OutStreamer.AddComment("trap"); 1645 OutStreamer.EmitIntValue(Val, 2); 1646 return; 1647 } 1648 break; 1649 } 1650 case ARM::t2Int_eh_sjlj_setjmp: 1651 case ARM::t2Int_eh_sjlj_setjmp_nofp: 1652 case ARM::tInt_eh_sjlj_setjmp: { 1653 // Two incoming args: GPR:$src, GPR:$val 1654 // mov $val, pc 1655 // adds $val, #7 1656 // str $val, [$src, #4] 1657 // movs r0, #0 1658 // b 1f 1659 // movs r0, #1 1660 // 1: 1661 unsigned SrcReg = MI->getOperand(0).getReg(); 1662 unsigned ValReg = MI->getOperand(1).getReg(); 1663 MCSymbol *Label = GetARMSJLJEHLabel(); 1664 { 1665 MCInst TmpInst; 1666 TmpInst.setOpcode(ARM::tMOVr); 1667 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1668 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1669 // Predicate. 1670 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1671 TmpInst.addOperand(MCOperand::CreateReg(0)); 1672 OutStreamer.AddComment("eh_setjmp begin"); 1673 OutStreamer.EmitInstruction(TmpInst); 1674 } 1675 { 1676 MCInst TmpInst; 1677 TmpInst.setOpcode(ARM::tADDi3); 1678 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1679 // 's' bit operand 1680 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1681 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1682 TmpInst.addOperand(MCOperand::CreateImm(7)); 1683 // Predicate. 1684 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1685 TmpInst.addOperand(MCOperand::CreateReg(0)); 1686 OutStreamer.EmitInstruction(TmpInst); 1687 } 1688 { 1689 MCInst TmpInst; 1690 TmpInst.setOpcode(ARM::tSTRi); 1691 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1692 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1693 // The offset immediate is #4. The operand value is scaled by 4 for the 1694 // tSTR instruction. 1695 TmpInst.addOperand(MCOperand::CreateImm(1)); 1696 // Predicate. 1697 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1698 TmpInst.addOperand(MCOperand::CreateReg(0)); 1699 OutStreamer.EmitInstruction(TmpInst); 1700 } 1701 { 1702 MCInst TmpInst; 1703 TmpInst.setOpcode(ARM::tMOVi8); 1704 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1705 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1706 TmpInst.addOperand(MCOperand::CreateImm(0)); 1707 // Predicate. 1708 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1709 TmpInst.addOperand(MCOperand::CreateReg(0)); 1710 OutStreamer.EmitInstruction(TmpInst); 1711 } 1712 { 1713 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1714 MCInst TmpInst; 1715 TmpInst.setOpcode(ARM::tB); 1716 TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1717 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1718 TmpInst.addOperand(MCOperand::CreateReg(0)); 1719 OutStreamer.EmitInstruction(TmpInst); 1720 } 1721 { 1722 MCInst TmpInst; 1723 TmpInst.setOpcode(ARM::tMOVi8); 1724 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1725 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1726 TmpInst.addOperand(MCOperand::CreateImm(1)); 1727 // Predicate. 1728 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1729 TmpInst.addOperand(MCOperand::CreateReg(0)); 1730 OutStreamer.AddComment("eh_setjmp end"); 1731 OutStreamer.EmitInstruction(TmpInst); 1732 } 1733 OutStreamer.EmitLabel(Label); 1734 return; 1735 } 1736 1737 case ARM::Int_eh_sjlj_setjmp_nofp: 1738 case ARM::Int_eh_sjlj_setjmp: { 1739 // Two incoming args: GPR:$src, GPR:$val 1740 // add $val, pc, #8 1741 // str $val, [$src, #+4] 1742 // mov r0, #0 1743 // add pc, pc, #0 1744 // mov r0, #1 1745 unsigned SrcReg = MI->getOperand(0).getReg(); 1746 unsigned ValReg = MI->getOperand(1).getReg(); 1747 1748 { 1749 MCInst TmpInst; 1750 TmpInst.setOpcode(ARM::ADDri); 1751 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1752 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1753 TmpInst.addOperand(MCOperand::CreateImm(8)); 1754 // Predicate. 1755 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1756 TmpInst.addOperand(MCOperand::CreateReg(0)); 1757 // 's' bit operand (always reg0 for this). 1758 TmpInst.addOperand(MCOperand::CreateReg(0)); 1759 OutStreamer.AddComment("eh_setjmp begin"); 1760 OutStreamer.EmitInstruction(TmpInst); 1761 } 1762 { 1763 MCInst TmpInst; 1764 TmpInst.setOpcode(ARM::STRi12); 1765 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1766 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1767 TmpInst.addOperand(MCOperand::CreateImm(4)); 1768 // Predicate. 1769 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1770 TmpInst.addOperand(MCOperand::CreateReg(0)); 1771 OutStreamer.EmitInstruction(TmpInst); 1772 } 1773 { 1774 MCInst TmpInst; 1775 TmpInst.setOpcode(ARM::MOVi); 1776 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1777 TmpInst.addOperand(MCOperand::CreateImm(0)); 1778 // Predicate. 1779 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1780 TmpInst.addOperand(MCOperand::CreateReg(0)); 1781 // 's' bit operand (always reg0 for this). 1782 TmpInst.addOperand(MCOperand::CreateReg(0)); 1783 OutStreamer.EmitInstruction(TmpInst); 1784 } 1785 { 1786 MCInst TmpInst; 1787 TmpInst.setOpcode(ARM::ADDri); 1788 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1789 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1790 TmpInst.addOperand(MCOperand::CreateImm(0)); 1791 // Predicate. 1792 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1793 TmpInst.addOperand(MCOperand::CreateReg(0)); 1794 // 's' bit operand (always reg0 for this). 1795 TmpInst.addOperand(MCOperand::CreateReg(0)); 1796 OutStreamer.EmitInstruction(TmpInst); 1797 } 1798 { 1799 MCInst TmpInst; 1800 TmpInst.setOpcode(ARM::MOVi); 1801 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1802 TmpInst.addOperand(MCOperand::CreateImm(1)); 1803 // Predicate. 1804 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1805 TmpInst.addOperand(MCOperand::CreateReg(0)); 1806 // 's' bit operand (always reg0 for this). 1807 TmpInst.addOperand(MCOperand::CreateReg(0)); 1808 OutStreamer.AddComment("eh_setjmp end"); 1809 OutStreamer.EmitInstruction(TmpInst); 1810 } 1811 return; 1812 } 1813 case ARM::Int_eh_sjlj_longjmp: { 1814 // ldr sp, [$src, #8] 1815 // ldr $scratch, [$src, #4] 1816 // ldr r7, [$src] 1817 // bx $scratch 1818 unsigned SrcReg = MI->getOperand(0).getReg(); 1819 unsigned ScratchReg = MI->getOperand(1).getReg(); 1820 { 1821 MCInst TmpInst; 1822 TmpInst.setOpcode(ARM::LDRi12); 1823 TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1824 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1825 TmpInst.addOperand(MCOperand::CreateImm(8)); 1826 // Predicate. 1827 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1828 TmpInst.addOperand(MCOperand::CreateReg(0)); 1829 OutStreamer.EmitInstruction(TmpInst); 1830 } 1831 { 1832 MCInst TmpInst; 1833 TmpInst.setOpcode(ARM::LDRi12); 1834 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1835 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1836 TmpInst.addOperand(MCOperand::CreateImm(4)); 1837 // Predicate. 1838 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1839 TmpInst.addOperand(MCOperand::CreateReg(0)); 1840 OutStreamer.EmitInstruction(TmpInst); 1841 } 1842 { 1843 MCInst TmpInst; 1844 TmpInst.setOpcode(ARM::LDRi12); 1845 TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1846 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1847 TmpInst.addOperand(MCOperand::CreateImm(0)); 1848 // Predicate. 1849 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1850 TmpInst.addOperand(MCOperand::CreateReg(0)); 1851 OutStreamer.EmitInstruction(TmpInst); 1852 } 1853 { 1854 MCInst TmpInst; 1855 TmpInst.setOpcode(ARM::BX); 1856 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1857 // Predicate. 1858 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1859 TmpInst.addOperand(MCOperand::CreateReg(0)); 1860 OutStreamer.EmitInstruction(TmpInst); 1861 } 1862 return; 1863 } 1864 case ARM::tInt_eh_sjlj_longjmp: { 1865 // ldr $scratch, [$src, #8] 1866 // mov sp, $scratch 1867 // ldr $scratch, [$src, #4] 1868 // ldr r7, [$src] 1869 // bx $scratch 1870 unsigned SrcReg = MI->getOperand(0).getReg(); 1871 unsigned ScratchReg = MI->getOperand(1).getReg(); 1872 { 1873 MCInst TmpInst; 1874 TmpInst.setOpcode(ARM::tLDRi); 1875 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1876 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1877 // The offset immediate is #8. The operand value is scaled by 4 for the 1878 // tLDR instruction. 1879 TmpInst.addOperand(MCOperand::CreateImm(2)); 1880 // Predicate. 1881 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1882 TmpInst.addOperand(MCOperand::CreateReg(0)); 1883 OutStreamer.EmitInstruction(TmpInst); 1884 } 1885 { 1886 MCInst TmpInst; 1887 TmpInst.setOpcode(ARM::tMOVr); 1888 TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1889 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1890 // Predicate. 1891 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1892 TmpInst.addOperand(MCOperand::CreateReg(0)); 1893 OutStreamer.EmitInstruction(TmpInst); 1894 } 1895 { 1896 MCInst TmpInst; 1897 TmpInst.setOpcode(ARM::tLDRi); 1898 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1899 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1900 TmpInst.addOperand(MCOperand::CreateImm(1)); 1901 // Predicate. 1902 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1903 TmpInst.addOperand(MCOperand::CreateReg(0)); 1904 OutStreamer.EmitInstruction(TmpInst); 1905 } 1906 { 1907 MCInst TmpInst; 1908 TmpInst.setOpcode(ARM::tLDRr); 1909 TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1910 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1911 TmpInst.addOperand(MCOperand::CreateReg(0)); 1912 // Predicate. 1913 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1914 TmpInst.addOperand(MCOperand::CreateReg(0)); 1915 OutStreamer.EmitInstruction(TmpInst); 1916 } 1917 { 1918 MCInst TmpInst; 1919 TmpInst.setOpcode(ARM::tBX); 1920 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1921 // Predicate. 1922 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1923 TmpInst.addOperand(MCOperand::CreateReg(0)); 1924 OutStreamer.EmitInstruction(TmpInst); 1925 } 1926 return; 1927 } 1928 } 1929 1930 MCInst TmpInst; 1931 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1932 1933 OutStreamer.EmitInstruction(TmpInst); 1934 } 1935 1936 //===----------------------------------------------------------------------===// 1937 // Target Registry Stuff 1938 //===----------------------------------------------------------------------===// 1939 1940 // Force static initialization. 1941 extern "C" void LLVMInitializeARMAsmPrinter() { 1942 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 1943 RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 1944 } 1945