Commit fb0028a0d7

Maciej 'vesim' Kuliński <vesim809@pm.me>
2024-09-07 17:29:43
mips: fix C ABI compatibility
1 parent fb81522
Changed files (4)
src
arch
mips
codegen
test
src/arch/mips/abi.zig
@@ -0,0 +1,86 @@
+const std = @import("std");
+const Type = @import("../../Type.zig");
+const Zcu = @import("../../Zcu.zig");
+const assert = std.debug.assert;
+
+pub const Class = union(enum) {
+    memory,
+    byval,
+    i32_array: u8,
+};
+
+pub const Context = enum { ret, arg };
+
+pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
+    const target = zcu.getTarget();
+    std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
+
+    const max_direct_size = target.ptrBitWidth() * 2;
+    switch (ty.zigTypeTag(zcu)) {
+        .@"struct" => {
+            const bit_size = ty.bitSize(zcu);
+            if (ty.containerLayout(zcu) == .@"packed") {
+                if (bit_size > max_direct_size) return .memory;
+                return .byval;
+            }
+            if (bit_size > max_direct_size) return .memory;
+            // TODO: for bit_size <= 32 using byval is more correct, but that needs inreg argument attribute
+            const count = @as(u8, @intCast(std.mem.alignForward(u64, bit_size, 32) / 32));
+            return .{ .i32_array = count };
+        },
+        .@"union" => {
+            const bit_size = ty.bitSize(zcu);
+            if (ty.containerLayout(zcu) == .@"packed") {
+                if (bit_size > max_direct_size) return .memory;
+                return .byval;
+            }
+            if (bit_size > max_direct_size) return .memory;
+
+            return .byval;
+        },
+        .bool => return .byval,
+        .float => return .byval,
+        .int, .@"enum", .error_set => {
+            const bit_size = ty.bitSize(zcu);
+            if (bit_size > max_direct_size) return .memory;
+            return .byval;
+        },
+        .vector => {
+            const elem_type = ty.elemType2(zcu);
+            switch (elem_type.zigTypeTag(zcu)) {
+                .bool, .int => {
+                    const bit_size = ty.bitSize(zcu);
+                    if (ctx == .ret and bit_size > 128) return .memory;
+                    if (bit_size > 512) return .memory;
+                    // TODO: byval vector arguments with non power of 2 size need inreg attribute
+                    return .byval;
+                },
+                .float => return .memory,
+                else => unreachable,
+            }
+        },
+        .optional => {
+            std.debug.assert(ty.isPtrLikeOptional(zcu));
+            return .byval;
+        },
+        .pointer => {
+            std.debug.assert(!ty.isSlice(zcu));
+            return .byval;
+        },
+        .error_union,
+        .frame,
+        .@"anyframe",
+        .noreturn,
+        .void,
+        .type,
+        .comptime_float,
+        .comptime_int,
+        .undefined,
+        .null,
+        .@"fn",
+        .@"opaque",
+        .enum_literal,
+        .array,
+        => unreachable,
+    }
+}
src/codegen/llvm.zig
@@ -26,6 +26,7 @@ const wasm_c_abi = @import("../arch/wasm/abi.zig");
 const aarch64_c_abi = @import("../arch/aarch64/abi.zig");
 const arm_c_abi = @import("../arch/arm/abi.zig");
 const riscv_c_abi = @import("../arch/riscv64/abi.zig");
+const mips_c_abi = @import("../arch/mips/abi.zig");
 const dev = @import("../dev.zig");
 
 const target_util = @import("../target.zig");
