[flang-commits] [flang] [flang][MIPS] Add N32 and N64 target ABI support (PR #224920)
Jiaxun Yang via flang-commits
flang-commits at lists.llvm.org
Thu Sep 24 02:38:10 PDT 2026
================
@@ -1409,6 +1411,87 @@ struct TargetSparcV9 : public GenericTarget<TargetSparcV9> {
};
} // namespace
+//===----------------------------------------------------------------------===//
+// MIPS N32 and N64 target specifics.
+//===----------------------------------------------------------------------===//
+
+namespace {
+struct TargetMips64 : public GenericTarget<TargetMips64> {
+ using GenericTarget::GenericTarget;
+
+ const int defaultWidth = targetABI == "n32" ? 32 : 64;
+
+ CodeGenSpecifics::Marshalling
+ complexArgumentType(mlir::Location loc, mlir::Type eleTy) const override {
+ return complexArgumentType(loc, eleTy, {});
+ }
+
+ CodeGenSpecifics::Marshalling
+ complexArgumentType(mlir::Location loc, mlir::Type eleTy,
+ const Marshalling &previousArguments) const override {
+ const auto *sem = &floatToSemantics(kindMap, eleTy);
+ if (sem != &llvm::APFloat::IEEEsingle() &&
+ sem != &llvm::APFloat::IEEEdouble())
+ typeTodo(sem, loc, "argument");
+
+ // N32/N64 share eight argument slots between integer and floating-point
+ // registers. A complex argument uses two FPRs when both parts fit.
+ // Otherwise, pass its memory representation in GPRs or on the stack,
+ // packing COMPLEX(4) into one slot.
+ uint64_t slots = 0;
+ for (auto [ty, attr] : previousArguments) {
+ if (attr.isAppend())
+ continue;
+ if (fir::conformsWithPassByRef(ty)) {
+ if (++slots >= 7)
+ break;
+ continue;
+ }
+ auto [size, align] = fir::getTypeSizeAndAlignmentOrCrash(
+ loc, ty, getDataLayout(), kindMap);
+ slots = llvm::alignTo(slots, align > 8 ? 2 : 1);
+ slots += llvm::divideCeil(size, uint64_t{8});
+ if (slots >= 7)
+ break;
+ }
+
+ if (slots < 7)
+ return {{eleTy, AT{}}, {eleTy, AT{}}};
+
+ auto i64Ty = mlir::IntegerType::get(eleTy.getContext(), 64);
+ if (sem == &llvm::APFloat::IEEEsingle())
+ return {{i64Ty, AT{}}};
+ return {{mlir::TupleType::get(eleTy.getContext(), {i64Ty, i64Ty}), AT{}}};
+ }
+
+ CodeGenSpecifics::Marshalling
+ complexReturnType(mlir::Location loc, mlir::Type eleTy) const override {
+ const auto *sem = &floatToSemantics(kindMap, eleTy);
+ auto structTy =
+ mlir::TupleType::get(eleTy.getContext(), mlir::TypeRange{eleTy, eleTy});
+ if (sem == &llvm::APFloat::IEEEsingle() ||
+ sem == &llvm::APFloat::IEEEdouble())
+ return {{structTy, AT{}}};
+ if (sem == &llvm::APFloat::IEEEquad())
+ return {{fir::ReferenceType::get(structTy),
+ AT{/*alignment=*/16, /*byval=*/false, /*sret=*/true}}};
----------------
FlyGoat wrote:
Yes, N32 have 64bit GPR, thus same stack alignment.
https://github.com/llvm/llvm-project/pull/224920
More information about the flang-commits
mailing list