diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 104 |
1 files changed, 56 insertions, 48 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index 62103e3107c0..7721e996aca5 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -1,9 +1,8 @@ //===-- AsmPrinterInlineAsm.cpp - AsmPrinter Inline Asm Handling ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,7 +18,6 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetRegisterInfo.h" -#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/InlineAsm.h" @@ -155,15 +153,10 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI, " we don't have an asm parser for this target\n"); Parser->setAssemblerDialect(Dialect); Parser->setTargetParser(*TAP.get()); - Parser->setEnablePrintSchedInfo(EnablePrintSchedInfo); // Enable lexing Masm binary and hex integer literals in intel inline // assembly. if (Dialect == InlineAsm::AD_Intel) Parser->getLexer().setLexMasmIntegers(true); - if (MF) { - const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); - TAP->SetFrameRegister(TRI->getFrameRegister(*MF)); - } emitInlineAsmStart(); // Don't implicitly switch to the text section before the asm. @@ -176,9 +169,8 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI, } static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI, - MachineModuleInfo *MMI, int InlineAsmVariant, - AsmPrinter *AP, unsigned LocCookie, - raw_ostream &OS) { + MachineModuleInfo *MMI, AsmPrinter *AP, + unsigned LocCookie, raw_ostream &OS) { // Switch to the inline assembly variant. OS << "\t.intel_syntax\n\t"; @@ -270,11 +262,9 @@ static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI, ++OpNo; // Skip over the ID number. if (InlineAsm::isMemKind(OpFlags)) { - Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant, - /*Modifier*/ nullptr, OS); + Error = AP->PrintAsmMemoryOperand(MI, OpNo, /*Modifier*/ nullptr, OS); } else { - Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant, - /*Modifier*/ nullptr, OS); + Error = AP->PrintAsmOperand(MI, OpNo, /*Modifier*/ nullptr, OS); } } if (Error) { @@ -291,9 +281,9 @@ static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI, } static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI, - MachineModuleInfo *MMI, int InlineAsmVariant, - int AsmPrinterVariant, AsmPrinter *AP, - unsigned LocCookie, raw_ostream &OS) { + MachineModuleInfo *MMI, int AsmPrinterVariant, + AsmPrinter *AP, unsigned LocCookie, + raw_ostream &OS) { int CurVariant = -1; // The number of the {.|.|.} region we are in. const char *LastEmitted = AsmStr; // One past the last character emitted. unsigned NumOperands = MI->getNumOperands(); @@ -435,17 +425,25 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI, unsigned OpFlags = MI->getOperand(OpNo).getImm(); ++OpNo; // Skip over the ID number. + // FIXME: Shouldn't arch-independent output template handling go into + // PrintAsmOperand? if (Modifier[0] == 'l') { // Labels are target independent. - // FIXME: What if the operand isn't an MBB, report error? - const MCSymbol *Sym = MI->getOperand(OpNo).getMBB()->getSymbol(); - Sym->print(OS, AP->MAI); + if (MI->getOperand(OpNo).isBlockAddress()) { + const BlockAddress *BA = MI->getOperand(OpNo).getBlockAddress(); + MCSymbol *Sym = AP->GetBlockAddressSymbol(BA); + Sym->print(OS, AP->MAI); + } else if (MI->getOperand(OpNo).isMBB()) { + const MCSymbol *Sym = MI->getOperand(OpNo).getMBB()->getSymbol(); + Sym->print(OS, AP->MAI); + } else { + Error = true; + } } else { if (InlineAsm::isMemKind(OpFlags)) { - Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant, - Modifier[0] ? Modifier : nullptr, - OS); + Error = AP->PrintAsmMemoryOperand( + MI, OpNo, Modifier[0] ? Modifier : nullptr, OS); } else { - Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant, + Error = AP->PrintAsmOperand(MI, OpNo, Modifier[0] ? Modifier : nullptr, OS); } } @@ -515,18 +513,11 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const { // The variant of the current asmprinter. int AsmPrinterVariant = MAI->getAssemblerDialect(); - InlineAsm::AsmDialect InlineAsmVariant = MI->getInlineAsmDialect(); AsmPrinter *AP = const_cast<AsmPrinter*>(this); - if (InlineAsmVariant == InlineAsm::AD_ATT) - EmitGCCInlineAsmStr(AsmStr, MI, MMI, InlineAsmVariant, AsmPrinterVariant, - AP, LocCookie, OS); + if (MI->getInlineAsmDialect() == InlineAsm::AD_ATT) + EmitGCCInlineAsmStr(AsmStr, MI, MMI, AsmPrinterVariant, AP, LocCookie, OS); else - EmitMSInlineAsmStr(AsmStr, MI, MMI, InlineAsmVariant, AP, LocCookie, OS); - - // Reset SanitizeAddress based on the function's attribute. - MCTargetOptions MCOptions = TM.Options.MCOptions; - MCOptions.SanitizeAddress = - MF->getFunction().hasFnAttribute(Attribute::SanitizeAddress); + EmitMSInlineAsmStr(AsmStr, MI, MMI, AP, LocCookie, OS); // Emit warnings if we use reserved registers on the clobber list, as // that might give surprising results. @@ -566,7 +557,7 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const { SrcMgr.PrintMessage(Loc, SourceMgr::DK_Note, Note); } - EmitInlineAsm(OS.str(), getSubtargetInfo(), MCOptions, LocMD, + EmitInlineAsm(OS.str(), getSubtargetInfo(), TM.Options.MCOptions, LocMD, MI->getInlineAsmDialect()); // Emit the #NOAPP end marker. This has to happen even if verbose-asm isn't @@ -608,32 +599,50 @@ void AsmPrinter::PrintSpecial(const MachineInstr *MI, raw_ostream &OS, } } +void AsmPrinter::PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS) { + assert(MO.isGlobal() && "caller should check MO.isGlobal"); + getSymbol(MO.getGlobal())->print(OS, MAI); + printOffset(MO.getOffset(), OS); +} + /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM /// instruction, using the specified assembler variant. Targets should -/// override this to format as appropriate. +/// override this to format as appropriate for machine specific ExtraCodes +/// or when the arch-independent handling would be too complex otherwise. bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &O) { + const char *ExtraCode, raw_ostream &O) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. + // https://gcc.gnu.org/onlinedocs/gccint/Output-Template.html const MachineOperand &MO = MI->getOperand(OpNo); switch (ExtraCode[0]) { default: return true; // Unknown modifier. + case 'a': // Print as memory address. + if (MO.isReg()) { + PrintAsmMemoryOperand(MI, OpNo, nullptr, O); + return false; + } + LLVM_FALLTHROUGH; // GCC allows '%a' to behave like '%c' with immediates. case 'c': // Substitute immediate value without immediate syntax - if (MO.getType() != MachineOperand::MO_Immediate) - return true; - O << MO.getImm(); - return false; + if (MO.isImm()) { + O << MO.getImm(); + return false; + } + if (MO.isGlobal()) { + PrintSymbolOperand(MO, O); + return false; + } + return true; case 'n': // Negate the immediate constant. - if (MO.getType() != MachineOperand::MO_Immediate) + if (!MO.isImm()) return true; O << -MO.getImm(); return false; case 's': // The GCC deprecated s modifier - if (MO.getType() != MachineOperand::MO_Immediate) + if (!MO.isImm()) return true; O << ((32 - MO.getImm()) & 31); return false; @@ -643,7 +652,6 @@ bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, } bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, raw_ostream &O) { // Target doesn't support this yet! return true; |