[clang] [llvm] Fix alignments for NetBSD/m68k. (PR #207602)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 5 12:40:41 PDT 2026
https://github.com/he32 updated https://github.com/llvm/llvm-project/pull/207602
>From 567e7ca34664ba5c5bfa00c00e1b46852c71c697 Mon Sep 17 00:00:00 2001
From: Havard Eidnes <he at NetBSD.org>
Date: Sun, 5 Jul 2026 18:13:57 +0000
Subject: [PATCH] Fix alignments for NetBSD/m68k.
Linux/m68k uses the ABI from Sun Microsystems for a.out on m68k,
which aligns ints/objects/pointers/stack on 16-bit boundaries.
NetBSD/m68k on the other hand uses the ABI from SVR4 for m68k,
which aligns ints/objects/pointers/stack on 32-bit boundaries.
This is a follow-up of
https://github.com/M680x0/issues/issues/13
---
clang/lib/Basic/Targets/M68k.cpp | 18 +++++++-
llvm/lib/TargetParser/TargetDataLayout.cpp | 50 ++++++++++++++++------
2 files changed, 55 insertions(+), 13 deletions(-)
diff --git a/clang/lib/Basic/Targets/M68k.cpp b/clang/lib/Basic/Targets/M68k.cpp
index fde1e3953a6c0..87da5849f35f7 100644
--- a/clang/lib/Basic/Targets/M68k.cpp
+++ b/clang/lib/Basic/Targets/M68k.cpp
@@ -24,6 +24,18 @@
namespace clang {
namespace targets {
+// Linux/m68k ("old") uses the ABI from Sun Microsystems a.out
+// for m68k, and uses 16-bit alignments for int/long/pointers.
+//
+// NetBSD/m68k uses the ABI from SVR4 for m68k,
+// which uses 32-bit alignments for int/long/pointers.
+//
+// Ref. https://github.com/M680x0/issues/issues/13 and
+// https://github.com/llvm/llvm-project/issues/199826
+//
+// Arguably this ought to respect -malign-int, as suggested
+// above, this code doesn't so far.
+
M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: TargetInfo(Triple), TargetOpts(Opts) {
@@ -32,7 +44,11 @@ M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
IntPtrType = SignedInt;
- IntAlign = LongAlign = PointerAlign = 16;
+ if (getTriple().isOSNetBSD()) {
+ IntAlign = LongAlign = PointerAlign = 32;
+ } else {
+ IntAlign = LongAlign = PointerAlign = 16;
+ }
}
bool M68kTargetInfo::setCPU(StringRef Name) {
diff --git a/llvm/lib/TargetParser/TargetDataLayout.cpp b/llvm/lib/TargetParser/TargetDataLayout.cpp
index cab9d7792c787..da6430517ac94 100644
--- a/llvm/lib/TargetParser/TargetDataLayout.cpp
+++ b/llvm/lib/TargetParser/TargetDataLayout.cpp
@@ -122,6 +122,18 @@ static std::string computeLoongArchDataLayout(const Triple &TT) {
return "e-m:e-p:32:32-i64:64-n32-S128";
}
+
+// The Linux m68k target uses the ABI used
+// by Sun Microsystems for the old a.out-based binaries: 16-bit
+// alignment of int/long/pointer.
+//
+// NetBSD/m68k on the other hand uses the SVR4 ABI, which
+// aligns int/long/pointer/objects/stack on 32-bit boundaries.
+//
+// For now we just fix this for NetBSD/m68k.
+//
+// Ref. https://github.com/llvm/llvm-project/issues/199826
+
static std::string computeM68kDataLayout(const Triple &TT) {
std::string Ret = "";
// M68k is Big Endian
@@ -130,22 +142,36 @@ static std::string computeM68kDataLayout(const Triple &TT) {
// FIXME how to wire it with the used object format?
Ret += "-m:e";
- // M68k pointers are always 32 bit wide even for 16-bit CPUs.
- // The ABI only specifies 16-bit alignment.
- // On at least the 68020+ with a 32-bit bus, there is a performance benefit
- // to having 32-bit alignment.
- Ret += "-p:32:16:32";
+ if (! TT.isOSNetBSD()) {
+ // M68k pointers are always 32 bit wide even for 16-bit CPUs.
+ // The ABI only specifies 16-bit alignment.
+ // On at least the 68020+ with a 32-bit bus, there is a performance benefit
+ // to having 32-bit alignment.
+ Ret += "-p:32:16:32";
- // Bytes do not require special alignment, words are word aligned and
- // long words are word aligned at minimum.
- Ret += "-i8:8:8-i16:16:16-i32:16:32";
+ // Bytes do not require special alignment, words are word aligned and
+ // long words are word aligned at minimum.
+ Ret += "-i8:8:8-i16:16:16-i32:16:32";
- // FIXME no floats at the moment
+ // The registers can hold 8, 16, 32 bits
+ Ret += "-n8:16:32";
- // The registers can hold 8, 16, 32 bits
- Ret += "-n8:16:32";
+ Ret += "-a:0:16-S16";
+ } else {
+ // NetBSD/m68k aligns long/pointer/stack/objects on 32-bits,
+ // ref. comment above.
+ Ret += "-p:32:32:32";
+ // Bytes do not require special alignment,
+ // 16-bit ints are 16-bit aligned and
+ // 32-bit ints are 32-bit aligned
+ Ret += "-i8:8:8-i16:16:16-i32:32:32";
+ // The registers can hold 8, 16, 32 bits
+ Ret += "-n8:16:32";
+ // object and stack alignment is also 32 bits
+ Ret += "-a:0:32-S32";
+ }
- Ret += "-a:0:16-S16";
+ // FIXME no floats at the moment
return Ret;
}
More information about the cfe-commits
mailing list