Commit 2f5892671e

Andrew Kelley <andrew@ziglang.org>
2023-01-31 22:56:35
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.
1 parent 90e48d4
Changed files (5)
lib/std/target.zig
@@ -1880,6 +1880,559 @@ pub const Target = struct {
             => 16,
         };
     }
+
+    pub const CType = enum {
+        short,
+        ushort,
+        int,
+        uint,
+        long,
+        ulong,
+        longlong,
+        ulonglong,
+        float,
+        double,
+        longdouble,
+    };
+
+    pub fn c_type_byte_size(t: Target, c_type: CType) u16 {
+        return switch (c_type) {
+            .short,
+            .ushort,
+            .int,
+            .uint,
+            .long,
+            .ulong,
+            .longlong,
+            .ulonglong,
+            => @divExact(c_type_bit_size(t, c_type), 8),
+
+            .float => 4,
+            .double => 8,
+
+            .longdouble => switch (c_type_bit_size(t, c_type)) {
+                16 => 2,
+                32 => 4,
+                64 => 8,
+                80 => @intCast(u16, mem.alignForward(10, c_type_alignment(t, .longdouble))),
+                128 => 16,
+                else => unreachable,
+            },
+        };
+    }
+
+    pub fn c_type_bit_size(target: Target, c_type: CType) u16 {
+        switch (target.os.tag) {
+            .freestanding, .other => switch (target.cpu.arch) {
+                .msp430 => switch (c_type) {
+                    .short, .ushort, .int, .uint => return 16,
+                    .float, .long, .ulong => return 32,
+                    .longlong, .ulonglong, .double, .longdouble => return 64,
+                },
+                .avr => switch (c_type) {
+                    .short, .ushort, .int, .uint => return 16,
+                    .long, .ulong, .float, .double, .longdouble => return 32,
+                    .longlong, .ulonglong => return 64,
+                },
+                .tce, .tcele => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
+                    .float, .double, .longdouble => return 32,
+                },
+                .mips64, .mips64el => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .float => return 32,
+                    .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
+                    .longlong, .ulonglong, .double => return 64,
+                    .longdouble => return 128,
+                },
+                .x86_64 => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .float => return 32,
+                    .long, .ulong => switch (target.abi) {
+                        .gnux32, .muslx32 => return 32,
+                        else => return 64,
+                    },
+                    .longlong, .ulonglong, .double => return 64,
+                    .longdouble => return 80,
+                },
+                else => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .float => return 32,
+                    .long, .ulong => return target.cpu.arch.ptrBitWidth(),
+                    .longlong, .ulonglong, .double => return 64,
+                    .longdouble => switch (target.cpu.arch) {
+                        .x86 => switch (target.abi) {
+                            .android => return 64,
+                            else => return 80,
+                        },
+
+                        .powerpc,
+                        .powerpcle,
+                        .powerpc64,
+                        .powerpc64le,
+                        => switch (target.abi) {
+                            .musl,
+                            .musleabi,
+                            .musleabihf,
+                            .muslx32,
+                            => return 64,
+                            else => return 128,
+                        },
+
+                        .riscv32,
+                        .riscv64,
+                        .aarch64,
+                        .aarch64_be,
+                        .aarch64_32,
+                        .s390x,
+                        .sparc,
+                        .sparc64,
+                        .sparcel,
+                        .wasm32,
+                        .wasm64,
+                        => return 128,
+
+                        else => return 64,
+                    },
+                },
+            },
+
+            .linux,
+            .freebsd,
+            .netbsd,
+            .dragonfly,
+            .openbsd,
+            .wasi,
+            .emscripten,
+            .plan9,
+            .solaris,
+            .haiku,
+            .ananas,
+            .fuchsia,
+            .minix,
+            => switch (target.cpu.arch) {
+                .msp430 => switch (c_type) {
+                    .short, .ushort, .int, .uint => return 16,
+                    .long, .ulong, .float => return 32,
+                    .longlong, .ulonglong, .double, .longdouble => return 64,
+                },
+                .avr => switch (c_type) {
+                    .short, .ushort, .int, .uint => return 16,
+                    .long, .ulong, .float, .double, .longdouble => return 32,
+                    .longlong, .ulonglong => return 64,
+                },
+                .tce, .tcele => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
+                    .float, .double, .longdouble => return 32,
+                },
+                .mips64, .mips64el => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .float => return 32,
+                    .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
+                    .longlong, .ulonglong, .double => return 64,
+                    .longdouble => if (target.os.tag == .freebsd) return 64 else return 128,
+                },
+                .x86_64 => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .float => return 32,
+                    .long, .ulong => switch (target.abi) {
+                        .gnux32, .muslx32 => return 32,
+                        else => return 64,
+                    },
+                    .longlong, .ulonglong, .double => return 64,
+                    .longdouble => return 80,
+                },
+                else => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .float => return 32,
+                    .long, .ulong => return target.cpu.arch.ptrBitWidth(),
+                    .longlong, .ulonglong, .double => return 64,
+                    .longdouble => switch (target.cpu.arch) {
+                        .x86 => switch (target.abi) {
+                            .android => return 64,
+                            else => return 80,
+                        },
+
+                        .powerpc,
+                        .powerpcle,
+                        => switch (target.abi) {
+                            .musl,
+                            .musleabi,
+                            .musleabihf,
+                            .muslx32,
+                            => return 64,
+                            else => switch (target.os.tag) {
+                                .freebsd, .netbsd, .openbsd => return 64,
+                                else => return 128,
+                            },
+                        },
+
+                        .powerpc64,
+                        .powerpc64le,
+                        => switch (target.abi) {
+                            .musl,
+                            .musleabi,
+                            .musleabihf,
+                            .muslx32,
+                            => return 64,
+                            else => switch (target.os.tag) {
+                                .freebsd, .openbsd => return 64,
+                                else => return 128,
+                            },
+                        },
+
+                        .riscv32,
+                        .riscv64,
+                        .aarch64,
+                        .aarch64_be,
+                        .aarch64_32,
+                        .s390x,
+                        .mips64,
+                        .mips64el,
+                        .sparc,
+                        .sparc64,
+                        .sparcel,
+                        .wasm32,
+                        .wasm64,
+                        => return 128,
+
+                        else => return 64,
+                    },
+                },
+            },
+
+            .windows, .uefi => switch (target.cpu.arch) {
+                .x86 => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .float => return 32,
+                    .long, .ulong => return 32,
+                    .longlong, .ulonglong, .double => return 64,
+                    .longdouble => switch (target.abi) {
+                        .gnu, .gnuilp32, .cygnus => return 80,
+                        else => return 64,
+                    },
+                },
+                .x86_64 => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .float => return 32,
+                    .long, .ulong => switch (target.abi) {
+                        .cygnus => return 64,
+                        else => return 32,
+                    },
+                    .longlong, .ulonglong, .double => return 64,
+                    .longdouble => switch (target.abi) {
+                        .gnu, .gnuilp32, .cygnus => return 80,
+                        else => return 64,
+                    },
+                },
+                else => switch (c_type) {
+                    .short, .ushort => return 16,
+                    .int, .uint, .float => return 32,
+                    .long, .ulong => return 32,
+                    .longlong, .ulonglong, .double => return 64,
+                    .longdouble => return 64,
+                },
+            },
+
+            .macos, .ios, .tvos, .watchos => switch (c_type) {
+                .short, .ushort => return 16,
+                .int, .uint, .float => return 32,
+                .long, .ulong => switch (target.cpu.arch) {
+                    .x86, .arm, .aarch64_32 => return 32,
+                    .x86_64 => switch (target.abi) {
+                        .gnux32, .muslx32 => return 32,
+                        else => return 64,
+                    },
+                    else => return 64,
+                },
+                .longlong, .ulonglong, .double => return 64,
+                .longdouble => switch (target.cpu.arch) {
+                    .x86 => switch (target.abi) {
+                        .android => return 64,
+                        else => return 80,
+                    },
+                    .x86_64 => return 80,
+                    else => return 64,
+                },
+            },
+
+            .nvcl, .cuda => switch (c_type) {
+                .short, .ushort => return 16,
+                .int, .uint, .float => return 32,
+                .long, .ulong => switch (target.cpu.arch) {
+                    .nvptx => return 32,
+                    .nvptx64 => return 64,
+                    else => return 64,
+                },
+                .longlong, .ulonglong, .double => return 64,
+                .longdouble => return 64,
+            },
+
+            .amdhsa, .amdpal => switch (c_type) {
+                .short, .ushort => return 16,
+                .int, .uint, .float => return 32,
+                .long, .ulong, .longlong, .ulonglong, .double => return 64,
+                .longdouble => return 128,
+            },
+
+            .cloudabi,
+            .kfreebsd,
+            .lv2,
+            .zos,
+            .rtems,
+            .nacl,
+            .aix,
+            .ps4,
+            .ps5,
+            .elfiamcu,
+            .mesa3d,
+            .contiki,
+            .hermit,
+            .hurd,
+            .opencl,
+            .glsl450,
+            .vulkan,
+            .driverkit,
+            .shadermodel,
+            => @panic("TODO specify the C integer and float type sizes for this OS"),
+        }
+    }
+
+    pub fn c_type_alignment(target: Target, c_type: CType) u16 {
+        // Overrides for unusual alignments
+        switch (target.cpu.arch) {
+            .avr => switch (c_type) {
+                .short, .ushort => return 2,
+                else => return 1,
+            },
+            .x86 => switch (target.os.tag) {
+                .windows, .uefi => switch (c_type) {
+                    .longlong, .ulonglong, .double => return 8,
+                    .longdouble => switch (target.abi) {
+                        .gnu, .gnuilp32, .cygnus => return 4,
+                        else => return 8,
+                    },
+                    else => {},
+                },
+                else => {},
+            },
+            else => {},
+        }
+
+        // Next-power-of-two-aligned, up to a maximum.
+        return @min(
+            std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8),
+            switch (target.cpu.arch) {
+                .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
+                    .netbsd => switch (target.abi) {
+                        .gnueabi,
+                        .gnueabihf,
+                        .eabi,
+                        .eabihf,
+                        .android,
+                        .musleabi,
+                        .musleabihf,
+                        => 8,
+
+                        else => @as(u16, 4),
+                    },
+                    .ios, .tvos, .watchos => 4,
+                    else => 8,
+                },
+
+                .msp430,
+                .avr,
+                => 2,
+
+                .arc,
+                .csky,
+                .x86,
+                .xcore,
+                .dxil,
+                .loongarch32,
+                .tce,
+                .tcele,
+                .le32,
+                .amdil,
+                .hsail,
+                .spir,
+                .spirv32,
+                .kalimba,
+                .shave,
+                .renderscript32,
+                .ve,
+                .spu_2,
+                => 4,
+
+                .aarch64_32,
+                .amdgcn,
+                .amdil64,
+                .bpfel,
+                .bpfeb,
+                .hexagon,
+                .hsail64,
+                .loongarch64,
+                .m68k,
+                .mips,
+                .mipsel,
+                .sparc,
+                .sparcel,
+                .sparc64,
+                .lanai,
+                .le64,
+                .nvptx,
+                .nvptx64,
+                .r600,
+                .s390x,
+                .spir64,
+                .spirv64,
+                .renderscript64,
+                => 8,
+
+                .aarch64,
+                .aarch64_be,
+                .mips64,
+                .mips64el,
+                .powerpc,
+                .powerpcle,
+                .powerpc64,
+                .powerpc64le,
+                .riscv32,
+                .riscv64,
+                .x86_64,
+                .wasm32,
+                .wasm64,
+                => 16,
+            },
+        );
+    }
+
+    pub fn c_type_preferred_alignment(target: Target, c_type: CType) u16 {
+        // Overrides for unusual alignments
+        switch (target.cpu.arch) {
+            .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
+                .netbsd => switch (target.abi) {
+                    .gnueabi,
+                    .gnueabihf,
+                    .eabi,
+                    .eabihf,
+                    .android,
+                    .musleabi,
+                    .musleabihf,
+                    => {},
+
+                    else => switch (c_type) {
+                        .longdouble => return 4,
+                        else => {},
+                    },
+                },
+                .ios, .tvos, .watchos => switch (c_type) {
+                    .longdouble => return 4,
+                    else => {},
+                },
+                else => {},
+            },
+            .arc => switch (c_type) {
+                .longdouble => return 4,
+                else => {},
+            },
+            .avr => switch (c_type) {
+                .int, .uint, .long, .ulong, .float, .longdouble => return 1,
+                .short, .ushort => return 2,
+                .double => return 4,
+                .longlong, .ulonglong => return 8,
+            },
+            .x86 => switch (target.os.tag) {
+                .windows, .uefi => switch (c_type) {
+                    .longdouble => switch (target.abi) {
+                        .gnu, .gnuilp32, .cygnus => return 4,
+                        else => return 8,
+                    },
+                    else => {},
+                },
+                else => switch (c_type) {
+                    .longdouble => return 4,
+                    else => {},
+                },
+            },
+            else => {},
+        }
+
+        // Next-power-of-two-aligned, up to a maximum.
+        return @min(
+            std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8),
+            switch (target.cpu.arch) {
+                .msp430 => @as(u16, 2),
+
+                .csky,
+                .xcore,
+                .dxil,
+                .loongarch32,
+                .tce,
+                .tcele,
+                .le32,
+                .amdil,
+                .hsail,
+                .spir,
+                .spirv32,
+                .kalimba,
+                .shave,
+                .renderscript32,
+                .ve,
+                .spu_2,
+                => 4,
+
+                .arc,
+                .arm,
+                .armeb,
+                .avr,
+                .thumb,
+                .thumbeb,
+                .aarch64_32,
+                .amdgcn,
+                .amdil64,
+                .bpfel,
+                .bpfeb,
+                .hexagon,
+                .hsail64,
+                .x86,
+                .loongarch64,
+                .m68k,
+                .mips,
+                .mipsel,
+                .sparc,
+                .sparcel,
+                .sparc64,
+                .lanai,
+                .le64,
+                .nvptx,
+                .nvptx64,
+                .r600,
+                .s390x,
+                .spir64,
+                .spirv64,
+                .renderscript64,
+                => 8,
+
+                .aarch64,
+                .aarch64_be,
+                .mips64,
+                .mips64el,
+                .powerpc,
+                .powerpcle,
+                .powerpc64,
+                .powerpc64le,
+                .riscv32,
+                .riscv64,
+                .x86_64,
+                .wasm32,
+                .wasm64,
+                => 16,
+            },
+        );
+    }
 };
 
 test {
src/codegen/c.zig
@@ -16,7 +16,6 @@ const trace = @import("../tracy.zig").trace;
 const LazySrcLoc = Module.LazySrcLoc;
 const Air = @import("../Air.zig");
 const Liveness = @import("../Liveness.zig");
-const CType = @import("../type.zig").CType;
 
 const target_util = @import("../target.zig");
 const libcFloatPrefix = target_util.libcFloatPrefix;
src/codegen/llvm.zig
@@ -19,7 +19,6 @@ const Liveness = @import("../Liveness.zig");
 const Value = @import("../value.zig").Value;
 const Type = @import("../type.zig").Type;
 const LazySrcLoc = Module.LazySrcLoc;
-const CType = @import("../type.zig").CType;
 const x86_64_abi = @import("../arch/x86_64/abi.zig");
 const wasm_c_abi = @import("../arch/wasm/abi.zig");
 const aarch64_c_abi = @import("../arch/aarch64/abi.zig");
@@ -11043,8 +11042,8 @@ fn backendSupportsF128(target: std.Target) bool {
 fn intrinsicsAllowed(scalar_ty: Type, target: std.Target) bool {
     return switch (scalar_ty.tag()) {
         .f16 => backendSupportsF16(target),
-        .f80 => (CType.longdouble.sizeInBits(target) == 80) and backendSupportsF80(target),
-        .f128 => (CType.longdouble.sizeInBits(target) == 128) and backendSupportsF128(target),
+        .f80 => (target.c_type_bit_size(.longdouble) == 80) and backendSupportsF80(target),
+        .f128 => (target.c_type_bit_size(.longdouble) == 128) and backendSupportsF128(target),
         else => true,
     };
 }
src/Sema.zig
@@ -26076,7 +26076,7 @@ fn coerceVarArgParam(
         .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
         .Float => float: {
             const target = sema.mod.getTarget();
-            const double_bits = @import("type.zig").CType.sizeInBits(.double, target);
+            const double_bits = target.c_type_bit_size(.double);
             const inst_bits = uncasted_ty.floatBits(sema.mod.getTarget());
             if (inst_bits >= double_bits) break :float inst;
             switch (double_bits) {
src/type.zig
@@ -2937,24 +2937,24 @@ pub const Type = extern union {
             .anyframe_T,
             => return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
 
-            .c_short => return AbiAlignmentAdvanced{ .scalar = CType.short.alignment(target) },
-            .c_ushort => return AbiAlignmentAdvanced{ .scalar = CType.ushort.alignment(target) },
-            .c_int => return AbiAlignmentAdvanced{ .scalar = CType.int.alignment(target) },
-            .c_uint => return AbiAlignmentAdvanced{ .scalar = CType.uint.alignment(target) },
-            .c_long => return AbiAlignmentAdvanced{ .scalar = CType.long.alignment(target) },
-            .c_ulong => return AbiAlignmentAdvanced{ .scalar = CType.ulong.alignment(target) },
-            .c_longlong => return AbiAlignmentAdvanced{ .scalar = CType.longlong.alignment(target) },
-            .c_ulonglong => return AbiAlignmentAdvanced{ .scalar = CType.ulonglong.alignment(target) },
-            .c_longdouble => return AbiAlignmentAdvanced{ .scalar = CType.longdouble.alignment(target) },
+            .c_short => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.short) },
+            .c_ushort => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.ushort) },
+            .c_int => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.int) },
+            .c_uint => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.uint) },
+            .c_long => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.long) },
+            .c_ulong => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.ulong) },
+            .c_longlong => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longlong) },
+            .c_ulonglong => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.ulonglong) },
+            .c_longdouble => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },
 
             .f16 => return AbiAlignmentAdvanced{ .scalar = 2 },
