[clang] [CIR] Implement codegen for inline assembly without input and output operands (PR #153546)
Bruno Cardoso Lopes via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 15 14:23:42 PDT 2025
================
@@ -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
More information about the cfe-commits
mailing list