LLVM API Documentation
00001 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains a printer that converts from our internal representation 00011 // of machine-dependent LLVM code to GAS-format ARM assembly language. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "ARMAsmPrinter.h" 00016 #include "ARM.h" 00017 #include "ARMConstantPoolValue.h" 00018 #include "ARMFPUName.h" 00019 #include "ARMMachineFunctionInfo.h" 00020 #include "ARMTargetMachine.h" 00021 #include "ARMTargetObjectFile.h" 00022 #include "InstPrinter/ARMInstPrinter.h" 00023 #include "MCTargetDesc/ARMAddressingModes.h" 00024 #include "MCTargetDesc/ARMMCExpr.h" 00025 #include "llvm/ADT/SetVector.h" 00026 #include "llvm/ADT/SmallString.h" 00027 #include "llvm/CodeGen/MachineFunctionPass.h" 00028 #include "llvm/CodeGen/MachineJumpTableInfo.h" 00029 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 00030 #include "llvm/IR/Constants.h" 00031 #include "llvm/IR/DataLayout.h" 00032 #include "llvm/IR/DebugInfo.h" 00033 #include "llvm/IR/Mangler.h" 00034 #include "llvm/IR/Module.h" 00035 #include "llvm/IR/Type.h" 00036 #include "llvm/MC/MCAsmInfo.h" 00037 #include "llvm/MC/MCAssembler.h" 00038 #include "llvm/MC/MCContext.h" 00039 #include "llvm/MC/MCELFStreamer.h" 00040 #include "llvm/MC/MCInst.h" 00041 #include "llvm/MC/MCInstBuilder.h" 00042 #include "llvm/MC/MCObjectStreamer.h" 00043 #include "llvm/MC/MCSectionMachO.h" 00044 #include "llvm/MC/MCStreamer.h" 00045 #include "llvm/MC/MCSymbol.h" 00046 #include "llvm/Support/ARMBuildAttributes.h" 00047 #include "llvm/Support/COFF.h" 00048 #include "llvm/Support/CommandLine.h" 00049 #include "llvm/Support/Debug.h" 00050 #include "llvm/Support/ELF.h" 00051 #include "llvm/Support/ErrorHandling.h" 00052 #include "llvm/Support/TargetRegistry.h" 00053 #include "llvm/Support/raw_ostream.h" 00054 #include "llvm/Target/TargetMachine.h" 00055 #include <cctype> 00056 using namespace llvm; 00057 00058 #define DEBUG_TYPE "asm-printer" 00059 00060 void ARMAsmPrinter::EmitFunctionBodyEnd() { 00061 // Make sure to terminate any constant pools that were at the end 00062 // of the function. 00063 if (!InConstantPool) 00064 return; 00065 InConstantPool = false; 00066 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 00067 } 00068 00069 void ARMAsmPrinter::EmitFunctionEntryLabel() { 00070 if (AFI->isThumbFunction()) { 00071 OutStreamer.EmitAssemblerFlag(MCAF_Code16); 00072 OutStreamer.EmitThumbFunc(CurrentFnSym); 00073 } 00074 00075 OutStreamer.EmitLabel(CurrentFnSym); 00076 } 00077 00078 void ARMAsmPrinter::EmitXXStructor(const Constant *CV) { 00079 uint64_t Size = 00080 TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(CV->getType()); 00081 assert(Size && "C++ constructor pointer had zero size!"); 00082 00083 const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts()); 00084 assert(GV && "C++ constructor pointer was not a GlobalValue!"); 00085 00086 const MCExpr *E = MCSymbolRefExpr::Create(GetARMGVSymbol(GV, 00087 ARMII::MO_NO_FLAG), 00088 (Subtarget->isTargetELF() 00089 ? MCSymbolRefExpr::VK_ARM_TARGET1 00090 : MCSymbolRefExpr::VK_None), 00091 OutContext); 00092 00093 OutStreamer.EmitValue(E, Size); 00094 } 00095 00096 /// runOnMachineFunction - This uses the EmitInstruction() 00097 /// method to print assembly for each instruction. 00098 /// 00099 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00100 AFI = MF.getInfo<ARMFunctionInfo>(); 00101 MCP = MF.getConstantPool(); 00102 00103 SetupMachineFunction(MF); 00104 00105 if (Subtarget->isTargetCOFF()) { 00106 bool Internal = MF.getFunction()->hasInternalLinkage(); 00107 COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC 00108 : COFF::IMAGE_SYM_CLASS_EXTERNAL; 00109 int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT; 00110 00111 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 00112 OutStreamer.EmitCOFFSymbolStorageClass(Scl); 00113 OutStreamer.EmitCOFFSymbolType(Type); 00114 OutStreamer.EndCOFFSymbolDef(); 00115 } 00116 00117 // Have common code print out the function header with linkage info etc. 00118 EmitFunctionHeader(); 00119 00120 // Emit the rest of the function body. 00121 EmitFunctionBody(); 00122 00123 // We didn't modify anything. 00124 return false; 00125 } 00126 00127 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 00128 raw_ostream &O, const char *Modifier) { 00129 const MachineOperand &MO = MI->getOperand(OpNum); 00130 unsigned TF = MO.getTargetFlags(); 00131 00132 switch (MO.getType()) { 00133 default: llvm_unreachable("<unknown operand type>"); 00134 case MachineOperand::MO_Register: { 00135 unsigned Reg = MO.getReg(); 00136 assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 00137 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 00138 if(ARM::GPRPairRegClass.contains(Reg)) { 00139 const MachineFunction &MF = *MI->getParent()->getParent(); 00140 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 00141 Reg = TRI->getSubReg(Reg, ARM::gsub_0); 00142 } 00143 O << ARMInstPrinter::getRegisterName(Reg); 00144 break; 00145 } 00146 case MachineOperand::MO_Immediate: { 00147 int64_t Imm = MO.getImm(); 00148 O << '#'; 00149 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 00150 (TF == ARMII::MO_LO16)) 00151 O << ":lower16:"; 00152 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 00153 (TF == ARMII::MO_HI16)) 00154 O << ":upper16:"; 00155 O << Imm; 00156 break; 00157 } 00158 case MachineOperand::MO_MachineBasicBlock: 00159 O << *MO.getMBB()->getSymbol(); 00160 return; 00161 case MachineOperand::MO_GlobalAddress: { 00162 const GlobalValue *GV = MO.getGlobal(); 00163 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 00164 (TF & ARMII::MO_LO16)) 00165 O << ":lower16:"; 00166 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 00167 (TF & ARMII::MO_HI16)) 00168 O << ":upper16:"; 00169 O << *GetARMGVSymbol(GV, TF); 00170 00171 printOffset(MO.getOffset(), O); 00172 if (TF == ARMII::MO_PLT) 00173 O << "(PLT)"; 00174 break; 00175 } 00176 case MachineOperand::MO_ConstantPoolIndex: 00177 O << *GetCPISymbol(MO.getIndex()); 00178 break; 00179 } 00180 } 00181 00182 //===--------------------------------------------------------------------===// 00183 00184 MCSymbol *ARMAsmPrinter:: 00185 GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 00186 const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); 00187 SmallString<60> Name; 00188 raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "JTI" 00189 << getFunctionNumber() << '_' << uid << '_' << uid2; 00190 return OutContext.GetOrCreateSymbol(Name.str()); 00191 } 00192 00193 00194 MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel() const { 00195 const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); 00196 SmallString<60> Name; 00197 raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "SJLJEH" 00198 << getFunctionNumber(); 00199 return OutContext.GetOrCreateSymbol(Name.str()); 00200 } 00201 00202 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 00203 unsigned AsmVariant, const char *ExtraCode, 00204 raw_ostream &O) { 00205 // Does this asm operand have a single letter operand modifier? 00206 if (ExtraCode && ExtraCode[0]) { 00207 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00208 00209 switch (ExtraCode[0]) { 00210 default: 00211 // See if this is a generic print operand 00212 return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O); 00213 case 'a': // Print as a memory address. 00214 if (MI->getOperand(OpNum).isReg()) { 00215 O << "[" 00216 << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 00217 << "]"; 00218 return false; 00219 } 00220 // Fallthrough 00221 case 'c': // Don't print "#" before an immediate operand. 00222 if (!MI->getOperand(OpNum).isImm()) 00223 return true; 00224 O << MI->getOperand(OpNum).getImm(); 00225 return false; 00226 case 'P': // Print a VFP double precision register. 00227 case 'q': // Print a NEON quad precision register. 00228 printOperand(MI, OpNum, O); 00229 return false; 00230 case 'y': // Print a VFP single precision register as indexed double. 00231 if (MI->getOperand(OpNum).isReg()) { 00232 unsigned Reg = MI->getOperand(OpNum).getReg(); 00233 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 00234 // Find the 'd' register that has this 's' register as a sub-register, 00235 // and determine the lane number. 00236 for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) { 00237 if (!ARM::DPRRegClass.contains(*SR)) 00238 continue; 00239 bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg; 00240 O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]"); 00241 return false; 00242 } 00243 } 00244 return true; 00245 case 'B': // Bitwise inverse of integer or symbol without a preceding #. 00246 if (!MI->getOperand(OpNum).isImm()) 00247 return true; 00248 O << ~(MI->getOperand(OpNum).getImm()); 00249 return false; 00250 case 'L': // The low 16 bits of an immediate constant. 00251 if (!MI->getOperand(OpNum).isImm()) 00252 return true; 00253 O << (MI->getOperand(OpNum).getImm() & 0xffff); 00254 return false; 00255 case 'M': { // A register range suitable for LDM/STM. 00256 if (!MI->getOperand(OpNum).isReg()) 00257 return true; 00258 const MachineOperand &MO = MI->getOperand(OpNum); 00259 unsigned RegBegin = MO.getReg(); 00260 // This takes advantage of the 2 operand-ness of ldm/stm and that we've 00261 // already got the operands in registers that are operands to the 00262 // inline asm statement. 00263 O << "{"; 00264 if (ARM::GPRPairRegClass.contains(RegBegin)) { 00265 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 00266 unsigned Reg0 = TRI->getSubReg(RegBegin, ARM::gsub_0); 00267 O << ARMInstPrinter::getRegisterName(Reg0) << ", "; 00268 RegBegin = TRI->getSubReg(RegBegin, ARM::gsub_1); 00269 } 00270 O << ARMInstPrinter::getRegisterName(RegBegin); 00271 00272 // FIXME: The register allocator not only may not have given us the 00273 // registers in sequence, but may not be in ascending registers. This 00274 // will require changes in the register allocator that'll need to be 00275 // propagated down here if the operands change. 00276 unsigned RegOps = OpNum + 1; 00277 while (MI->getOperand(RegOps).isReg()) { 00278 O << ", " 00279 << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg()); 00280 RegOps++; 00281 } 00282 00283 O << "}"; 00284 00285 return false; 00286 } 00287 case 'R': // The most significant register of a pair. 00288 case 'Q': { // The least significant register of a pair. 00289 if (OpNum == 0) 00290 return true; 00291 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 00292 if (!FlagsOP.isImm()) 00293 return true; 00294 unsigned Flags = FlagsOP.getImm(); 00295 00296 // This operand may not be the one that actually provides the register. If 00297 // it's tied to a previous one then we should refer instead to that one 00298 // for registers and their classes. 00299 unsigned TiedIdx; 00300 if (InlineAsm::isUseOperandTiedToDef(Flags, TiedIdx)) { 00301 for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) { 00302 unsigned OpFlags = MI->getOperand(OpNum).getImm(); 00303 OpNum += InlineAsm::getNumOperandRegisters(OpFlags) + 1; 00304 } 00305 Flags = MI->getOperand(OpNum).getImm(); 00306 00307 // Later code expects OpNum to be pointing at the register rather than 00308 // the flags. 00309 OpNum += 1; 00310 } 00311 00312 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 00313 unsigned RC; 00314 InlineAsm::hasRegClassConstraint(Flags, RC); 00315 if (RC == ARM::GPRPairRegClassID) { 00316 if (NumVals != 1) 00317 return true; 00318 const MachineOperand &MO = MI->getOperand(OpNum); 00319 if (!MO.isReg()) 00320 return true; 00321 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 00322 unsigned Reg = TRI->getSubReg(MO.getReg(), ExtraCode[0] == 'Q' ? 00323 ARM::gsub_0 : ARM::gsub_1); 00324 O << ARMInstPrinter::getRegisterName(Reg); 00325 return false; 00326 } 00327 if (NumVals != 2) 00328 return true; 00329 unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1; 00330 if (RegOp >= MI->getNumOperands()) 00331 return true; 00332 const MachineOperand &MO = MI->getOperand(RegOp); 00333 if (!MO.isReg()) 00334 return true; 00335 unsigned Reg = MO.getReg(); 00336 O << ARMInstPrinter::getRegisterName(Reg); 00337 return false; 00338 } 00339 00340 case 'e': // The low doubleword register of a NEON quad register. 00341 case 'f': { // The high doubleword register of a NEON quad register. 00342 if (!MI->getOperand(OpNum).isReg()) 00343 return true; 00344 unsigned Reg = MI->getOperand(OpNum).getReg(); 00345 if (!ARM::QPRRegClass.contains(Reg)) 00346 return true; 00347 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 00348 unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ? 00349 ARM::dsub_0 : ARM::dsub_1); 00350 O << ARMInstPrinter::getRegisterName(SubReg); 00351 return false; 00352 } 00353 00354 // This modifier is not yet supported. 00355 case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1. 00356 return true; 00357 case 'H': { // The highest-numbered register of a pair. 00358 const MachineOperand &MO = MI->getOperand(OpNum); 00359 if (!MO.isReg()) 00360 return true; 00361 const MachineFunction &MF = *MI->getParent()->getParent(); 00362 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 00363 unsigned Reg = MO.getReg(); 00364 if(!ARM::GPRPairRegClass.contains(Reg)) 00365 return false; 00366 Reg = TRI->getSubReg(Reg, ARM::gsub_1); 00367 O << ARMInstPrinter::getRegisterName(Reg); 00368 return false; 00369 } 00370 } 00371 } 00372 00373 printOperand(MI, OpNum, O); 00374 return false; 00375 } 00376 00377 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00378 unsigned OpNum, unsigned AsmVariant, 00379 const char *ExtraCode, 00380 raw_ostream &O) { 00381 // Does this asm operand have a single letter operand modifier? 00382 if (ExtraCode && ExtraCode[0]) { 00383 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00384 00385 switch (ExtraCode[0]) { 00386 case 'A': // A memory operand for a VLD1/VST1 instruction. 00387 default: return true; // Unknown modifier. 00388 case 'm': // The base register of a memory operand. 00389 if (!MI->getOperand(OpNum).isReg()) 00390 return true; 00391 O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()); 00392 return false; 00393 } 00394 } 00395 00396 const MachineOperand &MO = MI->getOperand(OpNum); 00397 assert(MO.isReg() && "unexpected inline asm memory operand"); 00398 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 00399 return false; 00400 } 00401 00402 static bool isThumb(const MCSubtargetInfo& STI) { 00403 return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 00404 } 00405 00406 void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 00407 const MCSubtargetInfo *EndInfo) const { 00408 // If either end mode is unknown (EndInfo == NULL) or different than 00409 // the start mode, then restore the start mode. 00410 const bool WasThumb = isThumb(StartInfo); 00411 if (!EndInfo || WasThumb != isThumb(*EndInfo)) { 00412 OutStreamer.EmitAssemblerFlag(WasThumb ? MCAF_Code16 : MCAF_Code32); 00413 } 00414 } 00415 00416 void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 00417 if (Subtarget->isTargetMachO()) { 00418 Reloc::Model RelocM = TM.getRelocationModel(); 00419 if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 00420 // Declare all the text sections up front (before the DWARF sections 00421 // emitted by AsmPrinter::doInitialization) so the assembler will keep 00422 // them together at the beginning of the object file. This helps 00423 // avoid out-of-range branches that are due a fundamental limitation of 00424 // the way symbol offsets are encoded with the current Darwin ARM 00425 // relocations. 00426 const TargetLoweringObjectFileMachO &TLOFMacho = 00427 static_cast<const TargetLoweringObjectFileMachO &>( 00428 getObjFileLowering()); 00429 00430 // Collect the set of sections our functions will go into. 00431 SetVector<const MCSection *, SmallVector<const MCSection *, 8>, 00432 SmallPtrSet<const MCSection *, 8> > TextSections; 00433 // Default text section comes first. 00434 TextSections.insert(TLOFMacho.getTextSection()); 00435 // Now any user defined text sections from function attributes. 00436 for (Module::iterator F = M.begin(), e = M.end(); F != e; ++F) 00437 if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage()) 00438 TextSections.insert(TLOFMacho.SectionForGlobal(F, *Mang, TM)); 00439 // Now the coalescable sections. 00440 TextSections.insert(TLOFMacho.getTextCoalSection()); 00441 TextSections.insert(TLOFMacho.getConstTextCoalSection()); 00442 00443 // Emit the sections in the .s file header to fix the order. 00444 for (unsigned i = 0, e = TextSections.size(); i != e; ++i) 00445 OutStreamer.SwitchSection(TextSections[i]); 00446 00447 if (RelocM == Reloc::DynamicNoPIC) { 00448 const MCSection *sect = 00449 OutContext.getMachOSection("__TEXT", "__symbol_stub4", 00450 MachO::S_SYMBOL_STUBS, 00451 12, SectionKind::getText()); 00452 OutStreamer.SwitchSection(sect); 00453 } else { 00454 const MCSection *sect = 00455 OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 00456 MachO::S_SYMBOL_STUBS, 00457 16, SectionKind::getText()); 00458 OutStreamer.SwitchSection(sect); 00459 } 00460 const MCSection *StaticInitSect = 00461 OutContext.getMachOSection("__TEXT", "__StaticInit", 00462 MachO::S_REGULAR | 00463 MachO::S_ATTR_PURE_INSTRUCTIONS, 00464 SectionKind::getText()); 00465 OutStreamer.SwitchSection(StaticInitSect); 00466 } 00467 00468 // Compiling with debug info should not affect the code 00469 // generation. Ensure the cstring section comes before the 00470 // optional __DWARF secion. Otherwise, PC-relative loads would 00471 // have to use different instruction sequences at "-g" in order to 00472 // reach global data in the same object file. 00473 OutStreamer.SwitchSection(getObjFileLowering().getCStringSection()); 00474 } 00475 00476 // Use unified assembler syntax. 00477 OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 00478 00479 // Emit ARM Build Attributes 00480 if (Subtarget->isTargetELF()) 00481 emitAttributes(); 00482 00483 if (!M.getModuleInlineAsm().empty() && Subtarget->isThumb()) 00484 OutStreamer.EmitAssemblerFlag(MCAF_Code16); 00485 } 00486 00487 static void 00488 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, 00489 MachineModuleInfoImpl::StubValueTy &MCSym) { 00490 // L_foo$stub: 00491 OutStreamer.EmitLabel(StubLabel); 00492 // .indirect_symbol _foo 00493 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 00494 00495 if (MCSym.getInt()) 00496 // External to current translation unit. 00497 OutStreamer.EmitIntValue(0, 4/*size*/); 00498 else 00499 // Internal to current translation unit. 00500 // 00501 // When we place the LSDA into the TEXT section, the type info 00502 // pointers need to be indirect and pc-rel. We accomplish this by 00503 // using NLPs; however, sometimes the types are local to the file. 00504 // We need to fill in the value for the NLP in those cases. 00505 OutStreamer.EmitValue( 00506 MCSymbolRefExpr::Create(MCSym.getPointer(), OutStreamer.getContext()), 00507 4 /*size*/); 00508 } 00509 00510 00511 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 00512 if (Subtarget->isTargetMachO()) { 00513 // All darwin targets use mach-o. 00514 const TargetLoweringObjectFileMachO &TLOFMacho = 00515 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 00516 MachineModuleInfoMachO &MMIMacho = 00517 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 00518 00519 // Output non-lazy-pointers for external and common global variables. 00520 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 00521 00522 if (!Stubs.empty()) { 00523 // Switch with ".non_lazy_symbol_pointer" directive. 00524 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 00525 EmitAlignment(2); 00526 00527 for (auto &Stub : Stubs) 00528 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); 00529 00530 Stubs.clear(); 00531 OutStreamer.AddBlankLine(); 00532 } 00533 00534 Stubs = MMIMacho.GetHiddenGVStubList(); 00535 if (!Stubs.empty()) { 00536 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 00537 EmitAlignment(2); 00538 00539 for (auto &Stub : Stubs) 00540 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); 00541 00542 Stubs.clear(); 00543 OutStreamer.AddBlankLine(); 00544 } 00545 00546 // Funny Darwin hack: This flag tells the linker that no global symbols 00547 // contain code that falls through to other global symbols (e.g. the obvious 00548 // implementation of multiple entry points). If this doesn't occur, the 00549 // linker can safely perform dead code stripping. Since LLVM never 00550 // generates code that does this, it is always safe to set. 00551 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 00552 } 00553 00554 // Emit a .data.rel section containing any stubs that were created. 00555 if (Subtarget->isTargetELF()) { 00556 const TargetLoweringObjectFileELF &TLOFELF = 00557 static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); 00558 00559 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 00560 00561 // Output stubs for external and common global variables. 00562 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 00563 if (!Stubs.empty()) { 00564 OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); 00565 const DataLayout *TD = TM.getSubtargetImpl()->getDataLayout(); 00566 00567 for (auto &stub: Stubs) { 00568 OutStreamer.EmitLabel(stub.first); 00569 OutStreamer.EmitSymbolValue(stub.second.getPointer(), 00570 TD->getPointerSize(0)); 00571 } 00572 Stubs.clear(); 00573 } 00574 } 00575 } 00576 00577 //===----------------------------------------------------------------------===// 00578 // Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 00579 // FIXME: 00580 // The following seem like one-off assembler flags, but they actually need 00581 // to appear in the .ARM.attributes section in ELF. 00582 // Instead of subclassing the MCELFStreamer, we do the work here. 00583 00584 static ARMBuildAttrs::CPUArch getArchForCPU(StringRef CPU, 00585 const ARMSubtarget *Subtarget) { 00586 if (CPU == "xscale") 00587 return ARMBuildAttrs::v5TEJ; 00588 00589 if (Subtarget->hasV8Ops()) 00590 return ARMBuildAttrs::v8; 00591 else if (Subtarget->hasV7Ops()) { 00592 if (Subtarget->isMClass() && Subtarget->hasThumb2DSP()) 00593 return ARMBuildAttrs::v7E_M; 00594 return ARMBuildAttrs::v7; 00595 } else if (Subtarget->hasV6T2Ops()) 00596 return ARMBuildAttrs::v6T2; 00597 else if (Subtarget->hasV6MOps()) 00598 return ARMBuildAttrs::v6S_M; 00599 else if (Subtarget->hasV6Ops()) 00600 return ARMBuildAttrs::v6; 00601 else if (Subtarget->hasV5TEOps()) 00602 return ARMBuildAttrs::v5TE; 00603 else if (Subtarget->hasV5TOps()) 00604 return ARMBuildAttrs::v5T; 00605 else if (Subtarget->hasV4TOps()) 00606 return ARMBuildAttrs::v4T; 00607 else 00608 return ARMBuildAttrs::v4; 00609 } 00610 00611 void ARMAsmPrinter::emitAttributes() { 00612 MCTargetStreamer &TS = *OutStreamer.getTargetStreamer(); 00613 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 00614 00615 ATS.switchVendor("aeabi"); 00616 00617 std::string CPUString = Subtarget->getCPUString(); 00618 00619 // FIXME: remove krait check when GNU tools support krait cpu 00620 if (CPUString != "generic" && CPUString != "krait") 00621 ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString); 00622 00623 ATS.emitAttribute(ARMBuildAttrs::CPU_arch, 00624 getArchForCPU(CPUString, Subtarget)); 00625 00626 // Tag_CPU_arch_profile must have the default value of 0 when "Architecture 00627 // profile is not applicable (e.g. pre v7, or cross-profile code)". 00628 if (Subtarget->hasV7Ops()) { 00629 if (Subtarget->isAClass()) { 00630 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile, 00631 ARMBuildAttrs::ApplicationProfile); 00632 } else if (Subtarget->isRClass()) { 00633 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile, 00634 ARMBuildAttrs::RealTimeProfile); 00635 } else if (Subtarget->isMClass()) { 00636 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile, 00637 ARMBuildAttrs::MicroControllerProfile); 00638 } 00639 } 00640 00641 ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget->hasARMOps() ? 00642 ARMBuildAttrs::Allowed : ARMBuildAttrs::Not_Allowed); 00643 if (Subtarget->isThumb1Only()) { 00644 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use, 00645 ARMBuildAttrs::Allowed); 00646 } else if (Subtarget->hasThumb2()) { 00647 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use, 00648 ARMBuildAttrs::AllowThumb32); 00649 } 00650 00651 if (Subtarget->hasNEON()) { 00652 /* NEON is not exactly a VFP architecture, but GAS emit one of 00653 * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */ 00654 if (Subtarget->hasFPARMv8()) { 00655 if (Subtarget->hasCrypto()) 00656 ATS.emitFPU(ARM::CRYPTO_NEON_FP_ARMV8); 00657 else 00658 ATS.emitFPU(ARM::NEON_FP_ARMV8); 00659 } 00660 else if (Subtarget->hasVFP4()) 00661 ATS.emitFPU(ARM::NEON_VFPV4); 00662 else 00663 ATS.emitFPU(ARM::NEON); 00664 // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture 00665 if (Subtarget->hasV8Ops()) 00666 ATS.emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 00667 ARMBuildAttrs::AllowNeonARMv8); 00668 } else { 00669 if (Subtarget->hasFPARMv8()) 00670 ATS.emitFPU(ARM::FP_ARMV8); 00671 else if (Subtarget->hasVFP4()) 00672 ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV4_D16 : ARM::VFPV4); 00673 else if (Subtarget->hasVFP3()) 00674 ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV3_D16 : ARM::VFPV3); 00675 else if (Subtarget->hasVFP2()) 00676 ATS.emitFPU(ARM::VFPV2); 00677 } 00678 00679 if (TM.getRelocationModel() == Reloc::PIC_) { 00680 // PIC specific attributes. 00681 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RW_data, 00682 ARMBuildAttrs::AddressRWPCRel); 00683 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RO_data, 00684 ARMBuildAttrs::AddressROPCRel); 00685 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use, 00686 ARMBuildAttrs::AddressGOT); 00687 } else { 00688 // Allow direct addressing of imported data for all other relocation models. 00689 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use, 00690 ARMBuildAttrs::AddressDirect); 00691 } 00692 00693 // Signal various FP modes. 00694 if (!TM.Options.UnsafeFPMath) { 00695 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::Allowed); 00696 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 00697 ARMBuildAttrs::Allowed); 00698 } 00699 00700 if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath) 00701 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 00702 ARMBuildAttrs::Allowed); 00703 else 00704 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 00705 ARMBuildAttrs::AllowIEE754); 00706 00707 // FIXME: add more flags to ARMBuildAttributes.h 00708 // 8-bytes alignment stuff. 00709 ATS.emitAttribute(ARMBuildAttrs::ABI_align_needed, 1); 00710 ATS.emitAttribute(ARMBuildAttrs::ABI_align_preserved, 1); 00711 00712 // ABI_HardFP_use attribute to indicate single precision FP. 00713 if (Subtarget->isFPOnlySP()) 00714 ATS.emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 00715 ARMBuildAttrs::HardFPSinglePrecision); 00716 00717 // Hard float. Use both S and D registers and conform to AAPCS-VFP. 00718 if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard) 00719 ATS.emitAttribute(ARMBuildAttrs::ABI_VFP_args, ARMBuildAttrs::HardFPAAPCS); 00720 00721 // FIXME: Should we signal R9 usage? 00722 00723 if (Subtarget->hasFP16()) 00724 ATS.emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP); 00725 00726 if (Subtarget->hasMPExtension()) 00727 ATS.emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP); 00728 00729 // Hardware divide in ARM mode is part of base arch, starting from ARMv8. 00730 // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M). 00731 // It is not possible to produce DisallowDIV: if hwdiv is present in the base 00732 // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits. 00733 // AllowDIVExt is only emitted if hwdiv isn't available in the base arch; 00734 // otherwise, the default value (AllowDIVIfExists) applies. 00735 if (Subtarget->hasDivideInARMMode() && !Subtarget->hasV8Ops()) 00736 ATS.emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt); 00737 00738 if (MMI) { 00739 if (const Module *SourceModule = MMI->getModule()) { 00740 // ABI_PCS_wchar_t to indicate wchar_t width 00741 // FIXME: There is no way to emit value 0 (wchar_t prohibited). 00742 if (auto WCharWidthValue = cast_or_null<ConstantInt>( 00743 SourceModule->getModuleFlag("wchar_size"))) { 00744 int WCharWidth = WCharWidthValue->getZExtValue(); 00745 assert((WCharWidth == 2 || WCharWidth == 4) && 00746 "wchar_t width must be 2 or 4 bytes"); 00747 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_wchar_t, WCharWidth); 00748 } 00749 00750 // ABI_enum_size to indicate enum width 00751 // FIXME: There is no way to emit value 0 (enums prohibited) or value 3 00752 // (all enums contain a value needing 32 bits to encode). 00753 if (auto EnumWidthValue = cast_or_null<ConstantInt>( 00754 SourceModule->getModuleFlag("min_enum_size"))) { 00755 int EnumWidth = EnumWidthValue->getZExtValue(); 00756 assert((EnumWidth == 1 || EnumWidth == 4) && 00757 "Minimum enum width must be 1 or 4 bytes"); 00758 int EnumBuildAttr = EnumWidth == 1 ? 1 : 2; 00759 ATS.emitAttribute(ARMBuildAttrs::ABI_enum_size, EnumBuildAttr); 00760 } 00761 } 00762 } 00763 00764 // TODO: We currently only support either reserving the register, or treating 00765 // it as another callee-saved register, but not as SB or a TLS pointer; It 00766 // would instead be nicer to push this from the frontend as metadata, as we do 00767 // for the wchar and enum size tags 00768 if (Subtarget->isR9Reserved()) 00769 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, 00770 ARMBuildAttrs::R9Reserved); 00771 else 00772 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, 00773 ARMBuildAttrs::R9IsGPR); 00774 00775 if (Subtarget->hasTrustZone() && Subtarget->hasVirtualization()) 00776 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, 00777 ARMBuildAttrs::AllowTZVirtualization); 00778 else if (Subtarget->hasTrustZone()) 00779 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, 00780 ARMBuildAttrs::AllowTZ); 00781 else if (Subtarget->hasVirtualization()) 00782 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, 00783 ARMBuildAttrs::AllowVirtualization); 00784 00785 ATS.finishAttributeSection(); 00786 } 00787 00788 //===----------------------------------------------------------------------===// 00789 00790 static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 00791 unsigned LabelId, MCContext &Ctx) { 00792 00793 MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 00794 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 00795 return Label; 00796 } 00797 00798 static MCSymbolRefExpr::VariantKind 00799 getModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 00800 switch (Modifier) { 00801 case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 00802 case ARMCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; 00803 case ARMCP::TPOFF: return MCSymbolRefExpr::VK_TPOFF; 00804 case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_GOTTPOFF; 00805 case ARMCP::GOT: return MCSymbolRefExpr::VK_GOT; 00806 case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_GOTOFF; 00807 } 00808 llvm_unreachable("Invalid ARMCPModifier!"); 00809 } 00810 00811 MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV, 00812 unsigned char TargetFlags) { 00813 if (Subtarget->isTargetMachO()) { 00814 bool IsIndirect = (TargetFlags & ARMII::MO_NONLAZY) && 00815 Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 00816 00817 if (!IsIndirect) 00818 return getSymbol(GV); 00819 00820 // FIXME: Remove this when Darwin transition to @GOT like syntax. 00821 MCSymbol *MCSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 00822 MachineModuleInfoMachO &MMIMachO = 00823 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 00824 MachineModuleInfoImpl::StubValueTy &StubSym = 00825 GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) 00826 : MMIMachO.getGVStubEntry(MCSym); 00827 if (!StubSym.getPointer()) 00828 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV), 00829 !GV->hasInternalLinkage()); 00830 return MCSym; 00831 } else if (Subtarget->isTargetCOFF()) { 00832 assert(Subtarget->isTargetWindows() && 00833 "Windows is the only supported COFF target"); 00834 00835 bool IsIndirect = (TargetFlags & ARMII::MO_DLLIMPORT); 00836 if (!IsIndirect) 00837 return getSymbol(GV); 00838 00839 SmallString<128> Name; 00840 Name = "__imp_"; 00841 getNameWithPrefix(Name, GV); 00842 00843 return OutContext.GetOrCreateSymbol(Name); 00844 } else if (Subtarget->isTargetELF()) { 00845 return getSymbol(GV); 00846 } 00847 llvm_unreachable("unexpected target"); 00848 } 00849 00850 void ARMAsmPrinter:: 00851 EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 00852 const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); 00853 int Size = 00854 TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(MCPV->getType()); 00855 00856 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 00857 00858 MCSymbol *MCSym; 00859 if (ACPV->isLSDA()) { 00860 SmallString<128> Str; 00861 raw_svector_ostream OS(Str); 00862 OS << DL->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 00863 MCSym = OutContext.GetOrCreateSymbol(OS.str()); 00864 } else if (ACPV->isBlockAddress()) { 00865 const BlockAddress *BA = 00866 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(); 00867 MCSym = GetBlockAddressSymbol(BA); 00868 } else if (ACPV->isGlobalValue()) { 00869 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV(); 00870 00871 // On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so 00872 // flag the global as MO_NONLAZY. 00873 unsigned char TF = Subtarget->isTargetMachO() ? ARMII::MO_NONLAZY : 0; 00874 MCSym = GetARMGVSymbol(GV, TF); 00875 } else if (ACPV->isMachineBasicBlock()) { 00876 const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB(); 00877 MCSym = MBB->getSymbol(); 00878 } else { 00879 assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 00880 const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(); 00881 MCSym = GetExternalSymbolSymbol(Sym); 00882 } 00883 00884 // Create an MCSymbol for the reference. 00885 const MCExpr *Expr = 00886 MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 00887 OutContext); 00888 00889 if (ACPV->getPCAdjustment()) { 00890 MCSymbol *PCLabel = getPICLabel(DL->getPrivateGlobalPrefix(), 00891 getFunctionNumber(), 00892 ACPV->getLabelId(), 00893 OutContext); 00894 const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 00895 PCRelExpr = 00896 MCBinaryExpr::CreateAdd(PCRelExpr, 00897 MCConstantExpr::Create(ACPV->getPCAdjustment(), 00898 OutContext), 00899 OutContext); 00900 if (ACPV->mustAddCurrentAddress()) { 00901 // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 00902 // label, so just emit a local label end reference that instead. 00903 MCSymbol *DotSym = OutContext.CreateTempSymbol(); 00904 OutStreamer.EmitLabel(DotSym); 00905 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 00906 PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 00907 } 00908 Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 00909 } 00910 OutStreamer.EmitValue(Expr, Size); 00911 } 00912 00913 void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 00914 unsigned Opcode = MI->getOpcode(); 00915 int OpNum = 1; 00916 if (Opcode == ARM::BR_JTadd) 00917 OpNum = 2; 00918 else if (Opcode == ARM::BR_JTm) 00919 OpNum = 3; 00920 00921 const MachineOperand &MO1 = MI->getOperand(OpNum); 00922 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 00923 unsigned JTI = MO1.getIndex(); 00924 00925 // Emit a label for the jump table. 00926 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 00927 OutStreamer.EmitLabel(JTISymbol); 00928 00929 // Mark the jump table as data-in-code. 00930 OutStreamer.EmitDataRegion(MCDR_DataRegionJT32); 00931 00932 // Emit each entry of the table. 00933 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 00934 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 00935 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 00936 00937 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 00938 MachineBasicBlock *MBB = JTBBs[i]; 00939 // Construct an MCExpr for the entry. We want a value of the form: 00940 // (BasicBlockAddr - TableBeginAddr) 00941 // 00942 // For example, a table with entries jumping to basic blocks BB0 and BB1 00943 // would look like: 00944 // LJTI_0_0: 00945 // .word (LBB0 - LJTI_0_0) 00946 // .word (LBB1 - LJTI_0_0) 00947 const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 00948 00949 if (TM.getRelocationModel() == Reloc::PIC_) 00950 Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 00951 OutContext), 00952 OutContext); 00953 // If we're generating a table of Thumb addresses in static relocation 00954 // model, we need to add one to keep interworking correctly. 00955 else if (AFI->isThumbFunction()) 00956 Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext), 00957 OutContext); 00958 OutStreamer.EmitValue(Expr, 4); 00959 } 00960 // Mark the end of jump table data-in-code region. 00961 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 00962 } 00963 00964 void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 00965 unsigned Opcode = MI->getOpcode(); 00966 int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 00967 const MachineOperand &MO1 = MI->getOperand(OpNum); 00968 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 00969 unsigned JTI = MO1.getIndex(); 00970 00971 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 00972 OutStreamer.EmitLabel(JTISymbol); 00973 00974 // Emit each entry of the table. 00975 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 00976 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 00977 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 00978 unsigned OffsetWidth = 4; 00979 if (MI->getOpcode() == ARM::t2TBB_JT) { 00980 OffsetWidth = 1; 00981 // Mark the jump table as data-in-code. 00982 OutStreamer.EmitDataRegion(MCDR_DataRegionJT8); 00983 } else if (MI->getOpcode() == ARM::t2TBH_JT) { 00984 OffsetWidth = 2; 00985 // Mark the jump table as data-in-code. 00986 OutStreamer.EmitDataRegion(MCDR_DataRegionJT16); 00987 } 00988 00989 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 00990 MachineBasicBlock *MBB = JTBBs[i]; 00991 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 00992 OutContext); 00993 // If this isn't a TBB or TBH, the entries are direct branch instructions. 00994 if (OffsetWidth == 4) { 00995 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2B) 00996 .addExpr(MBBSymbolExpr) 00997 .addImm(ARMCC::AL) 00998 .addReg(0)); 00999 continue; 01000 } 01001 // Otherwise it's an offset from the dispatch instruction. Construct an 01002 // MCExpr for the entry. We want a value of the form: 01003 // (BasicBlockAddr - TableBeginAddr) / 2 01004 // 01005 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 01006 // would look like: 01007 // LJTI_0_0: 01008 // .byte (LBB0 - LJTI_0_0) / 2 01009 // .byte (LBB1 - LJTI_0_0) / 2 01010 const MCExpr *Expr = 01011 MCBinaryExpr::CreateSub(MBBSymbolExpr, 01012 MCSymbolRefExpr::Create(JTISymbol, OutContext), 01013 OutContext); 01014 Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 01015 OutContext); 01016 OutStreamer.EmitValue(Expr, OffsetWidth); 01017 } 01018 // Mark the end of jump table data-in-code region. 32-bit offsets use 01019 // actual branch instructions here, so we don't mark those as a data-region 01020 // at all. 01021 if (OffsetWidth != 4) 01022 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 01023 } 01024 01025 void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { 01026 assert(MI->getFlag(MachineInstr::FrameSetup) && 01027 "Only instruction which are involved into frame setup code are allowed"); 01028 01029 MCTargetStreamer &TS = *OutStreamer.getTargetStreamer(); 01030 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 01031 const MachineFunction &MF = *MI->getParent()->getParent(); 01032 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 01033 const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); 01034 01035 unsigned FramePtr = RegInfo->getFrameRegister(MF); 01036 unsigned Opc = MI->getOpcode(); 01037 unsigned SrcReg, DstReg; 01038 01039 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { 01040 // Two special cases: 01041 // 1) tPUSH does not have src/dst regs. 01042 // 2) for Thumb1 code we sometimes materialize the constant via constpool 01043 // load. Yes, this is pretty fragile, but for now I don't see better 01044 // way... :( 01045 SrcReg = DstReg = ARM::SP; 01046 } else { 01047 SrcReg = MI->getOperand(1).getReg(); 01048 DstReg = MI->getOperand(0).getReg(); 01049 } 01050 01051 // Try to figure out the unwinding opcode out of src / dst regs. 01052 if (MI->mayStore()) { 01053 // Register saves. 01054 assert(DstReg == ARM::SP && 01055 "Only stack pointer as a destination reg is supported"); 01056 01057 SmallVector<unsigned, 4> RegList; 01058 // Skip src & dst reg, and pred ops. 01059 unsigned StartOp = 2 + 2; 01060 // Use all the operands. 01061 unsigned NumOffset = 0; 01062 01063 switch (Opc) { 01064 default: 01065 MI->dump(); 01066 llvm_unreachable("Unsupported opcode for unwinding information"); 01067 case ARM::tPUSH: 01068 // Special case here: no src & dst reg, but two extra imp ops. 01069 StartOp = 2; NumOffset = 2; 01070 case ARM::STMDB_UPD: 01071 case ARM::t2STMDB_UPD: 01072 case ARM::VSTMDDB_UPD: 01073 assert(SrcReg == ARM::SP && 01074 "Only stack pointer as a source reg is supported"); 01075 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset; 01076 i != NumOps; ++i) { 01077 const MachineOperand &MO = MI->getOperand(i); 01078 // Actually, there should never be any impdef stuff here. Skip it 01079 // temporary to workaround PR11902. 01080 if (MO.isImplicit()) 01081 continue; 01082 RegList.push_back(MO.getReg()); 01083 } 01084 break; 01085 case ARM::STR_PRE_IMM: 01086 case ARM::STR_PRE_REG: 01087 case ARM::t2STR_PRE: 01088 assert(MI->getOperand(2).getReg() == ARM::SP && 01089 "Only stack pointer as a source reg is supported"); 01090 RegList.push_back(SrcReg); 01091 break; 01092 } 01093 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) 01094 ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); 01095 } else { 01096 // Changes of stack / frame pointer. 01097 if (SrcReg == ARM::SP) { 01098 int64_t Offset = 0; 01099 switch (Opc) { 01100 default: 01101 MI->dump(); 01102 llvm_unreachable("Unsupported opcode for unwinding information"); 01103 case ARM::MOVr: 01104 case ARM::tMOVr: 01105 Offset = 0; 01106 break; 01107 case ARM::ADDri: 01108 Offset = -MI->getOperand(2).getImm(); 01109 break; 01110 case ARM::SUBri: 01111 case ARM::t2SUBri: 01112 Offset = MI->getOperand(2).getImm(); 01113 break; 01114 case ARM::tSUBspi: 01115 Offset = MI->getOperand(2).getImm()*4; 01116 break; 01117 case ARM::tADDspi: 01118 case ARM::tADDrSPi: 01119 Offset = -MI->getOperand(2).getImm()*4; 01120 break; 01121 case ARM::tLDRpci: { 01122 // Grab the constpool index and check, whether it corresponds to 01123 // original or cloned constpool entry. 01124 unsigned CPI = MI->getOperand(1).getIndex(); 01125 const MachineConstantPool *MCP = MF.getConstantPool(); 01126 if (CPI >= MCP->getConstants().size()) 01127 CPI = AFI.getOriginalCPIdx(CPI); 01128 assert(CPI != -1U && "Invalid constpool index"); 01129 01130 // Derive the actual offset. 01131 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; 01132 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); 01133 // FIXME: Check for user, it should be "add" instruction! 01134 Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue(); 01135 break; 01136 } 01137 } 01138 01139 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) { 01140 if (DstReg == FramePtr && FramePtr != ARM::SP) 01141 // Set-up of the frame pointer. Positive values correspond to "add" 01142 // instruction. 01143 ATS.emitSetFP(FramePtr, ARM::SP, -Offset); 01144 else if (DstReg == ARM::SP) { 01145 // Change of SP by an offset. Positive values correspond to "sub" 01146 // instruction. 01147 ATS.emitPad(Offset); 01148 } else { 01149 // Move of SP to a register. Positive values correspond to an "add" 01150 // instruction. 01151 ATS.emitMovSP(DstReg, -Offset); 01152 } 01153 } 01154 } else if (DstReg == ARM::SP) { 01155 MI->dump(); 01156 llvm_unreachable("Unsupported opcode for unwinding information"); 01157 } 01158 else { 01159 MI->dump(); 01160 llvm_unreachable("Unsupported opcode for unwinding information"); 01161 } 01162 } 01163 } 01164 01165 // Simple pseudo-instructions have their lowering (with expansion to real 01166 // instructions) auto-generated. 01167 #include "ARMGenMCPseudoLowering.inc" 01168 01169 void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 01170 const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); 01171 01172 // If we just ended a constant pool, mark it as such. 01173 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) { 01174 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 01175 InConstantPool = false; 01176 } 01177 01178 // Emit unwinding stuff for frame-related instructions 01179 if (Subtarget->isTargetEHABICompatible() && 01180 MI->getFlag(MachineInstr::FrameSetup)) 01181 EmitUnwindingInstruction(MI); 01182 01183 // Do any auto-generated pseudo lowerings. 01184 if (emitPseudoExpansionLowering(OutStreamer, MI)) 01185 return; 01186 01187 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) && 01188 "Pseudo flag setting opcode should be expanded early"); 01189 01190 // Check for manual lowerings. 01191 unsigned Opc = MI->getOpcode(); 01192 switch (Opc) { 01193 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass"); 01194 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing"); 01195 case ARM::LEApcrel: 01196 case ARM::tLEApcrel: 01197 case ARM::t2LEApcrel: { 01198 // FIXME: Need to also handle globals and externals 01199 MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex()); 01200 EmitToStreamer(OutStreamer, MCInstBuilder(MI->getOpcode() == 01201 ARM::t2LEApcrel ? ARM::t2ADR 01202 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 01203 : ARM::ADR)) 01204 .addReg(MI->getOperand(0).getReg()) 01205 .addExpr(MCSymbolRefExpr::Create(CPISymbol, OutContext)) 01206 // Add predicate operands. 01207 .addImm(MI->getOperand(2).getImm()) 01208 .addReg(MI->getOperand(3).getReg())); 01209 return; 01210 } 01211 case ARM::LEApcrelJT: 01212 case ARM::tLEApcrelJT: 01213 case ARM::t2LEApcrelJT: { 01214 MCSymbol *JTIPICSymbol = 01215 GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 01216 MI->getOperand(2).getImm()); 01217 EmitToStreamer(OutStreamer, MCInstBuilder(MI->getOpcode() == 01218 ARM::t2LEApcrelJT ? ARM::t2ADR 01219 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 01220 : ARM::ADR)) 01221 .addReg(MI->getOperand(0).getReg()) 01222 .addExpr(MCSymbolRefExpr::Create(JTIPICSymbol, OutContext)) 01223 // Add predicate operands. 01224 .addImm(MI->getOperand(3).getImm()) 01225 .addReg(MI->getOperand(4).getReg())); 01226 return; 01227 } 01228 // Darwin call instructions are just normal call instructions with different 01229 // clobber semantics (they clobber R9). 01230 case ARM::BX_CALL: { 01231 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 01232 .addReg(ARM::LR) 01233 .addReg(ARM::PC) 01234 // Add predicate operands. 01235 .addImm(ARMCC::AL) 01236 .addReg(0) 01237 // Add 's' bit operand (always reg0 for this) 01238 .addReg(0)); 01239 01240 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::BX) 01241 .addReg(MI->getOperand(0).getReg())); 01242 return; 01243 } 01244 case ARM::tBX_CALL: { 01245 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 01246 .addReg(ARM::LR) 01247 .addReg(ARM::PC) 01248 // Add predicate operands. 01249 .addImm(ARMCC::AL) 01250 .addReg(0)); 01251 01252 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX) 01253 .addReg(MI->getOperand(0).getReg()) 01254 // Add predicate operands. 01255 .addImm(ARMCC::AL) 01256 .addReg(0)); 01257 return; 01258 } 01259 case ARM::BMOVPCRX_CALL: { 01260 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 01261 .addReg(ARM::LR) 01262 .addReg(ARM::PC) 01263 // Add predicate operands. 01264 .addImm(ARMCC::AL) 01265 .addReg(0) 01266 // Add 's' bit operand (always reg0 for this) 01267 .addReg(0)); 01268 01269 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 01270 .addReg(ARM::PC) 01271 .addReg(MI->getOperand(0).getReg()) 01272 // Add predicate operands. 01273 .addImm(ARMCC::AL) 01274 .addReg(0) 01275 // Add 's' bit operand (always reg0 for this) 01276 .addReg(0)); 01277 return; 01278 } 01279 case ARM::BMOVPCB_CALL: { 01280 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr) 01281 .addReg(ARM::LR) 01282 .addReg(ARM::PC) 01283 // Add predicate operands. 01284 .addImm(ARMCC::AL) 01285 .addReg(0) 01286 // Add 's' bit operand (always reg0 for this) 01287 .addReg(0)); 01288 01289 const MachineOperand &Op = MI->getOperand(0); 01290 const GlobalValue *GV = Op.getGlobal(); 01291 const unsigned TF = Op.getTargetFlags(); 01292 MCSymbol *GVSym = GetARMGVSymbol(GV, TF); 01293 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 01294 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::Bcc) 01295 .addExpr(GVSymExpr) 01296 // Add predicate operands. 01297 .addImm(ARMCC::AL) 01298 .addReg(0)); 01299 return; 01300 } 01301 case ARM::MOVi16_ga_pcrel: 01302 case ARM::t2MOVi16_ga_pcrel: { 01303 MCInst TmpInst; 01304 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 01305 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01306 01307 unsigned TF = MI->getOperand(1).getTargetFlags(); 01308 const GlobalValue *GV = MI->getOperand(1).getGlobal(); 01309 MCSymbol *GVSym = GetARMGVSymbol(GV, TF); 01310 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 01311 01312 MCSymbol *LabelSym = getPICLabel(DL->getPrivateGlobalPrefix(), 01313 getFunctionNumber(), 01314 MI->getOperand(2).getImm(), OutContext); 01315 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 01316 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 01317 const MCExpr *PCRelExpr = 01318 ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 01319 MCBinaryExpr::CreateAdd(LabelSymExpr, 01320 MCConstantExpr::Create(PCAdj, OutContext), 01321 OutContext), OutContext), OutContext); 01322 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 01323 01324 // Add predicate operands. 01325 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 01326 TmpInst.addOperand(MCOperand::CreateReg(0)); 01327 // Add 's' bit operand (always reg0 for this) 01328 TmpInst.addOperand(MCOperand::CreateReg(0)); 01329 EmitToStreamer(OutStreamer, TmpInst); 01330 return; 01331 } 01332 case ARM::MOVTi16_ga_pcrel: 01333 case ARM::t2MOVTi16_ga_pcrel: { 01334 MCInst TmpInst; 01335 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 01336 ? ARM::MOVTi16 : ARM::t2MOVTi16); 01337 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01338 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 01339 01340 unsigned TF = MI->getOperand(2).getTargetFlags(); 01341 const GlobalValue *GV = MI->getOperand(2).getGlobal(); 01342 MCSymbol *GVSym = GetARMGVSymbol(GV, TF); 01343 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 01344 01345 MCSymbol *LabelSym = getPICLabel(DL->getPrivateGlobalPrefix(), 01346 getFunctionNumber(), 01347 MI->getOperand(3).getImm(), OutContext); 01348 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 01349 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 01350 const MCExpr *PCRelExpr = 01351 ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 01352 MCBinaryExpr::CreateAdd(LabelSymExpr, 01353 MCConstantExpr::Create(PCAdj, OutContext), 01354 OutContext), OutContext), OutContext); 01355 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 01356 // Add predicate operands. 01357 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 01358 TmpInst.addOperand(MCOperand::CreateReg(0)); 01359 // Add 's' bit operand (always reg0 for this) 01360 TmpInst.addOperand(MCOperand::CreateReg(0)); 01361 EmitToStreamer(OutStreamer, TmpInst); 01362 return; 01363 } 01364 case ARM::tPICADD: { 01365 // This is a pseudo op for a label + instruction sequence, which looks like: 01366 // LPC0: 01367 // add r0, pc 01368 // This adds the address of LPC0 to r0. 01369 01370 // Emit the label. 01371 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(), 01372 getFunctionNumber(), MI->getOperand(2).getImm(), 01373 OutContext)); 01374 01375 // Form and emit the add. 01376 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tADDhirr) 01377 .addReg(MI->getOperand(0).getReg()) 01378 .addReg(MI->getOperand(0).getReg()) 01379 .addReg(ARM::PC) 01380 // Add predicate operands. 01381 .addImm(ARMCC::AL) 01382 .addReg(0)); 01383 return; 01384 } 01385 case ARM::PICADD: { 01386 // This is a pseudo op for a label + instruction sequence, which looks like: 01387 // LPC0: 01388 // add r0, pc, r0 01389 // This adds the address of LPC0 to r0. 01390 01391 // Emit the label. 01392 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(), 01393 getFunctionNumber(), MI->getOperand(2).getImm(), 01394 OutContext)); 01395 01396 // Form and emit the add. 01397 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDrr) 01398 .addReg(MI->getOperand(0).getReg()) 01399 .addReg(ARM::PC) 01400 .addReg(MI->getOperand(1).getReg()) 01401 // Add predicate operands. 01402 .addImm(MI->getOperand(3).getImm()) 01403 .addReg(MI->getOperand(4).getReg()) 01404 // Add 's' bit operand (always reg0 for this) 01405 .addReg(0)); 01406 return; 01407 } 01408 case ARM::PICSTR: 01409 case ARM::PICSTRB: 01410 case ARM::PICSTRH: 01411 case ARM::PICLDR: 01412 case ARM::PICLDRB: 01413 case ARM::PICLDRH: 01414 case ARM::PICLDRSB: 01415 case ARM::PICLDRSH: { 01416 // This is a pseudo op for a label + instruction sequence, which looks like: 01417 // LPC0: 01418 // OP r0, [pc, r0] 01419 // The LCP0 label is referenced by a constant pool entry in order to get 01420 // a PC-relative address at the ldr instruction. 01421 01422 // Emit the label. 01423 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(), 01424 getFunctionNumber(), MI->getOperand(2).getImm(), 01425 OutContext)); 01426 01427 // Form and emit the load 01428 unsigned Opcode; 01429 switch (MI->getOpcode()) { 01430 default: 01431 llvm_unreachable("Unexpected opcode!"); 01432 case ARM::PICSTR: Opcode = ARM::STRrs; break; 01433 case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 01434 case ARM::PICSTRH: Opcode = ARM::STRH; break; 01435 case ARM::PICLDR: Opcode = ARM::LDRrs; break; 01436 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 01437 case ARM::PICLDRH: Opcode = ARM::LDRH; break; 01438 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 01439 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 01440 } 01441 EmitToStreamer(OutStreamer, MCInstBuilder(Opcode) 01442 .addReg(MI->getOperand(0).getReg()) 01443 .addReg(ARM::PC) 01444 .addReg(MI->getOperand(1).getReg()) 01445 .addImm(0) 01446 // Add predicate operands. 01447 .addImm(MI->getOperand(3).getImm()) 01448 .addReg(MI->getOperand(4).getReg())); 01449 01450 return; 01451 } 01452 case ARM::CONSTPOOL_ENTRY: { 01453 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 01454 /// in the function. The first operand is the ID# for this instruction, the 01455 /// second is the index into the MachineConstantPool that this is, the third 01456 /// is the size in bytes of this constant pool entry. 01457 /// The required alignment is specified on the basic block holding this MI. 01458 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 01459 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 01460 01461 // If this is the first entry of the pool, mark it. 01462 if (!InConstantPool) { 01463 OutStreamer.EmitDataRegion(MCDR_DataRegion); 01464 InConstantPool = true; 01465 } 01466 01467 OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 01468 01469 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 01470 if (MCPE.isMachineConstantPoolEntry()) 01471 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 01472 else 01473 EmitGlobalConstant(MCPE.Val.ConstVal); 01474 return; 01475 } 01476 case ARM::t2BR_JT: { 01477 // Lower and emit the instruction itself, then the jump table following it. 01478 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 01479 .addReg(ARM::PC) 01480 .addReg(MI->getOperand(0).getReg()) 01481 // Add predicate operands. 01482 .addImm(ARMCC::AL) 01483 .addReg(0)); 01484 01485 // Output the data for the jump table itself 01486 EmitJump2Table(MI); 01487 return; 01488 } 01489 case ARM::t2TBB_JT: { 01490 // Lower and emit the instruction itself, then the jump table following it. 01491 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2TBB) 01492 .addReg(ARM::PC) 01493 .addReg(MI->getOperand(0).getReg()) 01494 // Add predicate operands. 01495 .addImm(ARMCC::AL) 01496 .addReg(0)); 01497 01498 // Output the data for the jump table itself 01499 EmitJump2Table(MI); 01500 // Make sure the next instruction is 2-byte aligned. 01501 EmitAlignment(1); 01502 return; 01503 } 01504 case ARM::t2TBH_JT: { 01505 // Lower and emit the instruction itself, then the jump table following it. 01506 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2TBH) 01507 .addReg(ARM::PC) 01508 .addReg(MI->getOperand(0).getReg()) 01509 // Add predicate operands. 01510 .addImm(ARMCC::AL) 01511 .addReg(0)); 01512 01513 // Output the data for the jump table itself 01514 EmitJump2Table(MI); 01515 return; 01516 } 01517 case ARM::tBR_JTr: 01518 case ARM::BR_JTr: { 01519 // Lower and emit the instruction itself, then the jump table following it. 01520 // mov pc, target 01521 MCInst TmpInst; 01522 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 01523 ARM::MOVr : ARM::tMOVr; 01524 TmpInst.setOpcode(Opc); 01525 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 01526 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01527 // Add predicate operands. 01528 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 01529 TmpInst.addOperand(MCOperand::CreateReg(0)); 01530 // Add 's' bit operand (always reg0 for this) 01531 if (Opc == ARM::MOVr) 01532 TmpInst.addOperand(MCOperand::CreateReg(0)); 01533 EmitToStreamer(OutStreamer, TmpInst); 01534 01535 // Make sure the Thumb jump table is 4-byte aligned. 01536 if (Opc == ARM::tMOVr) 01537 EmitAlignment(2); 01538 01539 // Output the data for the jump table itself 01540 EmitJumpTable(MI); 01541 return; 01542 } 01543 case ARM::BR_JTm: { 01544 // Lower and emit the instruction itself, then the jump table following it. 01545 // ldr pc, target 01546 MCInst TmpInst; 01547 if (MI->getOperand(1).getReg() == 0) { 01548 // literal offset 01549 TmpInst.setOpcode(ARM::LDRi12); 01550 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 01551 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01552 TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 01553 } else { 01554 TmpInst.setOpcode(ARM::LDRrs); 01555 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 01556 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01557 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 01558 TmpInst.addOperand(MCOperand::CreateImm(0)); 01559 } 01560 // Add predicate operands. 01561 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 01562 TmpInst.addOperand(MCOperand::CreateReg(0)); 01563 EmitToStreamer(OutStreamer, TmpInst); 01564 01565 // Output the data for the jump table itself 01566 EmitJumpTable(MI); 01567 return; 01568 } 01569 case ARM::BR_JTadd: { 01570 // Lower and emit the instruction itself, then the jump table following it. 01571 // add pc, target, idx 01572 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDrr) 01573 .addReg(ARM::PC) 01574 .addReg(MI->getOperand(0).getReg()) 01575 .addReg(MI->getOperand(1).getReg()) 01576 // Add predicate operands. 01577 .addImm(ARMCC::AL) 01578 .addReg(0) 01579 // Add 's' bit operand (always reg0 for this) 01580 .addReg(0)); 01581 01582 // Output the data for the jump table itself 01583 EmitJumpTable(MI); 01584 return; 01585 } 01586 case ARM::TRAP: { 01587 // Non-Darwin binutils don't yet support the "trap" mnemonic. 01588 // FIXME: Remove this special case when they do. 01589 if (!Subtarget->isTargetMachO()) { 01590 //.long 0xe7ffdefe @ trap 01591 uint32_t Val = 0xe7ffdefeUL; 01592 OutStreamer.AddComment("trap"); 01593 OutStreamer.EmitIntValue(Val, 4); 01594 return; 01595 } 01596 break; 01597 } 01598 case ARM::TRAPNaCl: { 01599 //.long 0xe7fedef0 @ trap 01600 uint32_t Val = 0xe7fedef0UL; 01601 OutStreamer.AddComment("trap"); 01602 OutStreamer.EmitIntValue(Val, 4); 01603 return; 01604 } 01605 case ARM::tTRAP: { 01606 // Non-Darwin binutils don't yet support the "trap" mnemonic. 01607 // FIXME: Remove this special case when they do. 01608 if (!Subtarget->isTargetMachO()) { 01609 //.short 57086 @ trap 01610 uint16_t Val = 0xdefe; 01611 OutStreamer.AddComment("trap"); 01612 OutStreamer.EmitIntValue(Val, 2); 01613 return; 01614 } 01615 break; 01616 } 01617 case ARM::t2Int_eh_sjlj_setjmp: 01618 case ARM::t2Int_eh_sjlj_setjmp_nofp: 01619 case ARM::tInt_eh_sjlj_setjmp: { 01620 // Two incoming args: GPR:$src, GPR:$val 01621 // mov $val, pc 01622 // adds $val, #7 01623 // str $val, [$src, #4] 01624 // movs r0, #0 01625 // b 1f 01626 // movs r0, #1 01627 // 1: 01628 unsigned SrcReg = MI->getOperand(0).getReg(); 01629 unsigned ValReg = MI->getOperand(1).getReg(); 01630 MCSymbol *Label = GetARMSJLJEHLabel(); 01631 OutStreamer.AddComment("eh_setjmp begin"); 01632 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 01633 .addReg(ValReg) 01634 .addReg(ARM::PC) 01635 // Predicate. 01636 .addImm(ARMCC::AL) 01637 .addReg(0)); 01638 01639 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tADDi3) 01640 .addReg(ValReg) 01641 // 's' bit operand 01642 .addReg(ARM::CPSR) 01643 .addReg(ValReg) 01644 .addImm(7) 01645 // Predicate. 01646 .addImm(ARMCC::AL) 01647 .addReg(0)); 01648 01649 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tSTRi) 01650 .addReg(ValReg) 01651 .addReg(SrcReg) 01652 // The offset immediate is #4. The operand value is scaled by 4 for the 01653 // tSTR instruction. 01654 .addImm(1) 01655 // Predicate. 01656 .addImm(ARMCC::AL) 01657 .addReg(0)); 01658 01659 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVi8) 01660 .addReg(ARM::R0) 01661 .addReg(ARM::CPSR) 01662 .addImm(0) 01663 // Predicate. 01664 .addImm(ARMCC::AL) 01665 .addReg(0)); 01666 01667 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 01668 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tB) 01669 .addExpr(SymbolExpr) 01670 .addImm(ARMCC::AL) 01671 .addReg(0)); 01672 01673 OutStreamer.AddComment("eh_setjmp end"); 01674 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVi8) 01675 .addReg(ARM::R0) 01676 .addReg(ARM::CPSR) 01677 .addImm(1) 01678 // Predicate. 01679 .addImm(ARMCC::AL) 01680 .addReg(0)); 01681 01682 OutStreamer.EmitLabel(Label); 01683 return; 01684 } 01685 01686 case ARM::Int_eh_sjlj_setjmp_nofp: 01687 case ARM::Int_eh_sjlj_setjmp: { 01688 // Two incoming args: GPR:$src, GPR:$val 01689 // add $val, pc, #8 01690 // str $val, [$src, #+4] 01691 // mov r0, #0 01692 // add pc, pc, #0 01693 // mov r0, #1 01694 unsigned SrcReg = MI->getOperand(0).getReg(); 01695 unsigned ValReg = MI->getOperand(1).getReg(); 01696 01697 OutStreamer.AddComment("eh_setjmp begin"); 01698 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDri) 01699 .addReg(ValReg) 01700 .addReg(ARM::PC) 01701 .addImm(8) 01702 // Predicate. 01703 .addImm(ARMCC::AL) 01704 .addReg(0) 01705 // 's' bit operand (always reg0 for this). 01706 .addReg(0)); 01707 01708 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::STRi12) 01709 .addReg(ValReg) 01710 .addReg(SrcReg) 01711 .addImm(4) 01712 // Predicate. 01713 .addImm(ARMCC::AL) 01714 .addReg(0)); 01715 01716 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVi) 01717 .addReg(ARM::R0) 01718 .addImm(0) 01719 // Predicate. 01720 .addImm(ARMCC::AL) 01721 .addReg(0) 01722 // 's' bit operand (always reg0 for this). 01723 .addReg(0)); 01724 01725 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDri) 01726 .addReg(ARM::PC) 01727 .addReg(ARM::PC) 01728 .addImm(0) 01729 // Predicate. 01730 .addImm(ARMCC::AL) 01731 .addReg(0) 01732 // 's' bit operand (always reg0 for this). 01733 .addReg(0)); 01734 01735 OutStreamer.AddComment("eh_setjmp end"); 01736 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVi) 01737 .addReg(ARM::R0) 01738 .addImm(1) 01739 // Predicate. 01740 .addImm(ARMCC::AL) 01741 .addReg(0) 01742 // 's' bit operand (always reg0 for this). 01743 .addReg(0)); 01744 return; 01745 } 01746 case ARM::Int_eh_sjlj_longjmp: { 01747 // ldr sp, [$src, #8] 01748 // ldr $scratch, [$src, #4] 01749 // ldr r7, [$src] 01750 // bx $scratch 01751 unsigned SrcReg = MI->getOperand(0).getReg(); 01752 unsigned ScratchReg = MI->getOperand(1).getReg(); 01753 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12) 01754 .addReg(ARM::SP) 01755 .addReg(SrcReg) 01756 .addImm(8) 01757 // Predicate. 01758 .addImm(ARMCC::AL) 01759 .addReg(0)); 01760 01761 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12) 01762 .addReg(ScratchReg) 01763 .addReg(SrcReg) 01764 .addImm(4) 01765 // Predicate. 01766 .addImm(ARMCC::AL) 01767 .addReg(0)); 01768 01769 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12) 01770 .addReg(ARM::R7) 01771 .addReg(SrcReg) 01772 .addImm(0) 01773 // Predicate. 01774 .addImm(ARMCC::AL) 01775 .addReg(0)); 01776 01777 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::BX) 01778 .addReg(ScratchReg) 01779 // Predicate. 01780 .addImm(ARMCC::AL) 01781 .addReg(0)); 01782 return; 01783 } 01784 case ARM::tInt_eh_sjlj_longjmp: { 01785 // ldr $scratch, [$src, #8] 01786 // mov sp, $scratch 01787 // ldr $scratch, [$src, #4] 01788 // ldr r7, [$src] 01789 // bx $scratch 01790 unsigned SrcReg = MI->getOperand(0).getReg(); 01791 unsigned ScratchReg = MI->getOperand(1).getReg(); 01792 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi) 01793 .addReg(ScratchReg) 01794 .addReg(SrcReg) 01795 // The offset immediate is #8. The operand value is scaled by 4 for the 01796 // tLDR instruction. 01797 .addImm(2) 01798 // Predicate. 01799 .addImm(ARMCC::AL) 01800 .addReg(0)); 01801 01802 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr) 01803 .addReg(ARM::SP) 01804 .addReg(ScratchReg) 01805 // Predicate. 01806 .addImm(ARMCC::AL) 01807 .addReg(0)); 01808 01809 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi) 01810 .addReg(ScratchReg) 01811 .addReg(SrcReg) 01812 .addImm(1) 01813 // Predicate. 01814 .addImm(ARMCC::AL) 01815 .addReg(0)); 01816 01817 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi) 01818 .addReg(ARM::R7) 01819 .addReg(SrcReg) 01820 .addImm(0) 01821 // Predicate. 01822 .addImm(ARMCC::AL) 01823 .addReg(0)); 01824 01825 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX) 01826 .addReg(ScratchReg) 01827 // Predicate. 01828 .addImm(ARMCC::AL) 01829 .addReg(0)); 01830 return; 01831 } 01832 } 01833 01834 MCInst TmpInst; 01835 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 01836 01837 EmitToStreamer(OutStreamer, TmpInst); 01838 } 01839 01840 //===----------------------------------------------------------------------===// 01841 // Target Registry Stuff 01842 //===----------------------------------------------------------------------===// 01843 01844 // Force static initialization. 01845 extern "C" void LLVMInitializeARMAsmPrinter() { 01846 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMLETarget); 01847 RegisterAsmPrinter<ARMAsmPrinter> Y(TheARMBETarget); 01848 RegisterAsmPrinter<ARMAsmPrinter> A(TheThumbLETarget); 01849 RegisterAsmPrinter<ARMAsmPrinter> B(TheThumbBETarget); 01850 }