-            .f32 => return AbiAlignmentAdvanced{ .scalar = CType.float.alignment(target) },
-            .f64 => switch (CType.double.sizeInBits(target)) {
-                64 => return AbiAlignmentAdvanced{ .scalar = CType.double.alignment(target) },
+            .f32 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.float) },
+            .f64 => switch (target.c_type_bit_size(.double)) {
+                64 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.double) },
                 else => return AbiAlignmentAdvanced{ .scalar = 8 },
             },
-            .f80 => switch (CType.longdouble.sizeInBits(target)) {
-                80 => return AbiAlignmentAdvanced{ .scalar = CType.longdouble.alignment(target) },
+            .f80 => switch (target.c_type_bit_size(.longdouble)) {
+                80 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },
                 else => {
                     var payload: Payload.Bits = .{
                         .base = .{ .tag = .int_unsigned },
@@ -2964,8 +2964,8 @@ pub const Type = extern union {
                     return AbiAlignmentAdvanced{ .scalar = abiAlignment(u80_ty, target) };
                 },
             },
-            .f128 => switch (CType.longdouble.sizeInBits(target)) {
-                128 => return AbiAlignmentAdvanced{ .scalar = CType.longdouble.alignment(target) },
+            .f128 => switch (target.c_type_bit_size(.longdouble)) {
+                128 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },
                 else => return AbiAlignmentAdvanced{ .scalar = 16 },
             },
 
@@ -3434,21 +3434,22 @@ pub const Type = extern union {
                 else => return AbiSizeAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
             },
 
-            .c_short => return AbiSizeAdvanced{ .scalar = @divExact(CType.short.sizeInBits(target), 8) },
-            .c_ushort => return AbiSizeAdvanced{ .scalar = @divExact(CType.ushort.sizeInBits(target), 8) },
-            .c_int => return AbiSizeAdvanced{ .scalar = @divExact(CType.int.sizeInBits(target), 8) },
-            .c_uint => return AbiSizeAdvanced{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },
-            .c_long => return AbiSizeAdvanced{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },
-            .c_ulong => return AbiSizeAdvanced{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },
-            .c_longlong => return AbiSizeAdvanced{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },
-            .c_ulonglong => return AbiSizeAdvanced{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },
+            .c_short => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.short) },
+            .c_ushort => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ushort) },
+            .c_int => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.int) },
+            .c_uint => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.uint) },
+            .c_long => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.long) },
+            .c_ulong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ulong) },
+            .c_longlong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longlong) },
+            .c_ulonglong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ulonglong) },
+            .c_longdouble => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },
 
             .f16 => return AbiSizeAdvanced{ .scalar = 2 },
             .f32 => return AbiSizeAdvanced{ .scalar = 4 },
             .f64 => return AbiSizeAdvanced{ .scalar = 8 },
             .f128 => return AbiSizeAdvanced{ .scalar = 16 },
-            .f80 => switch (CType.longdouble.sizeInBits(target)) {
-                80 => return AbiSizeAdvanced{ .scalar = std.mem.alignForward(10, CType.longdouble.alignment(target)) },
+            .f80 => switch (target.c_type_bit_size(.longdouble)) {
+                80 => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },
                 else => {
                     var payload: Payload.Bits = .{
                         .base = .{ .tag = .int_unsigned },
@@ -3458,14 +3459,6 @@ pub const Type = extern union {
                     return AbiSizeAdvanced{ .scalar = abiSize(u80_ty, target) };
                 },
             },
-            .c_longdouble => switch (CType.longdouble.sizeInBits(target)) {
-                16 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f16, target) },
-                32 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f32, target) },
-                64 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f64, target) },
-                80 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f80, target) },
-                128 => return AbiSizeAdvanced{ .scalar = abiSize(Type.f128, target) },
-                else => unreachable,
-            },
 
             // TODO revisit this when we have the concept of the error tag type
             .anyerror_void_error_union,
@@ -3748,15 +3741,15 @@ pub const Type = extern union {
             .manyptr_const_u8_sentinel_0,
             => return target.cpu.arch.ptrBitWidth(),
 
-            .c_short => return CType.short.sizeInBits(target),
-            .c_ushort => return CType.ushort.sizeInBits(target),
-            .c_int => return CType.int.sizeInBits(target),
-            .c_uint => return CType.uint.sizeInBits(target),
-            .c_long => return CType.long.sizeInBits(target),
-            .c_ulong => return CType.ulong.sizeInBits(target),
-            .c_longlong => return CType.longlong.sizeInBits(target),
-            .c_ulonglong => return CType.ulonglong.sizeInBits(target),
-            .c_longdouble => return CType.longdouble.sizeInBits(target),
+            .c_short => return target.c_type_bit_size(.short),
+            .c_ushort => return target.c_type_bit_size(.ushort),
+            .c_int => return target.c_type_bit_size(.int),
+            .c_uint => return target.c_type_bit_size(.uint),
+            .c_long => return target.c_type_bit_size(.long),
+            .c_ulong => return target.c_type_bit_size(.ulong),
+            .c_longlong => return target.c_type_bit_size(.longlong),
+            .c_ulonglong => return target.c_type_bit_size(.ulonglong),
+            .c_longdouble => return target.c_type_bit_size(.longdouble),
 
             .error_set,
             .error_set_single,
@@ -4631,14 +4624,14 @@ pub const Type = extern union {
             .i128 => return .{ .signedness = .signed, .bits = 128 },
             .usize => return .{ .signedness = .unsigned, .bits = target.cpu.arch.ptrBitWidth() },
             .isize => return .{ .signedness = .signed, .bits = target.cpu.arch.ptrBitWidth() },
-            .c_short => return .{ .signedness = .signed, .bits = CType.short.sizeInBits(target) },
-            .c_ushort => return .{ .signedness = .unsigned, .bits = CType.ushort.sizeInBits(target) },
-            .c_int => return .{ .signedness = .signed, .bits = CType.int.sizeInBits(target) },
-            .c_uint => return .{ .signedness = .unsigned, .bits = CType.uint.sizeInBits(target) },
-            .c_long => return .{ .signedness = .signed, .bits = CType.long.sizeInBits(target) },
-            .c_ulong => return .{ .signedness = .unsigned, .bits = CType.ulong.sizeInBits(target) },
-            .c_longlong => return .{ .signedness = .signed, .bits = CType.longlong.sizeInBits(target) },
-            .c_ulonglong => return .{ .signedness = .unsigned, .bits = CType.ulonglong.sizeInBits(target) },
+            .c_short => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.short) },
+            .c_ushort => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ushort) },
+            .c_int => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.int) },
+            .c_uint => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.uint) },
+            .c_long => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.long) },
+            .c_ulong => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulong) },
+            .c_longlong => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.longlong) },
+            .c_ulonglong => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulonglong) },
 
             .enum_full, .enum_nonexhaustive => ty = ty.cast(Payload.EnumFull).?.data.tag_ty,
             .enum_numbered => ty = ty.castTag(.enum_numbered).?.data.tag_ty,
