diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-07-02 15:01:50 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-07-02 15:01:50 -0700 |
| commit | 5ae2428d52da3211ee7b1577fe01894dc10f0619 (patch) | |
| tree | 1cafa007289566834d110de803788c5c9cb8a908 /src/codegen/mips | |
| parent | a13f0d40eb0109e993d37ef4be9107a57e821bc9 (diff) | |
| download | zig-5ae2428d52da3211ee7b1577fe01894dc10f0619.tar.gz zig-5ae2428d52da3211ee7b1577fe01894dc10f0619.zip | |
compiler: change canonical path for backend ABI source files
Diffstat (limited to 'src/codegen/mips')
| -rw-r--r-- | src/codegen/mips/abi.zig | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/codegen/mips/abi.zig b/src/codegen/mips/abi.zig new file mode 100644 index 0000000000..02c4c637a4 --- /dev/null +++ b/src/codegen/mips/abi.zig @@ -0,0 +1,84 @@ +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 => { + 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, + } +} |