@@ -11681,7 +11682,10 @@ fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Targe
     return switch (fn_info.cc) {
         .Unspecified, .Inline => returnTypeByRef(zcu, target, return_type),
         .C => switch (target.cpu.arch) {
-            .mips, .mipsel => false,
+            .mips, .mipsel => switch (mips_c_abi.classifyType(return_type, zcu, .ret)) {
+                .memory, .i32_array => true,
+                .byval => false,
+            },
             .x86 => isByRef(return_type, zcu),
             .x86_64 => switch (target.os.tag) {
                 .windows => x86_64_abi.classifyWindows(return_type, zcu) == .memory,
@@ -11732,7 +11736,12 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
 
         .C => {
             switch (target.cpu.arch) {
-                .mips, .mipsel => return o.lowerType(return_type),
+                .mips, .mipsel => {
+                    switch (mips_c_abi.classifyType(return_type, zcu, .ret)) {
+                        .memory, .i32_array => return .void,
+                        .byval => return o.lowerType(return_type),
+                    }
+                },
                 .x86 => return if (isByRef(return_type, zcu)) .void else o.lowerType(return_type),
                 .x86_64 => switch (target.os.tag) {
                     .windows => return lowerWin64FnRetTy(o, fn_info),
@@ -11978,7 +11987,14 @@ const ParamTypeIterator = struct {
                 .mips, .mipsel => {
                     it.zig_index += 1;
                     it.llvm_index += 1;
-                    return .byval;
+                    switch (mips_c_abi.classifyType(ty, zcu, .arg)) {
+                        .memory => {
+                            it.byval_attr = true;
+                            return .byref;
+                        },
+                        .byval => return .byval,
+                        .i32_array => |size| return Lowering{ .i32_array = size },
+                    }
                 },
                 .x86_64 => switch (target.os.tag) {
                     .windows => return it.nextWin64(ty),
test/c_abi/cfuncs.c
@@ -2657,7 +2657,7 @@ void run_c_tests(void) {
     }
 #endif
 
-#if !defined(__mips__) && !defined(ZIG_PPC32)
+#if !defined(ZIG_PPC32)
     {
         struct Struct_u64_u64 s = zig_ret_struct_u64_u64();
         assert_or_panic(s.a == 1);
@@ -2708,7 +2708,7 @@ void run_c_tests(void) {
 #endif
 
 #if !defined __i386__ && !defined __arm__ && !defined __aarch64__ && \
-    !defined __mips__ && !defined __powerpc__ && !defined ZIG_RISCV64
+    !defined __powerpc__ && !defined ZIG_RISCV64
     {
         struct SmallStructInts s = {1, 2, 3, 4};
         zig_small_struct_ints(s);
@@ -2716,7 +2716,7 @@ void run_c_tests(void) {
 #endif
 
 #if !defined __arm__ && !defined __aarch64__ && \
-    !defined __mips__ && !defined __powerpc__ && !defined ZIG_RISCV64
+    !defined __powerpc__ && !defined ZIG_RISCV64
     {
         struct MedStructInts s = {1, 2, 3};
         zig_med_struct_ints(s);
@@ -2741,7 +2741,7 @@ void run_c_tests(void) {
         zig_small_packed_struct(s);
     }
 
-#if !defined __i386__ && !defined __arm__ && !defined __mips__ && \
+#if !defined __i386__ && !defined __arm__ && \
     !defined ZIG_PPC32 && !defined _ARCH_PPC64
     {
         struct SplitStructInts s = {1234, 100, 1337};
@@ -2756,7 +2756,7 @@ void run_c_tests(void) {
     }
 #endif
 
-#if !defined __i386__ && !defined __arm__ && !defined __mips__ && \
+#if !defined __i386__ && !defined __arm__ && \
     !defined ZIG_PPC32 && !defined _ARCH_PPC64
     {
         struct SplitStructMixed s = {1234, 100, 1337.0f};
@@ -2764,7 +2764,7 @@ void run_c_tests(void) {
     }
 #endif
 
-#if !defined __mips__ && !defined ZIG_PPC32
+#if !defined ZIG_PPC32
     {
         struct BigStruct s = {30, 31, 32, 33, 34};
         struct BigStruct res = zig_big_struct_both(s);
@@ -2784,7 +2784,7 @@ void run_c_tests(void) {
     }
 #endif
 
-#if !defined __mips__ && !defined ZIG_PPC32
+#if !defined ZIG_PPC32
     {
         struct FloatRect r1 = {1, 21, 16, 4};
         struct FloatRect r2 = {178, 189, 21, 15};
test/c_abi/main.zig
@@ -322,7 +322,7 @@ extern fn c_struct_u64_u64_7(usize, usize, usize, usize, usize, usize, usize, St
 extern fn c_struct_u64_u64_8(usize, usize, usize, usize, usize, usize, usize, usize, Struct_u64_u64) void;
 
 test "C ABI struct u64 u64" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
     const s = c_ret_struct_u64_u64();
@@ -359,7 +359,7 @@ extern fn c_ret_struct_f32f32_f32() Struct_f32f32_f32;
 extern fn c_struct_f32f32_f32(Struct_f32f32_f32) void;
 
 test "C ABI struct {f32,f32} f32" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
     const s = c_ret_struct_f32f32_f32();
@@ -389,7 +389,7 @@ extern fn c_ret_struct_f32_f32f32() Struct_f32_f32f32;
 extern fn c_struct_f32_f32f32(Struct_f32_f32f32) void;
 
 test "C ABI struct f32 {f32,f32}" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
     const s = c_ret_struct_f32_f32f32();
@@ -424,7 +424,7 @@ extern fn c_ret_struct_u32_union_u32_u32u32() Struct_u32_Union_u32_u32u32;
 extern fn c_struct_u32_union_u32_u32u32(Struct_u32_Union_u32_u32u32) void;
 
 test "C ABI struct{u32,union{u32,struct{u32,u32}}}" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     const s = c_ret_struct_u32_union_u32_u32u32();
@@ -444,7 +444,7 @@ const BigStruct = extern struct {
 extern fn c_big_struct(BigStruct) void;
 
 test "C ABI big struct" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
     const s = BigStruct{
@@ -503,7 +503,7 @@ extern fn c_med_struct_mixed(MedStructMixed) void;
 extern fn c_ret_med_struct_mixed() MedStructMixed;
 
 test "C ABI medium struct of ints and floats" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     const s = MedStructMixed{
@@ -535,7 +535,7 @@ extern fn c_ret_small_struct_ints() SmallStructInts;
 
 test "C ABI small struct of ints" {
     if (builtin.cpu.arch == .x86) return error.SkipZigTest;
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     const s = SmallStructInts{
@@ -568,7 +568,7 @@ extern fn c_med_struct_ints(MedStructInts) void;
 extern fn c_ret_med_struct_ints() MedStructInts;
 
 test "C ABI medium struct of ints" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     const s = MedStructInts{
@@ -646,7 +646,7 @@ extern fn c_split_struct_ints(SplitStructInt) void;
 
 test "C ABI split struct of ints" {
     if (builtin.cpu.arch == .x86) return error.SkipZigTest;
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     const s = SplitStructInt{
@@ -673,7 +673,7 @@ extern fn c_ret_split_struct_mixed() SplitStructMixed;
 
 test "C ABI split struct of ints and floats" {
     if (builtin.cpu.arch == .x86) return error.SkipZigTest;
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     const s = SplitStructMixed{
@@ -700,7 +700,7 @@ extern fn c_multiple_struct_ints(Rect, Rect) void;
 extern fn c_multiple_struct_floats(FloatRect, FloatRect) void;
 
 test "C ABI sret and byval together" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
     const s = BigStruct{
@@ -752,7 +752,7 @@ const Vector5 = extern struct {
 extern fn c_big_struct_floats(Vector5) void;
 
 test "C ABI structs of floats as parameter" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     const v3 = Vector3{
@@ -828,7 +828,7 @@ export fn zig_multiple_struct_floats(x: FloatRect, y: FloatRect) void {
 }
 
 test "C ABI structs of floats as multiple parameters" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
     const r1 = FloatRect{
@@ -941,7 +941,7 @@ extern fn c_ret_struct_with_array() StructWithArray;
 
 test "Struct with array as padding." {
     if (builtin.cpu.arch == .x86) return error.SkipZigTest;
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     c_struct_with_array(.{ .a = 1, .padding = undefined, .b = 2 });
@@ -966,7 +966,7 @@ extern fn c_float_array_struct(FloatArrayStruct) void;
 extern fn c_ret_float_array_struct() FloatArrayStruct;
 
 test "Float array like struct" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
     c_float_array_struct(.{
@@ -1031,7 +1031,7 @@ extern fn c_ret_big_vec() BigVec;
 test "big simd vector" {
     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
 
-    if (builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64() and builtin.mode != .Debug) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag == .macos and builtin.mode != .Debug) return error.SkipZigTest;
 
@@ -5340,7 +5340,7 @@ extern fn c_ptr_size_float_struct(Vector2) void;
 extern fn c_ret_ptr_size_float_struct() Vector2;
 
 test "C ABI pointer sized float struct" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
@@ -5362,25 +5362,25 @@ pub inline fn expectOk(c_err: c_int) !void {
 /// Tests for Double + Char struct
 const DC = extern struct { v1: f64, v2: u8 };
 test "DC: Zig passes to C" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectOk(c_assert_DC(.{ .v1 = -0.25, .v2 = 15 }));
 }
 test "DC: Zig returns to C" {
-    if (builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64() and builtin.mode != .Debug) return error.SkipZigTest;
     if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectOk(c_assert_ret_DC());
 }
 test "DC: C passes to Zig" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectOk(c_send_DC());
 }
 test "DC: C returns to Zig" {
-    if (builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64() and builtin.mode != .Debug) return error.SkipZigTest;
     if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectEqual(DC{ .v1 = -0.25, .v2 = 15 }, c_ret_DC());
@@ -5406,12 +5406,12 @@ const CFF = extern struct { v1: u8, v2: f32, v3: f32 };
 
 test "CFF: Zig passes to C" {
     if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectOk(c_assert_CFF(.{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }));
 }
 test "CFF: Zig returns to C" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectOk(c_assert_ret_CFF());
 }
@@ -5419,7 +5419,7 @@ test "CFF: C passes to Zig" {
     if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
     if (builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
     if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     try expectOk(c_send_CFF());
@@ -5427,7 +5427,7 @@ test "CFF: C passes to Zig" {
 test "CFF: C returns to Zig" {
     if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
     if (builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectEqual(CFF{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }, c_ret_CFF());
 }
@@ -5451,22 +5451,22 @@ pub export fn zig_ret_CFF() CFF {
 const PD = extern struct { v1: ?*anyopaque, v2: f64 };
 
 test "PD: Zig passes to C" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectOk(c_assert_PD(.{ .v1 = null, .v2 = 0.5 }));
 }
 test "PD: Zig returns to C" {
-    if (builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64() and builtin.mode != .Debug) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectOk(c_assert_ret_PD());
 }
 test "PD: C passes to Zig" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectOk(c_send_PD());
 }
 test "PD: C returns to Zig" {
-    if (builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64() and builtin.mode != .Debug) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
     try expectEqual(PD{ .v1 = null, .v2 = 0.5 }, c_ret_PD());
 }
@@ -5520,7 +5520,7 @@ const ByVal = extern struct {
 
 extern fn c_func_ptr_byval(*anyopaque, *anyopaque, ByVal, c_ulong, *anyopaque, c_ulong) void;
 test "C function that takes byval struct called via function pointer" {
-    if (builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64() and builtin.mode != .Debug) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
     var fn_ptr = &c_func_ptr_byval;
@@ -5551,7 +5551,7 @@ const f16_struct = extern struct {
 };
 extern fn c_f16_struct(f16_struct) f16_struct;
 test "f16 struct" {
-    if (builtin.target.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.target.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.target.cpu.arch.isPowerPC32()) return error.SkipZigTest;
     if (builtin.cpu.arch.isARM() and builtin.mode != .Debug) return error.SkipZigTest;
 
@@ -5666,7 +5666,7 @@ const Coord2 = extern struct {
 
 extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2;
 test "Stdcall ABI structs" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
 
     const res = stdcall_coord2(
@@ -5751,7 +5751,7 @@ const byval_tail_callsite_attr = struct {
 };
 
 test "byval tail callsite attribute" {
-    if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+    if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
     if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
 
     // Originally reported at https://github.com/ziglang/zig/issues/16290