@@ -4724,7 +4717,7 @@ pub const Type = extern union {
             .f64 => 64,
             .f80 => 80,
             .f128, .comptime_float => 128,
-            .c_longdouble => CType.longdouble.sizeInBits(target),
+            .c_longdouble => target.c_type_bit_size(.longdouble),
 
             else => unreachable,
         };
@@ -6689,536 +6682,3 @@ pub const Type = extern union {
     /// to packed struct layout to find out all the places in the codebase you need to edit!
     pub const packed_struct_layout_version = 2;
 };
-
-pub const CType = enum {
-    short,
-    ushort,
-    int,
-    uint,
-    long,
-    ulong,
-    longlong,
-    ulonglong,
-    longdouble,
-
-    // We don't have a `c_float`/`c_double` type in Zig, but these
-    // are useful for querying target-correct alignment and checking
-    // whether C's double is f64 or f32
-    float,
-    double,
-
-    pub fn sizeInBits(self: CType, target: Target) u16 {
-        switch (target.os.tag) {
-            .freestanding, .other => switch (target.cpu.arch) {
-                .msp430 => switch (self) {
-                    .short, .ushort, .int, .uint => return 16,
-                    .float, .long, .ulong => return 32,
-                    .longlong, .ulonglong, .double, .longdouble => return 64,
-                },
-                .avr => switch (self) {
-                    .short, .ushort, .int, .uint => return 16,
-                    .long, .ulong, .float, .double, .longdouble => return 32,
-                    .longlong, .ulonglong => return 64,
-                },
-                .tce, .tcele => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
-                    .float, .double, .longdouble => return 32,
-                },
-                .mips64, .mips64el => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .float => return 32,
-                    .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
-                    .longlong, .ulonglong, .double => return 64,
-                    .longdouble => return 128,
-                },
-                .x86_64 => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .float => return 32,
-                    .long, .ulong => switch (target.abi) {
-                        .gnux32, .muslx32 => return 32,
-                        else => return 64,
-                    },
-                    .longlong, .ulonglong, .double => return 64,
-                    .longdouble => return 80,
-                },
-                else => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .float => return 32,
-                    .long, .ulong => return target.cpu.arch.ptrBitWidth(),
-                    .longlong, .ulonglong, .double => return 64,
-                    .longdouble => switch (target.cpu.arch) {
-                        .x86 => switch (target.abi) {
-                            .android => return 64,
-                            else => return 80,
-                        },
-
-                        .powerpc,
-                        .powerpcle,
-                        .powerpc64,
-                        .powerpc64le,
-                        => switch (target.abi) {
-                            .musl,
-                            .musleabi,
-                            .musleabihf,
-                            .muslx32,
-                            => return 64,
-                            else => return 128,
-                        },
-
-                        .riscv32,
-                        .riscv64,
-                        .aarch64,
-                        .aarch64_be,
-                        .aarch64_32,
-                        .s390x,
-                        .sparc,
-                        .sparc64,
-                        .sparcel,
-                        .wasm32,
-                        .wasm64,
-                        => return 128,
-
-                        else => return 64,
-                    },
-                },
-            },
-
-            .linux,
-            .freebsd,
-            .netbsd,
-            .dragonfly,
-            .openbsd,
-            .wasi,
-            .emscripten,
-            .plan9,
-            .solaris,
-            .haiku,
-            .ananas,
-            .fuchsia,
-            .minix,
-            => switch (target.cpu.arch) {
-                .msp430 => switch (self) {
-                    .short, .ushort, .int, .uint => return 16,
-                    .long, .ulong, .float => return 32,
-                    .longlong, .ulonglong, .double, .longdouble => return 64,
-                },
-                .avr => switch (self) {
-                    .short, .ushort, .int, .uint => return 16,
-                    .long, .ulong, .float, .double, .longdouble => return 32,
-                    .longlong, .ulonglong => return 64,
-                },
-                .tce, .tcele => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
-                    .float, .double, .longdouble => return 32,
-                },
-                .mips64, .mips64el => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .float => return 32,
-                    .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
-                    .longlong, .ulonglong, .double => return 64,
-                    .longdouble => if (target.os.tag == .freebsd) return 64 else return 128,
-                },
-                .x86_64 => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .float => return 32,
-                    .long, .ulong => switch (target.abi) {
-                        .gnux32, .muslx32 => return 32,
-                        else => return 64,
-                    },
-                    .longlong, .ulonglong, .double => return 64,
-                    .longdouble => return 80,
-                },
-                else => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .float => return 32,
-                    .long, .ulong => return target.cpu.arch.ptrBitWidth(),
-                    .longlong, .ulonglong, .double => return 64,
-                    .longdouble => switch (target.cpu.arch) {
-                        .x86 => switch (target.abi) {
-                            .android => return 64,
-                            else => return 80,
-                        },
-
-                        .powerpc,
-                        .powerpcle,
-                        => switch (target.abi) {
-                            .musl,
-                            .musleabi,
-                            .musleabihf,
-                            .muslx32,
-                            => return 64,
-                            else => switch (target.os.tag) {
-                                .freebsd, .netbsd, .openbsd => return 64,
-                                else => return 128,
-                            },
-                        },
-
-                        .powerpc64,
-                        .powerpc64le,
-                        => switch (target.abi) {
-                            .musl,
-                            .musleabi,
-                            .musleabihf,
-                            .muslx32,
-                            => return 64,
-                            else => switch (target.os.tag) {
-                                .freebsd, .openbsd => return 64,
-                                else => return 128,
-                            },
-                        },
-
-                        .riscv32,
-                        .riscv64,
-                        .aarch64,
-                        .aarch64_be,
-                        .aarch64_32,
-                        .s390x,
-                        .mips64,
-                        .mips64el,
-                        .sparc,
-                        .sparc64,
-                        .sparcel,
-                        .wasm32,
-                        .wasm64,
-                        => return 128,
-
-                        else => return 64,
-                    },
-                },
-            },
-
-            .windows, .uefi => switch (target.cpu.arch) {
-                .x86 => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .float => return 32,
-                    .long, .ulong => return 32,
-                    .longlong, .ulonglong, .double => return 64,
-                    .longdouble => switch (target.abi) {
-                        .gnu, .gnuilp32, .cygnus => return 80,
-                        else => return 64,
-                    },
-                },
-                .x86_64 => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .float => return 32,
-                    .long, .ulong => switch (target.abi) {
-                        .cygnus => return 64,
-                        else => return 32,
-                    },
-                    .longlong, .ulonglong, .double => return 64,
-                    .longdouble => switch (target.abi) {
-                        .gnu, .gnuilp32, .cygnus => return 80,
-                        else => return 64,
-                    },
-                },
-                else => switch (self) {
-                    .short, .ushort => return 16,
-                    .int, .uint, .float => return 32,
-                    .long, .ulong => return 32,
-                    .longlong, .ulonglong, .double => return 64,
-                    .longdouble => return 64,
-                },
-            },
-
-            .macos, .ios, .tvos, .watchos => switch (self) {
-                .short, .ushort => return 16,
-                .int, .uint, .float => return 32,
-                .long, .ulong => switch (target.cpu.arch) {
-                    .x86, .arm, .aarch64_32 => return 32,
-                    .x86_64 => switch (target.abi) {
-                        .gnux32, .muslx32 => return 32,
-                        else => return 64,
-                    },
-                    else => return 64,
-                },
-                .longlong, .ulonglong, .double => return 64,
-                .longdouble => switch (target.cpu.arch) {
-                    .x86 => switch (target.abi) {
-                        .android => return 64,
-                        else => return 80,
-                    },
-                    .x86_64 => return 80,
-                    else => return 64,
-                },
-            },
-
-            .nvcl, .cuda => switch (self) {
-                .short, .ushort => return 16,
-                .int, .uint, .float => return 32,
-                .long, .ulong => switch (target.cpu.arch) {
-                    .nvptx => return 32,
-                    .nvptx64 => return 64,
-                    else => return 64,
-                },
-                .longlong, .ulonglong, .double => return 64,
-                .longdouble => return 64,
-            },
-
-            .amdhsa, .amdpal => switch (self) {
-                .short, .ushort => return 16,
-                .int, .uint, .float => return 32,
-                .long, .ulong, .longlong, .ulonglong, .double => return 64,
-                .longdouble => return 128,
-            },
-
-            .cloudabi,
-            .kfreebsd,
-            .lv2,
-            .zos,
-            .rtems,
-            .nacl,
-            .aix,
-            .ps4,
-            .ps5,
-            .elfiamcu,
-            .mesa3d,
-            .contiki,
-            .hermit,
-            .hurd,
-            .opencl,
-            .glsl450,
-            .vulkan,
-            .driverkit,
-            .shadermodel,
-            => @panic("TODO specify the C integer and float type sizes for this OS"),
-        }
-    }
-
-    pub fn alignment(self: CType, target: Target) u16 {
-
-        // Overrides for unusual alignments
-        switch (target.cpu.arch) {
-            .avr => switch (self) {
-                .short, .ushort => return 2,
-                else => return 1,
-            },
-            .x86 => switch (target.os.tag) {
-                .windows, .uefi => switch (self) {
-                    .longlong, .ulonglong, .double => return 8,
-                    .longdouble => switch (target.abi) {
-                        .gnu, .gnuilp32, .cygnus => return 4,
-                        else => return 8,
-                    },
-                    else => {},
-                },
-                else => {},
-            },
-            else => {},
-        }
-
-        // Next-power-of-two-aligned, up to a maximum.
-        return @min(
-            std.math.ceilPowerOfTwoAssert(u16, (self.sizeInBits(target) + 7) / 8),
-            switch (target.cpu.arch) {
-                .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
-                    .netbsd => switch (target.abi) {
-                        .gnueabi,
-                        .gnueabihf,
-                        .eabi,
-                        .eabihf,
-                        .android,
-                        .musleabi,
-                        .musleabihf,
-                        => 8,
-
-                        else => @as(u16, 4),
-                    },
-                    .ios, .tvos, .watchos => 4,
-                    else => 8,
-                },
-
-                .msp430,
-                .avr,
-                => 2,
-
-                .arc,
-                .csky,
-                .x86,
-                .xcore,
-                .dxil,
-                .loongarch32,
-                .tce,
-                .tcele,
-                .le32,
-                .amdil,
-                .hsail,
-                .spir,
-                .spirv32,
-                .kalimba,
-                .shave,
-                .renderscript32,
-                .ve,
-                .spu_2,
-                => 4,
-
-                .aarch64_32,
-                .amdgcn,
-                .amdil64,
-                .bpfel,
-                .bpfeb,
-                .hexagon,
-                .hsail64,
-                .loongarch64,
-                .m68k,
-                .mips,
-                .mipsel,
-                .sparc,
-                .sparcel,
-                .sparc64,
-                .lanai,
-                .le64,
-                .nvptx,
-                .nvptx64,
-                .r600,
-                .s390x,
-                .spir64,
-                .spirv64,
-                .renderscript64,
-                => 8,
-
-                .aarch64,
-                .aarch64_be,
-                .mips64,
-                .mips64el,
-                .powerpc,
-                .powerpcle,
-                .powerpc64,
-                .powerpc64le,
-                .riscv32,
-                .riscv64,
-                .x86_64,
-                .wasm32,
-                .wasm64,
-                => 16,
-            },
-        );
-    }
-
-    pub fn preferredAlignment(self: CType, target: Target) u16 {
-
-        // Overrides for unusual alignments
-        switch (target.cpu.arch) {
-            .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
-                .netbsd => switch (target.abi) {
-                    .gnueabi,
-                    .gnueabihf,
-                    .eabi,
-                    .eabihf,
-                    .android,
-                    .musleabi,
-                    .musleabihf,
-                    => {},
-
-                    else => switch (self) {
-                        .longdouble => return 4,
-                        else => {},
-                    },
-                },
-                .ios, .tvos, .watchos => switch (self) {
-                    .longdouble => return 4,
-                    else => {},
-                },
-                else => {},
-            },
-            .arc => switch (self) {
-                .longdouble => return 4,
-                else => {},
-            },
-            .avr => switch (self) {
-                .int, .uint, .long, .ulong, .float, .longdouble => return 1,
-                .short, .ushort => return 2,
-                .double => return 4,
-                .longlong, .ulonglong => return 8,
-            },
-            .x86 => switch (target.os.tag) {
-                .windows, .uefi => switch (self) {
-                    .longdouble => switch (target.abi) {
-                        .gnu, .gnuilp32, .cygnus => return 4,
-                        else => return 8,
-                    },
-                    else => {},
-                },
-                else => switch (self) {
-                    .longdouble => return 4,
-                    else => {},
-                },
-            },
-            else => {},
-        }
-
-        // Next-power-of-two-aligned, up to a maximum.
-        return @min(
-            std.math.ceilPowerOfTwoAssert(u16, (self.sizeInBits(target) + 7) / 8),
-            switch (target.cpu.arch) {
-                .msp430 => @as(u16, 2),
-
-                .csky,
-                .xcore,
-                .dxil,
-                .loongarch32,
-                .tce,
-                .tcele,
-                .le32,
-                .amdil,
-                .hsail,
-                .spir,
-                .spirv32,
-                .kalimba,
-                .shave,
-                .renderscript32,
-                .ve,
-                .spu_2,
-                => 4,
-
-                .arc,
-                .arm,
-                .armeb,
-                .avr,
-                .thumb,
-                .thumbeb,
-                .aarch64_32,
-                .amdgcn,
-                .amdil64,
-                .bpfel,
-                .bpfeb,
-                .hexagon,
-                .hsail64,
-                .x86,
-                .loongarch64,
-                .m68k,
-                .mips,
-                .mipsel,
-                .sparc,
-                .sparcel,
-                .sparc64,
-                .lanai,
-                .le64,
-                .nvptx,
-                .nvptx64,
-                .r600,
-                .s390x,
-                .spir64,
-                .spirv64,
-                .renderscript64,
-                => 8,
-
-                .aarch64,
-                .aarch64_be,
-                .mips64,
-                .mips64el,
-                .powerpc,
-                .powerpcle,
-                .powerpc64,
-                .powerpc64le,
-                .riscv32,
-                .riscv64,
-                .x86_64,
-                .wasm32,
-                .wasm64,
-                => 16,
-            },
-        );
-    }
-};