================ @@ -0,0 +1,136 @@ +//===--- CIRGenAsm.cpp - Inline Assembly Support for CIR CodeGen ---------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains code to emit inline assembly. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/DiagnosticSema.h" +#include "llvm/ADT/StringExtras.h" + +#include "CIRGenFunction.h" +#include "TargetInfo.h" +#include "clang/CIR/MissingFeatures.h" + +using namespace clang; +using namespace clang::CIRGen; +using namespace cir; + +static AsmFlavor inferFlavor(const CIRGenModule &cgm, const AsmStmt &s) { + AsmFlavor gnuAsmFlavor = + cgm.getCodeGenOpts().getInlineAsmDialect() == CodeGenOptions::IAD_ATT + ? AsmFlavor::x86_att + : AsmFlavor::x86_intel; + + return isa<MSAsmStmt>(&s) ? AsmFlavor::x86_intel : gnuAsmFlavor; +} + +static void collectClobbers(const CIRGenFunction &cgf, const AsmStmt &s, + std::string &constraints, bool &hasUnwindClobber, + bool &readOnly, bool readNone) { + + hasUnwindClobber = false; + const CIRGenModule &cgm = cgf.getCIRGenModule(); + + // Clobbers + for (unsigned i = 0, e = s.getNumClobbers(); i != e; i++) { + std::string clobberStr = s.getClobber(i); + StringRef clobber{clobberStr}; + if (clobber == "memory") + readOnly = readNone = false; + else if (clobber == "unwind") { + hasUnwindClobber = true; + continue; + } else if (clobber != "cc") { + clobber = cgf.getTarget().getNormalizedGCCRegisterName(clobber); + if (cgm.getCodeGenOpts().StackClashProtector && + cgf.getTarget().isSPRegName(clobber)) { + cgm.getDiags().Report(s.getAsmLoc(), + diag::warn_stack_clash_protection_inline_asm); + } + } + + if (isa<MSAsmStmt>(&s)) { + if (clobber == "eax" || clobber == "edx") { + if (constraints.find("=&A") != std::string::npos) + continue; + std::string::size_type position1 = + constraints.find("={" + clobber.str() + "}"); + if (position1 != std::string::npos) { + constraints.insert(position1 + 1, "&"); + continue; + } + std::string::size_type position2 = constraints.find("=A"); + if (position2 != std::string::npos) { + constraints.insert(position2 + 1, "&"); + continue; + } + } + } + if (!constraints.empty()) + constraints += ','; + + constraints += "~{"; + constraints += clobber; + constraints += '}'; + } + + // Add machine specific clobbers + std::string_view machineClobbers = cgf.getTarget().getClobbers(); + if (!machineClobbers.empty()) { + if (!constraints.empty()) + constraints += ','; + constraints += machineClobbers; + } +} + +mlir::LogicalResult CIRGenFunction::emitAsmStmt(const AsmStmt &s) { + // Assemble the final asm string. + std::string asmString = s.generateAsmString(getContext()); + + std::string constraints; + + // An inline asm can be marked readonly if it meets the following conditions: + // - it doesn't have any sideeffects + // - it doesn't clobber memory + // - it doesn't return a value by-reference + // It can be marked readnone if it doesn't have any input memory constraints + // in addition to meeting the conditions listed above. + bool readOnly = true, readNone = true; + + if (s.getNumInputs() != 0 || s.getNumOutputs() != 0) { + assert(!cir::MissingFeatures::asmInputOperands()); + assert(!cir::MissingFeatures::asmOutputOperands()); + cgm.errorNYI(s.getAsmLoc(), "asm with operands"); + } + + bool hasUnwindClobber = false; + collectClobbers(*this, s, constraints, hasUnwindClobber, readOnly, readNone); + + llvm::SmallVector<mlir::ValueRange, 8> operands; + mlir::Type resultType; + + bool hasSideEffect = s.isVolatile() || s.getNumOutputs() == 0; + + cir::InlineAsmOp ia = builder.create<cir::InlineAsmOp>( + getLoc(s.getAsmLoc()), resultType, operands, asmString, constraints, + hasSideEffect, inferFlavor(cgm, s), mlir::ArrayAttr()); + + if (false /*IsGCCAsmGoto*/) { ---------------- bcardosolopes wrote:
Please add `bool isGCCAsmGoto = false;` closer to the function entry and then update the if statement to use it. https://github.com/llvm/llvm-project/pull/153546 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits