aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-09-02 20:26:33 +0300
committerVeikka Tuominen <git@vexu.eu>2022-09-03 01:04:46 +0300
commitb83c037f9ffd7a4285de41c95827615fcbdbbf2f (patch)
tree25b6f3ce249c9b77603a47647fc9d658980da08a /src/arch
parent6aee07c1446f3ce98d326998c887fbca3b7fd945 (diff)
downloadzig-b83c037f9ffd7a4285de41c95827615fcbdbbf2f.tar.gz
zig-b83c037f9ffd7a4285de41c95827615fcbdbbf2f.zip
Sema: only ABI sized packed structs are extern compatible
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/wasm/abi.zig8
-rw-r--r--src/arch/x86_64/abi.zig12
2 files changed, 20 insertions, 0 deletions
diff --git a/src/arch/wasm/abi.zig b/src/arch/wasm/abi.zig
index b1e99f4f92..d54965a50c 100644
--- a/src/arch/wasm/abi.zig
+++ b/src/arch/wasm/abi.zig
@@ -23,6 +23,10 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
if (!ty.hasRuntimeBitsIgnoreComptime()) return none;
switch (ty.zigTypeTag()) {
.Struct => {
+ if (ty.containerLayout() == .Packed) {
+ if (ty.bitSize(target) <= 64) return direct;
+ return .{ .direct, .direct };
+ }
// When the struct type is non-scalar
if (ty.structFieldCount() > 1) return memory;
// When the struct's alignment is non-natural
@@ -57,6 +61,10 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
return direct;
},
.Union => {
+ if (ty.containerLayout() == .Packed) {
+ if (ty.bitSize(target) <= 64) return direct;
+ return .{ .direct, .direct };
+ }
const layout = ty.unionGetLayout(target);
std.debug.assert(layout.tag_size == 0);
if (ty.unionFields().count() > 1) return memory;
diff --git a/src/arch/x86_64/abi.zig b/src/arch/x86_64/abi.zig
index 7e2025a23d..7fede95155 100644
--- a/src/arch/x86_64/abi.zig
+++ b/src/arch/x86_64/abi.zig
@@ -174,6 +174,12 @@ pub fn classifySystemV(ty: Type, target: Target) [8]Class {
// "If the size of the aggregate exceeds a single eightbyte, each is classified
// separately.".
const ty_size = ty.abiSize(target);
+ if (ty.containerLayout() == .Packed) {
+ assert(ty_size <= 128);
+ result[0] = .integer;
+ if (ty_size > 64) result[1] = .integer;
+ return result;
+ }
if (ty_size > 64)
return memory_class;
@@ -284,6 +290,12 @@ pub fn classifySystemV(ty: Type, target: Target) [8]Class {
// "If the size of the aggregate exceeds a single eightbyte, each is classified
// separately.".
const ty_size = ty.abiSize(target);
+ if (ty.containerLayout() == .Packed) {
+ assert(ty_size <= 128);
+ result[0] = .integer;
+ if (ty_size > 64) result[1] = .integer;
+ return result;
+ }
if (ty_size > 64)
return memory_class;