1 //===-- lib/CodeGen/GlobalISel/InlineAsmLowering.cpp ----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file implements the lowering from LLVM IR inline asm to MIR INLINEASM
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
15 #include "llvm/CodeGen/Analysis.h"
16 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
17 #include "llvm/CodeGen/GlobalISel/Utils.h"
18 #include "llvm/CodeGen/MachineOperand.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/TargetLowering.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/LLVMContext.h"
24 #include "llvm/IR/Module.h"
25 
26 #define DEBUG_TYPE "inline-asm-lowering"
27 
28 using namespace llvm;
29 
30 void InlineAsmLowering::anchor() {}
31 
32 bool InlineAsmLowering::lowerInlineAsm(MachineIRBuilder &MIRBuilder,
33                                        const CallBase &Call) const {
34 
35   const InlineAsm *IA = cast<InlineAsm>(Call.getCalledOperand());
36   StringRef ConstraintStr = IA->getConstraintString();
37 
38   bool HasOnlyMemoryClobber = false;
39   if (!ConstraintStr.empty()) {
40     // Until we have full inline assembly support, we just try to handle the
41     // very simple case of just "~{memory}" to avoid falling back so often.
42     if (ConstraintStr != "~{memory}")
43       return false;
44     HasOnlyMemoryClobber = true;
45   }
46 
47   unsigned ExtraInfo = 0;
48   if (IA->hasSideEffects())
49     ExtraInfo |= InlineAsm::Extra_HasSideEffects;
50   if (IA->getDialect() == InlineAsm::AD_Intel)
51     ExtraInfo |= InlineAsm::Extra_AsmDialect;
52 
53   // HACK: special casing for ~memory.
54   if (HasOnlyMemoryClobber)
55     ExtraInfo |= (InlineAsm::Extra_MayLoad | InlineAsm::Extra_MayStore);
56 
57   auto Inst = MIRBuilder.buildInstr(TargetOpcode::INLINEASM)
58                   .addExternalSymbol(IA->getAsmString().c_str())
59                   .addImm(ExtraInfo);
60   if (const MDNode *SrcLoc = Call.getMetadata("srcloc"))
61     Inst.addMetadata(SrcLoc);
62 
63   return true;
64 }
65