================
@@ -55,6 +61,224 @@ namespace mlir {
 
 namespace {
 
+//===----------------------------------------------------------------------===//
+// x86_64 System V classifier bridge (scalar types)
+//
+// Maps scalar CIR types to llvm::abi::Type, runs the LLVM ABI Lowering
+// Library's SysV x86_64 classifier, and converts the result back into the
+// dialect-agnostic mlir::abi::FunctionClassification that CIRABIRewriteContext
+// consumes.  Only integer / pointer / bool / f32 / f64 signatures are handled;
+// aggregates and other leaf types are reported NYI by classifyX86_64Function
+// so an unsupported signature fails the pass instead of being misclassified.
+//===----------------------------------------------------------------------===//
+
+/// llvm::Align requires a power of two; DataLayout can report non-power-of-two
+/// alignments for unusual types.
+static llvm::Align safeAlign(uint64_t a) {
+  return llvm::Align(llvm::PowerOf2Ceil(std::max<uint64_t>(a, 1)));
+}
+
+/// The scalar CIR types the x86_64 bridge handles.  A regular integer up to
+/// 64 bits, pointer, bool, void, f32, or f64 is a single-register Direct or
+/// Extend argument.  `_BitInt`, `__int128`, and wider/other types need 
coercion
+/// or indirect passing, which this scalar bridge does not do.
+static bool isSupportedScalarType(mlir::Type ty) {
+  if (isa<cir::VoidType, cir::BoolType, cir::PointerType, cir::SingleType,
+          cir::DoubleType>(ty))
+    return true;
+  if (auto intTy = dyn_cast<cir::IntType>(ty))
+    return !intTy.getIsBitInt() && intTy.getWidth() <= 64;
+  return false;
+}
+
+/// Convert an llvm::abi::Type coercion type back to a scalar CIR type.
+static mlir::Type abiTypeToCIR(const llvm::abi::Type *ty, MLIRContext *ctx) {
+  if (!ty)
+    return nullptr;
+  return llvm::TypeSwitch<const llvm::abi::Type *, mlir::Type>(ty)
+      .Case(
+          [&](const llvm::abi::VoidType *) { return cir::VoidType::get(ctx); })
+      .Case([&](const llvm::abi::IntegerType *intTy) {
+        return cir::IntType::get(ctx, intTy->getSizeInBits().getFixedValue(),
+                                 intTy->isSigned());
+      })
+      .Case([&](const llvm::abi::FloatType *fltTy) -> mlir::Type {
+        const llvm::fltSemantics *sem = fltTy->getSemantics();
+        if (sem == &llvm::APFloat::IEEEsingle())
+          return cir::SingleType::get(ctx);
+        if (sem == &llvm::APFloat::IEEEdouble())
+          return cir::DoubleType::get(ctx);
+        return nullptr;
+      })
+      .Case([&](const llvm::abi::PointerType *) {
+        return cir::PointerType::get(cir::VoidType::get(ctx));
+      })
+      .Default([](const llvm::abi::Type *) -> mlir::Type { return nullptr; });
+}
+
+/// Map a scalar CIR type to an llvm::abi::Type.  classifyX86_64Function
+/// pre-filters the signature, so only the scalar types handled here can
+/// reach this function.
+static const llvm::abi::Type *mapCIRType(mlir::Type type,
+                                         mlir::abi::ABITypeMapper &typeMapper,
+                                         const DataLayout &dl) {
+  llvm::abi::TypeBuilder &tb = typeMapper.getTypeBuilder();
+  return llvm::TypeSwitch<mlir::Type, const llvm::abi::Type *>(type)
+      .Case([&](cir::IntType intTy) {
+        return tb.getIntegerType(intTy.getWidth(),
+                                 safeAlign(dl.getTypeABIAlignment(type)),
+                                 intTy.isSigned());
+      })
+      .Case([&](cir::PointerType ptrTy) {
+        unsigned addrSpace = 0;
+        if (auto targetAsAttr =
+                dyn_cast_if_present<cir::TargetAddressSpaceAttr>(
----------------
adams381 wrote:

Good catch.  I've Added an NYI here.


https://github.com/llvm/llvm-project/pull/209636
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to