authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-31 14:56:35-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-31 15:09:35-07:00
log2f5892671e49850070064f689a7d8f93d6a7a0dd
treef237a378b22789899fe87fba6b39884c38e5ad12
parent90e48d4b3469fb4f8dd2f3b52e05453029d45fdc

move compiler's CType logic to std.Target

This API only depends on std.Target and is extremely useful in build scripts when populating configure files.

5 files changed, 601 insertions(+), 590 deletions(-)

lib/std/target.zig+553
......@@ -1880,6 +1880,559 @@ pub const Target = struct {
18801880 => 16,
18811881 };
18821882 }
1883
1884 pub const CType = enum {
1885 short,
1886 ushort,
1887 int,
1888 uint,
1889 long,
1890 ulong,
1891 longlong,
1892 ulonglong,
1893 float,
1894 double,
1895 longdouble,
1896 };
1897
1898 pub fn c_type_byte_size(t: Target, c_type: CType) u16 {
1899 return switch (c_type) {
1900 .short,
1901 .ushort,
1902 .int,
1903 .uint,
1904 .long,
1905 .ulong,
1906 .longlong,
1907 .ulonglong,
1908 => @divExact(c_type_bit_size(t, c_type), 8),
1909
1910 .float => 4,
1911 .double => 8,
1912
1913 .longdouble => switch (c_type_bit_size(t, c_type)) {
1914 16 => 2,
1915 32 => 4,
1916 64 => 8,
1917 80 => @intCast(u16, mem.alignForward(10, c_type_alignment(t, .longdouble))),
1918 128 => 16,
1919 else => unreachable,
1920 },
1921 };
1922 }
1923
1924 pub fn c_type_bit_size(target: Target, c_type: CType) u16 {
1925 switch (target.os.tag) {
1926 .freestanding, .other => switch (target.cpu.arch) {
1927 .msp430 => switch (c_type) {
1928 .short, .ushort, .int, .uint => return 16,
1929 .float, .long, .ulong => return 32,
1930 .longlong, .ulonglong, .double, .longdouble => return 64,
1931 },
1932 .avr => switch (c_type) {
1933 .short, .ushort, .int, .uint => return 16,
1934 .long, .ulong, .float, .double, .longdouble => return 32,
1935 .longlong, .ulonglong => return 64,
1936 },
1937 .tce, .tcele => switch (c_type) {
1938 .short, .ushort => return 16,
1939 .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
1940 .float, .double, .longdouble => return 32,
1941 },
1942 .mips64, .mips64el => switch (c_type) {
1943 .short, .ushort => return 16,
1944 .int, .uint, .float => return 32,
1945 .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
1946 .longlong, .ulonglong, .double => return 64,
1947 .longdouble => return 128,
1948 },
1949 .x86_64 => switch (c_type) {
1950 .short, .ushort => return 16,
1951 .int, .uint, .float => return 32,
1952 .long, .ulong => switch (target.abi) {
1953 .gnux32, .muslx32 => return 32,
1954 else => return 64,
1955 },
1956 .longlong, .ulonglong, .double => return 64,
1957 .longdouble => return 80,
1958 },
1959 else => switch (c_type) {
1960 .short, .ushort => return 16,
1961 .int, .uint, .float => return 32,
1962 .long, .ulong => return target.cpu.arch.ptrBitWidth(),
1963 .longlong, .ulonglong, .double => return 64,
1964 .longdouble => switch (target.cpu.arch) {
1965 .x86 => switch (target.abi) {
1966 .android => return 64,
1967 else => return 80,
1968 },
1969
1970 .powerpc,
1971 .powerpcle,
1972 .powerpc64,
1973 .powerpc64le,
1974 => switch (target.abi) {
1975 .musl,
1976 .musleabi,
1977 .musleabihf,
1978 .muslx32,
1979 => return 64,
1980 else => return 128,
1981 },
1982
1983 .riscv32,
1984 .riscv64,
1985 .aarch64,
1986 .aarch64_be,
1987 .aarch64_32,
1988 .s390x,
1989 .sparc,
1990 .sparc64,
1991 .sparcel,
1992 .wasm32,
1993 .wasm64,
1994 => return 128,
1995
1996 else => return 64,
1997 },
1998 },
1999 },
2000
2001 .linux,
2002 .freebsd,
2003 .netbsd,
2004 .dragonfly,
2005 .openbsd,
2006 .wasi,
2007 .emscripten,
2008 .plan9,
2009 .solaris,
2010 .haiku,
2011 .ananas,
2012 .fuchsia,
2013 .minix,
2014 => switch (target.cpu.arch) {
2015 .msp430 => switch (c_type) {
2016 .short, .ushort, .int, .uint => return 16,
2017 .long, .ulong, .float => return 32,
2018 .longlong, .ulonglong, .double, .longdouble => return 64,
2019 },
2020 .avr => switch (c_type) {
2021 .short, .ushort, .int, .uint => return 16,
2022 .long, .ulong, .float, .double, .longdouble => return 32,
2023 .longlong, .ulonglong => return 64,
2024 },
2025 .tce, .tcele => switch (c_type) {
2026 .short, .ushort => return 16,
2027 .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
2028 .float, .double, .longdouble => return 32,
2029 },
2030 .mips64, .mips64el => switch (c_type) {
2031 .short, .ushort => return 16,
2032 .int, .uint, .float => return 32,
2033 .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
2034 .longlong, .ulonglong, .double => return 64,
2035 .longdouble => if (target.os.tag == .freebsd) return 64 else return 128,
2036 },
2037 .x86_64 => switch (c_type) {
2038 .short, .ushort => return 16,
2039 .int, .uint, .float => return 32,
2040 .long, .ulong => switch (target.abi) {
2041 .gnux32, .muslx32 => return 32,
2042 else => return 64,
2043 },
2044 .longlong, .ulonglong, .double => return 64,
2045 .longdouble => return 80,
2046 },
2047 else => switch (c_type) {
2048 .short, .ushort => return 16,
2049 .int, .uint, .float => return 32,
2050 .long, .ulong => return target.cpu.arch.ptrBitWidth(),
2051 .longlong, .ulonglong, .double => return 64,
2052 .longdouble => switch (target.cpu.arch) {
2053 .x86 => switch (target.abi) {
2054 .android => return 64,
2055 else => return 80,
2056 },
2057
2058 .powerpc,
2059 .powerpcle,
2060 => switch (target.abi) {
2061 .musl,
2062 .musleabi,
2063 .musleabihf,
2064 .muslx32,
2065 => return 64,
2066 else => switch (target.os.tag) {
2067 .freebsd, .netbsd, .openbsd => return 64,
2068 else => return 128,
2069 },
2070 },
2071
2072 .powerpc64,
2073 .powerpc64le,
2074 => switch (target.abi) {
2075 .musl,
2076 .musleabi,
2077 .musleabihf,
2078 .muslx32,
2079 => return 64,
2080 else => switch (target.os.tag) {
2081 .freebsd, .openbsd => return 64,
2082 else => return 128,
2083 },
2084 },
2085
2086 .riscv32,
2087 .riscv64,
2088 .aarch64,
2089 .aarch64_be,
2090 .aarch64_32,
2091 .s390x,
2092 .mips64,
2093 .mips64el,
2094 .sparc,
2095 .sparc64,
2096 .sparcel,
2097 .wasm32,
2098 .wasm64,
2099 => return 128,
2100
2101 else => return 64,
2102 },
2103 },
2104 },
2105
2106 .windows, .uefi => switch (target.cpu.arch) {
2107 .x86 => switch (c_type) {
2108 .short, .ushort => return 16,
2109 .int, .uint, .float => return 32,
2110 .long, .ulong => return 32,
2111 .longlong, .ulonglong, .double => return 64,
2112 .longdouble => switch (target.abi) {
2113 .gnu, .gnuilp32, .cygnus => return 80,
2114 else => return 64,
2115 },
2116 },
2117 .x86_64 => switch (c_type) {
2118 .short, .ushort => return 16,
2119 .int, .uint, .float => return 32,
2120 .long, .ulong => switch (target.abi) {
2121 .cygnus => return 64,
2122 else => return 32,
2123 },
2124 .longlong, .ulonglong, .double => return 64,
2125 .longdouble => switch (target.abi) {
2126 .gnu, .gnuilp32, .cygnus => return 80,
2127 else => return 64,
2128 },
2129 },
2130 else => switch (c_type) {
2131 .short, .ushort => return 16,
2132 .int, .uint, .float => return 32,
2133 .long, .ulong => return 32,
2134 .longlong, .ulonglong, .double => return 64,
2135 .longdouble => return 64,
2136 },
2137 },
2138
2139 .macos, .ios, .tvos, .watchos => switch (c_type) {
2140 .short, .ushort => return 16,
2141 .int, .uint, .float => return 32,
2142 .long, .ulong => switch (target.cpu.arch) {
2143 .x86, .arm, .aarch64_32 => return 32,
2144 .x86_64 => switch (target.abi) {
2145 .gnux32, .muslx32 => return 32,
2146 else => return 64,
2147 },
2148 else => return 64,
2149 },
2150 .longlong, .ulonglong, .double => return 64,
2151 .longdouble => switch (target.cpu.arch) {
2152 .x86 => switch (target.abi) {
2153 .android => return 64,
2154 else => return 80,
2155 },
2156 .x86_64 => return 80,
2157 else => return 64,
2158 },
2159 },
2160
2161 .nvcl, .cuda => switch (c_type) {
2162 .short, .ushort => return 16,
2163 .int, .uint, .float => return 32,
2164 .long, .ulong => switch (target.cpu.arch) {
2165 .nvptx => return 32,
2166 .nvptx64 => return 64,
2167 else => return 64,
2168 },
2169 .longlong, .ulonglong, .double => return 64,
2170 .longdouble => return 64,
2171 },
2172
2173 .amdhsa, .amdpal => switch (c_type) {
2174 .short, .ushort => return 16,
2175 .int, .uint, .float => return 32,
2176 .long, .ulong, .longlong, .ulonglong, .double => return 64,
2177 .longdouble => return 128,
2178 },
2179
2180 .cloudabi,
2181 .kfreebsd,
2182 .lv2,
2183 .zos,
2184 .rtems,
2185 .nacl,
2186 .aix,
2187 .ps4,
2188 .ps5,
2189 .elfiamcu,
2190 .mesa3d,
2191 .contiki,
2192 .hermit,
2193 .hurd,
2194 .opencl,
2195 .glsl450,
2196 .vulkan,
2197 .driverkit,
2198 .shadermodel,
2199 => @panic("TODO specify the C integer and float type sizes for this OS"),
2200 }
2201 }
2202
2203 pub fn c_type_alignment(target: Target, c_type: CType) u16 {
2204 // Overrides for unusual alignments
2205 switch (target.cpu.arch) {
2206 .avr => switch (c_type) {
2207 .short, .ushort => return 2,
2208 else => return 1,
2209 },
2210 .x86 => switch (target.os.tag) {
2211 .windows, .uefi => switch (c_type) {
2212 .longlong, .ulonglong, .double => return 8,
2213 .longdouble => switch (target.abi) {
2214 .gnu, .gnuilp32, .cygnus => return 4,
2215 else => return 8,
2216 },
2217 else => {},
2218 },
2219 else => {},
2220 },
2221 else => {},
2222 }
2223
2224 // Next-power-of-two-aligned, up to a maximum.
2225 return @min(
2226 std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8),
2227 switch (target.cpu.arch) {
2228 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
2229 .netbsd => switch (target.abi) {
2230 .gnueabi,
2231 .gnueabihf,
2232 .eabi,
2233 .eabihf,
2234 .android,
2235 .musleabi,
2236 .musleabihf,
2237 => 8,
2238
2239 else => @as(u16, 4),
2240 },
2241 .ios, .tvos, .watchos => 4,
2242 else => 8,
2243 },
2244
2245 .msp430,
2246 .avr,
2247 => 2,
2248
2249 .arc,
2250 .csky,
2251 .x86,
2252 .xcore,
2253 .dxil,
2254 .loongarch32,
2255 .tce,
2256 .tcele,
2257 .le32,
2258 .amdil,
2259 .hsail,
2260 .spir,
2261 .spirv32,
2262 .kalimba,
2263 .shave,
2264 .renderscript32,
2265 .ve,
2266 .spu_2,
2267 => 4,
2268
2269 .aarch64_32,
2270 .amdgcn,
2271 .amdil64,
2272 .bpfel,
2273 .bpfeb,
2274 .hexagon,
2275 .hsail64,
2276 .loongarch64,
2277 .m68k,
2278 .mips,
2279 .mipsel,
2280 .sparc,
2281 .sparcel,
2282 .sparc64,
2283 .lanai,
2284 .le64,
2285 .nvptx,
2286 .nvptx64,
2287 .r600,
2288 .s390x,
2289 .spir64,
2290 .spirv64,
2291 .renderscript64,
2292 => 8,
2293
2294 .aarch64,
2295 .aarch64_be,
2296 .mips64,
2297 .mips64el,
2298 .powerpc,
2299 .powerpcle,
2300 .powerpc64,
2301 .powerpc64le,
2302 .riscv32,
2303 .riscv64,
2304 .x86_64,
2305 .wasm32,
2306 .wasm64,
2307 => 16,
2308 },
2309 );
2310 }
2311
2312 pub fn c_type_preferred_alignment(target: Target, c_type: CType) u16 {
2313 // Overrides for unusual alignments
2314 switch (target.cpu.arch) {
2315 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
2316 .netbsd => switch (target.abi) {
2317 .gnueabi,
2318 .gnueabihf,
2319 .eabi,
2320 .eabihf,
2321 .android,
2322 .musleabi,
2323 .musleabihf,
2324 => {},
2325
2326 else => switch (c_type) {
2327 .longdouble => return 4,
2328 else => {},
2329 },
2330 },
2331 .ios, .tvos, .watchos => switch (c_type) {
2332 .longdouble => return 4,
2333 else => {},
2334 },
2335 else => {},
2336 },
2337 .arc => switch (c_type) {
2338 .longdouble => return 4,
2339 else => {},
2340 },
2341 .avr => switch (c_type) {
2342 .int, .uint, .long, .ulong, .float, .longdouble => return 1,
2343 .short, .ushort => return 2,
2344 .double => return 4,
2345 .longlong, .ulonglong => return 8,
2346 },
2347 .x86 => switch (target.os.tag) {
2348 .windows, .uefi => switch (c_type) {
2349 .longdouble => switch (target.abi) {
2350 .gnu, .gnuilp32, .cygnus => return 4,
2351 else => return 8,
2352 },
2353 else => {},
2354 },
2355 else => switch (c_type) {
2356 .longdouble => return 4,
2357 else => {},
2358 },
2359 },
2360 else => {},
2361 }
2362
2363 // Next-power-of-two-aligned, up to a maximum.
2364 return @min(
2365 std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8),
2366 switch (target.cpu.arch) {
2367 .msp430 => @as(u16, 2),
2368
2369 .csky,
2370 .xcore,
2371 .dxil,
2372 .loongarch32,
2373 .tce,
2374 .tcele,
2375 .le32,
2376 .amdil,
2377 .hsail,
2378 .spir,
2379 .spirv32,
2380 .kalimba,
2381 .shave,
2382 .renderscript32,
2383 .ve,
2384 .spu_2,
2385 => 4,
2386
2387 .arc,
2388 .arm,
2389 .armeb,
2390 .avr,
2391 .thumb,
2392 .thumbeb,
2393 .aarch64_32,
2394 .amdgcn,
2395 .amdil64,
2396 .bpfel,
2397 .bpfeb,
2398 .hexagon,
2399 .hsail64,
2400 .x86,
2401 .loongarch64,
2402 .m68k,
2403 .mips,
2404 .mipsel,
2405 .sparc,
2406 .sparcel,
2407 .sparc64,
2408 .lanai,
2409 .le64,
2410 .nvptx,
2411 .nvptx64,
2412 .r600,
2413 .s390x,
2414 .spir64,
2415 .spirv64,
2416 .renderscript64,
2417 => 8,
2418
2419 .aarch64,
2420 .aarch64_be,
2421 .mips64,
2422 .mips64el,
2423 .powerpc,
2424 .powerpcle,
2425 .powerpc64,
2426 .powerpc64le,
2427 .riscv32,
2428 .riscv64,
2429 .x86_64,
2430 .wasm32,
2431 .wasm64,
2432 => 16,
2433 },
2434 );
2435 }
18832436};
18842437
18852438test {
src/Sema.zig+1-1
......@@ -26076,7 +26076,7 @@ fn coerceVarArgParam(
2607626076 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
2607726077 .Float => float: {
2607826078 const target = sema.mod.getTarget();
26079 const double_bits = @import("type.zig").CType.sizeInBits(.double, target);
26079 const double_bits = target.c_type_bit_size(.double);
2608026080 const inst_bits = uncasted_ty.floatBits(sema.mod.getTarget());
2608126081 if (inst_bits >= double_bits) break :float inst;
2608226082 switch (double_bits) {
src/codegen/c.zig-1
......@@ -16,7 +16,6 @@ const trace = @import("../tracy.zig").trace;
1616const LazySrcLoc = Module.LazySrcLoc;
1717const Air = @import("../Air.zig");
1818const Liveness = @import("../Liveness.zig");
19const CType = @import("../type.zig").CType;
2019
2120const target_util = @import("../target.zig");
2221const libcFloatPrefix = target_util.libcFloatPrefix;
src/codegen/llvm.zig+2-3
......@@ -19,7 +19,6 @@ const Liveness = @import("../Liveness.zig");
1919const Value = @import("../value.zig").Value;
2020const Type = @import("../type.zig").Type;
2121const LazySrcLoc = Module.LazySrcLoc;
22const CType = @import("../type.zig").CType;
2322const x86_64_abi = @import("../arch/x86_64/abi.zig");
2423const wasm_c_abi = @import("../arch/wasm/abi.zig");
2524const aarch64_c_abi = @import("../arch/aarch64/abi.zig");
......@@ -11043,8 +11042,8 @@ fn backendSupportsF128(target: std.Target) bool {
1104311042fn intrinsicsAllowed(scalar_ty: Type, target: std.Target) bool {
1104411043 return switch (scalar_ty.tag()) {
1104511044 .f16 => backendSupportsF16(target),
11046 .f80 => (CType.longdouble.sizeInBits(target) == 80) and backendSupportsF80(target),
11047 .f128 => (CType.longdouble.sizeInBits(target) == 128) and backendSupportsF128(target),
11045 .f80 => (target.c_type_bit_size(.longdouble) == 80) and backendSupportsF80(target),
11046 .f128 => (target.c_type_bit_size(.longdouble) == 128) and backendSupportsF128(target),
1104811047 else => true,
1104911048 };
1105011049}
src/type.zig+45-585
......@@ -2937,24 +2937,24 @@ pub const Type = extern union {
29372937 .anyframe_T,
29382938 => return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
29392939
2940 .c_short => return AbiAlignmentAdvanced{ .scalar = CType.short.alignment(target) },
2941 .c_ushort => return AbiAlignmentAdvanced{ .scalar = CType.ushort.alignment(target) },
2942 .c_int => return AbiAlignmentAdvanced{ .scalar = CType.int.alignment(target) },
2943 .c_uint => return AbiAlignmentAdvanced{ .scalar = CType.uint.alignment(target) },
2944 .c_long => return AbiAlignmentAdvanced{ .scalar = CType.long.alignment(target) },
2945 .c_ulong => return AbiAlignmentAdvanced{ .scalar = CType.ulong.alignment(target) },
2946 .c_longlong => return AbiAlignmentAdvanced{ .scalar = CType.longlong.alignment(target) },
2947 .c_ulonglong => return AbiAlignmentAdvanced{ .scalar = CType.ulonglong.alignment(target) },
2948 .c_longdouble => return AbiAlignmentAdvanced{ .scalar = CType.longdouble.alignment(target) },
2940 .c_short => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.short) },
2941 .c_ushort => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.ushort) },
2942 .c_int => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.int) },
2943 .c_uint => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.uint) },
2944 .c_long => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.long) },
2945 .c_ulong => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.ulong) },
2946 .c_longlong => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longlong) },
2947 .c_ulonglong => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.ulonglong) },
2948 .c_longdouble => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },
29492949
29502950 .f16 => return AbiAlignmentAdvanced{ .scalar = 2 },
2951 .f32 => return AbiAlignmentAdvanced{ .scalar = CType.float.alignment(target) },
2952 .f64 => switch (CType.double.sizeInBits(target)) {
2953 64 => return AbiAlignmentAdvanced{ .scalar = CType.double.alignment(target) },
2951 .f32 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.float) },
2952 .f64 => switch (target.c_type_bit_size(.double)) {
2953 64 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.double) },
29542954 else => return AbiAlignmentAdvanced{ .scalar = 8 },
29552955 },
2956 .f80 => switch (CType.longdouble.sizeInBits(target)) {
2957 80 => return AbiAlignmentAdvanced{ .scalar = CType.longdouble.alignment(target) },
2956 .f80 => switch (target.c_type_bit_size(.longdouble)) {
2957 80 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },
29582958 else => {
29592959 var payload: Payload.Bits = .{
29602960 .base = .{ .tag = .int_unsigned },
......@@ -2964,8 +2964,8 @@ pub const Type = extern union {
29642964 return AbiAlignmentAdvanced{ .scalar = abiAlignment(u80_ty, target) };
29652965 },
29662966 },
2967 .f128 => switch (CType.longdouble.sizeInBits(target)) {
2968 128 => return AbiAlignmentAdvanced{ .scalar = CType.longdouble.alignment(target) },
2967 .f128 => switch (target.c_type_bit_size(.longdouble)) {
2968 128 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },
29692969 else => return AbiAlignmentAdvanced{ .scalar = 16 },
29702970 },
29712971
......@@ -3434,21 +3434,22 @@ pub const Type = extern union {
34343434 else => return AbiSizeAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
34353435 },
34363436
3437 .c_short => return AbiSizeAdvanced{ .scalar = @divExact(CType.short.sizeInBits(target), 8) },
3438 .c_ushort => return AbiSizeAdvanced{ .scalar = @divExact(CType.ushort.sizeInBits(target), 8) },
3439 .c_int => return AbiSizeAdvanced{ .scalar = @divExact(CType.int.sizeInBits(target), 8) },
3440 .c_uint => return AbiSizeAdvanced{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },
3441 .c_long => return AbiSizeAdvanced{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },
3442 .c_ulong => return AbiSizeAdvanced{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },
3443 .c_longlong => return AbiSizeAdvanced{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },
3444 .c_ulonglong => return AbiSizeAdvanced{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },
3437 .c_short => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.short) },
3438 .c_ushort => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ushort) },
3439 .c_int => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.int) },
3440 .c_uint => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.uint) },
3441 .c_long => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.long) },
3442 .c_ulong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ulong) },
3443 .c_longlong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longlong) },
3444 .c_ulonglong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ulonglong) },
3445 .c_longdouble => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },
34453446
34463447 .f16 => return AbiSizeAdvanced{ .scalar = 2 },
34473448 .f32 => return AbiSizeAdvanced{ .scalar = 4 },
34483449 .f64 => return AbiSizeAdvanced{ .scalar = 8 },
34493450 .f128 => return AbiSizeAdvanced{ .scalar = 16 },
3450 .f80 => switch (CType.longdouble.sizeInBits(target)) {
3451 80 => return AbiSizeAdvanced{ .scalar = std.mem.alignForward(10, CType.longdouble.alignment(target)) },
3451 .f80 => switch (target.c_type_bit_size(.longdouble)) {
3452 80 => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },
34523453 else => {
34533454 var payload: Payload.Bits = .{
34543455 .base = .{ .tag = .int_unsigned },
......@@ -3458,14 +3459,6 @@ pub const Type = extern union {
34583459 return AbiSizeAdvanced{ .scalar = abiSize(u80_ty, target) };
34593460 },
34603461 },
3461 .c_longdouble => switch (CType.longdouble.sizeInBits(target)) {
3462 16 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f16, target) },
3463 32 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f32, target) },
3464 64 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f64, target) },
3465 80 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f80, target) },
3466 128 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f128, target) },
3467 else => unreachable,
3468 },
34693462
34703463 // TODO revisit this when we have the concept of the error tag type
34713464 .anyerror_void_error_union,
......@@ -3748,15 +3741,15 @@ pub const Type = extern union {
37483741 .manyptr_const_u8_sentinel_0,
37493742 => return target.cpu.arch.ptrBitWidth(),
37503743
3751 .c_short => return CType.short.sizeInBits(target),
3752 .c_ushort => return CType.ushort.sizeInBits(target),
3753 .c_int => return CType.int.sizeInBits(target),
3754 .c_uint => return CType.uint.sizeInBits(target),
3755 .c_long => return CType.long.sizeInBits(target),
3756 .c_ulong => return CType.ulong.sizeInBits(target),
3757 .c_longlong => return CType.longlong.sizeInBits(target),
3758 .c_ulonglong => return CType.ulonglong.sizeInBits(target),
3759 .c_longdouble => return CType.longdouble.sizeInBits(target),
3744 .c_short => return target.c_type_bit_size(.short),
3745 .c_ushort => return target.c_type_bit_size(.ushort),
3746 .c_int => return target.c_type_bit_size(.int),
3747 .c_uint => return target.c_type_bit_size(.uint),
3748 .c_long => return target.c_type_bit_size(.long),
3749 .c_ulong => return target.c_type_bit_size(.ulong),
3750 .c_longlong => return target.c_type_bit_size(.longlong),
3751 .c_ulonglong => return target.c_type_bit_size(.ulonglong),
3752 .c_longdouble => return target.c_type_bit_size(.longdouble),
37603753
37613754 .error_set,
37623755 .error_set_single,
......@@ -4631,14 +4624,14 @@ pub const Type = extern union {
46314624 .i128 => return .{ .signedness = .signed, .bits = 128 },
46324625 .usize => return .{ .signedness = .unsigned, .bits = target.cpu.arch.ptrBitWidth() },
46334626 .isize => return .{ .signedness = .signed, .bits = target.cpu.arch.ptrBitWidth() },
4634 .c_short => return .{ .signedness = .signed, .bits = CType.short.sizeInBits(target) },
4635 .c_ushort => return .{ .signedness = .unsigned, .bits = CType.ushort.sizeInBits(target) },
4636 .c_int => return .{ .signedness = .signed, .bits = CType.int.sizeInBits(target) },
4637 .c_uint => return .{ .signedness = .unsigned, .bits = CType.uint.sizeInBits(target) },
4638 .c_long => return .{ .signedness = .signed, .bits = CType.long.sizeInBits(target) },
4639 .c_ulong => return .{ .signedness = .unsigned, .bits = CType.ulong.sizeInBits(target) },
4640 .c_longlong => return .{ .signedness = .signed, .bits = CType.longlong.sizeInBits(target) },
4641 .c_ulonglong => return .{ .signedness = .unsigned, .bits = CType.ulonglong.sizeInBits(target) },
4627 .c_short => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.short) },
4628 .c_ushort => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ushort) },
4629 .c_int => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.int) },
4630 .c_uint => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.uint) },
4631 .c_long => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.long) },
4632 .c_ulong => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulong) },
4633 .c_longlong => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.longlong) },
4634 .c_ulonglong => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulonglong) },
46424635
46434636 .enum_full, .enum_nonexhaustive => ty = ty.cast(Payload.EnumFull).?.data.tag_ty,
46444637 .enum_numbered => ty = ty.castTag(.enum_numbered).?.data.tag_ty,
......@@ -4724,7 +4717,7 @@ pub const Type = extern union {
47244717 .f64 => 64,
47254718 .f80 => 80,
47264719 .f128, .comptime_float => 128,
4727 .c_longdouble => CType.longdouble.sizeInBits(target),
4720 .c_longdouble => target.c_type_bit_size(.longdouble),
47284721
47294722 else => unreachable,
47304723 };
......@@ -6689,536 +6682,3 @@ pub const Type = extern union {
66896682 /// to packed struct layout to find out all the places in the codebase you need to edit!
66906683 pub const packed_struct_layout_version = 2;
66916684};
6692
6693pub const CType = enum {
6694 short,
6695 ushort,
6696 int,
6697 uint,
6698 long,
6699 ulong,
6700 longlong,
6701 ulonglong,
6702 longdouble,
6703
6704 // We don't have a `c_float`/`c_double` type in Zig, but these
6705 // are useful for querying target-correct alignment and checking
6706 // whether C's double is f64 or f32
6707 float,
6708 double,
6709
6710 pub fn sizeInBits(self: CType, target: Target) u16 {
6711 switch (target.os.tag) {
6712 .freestanding, .other => switch (target.cpu.arch) {
6713 .msp430 => switch (self) {
6714 .short, .ushort, .int, .uint => return 16,
6715 .float, .long, .ulong => return 32,
6716 .longlong, .ulonglong, .double, .longdouble => return 64,
6717 },
6718 .avr => switch (self) {
6719 .short, .ushort, .int, .uint => return 16,
6720 .long, .ulong, .float, .double, .longdouble => return 32,
6721 .longlong, .ulonglong => return 64,
6722 },
6723 .tce, .tcele => switch (self) {
6724 .short, .ushort => return 16,
6725 .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
6726 .float, .double, .longdouble => return 32,
6727 },
6728 .mips64, .mips64el => switch (self) {
6729 .short, .ushort => return 16,
6730 .int, .uint, .float => return 32,
6731 .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
6732 .longlong, .ulonglong, .double => return 64,
6733 .longdouble => return 128,
6734 },
6735 .x86_64 => switch (self) {
6736 .short, .ushort => return 16,
6737 .int, .uint, .float => return 32,
6738 .long, .ulong => switch (target.abi) {
6739 .gnux32, .muslx32 => return 32,
6740 else => return 64,
6741 },
6742 .longlong, .ulonglong, .double => return 64,
6743 .longdouble => return 80,
6744 },
6745 else => switch (self) {
6746 .short, .ushort => return 16,
6747 .int, .uint, .float => return 32,
6748 .long, .ulong => return target.cpu.arch.ptrBitWidth(),
6749 .longlong, .ulonglong, .double => return 64,
6750 .longdouble => switch (target.cpu.arch) {
6751 .x86 => switch (target.abi) {
6752 .android => return 64,
6753 else => return 80,
6754 },
6755
6756 .powerpc,
6757 .powerpcle,
6758 .powerpc64,
6759 .powerpc64le,
6760 => switch (target.abi) {
6761 .musl,
6762 .musleabi,
6763 .musleabihf,
6764 .muslx32,
6765 => return 64,
6766 else => return 128,
6767 },
6768
6769 .riscv32,
6770 .riscv64,
6771 .aarch64,
6772 .aarch64_be,
6773 .aarch64_32,
6774 .s390x,
6775 .sparc,
6776 .sparc64,
6777 .sparcel,
6778 .wasm32,
6779 .wasm64,
6780 => return 128,
6781
6782 else => return 64,
6783 },
6784 },
6785 },
6786
6787 .linux,
6788 .freebsd,
6789 .netbsd,
6790 .dragonfly,
6791 .openbsd,
6792 .wasi,
6793 .emscripten,
6794 .plan9,
6795 .solaris,
6796 .haiku,
6797 .ananas,
6798 .fuchsia,
6799 .minix,
6800 => switch (target.cpu.arch) {
6801 .msp430 => switch (self) {
6802 .short, .ushort, .int, .uint => return 16,
6803 .long, .ulong, .float => return 32,
6804 .longlong, .ulonglong, .double, .longdouble => return 64,
6805 },
6806 .avr => switch (self) {
6807 .short, .ushort, .int, .uint => return 16,
6808 .long, .ulong, .float, .double, .longdouble => return 32,
6809 .longlong, .ulonglong => return 64,
6810 },
6811 .tce, .tcele => switch (self) {
6812 .short, .ushort => return 16,
6813 .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
6814 .float, .double, .longdouble => return 32,
6815 },
6816 .mips64, .mips64el => switch (self) {
6817 .short, .ushort => return 16,
6818 .int, .uint, .float => return 32,
6819 .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
6820 .longlong, .ulonglong, .double => return 64,
6821 .longdouble => if (target.os.tag == .freebsd) return 64 else return 128,
6822 },
6823 .x86_64 => switch (self) {
6824 .short, .ushort => return 16,
6825 .int, .uint, .float => return 32,
6826 .long, .ulong => switch (target.abi) {
6827 .gnux32, .muslx32 => return 32,
6828 else => return 64,
6829 },
6830 .longlong, .ulonglong, .double => return 64,
6831 .longdouble => return 80,
6832 },
6833 else => switch (self) {
6834 .short, .ushort => return 16,
6835 .int, .uint, .float => return 32,
6836 .long, .ulong => return target.cpu.arch.ptrBitWidth(),
6837 .longlong, .ulonglong, .double => return 64,
6838 .longdouble => switch (target.cpu.arch) {
6839 .x86 => switch (target.abi) {
6840 .android => return 64,
6841 else => return 80,
6842 },
6843
6844 .powerpc,
6845 .powerpcle,
6846 => switch (target.abi) {
6847 .musl,
6848 .musleabi,
6849 .musleabihf,
6850 .muslx32,
6851 => return 64,
6852 else => switch (target.os.tag) {
6853 .freebsd, .netbsd, .openbsd => return 64,
6854 else => return 128,
6855 },
6856 },
6857
6858 .powerpc64,
6859 .powerpc64le,
6860 => switch (target.abi) {
6861 .musl,
6862 .musleabi,
6863 .musleabihf,
6864 .muslx32,
6865 => return 64,
6866 else => switch (target.os.tag) {
6867 .freebsd, .openbsd => return 64,
6868 else => return 128,
6869 },
6870 },
6871
6872 .riscv32,
6873 .riscv64,
6874 .aarch64,
6875 .aarch64_be,
6876 .aarch64_32,
6877 .s390x,
6878 .mips64,
6879 .mips64el,
6880 .sparc,
6881 .sparc64,
6882 .sparcel,
6883 .wasm32,
6884 .wasm64,
6885 => return 128,
6886
6887 else => return 64,
6888 },
6889 },
6890 },
6891
6892 .windows, .uefi => switch (target.cpu.arch) {
6893 .x86 => switch (self) {
6894 .short, .ushort => return 16,
6895 .int, .uint, .float => return 32,
6896 .long, .ulong => return 32,
6897 .longlong, .ulonglong, .double => return 64,
6898 .longdouble => switch (target.abi) {
6899 .gnu, .gnuilp32, .cygnus => return 80,
6900 else => return 64,
6901 },
6902 },
6903 .x86_64 => switch (self) {
6904 .short, .ushort => return 16,
6905 .int, .uint, .float => return 32,
6906 .long, .ulong => switch (target.abi) {
6907 .cygnus => return 64,
6908 else => return 32,
6909 },
6910 .longlong, .ulonglong, .double => return 64,
6911 .longdouble => switch (target.abi) {
6912 .gnu, .gnuilp32, .cygnus => return 80,
6913 else => return 64,
6914 },
6915 },
6916 else => switch (self) {
6917 .short, .ushort => return 16,
6918 .int, .uint, .float => return 32,
6919 .long, .ulong => return 32,
6920 .longlong, .ulonglong, .double => return 64,
6921 .longdouble => return 64,
6922 },
6923 },
6924
6925 .macos, .ios, .tvos, .watchos => switch (self) {
6926 .short, .ushort => return 16,
6927 .int, .uint, .float => return 32,
6928 .long, .ulong => switch (target.cpu.arch) {
6929 .x86, .arm, .aarch64_32 => return 32,
6930 .x86_64 => switch (target.abi) {
6931 .gnux32, .muslx32 => return 32,
6932 else => return 64,
6933 },
6934 else => return 64,
6935 },
6936 .longlong, .ulonglong, .double => return 64,
6937 .longdouble => switch (target.cpu.arch) {
6938 .x86 => switch (target.abi) {
6939 .android => return 64,
6940 else => return 80,
6941 },
6942 .x86_64 => return 80,
6943 else => return 64,
6944 },
6945 },
6946
6947 .nvcl, .cuda => switch (self) {
6948 .short, .ushort => return 16,
6949 .int, .uint, .float => return 32,
6950 .long, .ulong => switch (target.cpu.arch) {
6951 .nvptx => return 32,
6952 .nvptx64 => return 64,
6953 else => return 64,
6954 },
6955 .longlong, .ulonglong, .double => return 64,
6956 .longdouble => return 64,
6957 },
6958
6959 .amdhsa, .amdpal => switch (self) {
6960 .short, .ushort => return 16,
6961 .int, .uint, .float => return 32,
6962 .long, .ulong, .longlong, .ulonglong, .double => return 64,
6963 .longdouble => return 128,
6964 },
6965
6966 .cloudabi,
6967 .kfreebsd,
6968 .lv2,
6969 .zos,
6970 .rtems,
6971 .nacl,
6972 .aix,
6973 .ps4,
6974 .ps5,
6975 .elfiamcu,
6976 .mesa3d,
6977 .contiki,
6978 .hermit,
6979 .hurd,
6980 .opencl,
6981 .glsl450,
6982 .vulkan,
6983 .driverkit,
6984 .shadermodel,
6985 => @panic("TODO specify the C integer and float type sizes for this OS"),
6986 }
6987 }
6988
6989 pub fn alignment(self: CType, target: Target) u16 {
6990
6991 // Overrides for unusual alignments
6992 switch (target.cpu.arch) {
6993 .avr => switch (self) {
6994 .short, .ushort => return 2,
6995 else => return 1,
6996 },
6997 .x86 => switch (target.os.tag) {
6998 .windows, .uefi => switch (self) {
6999 .longlong, .ulonglong, .double => return 8,
7000 .longdouble => switch (target.abi) {
7001 .gnu, .gnuilp32, .cygnus => return 4,
7002 else => return 8,
7003 },
7004 else => {},
7005 },
7006 else => {},
7007 },
7008 else => {},
7009 }
7010
7011 // Next-power-of-two-aligned, up to a maximum.
7012 return @min(
7013 std.math.ceilPowerOfTwoAssert(u16, (self.sizeInBits(target) + 7) / 8),
7014 switch (target.cpu.arch) {
7015 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
7016 .netbsd => switch (target.abi) {
7017 .gnueabi,
7018 .gnueabihf,
7019 .eabi,
7020 .eabihf,
7021 .android,
7022 .musleabi,
7023 .musleabihf,
7024 => 8,
7025
7026 else => @as(u16, 4),
7027 },
7028 .ios, .tvos, .watchos => 4,
7029 else => 8,
7030 },
7031
7032 .msp430,
7033 .avr,
7034 => 2,
7035
7036 .arc,
7037 .csky,
7038 .x86,
7039 .xcore,
7040 .dxil,
7041 .loongarch32,
7042 .tce,
7043 .tcele,
7044 .le32,
7045 .amdil,
7046 .hsail,
7047 .spir,
7048 .spirv32,
7049 .kalimba,
7050 .shave,
7051 .renderscript32,
7052 .ve,
7053 .spu_2,
7054 => 4,
7055
7056 .aarch64_32,
7057 .amdgcn,
7058 .amdil64,
7059 .bpfel,
7060 .bpfeb,
7061 .hexagon,
7062 .hsail64,
7063 .loongarch64,
7064 .m68k,
7065 .mips,
7066 .mipsel,
7067 .sparc,
7068 .sparcel,
7069 .sparc64,
7070 .lanai,
7071 .le64,
7072 .nvptx,
7073 .nvptx64,
7074 .r600,
7075 .s390x,
7076 .spir64,
7077 .spirv64,
7078 .renderscript64,
7079 => 8,
7080
7081 .aarch64,
7082 .aarch64_be,
7083 .mips64,
7084 .mips64el,
7085 .powerpc,
7086 .powerpcle,
7087 .powerpc64,
7088 .powerpc64le,
7089 .riscv32,
7090 .riscv64,
7091 .x86_64,
7092 .wasm32,
7093 .wasm64,
7094 => 16,
7095 },
7096 );
7097 }
7098
7099 pub fn preferredAlignment(self: CType, target: Target) u16 {
7100
7101 // Overrides for unusual alignments
7102 switch (target.cpu.arch) {
7103 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
7104 .netbsd => switch (target.abi) {
7105 .gnueabi,
7106 .gnueabihf,
7107 .eabi,
7108 .eabihf,
7109 .android,
7110 .musleabi,
7111 .musleabihf,
7112 => {},
7113
7114 else => switch (self) {
7115 .longdouble => return 4,
7116 else => {},
7117 },
7118 },
7119 .ios, .tvos, .watchos => switch (self) {
7120 .longdouble => return 4,
7121 else => {},
7122 },
7123 else => {},
7124 },
7125 .arc => switch (self) {
7126 .longdouble => return 4,
7127 else => {},
7128 },
7129 .avr => switch (self) {
7130 .int, .uint, .long, .ulong, .float, .longdouble => return 1,
7131 .short, .ushort => return 2,
7132 .double => return 4,
7133 .longlong, .ulonglong => return 8,
7134 },
7135 .x86 => switch (target.os.tag) {
7136 .windows, .uefi => switch (self) {
7137 .longdouble => switch (target.abi) {
7138 .gnu, .gnuilp32, .cygnus => return 4,
7139 else => return 8,
7140 },
7141 else => {},
7142 },
7143 else => switch (self) {
7144 .longdouble => return 4,
7145 else => {},
7146 },
7147 },
7148 else => {},
7149 }
7150
7151 // Next-power-of-two-aligned, up to a maximum.
7152 return @min(
7153 std.math.ceilPowerOfTwoAssert(u16, (self.sizeInBits(target) + 7) / 8),
7154 switch (target.cpu.arch) {
7155 .msp430 => @as(u16, 2),
7156
7157 .csky,
7158 .xcore,
7159 .dxil,
7160 .loongarch32,
7161 .tce,
7162 .tcele,
7163 .le32,
7164 .amdil,
7165 .hsail,
7166 .spir,
7167 .spirv32,
7168 .kalimba,
7169 .shave,
7170 .renderscript32,
7171 .ve,
7172 .spu_2,
7173 => 4,
7174
7175 .arc,
7176 .arm,
7177 .armeb,
7178 .avr,
7179 .thumb,
7180 .thumbeb,
7181 .aarch64_32,
7182 .amdgcn,
7183 .amdil64,
7184 .bpfel,
7185 .bpfeb,
7186 .hexagon,
7187 .hsail64,
7188 .x86,
7189 .loongarch64,
7190 .m68k,
7191 .mips,
7192 .mipsel,
7193 .sparc,
7194 .sparcel,
7195 .sparc64,
7196 .lanai,
7197 .le64,
7198 .nvptx,
7199 .nvptx64,
7200 .r600,
7201 .s390x,
7202 .spir64,
7203 .spirv64,
7204 .renderscript64,
7205 => 8,
7206
7207 .aarch64,
7208 .aarch64_be,
7209 .mips64,
7210 .mips64el,
7211 .powerpc,
7212 .powerpcle,
7213 .powerpc64,
7214 .powerpc64le,
7215 .riscv32,
7216 .riscv64,
7217 .x86_64,
7218 .wasm32,
7219 .wasm64,
7220 => 16,
7221 },
7222 );
7223 }
7224};