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#include "ARMAsmPrinter.h" 16#include "ARM.h" 17#include "ARMConstantPoolValue.h" 18#include "ARMFPUName.h" 19#include "ARMArchExtName.h" 20#include "ARMMachineFunctionInfo.h" 21#include "ARMTargetMachine.h" 22#include "ARMTargetObjectFile.h" 23#include "InstPrinter/ARMInstPrinter.h" 24#include "MCTargetDesc/ARMAddressingModes.h" 25#include "MCTargetDesc/ARMMCExpr.h" 26#include "llvm/ADT/SetVector.h" 27#include "llvm/ADT/SmallString.h" 28#include "llvm/CodeGen/MachineFunctionPass.h" 29#include "llvm/CodeGen/MachineJumpTableInfo.h" 30#include "llvm/CodeGen/MachineModuleInfoImpls.h" 31#include "llvm/IR/Constants.h" 32#include "llvm/IR/DataLayout.h" 33#include "llvm/IR/DebugInfo.h" 34#include "llvm/IR/Mangler.h" 35#include "llvm/IR/Module.h" 36#include "llvm/IR/Type.h" 37#include "llvm/MC/MCAsmInfo.h" 38#include "llvm/MC/MCAssembler.h" 39#include "llvm/MC/MCContext.h" 40#include "llvm/MC/MCELFStreamer.h" 41#include "llvm/MC/MCInst.h" 42#include "llvm/MC/MCInstBuilder.h" 43#include "llvm/MC/MCObjectStreamer.h" 44#include "llvm/MC/MCSectionMachO.h" 45#include "llvm/MC/MCStreamer.h" 46#include "llvm/MC/MCSymbol.h" 47#include "llvm/Support/ARMBuildAttributes.h" 48#include "llvm/Support/COFF.h" 49#include "llvm/Support/CommandLine.h" 50#include "llvm/Support/Debug.h" 51#include "llvm/Support/ELF.h" 52#include "llvm/Support/ErrorHandling.h" 53#include "llvm/Support/TargetRegistry.h" 54#include "llvm/Support/raw_ostream.h" 55#include "llvm/Target/TargetMachine.h" 56#include <cctype> 57using namespace llvm; 58 59#define DEBUG_TYPE "asm-printer" 60 61ARMAsmPrinter::ARMAsmPrinter(TargetMachine &TM, 62 std::unique_ptr<MCStreamer> Streamer) 63 : AsmPrinter(TM, std::move(Streamer)), AFI(nullptr), MCP(nullptr), 64 InConstantPool(false) {} 65 66void ARMAsmPrinter::EmitFunctionBodyEnd() { 67 // Make sure to terminate any constant pools that were at the end 68 // of the function. 69 if (!InConstantPool) 70 return; 71 InConstantPool = false; 72 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 73} 74 75void ARMAsmPrinter::EmitFunctionEntryLabel() { 76 if (AFI->isThumbFunction()) { 77 OutStreamer.EmitAssemblerFlag(MCAF_Code16); 78 OutStreamer.EmitThumbFunc(CurrentFnSym); 79 } 80 81 OutStreamer.EmitLabel(CurrentFnSym); 82} 83 84void ARMAsmPrinter::EmitXXStructor(const Constant *CV) { 85 uint64_t Size = TM.getDataLayout()->getTypeAllocSize(CV->getType()); 86 assert(Size && "C++ constructor pointer had zero size!"); 87 88 const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts()); 89 assert(GV && "C++ constructor pointer was not a GlobalValue!"); 90 91 const MCExpr *E = MCSymbolRefExpr::Create(GetARMGVSymbol(GV, 92 ARMII::MO_NO_FLAG), 93 (Subtarget->isTargetELF() 94 ? MCSymbolRefExpr::VK_ARM_TARGET1 95 : MCSymbolRefExpr::VK_None), 96 OutContext); 97 98 OutStreamer.EmitValue(E, Size); 99} 100 101/// runOnMachineFunction - This uses the EmitInstruction() 102/// method to print assembly for each instruction. 103/// 104bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 105 AFI = MF.getInfo<ARMFunctionInfo>(); 106 MCP = MF.getConstantPool(); 107 Subtarget = &MF.getSubtarget<ARMSubtarget>(); 108 109 SetupMachineFunction(MF); 110 111 if (Subtarget->isTargetCOFF()) { 112 bool Internal = MF.getFunction()->hasInternalLinkage(); 113 COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC 114 : COFF::IMAGE_SYM_CLASS_EXTERNAL; 115 int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT; 116 117 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 118 OutStreamer.EmitCOFFSymbolStorageClass(Scl); 119 OutStreamer.EmitCOFFSymbolType(Type); 120 OutStreamer.EndCOFFSymbolDef(); 121 } 122 123 // Emit the rest of the function body. 124 EmitFunctionBody(); 125 126 // If we need V4T thumb mode Register Indirect Jump pads, emit them. 127 // These are created per function, rather than per TU, since it's 128 // relatively easy to exceed the thumb branch range within a TU. 129 if (! ThumbIndirectPads.empty()) { 130 OutStreamer.EmitAssemblerFlag(MCAF_Code16); 131 EmitAlignment(1); 132 for (unsigned i = 0, e = ThumbIndirectPads.size(); i < e; i++) { 133 OutStreamer.EmitLabel(ThumbIndirectPads[i].second); 134 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX) 135 .addReg(ThumbIndirectPads[i].first) 136 // Add predicate operands. 137 .addImm(ARMCC::AL) 138 .addReg(0)); 139 } 140 ThumbIndirectPads.clear(); 141 } 142 143 // We didn't modify anything. 144 return false; 145} 146 147void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 148 raw_ostream &O, const char *Modifier) { 149 const MachineOperand &MO = MI->getOperand(OpNum); 150 unsigned TF = MO.getTargetFlags(); 151 152 switch (MO.getType()) { 153 default: llvm_unreachable("<unknown operand type>"); 154 case MachineOperand::MO_Register: { 155 unsigned Reg = MO.getReg(); 156 assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 157 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 158 if(ARM::GPRPairRegClass.contains(Reg)) { 159 const MachineFunction &MF = *MI->getParent()->getParent(); 160 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 161 Reg = TRI->getSubReg(Reg, ARM::gsub_0); 162 } 163 O << ARMInstPrinter::getRegisterName(Reg); 164 break; 165 } 166 case MachineOperand::MO_Immediate: { 167 int64_t Imm = MO.getImm(); 168 O << '#'; 169 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 170 (TF == ARMII::MO_LO16)) 171 O << ":lower16:"; 172 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 173 (TF == ARMII::MO_HI16)) 174 O << ":upper16:"; 175 O << Imm; 176 break; 177 } 178 case MachineOperand::MO_MachineBasicBlock: 179 O << *MO.getMBB()->getSymbol(); 180 return; 181 case MachineOperand::MO_GlobalAddress: { 182 const GlobalValue *GV = MO.getGlobal(); 183 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 184 (TF & ARMII::MO_LO16)) 185 O << ":lower16:"; 186 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 187 (TF & ARMII::MO_HI16)) 188 O << ":upper16:"; 189 O << *GetARMGVSymbol(GV, TF); 190 191 printOffset(MO.getOffset(), O); 192 if (TF == ARMII::MO_PLT) 193 O << "(PLT)"; 194 break; 195 } 196 case MachineOperand::MO_ConstantPoolIndex: 197 O << *GetCPISymbol(MO.getIndex()); 198 break; 199 } 200} 201 202//===--------------------------------------------------------------------===// 203 204MCSymbol *ARMAsmPrinter:: 205GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 206 const DataLayout *DL = TM.getDataLayout(); 207 SmallString<60> Name; 208 raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "JTI" 209 << getFunctionNumber() << '_' << uid << '_' << uid2; 210 return OutContext.GetOrCreateSymbol(Name); 211} 212 213 214MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel() const { 215 const DataLayout *DL = TM.getDataLayout(); 216 SmallString<60> Name; 217 raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "SJLJEH" 218 << getFunctionNumber(); 219 return OutContext.GetOrCreateSymbol(Name); 220} 221 222bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 223 unsigned AsmVariant, const char *ExtraCode, 224 raw_ostream &O) { 225 // Does this asm operand have a single letter operand modifier? 226 if (ExtraCode && ExtraCode[0]) { 227 if (ExtraCode[1] != 0) return true; // Unknown modifier. 228 229 switch (ExtraCode[0]) { 230 default: 231 // See if this is a generic print operand 232 return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O); 233 case 'a': // Print as a memory address. 234 if (MI->getOperand(OpNum).isReg()) { 235 O << "[" 236 << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 237 << "]"; 238 return false; 239 } 240 // Fallthrough 241 case 'c': // Don't print "#" before an immediate operand. 242 if (!MI->getOperand(OpNum).isImm()) 243 return true; 244 O << MI->getOperand(OpNum).getImm(); 245 return false; 246 case 'P': // Print a VFP double precision register. 247 case 'q': // Print a NEON quad precision register. 248 printOperand(MI, OpNum, O); 249 return false; 250 case 'y': // Print a VFP single precision register as indexed double. 251 if (MI->getOperand(OpNum).isReg()) { 252 unsigned Reg = MI->getOperand(OpNum).getReg(); 253 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 254 // Find the 'd' register that has this 's' register as a sub-register, 255 // and determine the lane number. 256 for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) { 257 if (!ARM::DPRRegClass.contains(*SR)) 258 continue; 259 bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg; 260 O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]"); 261 return false; 262 } 263 } 264 return true; 265 case 'B': // Bitwise inverse of integer or symbol without a preceding #. 266 if (!MI->getOperand(OpNum).isImm()) 267 return true; 268 O << ~(MI->getOperand(OpNum).getImm()); 269 return false; 270 case 'L': // The low 16 bits of an immediate constant. 271 if (!MI->getOperand(OpNum).isImm()) 272 return true; 273 O << (MI->getOperand(OpNum).getImm() & 0xffff); 274 return false; 275 case 'M': { // A register range suitable for LDM/STM. 276 if (!MI->getOperand(OpNum).isReg()) 277 return true; 278 const MachineOperand &MO = MI->getOperand(OpNum); 279 unsigned RegBegin = MO.getReg(); 280 // This takes advantage of the 2 operand-ness of ldm/stm and that we've 281 // already got the operands in registers that are operands to the 282 // inline asm statement. 283 O << "{"; 284 if (ARM::GPRPairRegClass.contains(RegBegin)) { 285 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 286 unsigned Reg0 = TRI->getSubReg(RegBegin, ARM::gsub_0); 287 O << ARMInstPrinter::getRegisterName(Reg0) << ", "; 288 RegBegin = TRI->getSubReg(RegBegin, ARM::gsub_1); 289 } 290 O << ARMInstPrinter::getRegisterName(RegBegin); 291 292 // FIXME: The register allocator not only may not have given us the 293 // registers in sequence, but may not be in ascending registers. This 294 // will require changes in the register allocator that'll need to be 295 // propagated down here if the operands change. 296 unsigned RegOps = OpNum + 1; 297 while (MI->getOperand(RegOps).isReg()) { 298 O << ", " 299 << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg()); 300 RegOps++; 301 } 302 303 O << "}"; 304 305 return false; 306 } 307 case 'R': // The most significant register of a pair. 308 case 'Q': { // The least significant register of a pair. 309 if (OpNum == 0) 310 return true; 311 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 312 if (!FlagsOP.isImm()) 313 return true; 314 unsigned Flags = FlagsOP.getImm(); 315 316 // This operand may not be the one that actually provides the register. If 317 // it's tied to a previous one then we should refer instead to that one 318 // for registers and their classes. 319 unsigned TiedIdx; 320 if (InlineAsm::isUseOperandTiedToDef(Flags, TiedIdx)) { 321 for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) { 322 unsigned OpFlags = MI->getOperand(OpNum).getImm(); 323 OpNum += InlineAsm::getNumOperandRegisters(OpFlags) + 1; 324 } 325 Flags = MI->getOperand(OpNum).getImm(); 326 327 // Later code expects OpNum to be pointing at the register rather than 328 // the flags. 329 OpNum += 1; 330 } 331 332 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 333 unsigned RC; 334 InlineAsm::hasRegClassConstraint(Flags, RC); 335 if (RC == ARM::GPRPairRegClassID) { 336 if (NumVals != 1) 337 return true; 338 const MachineOperand &MO = MI->getOperand(OpNum); 339 if (!MO.isReg()) 340 return true; 341 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 342 unsigned Reg = TRI->getSubReg(MO.getReg(), ExtraCode[0] == 'Q' ? 343 ARM::gsub_0 : ARM::gsub_1); 344 O << ARMInstPrinter::getRegisterName(Reg); 345 return false; 346 } 347 if (NumVals != 2) 348 return true; 349 unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1; 350 if (RegOp >= MI->getNumOperands()) 351 return true; 352 const MachineOperand &MO = MI->getOperand(RegOp); 353 if (!MO.isReg()) 354 return true; 355 unsigned Reg = MO.getReg(); 356 O << ARMInstPrinter::getRegisterName(Reg); 357 return false; 358 } 359 360 case 'e': // The low doubleword register of a NEON quad register. 361 case 'f': { // The high doubleword register of a NEON quad register. 362 if (!MI->getOperand(OpNum).isReg()) 363 return true; 364 unsigned Reg = MI->getOperand(OpNum).getReg(); 365 if (!ARM::QPRRegClass.contains(Reg)) 366 return true; 367 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 368 unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ? 369 ARM::dsub_0 : ARM::dsub_1); 370 O << ARMInstPrinter::getRegisterName(SubReg); 371 return false; 372 } 373 374 // This modifier is not yet supported. 375 case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1. 376 return true; 377 case 'H': { // The highest-numbered register of a pair. 378 const MachineOperand &MO = MI->getOperand(OpNum); 379 if (!MO.isReg()) 380 return true; 381 const MachineFunction &MF = *MI->getParent()->getParent(); 382 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 383 unsigned Reg = MO.getReg(); 384 if(!ARM::GPRPairRegClass.contains(Reg)) 385 return false; 386 Reg = TRI->getSubReg(Reg, ARM::gsub_1); 387 O << ARMInstPrinter::getRegisterName(Reg); 388 return false; 389 } 390 } 391 } 392 393 printOperand(MI, OpNum, O); 394 return false; 395} 396 397bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 398 unsigned OpNum, unsigned AsmVariant, 399 const char *ExtraCode, 400 raw_ostream &O) { 401 // Does this asm operand have a single letter operand modifier? 402 if (ExtraCode && ExtraCode[0]) { 403 if (ExtraCode[1] != 0) return true; // Unknown modifier. 404 405 switch (ExtraCode[0]) { 406 case 'A': // A memory operand for a VLD1/VST1 instruction. 407 default: return true; // Unknown modifier. 408 case 'm': // The base register of a memory operand. 409 if (!MI->getOperand(OpNum).isReg()) 410 return true; 411 O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()); 412 return false; 413 } 414 } 415 416 const MachineOperand &MO = MI->getOperand(OpNum); 417 assert(MO.isReg() && "unexpected inline asm memory operand"); 418 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 419 return false; 420} 421 422static bool isThumb(const MCSubtargetInfo& STI) { 423 return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 424} 425 426void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 427 const MCSubtargetInfo *EndInfo) const { 428 // If either end mode is unknown (EndInfo == NULL) or different than 429 // the start mode, then restore the start mode. 430 const bool WasThumb = isThumb(StartInfo); 431 if (!EndInfo || WasThumb != isThumb(*EndInfo)) { 432 OutStreamer.EmitAssemblerFlag(WasThumb ? MCAF_Code16 : MCAF_Code32); 433 } 434} 435 436void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 437 Triple TT(TM.getTargetTriple()); 438 // Use unified assembler syntax. 439 OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 440 441 // Emit ARM Build Attributes 442 if (TT.isOSBinFormatELF()) 443 emitAttributes(); 444 445 // Use the triple's architecture and subarchitecture to determine 446 // if we're thumb for the purposes of the top level code16 assembler 447 // flag. 448 bool isThumb = TT.getArch() == Triple::thumb || 449 TT.getArch() == Triple::thumbeb || 450 TT.getSubArch() == Triple::ARMSubArch_v7m || 451 TT.getSubArch() == Triple::ARMSubArch_v6m; 452 if (!M.getModuleInlineAsm().empty() && isThumb) 453 OutStreamer.EmitAssemblerFlag(MCAF_Code16); 454} 455 456static void 457emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, 458 MachineModuleInfoImpl::StubValueTy &MCSym) { 459 // L_foo$stub: 460 OutStreamer.EmitLabel(StubLabel); 461 // .indirect_symbol _foo 462 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 463 464 if (MCSym.getInt()) 465 // External to current translation unit. 466 OutStreamer.EmitIntValue(0, 4/*size*/); 467 else 468 // Internal to current translation unit. 469 // 470 // When we place the LSDA into the TEXT section, the type info 471 // pointers need to be indirect and pc-rel. We accomplish this by 472 // using NLPs; however, sometimes the types are local to the file. 473 // We need to fill in the value for the NLP in those cases. 474 OutStreamer.EmitValue( 475 MCSymbolRefExpr::Create(MCSym.getPointer(), OutStreamer.getContext()), 476 4 /*size*/); 477} 478 479 480void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 481 Triple TT(TM.getTargetTriple()); 482 if (TT.isOSBinFormatMachO()) { 483 // All darwin targets use mach-o. 484 const TargetLoweringObjectFileMachO &TLOFMacho = 485 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 486 MachineModuleInfoMachO &MMIMacho = 487 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 488 489 // Output non-lazy-pointers for external and common global variables. 490 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 491 492 if (!Stubs.empty()) { 493 // Switch with ".non_lazy_symbol_pointer" directive. 494 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 495 EmitAlignment(2); 496 497 for (auto &Stub : Stubs) 498 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); 499 500 Stubs.clear(); 501 OutStreamer.AddBlankLine(); 502 } 503 504 Stubs = MMIMacho.GetHiddenGVStubList(); 505 if (!Stubs.empty()) { 506 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 507 EmitAlignment(2); 508 509 for (auto &Stub : Stubs) 510 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); 511 512 Stubs.clear(); 513 OutStreamer.AddBlankLine(); 514 } 515 516 // Funny Darwin hack: This flag tells the linker that no global symbols 517 // contain code that falls through to other global symbols (e.g. the obvious 518 // implementation of multiple entry points). If this doesn't occur, the 519 // linker can safely perform dead code stripping. Since LLVM never 520 // generates code that does this, it is always safe to set. 521 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 522 } 523} 524 525//===----------------------------------------------------------------------===// 526// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 527// FIXME: 528// The following seem like one-off assembler flags, but they actually need 529// to appear in the .ARM.attributes section in ELF. 530// Instead of subclassing the MCELFStreamer, we do the work here. 531 532static ARMBuildAttrs::CPUArch getArchForCPU(StringRef CPU, 533 const ARMSubtarget *Subtarget) { 534 if (CPU == "xscale") 535 return ARMBuildAttrs::v5TEJ; 536 537 if (Subtarget->hasV8Ops()) 538 return ARMBuildAttrs::v8; 539 else if (Subtarget->hasV7Ops()) { 540 if (Subtarget->isMClass() && Subtarget->hasThumb2DSP()) 541 return ARMBuildAttrs::v7E_M; 542 return ARMBuildAttrs::v7; 543 } else if (Subtarget->hasV6T2Ops()) 544 return ARMBuildAttrs::v6T2; 545 else if (Subtarget->hasV6MOps()) 546 return ARMBuildAttrs::v6S_M; 547 else if (Subtarget->hasV6Ops()) 548 return ARMBuildAttrs::v6; 549 else if (Subtarget->hasV5TEOps()) 550 return ARMBuildAttrs::v5TE; 551 else if (Subtarget->hasV5TOps()) 552 return ARMBuildAttrs::v5T; 553 else if (Subtarget->hasV4TOps()) 554 return ARMBuildAttrs::v4T; 555 else 556 return ARMBuildAttrs::v4; 557} 558 559void ARMAsmPrinter::emitAttributes() { 560 MCTargetStreamer &TS = *OutStreamer.getTargetStreamer(); 561 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 562 563 ATS.emitTextAttribute(ARMBuildAttrs::conformance, "2.09"); 564 565 ATS.switchVendor("aeabi"); 566 567 // Compute ARM ELF Attributes based on the default subtarget that 568 // we'd have constructed. The existing ARM behavior isn't LTO clean 569 // anyhow. 570 // FIXME: For ifunc related functions we could iterate over and look 571 // for a feature string that doesn't match the default one. 572 StringRef TT = TM.getTargetTriple(); 573 StringRef CPU = TM.getTargetCPU(); 574 StringRef FS = TM.getTargetFeatureString(); 575 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); 576 if (!FS.empty()) { 577 if (!ArchFS.empty()) 578 ArchFS = (Twine(ArchFS) + "," + FS).str(); 579 else 580 ArchFS = FS; 581 } 582 const ARMBaseTargetMachine &ATM = 583 static_cast<const ARMBaseTargetMachine &>(TM); 584 const ARMSubtarget STI(TT, CPU, ArchFS, ATM, ATM.isLittleEndian()); 585 586 std::string CPUString = STI.getCPUString(); 587 588 if (CPUString.find("generic") != 0) { //CPUString doesn't start with "generic" 589 // FIXME: remove krait check when GNU tools support krait cpu 590 if (STI.isKrait()) { 591 ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a9"); 592 // We consider krait as a "cortex-a9" + hwdiv CPU 593 // Enable hwdiv through ".arch_extension idiv" 594 if (STI.hasDivide() || STI.hasDivideInARMMode()) 595 ATS.emitArchExtension(ARM::HWDIV); 596 } else 597 ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString); 598 } 599 600 ATS.emitAttribute(ARMBuildAttrs::CPU_arch, getArchForCPU(CPUString, &STI)); 601 602 // Tag_CPU_arch_profile must have the default value of 0 when "Architecture 603 // profile is not applicable (e.g. pre v7, or cross-profile code)". 604 if (STI.hasV7Ops()) { 605 if (STI.isAClass()) { 606 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile, 607 ARMBuildAttrs::ApplicationProfile); 608 } else if (STI.isRClass()) { 609 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile, 610 ARMBuildAttrs::RealTimeProfile); 611 } else if (STI.isMClass()) { 612 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile, 613 ARMBuildAttrs::MicroControllerProfile); 614 } 615 } 616 617 ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use, 618 STI.hasARMOps() ? ARMBuildAttrs::Allowed 619 : ARMBuildAttrs::Not_Allowed); 620 if (STI.isThumb1Only()) { 621 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use, ARMBuildAttrs::Allowed); 622 } else if (STI.hasThumb2()) { 623 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use, 624 ARMBuildAttrs::AllowThumb32); 625 } 626 627 if (STI.hasNEON()) { 628 /* NEON is not exactly a VFP architecture, but GAS emit one of 629 * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */ 630 if (STI.hasFPARMv8()) { 631 if (STI.hasCrypto()) 632 ATS.emitFPU(ARM::CRYPTO_NEON_FP_ARMV8); 633 else 634 ATS.emitFPU(ARM::NEON_FP_ARMV8); 635 } else if (STI.hasVFP4()) 636 ATS.emitFPU(ARM::NEON_VFPV4); 637 else 638 ATS.emitFPU(ARM::NEON); 639 // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture 640 if (STI.hasV8Ops()) 641 ATS.emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 642 STI.hasV8_1aOps() ? ARMBuildAttrs::AllowNeonARMv8_1a: 643 ARMBuildAttrs::AllowNeonARMv8); 644 } else { 645 if (STI.hasFPARMv8()) 646 // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one 647 // FPU, but there are two different names for it depending on the CPU. 648 ATS.emitFPU(STI.hasD16() ? ARM::FPV5_D16 : ARM::FP_ARMV8); 649 else if (STI.hasVFP4()) 650 ATS.emitFPU(STI.hasD16() ? ARM::VFPV4_D16 : ARM::VFPV4); 651 else if (STI.hasVFP3()) 652 ATS.emitFPU(STI.hasD16() ? ARM::VFPV3_D16 : ARM::VFPV3); 653 else if (STI.hasVFP2()) 654 ATS.emitFPU(ARM::VFPV2); 655 } 656 657 if (TM.getRelocationModel() == Reloc::PIC_) { 658 // PIC specific attributes. 659 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RW_data, 660 ARMBuildAttrs::AddressRWPCRel); 661 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RO_data, 662 ARMBuildAttrs::AddressROPCRel); 663 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use, 664 ARMBuildAttrs::AddressGOT); 665 } else { 666 // Allow direct addressing of imported data for all other relocation models. 667 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use, 668 ARMBuildAttrs::AddressDirect); 669 } 670 671 // Signal various FP modes. 672 if (!TM.Options.UnsafeFPMath) { 673 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, 674 ARMBuildAttrs::IEEEDenormals); 675 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, ARMBuildAttrs::Allowed); 676 677 // If the user has permitted this code to choose the IEEE 754 678 // rounding at run-time, emit the rounding attribute. 679 if (TM.Options.HonorSignDependentRoundingFPMathOption) 680 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_rounding, ARMBuildAttrs::Allowed); 681 } else { 682 if (!STI.hasVFP2()) { 683 // When the target doesn't have an FPU (by design or 684 // intention), the assumptions made on the software support 685 // mirror that of the equivalent hardware support *if it 686 // existed*. For v7 and better we indicate that denormals are 687 // flushed preserving sign, and for V6 we indicate that 688 // denormals are flushed to positive zero. 689 if (STI.hasV7Ops()) 690 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, 691 ARMBuildAttrs::PreserveFPSign); 692 } else if (STI.hasVFP3()) { 693 // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is, 694 // the sign bit of the zero matches the sign bit of the input or 695 // result that is being flushed to zero. 696 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, 697 ARMBuildAttrs::PreserveFPSign); 698 } 699 // For VFPv2 implementations it is implementation defined as 700 // to whether denormals are flushed to positive zero or to 701 // whatever the sign of zero is (ARM v7AR ARM 2.7.5). Historically 702 // LLVM has chosen to flush this to positive zero (most likely for 703 // GCC compatibility), so that's the chosen value here (the 704 // absence of its emission implies zero). 705 } 706 707 // TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath is the 708 // equivalent of GCC's -ffinite-math-only flag. 709 if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath) 710 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 711 ARMBuildAttrs::Allowed); 712 else 713 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 714 ARMBuildAttrs::AllowIEE754); 715 716 if (STI.allowsUnalignedMem()) 717 ATS.emitAttribute(ARMBuildAttrs::CPU_unaligned_access, 718 ARMBuildAttrs::Allowed); 719 else 720 ATS.emitAttribute(ARMBuildAttrs::CPU_unaligned_access, 721 ARMBuildAttrs::Not_Allowed); 722 723 // FIXME: add more flags to ARMBuildAttributes.h 724 // 8-bytes alignment stuff. 725 ATS.emitAttribute(ARMBuildAttrs::ABI_align_needed, 1); 726 ATS.emitAttribute(ARMBuildAttrs::ABI_align_preserved, 1); 727 728 // ABI_HardFP_use attribute to indicate single precision FP. 729 if (STI.isFPOnlySP()) 730 ATS.emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 731 ARMBuildAttrs::HardFPSinglePrecision); 732 733 // Hard float. Use both S and D registers and conform to AAPCS-VFP. 734 if (STI.isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard) 735 ATS.emitAttribute(ARMBuildAttrs::ABI_VFP_args, ARMBuildAttrs::HardFPAAPCS); 736 737 // FIXME: Should we signal R9 usage? 738 739 if (STI.hasFP16()) 740 ATS.emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP); 741 742 // FIXME: To support emitting this build attribute as GCC does, the 743 // -mfp16-format option and associated plumbing must be 744 // supported. For now the __fp16 type is exposed by default, so this 745 // attribute should be emitted with value 1. 746 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_16bit_format, 747 ARMBuildAttrs::FP16FormatIEEE); 748 749 if (STI.hasMPExtension()) 750 ATS.emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP); 751 752 // Hardware divide in ARM mode is part of base arch, starting from ARMv8. 753 // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M). 754 // It is not possible to produce DisallowDIV: if hwdiv is present in the base 755 // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits. 756 // AllowDIVExt is only emitted if hwdiv isn't available in the base arch; 757 // otherwise, the default value (AllowDIVIfExists) applies. 758 if (STI.hasDivideInARMMode() && !STI.hasV8Ops()) 759 ATS.emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt); 760 761 if (MMI) { 762 if (const Module *SourceModule = MMI->getModule()) { 763 // ABI_PCS_wchar_t to indicate wchar_t width 764 // FIXME: There is no way to emit value 0 (wchar_t prohibited). 765 if (auto WCharWidthValue = mdconst::extract_or_null<ConstantInt>( 766 SourceModule->getModuleFlag("wchar_size"))) { 767 int WCharWidth = WCharWidthValue->getZExtValue(); 768 assert((WCharWidth == 2 || WCharWidth == 4) && 769 "wchar_t width must be 2 or 4 bytes"); 770 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_wchar_t, WCharWidth); 771 } 772 773 // ABI_enum_size to indicate enum width 774 // FIXME: There is no way to emit value 0 (enums prohibited) or value 3 775 // (all enums contain a value needing 32 bits to encode). 776 if (auto EnumWidthValue = mdconst::extract_or_null<ConstantInt>( 777 SourceModule->getModuleFlag("min_enum_size"))) { 778 int EnumWidth = EnumWidthValue->getZExtValue(); 779 assert((EnumWidth == 1 || EnumWidth == 4) && 780 "Minimum enum width must be 1 or 4 bytes"); 781 int EnumBuildAttr = EnumWidth == 1 ? 1 : 2; 782 ATS.emitAttribute(ARMBuildAttrs::ABI_enum_size, EnumBuildAttr); 783 } 784 } 785 } 786 787 // TODO: We currently only support either reserving the register, or treating 788 // it as another callee-saved register, but not as SB or a TLS pointer; It 789 // would instead be nicer to push this from the frontend as metadata, as we do 790 // for the wchar and enum size tags 791 if (STI.isR9Reserved()) 792 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, ARMBuildAttrs::R9Reserved); 793 else 794 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, ARMBuildAttrs::R9IsGPR); 795 796 if (STI.hasTrustZone() && STI.hasVirtualization()) 797 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, 798 ARMBuildAttrs::AllowTZVirtualization); 799 else if (STI.hasTrustZone()) 800 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, 801 ARMBuildAttrs::AllowTZ); 802 else if (STI.hasVirtualization()) 803 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, 804 ARMBuildAttrs::AllowVirtualization); 805 806 ATS.finishAttributeSection(); 807} 808 809//===----------------------------------------------------------------------===// 810 811static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 812 unsigned LabelId, MCContext &Ctx) { 813 814 MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 815 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 816 return Label; 817} 818 819static MCSymbolRefExpr::VariantKind 820getModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 821 switch (Modifier) { 822 case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 823 case ARMCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; 824 case ARMCP::TPOFF: return MCSymbolRefExpr::VK_TPOFF; 825 case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_GOTTPOFF; 826 case ARMCP::GOT: return MCSymbolRefExpr::VK_GOT; 827 case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_GOTOFF; 828 } 829 llvm_unreachable("Invalid ARMCPModifier!"); 830} 831 832MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV, 833 unsigned char TargetFlags) { 834 if (Subtarget->isTargetMachO()) { 835 bool IsIndirect = (TargetFlags & ARMII::MO_NONLAZY) && 836 Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 837 838 if (!IsIndirect) 839 return getSymbol(GV); 840 841 // FIXME: Remove this when Darwin transition to @GOT like syntax. 842 MCSymbol *MCSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 843 MachineModuleInfoMachO &MMIMachO = 844 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 845 MachineModuleInfoImpl::StubValueTy &StubSym = 846 GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) 847 : MMIMachO.getGVStubEntry(MCSym); 848 if (!StubSym.getPointer()) 849 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV), 850 !GV->hasInternalLinkage()); 851 return MCSym; 852 } else if (Subtarget->isTargetCOFF()) { 853 assert(Subtarget->isTargetWindows() && 854 "Windows is the only supported COFF target"); 855 856 bool IsIndirect = (TargetFlags & ARMII::MO_DLLIMPORT); 857 if (!IsIndirect) 858 return getSymbol(GV); 859 860 SmallString<128> Name; 861 Name = "__imp_"; 862 getNameWithPrefix(Name, GV); 863 864 return OutContext.GetOrCreateSymbol(Name); 865 } else if (Subtarget->isTargetELF()) { 866 return getSymbol(GV); 867 } 868 llvm_unreachable("unexpected target"); 869} 870 871void ARMAsmPrinter:: 872EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 873 const DataLayout *DL = TM.getDataLayout(); 874 int Size = TM.getDataLayout()->getTypeAllocSize(MCPV->getType()); 875 876 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 877 878 MCSymbol *MCSym; 879 if (ACPV->isLSDA()) { 880 MCSym = getCurExceptionSym(); 881 } else if (ACPV->isBlockAddress()) { 882 const BlockAddress *BA = 883 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(); 884 MCSym = GetBlockAddressSymbol(BA); 885 } else if (ACPV->isGlobalValue()) { 886 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV(); 887 888 // On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so 889 // flag the global as MO_NONLAZY. 890 unsigned char TF = Subtarget->isTargetMachO() ? ARMII::MO_NONLAZY : 0; 891 MCSym = GetARMGVSymbol(GV, TF); 892 } else if (ACPV->isMachineBasicBlock()) { 893 const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB(); 894 MCSym = MBB->getSymbol(); 895 } else { 896 assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 897 const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(); 898 MCSym = GetExternalSymbolSymbol(Sym); 899 } 900 901 // Create an MCSymbol for the reference. 902 const MCExpr *Expr = 903 MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 904 OutContext); 905 906 if (ACPV->getPCAdjustment()) { 907 MCSymbol *PCLabel = getPICLabel(DL->getPrivateGlobalPrefix(), 908 getFunctionNumber(), 909 ACPV->getLabelId(), 910 OutContext); 911 const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 912 PCRelExpr = 913 MCBinaryExpr::CreateAdd(PCRelExpr, 914 MCConstantExpr::Create(ACPV->getPCAdjustment(), 915 OutContext), 916 OutContext); 917 if (ACPV->mustAddCurrentAddress()) { 918 // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 919 // label, so just emit a local label end reference that instead. 920 MCSymbol *DotSym = OutContext.CreateTempSymbol(); 921 OutStreamer.EmitLabel(DotSym); 922 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 923 PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 924 } 925 Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 926 } 927 OutStreamer.EmitValue(Expr, Size); 928} 929 930void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 931 unsigned Opcode = MI->getOpcode(); 932 int OpNum = 1; 933 if (Opcode == ARM::BR_JTadd) 934 OpNum = 2; 935 else if (Opcode == ARM::BR_JTm) 936 OpNum = 3; 937 938 const MachineOperand &MO1 = MI->getOperand(OpNum); 939 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 940 unsigned JTI = MO1.getIndex(); 941 942 // Emit a label for the jump table. 943 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 944 OutStreamer.EmitLabel(JTISymbol); 945 946 // Mark the jump table as data-in-code. 947 OutStreamer.EmitDataRegion(MCDR_DataRegionJT32); 948 949 // Emit each entry of the table. 950 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 951 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 952 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 953 954 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 955 MachineBasicBlock *MBB = JTBBs[i]; 956 // Construct an MCExpr for the entry. We want a value of the form: 957 // (BasicBlockAddr - TableBeginAddr) 958 // 959 // For example, a table with entries jumping to basic blocks BB0 and BB1 960 // would look like: 961 // LJTI_0_0: 962 // .word (LBB0 - LJTI_0_0) 963 // .word (LBB1 - LJTI_0_0) 964 const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 965 966 if (TM.getRelocationModel() == Reloc::PIC_) 967 Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 968 OutContext), 969 OutContext); 970 // If we're generating a table of Thumb addresses in static relocation 971 // model, we need to add one to keep interworking correctly. 972 else if (AFI->isThumbFunction()) 973 Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext), 974 OutContext); 975 OutStreamer.EmitValue(Expr, 4); 976 } 977 // Mark the end of jump table data-in-code region. 978 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 979} 980 981void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 982 unsigned Opcode = MI->getOpcode(); 983 int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 984 const MachineOperand &MO1 = MI->getOperand(OpNum); 985 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 986 unsigned JTI = MO1.getIndex(); 987 988 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 989 OutStreamer.EmitLabel(JTISymbol); 990 991 // Emit each entry of the table. 992 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 993 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 994 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 995 unsigned OffsetWidth = 4; 996 if (MI->getOpcode() == ARM::t2TBB_JT) { 997 OffsetWidth = 1; 998 // Mark the jump table as data-in-code. 999 OutStreamer.EmitDataRegion(MCDR_DataRegionJT8); 1000 } else if (MI->getOpcode() == ARM::t2TBH_JT) { 1001 OffsetWidth = 2; 1002 // Mark the jump table as data-in-code. 1003 OutStreamer.EmitDataRegion(MCDR_DataRegionJT16); 1004 } 1005 1006 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 1007 MachineBasicBlock *MBB = JTBBs[i]; 1008 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 1009 OutContext); 1010 // If this isn't a TBB or TBH, the entries are direct branch instructions. 1011 if (OffsetWidth == 4) { 1012 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2B) 1013 .addExpr(MBBSymbolExpr) 1014 .addImm(ARMCC::AL) 1015 .addReg(0)); 1016 continue; 1017 } 1018 // Otherwise it's an offset from the dispatch instruction. Construct an 1019 // MCExpr for the entry. We want a value of the form: 1020 // (BasicBlockAddr - TableBeginAddr) / 2 1021 // 1022 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 1023 // would look like: 1024 // LJTI_0_0: 1025 // .byte (LBB0 - LJTI_0_0) / 2 1026 // .byte (LBB1 - LJTI_0_0) / 2 1027 const MCExpr *Expr = 1028 MCBinaryExpr::CreateSub(MBBSymbolExpr, 1029 MCSymbolRefExpr::Create(JTISymbol, OutContext), 1030 OutContext); 1031 Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 1032 OutContext); 1033 OutStreamer.EmitValue(Expr, OffsetWidth); 1034 } 1035 // Mark the end of jump table data-in-code region. 32-bit offsets use 1036 // actual branch instructions here, so we don't mark those as a data-region 1037 // at all. 1038 if (OffsetWidth != 4) 1039 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 1040} 1041 1042void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { 1043 assert(MI->getFlag(MachineInstr::FrameSetup) && 1044 "Only instruction which are involved into frame setup code are allowed"); 1045 1046 MCTargetStreamer &TS = *OutStreamer.getTargetStreamer(); 1047 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 1048 const MachineFunction &MF = *MI->getParent()->getParent(); 1049 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 1050 const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); 1051 1052 unsigned FramePtr = RegInfo->getFrameRegister(MF); 1053 unsigned Opc = MI->getOpcode(); 1054 unsigned SrcReg, DstReg; 1055 1056 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { 1057 // Two special cases: 1058 // 1) tPUSH does not have src/dst regs. 1059 // 2) for Thumb1 code we sometimes materialize the constant via constpool 1060 // load. Yes, this is pretty fragile, but for now I don't see better 1061 // way... :( 1062 SrcReg = DstReg = ARM::SP; 1063 } else { 1064 SrcReg = MI->getOperand(1).getReg(); 1065 DstReg = MI->getOperand(0).getReg(); 1066 } 1067 1068 // Try to figure out the unwinding opcode out of src / dst regs. 1069 if (MI->mayStore()) { 1070 // Register saves. 1071 assert(DstReg == ARM::SP && 1072 "Only stack pointer as a destination reg is supported"); 1073 1074 SmallVector<unsigned, 4> RegList; 1075 // Skip src & dst reg, and pred ops. 1076 unsigned StartOp = 2 + 2; 1077 // Use all the operands. 1078 unsigned NumOffset = 0; 1079 1080 switch (Opc) { 1081 default: 1082 MI->dump(); 1083 llvm_unreachable("Unsupported opcode for unwinding information"); 1084 case ARM::tPUSH: 1085 // Special case here: no src & dst reg, but two extra imp ops. 1086 StartOp = 2; NumOffset = 2; 1087 case ARM::STMDB_UPD: 1088 case ARM::t2STMDB_UPD: 1089 case ARM::VSTMDDB_UPD: 1090 assert(SrcReg == ARM::SP && 1091 "Only stack pointer as a source reg is supported"); 1092 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset; 1093 i != NumOps; ++i) { 1094 const MachineOperand &MO = MI->getOperand(i); 1095 // Actually, there should never be any impdef stuff here. Skip it 1096 // temporary to workaround PR11902. 1097 if (MO.isImplicit()) 1098 continue; 1099 RegList.push_back(MO.getReg()); 1100 } 1101 break; 1102 case ARM::STR_PRE_IMM: 1103 case ARM::STR_PRE_REG: 1104 case ARM::t2STR_PRE: 1105 assert(MI->getOperand(2).getReg() == ARM::SP && 1106 "Only stack pointer as a source reg is supported"); 1107 RegList.push_back(SrcReg); 1108 break; 1109 } 1110 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) 1111 ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); 1112 } else { 1113 // Changes of stack / frame pointer. 1114 if (SrcReg == ARM::SP) { 1115 int64_t Offset = 0; 1116 switch (Opc) { 1117 default: 1118 MI->dump(); 1119 llvm_unreachable("Unsupported opcode for unwinding information"); 1120 case ARM::MOVr: 1121 case ARM::tMOVr: 1122 Offset = 0; 1123 break; 1124 case ARM::ADDri: 1125 Offset = -MI->getOperand(2).getImm(); 1126 break; 1127 case ARM::SUBri: 1128 case ARM::t2SUBri: 1129 Offset = MI->getOperand(2).getImm(); 1130 break; 1131 case ARM::tSUBspi: 1132 Offset = MI->getOperand(2).getImm()*4; 1133 break; 1134 case ARM::tADDspi: 1135 case ARM::tADDrSPi: 1136 Offset = -MI->getOperand(2).getImm()*4; 1137 break; 1138 case ARM::tLDRpci: { 1139 // Grab the constpool index and check, whether it corresponds to 1140 // original or cloned constpool entry. 1141 unsigned CPI = MI->getOperand(1).getIndex(); 1142 const MachineConstantPool *MCP = MF.getConstantPool(); 1143 if (CPI >= MCP->getConstants().size()) 1144 CPI = AFI.getOriginalCPIdx(CPI); 1145 assert(CPI != -1U && "Invalid constpool index"); 1146 1147 // Derive the actual offset. 1148 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; 1149 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); 1150 // FIXME: Check for user, it should be "add" instruction! 1151 Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue(); 1152 break; 1153 } 1154 } 1155 1156 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) { 1157 if (DstReg == FramePtr && FramePtr != ARM::SP) 1158 // Set-up of the frame pointer. Positive values correspond to "add" 1159 // instruction. 1160 ATS.emitSetFP(FramePtr, ARM::SP, -Offset); 1161 else if (DstReg == ARM::SP) { 1162 // Change of SP by an offset. Positive values correspond to "sub" 1163 // instruction. 1164 ATS.emitPad(Offset); 1165 } else { 1166 // Move of SP to a register. Positive values correspond to an "add" 1167 // instruction. 1168 ATS.emitMovSP(DstReg, -Offset); 1169 } 1170 } 1171 } else if (DstReg == ARM::SP) { 1172 MI->dump(); 1173 llvm_unreachable("Unsupported opcode for unwinding information"); 1174 } 1175 else { 1176 MI->dump(); 1177 llvm_unreachable("Unsupported opcode for unwinding information"); 1178 } 1179 } 1180} 1181 1182// Simple pseudo-instructions have their lowering (with expansion to real 1183// instructions) auto-generated. 1184#include "ARMGenMCPseudoLowering.inc" 1185 1186void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 1187 const DataLayout *DL = TM.getDataLayout(); 1188 1189 // If we just ended a constant pool, mark it as such. 1190 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) { 1191 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 1192 InConstantPool = false; 1193 } 1194 1195 // Emit unwinding stuff for frame-related instructions 1196 if (Subtarget->isTargetEHABICompatible() && 1197 MI->getFlag(MachineInstr::FrameSetup)) 1198 EmitUnwindingInstruction(MI); 1199 1200 // Do any auto-generated pseudo lowerings. 1201 if (emitPseudoExpansionLowering(OutStreamer, MI)) 1202 return; 1203 1204 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) && 1205 "Pseudo flag setting opcode should be expanded early"); 1206 1207 // Check for manual lowerings. 1208 unsigned Opc = MI->getOpcode(); 1209 switch (Opc) { 1210 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass"); 1211 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing"); 1212 case ARM::LEApcrel: 1213 case ARM::tLEApcrel: 1214 case ARM::t2LEApcrel: { 1215 // FIXME: Need to also handle globals and externals 1216 MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex()); 1217 EmitToStreamer(OutStreamer, MCInstBuilder(MI->getOpcode() == 1218 ARM::t2LEApcrel ? ARM::t2ADR 1219 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 1220 : ARM::ADR)) 1221 .addReg(MI->getOperand(0).getReg()) 1222 .addExpr(MCSymbolRefExpr::Create(CPISymbol, OutContext)) 1223 // Add predicate operands. 1224 .addImm(MI->getOperand(2).getImm()) 1225 .addReg(MI->getOperand(3).getReg())); 1226 return; 1227 } 1228 case ARM::LEApcrelJT: 1229 case ARM::tLEApcrelJT: 1230 case ARM::t2LEApcrelJT: { 1231 MCSymbol *JTIPICSymbol = 1232 GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 1233 MI->getOperand(2).getImm()); 1234 EmitToStreamer(OutStreamer, MCInstBuilder(MI->getOpcode() == 1235 ARM::t2LEApcrelJT ? ARM::t2ADR 1236 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 1237 : ARM::ADR)) 1238 .addReg(MI->getOperand(0).getReg()) 1239 .addExpr(MCSymbolRefExpr::Create(JTIPICSymbol, OutContext)) 1240 // Add predicate operands. 1241 .addImm(MI->getOperand(3).getImm()) 1242 .addReg(MI->getOperand(4).getReg())); 1243 return; 1244 } 1245 // Darwin call instructions are just normal call instructions with different 1246 // clobber semantics (they clobber R9). 1247 case ARM::BX_CALL: { 1248 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 1249 .addReg(ARM::LR) 1250 .addReg(ARM::PC) 1251 // Add predicate operands. 1252 .addImm(ARMCC::AL) 1253 .addReg(0) 1254 // Add 's' bit operand (always reg0 for this) 1255 .addReg(0)); 1256 1257 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::BX) 1258 .addReg(MI->getOperand(0).getReg())); 1259 return; 1260 } 1261 case ARM::tBX_CALL: { 1262 if (Subtarget->hasV5TOps()) 1263 llvm_unreachable("Expected BLX to be selected for v5t+"); 1264 1265 // On ARM v4t, when doing a call from thumb mode, we need to ensure 1266 // that the saved lr has its LSB set correctly (the arch doesn't 1267 // have blx). 1268 // So here we generate a bl to a small jump pad that does bx rN. 1269 // The jump pads are emitted after the function body. 1270 1271 unsigned TReg = MI->getOperand(0).getReg(); 1272 MCSymbol *TRegSym = nullptr; 1273 for (unsigned i = 0, e = ThumbIndirectPads.size(); i < e; i++) { 1274 if (ThumbIndirectPads[i].first == TReg) { 1275 TRegSym = ThumbIndirectPads[i].second; 1276 break; 1277 } 1278 } 1279 1280 if (!TRegSym) { 1281 TRegSym = OutContext.CreateTempSymbol(); 1282 ThumbIndirectPads.push_back(std::make_pair(TReg, TRegSym)); 1283 } 1284 1285 // Create a link-saving branch to the Reg Indirect Jump Pad. 1286 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBL) 1287 // Predicate comes first here. 1288 .addImm(ARMCC::AL).addReg(0) 1289 .addExpr(MCSymbolRefExpr::Create(TRegSym, OutContext))); 1290 return; 1291 } 1292 case ARM::BMOVPCRX_CALL: { 1293 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 1294 .addReg(ARM::LR) 1295 .addReg(ARM::PC) 1296 // Add predicate operands. 1297 .addImm(ARMCC::AL) 1298 .addReg(0) 1299 // Add 's' bit operand (always reg0 for this) 1300 .addReg(0)); 1301 1302 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 1303 .addReg(ARM::PC) 1304 .addReg(MI->getOperand(0).getReg()) 1305 // Add predicate operands. 1306 .addImm(ARMCC::AL) 1307 .addReg(0) 1308 // Add 's' bit operand (always reg0 for this) 1309 .addReg(0)); 1310 return; 1311 } 1312 case ARM::BMOVPCB_CALL: { 1313 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 1314 .addReg(ARM::LR) 1315 .addReg(ARM::PC) 1316 // Add predicate operands. 1317 .addImm(ARMCC::AL) 1318 .addReg(0) 1319 // Add 's' bit operand (always reg0 for this) 1320 .addReg(0)); 1321 1322 const MachineOperand &Op = MI->getOperand(0); 1323 const GlobalValue *GV = Op.getGlobal(); 1324 const unsigned TF = Op.getTargetFlags(); 1325 MCSymbol *GVSym = GetARMGVSymbol(GV, TF); 1326 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 1327 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::Bcc) 1328 .addExpr(GVSymExpr) 1329 // Add predicate operands. 1330 .addImm(ARMCC::AL) 1331 .addReg(0)); 1332 return; 1333 } 1334 case ARM::MOVi16_ga_pcrel: 1335 case ARM::t2MOVi16_ga_pcrel: { 1336 MCInst TmpInst; 1337 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 1338 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1339 1340 unsigned TF = MI->getOperand(1).getTargetFlags(); 1341 const GlobalValue *GV = MI->getOperand(1).getGlobal(); 1342 MCSymbol *GVSym = GetARMGVSymbol(GV, TF); 1343 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 1344 1345 MCSymbol *LabelSym = getPICLabel(DL->getPrivateGlobalPrefix(), 1346 getFunctionNumber(), 1347 MI->getOperand(2).getImm(), OutContext); 1348 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 1349 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 1350 const MCExpr *PCRelExpr = 1351 ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 1352 MCBinaryExpr::CreateAdd(LabelSymExpr, 1353 MCConstantExpr::Create(PCAdj, OutContext), 1354 OutContext), OutContext), OutContext); 1355 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 1356 1357 // Add predicate operands. 1358 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1359 TmpInst.addOperand(MCOperand::CreateReg(0)); 1360 // Add 's' bit operand (always reg0 for this) 1361 TmpInst.addOperand(MCOperand::CreateReg(0)); 1362 EmitToStreamer(OutStreamer, TmpInst); 1363 return; 1364 } 1365 case ARM::MOVTi16_ga_pcrel: 1366 case ARM::t2MOVTi16_ga_pcrel: { 1367 MCInst TmpInst; 1368 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 1369 ? ARM::MOVTi16 : ARM::t2MOVTi16); 1370 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1371 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1372 1373 unsigned TF = MI->getOperand(2).getTargetFlags(); 1374 const GlobalValue *GV = MI->getOperand(2).getGlobal(); 1375 MCSymbol *GVSym = GetARMGVSymbol(GV, TF); 1376 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 1377 1378 MCSymbol *LabelSym = getPICLabel(DL->getPrivateGlobalPrefix(), 1379 getFunctionNumber(), 1380 MI->getOperand(3).getImm(), OutContext); 1381 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 1382 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 1383 const MCExpr *PCRelExpr = 1384 ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 1385 MCBinaryExpr::CreateAdd(LabelSymExpr, 1386 MCConstantExpr::Create(PCAdj, OutContext), 1387 OutContext), OutContext), OutContext); 1388 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 1389 // Add predicate operands. 1390 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1391 TmpInst.addOperand(MCOperand::CreateReg(0)); 1392 // Add 's' bit operand (always reg0 for this) 1393 TmpInst.addOperand(MCOperand::CreateReg(0)); 1394 EmitToStreamer(OutStreamer, TmpInst); 1395 return; 1396 } 1397 case ARM::tPICADD: { 1398 // This is a pseudo op for a label + instruction sequence, which looks like: 1399 // LPC0: 1400 // add r0, pc 1401 // This adds the address of LPC0 to r0. 1402 1403 // Emit the label. 1404 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(), 1405 getFunctionNumber(), MI->getOperand(2).getImm(), 1406 OutContext)); 1407 1408 // Form and emit the add. 1409 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tADDhirr) 1410 .addReg(MI->getOperand(0).getReg()) 1411 .addReg(MI->getOperand(0).getReg()) 1412 .addReg(ARM::PC) 1413 // Add predicate operands. 1414 .addImm(ARMCC::AL) 1415 .addReg(0)); 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(DL->getPrivateGlobalPrefix(), 1426 getFunctionNumber(), MI->getOperand(2).getImm(), 1427 OutContext)); 1428 1429 // Form and emit the add. 1430 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDrr) 1431 .addReg(MI->getOperand(0).getReg()) 1432 .addReg(ARM::PC) 1433 .addReg(MI->getOperand(1).getReg()) 1434 // Add predicate operands. 1435 .addImm(MI->getOperand(3).getImm()) 1436 .addReg(MI->getOperand(4).getReg()) 1437 // Add 's' bit operand (always reg0 for this) 1438 .addReg(0)); 1439 return; 1440 } 1441 case ARM::PICSTR: 1442 case ARM::PICSTRB: 1443 case ARM::PICSTRH: 1444 case ARM::PICLDR: 1445 case ARM::PICLDRB: 1446 case ARM::PICLDRH: 1447 case ARM::PICLDRSB: 1448 case ARM::PICLDRSH: { 1449 // This is a pseudo op for a label + instruction sequence, which looks like: 1450 // LPC0: 1451 // OP r0, [pc, r0] 1452 // The LCP0 label is referenced by a constant pool entry in order to get 1453 // a PC-relative address at the ldr instruction. 1454 1455 // Emit the label. 1456 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(), 1457 getFunctionNumber(), MI->getOperand(2).getImm(), 1458 OutContext)); 1459 1460 // Form and emit the load 1461 unsigned Opcode; 1462 switch (MI->getOpcode()) { 1463 default: 1464 llvm_unreachable("Unexpected opcode!"); 1465 case ARM::PICSTR: Opcode = ARM::STRrs; break; 1466 case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 1467 case ARM::PICSTRH: Opcode = ARM::STRH; break; 1468 case ARM::PICLDR: Opcode = ARM::LDRrs; break; 1469 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 1470 case ARM::PICLDRH: Opcode = ARM::LDRH; break; 1471 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 1472 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 1473 } 1474 EmitToStreamer(OutStreamer, MCInstBuilder(Opcode) 1475 .addReg(MI->getOperand(0).getReg()) 1476 .addReg(ARM::PC) 1477 .addReg(MI->getOperand(1).getReg()) 1478 .addImm(0) 1479 // Add predicate operands. 1480 .addImm(MI->getOperand(3).getImm()) 1481 .addReg(MI->getOperand(4).getReg())); 1482 1483 return; 1484 } 1485 case ARM::CONSTPOOL_ENTRY: { 1486 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 1487 /// in the function. The first operand is the ID# for this instruction, the 1488 /// second is the index into the MachineConstantPool that this is, the third 1489 /// is the size in bytes of this constant pool entry. 1490 /// The required alignment is specified on the basic block holding this MI. 1491 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 1492 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 1493 1494 // If this is the first entry of the pool, mark it. 1495 if (!InConstantPool) { 1496 OutStreamer.EmitDataRegion(MCDR_DataRegion); 1497 InConstantPool = true; 1498 } 1499 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 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 1512 .addReg(ARM::PC) 1513 .addReg(MI->getOperand(0).getReg()) 1514 // Add predicate operands. 1515 .addImm(ARMCC::AL) 1516 .addReg(0)); 1517 1518 // Output the data for the jump table itself 1519 EmitJump2Table(MI); 1520 return; 1521 } 1522 case ARM::t2TBB_JT: { 1523 // Lower and emit the instruction itself, then the jump table following it. 1524 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2TBB) 1525 .addReg(ARM::PC) 1526 .addReg(MI->getOperand(0).getReg()) 1527 // Add predicate operands. 1528 .addImm(ARMCC::AL) 1529 .addReg(0)); 1530 1531 // Output the data for the jump table itself 1532 EmitJump2Table(MI); 1533 // Make sure the next instruction is 2-byte aligned. 1534 EmitAlignment(1); 1535 return; 1536 } 1537 case ARM::t2TBH_JT: { 1538 // Lower and emit the instruction itself, then the jump table following it. 1539 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2TBH) 1540 .addReg(ARM::PC) 1541 .addReg(MI->getOperand(0).getReg()) 1542 // Add predicate operands. 1543 .addImm(ARMCC::AL) 1544 .addReg(0)); 1545 1546 // Output the data for the jump table itself 1547 EmitJump2Table(MI); 1548 return; 1549 } 1550 case ARM::tBR_JTr: 1551 case ARM::BR_JTr: { 1552 // Lower and emit the instruction itself, then the jump table following it. 1553 // mov pc, target 1554 MCInst TmpInst; 1555 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 1556 ARM::MOVr : ARM::tMOVr; 1557 TmpInst.setOpcode(Opc); 1558 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1559 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1560 // Add predicate operands. 1561 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1562 TmpInst.addOperand(MCOperand::CreateReg(0)); 1563 // Add 's' bit operand (always reg0 for this) 1564 if (Opc == ARM::MOVr) 1565 TmpInst.addOperand(MCOperand::CreateReg(0)); 1566 EmitToStreamer(OutStreamer, TmpInst); 1567 1568 // Make sure the Thumb jump table is 4-byte aligned. 1569 if (Opc == ARM::tMOVr) 1570 EmitAlignment(2); 1571 1572 // Output the data for the jump table itself 1573 EmitJumpTable(MI); 1574 return; 1575 } 1576 case ARM::BR_JTm: { 1577 // Lower and emit the instruction itself, then the jump table following it. 1578 // ldr pc, target 1579 MCInst TmpInst; 1580 if (MI->getOperand(1).getReg() == 0) { 1581 // literal offset 1582 TmpInst.setOpcode(ARM::LDRi12); 1583 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1584 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1585 TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 1586 } else { 1587 TmpInst.setOpcode(ARM::LDRrs); 1588 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1589 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1590 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1591 TmpInst.addOperand(MCOperand::CreateImm(0)); 1592 } 1593 // Add predicate operands. 1594 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1595 TmpInst.addOperand(MCOperand::CreateReg(0)); 1596 EmitToStreamer(OutStreamer, TmpInst); 1597 1598 // Output the data for the jump table itself 1599 EmitJumpTable(MI); 1600 return; 1601 } 1602 case ARM::BR_JTadd: { 1603 // Lower and emit the instruction itself, then the jump table following it. 1604 // add pc, target, idx 1605 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDrr) 1606 .addReg(ARM::PC) 1607 .addReg(MI->getOperand(0).getReg()) 1608 .addReg(MI->getOperand(1).getReg()) 1609 // Add predicate operands. 1610 .addImm(ARMCC::AL) 1611 .addReg(0) 1612 // Add 's' bit operand (always reg0 for this) 1613 .addReg(0)); 1614 1615 // Output the data for the jump table itself 1616 EmitJumpTable(MI); 1617 return; 1618 } 1619 case ARM::SPACE: 1620 OutStreamer.EmitZeros(MI->getOperand(1).getImm()); 1621 return; 1622 case ARM::TRAP: { 1623 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1624 // FIXME: Remove this special case when they do. 1625 if (!Subtarget->isTargetMachO()) { 1626 //.long 0xe7ffdefe @ trap 1627 uint32_t Val = 0xe7ffdefeUL; 1628 OutStreamer.AddComment("trap"); 1629 OutStreamer.EmitIntValue(Val, 4); 1630 return; 1631 } 1632 break; 1633 } 1634 case ARM::TRAPNaCl: { 1635 //.long 0xe7fedef0 @ trap 1636 uint32_t Val = 0xe7fedef0UL; 1637 OutStreamer.AddComment("trap"); 1638 OutStreamer.EmitIntValue(Val, 4); 1639 return; 1640 } 1641 case ARM::tTRAP: { 1642 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1643 // FIXME: Remove this special case when they do. 1644 if (!Subtarget->isTargetMachO()) { 1645 //.short 57086 @ trap 1646 uint16_t Val = 0xdefe; 1647 OutStreamer.AddComment("trap"); 1648 OutStreamer.EmitIntValue(Val, 2); 1649 return; 1650 } 1651 break; 1652 } 1653 case ARM::t2Int_eh_sjlj_setjmp: 1654 case ARM::t2Int_eh_sjlj_setjmp_nofp: 1655 case ARM::tInt_eh_sjlj_setjmp: { 1656 // Two incoming args: GPR:$src, GPR:$val 1657 // mov $val, pc 1658 // adds $val, #7 1659 // str $val, [$src, #4] 1660 // movs r0, #0 1661 // b 1f 1662 // movs r0, #1 1663 // 1: 1664 unsigned SrcReg = MI->getOperand(0).getReg(); 1665 unsigned ValReg = MI->getOperand(1).getReg(); 1666 MCSymbol *Label = GetARMSJLJEHLabel(); 1667 OutStreamer.AddComment("eh_setjmp begin"); 1668 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 1669 .addReg(ValReg) 1670 .addReg(ARM::PC) 1671 // Predicate. 1672 .addImm(ARMCC::AL) 1673 .addReg(0)); 1674 1675 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tADDi3) 1676 .addReg(ValReg) 1677 // 's' bit operand 1678 .addReg(ARM::CPSR) 1679 .addReg(ValReg) 1680 .addImm(7) 1681 // Predicate. 1682 .addImm(ARMCC::AL) 1683 .addReg(0)); 1684 1685 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tSTRi) 1686 .addReg(ValReg) 1687 .addReg(SrcReg) 1688 // The offset immediate is #4. The operand value is scaled by 4 for the 1689 // tSTR instruction. 1690 .addImm(1) 1691 // Predicate. 1692 .addImm(ARMCC::AL) 1693 .addReg(0)); 1694 1695 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVi8) 1696 .addReg(ARM::R0) 1697 .addReg(ARM::CPSR) 1698 .addImm(0) 1699 // Predicate. 1700 .addImm(ARMCC::AL) 1701 .addReg(0)); 1702 1703 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1704 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tB) 1705 .addExpr(SymbolExpr) 1706 .addImm(ARMCC::AL) 1707 .addReg(0)); 1708 1709 OutStreamer.AddComment("eh_setjmp end"); 1710 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVi8) 1711 .addReg(ARM::R0) 1712 .addReg(ARM::CPSR) 1713 .addImm(1) 1714 // Predicate. 1715 .addImm(ARMCC::AL) 1716 .addReg(0)); 1717 1718 OutStreamer.EmitLabel(Label); 1719 return; 1720 } 1721 1722 case ARM::Int_eh_sjlj_setjmp_nofp: 1723 case ARM::Int_eh_sjlj_setjmp: { 1724 // Two incoming args: GPR:$src, GPR:$val 1725 // add $val, pc, #8 1726 // str $val, [$src, #+4] 1727 // mov r0, #0 1728 // add pc, pc, #0 1729 // mov r0, #1 1730 unsigned SrcReg = MI->getOperand(0).getReg(); 1731 unsigned ValReg = MI->getOperand(1).getReg(); 1732 1733 OutStreamer.AddComment("eh_setjmp begin"); 1734 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDri) 1735 .addReg(ValReg) 1736 .addReg(ARM::PC) 1737 .addImm(8) 1738 // Predicate. 1739 .addImm(ARMCC::AL) 1740 .addReg(0) 1741 // 's' bit operand (always reg0 for this). 1742 .addReg(0)); 1743 1744 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::STRi12) 1745 .addReg(ValReg) 1746 .addReg(SrcReg) 1747 .addImm(4) 1748 // Predicate. 1749 .addImm(ARMCC::AL) 1750 .addReg(0)); 1751 1752 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVi) 1753 .addReg(ARM::R0) 1754 .addImm(0) 1755 // Predicate. 1756 .addImm(ARMCC::AL) 1757 .addReg(0) 1758 // 's' bit operand (always reg0 for this). 1759 .addReg(0)); 1760 1761 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDri) 1762 .addReg(ARM::PC) 1763 .addReg(ARM::PC) 1764 .addImm(0) 1765 // Predicate. 1766 .addImm(ARMCC::AL) 1767 .addReg(0) 1768 // 's' bit operand (always reg0 for this). 1769 .addReg(0)); 1770 1771 OutStreamer.AddComment("eh_setjmp end"); 1772 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVi) 1773 .addReg(ARM::R0) 1774 .addImm(1) 1775 // Predicate. 1776 .addImm(ARMCC::AL) 1777 .addReg(0) 1778 // 's' bit operand (always reg0 for this). 1779 .addReg(0)); 1780 return; 1781 } 1782 case ARM::Int_eh_sjlj_longjmp: { 1783 // ldr sp, [$src, #8] 1784 // ldr $scratch, [$src, #4] 1785 // ldr r7, [$src] 1786 // bx $scratch 1787 unsigned SrcReg = MI->getOperand(0).getReg(); 1788 unsigned ScratchReg = MI->getOperand(1).getReg(); 1789 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12) 1790 .addReg(ARM::SP) 1791 .addReg(SrcReg) 1792 .addImm(8) 1793 // Predicate. 1794 .addImm(ARMCC::AL) 1795 .addReg(0)); 1796 1797 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12) 1798 .addReg(ScratchReg) 1799 .addReg(SrcReg) 1800 .addImm(4) 1801 // Predicate. 1802 .addImm(ARMCC::AL) 1803 .addReg(0)); 1804 1805 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12) 1806 .addReg(ARM::R7) 1807 .addReg(SrcReg) 1808 .addImm(0) 1809 // Predicate. 1810 .addImm(ARMCC::AL) 1811 .addReg(0)); 1812 1813 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::BX) 1814 .addReg(ScratchReg) 1815 // Predicate. 1816 .addImm(ARMCC::AL) 1817 .addReg(0)); 1818 return; 1819 } 1820 case ARM::tInt_eh_sjlj_longjmp: { 1821 // ldr $scratch, [$src, #8] 1822 // mov sp, $scratch 1823 // ldr $scratch, [$src, #4] 1824 // ldr r7, [$src] 1825 // bx $scratch 1826 unsigned SrcReg = MI->getOperand(0).getReg(); 1827 unsigned ScratchReg = MI->getOperand(1).getReg(); 1828 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi) 1829 .addReg(ScratchReg) 1830 .addReg(SrcReg) 1831 // The offset immediate is #8. The operand value is scaled by 4 for the 1832 // tLDR instruction. 1833 .addImm(2) 1834 // Predicate. 1835 .addImm(ARMCC::AL) 1836 .addReg(0)); 1837 1838 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 1839 .addReg(ARM::SP) 1840 .addReg(ScratchReg) 1841 // Predicate. 1842 .addImm(ARMCC::AL) 1843 .addReg(0)); 1844 1845 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi) 1846 .addReg(ScratchReg) 1847 .addReg(SrcReg) 1848 .addImm(1) 1849 // Predicate. 1850 .addImm(ARMCC::AL) 1851 .addReg(0)); 1852 1853 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi) 1854 .addReg(ARM::R7) 1855 .addReg(SrcReg) 1856 .addImm(0) 1857 // Predicate. 1858 .addImm(ARMCC::AL) 1859 .addReg(0)); 1860 1861 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX) 1862 .addReg(ScratchReg) 1863 // Predicate. 1864 .addImm(ARMCC::AL) 1865 .addReg(0)); 1866 return; 1867 } 1868 } 1869 1870 MCInst TmpInst; 1871 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1872 1873 EmitToStreamer(OutStreamer, TmpInst); 1874} 1875 1876//===----------------------------------------------------------------------===// 1877// Target Registry Stuff 1878//===----------------------------------------------------------------------===// 1879 1880// Force static initialization. 1881extern "C" void LLVMInitializeARMAsmPrinter() { 1882 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMLETarget); 1883 RegisterAsmPrinter<ARMAsmPrinter> Y(TheARMBETarget); 1884 RegisterAsmPrinter<ARMAsmPrinter> A(TheThumbLETarget); 1885 RegisterAsmPrinter<ARMAsmPrinter> B(TheThumbBETarget); 1886} 1887