/// Measure the specified inline asm to determine an approximation of its /// length. /// Comments (which run till the next SeparatorString or newline) do not /// count as an instruction. /// Any other non-whitespace text is considered an instruction, with /// multiple instructions separated by SeparatorString or newlines. /// Variable-length instructions are not handled here; this function /// may be overloaded in the target code to do that. /// We implement the special case of the .space directive taking only an /// integer argument, which is the size in bytes. This is used for creating /// inline code spacing for testing purposes using inline assembly. /// unsigned Mips16InstrInfo::getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const { // Count the number of instructions in the asm. bool atInsnStart = true; unsigned Length = 0; for (; *Str; ++Str) { if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), strlen(MAI.getSeparatorString())) == 0) atInsnStart = true; if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) { if (strncmp(Str, ".space", 6)==0) { char *EStr; int Sz; Sz = strtol(Str+6, &EStr, 10); while (isspace(*EStr)) ++EStr; if (*EStr=='\0') { DEBUG(dbgs() << "parsed .space " << Sz << '\n'); return Sz; } } Length += MAI.getMaxInstLength(); atInsnStart = false; } if (atInsnStart && strncmp(Str, MAI.getCommentString(), strlen(MAI.getCommentString())) == 0) atInsnStart = false; } return Length; }
void LLVMTargetMachine::initAsmInfo() { MRI = TheTarget.createMCRegInfo(getTargetTriple().str()); MII = TheTarget.createMCInstrInfo(); // FIXME: Having an MCSubtargetInfo on the target machine is a hack due // to some backends having subtarget feature dependent module level // code generation. This is similar to the hack in the AsmPrinter for // module level assembly etc. STI = TheTarget.createMCSubtargetInfo(getTargetTriple().str(), getTargetCPU(), getTargetFeatureString()); MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo(*MRI, getTargetTriple().str()); // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0, // and if the old one gets included then MCAsmInfo will be NULL and // we'll crash later. // Provide the user with a useful error message about what's wrong. assert(TmpAsmInfo && "MCAsmInfo not initialized. " "Make sure you include the correct TargetSelect.h" "and that InitializeAllTargetMCs() is being invoked!"); if (Options.DisableIntegratedAS) TmpAsmInfo->setUseIntegratedAssembler(false); if (Options.CompressDebugSections) TmpAsmInfo->setCompressDebugSections(true); AsmInfo = TmpAsmInfo; }
static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { Triple TheTriple(TT); MCAsmInfo *MAI; switch (TheTriple.getOS()) { case llvm::Triple::Darwin: case llvm::Triple::IOS: case llvm::Triple::MacOSX: MAI = new ARMMCAsmInfoDarwin(TT); break; case llvm::Triple::Win32: switch (TheTriple.getEnvironment()) { case llvm::Triple::Itanium: MAI = new ARMCOFFMCAsmInfoGNU(); break; case llvm::Triple::MSVC: MAI = new ARMCOFFMCAsmInfoMicrosoft(); break; default: llvm_unreachable("invalid environment"); } break; default: if (TheTriple.isOSBinFormatMachO()) MAI = new ARMMCAsmInfoDarwin(TT); else MAI = new ARMELFMCAsmInfo(TT); break; } unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0)); return MAI; }
/// Measure the specified inline asm to determine an approximation of its /// length. /// Comments (which run till the next SeparatorString or newline) do not /// count as an instruction. /// Any other non-whitespace text is considered an instruction, with /// multiple instructions separated by SeparatorString or newlines. /// Variable-length instructions are not handled here; this function /// may be overloaded in the target code to do that. /// We implement a special case of the .space directive which takes only a /// single integer argument in base 10 that is the size in bytes. This is a /// restricted form of the GAS directive in that we only interpret /// simple--i.e. not a logical or arithmetic expression--size values without /// the optional fill value. This is primarily used for creating arbitrary /// sized inline asm blocks for testing purposes. unsigned TargetInstrInfo::getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const { // Count the number of instructions in the asm. bool AtInsnStart = true; unsigned Length = 0; for (; *Str; ++Str) { if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), strlen(MAI.getSeparatorString())) == 0) { AtInsnStart = true; } else if (isAsmComment(Str, MAI)) { // Stop counting as an instruction after a comment until the next // separator. AtInsnStart = false; } if (AtInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) { unsigned AddLength = MAI.getMaxInstLength(); if (strncmp(Str, ".space", 6) == 0) { char *EStr; int SpaceSize; SpaceSize = strtol(Str + 6, &EStr, 10); SpaceSize = SpaceSize < 0 ? 0 : SpaceSize; while (*EStr != '\n' && std::isspace(static_cast<unsigned char>(*EStr))) ++EStr; if (*EStr == '\0' || *EStr == '\n' || isAsmComment(EStr, MAI)) // Successfully parsed .space argument AddLength = SpaceSize; } Length += AddLength; AtInsnStart = false; } } return Length; }
static MCAsmInfo *createSystemZMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { MCAsmInfo *MAI = new SystemZMCAsmInfo(TT); MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, MRI.getDwarfRegNum(SystemZ::R15D, true), SystemZMC::CFAOffsetFromInitialSP); MAI->addInitialFrameState(Inst); return MAI; }
static MCAsmInfo *createCpu0MCAsmInfo(const Target &T, StringRef TT) { MCAsmInfo *MAI = new Cpu0MCAsmInfo(T, TT); MachineLocation Dst(MachineLocation::VirtualFP); MachineLocation Src(Cpu0::SP, 0); MAI->addInitialFrameState(0, Dst, Src); return MAI; }
static MCAsmInfo *createCpu0MCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { MCAsmInfo *MAI = new Cpu0MCAsmInfo(TT); unsigned SP = MRI.getDwarfRegNum(Cpu0::SP, true); MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, SP, 0); MAI->addInitialFrameState(Inst); return MAI; }
static MCAsmInfo *createSPUMCAsmInfo(const Target &T, StringRef TT) { MCAsmInfo *MAI = new SPULinuxMCAsmInfo(T, TT); // Initial state of the frame pointer is R1. MachineLocation Dst(MachineLocation::VirtualFP); MachineLocation Src(SPU::R1, 0); MAI->addInitialFrameState(0, Dst, Src); return MAI; }
static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT) { MCAsmInfo *MAI = new MipsMCAsmInfo(TT); unsigned SP = MRI.getDwarfRegNum(Mips::SP, true); MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, SP, 0); MAI->addInitialFrameState(Inst); return MAI; }
static MCAsmInfo *createXCoreMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT) { MCAsmInfo *MAI = new XCoreMCAsmInfo(TT); // Initial state of the frame pointer is SP. MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, XCore::SP, 0); MAI->addInitialFrameState(Inst); return MAI; }
static MCAsmInfo *createVideocoreMCAsmInfo(const Target &T, StringRef TT) { MCAsmInfo *MAI = new VideocoreMCAsmInfo(T, TT); // Initial state of the frame pointer is SP. MachineLocation Dst(MachineLocation::VirtualFP); MachineLocation Src(VC::SP, 0); MAI->addInitialFrameState(0, Dst, Src); return MAI; }
static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { MCAsmInfo *MAI = new HexagonMCAsmInfo(TT); // VirtualFP = (R30 + #0). MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0); MAI->addInitialFrameState(Inst); return MAI; }
static MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { Triple TheTriple(TT); MCAsmInfo *MAI = new AArch64ELFMCAsmInfo(); unsigned Reg = MRI.getDwarfRegNum(AArch64::XSP, true); MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 0); MAI->addInitialFrameState(Inst); return MAI; }
static MCAsmInfo *createNyuziMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT) { MCAsmInfo *MAI = new NyuziMCAsmInfo(TT); // Put an instruction into the common information entry (CIE), shared // by all frame description entries (FDE), which indicates the stack // pointer register (r29) is used to find the canonical frame address (CFA). unsigned SP = MRI.getDwarfRegNum(Nyuzi::SP_REG, true); MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, SP, 0); MAI->addInitialFrameState(Inst); return MAI; }
static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { Triple TheTriple(TT); MCAsmInfo *MAI; if (TheTriple.isOSBinFormatMachO()) MAI = new ARMMCAsmInfoDarwin(); else MAI = new ARMELFMCAsmInfo(); unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(0, Reg, 0)); return MAI; }
// Decides whether a '.section' directive // should be printed before the section name. bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const { if (isUnique()) return false; return MAI.shouldOmitSectionDirective(Name); }
static MCAsmInfo *createPPCMCAsmInfo(const Target &T, StringRef TT) { Triple TheTriple(TT); bool isPPC64 = TheTriple.getArch() == Triple::ppc64; MCAsmInfo *MAI; if (TheTriple.isOSDarwin()) MAI = new PPCMCAsmInfoDarwin(isPPC64); else MAI = new PPCLinuxMCAsmInfo(isPPC64); // Initial state of the frame pointer is R1. MachineLocation Dst(MachineLocation::VirtualFP); MachineLocation Src(isPPC64? PPC::X1 : PPC::R1, 0); MAI->addInitialFrameState(0, Dst, Src); return MAI; }
static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TheTriple) { MCAsmInfo *MAI; if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO()) MAI = new ARMMCAsmInfoDarwin(TheTriple); else if (TheTriple.isWindowsItaniumEnvironment()) MAI = new ARMCOFFMCAsmInfoGNU(); else if (TheTriple.isWindowsMSVCEnvironment()) MAI = new ARMCOFFMCAsmInfoMicrosoft(); else MAI = new ARMELFMCAsmInfo(TheTriple); unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0)); return MAI; }
static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { Triple TheTriple(TT); bool isPPC64 = TheTriple.getArch() == Triple::ppc64; MCAsmInfo *MAI; if (TheTriple.isOSDarwin()) MAI = new PPCMCAsmInfoDarwin(isPPC64); else MAI = new PPCLinuxMCAsmInfo(isPPC64); // Initial state of the frame pointer is R1. unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1; MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, MRI.getDwarfRegNum(Reg, true), 0); MAI->addInitialFrameState(Inst); return MAI; }
static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TheTriple) { bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 || TheTriple.getArch() == Triple::ppc64le); MCAsmInfo *MAI; if (TheTriple.isOSDarwin()) MAI = new PPCMCAsmInfoDarwin(isPPC64, TheTriple); else MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple); // Initial state of the frame pointer is R1. unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1; MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0); MAI->addInitialFrameState(Inst); return MAI; }
static MCAsmInfo *createARM64MCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { Triple TheTriple(TT); MCAsmInfo *MAI; if (TheTriple.isOSDarwin()) MAI = new ARM64MCAsmInfoDarwin(); else { assert(TheTriple.isOSBinFormatELF() && "Only expect Darwin or ELF"); MAI = new ARM64MCAsmInfoELF(); } // Initial state of the frame pointer is SP. unsigned Reg = MRI.getDwarfRegNum(ARM64::SP, true); MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 0); MAI->addInitialFrameState(Inst); return MAI; }
// ShouldOmitSectionDirective - Decides whether a '.section' directive // should be printed before the section name bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const { // FIXME: Does .section .bss/.data/.text work everywhere?? if (Name == ".text" || Name == ".data" || (Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS())) return true; return false; }
void LLVMTargetMachine::initAsmInfo() { MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo(*getRegisterInfo(), TargetTriple); // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0, // and if the old one gets included then MCAsmInfo will be NULL and // we'll crash later. // Provide the user with a useful error message about what's wrong. assert(TmpAsmInfo && "MCAsmInfo not initialized. " "Make sure you include the correct TargetSelect.h" "and that InitializeAllTargetMCs() is being invoked!"); if (Options.DisableIntegratedAS) TmpAsmInfo->setUseIntegratedAssembler(false); if (Options.CompressDebugSections) TmpAsmInfo->setCompressDebugSections(true); AsmInfo = TmpAsmInfo; }
static MCAsmInfo *createX86MCAsmInfo(const MCRegisterInfo &MRI, const Triple &TheTriple) { bool is64Bit = TheTriple.getArch() == Triple::x86_64; MCAsmInfo *MAI; if (TheTriple.isOSBinFormatMachO()) { if (is64Bit) MAI = new X86_64MCAsmInfoDarwin(TheTriple); else MAI = new X86MCAsmInfoDarwin(TheTriple); } else if (TheTriple.isOSBinFormatELF()) { // Force the use of an ELF container. MAI = new X86ELFMCAsmInfo(TheTriple); } else if (TheTriple.isWindowsMSVCEnvironment() || TheTriple.isWindowsCoreCLREnvironment()) { MAI = new X86MCAsmInfoMicrosoft(TheTriple); } else if (TheTriple.isOSCygMing() || TheTriple.isWindowsItaniumEnvironment()) { MAI = new X86MCAsmInfoGNUCOFF(TheTriple); } else { // The default is ELF. MAI = new X86ELFMCAsmInfo(TheTriple); } // Initialize initial frame state. // Calculate amount of bytes used for return address storing int stackGrowth = is64Bit ? -8 : -4; // Initial state of the frame pointer is esp+stackGrowth. unsigned StackPtr = is64Bit ? X86::RSP : X86::ESP; MCCFIInstruction Inst = MCCFIInstruction::createDefCfa( nullptr, MRI.getDwarfRegNum(StackPtr, true), -stackGrowth); MAI->addInitialFrameState(Inst); // Add return address to move list unsigned InstPtr = is64Bit ? X86::RIP : X86::EIP; MCCFIInstruction Inst2 = MCCFIInstruction::createOffset( nullptr, MRI.getDwarfRegNum(InstPtr, true), stackGrowth); MAI->addInitialFrameState(Inst2); return MAI; }
/// Measure the specified inline asm to determine an approximation of its /// length. /// Comments (which run till the next SeparatorString or newline) do not /// count as an instruction. /// Any other non-whitespace text is considered an instruction, with /// multiple instructions separated by SeparatorString or newlines. /// Variable-length instructions are not handled here; this function /// may be overloaded in the target code to do that. unsigned TargetInstrInfo::getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const { // Count the number of instructions in the asm. bool atInsnStart = true; unsigned Length = 0; for (; *Str; ++Str) { if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), strlen(MAI.getSeparatorString())) == 0) atInsnStart = true; if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) { Length += MAI.getMaxInstLength(); atInsnStart = false; } if (atInsnStart && strncmp(Str, MAI.getCommentString(), strlen(MAI.getCommentString())) == 0) atInsnStart = false; } return Length; }
static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, const MCSection &Section) { if (!AsmInfo.isSectionAtomizableBySymbols(Section)) return true; // If it is not dead stripped, it is safe to use private labels. const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) return true; return false; }
// ShouldOmitSectionDirective - Decides whether a '.section' directive // should be printed before the section name bool MCSectionELF::ShouldOmitSectionDirective(const char *Name, const MCAsmInfo &MAI) const { // FIXME: Does .section .bss/.data/.text work everywhere?? if (strcmp(Name, ".text") == 0 || strcmp(Name, ".data") == 0 || (strcmp(Name, ".bss") == 0 && !MAI.usesELFSectionDirectiveForBSS())) return true; return false; }
/// Measure the specified inline asm to determine an approximation of its /// length. /// Comments (which run till the next SeparatorString or newline) do not /// count as an instruction. /// Any other non-whitespace text is considered an instruction, with /// multiple instructions separated by SeparatorString or newlines. /// Variable-length instructions are not handled here; this function /// may be overloaded in the target code to do that. unsigned TargetInstrInfo::getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const { // Count the number of instructions in the asm. bool atInsnStart = true; unsigned InstCount = 0; for (; *Str; ++Str) { if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), strlen(MAI.getSeparatorString())) == 0) { atInsnStart = true; } else if (strncmp(Str, MAI.getCommentString(), strlen(MAI.getCommentString())) == 0) { // Stop counting as an instruction after a comment until the next // separator. atInsnStart = false; } if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) { ++InstCount; atInsnStart = false; } } return InstCount * MAI.getMaxInstLength(); }
AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) { AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); }
AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) { CurPtr = nullptr; isAtStartOfLine = true; AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); }