Commit 5792570197

Veikka Tuominen <git@vexu.eu>
2023-09-29 12:06:49
add Aro sources as a dependency
ref: 5688dbccfb58216468267a0f46b96bed7013715a
1 parent 47050fb
deps/aro/builtins/BuiltinFunction.zig
@@ -0,0 +1,35783 @@
+//! Autogenerated by process_builtins.py, do not edit
+
+const std = @import("std");
+const Properties = @import("Properties.zig");
+const TypeDescription = @import("TypeDescription.zig");
+const Attributes = Properties.Attributes;
+const TargetSet = Properties.TargetSet;
+
+pub const Tag = blk: {
+    @setEvalBranchQuota(10000);
+    break :blk std.meta.DeclEnum(functions);
+};
+
+tag: Tag,
+param_str: []const u8,
+properties: Properties,
+
+pub fn fromTag(builtin: Tag) @This() {
+    @setEvalBranchQuota(10000);
+    switch (builtin) {
+        inline else => |tag| {
+            const desc = @field(functions, @tagName(tag));
+            return .{
+                .tag = tag,
+                .param_str = desc.param_str,
+                .properties = .{
+                    .language = if (@hasDecl(desc, "language")) @field(desc, "language") else .all_languages,
+                    .header = if (@hasDecl(desc, "header")) @field(desc, "header") else .none,
+                    .attributes = if (@hasDecl(desc, "attributes")) @field(desc, "attributes") else Attributes{},
+                    .target_set = if (@hasDecl(desc, "target_set")) @field(desc, "target_set") else TargetSet.init(.{ .basic = true }),
+                },
+            };
+        },
+    }
+}
+
+pub fn isVarArgs(self: @This()) bool {
+    return self.param_str[self.param_str.len - 1] == '.';
+}
+
+const functions = struct {
+    pub const _Block_object_assign = struct {
+        const param_str = "vv*vC*iC";
+        const header = .blocks;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const _Block_object_dispose = struct {
+        const param_str = "vvC*iC";
+        const header = .blocks;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const _Exit = struct {
+        const param_str = "vi";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .noreturn = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const _InterlockedAnd = struct {
+        const param_str = "NiNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedAnd16 = struct {
+        const param_str = "ssD*s";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedAnd8 = struct {
+        const param_str = "ccD*c";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedCompareExchange = struct {
+        const param_str = "NiNiD*NiNi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedCompareExchange16 = struct {
+        const param_str = "ssD*ss";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedCompareExchange64 = struct {
+        const param_str = "LLiLLiD*LLiLLi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedCompareExchange8 = struct {
+        const param_str = "ccD*cc";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedCompareExchangePointer = struct {
+        const param_str = "v*v*D*v*v*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedCompareExchangePointer_nf = struct {
+        const param_str = "v*v*D*v*v*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedDecrement = struct {
+        const param_str = "NiNiD*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedDecrement16 = struct {
+        const param_str = "ssD*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchange = struct {
+        const param_str = "NiNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchange16 = struct {
+        const param_str = "ssD*s";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchange8 = struct {
+        const param_str = "ccD*c";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchangeAdd = struct {
+        const param_str = "NiNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchangeAdd16 = struct {
+        const param_str = "ssD*s";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchangeAdd8 = struct {
+        const param_str = "ccD*c";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchangePointer = struct {
+        const param_str = "v*v*D*v*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchangeSub = struct {
+        const param_str = "NiNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchangeSub16 = struct {
+        const param_str = "ssD*s";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedExchangeSub8 = struct {
+        const param_str = "ccD*c";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedIncrement = struct {
+        const param_str = "NiNiD*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedIncrement16 = struct {
+        const param_str = "ssD*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedOr = struct {
+        const param_str = "NiNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedOr16 = struct {
+        const param_str = "ssD*s";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedOr8 = struct {
+        const param_str = "ccD*c";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedXor = struct {
+        const param_str = "NiNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedXor16 = struct {
+        const param_str = "ssD*s";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _InterlockedXor8 = struct {
+        const param_str = "ccD*c";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _MoveFromCoprocessor = struct {
+        const param_str = "UiIUiIUiIUiIUiIUi";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const _MoveFromCoprocessor2 = struct {
+        const param_str = "UiIUiIUiIUiIUiIUi";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const _MoveToCoprocessor = struct {
+        const param_str = "vUiIUiIUiIUiIUiIUi";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const _MoveToCoprocessor2 = struct {
+        const param_str = "vUiIUiIUiIUiIUiIUi";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const _ReturnAddress = struct {
+        const param_str = "v*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __GetExceptionInfo = struct {
+        const param_str = "v*.";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .eval_args = false,
+        };
+    };
+
+    pub const __abnormal_termination = struct {
+        const param_str = "i";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __annotation = struct {
+        const param_str = "wC*.";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __arithmetic_fence = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __assume = struct {
+        const param_str = "vb";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __atomic_always_lock_free = struct {
+        const param_str = "bzvCD*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __atomic_clear = struct {
+        const param_str = "vvD*i";
+        const attributes = Attributes{};
+    };
+
+    pub const __atomic_is_lock_free = struct {
+        const param_str = "bzvCD*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __atomic_signal_fence = struct {
+        const param_str = "vi";
+        const attributes = Attributes{};
+    };
+
+    pub const __atomic_test_and_set = struct {
+        const param_str = "bvD*i";
+        const attributes = Attributes{};
+    };
+
+    pub const __atomic_thread_fence = struct {
+        const param_str = "vi";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin___CFStringMakeConstantString = struct {
+        const param_str = "FC*cC*";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin___NSStringMakeConstantString = struct {
+        const param_str = "FC*cC*";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin___clear_cache = struct {
+        const param_str = "vc*c*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin___fprintf_chk = struct {
+        const param_str = "iP*icC*.";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 2,
+        };
+    };
+
+    pub const __builtin___get_unsafe_stack_bottom = struct {
+        const param_str = "v*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___get_unsafe_stack_ptr = struct {
+        const param_str = "v*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___get_unsafe_stack_start = struct {
+        const param_str = "v*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___get_unsafe_stack_top = struct {
+        const param_str = "v*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___memccpy_chk = struct {
+        const param_str = "v*v*vC*izz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___memcpy_chk = struct {
+        const param_str = "v*v*vC*zz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___memmove_chk = struct {
+        const param_str = "v*v*vC*zz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___mempcpy_chk = struct {
+        const param_str = "v*v*vC*zz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___memset_chk = struct {
+        const param_str = "v*v*izz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___printf_chk = struct {
+        const param_str = "iicC*.";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const __builtin___snprintf_chk = struct {
+        const param_str = "ic*zizcC*.";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 4,
+        };
+    };
+
+    pub const __builtin___sprintf_chk = struct {
+        const param_str = "ic*izcC*.";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 3,
+        };
+    };
+
+    pub const __builtin___stpcpy_chk = struct {
+        const param_str = "c*c*cC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___stpncpy_chk = struct {
+        const param_str = "c*c*cC*zz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___strcat_chk = struct {
+        const param_str = "c*c*cC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___strcpy_chk = struct {
+        const param_str = "c*c*cC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___strlcat_chk = struct {
+        const param_str = "zc*cC*zz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___strlcpy_chk = struct {
+        const param_str = "zc*cC*zz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___strncat_chk = struct {
+        const param_str = "c*c*cC*zz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___strncpy_chk = struct {
+        const param_str = "c*c*cC*zz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin___vfprintf_chk = struct {
+        const param_str = "iP*icC*a";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 2,
+        };
+    };
+
+    pub const __builtin___vprintf_chk = struct {
+        const param_str = "iicC*a";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const __builtin___vsnprintf_chk = struct {
+        const param_str = "ic*zizcC*a";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 4,
+        };
+    };
+
+    pub const __builtin___vsprintf_chk = struct {
+        const param_str = "ic*izcC*a";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 3,
+        };
+    };
+
+    pub const __builtin_abort = struct {
+        const param_str = "v";
+        const attributes = Attributes{
+            .noreturn = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_abs = struct {
+        const param_str = "ii";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_acos = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_acosf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_acosf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_acosh = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_acoshf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_acoshf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_acoshl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_acosl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_add_overflow = struct {
+        const param_str = "b.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_addc = struct {
+        const param_str = "UiUiCUiCUiCUi*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_addcb = struct {
+        const param_str = "UcUcCUcCUcCUc*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_addcl = struct {
+        const param_str = "ULiULiCULiCULiCULi*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_addcll = struct {
+        const param_str = "ULLiULLiCULLiCULLiCULLi*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_addcs = struct {
+        const param_str = "UsUsCUsCUsCUs*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_addf128_round_to_odd = struct {
+        const param_str = "LLdLLdLLd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_align_down = struct {
+        const param_str = "v*vC*z";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_align_up = struct {
+        const param_str = "v*vC*z";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_alloca = struct {
+        const param_str = "v*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_alloca_uninitialized = struct {
+        const param_str = "v*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_alloca_with_align = struct {
+        const param_str = "v*zIz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_alloca_with_align_uninitialized = struct {
+        const param_str = "v*zIz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_altivec_crypto_vcipher = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vcipherlast = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vncipher = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vncipherlast = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vpermxor = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vpermxor_be = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vpmsumb = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vpmsumd = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vpmsumh = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vpmsumw = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vsbox = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vshasigmad = struct {
+        const param_str = "V2ULLiV2ULLiIiIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_crypto_vshasigmaw = struct {
+        const param_str = "V4UiV4UiIiIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_dss = struct {
+        const param_str = "vUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_dssall = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_dst = struct {
+        const param_str = "vvC*iUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_dstst = struct {
+        const param_str = "vvC*iUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_dststt = struct {
+        const param_str = "vvC*iUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_dstt = struct {
+        const param_str = "vvC*iUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_lvebx = struct {
+        const param_str = "V16cLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_lvehx = struct {
+        const param_str = "V8sLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_lvewx = struct {
+        const param_str = "V4iLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_lvsl = struct {
+        const param_str = "V16cUcvC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_lvsr = struct {
+        const param_str = "V16cUcvC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_lvx = struct {
+        const param_str = "V4iLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_lvxl = struct {
+        const param_str = "V4iLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_mfvscr = struct {
+        const param_str = "V8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_mtvscr = struct {
+        const param_str = "vV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_mtvsrbm = struct {
+        const param_str = "V16UcULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_mtvsrdm = struct {
+        const param_str = "V2ULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_mtvsrhm = struct {
+        const param_str = "V8UsULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_mtvsrqm = struct {
+        const param_str = "V1ULLLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_mtvsrwm = struct {
+        const param_str = "V4UiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_stvebx = struct {
+        const param_str = "vV16cLiv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_stvehx = struct {
+        const param_str = "vV8sLiv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_stvewx = struct {
+        const param_str = "vV4iLiv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_stvx = struct {
+        const param_str = "vV4iLiv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_stvxl = struct {
+        const param_str = "vV4iLiv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vabsdub = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vabsduh = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vabsduw = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddcuq = struct {
+        const param_str = "V1ULLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddcuq_c = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddcuw = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddecuq = struct {
+        const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddecuq_c = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddeuqm = struct {
+        const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddeuqm_c = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddsbs = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddshs = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddsws = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vaddubs = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vadduhs = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vadduqm = struct {
+        const param_str = "V1ULLLiV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vadduws = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vavgsb = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vavgsh = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vavgsw = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vavgub = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vavguh = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vavguw = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vbpermd = struct {
+        const param_str = "V2ULLiV2ULLiV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vbpermq = struct {
+        const param_str = "V2ULLiV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcfsx = struct {
+        const param_str = "V4fV4SiIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcfuged = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcfux = struct {
+        const param_str = "V4fV4UiIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vclrlb = struct {
+        const param_str = "V16UcV16UcUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vclrrb = struct {
+        const param_str = "V16UcV16UcUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vclzb = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vclzd = struct {
+        const param_str = "V2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vclzdm = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vclzh = struct {
+        const param_str = "V8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vclzlsbb = struct {
+        const param_str = "SiV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vclzw = struct {
+        const param_str = "V4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpbfp = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpbfp_p = struct {
+        const param_str = "iiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpeqfp = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpeqfp_p = struct {
+        const param_str = "iiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequb = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequb_p = struct {
+        const param_str = "iiV16cV16c";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequd = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequd_p = struct {
+        const param_str = "iiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequh = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequh_p = struct {
+        const param_str = "iiV8sV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequq = struct {
+        const param_str = "V1LLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequq_p = struct {
+        const param_str = "iiV1ULLLiV1LLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequw = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpequw_p = struct {
+        const param_str = "iiV4iV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgefp = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgefp_p = struct {
+        const param_str = "iiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtfp = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtfp_p = struct {
+        const param_str = "iiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsb = struct {
+        const param_str = "V16cV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsb_p = struct {
+        const param_str = "iiV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsd = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsd_p = struct {
+        const param_str = "iiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsh = struct {
+        const param_str = "V8sV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsh_p = struct {
+        const param_str = "iiV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsq = struct {
+        const param_str = "V1LLLiV1SLLLiV1SLLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsq_p = struct {
+        const param_str = "iiV1SLLLiV1SLLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsw = struct {
+        const param_str = "V4iV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtsw_p = struct {
+        const param_str = "iiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtub = struct {
+        const param_str = "V16cV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtub_p = struct {
+        const param_str = "iiV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtud = struct {
+        const param_str = "V2LLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtud_p = struct {
+        const param_str = "iiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtuh = struct {
+        const param_str = "V8sV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtuh_p = struct {
+        const param_str = "iiV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtuq = struct {
+        const param_str = "V1LLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtuq_p = struct {
+        const param_str = "iiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtuw = struct {
+        const param_str = "V4iV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpgtuw_p = struct {
+        const param_str = "iiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpneb = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpneb_p = struct {
+        const param_str = "iiV16cV16c";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpned_p = struct {
+        const param_str = "iiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpneh = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpneh_p = struct {
+        const param_str = "iiV8sV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpnew = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpnew_p = struct {
+        const param_str = "iiV4iV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpnezb = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpnezh = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcmpnezw = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcntmbb = struct {
+        const param_str = "ULLiV16UcUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcntmbd = struct {
+        const param_str = "ULLiV2ULLiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcntmbh = struct {
+        const param_str = "ULLiV8UsUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vcntmbw = struct {
+        const param_str = "ULLiV4UiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vctsxs = struct {
+        const param_str = "V4SiV4fIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vctuxs = struct {
+        const param_str = "V4UiV4fIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vctzb = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vctzd = struct {
+        const param_str = "V2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vctzdm = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vctzh = struct {
+        const param_str = "V8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vctzlsbb = struct {
+        const param_str = "SiV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vctzw = struct {
+        const param_str = "V4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vdivesd = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vdivesq = struct {
+        const param_str = "V1SLLLiV1SLLLiV1SLLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vdivesw = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vdiveud = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vdiveuq = struct {
+        const param_str = "V1ULLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vdiveuw = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vexpandbm = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vexpanddm = struct {
+        const param_str = "V2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vexpandhm = struct {
+        const param_str = "V8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vexpandqm = struct {
+        const param_str = "V1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vexpandwm = struct {
+        const param_str = "V4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vexptefp = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextddvlx = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextddvrx = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextdubvlx = struct {
+        const param_str = "V2ULLiV16UcV16UcUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextdubvrx = struct {
+        const param_str = "V2ULLiV16UcV16UcUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextduhvlx = struct {
+        const param_str = "V2ULLiV8UsV8UsUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextduhvrx = struct {
+        const param_str = "V2ULLiV8UsV8UsUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextduwvlx = struct {
+        const param_str = "V2ULLiV4UiV4UiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextduwvrx = struct {
+        const param_str = "V2ULLiV4UiV4UiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextractbm = struct {
+        const param_str = "UiV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextractdm = struct {
+        const param_str = "UiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextracthm = struct {
+        const param_str = "UiV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextractqm = struct {
+        const param_str = "UiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextractwm = struct {
+        const param_str = "UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextsb2d = struct {
+        const param_str = "V2SLLiV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextsb2w = struct {
+        const param_str = "V4SiV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextsd2q = struct {
+        const param_str = "V1SLLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextsh2d = struct {
+        const param_str = "V2SLLiV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextsh2w = struct {
+        const param_str = "V4SiV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vextsw2d = struct {
+        const param_str = "V2SLLiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vgbbd = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vgnb = struct {
+        const param_str = "ULLiV1ULLLiIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsblx = struct {
+        const param_str = "V16UcV16UcUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsbrx = struct {
+        const param_str = "V16UcV16UcUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsbvlx = struct {
+        const param_str = "V16UcV16UcUiV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsbvrx = struct {
+        const param_str = "V16UcV16UcUiV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsd = struct {
+        const param_str = "V16UcV16UcULLiIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsd_elt = struct {
+        const param_str = "V16UcV16UcULLiiC";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsdlx = struct {
+        const param_str = "V2ULLiV2ULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsdrx = struct {
+        const param_str = "V2ULLiV2ULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinshlx = struct {
+        const param_str = "V8UsV8UsUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinshrx = struct {
+        const param_str = "V8UsV8UsUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinshvlx = struct {
+        const param_str = "V8UsV8UsUiV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinshvrx = struct {
+        const param_str = "V8UsV8UsUiV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsw = struct {
+        const param_str = "V16UcV16UcUiIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinsw_elt = struct {
+        const param_str = "V16UcV16UcUiiC";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinswlx = struct {
+        const param_str = "V4UiV4UiUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinswrx = struct {
+        const param_str = "V4UiV4UiUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinswvlx = struct {
+        const param_str = "V4UiV4UiUiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vinswvrx = struct {
+        const param_str = "V4UiV4UiUiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vlogefp = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaddfp = struct {
+        const param_str = "V4fV4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaxfp = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaxsb = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaxsd = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaxsh = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaxsw = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaxub = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaxud = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaxuh = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmaxuw = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmhaddshs = struct {
+        const param_str = "V8sV8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmhraddshs = struct {
+        const param_str = "V8sV8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vminfp = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vminsb = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vminsd = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vminsh = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vminsw = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vminub = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vminud = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vminuh = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vminuw = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmsumcud = struct {
+        const param_str = "V1ULLLiV2ULLiV2ULLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmsummbm = struct {
+        const param_str = "V4SiV16ScV16UcV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmsumshm = struct {
+        const param_str = "V4SiV8SsV8SsV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmsumshs = struct {
+        const param_str = "V4SiV8SsV8SsV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmsumubm = struct {
+        const param_str = "V4UiV16UcV16UcV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmsumuhm = struct {
+        const param_str = "V4UiV8UsV8UsV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmsumuhs = struct {
+        const param_str = "V4UiV8UsV8UsV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulesb = struct {
+        const param_str = "V8SsV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulesd = struct {
+        const param_str = "V1SLLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulesh = struct {
+        const param_str = "V4SiV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulesw = struct {
+        const param_str = "V2SLLiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmuleub = struct {
+        const param_str = "V8UsV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmuleud = struct {
+        const param_str = "V1ULLLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmuleuh = struct {
+        const param_str = "V4UiV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmuleuw = struct {
+        const param_str = "V2ULLiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulhsd = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulhsw = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulhud = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulhuw = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulosb = struct {
+        const param_str = "V8SsV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulosd = struct {
+        const param_str = "V1SLLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulosh = struct {
+        const param_str = "V4SiV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulosw = struct {
+        const param_str = "V2SLLiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmuloub = struct {
+        const param_str = "V8UsV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmuloud = struct {
+        const param_str = "V1ULLLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulouh = struct {
+        const param_str = "V4UiV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vmulouw = struct {
+        const param_str = "V2ULLiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vnmsubfp = struct {
+        const param_str = "V4fV4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpdepd = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vperm_4si = struct {
+        const param_str = "V4iV4iV4iV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpextd = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpkpx = struct {
+        const param_str = "V8sV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpksdss = struct {
+        const param_str = "V4SiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpksdus = struct {
+        const param_str = "V4UiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpkshss = struct {
+        const param_str = "V16ScV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpkshus = struct {
+        const param_str = "V16UcV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpkswss = struct {
+        const param_str = "V8SsV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpkswus = struct {
+        const param_str = "V8UsV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpkudum = struct {
+        const param_str = "V4UiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpkudus = struct {
+        const param_str = "V4UiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpkuhus = struct {
+        const param_str = "V16UcV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpkuwus = struct {
+        const param_str = "V8UsV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpopcntb = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpopcntd = struct {
+        const param_str = "V2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpopcnth = struct {
+        const param_str = "V8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vpopcntw = struct {
+        const param_str = "V4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vprtybd = struct {
+        const param_str = "V2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vprtybq = struct {
+        const param_str = "V1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vprtybw = struct {
+        const param_str = "V4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrefp = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrfim = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrfin = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrfip = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrfiz = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrlb = struct {
+        const param_str = "V16cV16cV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrld = struct {
+        const param_str = "V2LLiV2LLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrldmi = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrldnm = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrlh = struct {
+        const param_str = "V8sV8sV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrlqmi = struct {
+        const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrlqnm = struct {
+        const param_str = "V1ULLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrlw = struct {
+        const param_str = "V4iV4iV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrlwmi = struct {
+        const param_str = "V4UiV4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrlwnm = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vrsqrtefp = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsel_4si = struct {
+        const param_str = "V4iV4iV4iV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsl = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsldbi = struct {
+        const param_str = "V16UcV16UcV16UcIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vslo = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vslv = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsr = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsrab = struct {
+        const param_str = "V16cV16cV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsrah = struct {
+        const param_str = "V8sV8sV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsraw = struct {
+        const param_str = "V4iV4iV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsrdbi = struct {
+        const param_str = "V16UcV16UcV16UcIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsro = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsrv = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vstribl = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vstribl_p = struct {
+        const param_str = "iiV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vstribr = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vstribr_p = struct {
+        const param_str = "iiV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vstrihl = struct {
+        const param_str = "V8sV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vstrihl_p = struct {
+        const param_str = "iiV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vstrihr = struct {
+        const param_str = "V8sV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vstrihr_p = struct {
+        const param_str = "iiV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubcuq = struct {
+        const param_str = "V1ULLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubcuq_c = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubcuw = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubecuq = struct {
+        const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubecuq_c = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubeuqm = struct {
+        const param_str = "V1ULLLiV1ULLLiV1ULLLiV1ULLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubeuqm_c = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubsbs = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubshs = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubsws = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsububs = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubuhs = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubuqm = struct {
+        const param_str = "V1ULLLiV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsubuws = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsum2sws = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsum4sbs = struct {
+        const param_str = "V4SiV16ScV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsum4shs = struct {
+        const param_str = "V4SiV8SsV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsum4ubs = struct {
+        const param_str = "V4UiV16UcV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vsumsws = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vupkhpx = struct {
+        const param_str = "V4UiV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vupkhsb = struct {
+        const param_str = "V8sV16c";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vupkhsh = struct {
+        const param_str = "V4iV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vupkhsw = struct {
+        const param_str = "V2LLiV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vupklpx = struct {
+        const param_str = "V4UiV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vupklsb = struct {
+        const param_str = "V8sV16c";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vupklsh = struct {
+        const param_str = "V4iV8s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_altivec_vupklsw = struct {
+        const param_str = "V2LLiV4i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_amdgcn_alignbit = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_alignbyte = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_atomic_dec32 = struct {
+        const param_str = "UZiUZiD*UZiUicC*";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_atomic_dec64 = struct {
+        const param_str = "UWiUWiD*UWiUicC*";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_atomic_inc32 = struct {
+        const param_str = "UZiUZiD*UZiUicC*";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_atomic_inc64 = struct {
+        const param_str = "UWiUWiD*UWiUicC*";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_buffer_wbinvl1 = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_class = struct {
+        const param_str = "bdi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_classf = struct {
+        const param_str = "bfi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cosf = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cubeid = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cubema = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cubesc = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cubetc = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cvt_pk_i16 = struct {
+        const param_str = "E2sii";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cvt_pk_u16 = struct {
+        const param_str = "E2UsUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cvt_pk_u8_f32 = struct {
+        const param_str = "UifUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cvt_pknorm_i16 = struct {
+        const param_str = "E2sff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cvt_pknorm_u16 = struct {
+        const param_str = "E2Usff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_cvt_pkrtz = struct {
+        const param_str = "E2hff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_dispatch_ptr = struct {
+        const param_str = "v*4";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_div_fixup = struct {
+        const param_str = "dddd";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_div_fixupf = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_div_fmas = struct {
+        const param_str = "ddddb";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_div_fmasf = struct {
+        const param_str = "ffffb";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_div_scale = struct {
+        const param_str = "dddbb*";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_div_scalef = struct {
+        const param_str = "fffbb*";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_append = struct {
+        const param_str = "ii*3";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_bpermute = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_ds_consume = struct {
+        const param_str = "ii*3";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_faddf = struct {
+        const param_str = "ff*3fIiIiIb";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_fmaxf = struct {
+        const param_str = "ff*3fIiIiIb";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_fminf = struct {
+        const param_str = "ff*3fIiIiIb";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_gws_barrier = struct {
+        const param_str = "vUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_gws_init = struct {
+        const param_str = "vUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_gws_sema_br = struct {
+        const param_str = "vUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_gws_sema_p = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_gws_sema_v = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_ds_permute = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_ds_swizzle = struct {
+        const param_str = "iiIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_endpgm = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .noreturn = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_fcmp = struct {
+        const param_str = "WUiddIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_fcmpf = struct {
+        const param_str = "WUiffIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_fence = struct {
+        const param_str = "vUicC*";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_fmed3f = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_fract = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_fractf = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_frexp_exp = struct {
+        const param_str = "id";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_frexp_expf = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_frexp_mant = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_frexp_mantf = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_grid_size_x = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_grid_size_y = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_grid_size_z = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_groupstaticsize = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_iglp_opt = struct {
+        const param_str = "vIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_implicitarg_ptr = struct {
+        const param_str = "v*4";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_interp_mov = struct {
+        const param_str = "fUiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_interp_p1 = struct {
+        const param_str = "ffUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_interp_p1_f16 = struct {
+        const param_str = "ffUiUibUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_interp_p2 = struct {
+        const param_str = "fffUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_interp_p2_f16 = struct {
+        const param_str = "hffUiUibUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_is_private = struct {
+        const param_str = "bvC*0";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_is_shared = struct {
+        const param_str = "bvC*0";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_kernarg_segment_ptr = struct {
+        const param_str = "v*4";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_ldexp = struct {
+        const param_str = "ddi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_ldexpf = struct {
+        const param_str = "ffi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_lerp = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_log_clampf = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_mbcnt_hi = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_mbcnt_lo = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_mqsad_pk_u16_u8 = struct {
+        const param_str = "WUiWUiUiWUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_mqsad_u32_u8 = struct {
+        const param_str = "V4UiWUiUiV4Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_msad_u8 = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_qsad_pk_u16_u8 = struct {
+        const param_str = "WUiWUiUiWUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_queue_ptr = struct {
+        const param_str = "v*4";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_rcp = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_rcpf = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_read_exec = struct {
+        const param_str = "WUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_read_exec_hi = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_read_exec_lo = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_readfirstlane = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_readlane = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_rsq = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_rsq_clamp = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_rsq_clampf = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_rsqf = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_s_barrier = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_dcache_inv = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_decperflevel = struct {
+        const param_str = "vIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_getpc = struct {
+        const param_str = "WUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_getreg = struct {
+        const param_str = "UiIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_incperflevel = struct {
+        const param_str = "vIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_sendmsg = struct {
+        const param_str = "vIiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_sendmsghalt = struct {
+        const param_str = "vIiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_setprio = struct {
+        const param_str = "vIs";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_setreg = struct {
+        const param_str = "vIiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_sleep = struct {
+        const param_str = "vIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_s_waitcnt = struct {
+        const param_str = "vIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_sad_hi_u8 = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_sad_u16 = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_sad_u8 = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_sbfe = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_sched_barrier = struct {
+        const param_str = "vIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_sched_group_barrier = struct {
+        const param_str = "vIiIiIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_sicmp = struct {
+        const param_str = "WUiiiIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_sicmpl = struct {
+        const param_str = "WUiWiWiIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_sinf = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_sqrt = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_sqrtf = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_trig_preop = struct {
+        const param_str = "ddi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_trig_preopf = struct {
+        const param_str = "ffi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_ubfe = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_uicmp = struct {
+        const param_str = "WUiUiUiIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_uicmpl = struct {
+        const param_str = "WUiWUiWUiIi";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_wave_barrier = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_amdgcn_workgroup_id_x = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_workgroup_id_y = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_workgroup_id_z = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_workgroup_size_x = struct {
+        const param_str = "Us";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_workgroup_size_y = struct {
+        const param_str = "Us";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_workgroup_size_z = struct {
+        const param_str = "Us";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_workitem_id_x = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_workitem_id_y = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_amdgcn_workitem_id_z = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_annotation = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_arm_cdp = struct {
+        const param_str = "vUIiUIiUIiUIiUIiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_cdp2 = struct {
+        const param_str = "vUIiUIiUIiUIiUIiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_clrex = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_cls = struct {
+        const param_str = "UiZUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_cls64 = struct {
+        const param_str = "UiWUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_cmse_TT = struct {
+        const param_str = "Uiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_arm_cmse_TTA = struct {
+        const param_str = "Uiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_arm_cmse_TTAT = struct {
+        const param_str = "Uiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_arm_cmse_TTT = struct {
+        const param_str = "Uiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_arm_dbg = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_dmb = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_dsb = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_get_fpscr = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_isb = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_ldaex = struct {
+        const param_str = "v.";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_arm_ldc = struct {
+        const param_str = "vUIiUIivC*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_ldc2 = struct {
+        const param_str = "vUIiUIivC*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_ldc2l = struct {
+        const param_str = "vUIiUIivC*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_ldcl = struct {
+        const param_str = "vUIiUIivC*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_ldrex = struct {
+        const param_str = "v.";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_arm_ldrexd = struct {
+        const param_str = "LLUiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_mcr = struct {
+        const param_str = "vUIiUIiUiUIiUIiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_mcr2 = struct {
+        const param_str = "vUIiUIiUiUIiUIiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_mcrr = struct {
+        const param_str = "vUIiUIiLLUiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_mcrr2 = struct {
+        const param_str = "vUIiUIiLLUiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_mrc = struct {
+        const param_str = "UiUIiUIiUIiUIiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_mrc2 = struct {
+        const param_str = "UiUIiUIiUIiUIiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_mrrc = struct {
+        const param_str = "LLUiUIiUIiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_mrrc2 = struct {
+        const param_str = "LLUiUIiUIiUIi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_nop = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_prefetch = struct {
+        const param_str = "!";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_qadd = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_qadd16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_qadd8 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_qasx = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_qdbl = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_qsax = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_qsub = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_qsub16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_qsub8 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_rbit = struct {
+        const param_str = "UiUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_rbit64 = struct {
+        const param_str = "WUiWUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_rsr = struct {
+        const param_str = "UicC*";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_rsr128 = struct {
+        const param_str = "LLLUicC*";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_rsr64 = struct {
+        const param_str = "!";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_rsrp = struct {
+        const param_str = "v*cC*";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_sadd16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_sadd8 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_sasx = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_sel = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_set_fpscr = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_sev = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_sevl = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_shadd16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_shadd8 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_shasx = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_shsax = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_shsub16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_shsub8 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlabb = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlabt = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlad = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smladx = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlald = struct {
+        const param_str = "LLiiiLLi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlaldx = struct {
+        const param_str = "LLiiiLLi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlatb = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlatt = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlawb = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlawt = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlsd = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlsdx = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlsld = struct {
+        const param_str = "LLiiiLLi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smlsldx = struct {
+        const param_str = "LLiiiLLi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smuad = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smuadx = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smulbb = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smulbt = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smultb = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smultt = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smulwb = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smulwt = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smusd = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_smusdx = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_ssat = struct {
+        const param_str = "iiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_ssat16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_ssax = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_ssub16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_ssub8 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_stc = struct {
+        const param_str = "vUIiUIiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_stc2 = struct {
+        const param_str = "vUIiUIiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_stc2l = struct {
+        const param_str = "vUIiUIiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_stcl = struct {
+        const param_str = "vUIiUIiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_stlex = struct {
+        const param_str = "i.";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_arm_strex = struct {
+        const param_str = "i.";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_arm_strexd = struct {
+        const param_str = "iLLUiv*";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_sxtab16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_sxtb16 = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_tcancel = struct {
+        const param_str = "vWUIi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_arm_tcommit = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_arm_tstart = struct {
+        const param_str = "WUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+        });
+        const attributes = Attributes{
+            .returns_twice = true,
+        };
+    };
+
+    pub const __builtin_arm_ttest = struct {
+        const param_str = "WUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uadd16 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uadd8 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uasx = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uhadd16 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uhadd8 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uhasx = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uhsax = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uhsub16 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uhsub8 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uqadd16 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uqadd8 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uqasx = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uqsax = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uqsub16 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uqsub8 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_usad8 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_usada8 = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_usat = struct {
+        const param_str = "UiiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_usat16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_usax = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_usub16 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_usub8 = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uxtab16 = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_uxtb16 = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_vcvtr_d = struct {
+        const param_str = "fdi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_vcvtr_f = struct {
+        const param_str = "ffi";
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_wfe = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_wfi = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_arm_wsr = struct {
+        const param_str = "vcC*Ui";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_wsr128 = struct {
+        const param_str = "vcC*LLLUi";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_wsr64 = struct {
+        const param_str = "!";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_wsrp = struct {
+        const param_str = "vcC*vC*";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_arm_yield = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __builtin_asin = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_asinf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_asinf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_asinh = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_asinhf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_asinhf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_asinhl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_asinl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_assume = struct {
+        const param_str = "vb";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_assume_aligned = struct {
+        const param_str = "v*vC*z.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_atan = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atan2 = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atan2f = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atan2f128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atan2l = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atanf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atanf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atanh = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atanhf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atanhf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atanhl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_atanl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_bcmp = struct {
+        const param_str = "ivC*vC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_bcopy = struct {
+        const param_str = "vv*v*z";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_bitrev = struct {
+        const param_str = "UiUi";
+        const target_set = TargetSet.init(.{
+            .xcore = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_bitreverse16 = struct {
+        const param_str = "UsUs";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_bitreverse32 = struct {
+        const param_str = "UZiUZi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_bitreverse64 = struct {
+        const param_str = "UWiUWi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_bitreverse8 = struct {
+        const param_str = "UcUc";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_bpermd = struct {
+        const param_str = "SLLiSLLiSLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_bswap16 = struct {
+        const param_str = "UsUs";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_bswap32 = struct {
+        const param_str = "UZiUZi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_bswap64 = struct {
+        const param_str = "UWiUWi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_bzero = struct {
+        const param_str = "vv*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cabs = struct {
+        const param_str = "dXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cabsf = struct {
+        const param_str = "fXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cabsl = struct {
+        const param_str = "LdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cacos = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cacosf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cacosh = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cacoshf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cacoshl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cacosl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_call_with_static_chain = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_calloc = struct {
+        const param_str = "v*zz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_canonicalize = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_canonicalizef = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_canonicalizef16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_canonicalizel = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_carg = struct {
+        const param_str = "dXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cargf = struct {
+        const param_str = "fXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cargl = struct {
+        const param_str = "LdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_casin = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_casinf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_casinh = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_casinhf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_casinhl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_casinl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_catan = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_catanf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_catanh = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_catanhf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_catanhl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_catanl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cbrt = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cbrtf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cbrtf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cbrtl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_ccos = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ccosf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ccosh = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ccoshf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ccoshl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ccosl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ceil = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_ceilf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_ceilf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_ceilf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_ceill = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cexp = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cexpf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cexpl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cfuged = struct {
+        const param_str = "ULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_char_memchr = struct {
+        const param_str = "c*cC*iz";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_cimag = struct {
+        const param_str = "dXd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cimagf = struct {
+        const param_str = "fXf";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cimagl = struct {
+        const param_str = "LdXLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_classify_type = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .eval_args = false,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_clog = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_clogf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_clogl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_clrsb = struct {
+        const param_str = "ii";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_clrsbl = struct {
+        const param_str = "iLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_clrsbll = struct {
+        const param_str = "iLLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_clz = struct {
+        const param_str = "iUi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_clzl = struct {
+        const param_str = "iULi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_clzll = struct {
+        const param_str = "iULLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_clzs = struct {
+        const param_str = "iUs";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_cntlzdm = struct {
+        const param_str = "ULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_cnttzdm = struct {
+        const param_str = "ULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_complex = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_conj = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_conjf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_conjl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_constant_p = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .eval_args = false,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_convertvector = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_copysign = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_copysignf = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_copysignf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_copysignf16 = struct {
+        const param_str = "hhh";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_copysignl = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_cos = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cosf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cosf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cosf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cosh = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_coshf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_coshf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_coshl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cosl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cpow = struct {
+        const param_str = "XdXdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cpowf = struct {
+        const param_str = "XfXfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cpowl = struct {
+        const param_str = "XLdXLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_cproj = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cprojf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cprojl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_cpu_init = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .x86 = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_cpu_is = struct {
+        const param_str = "bcC*";
+        const target_set = TargetSet.init(.{
+            .x86 = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_cpu_supports = struct {
+        const param_str = "bcC*";
+        const target_set = TargetSet.init(.{
+            .x86 = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_creal = struct {
+        const param_str = "dXd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_crealf = struct {
+        const param_str = "fXf";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_creall = struct {
+        const param_str = "LdXLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_csin = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_csinf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_csinh = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_csinhf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_csinhl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_csinl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_csqrt = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_csqrtf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_csqrtl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ctan = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ctanf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ctanh = struct {
+        const param_str = "XdXd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ctanhf = struct {
+        const param_str = "XfXf";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ctanhl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ctanl = struct {
+        const param_str = "XLdXLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ctz = struct {
+        const param_str = "iUi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_ctzl = struct {
+        const param_str = "iULi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_ctzll = struct {
+        const param_str = "iULLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_ctzs = struct {
+        const param_str = "iUs";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_darn = struct {
+        const param_str = "LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_darn_32 = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_darn_raw = struct {
+        const param_str = "LLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_dcbf = struct {
+        const param_str = "vvC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_debugtrap = struct {
+        const param_str = "v";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_divde = struct {
+        const param_str = "SLLiSLLiSLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_divdeu = struct {
+        const param_str = "ULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_divf128_round_to_odd = struct {
+        const param_str = "LLdLLdLLd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_divwe = struct {
+        const param_str = "SiSiSi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_divweu = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_dump_struct = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_dwarf_cfa = struct {
+        const param_str = "v*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_dwarf_sp_column = struct {
+        const param_str = "Ui";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_dynamic_object_size = struct {
+        const param_str = "zvC*i";
+        const attributes = Attributes{
+            .eval_args = false,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_eh_return = struct {
+        const param_str = "vzv*";
+        const attributes = Attributes{
+            .noreturn = true,
+        };
+    };
+
+    pub const __builtin_eh_return_data_regno = struct {
+        const param_str = "iIi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_elementwise_abs = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_add_sat = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_canonicalize = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_ceil = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_copysign = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_cos = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_floor = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_max = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_min = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_roundeven = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_sin = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_sub_sat = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_elementwise_trunc = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_erf = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_erfc = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_erfcf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_erfcf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_erfcl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_erff = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_erff128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_erfl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_exp = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_exp2 = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_exp2f = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_exp2f128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_exp2f16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_exp2l = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_expect = struct {
+        const param_str = "LiLiLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_expect_with_probability = struct {
+        const param_str = "LiLiLid";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_expf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_expf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_expf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_expl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_expm1 = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_expm1f = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_expm1f128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_expm1l = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_extend_pointer = struct {
+        const param_str = "ULLiv*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_extract_return_addr = struct {
+        const param_str = "v*v*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_fabs = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fabsf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fabsf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fabsf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_fabsl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fdim = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fdimf = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fdimf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fdiml = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ffs = struct {
+        const param_str = "ii";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_ffsl = struct {
+        const param_str = "iLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_ffsll = struct {
+        const param_str = "iLLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_floor = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_floorf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_floorf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_floorf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_floorl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_flt_rounds = struct {
+        const param_str = "i";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_fma = struct {
+        const param_str = "dddd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fmaf = struct {
+        const param_str = "ffff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fmaf128 = struct {
+        const param_str = "LLdLLdLLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fmaf128_round_to_odd = struct {
+        const param_str = "LLdLLdLLdLLd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_fmaf16 = struct {
+        const param_str = "hhhh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fmal = struct {
+        const param_str = "LdLdLdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fmax = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fmaxf = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fmaxf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fmaxf16 = struct {
+        const param_str = "hhh";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fmaxl = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fmin = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fminf = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fminf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fminf16 = struct {
+        const param_str = "hhh";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fminl = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fmod = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fmodf = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fmodf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fmodf16 = struct {
+        const param_str = "hhh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fmodl = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_fpclassify = struct {
+        const param_str = "iiiiii.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_fprintf = struct {
+        const param_str = "iP*cC*.";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const __builtin_frame_address = struct {
+        const param_str = "v*IUi";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_free = struct {
+        const param_str = "vv*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_frexp = struct {
+        const param_str = "ddi*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_frexpf = struct {
+        const param_str = "ffi*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_frexpf128 = struct {
+        const param_str = "LLdLLdi*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_frexpl = struct {
+        const param_str = "LdLdi*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_frob_return_addr = struct {
+        const param_str = "v*v*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_get_texasr = struct {
+        const param_str = "LUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_get_texasru = struct {
+        const param_str = "LUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_get_tfhar = struct {
+        const param_str = "LUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_get_tfiar = struct {
+        const param_str = "LUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_getid = struct {
+        const param_str = "Si";
+        const target_set = TargetSet.init(.{
+            .xcore = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_getps = struct {
+        const param_str = "UiUi";
+        const target_set = TargetSet.init(.{
+            .xcore = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_huge_val = struct {
+        const param_str = "d";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_huge_valf = struct {
+        const param_str = "f";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_huge_valf128 = struct {
+        const param_str = "LLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_huge_valf16 = struct {
+        const param_str = "x";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_huge_vall = struct {
+        const param_str = "Ld";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_hypot = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_hypotf = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_hypotf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_hypotl = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ia32_rdpmc = struct {
+        const param_str = "UOii";
+        const target_set = TargetSet.init(.{
+            .x86 = true,
+        });
+    };
+
+    pub const __builtin_ia32_rdtsc = struct {
+        const param_str = "UOi";
+        const target_set = TargetSet.init(.{
+            .x86 = true,
+        });
+    };
+
+    pub const __builtin_ia32_rdtscp = struct {
+        const param_str = "UOiUi*";
+        const target_set = TargetSet.init(.{
+            .x86 = true,
+        });
+    };
+
+    pub const __builtin_ilogb = struct {
+        const param_str = "id";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ilogbf = struct {
+        const param_str = "if";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ilogbf128 = struct {
+        const param_str = "iLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ilogbl = struct {
+        const param_str = "iLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_index = struct {
+        const param_str = "c*cC*i";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_inf = struct {
+        const param_str = "d";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_inff = struct {
+        const param_str = "f";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_inff128 = struct {
+        const param_str = "LLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_inff16 = struct {
+        const param_str = "x";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_infl = struct {
+        const param_str = "Ld";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_init_dwarf_reg_size_table = struct {
+        const param_str = "vv*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_is_aligned = struct {
+        const param_str = "bvC*z";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_isfinite = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_isgreater = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_isgreaterequal = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_isinf = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_isinf_sign = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_isless = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_islessequal = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_islessgreater = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_isnan = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_isnormal = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_isunordered = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_labs = struct {
+        const param_str = "LiLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_launder = struct {
+        const param_str = "v*v*";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_ldexp = struct {
+        const param_str = "ddi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ldexpf = struct {
+        const param_str = "ffi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ldexpf128 = struct {
+        const param_str = "LLdLLdi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ldexpl = struct {
+        const param_str = "LdLdi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_lgamma = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_lgammaf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_lgammaf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_lgammal = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_llabs = struct {
+        const param_str = "LLiLLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_llrint = struct {
+        const param_str = "LLid";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_llrintf = struct {
+        const param_str = "LLif";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_llrintf128 = struct {
+        const param_str = "LLiLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_llrintl = struct {
+        const param_str = "LLiLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_llround = struct {
+        const param_str = "LLid";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_llroundf = struct {
+        const param_str = "LLif";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_llroundf128 = struct {
+        const param_str = "LLiLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_llroundl = struct {
+        const param_str = "LLiLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log10 = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log10f = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log10f128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log10f16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log10l = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log1p = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log1pf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log1pf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log1pl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log2 = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log2f = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log2f128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log2f16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_log2l = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_logb = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_logbf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_logbf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_logbl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_logf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_logf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_logf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_logl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_longjmp = struct {
+        const param_str = "vv**i";
+        const attributes = Attributes{
+            .noreturn = true,
+        };
+    };
+
+    pub const __builtin_lrint = struct {
+        const param_str = "Lid";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_lrintf = struct {
+        const param_str = "Lif";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_lrintf128 = struct {
+        const param_str = "LiLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_lrintl = struct {
+        const param_str = "LiLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_lround = struct {
+        const param_str = "Lid";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_lroundf = struct {
+        const param_str = "Lif";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_lroundf128 = struct {
+        const param_str = "LiLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_lroundl = struct {
+        const param_str = "LiLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_malloc = struct {
+        const param_str = "v*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_matrix_column_major_load = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_matrix_column_major_store = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_matrix_transpose = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_memchr = struct {
+        const param_str = "v*vC*iz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_memcmp = struct {
+        const param_str = "ivC*vC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_memcpy = struct {
+        const param_str = "v*v*vC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_memcpy_inline = struct {
+        const param_str = "vv*vC*Iz";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_memmove = struct {
+        const param_str = "v*v*vC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_mempcpy = struct {
+        const param_str = "v*v*vC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_memset = struct {
+        const param_str = "v*v*iz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_memset_inline = struct {
+        const param_str = "vv*iIz";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_absq_s_ph = struct {
+        const param_str = "V2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_absq_s_qb = struct {
+        const param_str = "V4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_absq_s_w = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_addq_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_addq_s_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_addq_s_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_addqh_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_addqh_r_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_addqh_r_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_addqh_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_addsc = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_addu_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_addu_qb = struct {
+        const param_str = "V4ScV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_addu_s_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_addu_s_qb = struct {
+        const param_str = "V4ScV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_adduh_qb = struct {
+        const param_str = "V4ScV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_adduh_r_qb = struct {
+        const param_str = "V4ScV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_addwc = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_append = struct {
+        const param_str = "iiiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_balign = struct {
+        const param_str = "iiiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_bitrev = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_bposge32 = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmp_eq_ph = struct {
+        const param_str = "vV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmp_le_ph = struct {
+        const param_str = "vV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmp_lt_ph = struct {
+        const param_str = "vV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmpgdu_eq_qb = struct {
+        const param_str = "iV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmpgdu_le_qb = struct {
+        const param_str = "iV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmpgdu_lt_qb = struct {
+        const param_str = "iV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmpgu_eq_qb = struct {
+        const param_str = "iV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmpgu_le_qb = struct {
+        const param_str = "iV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmpgu_lt_qb = struct {
+        const param_str = "iV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmpu_eq_qb = struct {
+        const param_str = "vV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmpu_le_qb = struct {
+        const param_str = "vV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_cmpu_lt_qb = struct {
+        const param_str = "vV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_dpa_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_dpaq_s_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_dpaq_sa_l_w = struct {
+        const param_str = "LLiLLiii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_dpaqx_s_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_dpaqx_sa_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_dpau_h_qbl = struct {
+        const param_str = "LLiLLiV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_dpau_h_qbr = struct {
+        const param_str = "LLiLLiV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_dpax_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_dps_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_dpsq_s_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_dpsq_sa_l_w = struct {
+        const param_str = "LLiLLiii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_dpsqx_s_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_dpsqx_sa_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_dpsu_h_qbl = struct {
+        const param_str = "LLiLLiV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_dpsu_h_qbr = struct {
+        const param_str = "LLiLLiV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_dpsx_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_extp = struct {
+        const param_str = "iLLii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_extpdp = struct {
+        const param_str = "iLLii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_extr_r_w = struct {
+        const param_str = "iLLii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_extr_rs_w = struct {
+        const param_str = "iLLii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_extr_s_h = struct {
+        const param_str = "iLLii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_extr_w = struct {
+        const param_str = "iLLii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_insv = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_lbux = struct {
+        const param_str = "iv*i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_lhx = struct {
+        const param_str = "iv*i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_lwx = struct {
+        const param_str = "iv*i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_madd = struct {
+        const param_str = "LLiLLiii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_maddu = struct {
+        const param_str = "LLiLLiUiUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_maq_s_w_phl = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_maq_s_w_phr = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_maq_sa_w_phl = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_maq_sa_w_phr = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_modsub = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_msub = struct {
+        const param_str = "LLiLLiii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_msubu = struct {
+        const param_str = "LLiLLiUiUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_mthlip = struct {
+        const param_str = "LLiLLii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_mul_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_mul_s_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_muleq_s_w_phl = struct {
+        const param_str = "iV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_muleq_s_w_phr = struct {
+        const param_str = "iV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_muleu_s_ph_qbl = struct {
+        const param_str = "V2sV4ScV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_muleu_s_ph_qbr = struct {
+        const param_str = "V2sV4ScV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_mulq_rs_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_mulq_rs_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_mulq_s_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_mulq_s_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_mulsa_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_mulsaq_s_w_ph = struct {
+        const param_str = "LLiLLiV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_mult = struct {
+        const param_str = "LLiii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_multu = struct {
+        const param_str = "LLiUiUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_packrl_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_pick_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_pick_qb = struct {
+        const param_str = "V4ScV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_preceq_w_phl = struct {
+        const param_str = "iV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_preceq_w_phr = struct {
+        const param_str = "iV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_precequ_ph_qbl = struct {
+        const param_str = "V2sV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_precequ_ph_qbla = struct {
+        const param_str = "V2sV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_precequ_ph_qbr = struct {
+        const param_str = "V2sV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_precequ_ph_qbra = struct {
+        const param_str = "V2sV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_preceu_ph_qbl = struct {
+        const param_str = "V2sV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_preceu_ph_qbla = struct {
+        const param_str = "V2sV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_preceu_ph_qbr = struct {
+        const param_str = "V2sV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_preceu_ph_qbra = struct {
+        const param_str = "V2sV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_precr_qb_ph = struct {
+        const param_str = "V4ScV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_precr_sra_ph_w = struct {
+        const param_str = "V2siiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_precr_sra_r_ph_w = struct {
+        const param_str = "V2siiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_precrq_ph_w = struct {
+        const param_str = "V2sii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_precrq_qb_ph = struct {
+        const param_str = "V4ScV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_precrq_rs_ph_w = struct {
+        const param_str = "V2sii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_precrqu_s_qb_ph = struct {
+        const param_str = "V4ScV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_prepend = struct {
+        const param_str = "iiiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_raddu_w_qb = struct {
+        const param_str = "iV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_rddsp = struct {
+        const param_str = "iIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_repl_ph = struct {
+        const param_str = "V2si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_repl_qb = struct {
+        const param_str = "V4Sci";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_shilo = struct {
+        const param_str = "LLiLLii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_shll_ph = struct {
+        const param_str = "V2sV2si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_shll_qb = struct {
+        const param_str = "V4ScV4Sci";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_shll_s_ph = struct {
+        const param_str = "V2sV2si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_shll_s_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_shra_ph = struct {
+        const param_str = "V2sV2si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_shra_qb = struct {
+        const param_str = "V4ScV4Sci";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_shra_r_ph = struct {
+        const param_str = "V2sV2si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_shra_r_qb = struct {
+        const param_str = "V4ScV4Sci";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_shra_r_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_shrl_ph = struct {
+        const param_str = "V2sV2si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_shrl_qb = struct {
+        const param_str = "V4ScV4Sci";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_subq_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_subq_s_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_subq_s_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_subqh_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_subqh_r_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_subqh_r_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_subqh_w = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_subu_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_subu_qb = struct {
+        const param_str = "V4ScV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_subu_s_ph = struct {
+        const param_str = "V2sV2sV2s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_subu_s_qb = struct {
+        const param_str = "V4ScV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_mips_subuh_qb = struct {
+        const param_str = "V4ScV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_subuh_r_qb = struct {
+        const param_str = "V4ScV4ScV4Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mips_wrdsp = struct {
+        const param_str = "viIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_modf = struct {
+        const param_str = "ddd*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_modff = struct {
+        const param_str = "fff*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_modff128 = struct {
+        const param_str = "LLdLLdLLd*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_modfl = struct {
+        const param_str = "LdLdLd*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_msa_add_a_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_add_a_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_add_a_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_add_a_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_a_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_a_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_a_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_a_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_u_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_u_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_adds_u_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_addv_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_addv_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_addv_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_addv_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_addvi_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_addvi_d = struct {
+        const param_str = "V2LLiV2LLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_addvi_h = struct {
+        const param_str = "V8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_addvi_w = struct {
+        const param_str = "V4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_and_v = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_andi_b = struct {
+        const param_str = "V16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_asub_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_asub_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_asub_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_asub_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_asub_u_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_asub_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_asub_u_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_asub_u_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ave_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ave_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ave_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ave_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ave_u_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ave_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ave_u_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ave_u_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_aver_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_aver_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_aver_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_aver_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_aver_u_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_aver_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_aver_u_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_aver_u_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bclr_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bclr_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bclr_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bclr_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bclri_b = struct {
+        const param_str = "V16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bclri_d = struct {
+        const param_str = "V2ULLiV2ULLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bclri_h = struct {
+        const param_str = "V8UsV8UsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bclri_w = struct {
+        const param_str = "V4UiV4UiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsl_b = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsl_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsl_h = struct {
+        const param_str = "V8UsV8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsl_w = struct {
+        const param_str = "V4UiV4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsli_b = struct {
+        const param_str = "V16UcV16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsli_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsli_h = struct {
+        const param_str = "V8UsV8UsV8UsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsli_w = struct {
+        const param_str = "V4UiV4UiV4UiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsr_b = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsr_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsr_h = struct {
+        const param_str = "V8UsV8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsr_w = struct {
+        const param_str = "V4UiV4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsri_b = struct {
+        const param_str = "V16UcV16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsri_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsri_h = struct {
+        const param_str = "V8UsV8UsV8UsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_binsri_w = struct {
+        const param_str = "V4UiV4UiV4UiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bmnz_v = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bmnzi_b = struct {
+        const param_str = "V16UcV16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bmz_v = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bmzi_b = struct {
+        const param_str = "V16UcV16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bneg_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bneg_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bneg_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bneg_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bnegi_b = struct {
+        const param_str = "V16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bnegi_d = struct {
+        const param_str = "V2ULLiV2ULLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bnegi_h = struct {
+        const param_str = "V8UsV8UsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bnegi_w = struct {
+        const param_str = "V4UiV4UiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bnz_b = struct {
+        const param_str = "iV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bnz_d = struct {
+        const param_str = "iV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bnz_h = struct {
+        const param_str = "iV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bnz_v = struct {
+        const param_str = "iV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bnz_w = struct {
+        const param_str = "iV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bsel_v = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bseli_b = struct {
+        const param_str = "V16UcV16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bset_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bset_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bset_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bset_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bseti_b = struct {
+        const param_str = "V16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bseti_d = struct {
+        const param_str = "V2ULLiV2ULLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bseti_h = struct {
+        const param_str = "V8UsV8UsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bseti_w = struct {
+        const param_str = "V4UiV4UiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bz_b = struct {
+        const param_str = "iV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bz_d = struct {
+        const param_str = "iV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bz_h = struct {
+        const param_str = "iV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bz_v = struct {
+        const param_str = "iV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_bz_w = struct {
+        const param_str = "iV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ceq_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ceq_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ceq_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ceq_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ceqi_b = struct {
+        const param_str = "V16ScV16ScISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ceqi_d = struct {
+        const param_str = "V2SLLiV2SLLiISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ceqi_h = struct {
+        const param_str = "V8SsV8SsISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ceqi_w = struct {
+        const param_str = "V4SiV4SiISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_cfcmsa = struct {
+        const param_str = "iIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_msa_cle_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_cle_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_cle_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_cle_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_cle_u_b = struct {
+        const param_str = "V16ScV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_cle_u_d = struct {
+        const param_str = "V2SLLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_cle_u_h = struct {
+        const param_str = "V8SsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_cle_u_w = struct {
+        const param_str = "V4SiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clei_s_b = struct {
+        const param_str = "V16ScV16ScISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clei_s_d = struct {
+        const param_str = "V2SLLiV2SLLiISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clei_s_h = struct {
+        const param_str = "V8SsV8SsISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clei_s_w = struct {
+        const param_str = "V4SiV4SiISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clei_u_b = struct {
+        const param_str = "V16ScV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clei_u_d = struct {
+        const param_str = "V2SLLiV2ULLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clei_u_h = struct {
+        const param_str = "V8SsV8UsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clei_u_w = struct {
+        const param_str = "V4SiV4UiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clt_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clt_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clt_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clt_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clt_u_b = struct {
+        const param_str = "V16ScV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clt_u_d = struct {
+        const param_str = "V2SLLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clt_u_h = struct {
+        const param_str = "V8SsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clt_u_w = struct {
+        const param_str = "V4SiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clti_s_b = struct {
+        const param_str = "V16ScV16ScISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clti_s_d = struct {
+        const param_str = "V2SLLiV2SLLiISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clti_s_h = struct {
+        const param_str = "V8SsV8SsISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clti_s_w = struct {
+        const param_str = "V4SiV4SiISi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clti_u_b = struct {
+        const param_str = "V16ScV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clti_u_d = struct {
+        const param_str = "V2SLLiV2ULLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clti_u_h = struct {
+        const param_str = "V8SsV8UsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_clti_u_w = struct {
+        const param_str = "V4SiV4UiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_copy_s_b = struct {
+        const param_str = "iV16ScIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_copy_s_d = struct {
+        const param_str = "LLiV2SLLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_copy_s_h = struct {
+        const param_str = "iV8SsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_copy_s_w = struct {
+        const param_str = "iV4SiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_copy_u_b = struct {
+        const param_str = "iV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_copy_u_d = struct {
+        const param_str = "LLiV2ULLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_copy_u_h = struct {
+        const param_str = "iV8UsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_copy_u_w = struct {
+        const param_str = "iV4UiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ctcmsa = struct {
+        const param_str = "vIii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_msa_div_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_div_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_div_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_div_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_div_u_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_div_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_div_u_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_div_u_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dotp_s_d = struct {
+        const param_str = "V2SLLiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dotp_s_h = struct {
+        const param_str = "V8SsV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dotp_s_w = struct {
+        const param_str = "V4SiV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dotp_u_d = struct {
+        const param_str = "V2ULLiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dotp_u_h = struct {
+        const param_str = "V8UsV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dotp_u_w = struct {
+        const param_str = "V4UiV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpadd_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpadd_s_h = struct {
+        const param_str = "V8SsV8SsV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpadd_s_w = struct {
+        const param_str = "V4SiV4SiV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpadd_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpadd_u_h = struct {
+        const param_str = "V8UsV8UsV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpadd_u_w = struct {
+        const param_str = "V4UiV4UiV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpsub_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpsub_s_h = struct {
+        const param_str = "V8SsV8SsV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpsub_s_w = struct {
+        const param_str = "V4SiV4SiV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpsub_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpsub_u_h = struct {
+        const param_str = "V8UsV8UsV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_dpsub_u_w = struct {
+        const param_str = "V4UiV4UiV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fadd_d = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fadd_w = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcaf_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcaf_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fceq_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fceq_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fclass_d = struct {
+        const param_str = "V2LLiV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fclass_w = struct {
+        const param_str = "V4iV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcle_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcle_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fclt_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fclt_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcne_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcne_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcor_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcor_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcueq_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcueq_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcule_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcule_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcult_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcult_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcun_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcun_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcune_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fcune_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fdiv_d = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fdiv_w = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fexdo_h = struct {
+        const param_str = "V8hV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fexdo_w = struct {
+        const param_str = "V4fV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fexp2_d = struct {
+        const param_str = "V2dV2dV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fexp2_w = struct {
+        const param_str = "V4fV4fV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fexupl_d = struct {
+        const param_str = "V2dV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fexupl_w = struct {
+        const param_str = "V4fV8h";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fexupr_d = struct {
+        const param_str = "V2dV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fexupr_w = struct {
+        const param_str = "V4fV8h";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ffint_s_d = struct {
+        const param_str = "V2dV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ffint_s_w = struct {
+        const param_str = "V4fV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ffint_u_d = struct {
+        const param_str = "V2dV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ffint_u_w = struct {
+        const param_str = "V4fV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ffql_d = struct {
+        const param_str = "V2dV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ffql_w = struct {
+        const param_str = "V4fV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ffqr_d = struct {
+        const param_str = "V2dV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ffqr_w = struct {
+        const param_str = "V4fV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fill_b = struct {
+        const param_str = "V16Sci";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fill_d = struct {
+        const param_str = "V2SLLiLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fill_h = struct {
+        const param_str = "V8Ssi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fill_w = struct {
+        const param_str = "V4Sii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_flog2_d = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_flog2_w = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmadd_d = struct {
+        const param_str = "V2dV2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmadd_w = struct {
+        const param_str = "V4fV4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmax_a_d = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmax_a_w = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmax_d = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmax_w = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmin_a_d = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmin_a_w = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmin_d = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmin_w = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmsub_d = struct {
+        const param_str = "V2dV2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmsub_w = struct {
+        const param_str = "V4fV4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmul_d = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fmul_w = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_frcp_d = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_frcp_w = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_frint_d = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_frint_w = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_frsqrt_d = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_frsqrt_w = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsaf_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsaf_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fseq_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fseq_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsle_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsle_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fslt_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fslt_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsne_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsne_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsor_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsor_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsqrt_d = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsqrt_w = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsub_d = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsub_w = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsueq_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsueq_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsule_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsule_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsult_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsult_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsun_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsun_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsune_d = struct {
+        const param_str = "V2LLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_fsune_w = struct {
+        const param_str = "V4iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftint_s_d = struct {
+        const param_str = "V2SLLiV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftint_s_w = struct {
+        const param_str = "V4SiV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftint_u_d = struct {
+        const param_str = "V2ULLiV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftint_u_w = struct {
+        const param_str = "V4UiV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftq_h = struct {
+        const param_str = "V4UiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftq_w = struct {
+        const param_str = "V2ULLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftrunc_s_d = struct {
+        const param_str = "V2SLLiV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftrunc_s_w = struct {
+        const param_str = "V4SiV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftrunc_u_d = struct {
+        const param_str = "V2ULLiV2d";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ftrunc_u_w = struct {
+        const param_str = "V4UiV4f";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hadd_s_d = struct {
+        const param_str = "V2SLLiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hadd_s_h = struct {
+        const param_str = "V8SsV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hadd_s_w = struct {
+        const param_str = "V4SiV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hadd_u_d = struct {
+        const param_str = "V2ULLiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hadd_u_h = struct {
+        const param_str = "V8UsV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hadd_u_w = struct {
+        const param_str = "V4UiV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hsub_s_d = struct {
+        const param_str = "V2SLLiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hsub_s_h = struct {
+        const param_str = "V8SsV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hsub_s_w = struct {
+        const param_str = "V4SiV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hsub_u_d = struct {
+        const param_str = "V2ULLiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hsub_u_h = struct {
+        const param_str = "V8UsV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_hsub_u_w = struct {
+        const param_str = "V4UiV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvev_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvev_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvev_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvev_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvl_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvl_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvl_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvl_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvod_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvod_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvod_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvod_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvr_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvr_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvr_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ilvr_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_insert_b = struct {
+        const param_str = "V16ScV16ScIUii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_insert_d = struct {
+        const param_str = "V2SLLiV2SLLiIUiLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_insert_h = struct {
+        const param_str = "V8SsV8SsIUii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_insert_w = struct {
+        const param_str = "V4SiV4SiIUii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_insve_b = struct {
+        const param_str = "V16ScV16ScIUiV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_insve_d = struct {
+        const param_str = "V2SLLiV2SLLiIUiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_insve_h = struct {
+        const param_str = "V8SsV8SsIUiV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_insve_w = struct {
+        const param_str = "V4SiV4SiIUiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ld_b = struct {
+        const param_str = "V16Scv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ld_d = struct {
+        const param_str = "V2SLLiv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ld_h = struct {
+        const param_str = "V8Ssv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ld_w = struct {
+        const param_str = "V4Siv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ldi_b = struct {
+        const param_str = "V16cIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ldi_d = struct {
+        const param_str = "V2LLiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ldi_h = struct {
+        const param_str = "V8sIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ldi_w = struct {
+        const param_str = "V4iIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ldr_d = struct {
+        const param_str = "V2SLLiv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ldr_w = struct {
+        const param_str = "V4Siv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_madd_q_h = struct {
+        const param_str = "V8SsV8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_madd_q_w = struct {
+        const param_str = "V4SiV4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maddr_q_h = struct {
+        const param_str = "V8SsV8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maddr_q_w = struct {
+        const param_str = "V4SiV4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maddv_b = struct {
+        const param_str = "V16ScV16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maddv_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maddv_h = struct {
+        const param_str = "V8SsV8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maddv_w = struct {
+        const param_str = "V4SiV4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_a_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_a_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_a_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_a_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_u_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_u_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_max_u_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maxi_s_b = struct {
+        const param_str = "V16ScV16ScIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maxi_s_d = struct {
+        const param_str = "V2SLLiV2SLLiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maxi_s_h = struct {
+        const param_str = "V8SsV8SsIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maxi_s_w = struct {
+        const param_str = "V4SiV4SiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maxi_u_b = struct {
+        const param_str = "V16UcV16UcIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maxi_u_d = struct {
+        const param_str = "V2ULLiV2ULLiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maxi_u_h = struct {
+        const param_str = "V8UsV8UsIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_maxi_u_w = struct {
+        const param_str = "V4UiV4UiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_a_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_a_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_a_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_a_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_u_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_u_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_min_u_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mini_s_b = struct {
+        const param_str = "V16ScV16ScIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mini_s_d = struct {
+        const param_str = "V2SLLiV2SLLiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mini_s_h = struct {
+        const param_str = "V8SsV8SsIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mini_s_w = struct {
+        const param_str = "V4SiV4SiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mini_u_b = struct {
+        const param_str = "V16UcV16UcIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mini_u_d = struct {
+        const param_str = "V2ULLiV2ULLiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mini_u_h = struct {
+        const param_str = "V8UsV8UsIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mini_u_w = struct {
+        const param_str = "V4UiV4UiIi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mod_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mod_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mod_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mod_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mod_u_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mod_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mod_u_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mod_u_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_move_v = struct {
+        const param_str = "V16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_msub_q_h = struct {
+        const param_str = "V8SsV8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_msub_q_w = struct {
+        const param_str = "V4SiV4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_msubr_q_h = struct {
+        const param_str = "V8SsV8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_msubr_q_w = struct {
+        const param_str = "V4SiV4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_msubv_b = struct {
+        const param_str = "V16ScV16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_msubv_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_msubv_h = struct {
+        const param_str = "V8SsV8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_msubv_w = struct {
+        const param_str = "V4SiV4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mul_q_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mul_q_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mulr_q_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mulr_q_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mulv_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mulv_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mulv_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_mulv_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nloc_b = struct {
+        const param_str = "V16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nloc_d = struct {
+        const param_str = "V2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nloc_h = struct {
+        const param_str = "V8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nloc_w = struct {
+        const param_str = "V4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nlzc_b = struct {
+        const param_str = "V16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nlzc_d = struct {
+        const param_str = "V2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nlzc_h = struct {
+        const param_str = "V8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nlzc_w = struct {
+        const param_str = "V4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nor_v = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_nori_b = struct {
+        const param_str = "V16UcV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_or_v = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_ori_b = struct {
+        const param_str = "V16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pckev_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pckev_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pckev_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pckev_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pckod_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pckod_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pckod_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pckod_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pcnt_b = struct {
+        const param_str = "V16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pcnt_d = struct {
+        const param_str = "V2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pcnt_h = struct {
+        const param_str = "V8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_pcnt_w = struct {
+        const param_str = "V4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sat_s_b = struct {
+        const param_str = "V16ScV16ScIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sat_s_d = struct {
+        const param_str = "V2SLLiV2SLLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sat_s_h = struct {
+        const param_str = "V8SsV8SsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sat_s_w = struct {
+        const param_str = "V4SiV4SiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sat_u_b = struct {
+        const param_str = "V16UcV16UcIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sat_u_d = struct {
+        const param_str = "V2ULLiV2ULLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sat_u_h = struct {
+        const param_str = "V8UsV8UsIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sat_u_w = struct {
+        const param_str = "V4UiV4UiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_shf_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_shf_h = struct {
+        const param_str = "V8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_shf_w = struct {
+        const param_str = "V4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sld_b = struct {
+        const param_str = "V16cV16cV16cUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sld_d = struct {
+        const param_str = "V2LLiV2LLiV2LLiUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sld_h = struct {
+        const param_str = "V8sV8sV8sUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sld_w = struct {
+        const param_str = "V4iV4iV4iUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sldi_b = struct {
+        const param_str = "V16cV16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sldi_d = struct {
+        const param_str = "V2LLiV2LLiV2LLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sldi_h = struct {
+        const param_str = "V8sV8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sldi_w = struct {
+        const param_str = "V4iV4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sll_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sll_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sll_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sll_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_slli_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_slli_d = struct {
+        const param_str = "V2LLiV2LLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_slli_h = struct {
+        const param_str = "V8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_slli_w = struct {
+        const param_str = "V4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_splat_b = struct {
+        const param_str = "V16cV16cUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_splat_d = struct {
+        const param_str = "V2LLiV2LLiUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_splat_h = struct {
+        const param_str = "V8sV8sUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_splat_w = struct {
+        const param_str = "V4iV4iUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_splati_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_splati_d = struct {
+        const param_str = "V2LLiV2LLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_splati_h = struct {
+        const param_str = "V8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_splati_w = struct {
+        const param_str = "V4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sra_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sra_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sra_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_sra_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srai_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srai_d = struct {
+        const param_str = "V2LLiV2LLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srai_h = struct {
+        const param_str = "V8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srai_w = struct {
+        const param_str = "V4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srar_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srar_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srar_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srar_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srari_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srari_d = struct {
+        const param_str = "V2LLiV2LLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srari_h = struct {
+        const param_str = "V8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srari_w = struct {
+        const param_str = "V4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srl_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srl_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srl_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srl_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srli_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srli_d = struct {
+        const param_str = "V2LLiV2LLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srli_h = struct {
+        const param_str = "V8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srli_w = struct {
+        const param_str = "V4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srlr_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srlr_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srlr_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srlr_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srlri_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srlri_d = struct {
+        const param_str = "V2LLiV2LLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srlri_h = struct {
+        const param_str = "V8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_srlri_w = struct {
+        const param_str = "V4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_st_b = struct {
+        const param_str = "vV16Scv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_st_d = struct {
+        const param_str = "vV2SLLiv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_st_h = struct {
+        const param_str = "vV8Ssv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_st_w = struct {
+        const param_str = "vV4Siv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_str_d = struct {
+        const param_str = "vV2SLLiv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_str_w = struct {
+        const param_str = "vV4Siv*Ii";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subs_s_b = struct {
+        const param_str = "V16ScV16ScV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subs_s_d = struct {
+        const param_str = "V2SLLiV2SLLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subs_s_h = struct {
+        const param_str = "V8SsV8SsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subs_s_w = struct {
+        const param_str = "V4SiV4SiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subs_u_b = struct {
+        const param_str = "V16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subs_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subs_u_h = struct {
+        const param_str = "V8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subs_u_w = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subsus_u_b = struct {
+        const param_str = "V16UcV16UcV16Sc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subsus_u_d = struct {
+        const param_str = "V2ULLiV2ULLiV2SLLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subsus_u_h = struct {
+        const param_str = "V8UsV8UsV8Ss";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subsus_u_w = struct {
+        const param_str = "V4UiV4UiV4Si";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subsuu_s_b = struct {
+        const param_str = "V16ScV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subsuu_s_d = struct {
+        const param_str = "V2SLLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subsuu_s_h = struct {
+        const param_str = "V8SsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subsuu_s_w = struct {
+        const param_str = "V4SiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subv_b = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subv_d = struct {
+        const param_str = "V2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subv_h = struct {
+        const param_str = "V8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subv_w = struct {
+        const param_str = "V4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subvi_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subvi_d = struct {
+        const param_str = "V2LLiV2LLiIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subvi_h = struct {
+        const param_str = "V8sV8sIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_subvi_w = struct {
+        const param_str = "V4iV4iIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_vshf_b = struct {
+        const param_str = "V16cV16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_vshf_d = struct {
+        const param_str = "V2LLiV2LLiV2LLiV2LLi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_vshf_h = struct {
+        const param_str = "V8sV8sV8sV8s";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_vshf_w = struct {
+        const param_str = "V4iV4iV4iV4i";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_xor_v = struct {
+        const param_str = "V16cV16cV16c";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_msa_xori_b = struct {
+        const param_str = "V16cV16cIUi";
+        const target_set = TargetSet.init(.{
+            .mips = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_mul_overflow = struct {
+        const param_str = "b.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_mulf128_round_to_odd = struct {
+        const param_str = "LLdLLdLLd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_nan = struct {
+        const param_str = "dcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nanf = struct {
+        const param_str = "fcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nanf128 = struct {
+        const param_str = "LLdcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nanf16 = struct {
+        const param_str = "xcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nanl = struct {
+        const param_str = "LdcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nans = struct {
+        const param_str = "dcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nansf = struct {
+        const param_str = "fcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nansf128 = struct {
+        const param_str = "LLdcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nansf16 = struct {
+        const param_str = "xcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nansl = struct {
+        const param_str = "LdcC*";
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_nearbyint = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_nearbyintf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_nearbyintf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_nearbyintl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_nextafter = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_nextafterf = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_nextafterf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_nextafterl = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_nexttoward = struct {
+        const param_str = "ddLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_nexttowardf = struct {
+        const param_str = "ffLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_nexttowardf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_nexttowardl = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_nontemporal_load = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_nontemporal_store = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_objc_memmove_collectable = struct {
+        const param_str = "v*v*vC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_object_size = struct {
+        const param_str = "zvC*i";
+        const attributes = Attributes{
+            .eval_args = false,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_operator_delete = struct {
+        const param_str = "vv*";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_operator_new = struct {
+        const param_str = "v*z";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_os_log_format = struct {
+        const param_str = "v*v*cC*.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .format_kind = .printf,
+            .format_string_position = 0,
+        };
+    };
+
+    pub const __builtin_os_log_format_buffer_size = struct {
+        const param_str = "zcC*.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .eval_args = false,
+            .const_evaluable = true,
+            .format_kind = .printf,
+            .format_string_position = 0,
+        };
+    };
+
+    pub const __builtin_pack_longdouble = struct {
+        const param_str = "Lddd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_pack_vector_int128 = struct {
+        const param_str = "V1LLLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_parity = struct {
+        const param_str = "iUi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_parityl = struct {
+        const param_str = "iULi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_parityll = struct {
+        const param_str = "iULLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_pdepd = struct {
+        const param_str = "ULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_pextd = struct {
+        const param_str = "ULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_popcount = struct {
+        const param_str = "iUi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_popcountl = struct {
+        const param_str = "iULi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_popcountll = struct {
+        const param_str = "iULLi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_pow = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_powf = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_powf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_powf16 = struct {
+        const param_str = "hhh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_powi = struct {
+        const param_str = "ddi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_powif = struct {
+        const param_str = "ffi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_powil = struct {
+        const param_str = "LdLdi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_powl = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ppc_addex = struct {
+        const param_str = "LLiLLiLLiCIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_alignx = struct {
+        const param_str = "vIivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_ppc_bcdadd = struct {
+        const param_str = "V16UcV16UcV16UcIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_bcdadd_p = struct {
+        const param_str = "iiV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_bcdsub = struct {
+        const param_str = "V16UcV16UcV16UcIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_bcdsub_p = struct {
+        const param_str = "iiV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_cmpb = struct {
+        const param_str = "LLiLLiLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_cmpeqb = struct {
+        const param_str = "LLiLLiLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_cmprb = struct {
+        const param_str = "iCIiii";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_compare_and_swap = struct {
+        const param_str = "iiD*i*i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_compare_and_swaplp = struct {
+        const param_str = "iLiD*Li*Li";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_compare_exp_eq = struct {
+        const param_str = "idd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_compare_exp_gt = struct {
+        const param_str = "idd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_compare_exp_lt = struct {
+        const param_str = "idd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_compare_exp_uo = struct {
+        const param_str = "idd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_dcbfl = struct {
+        const param_str = "vvC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_dcbflp = struct {
+        const param_str = "vvC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_dcbst = struct {
+        const param_str = "vvC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_dcbt = struct {
+        const param_str = "vv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_dcbtst = struct {
+        const param_str = "vv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_dcbtstt = struct {
+        const param_str = "vv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_dcbtt = struct {
+        const param_str = "vv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_dcbz = struct {
+        const param_str = "vv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_eieio = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_extract_exp = struct {
+        const param_str = "Uid";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_extract_sig = struct {
+        const param_str = "ULLid";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fcfid = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fcfud = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fctid = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fctidz = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fctiw = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fctiwz = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fctudz = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fctuwz = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fetch_and_add = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fetch_and_addlp = struct {
+        const param_str = "LiLiD*Li";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fetch_and_and = struct {
+        const param_str = "UiUiD*Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fetch_and_andlp = struct {
+        const param_str = "ULiULiD*ULi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fetch_and_or = struct {
+        const param_str = "UiUiD*Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fetch_and_orlp = struct {
+        const param_str = "ULiULiD*ULi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fetch_and_swap = struct {
+        const param_str = "UiUiD*Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fetch_and_swaplp = struct {
+        const param_str = "ULiULiD*ULi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fmsub = struct {
+        const param_str = "dddd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fmsubs = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fnabs = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fnabss = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fnmadd = struct {
+        const param_str = "dddd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fnmadds = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fnmsub = struct {
+        const param_str = "dddd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fnmsubs = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fre = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fres = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fric = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_frim = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_frims = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_frin = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_frins = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_frip = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_frips = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_friz = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_frizs = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_frsqrte = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_frsqrtes = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fsel = struct {
+        const param_str = "dddd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fsels = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fsqrt = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_fsqrts = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_get_timebase = struct {
+        const param_str = "ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ppc_icbt = struct {
+        const param_str = "vv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_insert_exp = struct {
+        const param_str = "ddULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_iospace_eieio = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_iospace_lwsync = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_iospace_sync = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_isync = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_lbarx = struct {
+        const param_str = "ccD*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_ldarx = struct {
+        const param_str = "LiLiD*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_lharx = struct {
+        const param_str = "ssD*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_load2r = struct {
+        const param_str = "UsUs*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_load4r = struct {
+        const param_str = "UiUi*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_load8r = struct {
+        const param_str = "ULLiULLi*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_lwarx = struct {
+        const param_str = "iiD*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_lwsync = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_maddhd = struct {
+        const param_str = "LLiLLiLLiLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_maddhdu = struct {
+        const param_str = "ULLiULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_maddld = struct {
+        const param_str = "LLiLLiLLiLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_maxfe = struct {
+        const param_str = "LdLdLdLd.";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_ppc_maxfl = struct {
+        const param_str = "dddd.";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_ppc_maxfs = struct {
+        const param_str = "ffff.";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_ppc_mfmsr = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mfspr = struct {
+        const param_str = "ULiIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mftbu = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_minfe = struct {
+        const param_str = "LdLdLdLd.";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_ppc_minfl = struct {
+        const param_str = "dddd.";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_ppc_minfs = struct {
+        const param_str = "ffff.";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_ppc_mtfsb0 = struct {
+        const param_str = "vUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mtfsb1 = struct {
+        const param_str = "vUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mtfsf = struct {
+        const param_str = "vUIiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mtfsfi = struct {
+        const param_str = "vUIiUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mtmsr = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mtspr = struct {
+        const param_str = "vIiULi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mulhd = struct {
+        const param_str = "LLiLiLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mulhdu = struct {
+        const param_str = "ULLiULiULi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mulhw = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_mulhwu = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_popcntb = struct {
+        const param_str = "ULiULi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_poppar4 = struct {
+        const param_str = "iUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_poppar8 = struct {
+        const param_str = "iULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_rdlam = struct {
+        const param_str = "UWiUWiUWiUWIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_ppc_recipdivd = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_recipdivf = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_rldimi = struct {
+        const param_str = "ULLiULLiULLiIUiIULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_rlwimi = struct {
+        const param_str = "UiUiUiIUiIUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_rlwnm = struct {
+        const param_str = "UiUiUiIUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_rsqrtd = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_rsqrtf = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_setb = struct {
+        const param_str = "LLiLLiLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_stbcx = struct {
+        const param_str = "icD*i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_stdcx = struct {
+        const param_str = "iLiD*Li";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_stfiw = struct {
+        const param_str = "viC*d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_sthcx = struct {
+        const param_str = "isD*s";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_store2r = struct {
+        const param_str = "vUiUs*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_store4r = struct {
+        const param_str = "vUiUi*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_store8r = struct {
+        const param_str = "vULLiULLi*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_stwcx = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_swdiv = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_swdiv_nochk = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_swdivs = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_swdivs_nochk = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_sync = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_tdw = struct {
+        const param_str = "vLLiLLiIUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_test_data_class = struct {
+        const param_str = "idIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_ppc_trap = struct {
+        const param_str = "vi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_trapd = struct {
+        const param_str = "vLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ppc_tw = struct {
+        const param_str = "viiIUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_prefetch = struct {
+        const param_str = "vvC*.";
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_preserve_access_index = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_printf = struct {
+        const param_str = "icC*.";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 0,
+        };
+    };
+
+    pub const __builtin_ptx_get_image_channel_data_typei_ = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_get_image_channel_orderi_ = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_get_image_depthi_ = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_get_image_heighti_ = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_get_image_widthi_ = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_read_image2Dff_ = struct {
+        const param_str = "V4fiiff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_read_image2Dfi_ = struct {
+        const param_str = "V4fiiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_read_image2Dif_ = struct {
+        const param_str = "V4iiiff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_read_image2Dii_ = struct {
+        const param_str = "V4iiiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_read_image3Dff_ = struct {
+        const param_str = "V4fiiffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_read_image3Dfi_ = struct {
+        const param_str = "V4fiiiiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_read_image3Dif_ = struct {
+        const param_str = "V4iiiffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_read_image3Dii_ = struct {
+        const param_str = "V4iiiiiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_write_image2Df_ = struct {
+        const param_str = "viiiffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_write_image2Di_ = struct {
+        const param_str = "viiiiiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_ptx_write_image2Dui_ = struct {
+        const param_str = "viiiUiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __builtin_r600_implicitarg_ptr = struct {
+        const param_str = "Uc*7";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_r600_read_tgid_x = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_r600_read_tgid_y = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_r600_read_tgid_z = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_r600_read_tidig_x = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_r600_read_tidig_y = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_r600_read_tidig_z = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_r600_recipsqrt_ieee = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_r600_recipsqrt_ieeef = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .amdgpu = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_readcyclecounter = struct {
+        const param_str = "ULLi";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_readflm = struct {
+        const param_str = "d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_realloc = struct {
+        const param_str = "v*v*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_reduce_add = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_reduce_and = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_reduce_max = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_reduce_min = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_reduce_mul = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_reduce_or = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_reduce_xor = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_remainder = struct {
+        const param_str = "ddd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_remainderf = struct {
+        const param_str = "fff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_remainderf128 = struct {
+        const param_str = "LLdLLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_remainderl = struct {
+        const param_str = "LdLdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_remquo = struct {
+        const param_str = "dddi*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_remquof = struct {
+        const param_str = "fffi*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_remquof128 = struct {
+        const param_str = "LLdLLdLLdi*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_remquol = struct {
+        const param_str = "LdLdLdi*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_return_address = struct {
+        const param_str = "v*IUi";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_rindex = struct {
+        const param_str = "c*cC*i";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_rint = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_rintf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_rintf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_rintf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_rintl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_rotateleft16 = struct {
+        const param_str = "UsUsUs";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_rotateleft32 = struct {
+        const param_str = "UZiUZiUZi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_rotateleft64 = struct {
+        const param_str = "UWiUWiUWi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_rotateleft8 = struct {
+        const param_str = "UcUcUc";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_rotateright16 = struct {
+        const param_str = "UsUsUs";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_rotateright32 = struct {
+        const param_str = "UZiUZiUZi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_rotateright64 = struct {
+        const param_str = "UWiUWiUWi";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_rotateright8 = struct {
+        const param_str = "UcUcUc";
+        const attributes = Attributes{
+            .@"const" = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_round = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_roundf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_roundf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_roundf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_roundl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_sadd_overflow = struct {
+        const param_str = "bSiCSiCSi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_saddl_overflow = struct {
+        const param_str = "bSLiCSLiCSLi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_saddll_overflow = struct {
+        const param_str = "bSLLiCSLLiCSLLi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_scalbln = struct {
+        const param_str = "ddLi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_scalblnf = struct {
+        const param_str = "ffLi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_scalblnf128 = struct {
+        const param_str = "LLdLLdLi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_scalblnl = struct {
+        const param_str = "LdLdLi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_scalbn = struct {
+        const param_str = "ddi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_scalbnf = struct {
+        const param_str = "ffi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_scalbnf128 = struct {
+        const param_str = "LLdLLdi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_scalbnl = struct {
+        const param_str = "LdLdi";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_set_texasr = struct {
+        const param_str = "vLUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_set_texasru = struct {
+        const param_str = "vLUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_set_tfhar = struct {
+        const param_str = "vLUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_set_tfiar = struct {
+        const param_str = "vLUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_setflm = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_setjmp = struct {
+        const param_str = "iv**";
+        const attributes = Attributes{
+            .returns_twice = true,
+        };
+    };
+
+    pub const __builtin_setps = struct {
+        const param_str = "vUiUi";
+        const target_set = TargetSet.init(.{
+            .xcore = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_setrnd = struct {
+        const param_str = "di";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_shufflevector = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_signbit = struct {
+        const param_str = "i.";
+        const attributes = Attributes{
+            .@"const" = true,
+            .custom_typecheck = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_signbitf = struct {
+        const param_str = "if";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_signbitl = struct {
+        const param_str = "iLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_sin = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sinf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sinf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sinf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sinh = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sinhf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sinhf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sinhl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sinl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_smul_overflow = struct {
+        const param_str = "bSiCSiCSi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_smull_overflow = struct {
+        const param_str = "bSLiCSLiCSLi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_smulll_overflow = struct {
+        const param_str = "bSLLiCSLLiCSLLi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_snprintf = struct {
+        const param_str = "ic*zcC*.";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 2,
+        };
+    };
+
+    pub const __builtin_sponentry = struct {
+        const param_str = "v*";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_sprintf = struct {
+        const param_str = "ic*cC*.";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const __builtin_sqrt = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sqrtf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sqrtf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sqrtf128_round_to_odd = struct {
+        const param_str = "LLdLLd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_sqrtf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_sqrtl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_ssub_overflow = struct {
+        const param_str = "bSiCSiCSi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_ssubl_overflow = struct {
+        const param_str = "bSLiCSLiCSLi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_ssubll_overflow = struct {
+        const param_str = "bSLLiCSLLiCSLLi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_stdarg_start = struct {
+        const param_str = "vA.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_stpcpy = struct {
+        const param_str = "c*c*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_stpncpy = struct {
+        const param_str = "c*c*cC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strcasecmp = struct {
+        const param_str = "icC*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strcat = struct {
+        const param_str = "c*c*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strchr = struct {
+        const param_str = "c*cC*i";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_strcmp = struct {
+        const param_str = "icC*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_strcpy = struct {
+        const param_str = "c*c*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strcspn = struct {
+        const param_str = "zcC*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strdup = struct {
+        const param_str = "c*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strlen = struct {
+        const param_str = "zcC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_strncasecmp = struct {
+        const param_str = "icC*cC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strncat = struct {
+        const param_str = "c*c*cC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strncmp = struct {
+        const param_str = "icC*cC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_strncpy = struct {
+        const param_str = "c*c*cC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strndup = struct {
+        const param_str = "c*cC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strpbrk = struct {
+        const param_str = "c*cC*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strrchr = struct {
+        const param_str = "c*cC*i";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strspn = struct {
+        const param_str = "zcC*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_strstr = struct {
+        const param_str = "c*cC*cC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_sub_overflow = struct {
+        const param_str = "b.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_subc = struct {
+        const param_str = "UiUiCUiCUiCUi*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_subcb = struct {
+        const param_str = "UcUcCUcCUcCUc*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_subcl = struct {
+        const param_str = "ULiULiCULiCULiCULi*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_subcll = struct {
+        const param_str = "ULLiULLiCULLiCULLiCULLi*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_subcs = struct {
+        const param_str = "UsUsCUsCUsCUs*";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_subf128_round_to_odd = struct {
+        const param_str = "LLdLLdLLd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tabort = struct {
+        const param_str = "UiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tabortdc = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tabortdci = struct {
+        const param_str = "UiUiUii";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tabortwc = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tabortwci = struct {
+        const param_str = "UiUiUii";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tan = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tanf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tanf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tanh = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tanhf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tanhf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tanhl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tanl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tbegin = struct {
+        const param_str = "UiUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tcheck = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tend = struct {
+        const param_str = "UiUIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tendall = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tgamma = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tgammaf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tgammaf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_tgammal = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __builtin_thread_pointer = struct {
+        const param_str = "v*";
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_trap = struct {
+        const param_str = "v";
+        const attributes = Attributes{
+            .noreturn = true,
+        };
+    };
+
+    pub const __builtin_trechkpt = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_treclaim = struct {
+        const param_str = "UiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tresume = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_trunc = struct {
+        const param_str = "dd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_truncf = struct {
+        const param_str = "ff";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_truncf128 = struct {
+        const param_str = "LLdLLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_truncf128_round_to_odd = struct {
+        const param_str = "dLLd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_truncf16 = struct {
+        const param_str = "hh";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_truncl = struct {
+        const param_str = "LdLd";
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_with_builtin_prefix = true,
+        };
+    };
+
+    pub const __builtin_tsr = struct {
+        const param_str = "UiUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_tsuspend = struct {
+        const param_str = "Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_ttest = struct {
+        const param_str = "LUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_uadd_overflow = struct {
+        const param_str = "bUiCUiCUi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_uaddl_overflow = struct {
+        const param_str = "bULiCULiCULi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_uaddll_overflow = struct {
+        const param_str = "bULLiCULLiCULLi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_umul_overflow = struct {
+        const param_str = "bUiCUiCUi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_umull_overflow = struct {
+        const param_str = "bULiCULiCULi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_umulll_overflow = struct {
+        const param_str = "bULLiCULLiCULLi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_unpack_longdouble = struct {
+        const param_str = "dLdIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_unpack_vector_int128 = struct {
+        const param_str = "ULLiV1LLLii";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_unpredictable = struct {
+        const param_str = "LiLi";
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_unreachable = struct {
+        const param_str = "v";
+        const attributes = Attributes{
+            .noreturn = true,
+        };
+    };
+
+    pub const __builtin_unwind_init = struct {
+        const param_str = "v";
+    };
+
+    pub const __builtin_usub_overflow = struct {
+        const param_str = "bUiCUiCUi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_usubl_overflow = struct {
+        const param_str = "bULiCULiCULi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_usubll_overflow = struct {
+        const param_str = "bULLiCULLiCULLi*";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_va_copy = struct {
+        const param_str = "vAA";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_va_end = struct {
+        const param_str = "vA";
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_va_start = struct {
+        const param_str = "vA.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_ve_vl_andm_MMM = struct {
+        const param_str = "V512bV512bV512b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_andm_mmm = struct {
+        const param_str = "V256bV256bV256b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_eqvm_MMM = struct {
+        const param_str = "V512bV512bV512b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_eqvm_mmm = struct {
+        const param_str = "V256bV256bV256b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_extract_vm512l = struct {
+        const param_str = "V256bV512b";
+        const target_set = TargetSet.init(.{
+            .ve = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_extract_vm512u = struct {
+        const param_str = "V256bV512b";
+        const target_set = TargetSet.init(.{
+            .ve = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_fencec_s = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_fencei = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_fencem_s = struct {
+        const param_str = "vUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_fidcr_sss = struct {
+        const param_str = "LUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_insert_vm512l = struct {
+        const param_str = "V512bV512bV256b";
+        const target_set = TargetSet.init(.{
+            .ve = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_insert_vm512u = struct {
+        const param_str = "V512bV512bV256b";
+        const target_set = TargetSet.init(.{
+            .ve = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_lcr_sss = struct {
+        const param_str = "LUiLUiLUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_lsv_vvss = struct {
+        const param_str = "V256dV256dUiLUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_lvm_MMss = struct {
+        const param_str = "V512bV512bLUiLUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_lvm_mmss = struct {
+        const param_str = "V256bV256bLUiLUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_lvsd_svs = struct {
+        const param_str = "dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_lvsl_svs = struct {
+        const param_str = "LUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_lvss_svs = struct {
+        const param_str = "fV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_lzvm_sml = struct {
+        const param_str = "LUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_negm_MM = struct {
+        const param_str = "V512bV512b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_negm_mm = struct {
+        const param_str = "V256bV256b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_nndm_MMM = struct {
+        const param_str = "V512bV512bV512b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_nndm_mmm = struct {
+        const param_str = "V256bV256bV256b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_orm_MMM = struct {
+        const param_str = "V512bV512bV512b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_orm_mmm = struct {
+        const param_str = "V256bV256bV256b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pack_f32a = struct {
+        const param_str = "ULifC*";
+        const target_set = TargetSet.init(.{
+            .ve = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pack_f32p = struct {
+        const param_str = "ULifC*fC*";
+        const target_set = TargetSet.init(.{
+            .ve = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pcvm_sml = struct {
+        const param_str = "LUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pfchv_ssl = struct {
+        const param_str = "vLivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pfchvnc_ssl = struct {
+        const param_str = "vLivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvadds_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvadds_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvadds_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvadds_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvadds_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvadds_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvaddu_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvaddu_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvaddu_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvaddu_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvaddu_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvaddu_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvand_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvand_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvand_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvand_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvand_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvand_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrd_vsMvl = struct {
+        const param_str = "V256dLUiV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrd_vsl = struct {
+        const param_str = "V256dLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrd_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrv_vvMvl = struct {
+        const param_str = "V256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrv_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrv_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrvlo_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrvlo_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrvlo_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrvup_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrvup_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvbrvup_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmps_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmps_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmps_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmps_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmps_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmps_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmpu_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmpu_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmpu_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmpu_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmpu_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcmpu_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcvtsw_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcvtsw_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcvtws_vvMvl = struct {
+        const param_str = "V256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcvtws_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcvtws_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcvtwsrz_vvMvl = struct {
+        const param_str = "V256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcvtwsrz_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvcvtwsrz_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pveqv_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pveqv_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pveqv_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pveqv_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pveqv_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pveqv_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfadd_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfadd_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfadd_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfadd_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfadd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfadd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfcmp_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfcmp_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfcmp_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfcmp_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfcmp_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfcmp_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmad_vsvvMvl = struct {
+        const param_str = "V256dLUiV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmad_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmad_vsvvvl = struct {
+        const param_str = "V256dLUiV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmad_vvsvMvl = struct {
+        const param_str = "V256dV256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmad_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmad_vvsvvl = struct {
+        const param_str = "V256dV256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmad_vvvvMvl = struct {
+        const param_str = "V256dV256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmad_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmad_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmax_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmax_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmax_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmax_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmax_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmax_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmin_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmin_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmin_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmin_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmin_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmin_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkaf_Ml = struct {
+        const param_str = "V512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkat_Ml = struct {
+        const param_str = "V512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkseq_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkseq_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkseqnan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkseqnan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksge_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksge_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksgenan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksgenan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksgt_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksgt_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksgtnan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksgtnan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksle_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksle_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslenan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslenan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksloeq_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksloeq_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksloeqnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksloeqnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksloge_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksloge_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslogenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslogenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslogt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslogt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslogtnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslogtnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslole_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslole_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslolenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslolenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslolt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslolt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksloltnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksloltnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslonan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslonan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslone_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslone_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslonenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslonenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslonum_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslonum_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslt_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkslt_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksltnan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksltnan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksnan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksnan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksne_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksne_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksnenan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksnenan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksnum_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksnum_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupeq_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupeq_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupeqnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupeqnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupge_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupge_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupgenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupgenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupgt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupgt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupgtnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupgtnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksuple_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksuple_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksuplenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksuplenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksuplt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksuplt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupltnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupltnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupne_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupne_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupnenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupnenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupnum_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmksupnum_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkweq_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkweq_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkweqnan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkweqnan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwge_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwge_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwgenan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwgenan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwgt_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwgt_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwgtnan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwgtnan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwle_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwle_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlenan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlenan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwloeq_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwloeq_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwloeqnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwloeqnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwloge_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwloge_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlogenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlogenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlogt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlogt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlogtnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlogtnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlole_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlole_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlolenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlolenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlolt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlolt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwloltnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwloltnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlonan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlonan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlone_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlone_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlonenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlonenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlonum_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlonum_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlt_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwlt_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwltnan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwltnan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwnan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwnan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwne_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwne_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwnenan_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwnenan_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwnum_MvMl = struct {
+        const param_str = "V512bV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwnum_Mvl = struct {
+        const param_str = "V512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupeq_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupeq_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupeqnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupeqnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupge_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupge_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupgenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupgenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupgt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupgt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupgtnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupgtnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwuple_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwuple_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwuplenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwuplenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwuplt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwuplt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupltnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupltnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupne_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupne_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupnenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupnenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupnum_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmkwupnum_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmsb_vsvvMvl = struct {
+        const param_str = "V256dLUiV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmsb_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmsb_vsvvvl = struct {
+        const param_str = "V256dLUiV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmsb_vvsvMvl = struct {
+        const param_str = "V256dV256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmsb_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmsb_vvsvvl = struct {
+        const param_str = "V256dV256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmsb_vvvvMvl = struct {
+        const param_str = "V256dV256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmsb_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmsb_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmul_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmul_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmul_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmul_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmul_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfmul_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmad_vsvvMvl = struct {
+        const param_str = "V256dLUiV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmad_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmad_vsvvvl = struct {
+        const param_str = "V256dLUiV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmad_vvsvMvl = struct {
+        const param_str = "V256dV256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmad_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmad_vvsvvl = struct {
+        const param_str = "V256dV256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmad_vvvvMvl = struct {
+        const param_str = "V256dV256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmad_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmad_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmsb_vsvvMvl = struct {
+        const param_str = "V256dLUiV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmsb_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmsb_vsvvvl = struct {
+        const param_str = "V256dLUiV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmsb_vvsvMvl = struct {
+        const param_str = "V256dV256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmsb_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmsb_vvsvvl = struct {
+        const param_str = "V256dV256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmsb_vvvvMvl = struct {
+        const param_str = "V256dV256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmsb_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfnmsb_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfsub_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfsub_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfsub_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfsub_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfsub_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvfsub_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvldz_vvMvl = struct {
+        const param_str = "V256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvldz_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvldz_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvldzlo_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvldzlo_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvldzlo_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvldzup_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvldzup_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvldzup_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmaxs_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmaxs_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmaxs_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmaxs_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmaxs_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmaxs_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmins_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmins_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmins_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmins_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmins_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvmins_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvor_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvor_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvor_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvor_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvor_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvor_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvpcnt_vvMvl = struct {
+        const param_str = "V256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvpcnt_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvpcnt_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvpcntlo_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvpcntlo_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvpcntlo_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvpcntup_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvpcntup_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvpcntup_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvrcp_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvrcp_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvrsqrt_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvrsqrt_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvrsqrtnex_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvrsqrtnex_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvseq_vl = struct {
+        const param_str = "V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvseq_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvseqlo_vl = struct {
+        const param_str = "V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvseqlo_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsequp_vl = struct {
+        const param_str = "V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsequp_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsla_vvsMvl = struct {
+        const param_str = "V256dV256dLUiV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsla_vvsl = struct {
+        const param_str = "V256dV256dLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsla_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsla_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsla_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsla_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsll_vvsMvl = struct {
+        const param_str = "V256dV256dLUiV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsll_vvsl = struct {
+        const param_str = "V256dV256dLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsll_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsll_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsll_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsll_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsra_vvsMvl = struct {
+        const param_str = "V256dV256dLUiV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsra_vvsl = struct {
+        const param_str = "V256dV256dLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsra_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsra_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsra_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsra_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsrl_vvsMvl = struct {
+        const param_str = "V256dV256dLUiV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsrl_vvsl = struct {
+        const param_str = "V256dV256dLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsrl_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsrl_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsrl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsrl_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubs_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubs_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubs_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubs_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubs_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubs_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubu_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubu_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubu_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubu_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubu_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvsubu_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvxor_vsvMvl = struct {
+        const param_str = "V256dLUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvxor_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvxor_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvxor_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvxor_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_pvxor_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_scr_sss = struct {
+        const param_str = "vLUiLUiLUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_svm_sMs = struct {
+        const param_str = "LUiV512bLUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_svm_sms = struct {
+        const param_str = "LUiV256bLUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_svob = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_tovm_sml = struct {
+        const param_str = "LUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_tscr_ssss = struct {
+        const param_str = "LUiLUiLUiLUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddsl_vsvl = struct {
+        const param_str = "V256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddsl_vsvmvl = struct {
+        const param_str = "V256dLiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddsl_vsvvl = struct {
+        const param_str = "V256dLiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddsl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddsl_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddsl_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswsx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswsx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswsx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswsx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswsx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswzx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswzx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswzx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswzx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddswzx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddul_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddul_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddul_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddul_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddul_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vaddul_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vadduw_vsvl = struct {
+        const param_str = "V256dUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vadduw_vsvmvl = struct {
+        const param_str = "V256dUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vadduw_vsvvl = struct {
+        const param_str = "V256dUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vadduw_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vadduw_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vadduw_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vand_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vand_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vand_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vand_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vand_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vand_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrdd_vsl = struct {
+        const param_str = "V256ddUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrdd_vsmvl = struct {
+        const param_str = "V256ddV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrdd_vsvl = struct {
+        const param_str = "V256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrdl_vsl = struct {
+        const param_str = "V256dLiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrdl_vsmvl = struct {
+        const param_str = "V256dLiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrdl_vsvl = struct {
+        const param_str = "V256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrds_vsl = struct {
+        const param_str = "V256dfUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrds_vsmvl = struct {
+        const param_str = "V256dfV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrds_vsvl = struct {
+        const param_str = "V256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrdw_vsl = struct {
+        const param_str = "V256diUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrdw_vsmvl = struct {
+        const param_str = "V256diV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrdw_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrv_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrv_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vbrv_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpsl_vsvl = struct {
+        const param_str = "V256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpsl_vsvmvl = struct {
+        const param_str = "V256dLiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpsl_vsvvl = struct {
+        const param_str = "V256dLiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpsl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpsl_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpsl_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswsx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswsx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswsx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswsx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswsx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswzx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswzx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswzx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswzx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpswzx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpul_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpul_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpul_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpul_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpul_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpul_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpuw_vsvl = struct {
+        const param_str = "V256dUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpuw_vsvmvl = struct {
+        const param_str = "V256dUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpuw_vsvvl = struct {
+        const param_str = "V256dUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpuw_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpuw_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcmpuw_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcp_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtdl_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtdl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtds_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtds_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtdw_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtdw_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtld_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtld_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtld_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtldrz_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtldrz_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtldrz_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtsd_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtsd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtsw_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtsw_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdsx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdsx_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdsxrz_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdsxrz_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdsxrz_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdzx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdzx_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdzxrz_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdzxrz_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwdzxrz_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwssx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwssx_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwssx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwssxrz_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwssxrz_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwssxrz_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwszx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwszx_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwszx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwszxrz_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwszxrz_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vcvtwszxrz_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivsl_vsvl = struct {
+        const param_str = "V256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivsl_vsvmvl = struct {
+        const param_str = "V256dLiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivsl_vsvvl = struct {
+        const param_str = "V256dLiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivsl_vvsl = struct {
+        const param_str = "V256dV256dLiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivsl_vvsmvl = struct {
+        const param_str = "V256dV256dLiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivsl_vvsvl = struct {
+        const param_str = "V256dV256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivsl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivsl_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivsl_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswsx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswsx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswsx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswsx_vvsl = struct {
+        const param_str = "V256dV256diUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswsx_vvsmvl = struct {
+        const param_str = "V256dV256diV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswsx_vvsvl = struct {
+        const param_str = "V256dV256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswsx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswsx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswzx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswzx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswzx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswzx_vvsl = struct {
+        const param_str = "V256dV256diUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswzx_vvsmvl = struct {
+        const param_str = "V256dV256diV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswzx_vvsvl = struct {
+        const param_str = "V256dV256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswzx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivswzx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivul_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivul_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivul_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivul_vvsl = struct {
+        const param_str = "V256dV256dLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivul_vvsmvl = struct {
+        const param_str = "V256dV256dLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivul_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivul_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivul_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivul_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivuw_vsvl = struct {
+        const param_str = "V256dUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivuw_vsvmvl = struct {
+        const param_str = "V256dUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivuw_vsvvl = struct {
+        const param_str = "V256dUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivuw_vvsl = struct {
+        const param_str = "V256dV256dUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivuw_vvsmvl = struct {
+        const param_str = "V256dV256dUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivuw_vvsvl = struct {
+        const param_str = "V256dV256dUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivuw_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivuw_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vdivuw_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_veqv_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_veqv_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_veqv_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_veqv_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_veqv_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_veqv_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vex_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfaddd_vsvl = struct {
+        const param_str = "V256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfaddd_vsvmvl = struct {
+        const param_str = "V256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfaddd_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfaddd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfaddd_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfaddd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfadds_vsvl = struct {
+        const param_str = "V256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfadds_vsvmvl = struct {
+        const param_str = "V256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfadds_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfadds_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfadds_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfadds_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmpd_vsvl = struct {
+        const param_str = "V256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmpd_vsvmvl = struct {
+        const param_str = "V256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmpd_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmpd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmpd_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmpd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmps_vsvl = struct {
+        const param_str = "V256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmps_vsvmvl = struct {
+        const param_str = "V256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmps_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmps_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmps_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfcmps_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivd_vsvl = struct {
+        const param_str = "V256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivd_vsvmvl = struct {
+        const param_str = "V256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivd_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivd_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivs_vsvl = struct {
+        const param_str = "V256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivs_vsvmvl = struct {
+        const param_str = "V256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivs_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivs_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivs_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfdivs_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmadd_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmadd_vsvvmvl = struct {
+        const param_str = "V256ddV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmadd_vsvvvl = struct {
+        const param_str = "V256ddV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmadd_vvsvl = struct {
+        const param_str = "V256dV256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmadd_vvsvmvl = struct {
+        const param_str = "V256dV256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmadd_vvsvvl = struct {
+        const param_str = "V256dV256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmadd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmadd_vvvvmvl = struct {
+        const param_str = "V256dV256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmadd_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmads_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmads_vsvvmvl = struct {
+        const param_str = "V256dfV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmads_vsvvvl = struct {
+        const param_str = "V256dfV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmads_vvsvl = struct {
+        const param_str = "V256dV256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmads_vvsvmvl = struct {
+        const param_str = "V256dV256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmads_vvsvvl = struct {
+        const param_str = "V256dV256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmads_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmads_vvvvmvl = struct {
+        const param_str = "V256dV256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmads_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxd_vsvl = struct {
+        const param_str = "V256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxd_vsvmvl = struct {
+        const param_str = "V256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxd_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxd_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxs_vsvl = struct {
+        const param_str = "V256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxs_vsvmvl = struct {
+        const param_str = "V256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxs_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxs_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxs_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmaxs_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmind_vsvl = struct {
+        const param_str = "V256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmind_vsvmvl = struct {
+        const param_str = "V256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmind_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmind_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmind_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmind_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmins_vsvl = struct {
+        const param_str = "V256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmins_vsvmvl = struct {
+        const param_str = "V256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmins_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmins_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmins_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmins_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdeq_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdeq_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdeqnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdeqnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdge_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdge_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdgenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdgenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdgt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdgt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdgtnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdgtnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdle_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdle_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdlenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdlenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdlt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdlt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdltnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdltnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdne_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdne_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdnenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdnenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdnum_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkdnum_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklaf_ml = struct {
+        const param_str = "V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklat_ml = struct {
+        const param_str = "V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkleq_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkleq_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkleqnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkleqnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklge_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklge_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklgenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklgenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklgt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklgt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklgtnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklgtnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklle_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklle_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkllenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkllenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkllt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkllt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklltnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklltnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklne_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklne_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklnenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklnenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklnum_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmklnum_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkseq_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkseq_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkseqnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkseqnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksge_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksge_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksgenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksgenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksgt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksgt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksgtnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksgtnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksle_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksle_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkslenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkslenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkslt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkslt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksltnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksltnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksne_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksne_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksnenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksnenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksnum_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmksnum_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkweq_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkweq_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkweqnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkweqnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwge_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwge_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwgenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwgenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwgt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwgt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwgtnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwgtnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwle_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwle_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwlenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwlenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwlt_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwlt_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwltnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwltnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwnan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwnan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwne_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwne_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwnenan_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwnenan_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwnum_mvl = struct {
+        const param_str = "V256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmkwnum_mvml = struct {
+        const param_str = "V256bV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbd_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbd_vsvvmvl = struct {
+        const param_str = "V256ddV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbd_vsvvvl = struct {
+        const param_str = "V256ddV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbd_vvsvl = struct {
+        const param_str = "V256dV256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbd_vvsvmvl = struct {
+        const param_str = "V256dV256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbd_vvsvvl = struct {
+        const param_str = "V256dV256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbd_vvvvmvl = struct {
+        const param_str = "V256dV256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbd_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbs_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbs_vsvvmvl = struct {
+        const param_str = "V256dfV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbs_vsvvvl = struct {
+        const param_str = "V256dfV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbs_vvsvl = struct {
+        const param_str = "V256dV256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbs_vvsvmvl = struct {
+        const param_str = "V256dV256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbs_vvsvvl = struct {
+        const param_str = "V256dV256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbs_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbs_vvvvmvl = struct {
+        const param_str = "V256dV256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmsbs_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuld_vsvl = struct {
+        const param_str = "V256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuld_vsvmvl = struct {
+        const param_str = "V256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuld_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuld_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuld_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuld_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuls_vsvl = struct {
+        const param_str = "V256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuls_vsvmvl = struct {
+        const param_str = "V256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuls_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuls_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuls_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfmuls_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmadd_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmadd_vsvvmvl = struct {
+        const param_str = "V256ddV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmadd_vsvvvl = struct {
+        const param_str = "V256ddV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmadd_vvsvl = struct {
+        const param_str = "V256dV256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmadd_vvsvmvl = struct {
+        const param_str = "V256dV256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmadd_vvsvvl = struct {
+        const param_str = "V256dV256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmadd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmadd_vvvvmvl = struct {
+        const param_str = "V256dV256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmadd_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmads_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmads_vsvvmvl = struct {
+        const param_str = "V256dfV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmads_vsvvvl = struct {
+        const param_str = "V256dfV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmads_vvsvl = struct {
+        const param_str = "V256dV256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmads_vvsvmvl = struct {
+        const param_str = "V256dV256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmads_vvsvvl = struct {
+        const param_str = "V256dV256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmads_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmads_vvvvmvl = struct {
+        const param_str = "V256dV256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmads_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbd_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbd_vsvvmvl = struct {
+        const param_str = "V256ddV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbd_vsvvvl = struct {
+        const param_str = "V256ddV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbd_vvsvl = struct {
+        const param_str = "V256dV256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbd_vvsvmvl = struct {
+        const param_str = "V256dV256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbd_vvsvvl = struct {
+        const param_str = "V256dV256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbd_vvvvmvl = struct {
+        const param_str = "V256dV256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbd_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbs_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbs_vsvvmvl = struct {
+        const param_str = "V256dfV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbs_vsvvvl = struct {
+        const param_str = "V256dfV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbs_vvsvl = struct {
+        const param_str = "V256dV256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbs_vvsvmvl = struct {
+        const param_str = "V256dV256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbs_vvsvvl = struct {
+        const param_str = "V256dV256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbs_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbs_vvvvmvl = struct {
+        const param_str = "V256dV256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfnmsbs_vvvvvl = struct {
+        const param_str = "V256dV256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmaxdfst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmaxdfst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmaxdlst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmaxdlst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmaxsfst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmaxsfst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmaxslst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmaxslst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmindfst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmindfst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmindlst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrmindlst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrminsfst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrminsfst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrminslst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfrminslst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsqrtd_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsqrtd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsqrts_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsqrts_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubd_vsvl = struct {
+        const param_str = "V256ddV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubd_vsvmvl = struct {
+        const param_str = "V256ddV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubd_vsvvl = struct {
+        const param_str = "V256ddV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubd_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubd_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubs_vsvl = struct {
+        const param_str = "V256dfV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubs_vsvmvl = struct {
+        const param_str = "V256dfV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubs_vsvvl = struct {
+        const param_str = "V256dfV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubs_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubs_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsubs_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsumd_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsumd_vvml = struct {
+        const param_str = "V256dV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsums_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vfsums_vvml = struct {
+        const param_str = "V256dV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgt_vvssl = struct {
+        const param_str = "V256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgt_vvssml = struct {
+        const param_str = "V256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgt_vvssmvl = struct {
+        const param_str = "V256dV256dLUiLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgt_vvssvl = struct {
+        const param_str = "V256dV256dLUiLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlsx_vvssl = struct {
+        const param_str = "V256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlsx_vvssml = struct {
+        const param_str = "V256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlsx_vvssmvl = struct {
+        const param_str = "V256dV256dLUiLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlsx_vvssvl = struct {
+        const param_str = "V256dV256dLUiLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlsxnc_vvssl = struct {
+        const param_str = "V256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlsxnc_vvssml = struct {
+        const param_str = "V256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlsxnc_vvssmvl = struct {
+        const param_str = "V256dV256dLUiLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlsxnc_vvssvl = struct {
+        const param_str = "V256dV256dLUiLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlzx_vvssl = struct {
+        const param_str = "V256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlzx_vvssml = struct {
+        const param_str = "V256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlzx_vvssmvl = struct {
+        const param_str = "V256dV256dLUiLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlzx_vvssvl = struct {
+        const param_str = "V256dV256dLUiLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlzxnc_vvssl = struct {
+        const param_str = "V256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlzxnc_vvssml = struct {
+        const param_str = "V256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlzxnc_vvssmvl = struct {
+        const param_str = "V256dV256dLUiLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtlzxnc_vvssvl = struct {
+        const param_str = "V256dV256dLUiLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtnc_vvssl = struct {
+        const param_str = "V256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtnc_vvssml = struct {
+        const param_str = "V256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtnc_vvssmvl = struct {
+        const param_str = "V256dV256dLUiLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtnc_vvssvl = struct {
+        const param_str = "V256dV256dLUiLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtu_vvssl = struct {
+        const param_str = "V256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtu_vvssml = struct {
+        const param_str = "V256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtu_vvssmvl = struct {
+        const param_str = "V256dV256dLUiLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtu_vvssvl = struct {
+        const param_str = "V256dV256dLUiLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtunc_vvssl = struct {
+        const param_str = "V256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtunc_vvssml = struct {
+        const param_str = "V256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtunc_vvssmvl = struct {
+        const param_str = "V256dV256dLUiLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vgtunc_vvssvl = struct {
+        const param_str = "V256dV256dLUiLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vld2d_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vld2d_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vld2dnc_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vld2dnc_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vld_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vld_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldl2dsx_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldl2dsx_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldl2dsxnc_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldl2dsxnc_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldl2dzx_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldl2dzx_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldl2dzxnc_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldl2dzxnc_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldlsx_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldlsx_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldlsxnc_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldlsxnc_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldlzx_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldlzx_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldlzxnc_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldlzxnc_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldnc_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldnc_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldu2d_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldu2d_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldu2dnc_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldu2dnc_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldu_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldu_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldunc_vssl = struct {
+        const param_str = "V256dLUivC*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldunc_vssvl = struct {
+        const param_str = "V256dLUivC*V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldz_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldz_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vldz_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxsl_vsvl = struct {
+        const param_str = "V256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxsl_vsvmvl = struct {
+        const param_str = "V256dLiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxsl_vsvvl = struct {
+        const param_str = "V256dLiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxsl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxsl_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxsl_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswsx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswsx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswsx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswsx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswsx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswzx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswzx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswzx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswzx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmaxswzx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminsl_vsvl = struct {
+        const param_str = "V256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminsl_vsvmvl = struct {
+        const param_str = "V256dLiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminsl_vsvvl = struct {
+        const param_str = "V256dLiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminsl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminsl_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminsl_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswsx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswsx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswsx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswsx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswsx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswzx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswzx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswzx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswzx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vminswzx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmrg_vsvml = struct {
+        const param_str = "V256dLUiV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmrg_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmrg_vvvml = struct {
+        const param_str = "V256dV256dV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmrg_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmrgw_vsvMl = struct {
+        const param_str = "V256dUiV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmrgw_vsvMvl = struct {
+        const param_str = "V256dUiV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmrgw_vvvMl = struct {
+        const param_str = "V256dV256dV256dV512bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmrgw_vvvMvl = struct {
+        const param_str = "V256dV256dV256dV512bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulsl_vsvl = struct {
+        const param_str = "V256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulsl_vsvmvl = struct {
+        const param_str = "V256dLiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulsl_vsvvl = struct {
+        const param_str = "V256dLiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulsl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulsl_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulsl_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulslw_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulslw_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulslw_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulslw_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswsx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswsx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswsx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswsx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswsx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswzx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswzx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswzx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswzx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulswzx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulul_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulul_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulul_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulul_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulul_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmulul_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmuluw_vsvl = struct {
+        const param_str = "V256dUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmuluw_vsvmvl = struct {
+        const param_str = "V256dUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmuluw_vsvvl = struct {
+        const param_str = "V256dUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmuluw_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmuluw_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmuluw_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmv_vsvl = struct {
+        const param_str = "V256dUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmv_vsvmvl = struct {
+        const param_str = "V256dUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vmv_vsvvl = struct {
+        const param_str = "V256dUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vor_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vor_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vor_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vor_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vor_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vor_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vpcnt_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vpcnt_vvmvl = struct {
+        const param_str = "V256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vpcnt_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrand_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrand_vvml = struct {
+        const param_str = "V256dV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrcpd_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrcpd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrcps_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrcps_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxslfst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxslfst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxsllst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxsllst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxswfstsx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxswfstsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxswfstzx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxswfstzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxswlstsx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxswlstsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxswlstzx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrmaxswlstzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminslfst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminslfst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminsllst_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminsllst_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminswfstsx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminswfstsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminswfstzx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminswfstzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminswlstsx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminswlstsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminswlstzx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrminswlstzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vror_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vror_vvml = struct {
+        const param_str = "V256dV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrsqrtd_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrsqrtd_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrsqrtdnex_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrsqrtdnex_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrsqrts_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrsqrts_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrsqrtsnex_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrsqrtsnex_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrxor_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vrxor_vvml = struct {
+        const param_str = "V256dV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsc_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsc_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscl_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscl_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsclnc_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsclnc_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsclncot_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsclncot_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsclot_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsclot_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscnc_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscnc_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscncot_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscncot_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscot_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscot_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscu_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscu_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscunc_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscunc_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscuncot_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscuncot_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscuot_vvssl = struct {
+        const param_str = "vV256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vscuot_vvssml = struct {
+        const param_str = "vV256dV256dLUiLUiV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vseq_vl = struct {
+        const param_str = "V256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vseq_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsfa_vvssl = struct {
+        const param_str = "V256dV256dLUiLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsfa_vvssmvl = struct {
+        const param_str = "V256dV256dLUiLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsfa_vvssvl = struct {
+        const param_str = "V256dV256dLUiLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vshf_vvvsl = struct {
+        const param_str = "V256dV256dV256dLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vshf_vvvsvl = struct {
+        const param_str = "V256dV256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslal_vvsl = struct {
+        const param_str = "V256dV256dLiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslal_vvsmvl = struct {
+        const param_str = "V256dV256dLiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslal_vvsvl = struct {
+        const param_str = "V256dV256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslal_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslal_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslal_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawsx_vvsl = struct {
+        const param_str = "V256dV256diUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawsx_vvsmvl = struct {
+        const param_str = "V256dV256diV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawsx_vvsvl = struct {
+        const param_str = "V256dV256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawsx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawsx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawzx_vvsl = struct {
+        const param_str = "V256dV256diUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawzx_vvsmvl = struct {
+        const param_str = "V256dV256diV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawzx_vvsvl = struct {
+        const param_str = "V256dV256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawzx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vslawzx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsll_vvsl = struct {
+        const param_str = "V256dV256dLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsll_vvsmvl = struct {
+        const param_str = "V256dV256dLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsll_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsll_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsll_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsll_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsral_vvsl = struct {
+        const param_str = "V256dV256dLiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsral_vvsmvl = struct {
+        const param_str = "V256dV256dLiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsral_vvsvl = struct {
+        const param_str = "V256dV256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsral_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsral_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsral_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawsx_vvsl = struct {
+        const param_str = "V256dV256diUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawsx_vvsmvl = struct {
+        const param_str = "V256dV256diV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawsx_vvsvl = struct {
+        const param_str = "V256dV256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawsx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawsx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawzx_vvsl = struct {
+        const param_str = "V256dV256diUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawzx_vvsmvl = struct {
+        const param_str = "V256dV256diV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawzx_vvsvl = struct {
+        const param_str = "V256dV256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawzx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrawzx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrl_vvsl = struct {
+        const param_str = "V256dV256dLUiUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrl_vvsmvl = struct {
+        const param_str = "V256dV256dLUiV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrl_vvsvl = struct {
+        const param_str = "V256dV256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrl_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsrl_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst2d_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst2d_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst2dnc_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst2dnc_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst2dncot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst2dncot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst2dot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst2dot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vst_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl2d_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl2d_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl2dnc_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl2dnc_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl2dncot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl2dncot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl2dot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl2dot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstl_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstlnc_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstlnc_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstlncot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstlncot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstlot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstlot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstnc_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstnc_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstncot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstncot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu2d_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu2d_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu2dnc_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu2dnc_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu2dncot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu2dncot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu2dot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu2dot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstu_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstunc_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstunc_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstuncot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstuncot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstuot_vssl = struct {
+        const param_str = "vV256dLUiv*Ui";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vstuot_vssml = struct {
+        const param_str = "vV256dLUiv*V256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubsl_vsvl = struct {
+        const param_str = "V256dLiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubsl_vsvmvl = struct {
+        const param_str = "V256dLiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubsl_vsvvl = struct {
+        const param_str = "V256dLiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubsl_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubsl_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubsl_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswsx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswsx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswsx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswsx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswsx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswsx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswzx_vsvl = struct {
+        const param_str = "V256diV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswzx_vsvmvl = struct {
+        const param_str = "V256diV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswzx_vsvvl = struct {
+        const param_str = "V256diV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswzx_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswzx_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubswzx_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubul_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubul_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubul_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubul_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubul_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubul_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubuw_vsvl = struct {
+        const param_str = "V256dUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubuw_vsvmvl = struct {
+        const param_str = "V256dUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubuw_vsvvl = struct {
+        const param_str = "V256dUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubuw_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubuw_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsubuw_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsuml_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsuml_vvml = struct {
+        const param_str = "V256dV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsumwsx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsumwsx_vvml = struct {
+        const param_str = "V256dV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsumwzx_vvl = struct {
+        const param_str = "V256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vsumwzx_vvml = struct {
+        const param_str = "V256dV256dV256bUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vxor_vsvl = struct {
+        const param_str = "V256dLUiV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vxor_vsvmvl = struct {
+        const param_str = "V256dLUiV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vxor_vsvvl = struct {
+        const param_str = "V256dLUiV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vxor_vvvl = struct {
+        const param_str = "V256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vxor_vvvmvl = struct {
+        const param_str = "V256dV256dV256dV256bV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_vxor_vvvvl = struct {
+        const param_str = "V256dV256dV256dV256dUi";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_xorm_MMM = struct {
+        const param_str = "V512bV512bV512b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_ve_vl_xorm_mmm = struct {
+        const param_str = "V256bV256bV256b";
+        const target_set = TargetSet.init(.{
+            .vevl_gen = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_vsnprintf = struct {
+        const param_str = "ic*zcC*a";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 2,
+        };
+    };
+
+    pub const __builtin_vsprintf = struct {
+        const param_str = "ic*cC*a";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const __builtin_vsx_extractuword = struct {
+        const param_str = "V2ULLiV16UcIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_insertword = struct {
+        const param_str = "V16UcV4UiV16UcIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_ldrmb = struct {
+        const param_str = "V16UcCc*Ii";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_lxvd2x = struct {
+        const param_str = "V2dLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_lxvd2x_be = struct {
+        const param_str = "V2dSLLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_lxvl = struct {
+        const param_str = "V4ivC*ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_lxvll = struct {
+        const param_str = "V4ivC*ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_lxvw4x = struct {
+        const param_str = "V4iLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_lxvw4x_be = struct {
+        const param_str = "V4iSLLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_scalar_extract_expq = struct {
+        const param_str = "ULLiLLd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_scalar_insert_exp_qp = struct {
+        const param_str = "LLdLLdULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_strmb = struct {
+        const param_str = "vCc*IiV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_stxvd2x = struct {
+        const param_str = "vV2dLiv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_stxvd2x_be = struct {
+        const param_str = "vV2dSLLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_stxvl = struct {
+        const param_str = "vV4iv*ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_stxvll = struct {
+        const param_str = "vV4iv*ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_stxvw4x = struct {
+        const param_str = "vV4iLiv*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_stxvw4x_be = struct {
+        const param_str = "vV4iSLLivC*";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xsmaxdp = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xsmindp = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvabsdp = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvabssp = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpeqdp = struct {
+        const param_str = "V2ULLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpeqdp_p = struct {
+        const param_str = "iiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpeqsp = struct {
+        const param_str = "V4UiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpeqsp_p = struct {
+        const param_str = "iiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpgedp = struct {
+        const param_str = "V2ULLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpgedp_p = struct {
+        const param_str = "iiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpgesp = struct {
+        const param_str = "V4UiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpgesp_p = struct {
+        const param_str = "iiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpgtdp = struct {
+        const param_str = "V2ULLiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpgtdp_p = struct {
+        const param_str = "iiV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpgtsp = struct {
+        const param_str = "V4UiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcmpgtsp_p = struct {
+        const param_str = "iiV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcpsgndp = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcpsgnsp = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvbf16spn = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvdpsp = struct {
+        const param_str = "V4fV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvdpsxws = struct {
+        const param_str = "V4SiV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvdpuxws = struct {
+        const param_str = "V4UiV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvhpsp = struct {
+        const param_str = "V4fV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvspbf16 = struct {
+        const param_str = "V16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvspdp = struct {
+        const param_str = "V2dV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvsphp = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvspsxds = struct {
+        const param_str = "V2SLLiV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvspuxds = struct {
+        const param_str = "V2ULLiV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvsxdsp = struct {
+        const param_str = "V4fV2SLLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvsxwdp = struct {
+        const param_str = "V2dV4Si";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvuxdsp = struct {
+        const param_str = "V4fV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvcvuxwdp = struct {
+        const param_str = "V2dV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvdivdp = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvdivsp = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xviexpdp = struct {
+        const param_str = "V2dV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xviexpsp = struct {
+        const param_str = "V4fV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvmaddadp = struct {
+        const param_str = "V2dV2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvmaddasp = struct {
+        const param_str = "V4fV4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvmaxdp = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvmaxsp = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvmindp = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvminsp = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvmsubadp = struct {
+        const param_str = "V2dV2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvmsubasp = struct {
+        const param_str = "V4fV4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvmuldp = struct {
+        const param_str = "V2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvmulsp = struct {
+        const param_str = "V4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvnmaddadp = struct {
+        const param_str = "V2dV2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvnmaddasp = struct {
+        const param_str = "V4fV4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvnmsubadp = struct {
+        const param_str = "V2dV2dV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvnmsubasp = struct {
+        const param_str = "V4fV4fV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrdpi = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrdpic = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrdpim = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrdpip = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrdpiz = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvredp = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvresp = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrspi = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrspic = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrspim = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrspip = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrspiz = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrsqrtedp = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvrsqrtesp = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvsqrtdp = struct {
+        const param_str = "V2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvsqrtsp = struct {
+        const param_str = "V4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvtdivdp = struct {
+        const param_str = "iV2dV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvtdivsp = struct {
+        const param_str = "iV4fV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvtlsbb = struct {
+        const param_str = "iV16UcUi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvtsqrtdp = struct {
+        const param_str = "iV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvtsqrtsp = struct {
+        const param_str = "iV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvtstdcdp = struct {
+        const param_str = "V2ULLiV2dIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvtstdcsp = struct {
+        const param_str = "V4UiV4fIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvxexpdp = struct {
+        const param_str = "V2ULLiV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvxexpsp = struct {
+        const param_str = "V4UiV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvxsigdp = struct {
+        const param_str = "V2ULLiV2d";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xvxsigsp = struct {
+        const param_str = "V4UiV4f";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxblendvb = struct {
+        const param_str = "V16UcV16UcV16UcV16Uc";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxblendvd = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLiV2ULLi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxblendvh = struct {
+        const param_str = "V8UsV8UsV8UsV8Us";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxblendvw = struct {
+        const param_str = "V4UiV4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxeval = struct {
+        const param_str = "V2ULLiV2ULLiV2ULLiV2ULLiIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxgenpcvbm = struct {
+        const param_str = "V16UcV16Uci";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxgenpcvdm = struct {
+        const param_str = "V2ULLiV2ULLii";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxgenpcvhm = struct {
+        const param_str = "V8UsV8Usi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxgenpcvwm = struct {
+        const param_str = "V4UiV4Uii";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxleqv = struct {
+        const param_str = "V4UiV4UiV4Ui";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxpermdi = struct {
+        const param_str = "v.";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_vsx_xxpermx = struct {
+        const param_str = "V16UcV16UcV16UcV16UcIi";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+    };
+
+    pub const __builtin_vsx_xxsldwi = struct {
+        const param_str = "v.";
+        const target_set = TargetSet.init(.{
+            .ppc = true,
+        });
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __builtin_wasm_max_f32 = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_max_f64 = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_memory_grow = struct {
+        const param_str = "zIiz";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_wasm_memory_size = struct {
+        const param_str = "zIi";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __builtin_wasm_min_f32 = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_min_f64 = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_trunc_s_i32_f32 = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_trunc_s_i32_f64 = struct {
+        const param_str = "id";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_trunc_s_i64_f32 = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_trunc_s_i64_f64 = struct {
+        const param_str = "LLid";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_trunc_u_i32_f32 = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_trunc_u_i32_f64 = struct {
+        const param_str = "id";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_trunc_u_i64_f32 = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wasm_trunc_u_i64_f64 = struct {
+        const param_str = "LLid";
+        const target_set = TargetSet.init(.{
+            .webassembly = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __builtin_wcschr = struct {
+        const param_str = "w*wC*w";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_wcscmp = struct {
+        const param_str = "iwC*wC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_wcslen = struct {
+        const param_str = "zwC*";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_wcsncmp = struct {
+        const param_str = "iwC*wC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_wmemchr = struct {
+        const param_str = "w*wC*wz";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_wmemcmp = struct {
+        const param_str = "iwC*wC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_wmemcpy = struct {
+        const param_str = "w*w*wC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __builtin_wmemmove = struct {
+        const param_str = "w*w*wC*z";
+        const attributes = Attributes{
+            .lib_function_with_builtin_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __c11_atomic_is_lock_free = struct {
+        const param_str = "bz";
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const __c11_atomic_signal_fence = struct {
+        const param_str = "vi";
+        const attributes = Attributes{};
+    };
+
+    pub const __c11_atomic_thread_fence = struct {
+        const param_str = "vi";
+        const attributes = Attributes{};
+    };
+
+    pub const __clear_cache = struct {
+        const param_str = "vv*v*";
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __cospi = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __cospif = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __debugbreak = struct {
+        const param_str = "v";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __dmb = struct {
+        const param_str = "vUi";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __dsb = struct {
+        const param_str = "vUi";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __emit = struct {
+        const param_str = "vIUiC";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __exception_code = struct {
+        const param_str = "UNi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __exception_info = struct {
+        const param_str = "v*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __exp10 = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __exp10f = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __fastfail = struct {
+        const param_str = "vUi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .noreturn = true,
+        };
+    };
+
+    pub const __finite = struct {
+        const param_str = "id";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const __finitef = struct {
+        const param_str = "if";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const __finitel = struct {
+        const param_str = "iLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const __isb = struct {
+        const param_str = "vUi";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __iso_volatile_load16 = struct {
+        const param_str = "ssCD*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __iso_volatile_load32 = struct {
+        const param_str = "iiCD*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __iso_volatile_load64 = struct {
+        const param_str = "LLiLLiCD*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __iso_volatile_load8 = struct {
+        const param_str = "ccCD*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __iso_volatile_store16 = struct {
+        const param_str = "vsD*s";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __iso_volatile_store32 = struct {
+        const param_str = "viD*i";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __iso_volatile_store64 = struct {
+        const param_str = "vLLiD*LLi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __iso_volatile_store8 = struct {
+        const param_str = "vcD*c";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __ldrexd = struct {
+        const param_str = "WiWiCD*";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .arm = true,
+        });
+    };
+
+    pub const __lzcnt = struct {
+        const param_str = "UiUi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __lzcnt16 = struct {
+        const param_str = "UsUs";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __lzcnt64 = struct {
+        const param_str = "UWiUWi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __noop = struct {
+        const param_str = "i.";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_add_rm_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rm_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rm_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rn_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rn_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rn_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rp_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rp_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rp_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rz_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_add_rz_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_atom_add_gen_f = struct {
+        const param_str = "ffD*f";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_add_gen_i = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_add_gen_l = struct {
+        const param_str = "LiLiD*Li";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_add_gen_ll = struct {
+        const param_str = "LLiLLiD*LLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_and_gen_i = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_and_gen_l = struct {
+        const param_str = "LiLiD*Li";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_and_gen_ll = struct {
+        const param_str = "LLiLLiD*LLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_cas_gen_i = struct {
+        const param_str = "iiD*ii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_cas_gen_l = struct {
+        const param_str = "LiLiD*LiLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_cas_gen_ll = struct {
+        const param_str = "LLiLLiD*LLiLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_dec_gen_ui = struct {
+        const param_str = "UiUiD*Ui";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_inc_gen_ui = struct {
+        const param_str = "UiUiD*Ui";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_max_gen_i = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_max_gen_l = struct {
+        const param_str = "LiLiD*Li";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_max_gen_ll = struct {
+        const param_str = "LLiLLiD*LLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_max_gen_ui = struct {
+        const param_str = "UiUiD*Ui";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_max_gen_ul = struct {
+        const param_str = "ULiULiD*ULi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_max_gen_ull = struct {
+        const param_str = "ULLiULLiD*ULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_min_gen_i = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_min_gen_l = struct {
+        const param_str = "LiLiD*Li";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_min_gen_ll = struct {
+        const param_str = "LLiLLiD*LLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_min_gen_ui = struct {
+        const param_str = "UiUiD*Ui";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_min_gen_ul = struct {
+        const param_str = "ULiULiD*ULi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_min_gen_ull = struct {
+        const param_str = "ULLiULLiD*ULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_or_gen_i = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_or_gen_l = struct {
+        const param_str = "LiLiD*Li";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_or_gen_ll = struct {
+        const param_str = "LLiLLiD*LLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_sub_gen_i = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_sub_gen_l = struct {
+        const param_str = "LiLiD*Li";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_sub_gen_ll = struct {
+        const param_str = "LLiLLiD*LLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_xchg_gen_i = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_xchg_gen_l = struct {
+        const param_str = "LiLiD*Li";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_xchg_gen_ll = struct {
+        const param_str = "LLiLLiD*LLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_xor_gen_i = struct {
+        const param_str = "iiD*i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_xor_gen_l = struct {
+        const param_str = "LiLiD*Li";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_atom_xor_gen_ll = struct {
+        const param_str = "LLiLLiD*LLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_bar0_and = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_bar0_or = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_bar0_popc = struct {
+        const param_str = "ii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_bar_sync = struct {
+        const param_str = "vi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_bitcast_d2ll = struct {
+        const param_str = "LLid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_bitcast_f2i = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_bitcast_i2f = struct {
+        const param_str = "fi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_bitcast_ll2d = struct {
+        const param_str = "dLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ceil_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ceil_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ceil_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_compiler_error = struct {
+        const param_str = "vcC*4";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_compiler_warn = struct {
+        const param_str = "vcC*4";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_cos_approx_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_cos_approx_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2f_rm = struct {
+        const param_str = "fd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2f_rm_ftz = struct {
+        const param_str = "fd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2f_rn = struct {
+        const param_str = "fd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2f_rn_ftz = struct {
+        const param_str = "fd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2f_rp = struct {
+        const param_str = "fd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2f_rp_ftz = struct {
+        const param_str = "fd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2f_rz = struct {
+        const param_str = "fd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2f_rz_ftz = struct {
+        const param_str = "fd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2i_hi = struct {
+        const param_str = "id";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2i_lo = struct {
+        const param_str = "id";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2i_rm = struct {
+        const param_str = "id";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2i_rn = struct {
+        const param_str = "id";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2i_rp = struct {
+        const param_str = "id";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2i_rz = struct {
+        const param_str = "id";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ll_rm = struct {
+        const param_str = "LLid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ll_rn = struct {
+        const param_str = "LLid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ll_rp = struct {
+        const param_str = "LLid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ll_rz = struct {
+        const param_str = "LLid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ui_rm = struct {
+        const param_str = "Uid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ui_rn = struct {
+        const param_str = "Uid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ui_rp = struct {
+        const param_str = "Uid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ui_rz = struct {
+        const param_str = "Uid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ull_rm = struct {
+        const param_str = "ULLid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ull_rn = struct {
+        const param_str = "ULLid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ull_rp = struct {
+        const param_str = "ULLid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_d2ull_rz = struct {
+        const param_str = "ULLid";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_approx_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_approx_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rm_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rm_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rm_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rn_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rn_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rn_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rp_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rp_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rp_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rz_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_div_rz_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ex2_approx_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ex2_approx_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ex2_approx_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2h_rn = struct {
+        const param_str = "Usf";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2h_rn_ftz = struct {
+        const param_str = "Usf";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2i_rm = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2i_rm_ftz = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2i_rn = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2i_rn_ftz = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2i_rp = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2i_rp_ftz = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2i_rz = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2i_rz_ftz = struct {
+        const param_str = "if";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ll_rm = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ll_rm_ftz = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ll_rn = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ll_rn_ftz = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ll_rp = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ll_rp_ftz = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ll_rz = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ll_rz_ftz = struct {
+        const param_str = "LLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ui_rm = struct {
+        const param_str = "Uif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ui_rm_ftz = struct {
+        const param_str = "Uif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ui_rn = struct {
+        const param_str = "Uif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ui_rn_ftz = struct {
+        const param_str = "Uif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ui_rp = struct {
+        const param_str = "Uif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ui_rp_ftz = struct {
+        const param_str = "Uif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ui_rz = struct {
+        const param_str = "Uif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ui_rz_ftz = struct {
+        const param_str = "Uif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ull_rm = struct {
+        const param_str = "ULLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ull_rm_ftz = struct {
+        const param_str = "ULLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ull_rn = struct {
+        const param_str = "ULLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ull_rn_ftz = struct {
+        const param_str = "ULLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ull_rp = struct {
+        const param_str = "ULLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ull_rp_ftz = struct {
+        const param_str = "ULLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ull_rz = struct {
+        const param_str = "ULLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_f2ull_rz_ftz = struct {
+        const param_str = "ULLif";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fabs_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fabs_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fabs_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_floor_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_floor_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_floor_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rm_d = struct {
+        const param_str = "dddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rm_f = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rm_ftz_f = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rn_d = struct {
+        const param_str = "dddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rn_f = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rn_ftz_f = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rp_d = struct {
+        const param_str = "dddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rp_f = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rp_ftz_f = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rz_d = struct {
+        const param_str = "dddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rz_f = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fma_rz_ftz_f = struct {
+        const param_str = "ffff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fmax_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fmax_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fmax_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fmin_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fmin_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_fmin_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_i2d_rm = struct {
+        const param_str = "di";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_i2d_rn = struct {
+        const param_str = "di";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_i2d_rp = struct {
+        const param_str = "di";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_i2d_rz = struct {
+        const param_str = "di";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_i2f_rm = struct {
+        const param_str = "fi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_i2f_rn = struct {
+        const param_str = "fi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_i2f_rp = struct {
+        const param_str = "fi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_i2f_rz = struct {
+        const param_str = "fi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_isspacep_const = struct {
+        const param_str = "bvC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_isspacep_global = struct {
+        const param_str = "bvC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_isspacep_local = struct {
+        const param_str = "bvC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_isspacep_shared = struct {
+        const param_str = "bvC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_ldg_c = struct {
+        const param_str = "ccC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_c2 = struct {
+        const param_str = "E2cE2cC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_c4 = struct {
+        const param_str = "E4cE4cC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_d = struct {
+        const param_str = "ddC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_d2 = struct {
+        const param_str = "E2dE2dC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_f = struct {
+        const param_str = "ffC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_f2 = struct {
+        const param_str = "E2fE2fC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_f4 = struct {
+        const param_str = "E4fE4fC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_i = struct {
+        const param_str = "iiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_i2 = struct {
+        const param_str = "E2iE2iC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_i4 = struct {
+        const param_str = "E4iE4iC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_l = struct {
+        const param_str = "LiLiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_ll = struct {
+        const param_str = "LLiLLiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_ll2 = struct {
+        const param_str = "E2LLiE2LLiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_s = struct {
+        const param_str = "ssC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_s2 = struct {
+        const param_str = "E2sE2sC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_s4 = struct {
+        const param_str = "E4sE4sC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_uc = struct {
+        const param_str = "UcUcC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_uc2 = struct {
+        const param_str = "E2UcE2UcC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_uc4 = struct {
+        const param_str = "E4UcE4UcC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_ui = struct {
+        const param_str = "UiUiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_ui2 = struct {
+        const param_str = "E2UiE2UiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_ui4 = struct {
+        const param_str = "E4UiE4UiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_ul = struct {
+        const param_str = "ULiULiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_ull = struct {
+        const param_str = "ULLiULLiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_ull2 = struct {
+        const param_str = "E2ULLiE2ULLiC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_us = struct {
+        const param_str = "UsUsC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_us2 = struct {
+        const param_str = "E2UsE2UsC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ldg_us4 = struct {
+        const param_str = "E4UsE4UsC*";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_lg2_approx_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_lg2_approx_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_lg2_approx_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ll2d_rm = struct {
+        const param_str = "dLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ll2d_rn = struct {
+        const param_str = "dLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ll2d_rp = struct {
+        const param_str = "dLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ll2d_rz = struct {
+        const param_str = "dLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ll2f_rm = struct {
+        const param_str = "fLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ll2f_rn = struct {
+        const param_str = "fLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ll2f_rp = struct {
+        const param_str = "fLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ll2f_rz = struct {
+        const param_str = "fLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_lohi_i2d = struct {
+        const param_str = "dii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_membar_cta = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_membar_gl = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_membar_sys = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_memcpy = struct {
+        const param_str = "vUc*Uc*zi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_memset = struct {
+        const param_str = "vUc*Uczi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul24_i = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul24_ui = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rm_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rm_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rm_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rn_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rn_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rn_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rp_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rp_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rp_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rz_d = struct {
+        const param_str = "ddd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mul_rz_ftz_f = struct {
+        const param_str = "fff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mulhi_i = struct {
+        const param_str = "iii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mulhi_ll = struct {
+        const param_str = "LLiLLiLLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mulhi_ui = struct {
+        const param_str = "UiUiUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_mulhi_ull = struct {
+        const param_str = "ULLiULLiULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_prmt = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_approx_ftz_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_approx_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rm_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rm_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rm_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rn_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rn_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rn_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rp_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rp_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rp_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rz_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rcp_rz_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_read_ptx_sreg_clock = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_read_ptx_sreg_clock64 = struct {
+        const param_str = "LLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_read_ptx_sreg_ctaid_w = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_ctaid_x = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_ctaid_y = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_ctaid_z = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_gridid = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_laneid = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_lanemask_eq = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_lanemask_ge = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_lanemask_gt = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_lanemask_le = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_lanemask_lt = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_nctaid_w = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_nctaid_x = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_nctaid_y = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_nctaid_z = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_nsmid = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_ntid_w = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_ntid_x = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_ntid_y = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_ntid_z = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_nwarpid = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_pm0 = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_read_ptx_sreg_pm1 = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_read_ptx_sreg_pm2 = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_read_ptx_sreg_pm3 = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{};
+    };
+
+    pub const __nvvm_read_ptx_sreg_smid = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_tid_w = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_tid_x = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_tid_y = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_tid_z = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_read_ptx_sreg_warpid = struct {
+        const param_str = "i";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __nvvm_round_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_round_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_round_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rsqrt_approx_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rsqrt_approx_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_rsqrt_approx_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sad_i = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sad_ui = struct {
+        const param_str = "UiUiUiUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_saturate_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_saturate_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_saturate_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_shfl_bfly_f32 = struct {
+        const param_str = "ffii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_shfl_bfly_i32 = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_shfl_down_f32 = struct {
+        const param_str = "ffii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_shfl_down_i32 = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_shfl_idx_f32 = struct {
+        const param_str = "ffii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_shfl_idx_i32 = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_shfl_up_f32 = struct {
+        const param_str = "ffii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_shfl_up_i32 = struct {
+        const param_str = "iiii";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sin_approx_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sin_approx_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_approx_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_approx_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rm_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rm_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rm_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rn_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rn_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rn_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rp_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rp_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rp_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rz_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_sqrt_rz_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_trunc_d = struct {
+        const param_str = "dd";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_trunc_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_trunc_ftz_f = struct {
+        const param_str = "ff";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ui2d_rm = struct {
+        const param_str = "dUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ui2d_rn = struct {
+        const param_str = "dUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ui2d_rp = struct {
+        const param_str = "dUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ui2d_rz = struct {
+        const param_str = "dUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ui2f_rm = struct {
+        const param_str = "fUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ui2f_rn = struct {
+        const param_str = "fUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ui2f_rp = struct {
+        const param_str = "fUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ui2f_rz = struct {
+        const param_str = "fUi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ull2d_rm = struct {
+        const param_str = "dULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ull2d_rn = struct {
+        const param_str = "dULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ull2d_rp = struct {
+        const param_str = "dULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ull2d_rz = struct {
+        const param_str = "dULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ull2f_rm = struct {
+        const param_str = "fULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ull2f_rn = struct {
+        const param_str = "fULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ull2f_rp = struct {
+        const param_str = "fULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_ull2f_rz = struct {
+        const param_str = "fULLi";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_vote_all = struct {
+        const param_str = "bb";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_vote_any = struct {
+        const param_str = "bb";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_vote_ballot = struct {
+        const param_str = "Uib";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __nvvm_vote_uni = struct {
+        const param_str = "bb";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __popcnt = struct {
+        const param_str = "UiUi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __popcnt16 = struct {
+        const param_str = "UsUs";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __popcnt64 = struct {
+        const param_str = "UWiUWi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .@"const" = true,
+        };
+    };
+
+    pub const __rdtsc = struct {
+        const param_str = "UOi";
+        const target_set = TargetSet.init(.{
+            .x86 = true,
+        });
+    };
+
+    pub const __sev = struct {
+        const param_str = "v";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __sevl = struct {
+        const param_str = "v";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __sigsetjmp = struct {
+        const param_str = "iSJi";
+        const header = .setjmp;
+        const attributes = Attributes{
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+            .returns_twice = true,
+        };
+    };
+
+    pub const __sinpi = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __sinpif = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __sync_add_and_fetch = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_add_and_fetch_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_add_and_fetch_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_add_and_fetch_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_add_and_fetch_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_add_and_fetch_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_and_and_fetch = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_and_and_fetch_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_and_and_fetch_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_and_and_fetch_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_and_and_fetch_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_and_and_fetch_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_bool_compare_and_swap = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_bool_compare_and_swap_1 = struct {
+        const param_str = "bcD*cc.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_bool_compare_and_swap_16 = struct {
+        const param_str = "bLLLiD*LLLiLLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_bool_compare_and_swap_2 = struct {
+        const param_str = "bsD*ss.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_bool_compare_and_swap_4 = struct {
+        const param_str = "biD*ii.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_bool_compare_and_swap_8 = struct {
+        const param_str = "bLLiD*LLiLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_add = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_add_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_add_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_add_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_add_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_add_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_and = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_and_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_and_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_and_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_and_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_and_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_max = struct {
+        const param_str = "iiD*i";
+        const attributes = Attributes{};
+    };
+
+    pub const __sync_fetch_and_min = struct {
+        const param_str = "iiD*i";
+        const attributes = Attributes{};
+    };
+
+    pub const __sync_fetch_and_nand = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_nand_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_nand_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_nand_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_nand_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_nand_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_or = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_or_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_or_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_or_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_or_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_or_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_sub = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_sub_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_sub_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_sub_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_sub_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_sub_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_umax = struct {
+        const param_str = "UiUiD*Ui";
+        const attributes = Attributes{};
+    };
+
+    pub const __sync_fetch_and_umin = struct {
+        const param_str = "UiUiD*Ui";
+        const attributes = Attributes{};
+    };
+
+    pub const __sync_fetch_and_xor = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_xor_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_xor_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_xor_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_xor_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_fetch_and_xor_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_release = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_release_1 = struct {
+        const param_str = "vcD*.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_release_16 = struct {
+        const param_str = "vLLLiD*.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_release_2 = struct {
+        const param_str = "vsD*.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_release_4 = struct {
+        const param_str = "viD*.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_release_8 = struct {
+        const param_str = "vLLiD*.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_test_and_set = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_test_and_set_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_test_and_set_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_test_and_set_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_test_and_set_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_lock_test_and_set_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_nand_and_fetch = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_nand_and_fetch_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_nand_and_fetch_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_nand_and_fetch_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_nand_and_fetch_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_nand_and_fetch_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_or_and_fetch = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_or_and_fetch_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_or_and_fetch_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_or_and_fetch_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_or_and_fetch_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_or_and_fetch_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_sub_and_fetch = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_sub_and_fetch_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_sub_and_fetch_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_sub_and_fetch_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_sub_and_fetch_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_sub_and_fetch_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_swap = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_swap_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_swap_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_swap_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_swap_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_swap_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_synchronize = struct {
+        const param_str = "v";
+        const attributes = Attributes{};
+    };
+
+    pub const __sync_val_compare_and_swap = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_val_compare_and_swap_1 = struct {
+        const param_str = "ccD*cc.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_val_compare_and_swap_16 = struct {
+        const param_str = "LLLiLLLiD*LLLiLLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_val_compare_and_swap_2 = struct {
+        const param_str = "ssD*ss.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_val_compare_and_swap_4 = struct {
+        const param_str = "iiD*ii.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_val_compare_and_swap_8 = struct {
+        const param_str = "LLiLLiD*LLiLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_xor_and_fetch = struct {
+        const param_str = "v.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_xor_and_fetch_1 = struct {
+        const param_str = "ccD*c.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_xor_and_fetch_16 = struct {
+        const param_str = "LLLiLLLiD*LLLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_xor_and_fetch_2 = struct {
+        const param_str = "ssD*s.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_xor_and_fetch_4 = struct {
+        const param_str = "iiD*i.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __sync_xor_and_fetch_8 = struct {
+        const param_str = "LLiLLiD*LLi.";
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __syncthreads = struct {
+        const param_str = "v";
+        const target_set = TargetSet.init(.{
+            .nvptx = true,
+        });
+    };
+
+    pub const __tanpi = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __tanpif = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const __va_start = struct {
+        const param_str = "vc**.";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .custom_typecheck = true,
+        };
+    };
+
+    pub const __warn_memset_zero_len = struct {
+        const param_str = "v";
+        const attributes = Attributes{
+            .pure = true,
+        };
+    };
+
+    pub const __wfe = struct {
+        const param_str = "v";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __wfi = struct {
+        const param_str = "v";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const __xray_customevent = struct {
+        const param_str = "vcC*z";
+    };
+
+    pub const __xray_typedevent = struct {
+        const param_str = "vzcC*z";
+    };
+
+    pub const __yield = struct {
+        const param_str = "v";
+        const language = .all_ms_languages;
+        const target_set = TargetSet.init(.{
+            .aarch64 = true,
+            .arm = true,
+        });
+    };
+
+    pub const _abnormal_termination = struct {
+        const param_str = "i";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _alloca = struct {
+        const param_str = "v*z";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _bittest = struct {
+        const param_str = "UcNiC*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _bittest64 = struct {
+        const param_str = "UcWiC*Wi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _bittestandcomplement = struct {
+        const param_str = "UcNi*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _bittestandcomplement64 = struct {
+        const param_str = "UcWi*Wi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _bittestandreset = struct {
+        const param_str = "UcNi*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _bittestandreset64 = struct {
+        const param_str = "UcWi*Wi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _bittestandset = struct {
+        const param_str = "UcNi*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _bittestandset64 = struct {
+        const param_str = "UcWi*Wi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _byteswap_uint64 = struct {
+        const param_str = "ULLiULLi";
+        const language = .all_ms_languages;
+        const header = .stdlib;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const _byteswap_ulong = struct {
+        const param_str = "UNiUNi";
+        const language = .all_ms_languages;
+        const header = .stdlib;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const _byteswap_ushort = struct {
+        const param_str = "UsUs";
+        const language = .all_ms_languages;
+        const header = .stdlib;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const _exception_code = struct {
+        const param_str = "UNi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _exception_info = struct {
+        const param_str = "v*";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _exit = struct {
+        const param_str = "vi";
+        const language = .all_gnu_languages;
+        const header = .unistd;
+        const attributes = Attributes{
+            .noreturn = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const _interlockedbittestandreset = struct {
+        const param_str = "UcNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _interlockedbittestandreset64 = struct {
+        const param_str = "UcWiD*Wi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _interlockedbittestandreset_acq = struct {
+        const param_str = "UcNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _interlockedbittestandreset_nf = struct {
+        const param_str = "UcNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _interlockedbittestandreset_rel = struct {
+        const param_str = "UcNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _interlockedbittestandset = struct {
+        const param_str = "UcNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _interlockedbittestandset64 = struct {
+        const param_str = "UcWiD*Wi";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _interlockedbittestandset_acq = struct {
+        const param_str = "UcNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _interlockedbittestandset_nf = struct {
+        const param_str = "UcNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _interlockedbittestandset_rel = struct {
+        const param_str = "UcNiD*Ni";
+        const language = .all_ms_languages;
+        const attributes = Attributes{};
+    };
+
+    pub const _longjmp = struct {
+        const param_str = "vJi";
+        const language = .all_gnu_languages;
+        const header = .setjmp;
+        const attributes = Attributes{
+            .noreturn = true,
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const _lrotl = struct {
+        const param_str = "ULiULii";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _lrotr = struct {
+        const param_str = "ULiULii";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _rotl = struct {
+        const param_str = "UiUii";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _rotl16 = struct {
+        const param_str = "UsUsUc";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _rotl64 = struct {
+        const param_str = "UWiUWii";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _rotl8 = struct {
+        const param_str = "UcUcUc";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _rotr = struct {
+        const param_str = "UiUii";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _rotr16 = struct {
+        const param_str = "UsUsUc";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _rotr64 = struct {
+        const param_str = "UWiUWii";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _rotr8 = struct {
+        const param_str = "UcUcUc";
+        const language = .all_ms_languages;
+        const attributes = Attributes{
+            .const_evaluable = true,
+        };
+    };
+
+    pub const _setjmp = struct {
+        const param_str = "iJ";
+        const header = .setjmp;
+        const attributes = Attributes{
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+            .returns_twice = true,
+        };
+    };
+
+    pub const _setjmpex = struct {
+        const param_str = "iJ";
+        const language = .all_ms_languages;
+        const header = .setjmpex;
+        const attributes = Attributes{
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+            .returns_twice = true,
+        };
+    };
+
+    pub const abort = struct {
+        const param_str = "v";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .noreturn = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const abs = struct {
+        const param_str = "ii";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const acos = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const acosf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const acosh = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const acoshf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const acoshl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const acosl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const aligned_alloc = struct {
+        const param_str = "v*zz";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const alloca = struct {
+        const param_str = "v*z";
+        const language = .all_gnu_languages;
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const asin = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const asinf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const asinh = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const asinhf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const asinhl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const asinl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const atan = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const atan2 = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const atan2f = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const atan2l = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const atanf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const atanh = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const atanhf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const atanhl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const atanl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const bcmp = struct {
+        const param_str = "ivC*vC*z";
+        const language = .all_gnu_languages;
+        const header = .strings;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const bzero = struct {
+        const param_str = "vv*z";
+        const language = .all_gnu_languages;
+        const header = .strings;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const cabs = struct {
+        const param_str = "dXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cabsf = struct {
+        const param_str = "fXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cabsl = struct {
+        const param_str = "LdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cacos = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cacosf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cacosh = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cacoshf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cacoshl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cacosl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const calloc = struct {
+        const param_str = "v*zz";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const carg = struct {
+        const param_str = "dXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cargf = struct {
+        const param_str = "fXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cargl = struct {
+        const param_str = "LdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const casin = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const casinf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const casinh = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const casinhf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const casinhl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const casinl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const catan = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const catanf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const catanh = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const catanhf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const catanhl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const catanl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cbrt = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const cbrtf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const cbrtl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const ccos = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ccosf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ccosh = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ccoshf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ccoshl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ccosl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ceil = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const ceilf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const ceill = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const cexp = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cexpf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cexpl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cimag = struct {
+        const param_str = "dXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const cimagf = struct {
+        const param_str = "fXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const cimagl = struct {
+        const param_str = "LdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const clog = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const clogf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const clogl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const conj = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const conjf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const conjl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const copysign = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const copysignf = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const copysignl = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const cos = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cosf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cosh = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const coshf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const coshl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cosl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cpow = struct {
+        const param_str = "XdXdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cpowf = struct {
+        const param_str = "XfXfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cpowl = struct {
+        const param_str = "XLdXLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const cproj = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const cprojf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const cprojl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const creal = struct {
+        const param_str = "dXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const crealf = struct {
+        const param_str = "fXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const creall = struct {
+        const param_str = "LdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const csin = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const csinf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const csinh = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const csinhf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const csinhl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const csinl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const csqrt = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const csqrtf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const csqrtl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ctan = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ctanf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ctanh = struct {
+        const param_str = "XdXd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ctanhf = struct {
+        const param_str = "XfXf";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ctanhl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ctanl = struct {
+        const param_str = "XLdXLd";
+        const header = .complex;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const erf = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const erfc = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const erfcf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const erfcl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const erff = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const erfl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const exit = struct {
+        const param_str = "vi";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .noreturn = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const exp = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const exp2 = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const exp2f = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const exp2l = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const expf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const expl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const expm1 = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const expm1f = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const expm1l = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const fabs = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fabsf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fabsl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fdim = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const fdimf = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const fdiml = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const finite = struct {
+        const param_str = "id";
+        const language = .gnu_lang;
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const finitef = struct {
+        const param_str = "if";
+        const language = .gnu_lang;
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const finitel = struct {
+        const param_str = "iLd";
+        const language = .gnu_lang;
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const floor = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const floorf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const floorl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fma = struct {
+        const param_str = "dddd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const fmaf = struct {
+        const param_str = "ffff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const fmal = struct {
+        const param_str = "LdLdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const fmax = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fmaxf = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fmaxl = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fmin = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fminf = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fminl = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fmod = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const fmodf = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const fmodl = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const fopen = struct {
+        const param_str = "P*cC*cC*";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fprintf = struct {
+        const param_str = "iP*cC*.";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const fread = struct {
+        const param_str = "zv*zzP*";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const free = struct {
+        const param_str = "vv*";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const frexp = struct {
+        const param_str = "ddi*";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const frexpf = struct {
+        const param_str = "ffi*";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const frexpl = struct {
+        const param_str = "LdLdi*";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const fscanf = struct {
+        const param_str = "iP*RcC*R.";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .scanf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const fwrite = struct {
+        const param_str = "zvC*zzP*";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const getcontext = struct {
+        const param_str = "iK*";
+        const header = .setjmp;
+        const attributes = Attributes{
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+            .returns_twice = true,
+        };
+    };
+
+    pub const hypot = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const hypotf = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const hypotl = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ilogb = struct {
+        const param_str = "id";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ilogbf = struct {
+        const param_str = "if";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ilogbl = struct {
+        const param_str = "iLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const index = struct {
+        const param_str = "c*cC*i";
+        const language = .all_gnu_languages;
+        const header = .strings;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const isalnum = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const isalpha = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const isblank = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const iscntrl = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const isdigit = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const isgraph = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const islower = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const isprint = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const ispunct = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const isspace = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const isupper = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const isxdigit = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const labs = struct {
+        const param_str = "LiLi";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const ldexp = struct {
+        const param_str = "ddi";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ldexpf = struct {
+        const param_str = "ffi";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const ldexpl = struct {
+        const param_str = "LdLdi";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const lgamma = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const lgammaf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const lgammal = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const llabs = struct {
+        const param_str = "LLiLLi";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const llrint = struct {
+        const param_str = "LLid";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const llrintf = struct {
+        const param_str = "LLif";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const llrintl = struct {
+        const param_str = "LLiLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const llround = struct {
+        const param_str = "LLid";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const llroundf = struct {
+        const param_str = "LLif";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const llroundl = struct {
+        const param_str = "LLiLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log10 = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log10f = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log10l = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log1p = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log1pf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log1pl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log2 = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log2f = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const log2l = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const logb = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const logbf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const logbl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const logf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const logl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const longjmp = struct {
+        const param_str = "vJi";
+        const header = .setjmp;
+        const attributes = Attributes{
+            .noreturn = true,
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const lrint = struct {
+        const param_str = "Lid";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const lrintf = struct {
+        const param_str = "Lif";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const lrintl = struct {
+        const param_str = "LiLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const lround = struct {
+        const param_str = "Lid";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const lroundf = struct {
+        const param_str = "Lif";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const lroundl = struct {
+        const param_str = "LiLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const malloc = struct {
+        const param_str = "v*z";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const memalign = struct {
+        const param_str = "v*zz";
+        const language = .all_gnu_languages;
+        const header = .malloc;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const memccpy = struct {
+        const param_str = "v*v*vC*iz";
+        const language = .all_gnu_languages;
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const memchr = struct {
+        const param_str = "v*vC*iz";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const memcmp = struct {
+        const param_str = "ivC*vC*z";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const memcpy = struct {
+        const param_str = "v*v*vC*z";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const memmove = struct {
+        const param_str = "v*v*vC*z";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const mempcpy = struct {
+        const param_str = "v*v*vC*z";
+        const language = .all_gnu_languages;
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const memset = struct {
+        const param_str = "v*v*iz";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const modf = struct {
+        const param_str = "ddd*";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const modff = struct {
+        const param_str = "fff*";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const modfl = struct {
+        const param_str = "LdLdLd*";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const nan = struct {
+        const param_str = "dcC*";
+        const header = .math;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const nanf = struct {
+        const param_str = "fcC*";
+        const header = .math;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const nanl = struct {
+        const param_str = "LdcC*";
+        const header = .math;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const nearbyint = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const nearbyintf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const nearbyintl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const nextafter = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const nextafterf = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const nextafterl = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const nexttoward = struct {
+        const param_str = "ddLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const nexttowardf = struct {
+        const param_str = "ffLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const nexttowardl = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const pow = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const powf = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const powl = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const printf = struct {
+        const param_str = "icC*.";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 0,
+        };
+    };
+
+    pub const realloc = struct {
+        const param_str = "v*v*z";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const remainder = struct {
+        const param_str = "ddd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const remainderf = struct {
+        const param_str = "fff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const remainderl = struct {
+        const param_str = "LdLdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const remquo = struct {
+        const param_str = "dddi*";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const remquof = struct {
+        const param_str = "fffi*";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const remquol = struct {
+        const param_str = "LdLdLdi*";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const rindex = struct {
+        const param_str = "c*cC*i";
+        const language = .all_gnu_languages;
+        const header = .strings;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const rint = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_fp_exceptions = true,
+        };
+    };
+
+    pub const rintf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_fp_exceptions = true,
+        };
+    };
+
+    pub const rintl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_fp_exceptions = true,
+        };
+    };
+
+    pub const round = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const roundf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const roundl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const savectx = struct {
+        const param_str = "iJ";
+        const header = .setjmp;
+        const attributes = Attributes{
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+            .returns_twice = true,
+        };
+    };
+
+    pub const scalbln = struct {
+        const param_str = "ddLi";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const scalblnf = struct {
+        const param_str = "ffLi";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const scalblnl = struct {
+        const param_str = "LdLdLi";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const scalbn = struct {
+        const param_str = "ddi";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const scalbnf = struct {
+        const param_str = "ffi";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const scalbnl = struct {
+        const param_str = "LdLdi";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const scanf = struct {
+        const param_str = "icC*R.";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .scanf,
+            .format_string_position = 0,
+        };
+    };
+
+    pub const setjmp = struct {
+        const param_str = "iJ";
+        const header = .setjmp;
+        const attributes = Attributes{
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+            .returns_twice = true,
+        };
+    };
+
+    pub const siglongjmp = struct {
+        const param_str = "vSJi";
+        const language = .all_gnu_languages;
+        const header = .setjmp;
+        const attributes = Attributes{
+            .noreturn = true,
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const sigsetjmp = struct {
+        const param_str = "iSJi";
+        const header = .setjmp;
+        const attributes = Attributes{
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+            .returns_twice = true,
+        };
+    };
+
+    pub const sin = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const sinf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const sinh = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const sinhf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const sinhl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const sinl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const snprintf = struct {
+        const param_str = "ic*zcC*.";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 2,
+        };
+    };
+
+    pub const sprintf = struct {
+        const param_str = "ic*cC*.";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .printf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const sqrt = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const sqrtf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const sqrtl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const sscanf = struct {
+        const param_str = "icC*RcC*R.";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .scanf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const stpcpy = struct {
+        const param_str = "c*c*cC*";
+        const language = .all_gnu_languages;
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const stpncpy = struct {
+        const param_str = "c*c*cC*z";
+        const language = .all_gnu_languages;
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strcasecmp = struct {
+        const param_str = "icC*cC*";
+        const language = .all_gnu_languages;
+        const header = .strings;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strcat = struct {
+        const param_str = "c*c*cC*";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strchr = struct {
+        const param_str = "c*cC*i";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const strcmp = struct {
+        const param_str = "icC*cC*";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const strcpy = struct {
+        const param_str = "c*c*cC*";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strcspn = struct {
+        const param_str = "zcC*cC*";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strdup = struct {
+        const param_str = "c*cC*";
+        const language = .all_gnu_languages;
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strerror = struct {
+        const param_str = "c*i";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strlcat = struct {
+        const param_str = "zc*cC*z";
+        const language = .all_gnu_languages;
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strlcpy = struct {
+        const param_str = "zc*cC*z";
+        const language = .all_gnu_languages;
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strlen = struct {
+        const param_str = "zcC*";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const strncasecmp = struct {
+        const param_str = "icC*cC*z";
+        const language = .all_gnu_languages;
+        const header = .strings;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strncat = struct {
+        const param_str = "c*c*cC*z";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strncmp = struct {
+        const param_str = "icC*cC*z";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const strncpy = struct {
+        const param_str = "c*c*cC*z";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strndup = struct {
+        const param_str = "c*cC*z";
+        const language = .all_gnu_languages;
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strpbrk = struct {
+        const param_str = "c*cC*cC*";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strrchr = struct {
+        const param_str = "c*cC*i";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strspn = struct {
+        const param_str = "zcC*cC*";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strstr = struct {
+        const param_str = "c*cC*cC*";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strtod = struct {
+        const param_str = "dcC*c**";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strtof = struct {
+        const param_str = "fcC*c**";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strtok = struct {
+        const param_str = "c*c*cC*";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strtol = struct {
+        const param_str = "LicC*c**i";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strtold = struct {
+        const param_str = "LdcC*c**";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strtoll = struct {
+        const param_str = "LLicC*c**i";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strtoul = struct {
+        const param_str = "ULicC*c**i";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strtoull = struct {
+        const param_str = "ULLicC*c**i";
+        const header = .stdlib;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const strxfrm = struct {
+        const param_str = "zc*cC*z";
+        const header = .string;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const tan = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const tanf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const tanh = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const tanhf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const tanhl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const tanl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const tgamma = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const tgammaf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const tgammal = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_without_errno_and_fp_exceptions = true,
+        };
+    };
+
+    pub const tolower = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const toupper = struct {
+        const param_str = "ii";
+        const header = .ctype;
+        const attributes = Attributes{
+            .pure = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const trunc = struct {
+        const param_str = "dd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const truncf = struct {
+        const param_str = "ff";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const truncl = struct {
+        const param_str = "LdLd";
+        const header = .math;
+        const attributes = Attributes{
+            .@"const" = true,
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const va_copy = struct {
+        const param_str = "vAA";
+        const header = .stdarg;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const va_end = struct {
+        const param_str = "vA";
+        const header = .stdarg;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const va_start = struct {
+        const param_str = "vA.";
+        const header = .stdarg;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+        };
+    };
+
+    pub const vfork = struct {
+        const param_str = "p";
+        const header = .unistd;
+        const attributes = Attributes{
+            .allow_type_mismatch = true,
+            .lib_function_without_prefix = true,
+            .returns_twice = true,
+        };
+    };
+
+    pub const vfprintf = struct {
+        const param_str = "iP*cC*a";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const vfscanf = struct {
+        const param_str = "iP*RcC*Ra";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .vscanf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const vprintf = struct {
+        const param_str = "icC*a";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 0,
+        };
+    };
+
+    pub const vscanf = struct {
+        const param_str = "icC*Ra";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .vscanf,
+            .format_string_position = 0,
+        };
+    };
+
+    pub const vsnprintf = struct {
+        const param_str = "ic*zcC*a";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 2,
+        };
+    };
+
+    pub const vsprintf = struct {
+        const param_str = "ic*cC*a";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .vprintf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const vsscanf = struct {
+        const param_str = "icC*RcC*Ra";
+        const header = .stdio;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .format_kind = .vscanf,
+            .format_string_position = 1,
+        };
+    };
+
+    pub const wcschr = struct {
+        const param_str = "w*wC*w";
+        const header = .wchar;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const wcscmp = struct {
+        const param_str = "iwC*wC*";
+        const header = .wchar;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const wcslen = struct {
+        const param_str = "zwC*";
+        const header = .wchar;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const wcsncmp = struct {
+        const param_str = "iwC*wC*z";
+        const header = .wchar;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const wmemchr = struct {
+        const param_str = "w*wC*wz";
+        const header = .wchar;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const wmemcmp = struct {
+        const param_str = "iwC*wC*z";
+        const header = .wchar;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const wmemcpy = struct {
+        const param_str = "w*w*wC*z";
+        const header = .wchar;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+
+    pub const wmemmove = struct {
+        const param_str = "w*w*wC*z";
+        const header = .wchar;
+        const attributes = Attributes{
+            .lib_function_without_prefix = true,
+            .const_evaluable = true,
+        };
+    };
+};
+pub const MaxParamCount = 12;
deps/aro/builtins/Properties.zig
@@ -0,0 +1,138 @@
+const std = @import("std");
+
+const Properties = @This();
+
+language: Language,
+attributes: Attributes,
+header: Header,
+target_set: TargetSet,
+
+/// Header which must be included for a builtin to be available
+pub const Header = enum {
+    none,
+    /// stdio.h
+    stdio,
+    /// stdlib.h
+    stdlib,
+    /// setjmpex.h
+    setjmpex,
+    /// stdarg.h
+    stdarg,
+    /// string.h
+    string,
+    /// ctype.h
+    ctype,
+    /// wchar.h
+    wchar,
+    /// setjmp.h
+    setjmp,
+    /// malloc.h
+    malloc,
+    /// strings.h
+    strings,
+    /// unistd.h
+    unistd,
+    /// pthread.h
+    pthread,
+    /// math.h
+    math,
+    /// complex.h
+    complex,
+    /// Blocks.h
+    blocks,
+};
+
+/// Languages in which a builtin is available
+pub const Language = enum {
+    all_languages,
+    all_ms_languages,
+    all_gnu_languages,
+    gnu_lang,
+};
+
+pub const Attributes = packed struct {
+    /// Function does not return
+    noreturn: bool = false,
+
+    /// Function has no side effects
+    pure: bool = false,
+
+    /// Function has no side effects and does not read memory
+    @"const": bool = false,
+
+    /// Signature is meaningless; use custom typecheck
+    custom_typecheck: bool = false,
+
+    /// A declaration of this builtin should be recognized even if the type doesn't match the specified signature.
+    allow_type_mismatch: bool = false,
+
+    /// this is a libc/libm function with a '__builtin_' prefix added.
+    lib_function_with_builtin_prefix: bool = false,
+
+    /// this is a libc/libm function without a '__builtin_' prefix.  This builtin is disableable by '-fno-builtin-foo'
+    lib_function_without_prefix: bool = false,
+
+    /// Function returns twice (e.g. setjmp)
+    returns_twice: bool = false,
+
+    /// Nature of the format string passed to this function
+    format_kind: enum(u3) {
+        /// Does not take a format string
+        none,
+        /// this is a printf-like function whose Nth argument is the format string
+        printf,
+        /// function is like vprintf in that it accepts its arguments as a va_list rather than through an ellipsis
+        vprintf,
+        /// this is a scanf-like function whose Nth argument is the format string
+        scanf,
+        /// the function is like vscanf in that it accepts its arguments as a va_list rather than through an ellipsis
+        vscanf,
+    } = .none,
+
+    /// Position of format string argument. Only meaningful if format_kind is not .none
+    format_string_position: u5 = 0,
+
+    /// if false, arguments are not evaluated
+    eval_args: bool = true,
+
+    /// no side effects and does not read memory, but only when -fno-math-errno and FP exceptions are ignored
+    const_without_errno_and_fp_exceptions: bool = false,
+
+    /// no side effects and does not read memory, but only when FP exceptions are ignored
+    const_without_fp_exceptions: bool = false,
+
+    /// this function can be constant evaluated by the frontend
+    const_evaluable: bool = false,
+};
+
+pub const Target = enum {
+    /// Supported on all targets
+    basic,
+    aarch64,
+    aarch64_neon_sve_bridge,
+    aarch64_neon_sve_bridge_cg,
+    amdgpu,
+    arm,
+    bpf,
+    hexagon,
+    hexagon_dep,
+    hexagon_map_custom_dep,
+    loong_arch,
+    mips,
+    neon,
+    nvptx,
+    ppc,
+    riscv,
+    riscv_vector,
+    sve,
+    systemz,
+    ve,
+    vevl_gen,
+    webassembly,
+    x86,
+    x86_64,
+    xcore,
+};
+
+/// Targets for which a builtin is enabled
+pub const TargetSet = std.enums.EnumSet(Target);
deps/aro/builtins/TypeDescription.zig
@@ -0,0 +1,277 @@
+const std = @import("std");
+
+const TypeDescription = @This();
+
+prefix: []const Prefix,
+spec: Spec,
+suffix: []const Suffix,
+
+pub const Component = union(enum) {
+    prefix: Prefix,
+    spec: Spec,
+    suffix: Suffix,
+};
+
+pub const ComponentIterator = struct {
+    str: []const u8,
+    idx: usize,
+
+    pub fn init(str: []const u8) ComponentIterator {
+        return .{
+            .str = str,
+            .idx = 0,
+        };
+    }
+
+    pub fn peek(self: *ComponentIterator) ?Component {
+        const idx = self.idx;
+        defer self.idx = idx;
+        return self.next();
+    }
+
+    pub fn next(self: *ComponentIterator) ?Component {
+        if (self.idx == self.str.len) return null;
+        const c = self.str[self.idx];
+        self.idx += 1;
+        switch (c) {
+            'L' => {
+                if (self.str[self.idx] != 'L') return .{ .prefix = .L };
+                self.idx += 1;
+                if (self.str[self.idx] != 'L') return .{ .prefix = .LL };
+                self.idx += 1;
+                return .{ .prefix = .LLL };
+            },
+            'Z' => return .{ .prefix = .Z },
+            'W' => return .{ .prefix = .W },
+            'N' => return .{ .prefix = .N },
+            'O' => return .{ .prefix = .O },
+            'S' => {
+                if (self.str[self.idx] == 'J') {
+                    self.idx += 1;
+                    return .{ .spec = .SJ };
+                }
+                return .{ .prefix = .S };
+            },
+            'U' => return .{ .prefix = .U },
+            'I' => return .{ .prefix = .I },
+
+            'v' => return .{ .spec = .v },
+            'b' => return .{ .spec = .b },
+            'c' => return .{ .spec = .c },
+            's' => return .{ .spec = .s },
+            'i' => return .{ .spec = .i },
+            'h' => return .{ .spec = .h },
+            'x' => return .{ .spec = .x },
+            'y' => return .{ .spec = .y },
+            'f' => return .{ .spec = .f },
+            'd' => return .{ .spec = .d },
+            'z' => return .{ .spec = .z },
+            'w' => return .{ .spec = .w },
+            'F' => return .{ .spec = .F },
+            'a' => return .{ .spec = .a },
+            'A' => return .{ .spec = .A },
+            'V', 'q', 'E' => {
+                const start = self.idx;
+                while (std.ascii.isDigit(self.str[self.idx])) : (self.idx += 1) {}
+                const count = std.fmt.parseUnsigned(u32, self.str[start..self.idx], 10) catch unreachable;
+                return switch (c) {
+                    'V' => .{ .spec = .{ .V = count } },
+                    'q' => .{ .spec = .{ .q = count } },
+                    'E' => .{ .spec = .{ .E = count } },
+                    else => unreachable,
+                };
+            },
+            'X' => {
+                defer self.idx += 1;
+                switch (self.str[self.idx]) {
+                    'f' => return .{ .spec = .{ .X = .float } },
+                    'd' => return .{ .spec = .{ .X = .double } },
+                    'L' => {
+                        self.idx += 1;
+                        return .{ .spec = .{ .X = .longdouble } };
+                    },
+                    else => unreachable,
+                }
+            },
+            'Y' => return .{ .spec = .Y },
+            'P' => return .{ .spec = .P },
+            'J' => return .{ .spec = .J },
+            'K' => return .{ .spec = .K },
+            'p' => return .{ .spec = .p },
+            '.' => {
+                // can only appear at end of param string; indicates varargs function
+                std.debug.assert(self.idx == self.str.len);
+                return null;
+            },
+            '!' => {
+                std.debug.assert(self.str.len == 1);
+                return .{ .spec = .@"!" };
+            },
+
+            '*' => {
+                if (self.idx < self.str.len and std.ascii.isDigit(self.str[self.idx])) {
+                    defer self.idx += 1;
+                    const addr_space = self.str[self.idx] - '0';
+                    return .{ .suffix = .{ .@"*" = addr_space } };
+                } else {
+                    return .{ .suffix = .{ .@"*" = null } };
+                }
+            },
+            'C' => return .{ .suffix = .C },
+            'D' => return .{ .suffix = .D },
+            'R' => return .{ .suffix = .R },
+            else => unreachable,
+        }
+        return null;
+    }
+};
+
+pub const TypeIterator = struct {
+    param_str: []const u8,
+    prefix: [4]Prefix,
+    spec: Spec,
+    suffix: [4]Suffix,
+    idx: usize,
+
+    pub fn init(param_str: []const u8) TypeIterator {
+        return .{
+            .param_str = param_str,
+            .prefix = undefined,
+            .spec = undefined,
+            .suffix = undefined,
+            .idx = 0,
+        };
+    }
+
+    /// Returned `TypeDescription` contains fields which are slices into the underlying `TypeIterator`
+    /// The returned value is invalidated when `.next()` is called again or the TypeIterator goes out
+    // of scope.
+    pub fn next(self: *TypeIterator) ?TypeDescription {
+        var it = ComponentIterator.init(self.param_str[self.idx..]);
+        defer self.idx += it.idx;
+
+        var prefix_count: usize = 0;
+        var maybe_spec: ?Spec = null;
+        var suffix_count: usize = 0;
+        while (it.peek()) |component| {
+            switch (component) {
+                .prefix => |prefix| {
+                    if (maybe_spec != null) break;
+                    self.prefix[prefix_count] = prefix;
+                    prefix_count += 1;
+                },
+                .spec => |spec| {
+                    if (maybe_spec != null) break;
+                    maybe_spec = spec;
+                },
+                .suffix => |suffix| {
+                    std.debug.assert(maybe_spec != null);
+                    self.suffix[suffix_count] = suffix;
+                    suffix_count += 1;
+                },
+            }
+            _ = it.next();
+        }
+        if (maybe_spec) |spec| {
+            return TypeDescription{
+                .prefix = self.prefix[0..prefix_count],
+                .spec = spec,
+                .suffix = self.suffix[0..suffix_count],
+            };
+        }
+        return null;
+    }
+};
+
+const Prefix = enum {
+    /// long (e.g. Li for 'long int', Ld for 'long double')
+    L,
+    /// long long (e.g. LLi for 'long long int', LLd for __float128)
+    LL,
+    /// __int128_t (e.g. LLLi)
+    LLL,
+    /// int32_t (require a native 32-bit integer type on the target)
+    Z,
+    /// int64_t (require a native 64-bit integer type on the target)
+    W,
+    /// 'int' size if target is LP64, 'L' otherwise.
+    N,
+    /// long for OpenCL targets, long long otherwise.
+    O,
+    /// signed
+    S,
+    /// unsigned
+    U,
+    /// Required to constant fold to an integer constant expression.
+    I,
+};
+
+const Spec = union(enum) {
+    /// void
+    v,
+    /// boolean
+    b,
+    /// char
+    c,
+    /// short
+    s,
+    /// int
+    i,
+    /// half (__fp16, OpenCL)
+    h,
+    /// half (_Float16)
+    x,
+    /// half (__bf16)
+    y,
+    /// float
+    f,
+    /// double
+    d,
+    /// size_t
+    z,
+    /// wchar_t
+    w,
+    /// constant CFString
+    F,
+    /// __builtin_va_list
+    a,
+    /// "reference" to __builtin_va_list
+    A,
+    /// Vector, followed by the number of elements and the base type.
+    V: u32,
+    /// Scalable vector, followed by the number of elements and the base type.
+    q: u32,
+    /// ext_vector, followed by the number of elements and the base type.
+    E: u32,
+    /// _Complex, followed by the base type.
+    X: enum {
+        float,
+        double,
+        longdouble,
+    },
+    /// ptrdiff_t
+    Y,
+    /// FILE
+    P,
+    /// jmp_buf
+    J,
+    /// sigjmp_buf
+    SJ,
+    /// ucontext_t
+    K,
+    /// pid_t
+    p,
+    /// Used to indicate a builtin with target-dependent param types. Must appear by itself
+    @"!",
+};
+
+const Suffix = union(enum) {
+    /// pointer (optionally followed by an address space number,if no address space is specified than any address space will be accepted)
+    @"*": ?u8,
+    /// const
+    C,
+    /// volatile
+    D,
+    /// restrict
+    R,
+};
deps/aro/codegen/x86_64.zig
@@ -0,0 +1,221 @@
+const std = @import("std");
+const Codegen = @import("../Codegen_legacy.zig");
+const Tree = @import("../Tree.zig");
+const NodeIndex = Tree.NodeIndex;
+const x86_64 = @import("zig").codegen.x86_64;
+const Register = x86_64.Register;
+const RegisterManager = @import("zig").RegisterManager;
+
+const Fn = @This();
+
+const Value = union(enum) {
+    symbol: []const u8,
+    immediate: i64,
+    register: Register,
+    none,
+};
+
+register_manager: RegisterManager(Fn, Register, &x86_64.callee_preserved_regs) = .{},
+data: *std.ArrayList(u8),
+c: *Codegen,
+
+pub fn deinit(func: *Fn) void {
+    func.* = undefined;
+}
+
+pub fn genFn(c: *Codegen, decl: NodeIndex, data: *std.ArrayList(u8)) Codegen.Error!void {
+    var func = Fn{ .data = data, .c = c };
+    defer func.deinit();
+
+    // function prologue
+    try func.data.appendSlice(&.{
+        0x55, // push rbp
+        0x48, 0x89, 0xe5, // mov rbp,rsp
+    });
+    _ = try func.genNode(c.node_data[@intFromEnum(decl)].decl.node);
+    // all functions are guaranteed to end in a return statement so no extra work required here
+}
+
+pub fn spillInst(f: *Fn, reg: Register, inst: u32) !void {
+    _ = inst;
+    _ = reg;
+    _ = f;
+}
+
+fn setReg(func: *Fn, val: Value, reg: Register) !void {
+    switch (val) {
+        .none => unreachable,
+        .symbol => |sym| {
+            // lea address with 0 and add relocation
+            const encoder = try x86_64.Encoder.init(func.data, 8);
+            encoder.rex(.{ .w = true });
+            encoder.opcode_1byte(0x8D);
+            encoder.modRm_RIPDisp32(reg.low_id());
+
+            const offset = func.data.items.len;
+            encoder.imm32(0);
+
+            try func.c.obj.addRelocation(sym, .func, offset, -4);
+        },
+        .immediate => |x| if (x == 0) {
+            // 32-bit moves zero-extend to 64-bit, so xoring the 32-bit
+            // register is the fastest way to zero a register.
+            // The encoding for `xor r32, r32` is `0x31 /r`.
+            const encoder = try x86_64.Encoder.init(func.data, 3);
+
+            // If we're accessing e.g. r8d, we need to use a REX prefix before the actual operation. Since
+            // this is a 32-bit operation, the W flag is set to zero. X is also zero, as we're not using a SIB.
+            // Both R and B are set, as we're extending, in effect, the register bits *and* the operand.
+            encoder.rex(.{ .r = reg.isExtended(), .b = reg.isExtended() });
+            encoder.opcode_1byte(0x31);
+            // Section 3.1.1.1 of the Intel x64 Manual states that "/r indicates that the
+            // ModR/M byte of the instruction contains a register operand and an r/m operand."
+            encoder.modRm_direct(reg.low_id(), reg.low_id());
+        } else if (x <= std.math.maxInt(i32)) {
+            // Next best case: if we set the lower four bytes, the upper four will be zeroed.
+            //
+            // The encoding for `mov IMM32 -> REG` is (0xB8 + R) IMM.
+
+            const encoder = try x86_64.Encoder.init(func.data, 6);
+            // Just as with XORing, we need a REX prefix. This time though, we only
+            // need the B bit set, as we're extending the opcode's register field,
+            // and there is no Mod R/M byte.
+            encoder.rex(.{ .b = reg.isExtended() });
+            encoder.opcode_withReg(0xB8, reg.low_id());
+
+            // no ModR/M byte
+
+            // IMM
+            encoder.imm32(@intCast(x));
+        } else {
+            // Worst case: we need to load the 64-bit register with the IMM. GNU's assemblers calls
+            // this `movabs`, though this is officially just a different variant of the plain `mov`
+            // instruction.
+            //
+            // This encoding is, in fact, the *same* as the one used for 32-bit loads. The only
+            // difference is that we set REX.W before the instruction, which extends the load to
+            // 64-bit and uses the full bit-width of the register.
+            {
+                const encoder = try x86_64.Encoder.init(func.data, 10);
+                encoder.rex(.{ .w = true, .b = reg.isExtended() });
+                encoder.opcode_withReg(0xB8, reg.low_id());
+                encoder.imm64(@bitCast(x));
+            }
+        },
+        .register => |src_reg| {
+            // If the registers are the same, nothing to do.
+            if (src_reg.id() == reg.id())
+                return;
+
+            // This is a variant of 8B /r.
+            const encoder = try x86_64.Encoder.init(func.data, 3);
+            encoder.rex(.{
+                .w = true,
+                .r = reg.isExtended(),
+                .b = src_reg.isExtended(),
+            });
+            encoder.opcode_1byte(0x8B);
+            encoder.modRm_direct(reg.low_id(), src_reg.low_id());
+        },
+    }
+}
+
+fn genNode(func: *Fn, node: NodeIndex) Codegen.Error!Value {
+    if (func.c.tree.value_map.get(node)) |some| {
+        if (some.tag == .int)
+            return Value{ .immediate = @bitCast(some.data.int) };
+    }
+
+    const data = func.c.node_data[@intFromEnum(node)];
+    switch (func.c.node_tag[@intFromEnum(node)]) {
+        .static_assert => return Value{ .none = {} },
+        .compound_stmt_two => {
+            if (data.bin.lhs != .none) _ = try func.genNode(data.bin.lhs);
+            if (data.bin.rhs != .none) _ = try func.genNode(data.bin.rhs);
+            return Value{ .none = {} };
+        },
+        .compound_stmt => {
+            for (func.c.tree.data[data.range.start..data.range.end]) |stmt| {
+                _ = try func.genNode(stmt);
+            }
+            return Value{ .none = {} };
+        },
+        .call_expr_one => if (data.bin.rhs != .none)
+            return func.genCall(data.bin.lhs, &.{data.bin.rhs})
+        else
+            return func.genCall(data.bin.lhs, &.{}),
+        .call_expr => return func.genCall(func.c.tree.data[data.range.start], func.c.tree.data[data.range.start + 1 .. data.range.end]),
+        .explicit_cast, .implicit_cast => {
+            switch (data.cast.kind) {
+                .function_to_pointer,
+                .array_to_pointer,
+                => return func.genNode(data.cast.operand), // no-op
+                else => return func.c.comp.diag.fatalNoSrc("TODO x86_64 genNode for cast {s}\n", .{@tagName(data.cast.kind)}),
+            }
+        },
+        .decl_ref_expr => {
+            // TODO locals and arguments
+            return Value{ .symbol = func.c.tree.tokSlice(data.decl_ref) };
+        },
+        .return_stmt => {
+            const value = try func.genNode(data.un);
+            try func.setReg(value, x86_64.c_abi_int_return_regs[0]);
+            try func.data.appendSlice(&.{
+                0x5d, // pop rbp
+                0xc3, // ret
+            });
+            return Value{ .none = {} };
+        },
+        .implicit_return => {
+            try func.setReg(.{ .immediate = 0 }, x86_64.c_abi_int_return_regs[0]);
+            try func.data.appendSlice(&.{
+                0x5d, // pop rbp
+                0xc3, // ret
+            });
+            return Value{ .none = {} };
+        },
+        .int_literal => return Value{ .immediate = @bitCast(data.int) },
+        .string_literal_expr => {
+            const range = func.c.tree.value_map.get(node).?.data.bytes;
+            const str_bytes = range.slice(func.c.tree.strings);
+            const section = try func.c.obj.getSection(.strings);
+            const start = section.items.len;
+            try section.appendSlice(str_bytes);
+            const symbol_name = try func.c.obj.declareSymbol(.strings, null, .Internal, .variable, start, str_bytes.len);
+            return Value{ .symbol = symbol_name };
+        },
+        else => return func.c.comp.diag.fatalNoSrc("TODO x86_64 genNode {}\n", .{func.c.node_tag[@intFromEnum(node)]}),
+    }
+}
+
+fn genCall(func: *Fn, lhs: NodeIndex, args: []const NodeIndex) Codegen.Error!Value {
+    if (args.len > x86_64.c_abi_int_param_regs.len)
+        return func.c.comp.diag.fatalNoSrc("TODO more than args {d}\n", .{x86_64.c_abi_int_param_regs.len});
+
+    const func_value = try func.genNode(lhs);
+    for (args, 0..) |arg, i| {
+        const value = try func.genNode(arg);
+        try func.setReg(value, x86_64.c_abi_int_param_regs[i]);
+    }
+
+    switch (func_value) {
+        .none => unreachable,
+        .symbol => |sym| {
+            const encoder = try x86_64.Encoder.init(func.data, 5);
+            encoder.opcode_1byte(0xe8);
+
+            const offset = func.data.items.len;
+            encoder.imm32(0);
+
+            try func.c.obj.addRelocation(sym, .func, offset, -4);
+        },
+        .immediate => return func.c.comp.diag.fatalNoSrc("TODO call immediate\n", .{}),
+        .register => return func.c.comp.diag.fatalNoSrc("TODO call reg\n", .{}),
+    }
+    return Value{ .register = x86_64.c_abi_int_return_regs[0] };
+}
+
+pub fn genVar(c: *Codegen, decl: NodeIndex) Codegen.Error!void {
+    _ = c;
+    _ = decl;
+}
deps/aro/Driver/Distro.zig
@@ -0,0 +1,329 @@
+//! Tools for figuring out what Linux distro we're running on
+
+const std = @import("std");
+const mem = std.mem;
+const util = @import("../util.zig");
+const Filesystem = @import("Filesystem.zig").Filesystem;
+
+const MAX_BYTES = 1024; // TODO: Can we assume 1024 bytes enough for the info we need?
+
+/// Value for linker `--hash-style=` argument
+pub const HashStyle = enum {
+    both,
+    gnu,
+};
+
+pub const Tag = enum {
+    alpine,
+    arch,
+    debian_lenny,
+    debian_squeeze,
+    debian_wheezy,
+    debian_jessie,
+    debian_stretch,
+    debian_buster,
+    debian_bullseye,
+    debian_bookworm,
+    debian_trixie,
+    exherbo,
+    rhel5,
+    rhel6,
+    rhel7,
+    fedora,
+    gentoo,
+    open_suse,
+    ubuntu_hardy,
+    ubuntu_intrepid,
+    ubuntu_jaunty,
+    ubuntu_karmic,
+    ubuntu_lucid,
+    ubuntu_maverick,
+    ubuntu_natty,
+    ubuntu_oneiric,
+    ubuntu_precise,
+    ubuntu_quantal,
+    ubuntu_raring,
+    ubuntu_saucy,
+    ubuntu_trusty,
+    ubuntu_utopic,
+    ubuntu_vivid,
+    ubuntu_wily,
+    ubuntu_xenial,
+    ubuntu_yakkety,
+    ubuntu_zesty,
+    ubuntu_artful,
+    ubuntu_bionic,
+    ubuntu_cosmic,
+    ubuntu_disco,
+    ubuntu_eoan,
+    ubuntu_focal,
+    ubuntu_groovy,
+    ubuntu_hirsute,
+    ubuntu_impish,
+    ubuntu_jammy,
+    ubuntu_kinetic,
+    ubuntu_lunar,
+    unknown,
+
+    pub fn getHashStyle(self: Tag) HashStyle {
+        if (self.isOpenSUSE()) return .both;
+        return switch (self) {
+            .ubuntu_lucid,
+            .ubuntu_jaunty,
+            .ubuntu_karmic,
+            => .both,
+            else => .gnu,
+        };
+    }
+
+    pub fn isRedhat(self: Tag) bool {
+        return switch (self) {
+            .fedora,
+            .rhel5,
+            .rhel6,
+            .rhel7,
+            => true,
+            else => false,
+        };
+    }
+
+    pub fn isOpenSUSE(self: Tag) bool {
+        return self == .open_suse;
+    }
+
+    pub fn isDebian(self: Tag) bool {
+        return switch (self) {
+            .debian_lenny,
+            .debian_squeeze,
+            .debian_wheezy,
+            .debian_jessie,
+            .debian_stretch,
+            .debian_buster,
+            .debian_bullseye,
+            .debian_bookworm,
+            .debian_trixie,
+            => true,
+            else => false,
+        };
+    }
+    pub fn isUbuntu(self: Tag) bool {
+        return switch (self) {
+            .ubuntu_hardy,
+            .ubuntu_intrepid,
+            .ubuntu_jaunty,
+            .ubuntu_karmic,
+            .ubuntu_lucid,
+            .ubuntu_maverick,
+            .ubuntu_natty,
+            .ubuntu_oneiric,
+            .ubuntu_precise,
+            .ubuntu_quantal,
+            .ubuntu_raring,
+            .ubuntu_saucy,
+            .ubuntu_trusty,
+            .ubuntu_utopic,
+            .ubuntu_vivid,
+            .ubuntu_wily,
+            .ubuntu_xenial,
+            .ubuntu_yakkety,
+            .ubuntu_zesty,
+            .ubuntu_artful,
+            .ubuntu_bionic,
+            .ubuntu_cosmic,
+            .ubuntu_disco,
+            .ubuntu_eoan,
+            .ubuntu_focal,
+            .ubuntu_groovy,
+            .ubuntu_hirsute,
+            .ubuntu_impish,
+            .ubuntu_jammy,
+            .ubuntu_kinetic,
+            .ubuntu_lunar,
+            => true,
+
+            else => false,
+        };
+    }
+    pub fn isAlpine(self: Tag) bool {
+        return self == .alpine;
+    }
+    pub fn isGentoo(self: Tag) bool {
+        return self == .gentoo;
+    }
+};
+
+fn scanForOsRelease(buf: []const u8) ?Tag {
+    var it = mem.splitScalar(u8, buf, '\n');
+    while (it.next()) |line| {
+        if (mem.startsWith(u8, line, "ID=")) {
+            const rest = line["ID=".len..];
+            if (mem.eql(u8, rest, "alpine")) return .alpine;
+            if (mem.eql(u8, rest, "fedora")) return .fedora;
+            if (mem.eql(u8, rest, "gentoo")) return .gentoo;
+            if (mem.eql(u8, rest, "arch")) return .arch;
+            if (mem.eql(u8, rest, "sles")) return .open_suse;
+            if (mem.eql(u8, rest, "opensuse")) return .open_suse;
+            if (mem.eql(u8, rest, "exherbo")) return .exherbo;
+        }
+    }
+    return null;
+}
+
+fn detectOsRelease(fs: Filesystem) ?Tag {
+    var buf: [MAX_BYTES]u8 = undefined;
+    const data = fs.readFile("/etc/os-release", &buf) orelse fs.readFile("/usr/lib/os-release", &buf) orelse return null;
+    return scanForOsRelease(data);
+}
+
+fn scanForLSBRelease(buf: []const u8) ?Tag {
+    var it = mem.splitScalar(u8, buf, '\n');
+    while (it.next()) |line| {
+        if (mem.startsWith(u8, line, "DISTRIB_CODENAME=")) {
+            const rest = line["DISTRIB_CODENAME=".len..];
+            if (mem.eql(u8, rest, "hardy")) return .ubuntu_hardy;
+            if (mem.eql(u8, rest, "intrepid")) return .ubuntu_intrepid;
+            if (mem.eql(u8, rest, "jaunty")) return .ubuntu_jaunty;
+            if (mem.eql(u8, rest, "karmic")) return .ubuntu_karmic;
+            if (mem.eql(u8, rest, "lucid")) return .ubuntu_lucid;
+            if (mem.eql(u8, rest, "maverick")) return .ubuntu_maverick;
+            if (mem.eql(u8, rest, "natty")) return .ubuntu_natty;
+            if (mem.eql(u8, rest, "oneiric")) return .ubuntu_oneiric;
+            if (mem.eql(u8, rest, "precise")) return .ubuntu_precise;
+            if (mem.eql(u8, rest, "quantal")) return .ubuntu_quantal;
+            if (mem.eql(u8, rest, "raring")) return .ubuntu_raring;
+            if (mem.eql(u8, rest, "saucy")) return .ubuntu_saucy;
+            if (mem.eql(u8, rest, "trusty")) return .ubuntu_trusty;
+            if (mem.eql(u8, rest, "utopic")) return .ubuntu_utopic;
+            if (mem.eql(u8, rest, "vivid")) return .ubuntu_vivid;
+            if (mem.eql(u8, rest, "wily")) return .ubuntu_wily;
+            if (mem.eql(u8, rest, "xenial")) return .ubuntu_xenial;
+            if (mem.eql(u8, rest, "yakkety")) return .ubuntu_yakkety;
+            if (mem.eql(u8, rest, "zesty")) return .ubuntu_zesty;
+            if (mem.eql(u8, rest, "artful")) return .ubuntu_artful;
+            if (mem.eql(u8, rest, "bionic")) return .ubuntu_bionic;
+            if (mem.eql(u8, rest, "cosmic")) return .ubuntu_cosmic;
+            if (mem.eql(u8, rest, "disco")) return .ubuntu_disco;
+            if (mem.eql(u8, rest, "eoan")) return .ubuntu_eoan;
+            if (mem.eql(u8, rest, "focal")) return .ubuntu_focal;
+            if (mem.eql(u8, rest, "groovy")) return .ubuntu_groovy;
+            if (mem.eql(u8, rest, "hirsute")) return .ubuntu_hirsute;
+            if (mem.eql(u8, rest, "impish")) return .ubuntu_impish;
+            if (mem.eql(u8, rest, "jammy")) return .ubuntu_jammy;
+            if (mem.eql(u8, rest, "kinetic")) return .ubuntu_kinetic;
+            if (mem.eql(u8, rest, "lunar")) return .ubuntu_lunar;
+        }
+    }
+    return null;
+}
+
+fn detectLSBRelease(fs: Filesystem) ?Tag {
+    var buf: [MAX_BYTES]u8 = undefined;
+    const data = fs.readFile("/etc/lsb-release", &buf) orelse return null;
+
+    return scanForLSBRelease(data);
+}
+
+fn scanForRedHat(buf: []const u8) Tag {
+    if (mem.startsWith(u8, buf, "Fedora release")) return .fedora;
+    if (mem.startsWith(u8, buf, "Red Hat Enterprise Linux") or mem.startsWith(u8, buf, "CentOS") or mem.startsWith(u8, buf, "Scientific Linux")) {
+        if (mem.indexOfPos(u8, buf, 0, "release 7") != null) return .rhel7;
+        if (mem.indexOfPos(u8, buf, 0, "release 6") != null) return .rhel6;
+        if (mem.indexOfPos(u8, buf, 0, "release 5") != null) return .rhel5;
+    }
+
+    return .unknown;
+}
+
+fn detectRedhat(fs: Filesystem) ?Tag {
+    var buf: [MAX_BYTES]u8 = undefined;
+    const data = fs.readFile("/etc/redhat-release", &buf) orelse return null;
+    return scanForRedHat(data);
+}
+
+fn scanForDebian(buf: []const u8) Tag {
+    var it = mem.splitScalar(u8, buf, '.');
+    if (std.fmt.parseInt(u8, it.next().?, 10)) |major| {
+        return switch (major) {
+            5 => .debian_lenny,
+            6 => .debian_squeeze,
+            7 => .debian_wheezy,
+            8 => .debian_jessie,
+            9 => .debian_stretch,
+            10 => .debian_buster,
+            11 => .debian_bullseye,
+            12 => .debian_bookworm,
+            13 => .debian_trixie,
+            else => .unknown,
+        };
+    } else |_| {}
+
+    it = mem.splitScalar(u8, buf, '\n');
+    const name = it.next().?;
+    if (mem.eql(u8, name, "squeeze/sid")) return .debian_squeeze;
+    if (mem.eql(u8, name, "wheezy/sid")) return .debian_wheezy;
+    if (mem.eql(u8, name, "jessie/sid")) return .debian_jessie;
+    if (mem.eql(u8, name, "stretch/sid")) return .debian_stretch;
+    if (mem.eql(u8, name, "buster/sid")) return .debian_buster;
+    if (mem.eql(u8, name, "bullseye/sid")) return .debian_bullseye;
+    if (mem.eql(u8, name, "bookworm/sid")) return .debian_bookworm;
+
+    return .unknown;
+}
+
+fn detectDebian(fs: Filesystem) ?Tag {
+    var buf: [MAX_BYTES]u8 = undefined;
+    const data = fs.readFile("/etc/debian_version", &buf) orelse return null;
+    return scanForDebian(data);
+}
+
+pub fn detect(target: std.Target, fs: Filesystem) Tag {
+    if (target.os.tag != .linux) return .unknown;
+
+    if (detectOsRelease(fs)) |tag| return tag;
+    if (detectLSBRelease(fs)) |tag| return tag;
+    if (detectRedhat(fs)) |tag| return tag;
+    if (detectDebian(fs)) |tag| return tag;
+
+    if (fs.exists("/etc/gentoo-release")) return .gentoo;
+
+    return .unknown;
+}
+
+test scanForDebian {
+    try std.testing.expectEqual(Tag.debian_squeeze, scanForDebian("squeeze/sid"));
+    try std.testing.expectEqual(Tag.debian_bullseye, scanForDebian("11.1.2"));
+    try std.testing.expectEqual(Tag.unknown, scanForDebian("None"));
+    try std.testing.expectEqual(Tag.unknown, scanForDebian(""));
+}
+
+test scanForRedHat {
+    try std.testing.expectEqual(Tag.fedora, scanForRedHat("Fedora release 7"));
+    try std.testing.expectEqual(Tag.rhel7, scanForRedHat("Red Hat Enterprise Linux release 7"));
+    try std.testing.expectEqual(Tag.rhel5, scanForRedHat("CentOS release 5"));
+    try std.testing.expectEqual(Tag.unknown, scanForRedHat("CentOS release 4"));
+    try std.testing.expectEqual(Tag.unknown, scanForRedHat(""));
+}
+
+test scanForLSBRelease {
+    const text =
+        \\DISTRIB_ID=Ubuntu
+        \\DISTRIB_RELEASE=20.04
+        \\DISTRIB_CODENAME=focal
+        \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
+        \\
+    ;
+    try std.testing.expectEqual(Tag.ubuntu_focal, scanForLSBRelease(text).?);
+}
+
+test scanForOsRelease {
+    const text =
+        \\NAME="Alpine Linux"
+        \\ID=alpine
+        \\VERSION_ID=3.18.2
+        \\PRETTY_NAME="Alpine Linux v3.18"
+        \\HOME_URL="https://alpinelinux.org/"
+        \\BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
+        \\
+    ;
+    try std.testing.expectEqual(Tag.alpine, scanForOsRelease(text).?);
+}
deps/aro/Driver/Filesystem.zig
@@ -0,0 +1,242 @@
+const std = @import("std");
+const mem = std.mem;
+const builtin = @import("builtin");
+const system_defaults = @import("system_defaults");
+const is_windows = builtin.os.tag == .windows;
+
+fn readFileFake(entries: []const Filesystem.Entry, path: []const u8, buf: []u8) ?[]const u8 {
+    @setCold(true);
+    for (entries) |entry| {
+        if (mem.eql(u8, entry.path, path)) {
+            const len = @min(entry.contents.len, buf.len);
+            @memcpy(buf[0..len], entry.contents[0..len]);
+            return buf[0..len];
+        }
+    }
+    return null;
+}
+
+fn findProgramByNameFake(entries: []const Filesystem.Entry, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
+    @setCold(true);
+    if (mem.indexOfScalar(u8, name, '/') != null) {
+        @memcpy(buf[0..name.len], name);
+        return buf[0..name.len];
+    }
+    const path_env = path orelse return null;
+    var fib = std.heap.FixedBufferAllocator.init(buf);
+
+    var it = mem.tokenizeScalar(u8, path_env, system_defaults.path_sep);
+    while (it.next()) |path_dir| {
+        defer fib.reset();
+        const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue;
+        if (canExecuteFake(entries, full_path)) return full_path;
+    }
+
+    return null;
+}
+
+fn canExecuteFake(entries: []const Filesystem.Entry, path: []const u8) bool {
+    @setCold(true);
+    for (entries) |entry| {
+        if (mem.eql(u8, entry.path, path)) {
+            return entry.executable;
+        }
+    }
+    return false;
+}
+
+fn existsFake(entries: []const Filesystem.Entry, path: []const u8) bool {
+    @setCold(true);
+    var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+    var fib = std.heap.FixedBufferAllocator.init(&buf);
+    const resolved = std.fs.path.resolvePosix(fib.allocator(), &.{path}) catch return false;
+    for (entries) |entry| {
+        if (mem.eql(u8, entry.path, resolved)) return true;
+    }
+    return false;
+}
+
+fn canExecutePosix(path: []const u8) bool {
+    std.os.access(path, std.os.X_OK) catch return false;
+    // Todo: ensure path is not a directory
+    return true;
+}
+
+/// TODO
+fn canExecuteWindows(path: []const u8) bool {
+    _ = path;
+    return true;
+}
+
+/// TODO
+fn findProgramByNameWindows(allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
+    _ = path;
+    _ = buf;
+    _ = name;
+    _ = allocator;
+    return null;
+}
+
+/// TODO: does WASI need special handling?
+fn findProgramByNamePosix(name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
+    if (mem.indexOfScalar(u8, name, '/') != null) {
+        @memcpy(buf[0..name.len], name);
+        return buf[0..name.len];
+    }
+    const path_env = path orelse return null;
+    var fib = std.heap.FixedBufferAllocator.init(buf);
+
+    var it = mem.tokenizeScalar(u8, path_env, system_defaults.path_sep);
+    while (it.next()) |path_dir| {
+        defer fib.reset();
+        const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue;
+        if (canExecutePosix(full_path)) return full_path;
+    }
+
+    return null;
+}
+
+pub const Filesystem = union(enum) {
+    real: void,
+    fake: []const Entry,
+
+    const Entry = struct {
+        path: []const u8,
+        contents: []const u8 = "",
+        executable: bool = false,
+    };
+
+    const FakeDir = struct {
+        entries: []const Entry,
+        path: []const u8,
+
+        fn iterate(self: FakeDir) FakeDir.Iterator {
+            return .{
+                .entries = self.entries,
+                .base = self.path,
+            };
+        }
+
+        const Iterator = struct {
+            entries: []const Entry,
+            base: []const u8,
+            i: usize = 0,
+
+            const Self = @This();
+
+            fn next(self: *@This()) !?std.fs.IterableDir.Entry {
+                while (self.i < self.entries.len) {
+                    const entry = self.entries[self.i];
+                    self.i += 1;
+                    if (entry.path.len == self.base.len) continue;
+                    if (std.mem.startsWith(u8, entry.path, self.base)) {
+                        const remaining = entry.path[self.base.len + 1 ..];
+                        if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue;
+                        const extension = std.fs.path.extension(remaining);
+                        const kind: std.fs.IterableDir.Entry.Kind = if (extension.len == 0) .directory else .file;
+                        return .{ .name = remaining, .kind = kind };
+                    }
+                }
+                return null;
+            }
+        };
+    };
+
+    const IterableDir = union(enum) {
+        dir: std.fs.IterableDir,
+        fake: FakeDir,
+
+        pub fn iterate(self: IterableDir) Iterator {
+            return switch (self) {
+                .dir => |dir| .{ .iterator = dir.iterate() },
+                .fake => |fake| .{ .fake = fake.iterate() },
+            };
+        }
+
+        pub fn close(self: *IterableDir) void {
+            switch (self.*) {
+                .dir => |*d| d.close(),
+                .fake => {},
+            }
+        }
+    };
+
+    const Iterator = union(enum) {
+        iterator: std.fs.IterableDir.Iterator,
+        fake: FakeDir.Iterator,
+
+        pub fn next(self: *Iterator) std.fs.IterableDir.Iterator.Error!?std.fs.IterableDir.Entry {
+            return switch (self.*) {
+                .iterator => |*it| it.next(),
+                .fake => |*it| it.next(),
+            };
+        }
+    };
+
+    pub fn exists(fs: Filesystem, path: []const u8) bool {
+        switch (fs) {
+            .real => {
+                std.os.access(path, std.os.F_OK) catch return false;
+                return true;
+            },
+            .fake => |paths| return existsFake(paths, path),
+        }
+    }
+
+    pub fn joinedExists(fs: Filesystem, parts: []const []const u8) bool {
+        var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+        var fib = std.heap.FixedBufferAllocator.init(&buf);
+        const joined = std.fs.path.join(fib.allocator(), parts) catch return false;
+        return fs.exists(joined);
+    }
+
+    pub fn canExecute(fs: Filesystem, path: []const u8) bool {
+        return switch (fs) {
+            .real => if (is_windows) canExecuteWindows(path) else canExecutePosix(path),
+            .fake => |entries| canExecuteFake(entries, path),
+        };
+    }
+
+    /// Search for an executable named `name` using platform-specific logic
+    /// If it's found, write the full path to `buf` and return a slice of it
+    /// Otherwise retun null
+    pub fn findProgramByName(fs: Filesystem, allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
+        std.debug.assert(name.len > 0);
+        return switch (fs) {
+            .real => if (is_windows) findProgramByNameWindows(allocator, name, path, buf) else findProgramByNamePosix(name, path, buf),
+            .fake => |entries| findProgramByNameFake(entries, name, path, buf),
+        };
+    }
+
+    /// Read the file at `path` into `buf`.
+    /// Returns null if any errors are encountered
+    /// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned
+    pub fn readFile(fs: Filesystem, path: []const u8, buf: []u8) ?[]const u8 {
+        return switch (fs) {
+            .real => {
+                const file = std.fs.cwd().openFile(path, .{}) catch return null;
+                defer file.close();
+
+                const bytes_read = file.readAll(buf) catch return null;
+                return buf[0..bytes_read];
+            },
+            .fake => |entries| readFileFake(entries, path, buf),
+        };
+    }
+
+    pub fn openIterableDir(fs: Filesystem, dir_name: []const u8) std.fs.Dir.OpenError!IterableDir {
+        return switch (fs) {
+            .real => .{ .dir = try std.fs.cwd().openIterableDir(dir_name, .{ .access_sub_paths = false }) },
+            .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } },
+        };
+    }
+};
+
+test "Fake filesystem" {
+    const fs: Filesystem = .{ .fake = &.{
+        .{ .path = "/usr/bin" },
+    } };
+    try std.testing.expect(fs.exists("/usr/bin"));
+    try std.testing.expect(fs.exists("/usr/bin/foo/.."));
+    try std.testing.expect(!fs.exists("/usr/bin/bar"));
+}
deps/aro/Driver/GCCDetector.zig
@@ -0,0 +1,610 @@
+const std = @import("std");
+const Toolchain = @import("../Toolchain.zig");
+const target_util = @import("../target.zig");
+const system_defaults = @import("system_defaults");
+const util = @import("../util.zig");
+const GCCVersion = @import("GCCVersion.zig");
+const Multilib = @import("Multilib.zig");
+const GCCDetector = @This();
+
+is_valid: bool = false,
+install_path: []const u8 = "",
+parent_lib_path: []const u8 = "",
+version: GCCVersion = .{},
+gcc_triple: []const u8 = "",
+selected: Multilib = .{},
+biarch_sibling: ?Multilib = null,
+
+pub fn deinit(self: *GCCDetector) void {
+    if (!self.is_valid) return;
+}
+
+pub fn appendToolPath(self: *const GCCDetector, tc: *Toolchain) !void {
+    if (!self.is_valid) return;
+    return tc.addPathFromComponents(&.{
+        self.parent_lib_path,
+        "..",
+        self.gcc_triple,
+        "bin",
+    }, .program);
+}
+
+fn addDefaultGCCPrefixes(prefixes: *PathPrefixes, tc: *const Toolchain) !void {
+    const sysroot = tc.getSysroot();
+    const target = tc.getTarget();
+    if (sysroot.len == 0 and target.os.tag == .linux and tc.filesystem.exists("/opt/rh")) {
+        prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-12/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-11/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-10/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-12/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-11/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-10/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-9/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-8/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-7/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-6/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-4/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-3/root/usr");
+        prefixes.appendAssumeCapacity("/opt/rh/devtoolset-2/root/usr");
+    }
+    if (sysroot.len == 0) {
+        prefixes.appendAssumeCapacity("/usr");
+    } else {
+        var usr_path = try tc.arena.alloc(u8, 4 + sysroot.len);
+        @memcpy(usr_path[0..4], "/usr");
+        @memcpy(usr_path[4..], sysroot);
+        prefixes.appendAssumeCapacity(usr_path);
+    }
+}
+
+const PathPrefixes = std.BoundedArray([]const u8, 16);
+
+fn collectLibDirsAndTriples(
+    tc: *Toolchain,
+    lib_dirs: *PathPrefixes,
+    triple_aliases: *PathPrefixes,
+    biarch_libdirs: *PathPrefixes,
+    biarch_triple_aliases: *PathPrefixes,
+) !void {
+    const AArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const AArch64Triples: [4][]const u8 = .{ "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux" };
+    const AArch64beLibDirs: [1][]const u8 = .{"/lib"};
+    const AArch64beTriples: [2][]const u8 = .{ "aarch64_be-none-linux-gnu", "aarch64_be-linux-gnu" };
+
+    const ARMLibDirs: [1][]const u8 = .{"/lib"};
+    const ARMTriples: [1][]const u8 = .{"arm-linux-gnueabi"};
+    const ARMHFTriples: [4][]const u8 = .{ "arm-linux-gnueabihf", "armv7hl-redhat-linux-gnueabi", "armv6hl-suse-linux-gnueabi", "armv7hl-suse-linux-gnueabi" };
+
+    const ARMebLibDirs: [1][]const u8 = .{"/lib"};
+    const ARMebTriples: [1][]const u8 = .{"armeb-linux-gnueabi"};
+    const ARMebHFTriples: [2][]const u8 = .{ "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi" };
+
+    const AVRLibDirs: [1][]const u8 = .{"/lib"};
+    const AVRTriples: [1][]const u8 = .{"avr"};
+
+    const CSKYLibDirs: [1][]const u8 = .{"/lib"};
+    const CSKYTriples: [3][]const u8 = .{ "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2" };
+
+    const X86_64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const X86_64Triples: [11][]const u8 = .{
+        "x86_64-linux-gnu",       "x86_64-unknown-linux-gnu",
+        "x86_64-pc-linux-gnu",    "x86_64-redhat-linux6E",
+        "x86_64-redhat-linux",    "x86_64-suse-linux",
+        "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
+        "x86_64-slackware-linux", "x86_64-unknown-linux",
+        "x86_64-amazon-linux",
+    };
+    const X32Triples: [2][]const u8 = .{ "x86_64-linux-gnux32", "x86_64-pc-linux-gnux32" };
+    const X32LibDirs: [2][]const u8 = .{ "/libx32", "/lib" };
+    const X86LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+    const X86Triples: [9][]const u8 = .{
+        "i586-linux-gnu",      "i686-linux-gnu",        "i686-pc-linux-gnu",
+        "i386-redhat-linux6E", "i686-redhat-linux",     "i386-redhat-linux",
+        "i586-suse-linux",     "i686-montavista-linux", "i686-gnu",
+    };
+
+    const LoongArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const LoongArch64Triples: [2][]const u8 = .{ "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu" };
+
+    const M68kLibDirs: [1][]const u8 = .{"/lib"};
+    const M68kTriples: [3][]const u8 = .{ "m68k-linux-gnu", "m68k-unknown-linux-gnu", "m68k-suse-linux" };
+
+    const MIPSLibDirs: [2][]const u8 = .{ "/libo32", "/lib" };
+    const MIPSTriples: [5][]const u8 = .{
+        "mips-linux-gnu",        "mips-mti-linux",
+        "mips-mti-linux-gnu",    "mips-img-linux-gnu",
+        "mipsisa32r6-linux-gnu",
+    };
+    const MIPSELLibDirs: [2][]const u8 = .{ "/libo32", "/lib" };
+    const MIPSELTriples: [3][]const u8 = .{ "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu" };
+
+    const MIPS64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const MIPS64Triples: [6][]const u8 = .{
+        "mips64-linux-gnu",      "mips-mti-linux-gnu",
+        "mips-img-linux-gnu",    "mips64-linux-gnuabi64",
+        "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64",
+    };
+    const MIPS64ELLibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const MIPS64ELTriples: [6][]const u8 = .{
+        "mips64el-linux-gnu",      "mips-mti-linux-gnu",
+        "mips-img-linux-gnu",      "mips64el-linux-gnuabi64",
+        "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64",
+    };
+
+    const MIPSN32LibDirs: [1][]const u8 = .{"/lib32"};
+    const MIPSN32Triples: [2][]const u8 = .{ "mips64-linux-gnuabin32", "mipsisa64r6-linux-gnuabin32" };
+    const MIPSN32ELLibDirs: [1][]const u8 = .{"/lib32"};
+    const MIPSN32ELTriples: [2][]const u8 = .{ "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32" };
+
+    const MSP430LibDirs: [1][]const u8 = .{"/lib"};
+    const MSP430Triples: [1][]const u8 = .{"msp430-elf"};
+
+    const PPCLibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+    const PPCTriples: [5][]const u8 = .{
+        "powerpc-linux-gnu",    "powerpc-unknown-linux-gnu",   "powerpc-linux-gnuspe",
+        // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a
+        // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux".
+        "powerpc64-suse-linux", "powerpc-montavista-linuxspe",
+    };
+    const PPCLELibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+    const PPCLETriples: [3][]const u8 = .{ "powerpcle-linux-gnu", "powerpcle-unknown-linux-gnu", "powerpcle-linux-musl" };
+
+    const PPC64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const PPC64Triples: [4][]const u8 = .{
+        "powerpc64-linux-gnu",  "powerpc64-unknown-linux-gnu",
+        "powerpc64-suse-linux", "ppc64-redhat-linux",
+    };
+    const PPC64LELibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const PPC64LETriples: [5][]const u8 = .{
+        "powerpc64le-linux-gnu",      "powerpc64le-unknown-linux-gnu",
+        "powerpc64le-none-linux-gnu", "powerpc64le-suse-linux",
+        "ppc64le-redhat-linux",
+    };
+
+    const RISCV32LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+    const RISCV32Triples: [3][]const u8 = .{ "riscv32-unknown-linux-gnu", "riscv32-linux-gnu", "riscv32-unknown-elf" };
+    const RISCV64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const RISCV64Triples: [3][]const u8 = .{
+        "riscv64-unknown-linux-gnu",
+        "riscv64-linux-gnu",
+        "riscv64-unknown-elf",
+    };
+
+    const SPARCv8LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
+    const SPARCv8Triples: [2][]const u8 = .{ "sparc-linux-gnu", "sparcv8-linux-gnu" };
+    const SPARCv9LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const SPARCv9Triples: [2][]const u8 = .{ "sparc64-linux-gnu", "sparcv9-linux-gnu" };
+
+    const SystemZLibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
+    const SystemZTriples: [5][]const u8 = .{
+        "s390x-linux-gnu",  "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
+        "s390x-suse-linux", "s390x-redhat-linux",
+    };
+    const target = tc.getTarget();
+    if (target.os.tag == .solaris) {
+        // TODO
+        return;
+    }
+    if (target.isAndroid()) {
+        const AArch64AndroidTriples: [1][]const u8 = .{"aarch64-linux-android"};
+        const ARMAndroidTriples: [1][]const u8 = .{"arm-linux-androideabi"};
+        const MIPSELAndroidTriples: [1][]const u8 = .{"mipsel-linux-android"};
+        const MIPS64ELAndroidTriples: [1][]const u8 = .{"mips64el-linux-android"};
+        const X86AndroidTriples: [1][]const u8 = .{"i686-linux-android"};
+        const X86_64AndroidTriples: [1][]const u8 = .{"x86_64-linux-android"};
+
+        switch (target.cpu.arch) {
+            .aarch64 => {
+                lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs);
+                triple_aliases.appendSliceAssumeCapacity(&AArch64AndroidTriples);
+            },
+            .arm,
+            .thumb,
+            => {
+                lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs);
+                triple_aliases.appendSliceAssumeCapacity(&ARMAndroidTriples);
+            },
+            .mipsel => {
+                lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
+                triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples);
+                biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
+                biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples);
+            },
+            .mips64el => {
+                lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
+                triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples);
+                biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
+                biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples);
+            },
+            .x86_64 => {
+                lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+                triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples);
+                biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs);
+                biarch_triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples);
+            },
+            .x86 => {
+                lib_dirs.appendSliceAssumeCapacity(&X86LibDirs);
+                triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples);
+                biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+                biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples);
+            },
+            else => {},
+        }
+        return;
+    }
+    switch (target.cpu.arch) {
+        .aarch64 => {
+            lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&AArch64Triples);
+            biarch_libdirs.appendSliceAssumeCapacity(&AArch64LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64Triples);
+        },
+        .aarch64_be => {
+            lib_dirs.appendSliceAssumeCapacity(&AArch64beLibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&AArch64beLibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples);
+        },
+        .arm, .thumb => {
+            lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs);
+            if (target.abi == .gnueabihf) {
+                triple_aliases.appendSliceAssumeCapacity(&ARMHFTriples);
+            } else {
+                triple_aliases.appendSliceAssumeCapacity(&ARMTriples);
+            }
+        },
+        .armeb, .thumbeb => {
+            lib_dirs.appendSliceAssumeCapacity(&ARMebLibDirs);
+            if (target.abi == .gnueabihf) {
+                triple_aliases.appendSliceAssumeCapacity(&ARMebHFTriples);
+            } else {
+                triple_aliases.appendSliceAssumeCapacity(&ARMebTriples);
+            }
+        },
+        .avr => {
+            lib_dirs.appendSliceAssumeCapacity(&AVRLibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&AVRTriples);
+        },
+        .csky => {
+            lib_dirs.appendSliceAssumeCapacity(&CSKYLibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&CSKYTriples);
+        },
+        .x86_64 => {
+            if (target.abi == .gnux32 or target.abi == .muslx32) {
+                lib_dirs.appendSliceAssumeCapacity(&X32LibDirs);
+                triple_aliases.appendSliceAssumeCapacity(&X32Triples);
+                biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+                biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
+            } else {
+                lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+                triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
+                biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs);
+                biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples);
+            }
+            biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&X86Triples);
+        },
+        .x86 => {
+            lib_dirs.appendSliceAssumeCapacity(&X86LibDirs);
+            // MCU toolchain is 32 bit only and its triple alias is TargetTriple
+            // itself, which will be appended below.
+            if (target.os.tag != .elfiamcu) {
+                triple_aliases.appendSliceAssumeCapacity(&X86Triples);
+                biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
+                biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
+                biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs);
+                biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples);
+            }
+        },
+        .loongarch64 => {
+            lib_dirs.appendSliceAssumeCapacity(&LoongArch64LibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&LoongArch64Triples);
+        },
+        .m68k => {
+            lib_dirs.appendSliceAssumeCapacity(&M68kLibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&M68kTriples);
+        },
+        .mips => {
+            lib_dirs.appendSliceAssumeCapacity(&MIPSLibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&MIPS64LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples);
+            biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples);
+        },
+        .mipsel => {
+            lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples);
+            triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples);
+        },
+        .mips64 => {
+            lib_dirs.appendSliceAssumeCapacity(&MIPS64LibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples);
+            biarch_libdirs.appendSliceAssumeCapacity(&MIPSLibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples);
+        },
+        .mips64el => {
+            lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
+        },
+        .msp430 => {
+            lib_dirs.appendSliceAssumeCapacity(&MSP430LibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&MSP430Triples);
+        },
+        .powerpc => {
+            lib_dirs.appendSliceAssumeCapacity(&PPCLibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&PPCTriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&PPC64LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64Triples);
+        },
+        .powerpcle => {
+            lib_dirs.appendSliceAssumeCapacity(&PPCLELibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&PPCLETriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&PPC64LELibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples);
+        },
+        .powerpc64 => {
+            lib_dirs.appendSliceAssumeCapacity(&PPC64LibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&PPC64Triples);
+            biarch_libdirs.appendSliceAssumeCapacity(&PPCLibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&PPCTriples);
+        },
+        .powerpc64le => {
+            lib_dirs.appendSliceAssumeCapacity(&PPC64LELibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples);
+            biarch_libdirs.appendSliceAssumeCapacity(&PPCLELibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&PPCLETriples);
+        },
+        .riscv32 => {
+            lib_dirs.appendSliceAssumeCapacity(&RISCV32LibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples);
+            biarch_libdirs.appendSliceAssumeCapacity(&RISCV64LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples);
+        },
+        .riscv64 => {
+            lib_dirs.appendSliceAssumeCapacity(&RISCV64LibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples);
+            biarch_libdirs.appendSliceAssumeCapacity(&RISCV32LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples);
+        },
+        .sparc, .sparcel => {
+            lib_dirs.appendSliceAssumeCapacity(&SPARCv8LibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples);
+            biarch_libdirs.appendSliceAssumeCapacity(&SPARCv9LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples);
+        },
+        .sparc64 => {
+            lib_dirs.appendSliceAssumeCapacity(&SPARCv9LibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples);
+            biarch_libdirs.appendSliceAssumeCapacity(&SPARCv8LibDirs);
+            biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples);
+        },
+        .s390x => {
+            lib_dirs.appendSliceAssumeCapacity(&SystemZLibDirs);
+            triple_aliases.appendSliceAssumeCapacity(&SystemZTriples);
+        },
+        else => {},
+    }
+}
+
+pub fn discover(self: *GCCDetector, tc: *Toolchain) !void {
+    var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+    var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+
+    const target = tc.getTarget();
+    const biarch_variant_target = if (target.ptrBitWidth() == 32) target_util.get64BitArchVariant(target) else target_util.get32BitArchVariant(target);
+
+    var candidate_lib_dirs: PathPrefixes = .{};
+    var candidate_biarch_lib_dirs: PathPrefixes = .{};
+    var candidate_triple_aliases: PathPrefixes = .{};
+    var candidate_biarch_triple_aliases: PathPrefixes = .{};
+    try collectLibDirsAndTriples(tc, &candidate_lib_dirs, &candidate_biarch_lib_dirs, &candidate_triple_aliases, &candidate_biarch_triple_aliases);
+
+    var target_buf: [64]u8 = undefined;
+    const triple_str = target_util.toLLVMTriple(target, &target_buf);
+    candidate_triple_aliases.appendAssumeCapacity(triple_str);
+
+    // Also include the multiarch variant if it's different.
+    var biarch_buf: [64]u8 = undefined;
+    if (biarch_variant_target) |biarch_target| {
+        const biarch_triple_str = target_util.toLLVMTriple(biarch_target, &biarch_buf);
+        if (!std.mem.eql(u8, biarch_triple_str, triple_str)) {
+            candidate_triple_aliases.appendAssumeCapacity(biarch_triple_str);
+        }
+    }
+
+    var prefixes: PathPrefixes = .{};
+    const gcc_toolchain_dir = gccToolchainDir(tc);
+    if (gcc_toolchain_dir.len != 0) {
+        const adjusted = if (gcc_toolchain_dir[gcc_toolchain_dir.len - 1] == '/')
+            gcc_toolchain_dir[0 .. gcc_toolchain_dir.len - 1]
+        else
+            gcc_toolchain_dir;
+        prefixes.appendAssumeCapacity(adjusted);
+    } else {
+        const sysroot = tc.getSysroot();
+        if (sysroot.len > 0) {
+            prefixes.appendAssumeCapacity(sysroot);
+            try addDefaultGCCPrefixes(&prefixes, tc);
+        }
+
+        if (sysroot.len == 0) {
+            try addDefaultGCCPrefixes(&prefixes, tc);
+        }
+        // TODO: Special-case handling for Gentoo
+    }
+
+    const v0 = GCCVersion.parse("0.0.0");
+    for (prefixes.constSlice()) |prefix| {
+        if (!tc.filesystem.exists(prefix)) continue;
+
+        for (candidate_lib_dirs.constSlice()) |suffix| {
+            defer fib.reset();
+            const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue;
+            if (!tc.filesystem.exists(lib_dir)) continue;
+
+            const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" });
+            const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" });
+
+            try self.scanLibDirForGCCTriple(tc, target, lib_dir, triple_str, false, gcc_dir_exists, gcc_cross_dir_exists);
+            for (candidate_triple_aliases.constSlice()) |candidate| {
+                try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, false, gcc_dir_exists, gcc_cross_dir_exists);
+            }
+        }
+        for (candidate_biarch_lib_dirs.constSlice()) |suffix| {
+            const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue;
+            if (!tc.filesystem.exists(lib_dir)) continue;
+
+            const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" });
+            const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" });
+            for (candidate_biarch_triple_aliases.constSlice()) |candidate| {
+                try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, true, gcc_dir_exists, gcc_cross_dir_exists);
+            }
+        }
+        if (self.version.order(v0) == .gt) break;
+    }
+}
+
+fn findBiarchMultilibs(tc: *const Toolchain, result: *Multilib.Detected, target: std.Target, path: [2][]const u8, needs_biarch_suffix: bool) !bool {
+    const suff64 = if (target.os.tag == .solaris) switch (target.cpu.arch) {
+        .x86, .x86_64 => "/amd64",
+        .sparc => "/sparcv9",
+        else => "/64",
+    } else "/64";
+
+    const alt_64 = Multilib.init(suff64, suff64, &.{ "-m32", "+m64", "-mx32" });
+    const alt_32 = Multilib.init("/32", "/32", &.{ "+m32", "-m64", "-mx32" });
+    const alt_x32 = Multilib.init("/x32", "/x32", &.{ "-m32", "-m64", "+mx32" });
+
+    const multilib_filter = Multilib.Filter{
+        .base = path,
+        .file = if (target.os.tag == .elfiamcu) "libgcc.a" else "crtbegin.o",
+    };
+
+    const Want = enum {
+        want32,
+        want64,
+        wantx32,
+    };
+    const is_x32 = target.abi == .gnux32 or target.abi == .muslx32;
+    const target_ptr_width = target.ptrBitWidth();
+    const want: Want = if (target_ptr_width == 32 and multilib_filter.exists(alt_32, tc.filesystem))
+        .want64
+    else if (target_ptr_width == 64 and is_x32 and multilib_filter.exists(alt_x32, tc.filesystem))
+        .want64
+    else if (target_ptr_width == 64 and !is_x32 and multilib_filter.exists(alt_64, tc.filesystem))
+        .want32
+    else if (target_ptr_width == 32)
+        if (needs_biarch_suffix) .want64 else .want32
+    else if (is_x32)
+        if (needs_biarch_suffix) .want64 else .wantx32
+    else if (needs_biarch_suffix) .want32 else .want64;
+
+    const default = switch (want) {
+        .want32 => Multilib.init("", "", &.{ "+m32", "-m64", "-mx32" }),
+        .want64 => Multilib.init("", "", &.{ "-m32", "+m64", "-mx32" }),
+        .wantx32 => Multilib.init("", "", &.{ "-m32", "-m64", "+mx32" }),
+    };
+    result.multilibs.appendSliceAssumeCapacity(&.{
+        default,
+        alt_64,
+        alt_32,
+        alt_x32,
+    });
+    result.filter(multilib_filter, tc.filesystem);
+    var flags: Multilib.Flags = .{};
+    flags.appendAssumeCapacity(if (target_ptr_width == 64 and !is_x32) "+m64" else "-m64");
+    flags.appendAssumeCapacity(if (target_ptr_width == 32) "+m32" else "-m32");
+    flags.appendAssumeCapacity(if (target_ptr_width == 64 and is_x32) "+mx32" else "-mx32");
+
+    return result.select(flags);
+}
+
+fn scanGCCForMultilibs(self: *GCCDetector, tc: *const Toolchain, target: std.Target, path: [2][]const u8, needs_biarch_suffix: bool) !bool {
+    var detected: Multilib.Detected = .{};
+    if (target.cpu.arch == .csky) {
+        // TODO
+    } else if (target.cpu.arch.isMIPS()) {
+        // TODO
+    } else if (target.cpu.arch.isRISCV()) {
+        // TODO
+    } else if (target.cpu.arch == .msp430) {
+        // TODO
+    } else if (target.cpu.arch == .avr) {
+        // No multilibs
+    } else if (!try findBiarchMultilibs(tc, &detected, target, path, needs_biarch_suffix)) {
+        return false;
+    }
+    self.selected = detected.selected;
+    self.biarch_sibling = detected.biarch_sibling;
+    return true;
+}
+
+fn scanLibDirForGCCTriple(
+    self: *GCCDetector,
+    tc: *const Toolchain,
+    target: std.Target,
+    lib_dir: []const u8,
+    candidate_triple: []const u8,
+    needs_biarch_suffix: bool,
+    gcc_dir_exists: bool,
+    gcc_cross_dir_exists: bool,
+) !void {
+    var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+    var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+    for (0..2) |i| {
+        if (i == 0 and !gcc_dir_exists) continue;
+        if (i == 1 and !gcc_cross_dir_exists) continue;
+        defer fib.reset();
+
+        const base: []const u8 = if (i == 0) "gcc" else "gcc-cross";
+        var lib_suffix_buf: [64]u8 = undefined;
+        var suffix_buf_fib = std.heap.FixedBufferAllocator.init(&lib_suffix_buf);
+        const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue;
+
+        const dir_name = std.fs.path.join(fib.allocator(), &.{ lib_dir, lib_suffix }) catch continue;
+        var parent_dir = tc.filesystem.openIterableDir(dir_name) catch continue;
+        defer parent_dir.close();
+
+        var it = parent_dir.iterate();
+        while (it.next() catch continue) |entry| {
+            if (entry.kind != .directory) continue;
+
+            const version_text = entry.name;
+            const candidate_version = GCCVersion.parse(version_text);
+            if (candidate_version.major != -1) {
+                // TODO: cache path so we're not repeatedly scanning
+            }
+            if (candidate_version.isLessThan(4, 1, 1, "")) continue;
+            switch (candidate_version.order(self.version)) {
+                .lt, .eq => continue,
+                .gt => {},
+            }
+
+            if (!try self.scanGCCForMultilibs(tc, target, .{ dir_name, version_text }, needs_biarch_suffix)) continue;
+
+            self.version = candidate_version;
+            self.gcc_triple = try tc.arena.dupe(u8, candidate_triple);
+            self.install_path = try std.fs.path.join(tc.arena, &.{ lib_dir, lib_suffix, version_text });
+            self.parent_lib_path = try std.fs.path.join(tc.arena, &.{ self.install_path, "..", "..", ".." });
+            self.is_valid = true;
+        }
+    }
+}
+
+fn gccToolchainDir(tc: *const Toolchain) []const u8 {
+    const sysroot = tc.getSysroot();
+    if (sysroot.len != 0) return "";
+    return system_defaults.gcc_install_prefix;
+}
deps/aro/Driver/GCCVersion.zig
@@ -0,0 +1,122 @@
+const std = @import("std");
+const mem = std.mem;
+const Order = std.math.Order;
+
+const GCCVersion = @This();
+
+/// Raw version number text
+raw: []const u8 = "",
+
+/// -1 indicates not present
+major: i32 = -1,
+/// -1 indicates not present
+minor: i32 = -1,
+/// -1 indicates not present
+patch: i32 = -1,
+
+/// Text of parsed major version number
+major_str: []const u8 = "",
+/// Text of parsed major + minor version number
+minor_str: []const u8 = "",
+
+/// Patch number suffix
+suffix: []const u8 = "",
+
+/// This orders versions according to the preferred usage order, not a notion of release-time ordering
+/// Higher version numbers are preferred, but nonexistent minor/patch/suffix is preferred to one that does exist
+/// e.g. `4.1` is preferred over `4.0` but `4` is preferred over both `4.0` and `4.1`
+pub fn isLessThan(self: GCCVersion, rhs_major: i32, rhs_minor: i32, rhs_patch: i32, rhs_suffix: []const u8) bool {
+    if (self.major != rhs_major) {
+        return self.major < rhs_major;
+    }
+    if (self.minor != rhs_minor) {
+        if (rhs_minor == -1) return true;
+        if (self.minor == -1) return false;
+        return self.minor < rhs_minor;
+    }
+    if (self.patch != rhs_patch) {
+        if (rhs_patch == -1) return true;
+        if (self.patch == -1) return false;
+        return self.patch < rhs_patch;
+    }
+    if (!mem.eql(u8, self.suffix, rhs_suffix)) {
+        if (rhs_suffix.len == 0) return true;
+        if (self.suffix.len == 0) return false;
+        return switch (std.mem.order(u8, self.suffix, rhs_suffix)) {
+            .lt => true,
+            .eq => unreachable,
+            .gt => false,
+        };
+    }
+    return false;
+}
+
+/// Strings in the returned GCCVersion struct have the same lifetime as `text`
+pub fn parse(text: []const u8) GCCVersion {
+    const bad = GCCVersion{ .major = -1 };
+    var good = bad;
+
+    var it = mem.splitScalar(u8, text, '.');
+    const first = it.next().?;
+    const second = it.next() orelse "";
+    const rest = it.next() orelse "";
+
+    good.major = std.fmt.parseInt(i32, first, 10) catch return bad;
+    if (good.major < 0) return bad;
+    good.major_str = first;
+
+    if (second.len == 0) return good;
+    var minor_str = second;
+
+    if (rest.len == 0) {
+        const end = mem.indexOfNone(u8, minor_str, "0123456789") orelse minor_str.len;
+        if (end > 0) {
+            good.suffix = minor_str[end..];
+            minor_str = minor_str[0..end];
+        }
+    }
+    good.minor = std.fmt.parseInt(i32, minor_str, 10) catch return bad;
+    if (good.minor < 0) return bad;
+    good.minor_str = minor_str;
+
+    if (rest.len > 0) {
+        const end = mem.indexOfNone(u8, rest, "0123456789") orelse rest.len;
+        if (end > 0) {
+            const patch_num_text = rest[0..end];
+            good.patch = std.fmt.parseInt(i32, patch_num_text, 10) catch return bad;
+            if (good.patch < 0) return bad;
+            good.suffix = rest[end..];
+        }
+    }
+
+    return good;
+}
+
+pub fn order(a: GCCVersion, b: GCCVersion) Order {
+    if (a.isLessThan(b.major, b.minor, b.patch, b.suffix)) return .lt;
+    if (b.isLessThan(a.major, a.minor, a.patch, a.suffix)) return .gt;
+    return .eq;
+}
+
+test parse {
+    const versions = [10]GCCVersion{
+        parse("5"),
+        parse("4"),
+        parse("4.2"),
+        parse("4.0"),
+        parse("4.0-patched"),
+        parse("4.0.2"),
+        parse("4.0.1"),
+        parse("4.0.1-patched"),
+        parse("4.0.0"),
+        parse("4.0.0-patched"),
+    };
+
+    for (versions[0 .. versions.len - 1], versions[1..versions.len]) |first, second| {
+        try std.testing.expectEqual(Order.eq, first.order(first));
+        try std.testing.expectEqual(Order.gt, first.order(second));
+        try std.testing.expectEqual(Order.lt, second.order(first));
+    }
+    const last = versions[versions.len - 1];
+    try std.testing.expectEqual(Order.eq, last.order(last));
+}
deps/aro/Driver/Multilib.zig
@@ -0,0 +1,72 @@
+const std = @import("std");
+const util = @import("../util.zig");
+const Filesystem = @import("Filesystem.zig").Filesystem;
+
+pub const Flags = std.BoundedArray([]const u8, 6);
+
+/// Large enough for GCCDetector for Linux; may need to be increased to support other toolchains.
+const max_multilibs = 4;
+
+const MultilibArray = std.BoundedArray(Multilib, max_multilibs);
+
+pub const Detected = struct {
+    multilibs: MultilibArray = .{},
+    selected: Multilib = .{},
+    biarch_sibling: ?Multilib = null,
+
+    pub fn filter(self: *Detected, multilib_filter: Filter, fs: Filesystem) void {
+        var found_count: usize = 0;
+        for (self.multilibs.constSlice()) |multilib| {
+            if (multilib_filter.exists(multilib, fs)) {
+                self.multilibs.set(found_count, multilib);
+                found_count += 1;
+            }
+        }
+        self.multilibs.resize(found_count) catch unreachable;
+    }
+
+    pub fn select(self: *Detected, flags: Flags) !bool {
+        var filtered: MultilibArray = .{};
+        for (self.multilibs.constSlice()) |multilib| {
+            for (multilib.flags.constSlice()) |multilib_flag| {
+                const matched = for (flags.constSlice()) |arg_flag| {
+                    if (std.mem.eql(u8, arg_flag[1..], multilib_flag[1..])) break arg_flag;
+                } else multilib_flag;
+                if (matched[0] != multilib_flag[0]) break;
+            } else {
+                filtered.appendAssumeCapacity(multilib);
+            }
+        }
+        if (filtered.len == 0) return false;
+        if (filtered.len == 1) {
+            self.selected = filtered.get(0);
+            return true;
+        }
+        return error.TooManyMultilibs;
+    }
+};
+
+pub const Filter = struct {
+    base: [2][]const u8,
+    file: []const u8,
+    pub fn exists(self: Filter, m: Multilib, fs: Filesystem) bool {
+        return fs.joinedExists(&.{ self.base[0], self.base[1], m.gcc_suffix, self.file });
+    }
+};
+
+const Multilib = @This();
+
+gcc_suffix: []const u8 = "",
+os_suffix: []const u8 = "",
+include_suffix: []const u8 = "",
+flags: Flags = .{},
+priority: u32 = 0,
+
+pub fn init(gcc_suffix: []const u8, os_suffix: []const u8, flags: []const []const u8) Multilib {
+    var self: Multilib = .{
+        .gcc_suffix = gcc_suffix,
+        .os_suffix = os_suffix,
+    };
+    self.flags.appendSliceAssumeCapacity(flags);
+    return self;
+}
deps/aro/object/Elf.zig
@@ -0,0 +1,377 @@
+const std = @import("std");
+const Compilation = @import("../Compilation.zig");
+const Object = @import("../Object.zig");
+
+const Elf = @This();
+
+const Section = struct {
+    data: std.ArrayList(u8),
+    relocations: std.ArrayListUnmanaged(Relocation) = .{},
+    flags: u64,
+    type: u32,
+    index: u16 = undefined,
+};
+
+const Symbol = struct {
+    section: ?*Section,
+    size: u64,
+    offset: u64,
+    index: u16 = undefined,
+    info: u8,
+};
+
+const Relocation = packed struct {
+    symbol: *Symbol,
+    addend: i64,
+    offset: u48,
+    type: u8,
+};
+
+const additional_sections = 3; // null section, strtab, symtab
+const strtab_index = 1;
+const symtab_index = 2;
+const strtab_default = "\x00.strtab\x00.symtab\x00";
+const strtab_name = 1;
+const symtab_name = "\x00.strtab\x00".len;
+
+obj: Object,
+/// The keys are owned by the Codegen.tree
+sections: std.StringHashMapUnmanaged(*Section) = .{},
+local_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
+global_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
+unnamed_symbol_mangle: u32 = 0,
+strtab_len: u64 = strtab_default.len,
+arena: std.heap.ArenaAllocator,
+
+pub fn create(comp: *Compilation) !*Object {
+    const elf = try comp.gpa.create(Elf);
+    elf.* = .{
+        .obj = .{ .format = .elf, .comp = comp },
+        .arena = std.heap.ArenaAllocator.init(comp.gpa),
+    };
+    return &elf.obj;
+}
+
+pub fn deinit(elf: *Elf) void {
+    const gpa = elf.arena.child_allocator;
+    {
+        var it = elf.sections.valueIterator();
+        while (it.next()) |sect| {
+            sect.*.data.deinit();
+            sect.*.relocations.deinit(gpa);
+        }
+    }
+    elf.sections.deinit(gpa);
+    elf.local_symbols.deinit(gpa);
+    elf.global_symbols.deinit(gpa);
+    elf.arena.deinit();
+    gpa.destroy(elf);
+}
+
+fn sectionString(sec: Object.Section) []const u8 {
+    return switch (sec) {
+        .undefined => unreachable,
+        .data => "data",
+        .read_only_data => "rodata",
+        .func => "text",
+        .strings => "rodata.str",
+        .custom => |name| name,
+    };
+}
+
+pub fn getSection(elf: *Elf, section_kind: Object.Section) !*std.ArrayList(u8) {
+    const section_name = sectionString(section_kind);
+    const section = elf.sections.get(section_name) orelse blk: {
+        const section = try elf.arena.allocator().create(Section);
+        section.* = .{
+            .data = std.ArrayList(u8).init(elf.arena.child_allocator),
+            .type = std.elf.SHT_PROGBITS,
+            .flags = switch (section_kind) {
+                .func, .custom => std.elf.SHF_ALLOC + std.elf.SHF_EXECINSTR,
+                .strings => std.elf.SHF_ALLOC + std.elf.SHF_MERGE + std.elf.SHF_STRINGS,
+                .read_only_data => std.elf.SHF_ALLOC,
+                .data => std.elf.SHF_ALLOC + std.elf.SHF_WRITE,
+                .undefined => unreachable,
+            },
+        };
+        try elf.sections.putNoClobber(elf.arena.child_allocator, section_name, section);
+        elf.strtab_len += section_name.len + ".\x00".len;
+        break :blk section;
+    };
+    return &section.data;
+}
+
+pub fn declareSymbol(
+    elf: *Elf,
+    section_kind: Object.Section,
+    maybe_name: ?[]const u8,
+    linkage: std.builtin.GlobalLinkage,
+    @"type": Object.SymbolType,
+    offset: u64,
+    size: u64,
+) ![]const u8 {
+    const section = blk: {
+        if (section_kind == .undefined) break :blk null;
+        const section_name = sectionString(section_kind);
+        break :blk elf.sections.get(section_name);
+    };
+    const binding: u8 = switch (linkage) {
+        .Internal => std.elf.STB_LOCAL,
+        .Strong => std.elf.STB_GLOBAL,
+        .Weak => std.elf.STB_WEAK,
+        .LinkOnce => unreachable,
+    };
+    const sym_type: u8 = switch (@"type") {
+        .func => std.elf.STT_FUNC,
+        .variable => std.elf.STT_OBJECT,
+        .external => std.elf.STT_NOTYPE,
+    };
+    const name = if (maybe_name) |some| some else blk: {
+        defer elf.unnamed_symbol_mangle += 1;
+        break :blk try std.fmt.allocPrint(elf.arena.allocator(), ".L.{d}", .{elf.unnamed_symbol_mangle});
+    };
+
+    const gop = if (linkage == .Internal)
+        try elf.local_symbols.getOrPut(elf.arena.child_allocator, name)
+    else
+        try elf.global_symbols.getOrPut(elf.arena.child_allocator, name);
+
+    if (!gop.found_existing) {
+        gop.value_ptr.* = try elf.arena.allocator().create(Symbol);
+        elf.strtab_len += name.len + 1; // +1 for null byte
+    }
+    gop.value_ptr.*.* = .{
+        .section = section,
+        .size = size,
+        .offset = offset,
+        .info = (binding << 4) + sym_type,
+    };
+    return name;
+}
+
+pub fn addRelocation(elf: *Elf, name: []const u8, section_kind: Object.Section, address: u64, addend: i64) !void {
+    const section_name = sectionString(section_kind);
+    const symbol = elf.local_symbols.get(name) orelse elf.global_symbols.get(name).?; // reference to undeclared symbol
+    const section = elf.sections.get(section_name).?;
+    if (section.relocations.items.len == 0) elf.strtab_len += ".rela".len;
+
+    try section.relocations.append(elf.arena.child_allocator, .{
+        .symbol = symbol,
+        .offset = @intCast(address),
+        .addend = addend,
+        .type = if (symbol.section == null) 4 else 2, // TODO
+    });
+}
+
+/// elf header
+/// sections contents
+/// symbols
+/// relocations
+/// strtab
+/// section headers
+pub fn finish(elf: *Elf, file: std.fs.File) !void {
+    var buf_writer = std.io.bufferedWriter(file.writer());
+    const w = buf_writer.writer();
+
+    var num_sections: std.elf.Elf64_Half = additional_sections;
+    var relocations_len: std.elf.Elf64_Off = 0;
+    var sections_len: std.elf.Elf64_Off = 0;
+    {
+        var it = elf.sections.valueIterator();
+        while (it.next()) |sect| {
+            sections_len += sect.*.data.items.len;
+            relocations_len += sect.*.relocations.items.len * @sizeOf(std.elf.Elf64_Rela);
+            sect.*.index = num_sections;
+            num_sections += 1;
+            num_sections += @intFromBool(sect.*.relocations.items.len != 0);
+        }
+    }
+    const symtab_len = (elf.local_symbols.count() + elf.global_symbols.count() + 1) * @sizeOf(std.elf.Elf64_Sym);
+
+    const symtab_offset = @sizeOf(std.elf.Elf64_Ehdr) + sections_len;
+    const symtab_offset_aligned = std.mem.alignForward(u64, symtab_offset, 8);
+    const rela_offset = symtab_offset_aligned + symtab_len;
+    const strtab_offset = rela_offset + relocations_len;
+    const sh_offset = strtab_offset + elf.strtab_len;
+    const sh_offset_aligned = std.mem.alignForward(u64, sh_offset, 16);
+
+    var elf_header = std.elf.Elf64_Ehdr{
+        .e_ident = .{ 0x7F, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+        .e_type = std.elf.ET.REL, // we only produce relocatables
+        .e_machine = elf.obj.comp.target.cpu.arch.toElfMachine(),
+        .e_version = 1,
+        .e_entry = 0, // linker will handle this
+        .e_phoff = 0, // no program header
+        .e_shoff = sh_offset_aligned, // section headers offset
+        .e_flags = 0, // no flags
+        .e_ehsize = @sizeOf(std.elf.Elf64_Ehdr),
+        .e_phentsize = 0, // no program header
+        .e_phnum = 0, // no program header
+        .e_shentsize = @sizeOf(std.elf.Elf64_Shdr),
+        .e_shnum = num_sections,
+        .e_shstrndx = strtab_index,
+    };
+    try w.writeStruct(elf_header);
+
+    // write contents of sections
+    {
+        var it = elf.sections.valueIterator();
+        while (it.next()) |sect| try w.writeAll(sect.*.data.items);
+    }
+
+    // pad to 8 bytes
+    try w.writeByteNTimes(0, @intCast(symtab_offset_aligned - symtab_offset));
+
+    var name_offset: u32 = strtab_default.len;
+    // write symbols
+    {
+        // first symbol must be null
+        try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Sym));
+
+        var sym_index: u16 = 1;
+        var it = elf.local_symbols.iterator();
+        while (it.next()) |entry| {
+            const sym = entry.value_ptr.*;
+            try w.writeStruct(std.elf.Elf64_Sym{
+                .st_name = name_offset,
+                .st_info = sym.info,
+                .st_other = 0,
+                .st_shndx = if (sym.section) |some| some.index else 0,
+                .st_value = sym.offset,
+                .st_size = sym.size,
+            });
+            sym.index = sym_index;
+            sym_index += 1;
+            name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte
+        }
+        it = elf.global_symbols.iterator();
+        while (it.next()) |entry| {
+            const sym = entry.value_ptr.*;
+            try w.writeStruct(std.elf.Elf64_Sym{
+                .st_name = name_offset,
+                .st_info = sym.info,
+                .st_other = 0,
+                .st_shndx = if (sym.section) |some| some.index else 0,
+                .st_value = sym.offset,
+                .st_size = sym.size,
+            });
+            sym.index = sym_index;
+            sym_index += 1;
+            name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte
+        }
+    }
+
+    // write relocations
+    {
+        var it = elf.sections.valueIterator();
+        while (it.next()) |sect| {
+            for (sect.*.relocations.items) |rela| {
+                try w.writeStruct(std.elf.Elf64_Rela{
+                    .r_offset = rela.offset,
+                    .r_addend = rela.addend,
+                    .r_info = (@as(u64, rela.symbol.index) << 32) | rela.type,
+                });
+            }
+        }
+    }
+
+    // write strtab
+    try w.writeAll(strtab_default);
+    {
+        var it = elf.local_symbols.keyIterator();
+        while (it.next()) |key| try w.print("{s}\x00", .{key.*});
+        it = elf.global_symbols.keyIterator();
+        while (it.next()) |key| try w.print("{s}\x00", .{key.*});
+    }
+    {
+        var it = elf.sections.iterator();
+        while (it.next()) |entry| {
+            if (entry.value_ptr.*.relocations.items.len != 0) try w.writeAll(".rela");
+            try w.print(".{s}\x00", .{entry.key_ptr.*});
+        }
+    }
+
+    // pad to 16 bytes
+    try w.writeByteNTimes(0, @intCast(sh_offset_aligned - sh_offset));
+    // mandatory null header
+    try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Shdr));
+
+    // write strtab section header
+    {
+        var sect_header = std.elf.Elf64_Shdr{
+            .sh_name = strtab_name,
+            .sh_type = std.elf.SHT_STRTAB,
+            .sh_flags = 0,
+            .sh_addr = 0,
+            .sh_offset = strtab_offset,
+            .sh_size = elf.strtab_len,
+            .sh_link = 0,
+            .sh_info = 0,
+            .sh_addralign = 1,
+            .sh_entsize = 0,
+        };
+        try w.writeStruct(sect_header);
+    }
+
+    // write symtab section header
+    {
+        var sect_header = std.elf.Elf64_Shdr{
+            .sh_name = symtab_name,
+            .sh_type = std.elf.SHT_SYMTAB,
+            .sh_flags = 0,
+            .sh_addr = 0,
+            .sh_offset = symtab_offset_aligned,
+            .sh_size = symtab_len,
+            .sh_link = strtab_index,
+            .sh_info = elf.local_symbols.size + 1,
+            .sh_addralign = 8,
+            .sh_entsize = @sizeOf(std.elf.Elf64_Sym),
+        };
+        try w.writeStruct(sect_header);
+    }
+
+    // remaining section headers
+    {
+        var sect_offset: u64 = @sizeOf(std.elf.Elf64_Ehdr);
+        var rela_sect_offset: u64 = rela_offset;
+        var it = elf.sections.iterator();
+        while (it.next()) |entry| {
+            const sect = entry.value_ptr.*;
+            const rela_count = sect.relocations.items.len;
+            const rela_name_offset: u32 = if (rela_count != 0) @truncate(".rela".len) else 0;
+            try w.writeStruct(std.elf.Elf64_Shdr{
+                .sh_name = rela_name_offset + name_offset,
+                .sh_type = sect.type,
+                .sh_flags = sect.flags,
+                .sh_addr = 0,
+                .sh_offset = sect_offset,
+                .sh_size = sect.data.items.len,
+                .sh_link = 0,
+                .sh_info = 0,
+                .sh_addralign = if (sect.flags & std.elf.SHF_EXECINSTR != 0) 16 else 1,
+                .sh_entsize = 0,
+            });
+
+            if (rela_count != 0) {
+                const size = rela_count * @sizeOf(std.elf.Elf64_Rela);
+                try w.writeStruct(std.elf.Elf64_Shdr{
+                    .sh_name = name_offset,
+                    .sh_type = std.elf.SHT_RELA,
+                    .sh_flags = 0,
+                    .sh_addr = 0,
+                    .sh_offset = rela_sect_offset,
+                    .sh_size = rela_count * @sizeOf(std.elf.Elf64_Rela),
+                    .sh_link = symtab_index,
+                    .sh_info = sect.index,
+                    .sh_addralign = 8,
+                    .sh_entsize = @sizeOf(std.elf.Elf64_Rela),
+                });
+                rela_sect_offset += size;
+            }
+
+            sect_offset += sect.data.items.len;
+            name_offset += @as(u32, @intCast(entry.key_ptr.len + ".\x00".len)) + rela_name_offset;
+        }
+    }
+    try buf_writer.flush();
+}
deps/aro/pragmas/gcc.zig
@@ -0,0 +1,199 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const Pragma = @import("../Pragma.zig");
+const Diagnostics = @import("../Diagnostics.zig");
+const Preprocessor = @import("../Preprocessor.zig");
+const Parser = @import("../Parser.zig");
+const TokenIndex = @import("../Tree.zig").TokenIndex;
+
+const GCC = @This();
+
+pragma: Pragma = .{
+    .beforeParse = beforeParse,
+    .beforePreprocess = beforePreprocess,
+    .afterParse = afterParse,
+    .deinit = deinit,
+    .preprocessorHandler = preprocessorHandler,
+    .parserHandler = parserHandler,
+    .preserveTokens = preserveTokens,
+},
+original_options: Diagnostics.Options = .{},
+options_stack: std.ArrayListUnmanaged(Diagnostics.Options) = .{},
+
+const Directive = enum {
+    warning,
+    @"error",
+    diagnostic,
+    poison,
+    const Diagnostics = enum {
+        ignored,
+        warning,
+        @"error",
+        fatal,
+        push,
+        pop,
+    };
+};
+
+fn beforePreprocess(pragma: *Pragma, comp: *Compilation) void {
+    var self = @fieldParentPtr(GCC, "pragma", pragma);
+    self.original_options = comp.diag.options;
+}
+
+fn beforeParse(pragma: *Pragma, comp: *Compilation) void {
+    var self = @fieldParentPtr(GCC, "pragma", pragma);
+    comp.diag.options = self.original_options;
+    self.options_stack.items.len = 0;
+}
+
+fn afterParse(pragma: *Pragma, comp: *Compilation) void {
+    var self = @fieldParentPtr(GCC, "pragma", pragma);
+    comp.diag.options = self.original_options;
+    self.options_stack.items.len = 0;
+}
+
+pub fn init(allocator: mem.Allocator) !*Pragma {
+    var gcc = try allocator.create(GCC);
+    gcc.* = .{};
+    return &gcc.pragma;
+}
+
+fn deinit(pragma: *Pragma, comp: *Compilation) void {
+    var self = @fieldParentPtr(GCC, "pragma", pragma);
+    self.options_stack.deinit(comp.gpa);
+    comp.gpa.destroy(self);
+}
+
+fn diagnosticHandler(self: *GCC, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
+    const diagnostic_tok = pp.tokens.get(start_idx);
+    if (diagnostic_tok.id == .nl) return;
+
+    const diagnostic = std.meta.stringToEnum(Directive.Diagnostics, pp.expandedSlice(diagnostic_tok)) orelse
+        return error.UnknownPragma;
+
+    switch (diagnostic) {
+        .ignored, .warning, .@"error", .fatal => {
+            const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) {
+                error.ExpectedStringLiteral => {
+                    return pp.comp.diag.add(.{
+                        .tag = .pragma_requires_string_literal,
+                        .loc = diagnostic_tok.loc,
+                        .extra = .{ .str = "GCC diagnostic" },
+                    }, diagnostic_tok.expansionSlice());
+                },
+                else => |e| return e,
+            };
+            if (!mem.startsWith(u8, str, "-W")) {
+                const next = pp.tokens.get(start_idx + 1);
+                return pp.comp.diag.add(.{
+                    .tag = .malformed_warning_check,
+                    .loc = next.loc,
+                    .extra = .{ .str = "GCC diagnostic" },
+                }, next.expansionSlice());
+            }
+            const new_kind = switch (diagnostic) {
+                .ignored => Diagnostics.Kind.off,
+                .warning => Diagnostics.Kind.warning,
+                .@"error" => Diagnostics.Kind.@"error",
+                .fatal => Diagnostics.Kind.@"fatal error",
+                else => unreachable,
+            };
+
+            try pp.comp.diag.set(str[2..], new_kind);
+        },
+        .push => try self.options_stack.append(pp.comp.gpa, pp.comp.diag.options),
+        .pop => pp.comp.diag.options = self.options_stack.popOrNull() orelse self.original_options,
+    }
+}
+
+fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
+    var self = @fieldParentPtr(GCC, "pragma", pragma);
+    const directive_tok = pp.tokens.get(start_idx + 1);
+    if (directive_tok.id == .nl) return;
+
+    const gcc_pragma = std.meta.stringToEnum(Directive, pp.expandedSlice(directive_tok)) orelse
+        return pp.comp.diag.add(.{
+        .tag = .unknown_gcc_pragma,
+        .loc = directive_tok.loc,
+    }, directive_tok.expansionSlice());
+
+    switch (gcc_pragma) {
+        .warning, .@"error" => {
+            const text = Pragma.pasteTokens(pp, start_idx + 2) catch |err| switch (err) {
+                error.ExpectedStringLiteral => {
+                    return pp.comp.diag.add(.{
+                        .tag = .pragma_requires_string_literal,
+                        .loc = directive_tok.loc,
+                        .extra = .{ .str = @tagName(gcc_pragma) },
+                    }, directive_tok.expansionSlice());
+                },
+                else => |e| return e,
+            };
+            const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diag.arena.allocator().dupe(u8, text) };
+            const diagnostic_tag: Diagnostics.Tag = if (gcc_pragma == .warning) .pragma_warning_message else .pragma_error_message;
+            return pp.comp.diag.add(
+                .{ .tag = diagnostic_tag, .loc = directive_tok.loc, .extra = extra },
+                directive_tok.expansionSlice(),
+            );
+        },
+        .diagnostic => return self.diagnosticHandler(pp, start_idx + 2) catch |err| switch (err) {
+            error.UnknownPragma => {
+                const tok = pp.tokens.get(start_idx + 2);
+                return pp.comp.diag.add(.{
+                    .tag = .unknown_gcc_pragma_directive,
+                    .loc = tok.loc,
+                }, tok.expansionSlice());
+            },
+            else => |e| return e,
+        },
+        .poison => {
+            var i: usize = 2;
+            while (true) : (i += 1) {
+                const tok = pp.tokens.get(start_idx + i);
+                if (tok.id == .nl) break;
+
+                if (!tok.id.isMacroIdentifier()) {
+                    return pp.comp.diag.add(.{
+                        .tag = .pragma_poison_identifier,
+                        .loc = tok.loc,
+                    }, tok.expansionSlice());
+                }
+                const str = pp.expandedSlice(tok);
+                if (pp.defines.get(str) != null) {
+                    try pp.comp.diag.add(.{
+                        .tag = .pragma_poison_macro,
+                        .loc = tok.loc,
+                    }, tok.expansionSlice());
+                }
+                try pp.poisoned_identifiers.put(str, {});
+            }
+            return;
+        },
+    }
+}
+
+fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
+    var self = @fieldParentPtr(GCC, "pragma", pragma);
+    const directive_tok = p.pp.tokens.get(start_idx + 1);
+    if (directive_tok.id == .nl) return;
+    const name = p.pp.expandedSlice(directive_tok);
+    if (mem.eql(u8, name, "diagnostic")) {
+        return self.diagnosticHandler(p.pp, start_idx + 2) catch |err| switch (err) {
+            error.UnknownPragma => {}, // handled during preprocessing
+            error.StopPreprocessing => unreachable, // Only used by #pragma once
+            else => |e| return e,
+        };
+    }
+}
+
+fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
+    const next = pp.tokens.get(start_idx + 1);
+    if (next.id != .nl) {
+        const name = pp.expandedSlice(next);
+        if (mem.eql(u8, name, "poison")) {
+            return false;
+        }
+    }
+    return true;
+}
deps/aro/pragmas/message.zig
@@ -0,0 +1,50 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const Pragma = @import("../Pragma.zig");
+const Diagnostics = @import("../Diagnostics.zig");
+const Preprocessor = @import("../Preprocessor.zig");
+const Parser = @import("../Parser.zig");
+const TokenIndex = @import("../Tree.zig").TokenIndex;
+const Source = @import("../Source.zig");
+
+const Message = @This();
+
+pragma: Pragma = .{
+    .deinit = deinit,
+    .preprocessorHandler = preprocessorHandler,
+},
+
+pub fn init(allocator: mem.Allocator) !*Pragma {
+    var once = try allocator.create(Message);
+    once.* = .{};
+    return &once.pragma;
+}
+
+fn deinit(pragma: *Pragma, comp: *Compilation) void {
+    var self = @fieldParentPtr(Message, "pragma", pragma);
+    comp.gpa.destroy(self);
+}
+
+fn preprocessorHandler(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
+    const message_tok = pp.tokens.get(start_idx);
+    const message_expansion_locs = message_tok.expansionSlice();
+
+    const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) {
+        error.ExpectedStringLiteral => {
+            return pp.comp.diag.add(.{
+                .tag = .pragma_requires_string_literal,
+                .loc = message_tok.loc,
+                .extra = .{ .str = "message" },
+            }, message_expansion_locs);
+        },
+        else => |e| return e,
+    };
+
+    const loc = if (message_expansion_locs.len != 0)
+        message_expansion_locs[message_expansion_locs.len - 1]
+    else
+        message_tok.loc;
+    const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diag.arena.allocator().dupe(u8, str) };
+    return pp.comp.diag.add(.{ .tag = .pragma_message, .loc = loc, .extra = extra }, &.{});
+}
deps/aro/pragmas/once.zig
@@ -0,0 +1,56 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const Pragma = @import("../Pragma.zig");
+const Diagnostics = @import("../Diagnostics.zig");
+const Preprocessor = @import("../Preprocessor.zig");
+const Parser = @import("../Parser.zig");
+const TokenIndex = @import("../Tree.zig").TokenIndex;
+const Source = @import("../Source.zig");
+
+const Once = @This();
+
+pragma: Pragma = .{
+    .afterParse = afterParse,
+    .deinit = deinit,
+    .preprocessorHandler = preprocessorHandler,
+},
+pragma_once: std.AutoHashMap(Source.Id, void),
+preprocess_count: u32 = 0,
+
+pub fn init(allocator: mem.Allocator) !*Pragma {
+    var once = try allocator.create(Once);
+    once.* = .{
+        .pragma_once = std.AutoHashMap(Source.Id, void).init(allocator),
+    };
+    return &once.pragma;
+}
+
+fn afterParse(pragma: *Pragma, _: *Compilation) void {
+    var self = @fieldParentPtr(Once, "pragma", pragma);
+    self.pragma_once.clearRetainingCapacity();
+}
+
+fn deinit(pragma: *Pragma, comp: *Compilation) void {
+    var self = @fieldParentPtr(Once, "pragma", pragma);
+    self.pragma_once.deinit();
+    comp.gpa.destroy(self);
+}
+
+fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
+    var self = @fieldParentPtr(Once, "pragma", pragma);
+    const name_tok = pp.tokens.get(start_idx);
+    const next = pp.tokens.get(start_idx + 1);
+    if (next.id != .nl) {
+        try pp.comp.diag.add(.{
+            .tag = .extra_tokens_directive_end,
+            .loc = name_tok.loc,
+        }, next.expansionSlice());
+    }
+    const seen = self.preprocess_count == pp.preprocess_count;
+    const prev = try self.pragma_once.fetchPut(name_tok.loc.id, {});
+    if (prev != null and !seen) {
+        return error.StopPreprocessing;
+    }
+    self.preprocess_count = pp.preprocess_count;
+}
deps/aro/pragmas/pack.zig
@@ -0,0 +1,164 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const Pragma = @import("../Pragma.zig");
+const Diagnostics = @import("../Diagnostics.zig");
+const Preprocessor = @import("../Preprocessor.zig");
+const Parser = @import("../Parser.zig");
+const Tree = @import("../Tree.zig");
+const TokenIndex = Tree.TokenIndex;
+
+const Pack = @This();
+
+pragma: Pragma = .{
+    .deinit = deinit,
+    .parserHandler = parserHandler,
+    .preserveTokens = preserveTokens,
+},
+stack: std.ArrayListUnmanaged(struct { label: []const u8, val: u8 }) = .{},
+
+pub fn init(allocator: mem.Allocator) !*Pragma {
+    var pack = try allocator.create(Pack);
+    pack.* = .{};
+    return &pack.pragma;
+}
+
+fn deinit(pragma: *Pragma, comp: *Compilation) void {
+    var self = @fieldParentPtr(Pack, "pragma", pragma);
+    self.stack.deinit(comp.gpa);
+    comp.gpa.destroy(self);
+}
+
+fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
+    var pack = @fieldParentPtr(Pack, "pragma", pragma);
+    var idx = start_idx + 1;
+    const l_paren = p.pp.tokens.get(idx);
+    if (l_paren.id != .l_paren) {
+        return p.pp.comp.diag.add(.{
+            .tag = .pragma_pack_lparen,
+            .loc = l_paren.loc,
+        }, l_paren.expansionSlice());
+    }
+    idx += 1;
+
+    // TODO -fapple-pragma-pack -fxl-pragma-pack
+    const apple_or_xl = false;
+    const tok_ids = p.pp.tokens.items(.id);
+    const arg = idx;
+    switch (tok_ids[arg]) {
+        .identifier => {
+            idx += 1;
+            const Action = enum {
+                show,
+                push,
+                pop,
+            };
+            const action = std.meta.stringToEnum(Action, p.tokSlice(arg)) orelse {
+                return p.errTok(.pragma_pack_unknown_action, arg);
+            };
+            switch (action) {
+                .show => {
+                    try p.errExtra(.pragma_pack_show, arg, .{ .unsigned = p.pragma_pack orelse 8 });
+                },
+                .push, .pop => {
+                    var new_val: ?u8 = null;
+                    var label: ?[]const u8 = null;
+                    if (tok_ids[idx] == .comma) {
+                        idx += 1;
+                        const next = idx;
+                        idx += 1;
+                        switch (tok_ids[next]) {
+                            .pp_num => new_val = (try packInt(p, next)) orelse return,
+                            .identifier => {
+                                label = p.tokSlice(next);
+                                if (tok_ids[idx] == .comma) {
+                                    idx += 1;
+                                    const int = idx;
+                                    idx += 1;
+                                    if (tok_ids[int] != .pp_num) return p.errTok(.pragma_pack_int_ident, int);
+                                    new_val = (try packInt(p, int)) orelse return;
+                                }
+                            },
+                            else => return p.errTok(.pragma_pack_int_ident, next),
+                        }
+                    }
+                    if (action == .push) {
+                        try pack.stack.append(p.pp.comp.gpa, .{ .label = label orelse "", .val = p.pragma_pack orelse 8 });
+                    } else {
+                        pack.pop(p, label);
+                        if (new_val != null) {
+                            try p.errTok(.pragma_pack_undefined_pop, arg);
+                        } else if (pack.stack.items.len == 0) {
+                            try p.errTok(.pragma_pack_empty_stack, arg);
+                        }
+                    }
+                    if (new_val) |some| {
+                        p.pragma_pack = some;
+                    }
+                },
+            }
+        },
+        .r_paren => if (apple_or_xl) {
+            pack.pop(p, null);
+        } else {
+            p.pragma_pack = null;
+        },
+        .pp_num => {
+            const new_val = (try packInt(p, arg)) orelse return;
+            idx += 1;
+            if (apple_or_xl) {
+                try pack.stack.append(p.pp.comp.gpa, .{ .label = "", .val = p.pragma_pack });
+            }
+            p.pragma_pack = new_val;
+        },
+        else => {},
+    }
+
+    if (tok_ids[idx] != .r_paren) {
+        return p.errTok(.pragma_pack_rparen, idx);
+    }
+}
+
+fn packInt(p: *Parser, tok_i: TokenIndex) Compilation.Error!?u8 {
+    const res = p.parseNumberToken(tok_i) catch |err| switch (err) {
+        error.ParsingFailed => {
+            try p.errTok(.pragma_pack_int, tok_i);
+            return null;
+        },
+        else => |e| return e,
+    };
+    const int = if (res.val.tag == .int) res.val.getInt(u64) else 99;
+    switch (int) {
+        1, 2, 4, 8, 16 => return @intCast(int),
+        else => {
+            try p.errTok(.pragma_pack_int, tok_i);
+            return null;
+        },
+    }
+}
+
+fn pop(pack: *Pack, p: *Parser, maybe_label: ?[]const u8) void {
+    if (maybe_label) |label| {
+        var i = pack.stack.items.len;
+        while (i > 0) {
+            i -= 1;
+            if (std.mem.eql(u8, pack.stack.items[i].label, label)) {
+                const prev = pack.stack.orderedRemove(i);
+                p.pragma_pack = prev.val;
+                return;
+            }
+        }
+    } else {
+        const prev = pack.stack.popOrNull() orelse {
+            p.pragma_pack = 2;
+            return;
+        };
+        p.pragma_pack = prev.val;
+    }
+}
+
+fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
+    _ = pp;
+    _ = start_idx;
+    return true;
+}
deps/aro/toolchains/Linux.zig
@@ -0,0 +1,482 @@
+const std = @import("std");
+const mem = std.mem;
+const Compilation = @import("../Compilation.zig");
+const GCCDetector = @import("../Driver/GCCDetector.zig");
+const Toolchain = @import("../Toolchain.zig");
+const Driver = @import("../Driver.zig");
+const Distro = @import("../Driver/Distro.zig");
+const target_util = @import("../target.zig");
+const system_defaults = @import("system_defaults");
+
+const Linux = @This();
+
+distro: Distro.Tag = .unknown,
+extra_opts: std.ArrayListUnmanaged([]const u8) = .{},
+gcc_detector: GCCDetector = .{},
+
+pub fn discover(self: *Linux, tc: *Toolchain) !void {
+    self.distro = Distro.detect(tc.getTarget(), tc.filesystem);
+    try self.gcc_detector.discover(tc);
+    tc.selected_multilib = self.gcc_detector.selected;
+
+    try self.gcc_detector.appendToolPath(tc);
+    try self.buildExtraOpts(tc);
+    try self.findPaths(tc);
+}
+
+fn buildExtraOpts(self: *Linux, tc: *const Toolchain) !void {
+    const gpa = tc.driver.comp.gpa;
+    const target = tc.getTarget();
+    const is_android = target.isAndroid();
+    if (self.distro.isAlpine() or is_android) {
+        try self.extra_opts.ensureUnusedCapacity(gpa, 2);
+        self.extra_opts.appendAssumeCapacity("-z");
+        self.extra_opts.appendAssumeCapacity("now");
+    }
+
+    if (self.distro.isOpenSUSE() or self.distro.isUbuntu() or self.distro.isAlpine() or is_android) {
+        try self.extra_opts.ensureUnusedCapacity(gpa, 2);
+        self.extra_opts.appendAssumeCapacity("-z");
+        self.extra_opts.appendAssumeCapacity("relro");
+    }
+
+    if (target.cpu.arch.isARM() or target.cpu.arch.isAARCH64() or is_android) {
+        try self.extra_opts.ensureUnusedCapacity(gpa, 2);
+        self.extra_opts.appendAssumeCapacity("-z");
+        self.extra_opts.appendAssumeCapacity("max-page-size=4096");
+    }
+
+    if (target.cpu.arch == .arm or target.cpu.arch == .thumb) {
+        try self.extra_opts.append(gpa, "-X");
+    }
+
+    if (!target.cpu.arch.isMIPS() and target.cpu.arch != .hexagon) {
+        const hash_style = if (is_android) .both else self.distro.getHashStyle();
+        try self.extra_opts.append(gpa, switch (hash_style) {
+            inline else => |tag| "--hash-style=" ++ @tagName(tag),
+        });
+    }
+
+    if (system_defaults.enable_linker_build_id) {
+        try self.extra_opts.append(gpa, "--build-id");
+    }
+}
+
+fn addMultiLibPaths(self: *Linux, tc: *Toolchain, sysroot: []const u8, os_lib_dir: []const u8) !void {
+    if (!self.gcc_detector.is_valid) return;
+    const gcc_triple = self.gcc_detector.gcc_triple;
+    const lib_path = self.gcc_detector.parent_lib_path;
+
+    // Add lib/gcc/$triple/$version, with an optional /multilib suffix.
+    try tc.addPathIfExists(&.{ self.gcc_detector.install_path, tc.selected_multilib.gcc_suffix }, .file);
+
+    // Add lib/gcc/$triple/$libdir
+    // For GCC built with --enable-version-specific-runtime-libs.
+    try tc.addPathIfExists(&.{ self.gcc_detector.install_path, "..", os_lib_dir }, .file);
+
+    try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", "..", os_lib_dir, tc.selected_multilib.os_suffix }, .file);
+
+    // If the GCC installation we found is inside of the sysroot, we want to
+    // prefer libraries installed in the parent prefix of the GCC installation.
+    // It is important to *not* use these paths when the GCC installation is
+    // outside of the system root as that can pick up unintended libraries.
+    // This usually happens when there is an external cross compiler on the
+    // host system, and a more minimal sysroot available that is the target of
+    // the cross. Note that GCC does include some of these directories in some
+    // configurations but this seems somewhere between questionable and simply
+    // a bug.
+    if (mem.startsWith(u8, lib_path, sysroot)) {
+        try tc.addPathIfExists(&.{ lib_path, "..", os_lib_dir }, .file);
+    }
+}
+
+fn addMultiArchPaths(self: *Linux, tc: *Toolchain) !void {
+    if (!self.gcc_detector.is_valid) return;
+    const lib_path = self.gcc_detector.parent_lib_path;
+    const gcc_triple = self.gcc_detector.gcc_triple;
+    const multilib = self.gcc_detector.selected;
+    try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", multilib.os_suffix }, .file);
+}
+
+/// TODO: Very incomplete
+fn findPaths(self: *Linux, tc: *Toolchain) !void {
+    const target = tc.getTarget();
+    const sysroot = tc.getSysroot();
+
+    var output: [64]u8 = undefined;
+
+    const os_lib_dir = getOSLibDir(target);
+    const multiarch_triple = getMultiarchTriple(target) orelse target_util.toLLVMTriple(target, &output);
+
+    try self.addMultiLibPaths(tc, sysroot, os_lib_dir);
+
+    try tc.addPathIfExists(&.{ sysroot, "/lib", multiarch_triple }, .file);
+    try tc.addPathIfExists(&.{ sysroot, "/lib", "..", os_lib_dir }, .file);
+
+    if (target.isAndroid()) {
+        // TODO
+    }
+    try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", multiarch_triple }, .file);
+    try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", "..", os_lib_dir }, .file);
+
+    try self.addMultiArchPaths(tc);
+
+    try tc.addPathIfExists(&.{ sysroot, "/lib" }, .file);
+    try tc.addPathIfExists(&.{ sysroot, "/usr", "lib" }, .file);
+}
+
+pub fn deinit(self: *Linux, allocator: std.mem.Allocator) void {
+    self.extra_opts.deinit(allocator);
+}
+
+fn isPIEDefault(self: *const Linux) bool {
+    _ = self;
+    return false;
+}
+
+fn getPIE(self: *const Linux, d: *const Driver) bool {
+    if (d.shared or d.static or d.relocatable or d.static_pie) {
+        return false;
+    }
+    return d.pie orelse self.isPIEDefault();
+}
+
+fn getStaticPIE(self: *const Linux, d: *Driver) !bool {
+    _ = self;
+    if (d.static_pie and d.pie != null) {
+        try d.err("cannot specify 'nopie' along with 'static-pie'");
+    }
+    return d.static_pie;
+}
+
+fn getStatic(self: *const Linux, d: *const Driver) bool {
+    _ = self;
+    return d.static and !d.static_pie;
+}
+
+pub fn getDefaultLinker(self: *const Linux, target: std.Target) []const u8 {
+    _ = self;
+    if (target.isAndroid()) {
+        return "ld.lld";
+    }
+    return "ld";
+}
+
+pub fn buildLinkerArgs(self: *const Linux, tc: *const Toolchain, argv: *std.ArrayList([]const u8)) Compilation.Error!void {
+    const d = tc.driver;
+    const target = tc.getTarget();
+
+    const is_pie = self.getPIE(d);
+    const is_static_pie = try self.getStaticPIE(d);
+    const is_static = self.getStatic(d);
+    const is_android = target.isAndroid();
+    const is_iamcu = target.os.tag == .elfiamcu;
+    const is_ve = target.cpu.arch == .ve;
+    const has_crt_begin_end_files = target.abi != .none; // TODO: clang checks for MIPS vendor
+
+    if (is_pie) {
+        try argv.append("-pie");
+    }
+    if (is_static_pie) {
+        try argv.appendSlice(&.{ "-static", "-pie", "--no-dynamic-linker", "-z", "text" });
+    }
+
+    if (d.rdynamic) {
+        try argv.append("-export-dynamic");
+    }
+
+    if (d.strip) {
+        try argv.append("-s");
+    }
+
+    try argv.appendSlice(self.extra_opts.items);
+    try argv.append("--eh-frame-hdr");
+
+    // Todo: Driver should parse `-EL`/`-EB` for arm to set endianness for arm targets
+    if (target_util.ldEmulationOption(d.comp.target, null)) |emulation| {
+        try argv.appendSlice(&.{ "-m", emulation });
+    } else {
+        try d.err("Unknown target triple");
+        return;
+    }
+    if (d.comp.target.cpu.arch.isRISCV()) {
+        try argv.append("-X");
+    }
+    if (d.shared) {
+        try argv.append("-shared");
+    }
+    if (is_static) {
+        try argv.append("-static");
+    } else {
+        if (d.rdynamic) {
+            try argv.append("-export-dynamic");
+        }
+        if (!d.shared and !is_static_pie and !d.relocatable) {
+            const dynamic_linker = d.comp.target.standardDynamicLinkerPath();
+            // todo: check for --dyld-prefix
+            if (dynamic_linker.get()) |path| {
+                try argv.appendSlice(&.{ "-dynamic-linker", try tc.arena.dupe(u8, path) });
+            } else {
+                try d.err("Could not find dynamic linker path");
+            }
+        }
+    }
+
+    try argv.appendSlice(&.{ "-o", d.output_name orelse "a.out" });
+
+    if (!d.nostdlib and !d.nostartfiles and !d.relocatable) {
+        if (!is_android and !is_iamcu) {
+            if (!d.shared) {
+                const crt1 = if (is_pie)
+                    "Scrt1.o"
+                else if (is_static_pie)
+                    "rcrt1.o"
+                else
+                    "crt1.o";
+                try argv.append(try tc.getFilePath(crt1));
+            }
+            try argv.append(try tc.getFilePath("crti.o"));
+        }
+        if (is_ve) {
+            try argv.appendSlice(&.{ "-z", "max-page-size=0x4000000" });
+        }
+
+        if (is_iamcu) {
+            try argv.append(try tc.getFilePath("crt0.o"));
+        } else if (has_crt_begin_end_files) {
+            var path: []const u8 = "";
+            if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) {
+                const crt_begin = try tc.getCompilerRt("crtbegin", .object);
+                if (tc.filesystem.exists(crt_begin)) {
+                    path = crt_begin;
+                }
+            }
+            if (path.len == 0) {
+                const crt_begin = if (tc.driver.shared)
+                    if (is_android) "crtbegin_so.o" else "crtbeginS.o"
+                else if (is_static)
+                    if (is_android) "crtbegin_static.o" else "crtbeginT.o"
+                else if (is_pie or is_static_pie)
+                    if (is_android) "crtbegin_dynamic.o" else "crtbeginS.o"
+                else if (is_android) "crtbegin_dynamic.o" else "crtbegin.o";
+                path = try tc.getFilePath(crt_begin);
+            }
+            try argv.append(path);
+        }
+    }
+
+    // TODO add -L opts
+    // TODO add -u opts
+
+    try tc.addFilePathLibArgs(argv);
+
+    // TODO handle LTO
+
+    try argv.appendSlice(d.link_objects.items);
+
+    if (!d.nostdlib and !d.relocatable) {
+        if (!d.nodefaultlibs) {
+            if (is_static or is_static_pie) {
+                try argv.append("--start-group");
+            }
+            try tc.addRuntimeLibs(argv);
+
+            // TODO: add pthread if needed
+            if (!d.nolibc) {
+                try argv.append("-lc");
+            }
+            if (is_iamcu) {
+                try argv.append("-lgloss");
+            }
+            if (is_static or is_static_pie) {
+                try argv.append("--end-group");
+            } else {
+                try tc.addRuntimeLibs(argv);
+            }
+            if (is_iamcu) {
+                try argv.appendSlice(&.{ "--as-needed", "-lsoftfp", "--no-as-needed" });
+            }
+        }
+        if (!d.nostartfiles and !is_iamcu) {
+            if (has_crt_begin_end_files) {
+                var path: []const u8 = "";
+                if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) {
+                    const crt_end = try tc.getCompilerRt("crtend", .object);
+                    if (tc.filesystem.exists(crt_end)) {
+                        path = crt_end;
+                    }
+                }
+                if (path.len == 0) {
+                    const crt_end = if (d.shared)
+                        if (is_android) "crtend_so.o" else "crtendS.o"
+                    else if (is_pie or is_static_pie)
+                        if (is_android) "crtend_android.o" else "crtendS.o"
+                    else if (is_android) "crtend_android.o" else "crtend.o";
+                    path = try tc.getFilePath(crt_end);
+                }
+                try argv.append(path);
+            }
+            if (!is_android) {
+                try argv.append(try tc.getFilePath("crtn.o"));
+            }
+        }
+    }
+
+    // TODO add -T args
+}
+
+fn getMultiarchTriple(target: std.Target) ?[]const u8 {
+    const is_android = target.isAndroid();
+    const is_mips_r6 = std.Target.mips.featureSetHas(target.cpu.features, .mips32r6);
+    return switch (target.cpu.arch) {
+        .arm, .thumb => if (is_android) "arm-linux-androideabi" else if (target.abi == .gnueabihf) "arm-linux-gnueabihf" else "arm-linux-gnueabi",
+        .armeb, .thumbeb => if (target.abi == .gnueabihf) "armeb-linux-gnueabihf" else "armeb-linux-gnueabi",
+        .aarch64 => if (is_android) "aarch64-linux-android" else "aarch64-linux-gnu",
+        .aarch64_be => "aarch64_be-linux-gnu",
+        .x86 => if (is_android) "i686-linux-android" else "i386-linux-gnu",
+        .x86_64 => if (is_android) "x86_64-linux-android" else if (target.abi == .gnux32) "x86_64-linux-gnux32" else "x86_64-linux-gnu",
+        .m68k => "m68k-linux-gnu",
+        .mips => if (is_mips_r6) "mipsisa32r6-linux-gnu" else "mips-linux-gnu",
+        .mipsel => if (is_android) "mipsel-linux-android" else if (is_mips_r6) "mipsisa32r6el-linux-gnu" else "mipsel-linux-gnu",
+        .powerpcle => "powerpcle-linux-gnu",
+        .powerpc64 => "powerpc64-linux-gnu",
+        .powerpc64le => "powerpc64le-linux-gnu",
+        .riscv64 => "riscv64-linux-gnu",
+        .sparc => "sparc-linux-gnu",
+        .sparc64 => "sparc64-linux-gnu",
+        .s390x => "s390x-linux-gnu",
+
+        // TODO: expand this
+        else => null,
+    };
+}
+
+fn getOSLibDir(target: std.Target) []const u8 {
+    switch (target.cpu.arch) {
+        .x86,
+        .powerpc,
+        .powerpcle,
+        .sparc,
+        .sparcel,
+        => return "lib32",
+        else => {},
+    }
+    if (target.cpu.arch == .x86_64 and (target.abi == .gnux32 or target.abi == .muslx32)) {
+        return "libx32";
+    }
+    if (target.cpu.arch == .riscv32) {
+        return "lib32";
+    }
+    if (target.ptrBitWidth() == 32) {
+        return "lib";
+    }
+    return "lib64";
+}
+
+test Linux {
+    if (@import("builtin").os.tag == .windows) return error.SkipZigTest;
+
+    var arena_instance = std.heap.ArenaAllocator.init(std.testing.allocator);
+    defer arena_instance.deinit();
+    const arena = arena_instance.allocator();
+
+    var comp = Compilation.init(std.testing.allocator);
+    defer comp.deinit();
+    comp.environment = .{
+        .path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+    };
+
+    const raw_triple = "x86_64-linux-gnu";
+    const cross = std.zig.CrossTarget.parse(.{ .arch_os_abi = raw_triple }) catch unreachable;
+    comp.target = cross.toTarget(); // TODO deprecated
+    comp.langopts.setEmulatedCompiler(.gcc);
+
+    var driver: Driver = .{ .comp = &comp };
+    defer driver.deinit();
+    driver.raw_target_triple = raw_triple;
+
+    const link_obj = try driver.comp.gpa.dupe(u8, "/tmp/foo.o");
+    try driver.link_objects.append(driver.comp.gpa, link_obj);
+    driver.temp_file_count += 1;
+
+    var toolchain: Toolchain = .{ .driver = &driver, .arena = arena, .filesystem = .{ .fake = &.{
+        .{ .path = "/tmp" },
+        .{ .path = "/usr" },
+        .{ .path = "/usr/lib64" },
+        .{ .path = "/usr/bin" },
+        .{ .path = "/usr/bin/ld", .executable = true },
+        .{ .path = "/lib" },
+        .{ .path = "/lib/x86_64-linux-gnu" },
+        .{ .path = "/lib/x86_64-linux-gnu/crt1.o" },
+        .{ .path = "/lib/x86_64-linux-gnu/crti.o" },
+        .{ .path = "/lib/x86_64-linux-gnu/crtn.o" },
+        .{ .path = "/lib64" },
+        .{ .path = "/usr/lib" },
+        .{ .path = "/usr/lib/gcc" },
+        .{ .path = "/usr/lib/gcc/x86_64-linux-gnu" },
+        .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9" },
+        .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o" },
+        .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o" },
+        .{ .path = "/usr/lib/x86_64-linux-gnu" },
+        .{ .path = "/etc/lsb-release", .contents = 
+        \\DISTRIB_ID=Ubuntu
+        \\DISTRIB_RELEASE=20.04
+        \\DISTRIB_CODENAME=focal
+        \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
+        \\
+        },
+    } } };
+    defer toolchain.deinit();
+
+    try toolchain.discover();
+
+    var argv = std.ArrayList([]const u8).init(driver.comp.gpa);
+    defer argv.deinit();
+
+    var linker_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+    const linker_path = try toolchain.getLinkerPath(&linker_path_buf);
+    try argv.append(linker_path);
+
+    try toolchain.buildLinkerArgs(&argv);
+
+    const expected = [_][]const u8{
+        "/usr/bin/ld",
+        "-z",
+        "relro",
+        "--hash-style=gnu",
+        "--eh-frame-hdr",
+        "-m",
+        "elf_x86_64",
+        "-dynamic-linker",
+        "/lib64/ld-linux-x86-64.so.2",
+        "-o",
+        "a.out",
+        "/lib/x86_64-linux-gnu/crt1.o",
+        "/lib/x86_64-linux-gnu/crti.o",
+        "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o",
+        "-L/usr/lib/gcc/x86_64-linux-gnu/9",
+        "-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib64",
+        "-L/lib/x86_64-linux-gnu",
+        "-L/lib/../lib64",
+        "-L/usr/lib/x86_64-linux-gnu",
+        "-L/usr/lib/../lib64",
+        "-L/lib",
+        "-L/usr/lib",
+        link_obj,
+        "-lgcc",
+        "--as-needed",
+        "-lgcc_s",
+        "--no-as-needed",
+        "-lc",
+        "-lgcc",
+        "--as-needed",
+        "-lgcc_s",
+        "--no-as-needed",
+        "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o",
+        "/lib/x86_64-linux-gnu/crtn.o",
+    };
+    try std.testing.expectEqual(expected.len, argv.items.len);
+    for (expected, argv.items) |expected_item, actual_item| {
+        try std.testing.expectEqualStrings(expected_item, actual_item);
+    }
+}
deps/aro/Attribute.zig
@@ -0,0 +1,1346 @@
+const std = @import("std");
+const mem = std.mem;
+const ZigType = std.builtin.Type;
+const CallingConvention = @import("lib.zig").CallingConvention;
+const Compilation = @import("Compilation.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const Parser = @import("Parser.zig");
+const Tree = @import("Tree.zig");
+const NodeIndex = Tree.NodeIndex;
+const TokenIndex = Tree.TokenIndex;
+const Type = @import("Type.zig");
+const Value = @import("Value.zig");
+
+const Attribute = @This();
+
+tag: Tag,
+syntax: Syntax,
+args: Arguments,
+
+pub const Syntax = enum {
+    c2x,
+    declspec,
+    gnu,
+    keyword,
+};
+
+pub const Kind = enum {
+    c2x,
+    declspec,
+    gnu,
+
+    pub fn toSyntax(kind: Kind) Syntax {
+        return switch (kind) {
+            .c2x => .c2x,
+            .declspec => .declspec,
+            .gnu => .gnu,
+        };
+    }
+};
+
+pub const ArgumentType = enum {
+    string,
+    identifier,
+    int,
+    alignment,
+    float,
+    expression,
+    nullptr_t,
+
+    pub fn toString(self: ArgumentType) []const u8 {
+        return switch (self) {
+            .string => "a string",
+            .identifier => "an identifier",
+            .int, .alignment => "an integer constant",
+            .nullptr_t => "nullptr",
+            .float => "a floating point number",
+            .expression => "an expression",
+        };
+    }
+
+    fn fromType(comptime T: type) ArgumentType {
+        return switch (T) {
+            []const u8 => .string,
+            Identifier => .identifier,
+            u32 => .int,
+            Alignment => .alignment,
+            CallingConvention => .identifier,
+            else => switch (@typeInfo(T)) {
+                .Enum => if (T.opts.enum_kind == .string) .string else .identifier,
+                else => unreachable,
+            },
+        };
+    }
+
+    fn fromVal(value: Value) ArgumentType {
+        return switch (value.tag) {
+            .int => .int,
+            .bytes => .string,
+            .unavailable => .expression,
+            .float => .float,
+            .nullptr_t => .nullptr_t,
+        };
+    }
+};
+
+fn getArguments(comptime descriptor: type) []const ZigType.StructField {
+    return if (@hasDecl(descriptor, "Args")) std.meta.fields(descriptor.Args) else &.{};
+}
+
+/// number of required arguments
+pub fn requiredArgCount(attr: Tag) u32 {
+    switch (attr) {
+        inline else => |tag| {
+            comptime var needed = 0;
+            comptime {
+                const fields = getArguments(@field(attributes, @tagName(tag)));
+                for (fields) |arg_field| {
+                    if (!mem.eql(u8, arg_field.name, "__name_tok") and @typeInfo(arg_field.type) != .Optional) needed += 1;
+                }
+            }
+            return needed;
+        },
+    }
+}
+
+/// maximum number of args that can be passed
+pub fn maxArgCount(attr: Tag) u32 {
+    switch (attr) {
+        inline else => |tag| {
+            comptime var max = 0;
+            comptime {
+                const fields = getArguments(@field(attributes, @tagName(tag)));
+                for (fields) |arg_field| {
+                    if (!mem.eql(u8, arg_field.name, "__name_tok")) max += 1;
+                }
+            }
+            return max;
+        },
+    }
+}
+
+fn UnwrapOptional(comptime T: type) type {
+    return switch (@typeInfo(T)) {
+        .Optional => |optional| optional.child,
+        else => T,
+    };
+}
+
+pub const Formatting = struct {
+    /// The quote char (single or double) to use when printing identifiers/strings corresponding
+    /// to the enum in the first field of the Args of `attr`. Identifier enums use single quotes, string enums
+    /// use double quotes
+    fn quoteChar(attr: Tag) []const u8 {
+        switch (attr) {
+            .calling_convention => unreachable,
+            inline else => |tag| {
+                const fields = getArguments(@field(attributes, @tagName(tag)));
+
+                if (fields.len == 0) unreachable;
+                const Unwrapped = UnwrapOptional(fields[0].type);
+                if (@typeInfo(Unwrapped) != .Enum) unreachable;
+
+                return if (Unwrapped.opts.enum_kind == .identifier) "'" else "\"";
+            },
+        }
+    }
+
+    /// returns a comma-separated string of quoted enum values, representing the valid
+    /// choices for the string or identifier enum of the first field of the Args of `attr`.
+    pub fn choices(attr: Tag) []const u8 {
+        switch (attr) {
+            .calling_convention => unreachable,
+            inline else => |tag| {
+                const fields = getArguments(@field(attributes, @tagName(tag)));
+
+                if (fields.len == 0) unreachable;
+                const Unwrapped = UnwrapOptional(fields[0].type);
+                if (@typeInfo(Unwrapped) != .Enum) unreachable;
+
+                const enum_fields = @typeInfo(Unwrapped).Enum.fields;
+                @setEvalBranchQuota(3000);
+                const quote = comptime quoteChar(@enumFromInt(@intFromEnum(tag)));
+                comptime var values: []const u8 = quote ++ enum_fields[0].name ++ quote;
+                inline for (enum_fields[1..]) |enum_field| {
+                    values = values ++ ", ";
+                    values = values ++ quote ++ enum_field.name ++ quote;
+                }
+                return values;
+            },
+        }
+    }
+};
+
+/// Checks if the first argument (if it exists) is an identifier enum
+pub fn wantsIdentEnum(attr: Tag) bool {
+    switch (attr) {
+        .calling_convention => return false,
+        inline else => |tag| {
+            const fields = getArguments(@field(attributes, @tagName(tag)));
+
+            if (fields.len == 0) return false;
+            const Unwrapped = UnwrapOptional(fields[0].type);
+            if (@typeInfo(Unwrapped) != .Enum) return false;
+
+            return Unwrapped.opts.enum_kind == .identifier;
+        },
+    }
+}
+
+pub fn diagnoseIdent(attr: Tag, arguments: *Arguments, ident: []const u8) ?Diagnostics.Message {
+    switch (attr) {
+        inline else => |tag| {
+            const fields = getArguments(@field(attributes, @tagName(tag)));
+            if (fields.len == 0) unreachable;
+            const Unwrapped = UnwrapOptional(fields[0].type);
+            if (@typeInfo(Unwrapped) != .Enum) unreachable;
+            if (std.meta.stringToEnum(Unwrapped, normalize(ident))) |enum_val| {
+                @field(@field(arguments, @tagName(tag)), fields[0].name) = enum_val;
+                return null;
+            }
+            return Diagnostics.Message{
+                .tag = .unknown_attr_enum,
+                .extra = .{ .attr_enum = .{ .tag = attr } },
+            };
+        },
+    }
+}
+
+pub fn wantsAlignment(attr: Tag, idx: usize) bool {
+    switch (attr) {
+        inline else => |tag| {
+            const fields = getArguments(@field(attributes, @tagName(tag)));
+            if (fields.len == 0) return false;
+
+            return switch (idx) {
+                inline 0...fields.len - 1 => |i| UnwrapOptional(fields[i].type) == Alignment,
+                else => false,
+            };
+        },
+    }
+}
+
+pub fn diagnoseAlignment(attr: Tag, arguments: *Arguments, arg_idx: u32, val: Value, ty: Type, comp: *Compilation) ?Diagnostics.Message {
+    switch (attr) {
+        inline else => |tag| {
+            const arg_fields = getArguments(@field(attributes, @tagName(tag)));
+            if (arg_fields.len == 0) unreachable;
+
+            switch (arg_idx) {
+                inline 0...arg_fields.len - 1 => |arg_i| {
+                    if (UnwrapOptional(arg_fields[arg_i].type) != Alignment) unreachable;
+
+                    if (val.tag != .int) return Diagnostics.Message{ .tag = .alignas_unavailable };
+                    if (val.compare(.lt, Value.int(0), ty, comp)) {
+                        return Diagnostics.Message{ .tag = .negative_alignment, .extra = .{ .signed = val.signExtend(ty, comp) } };
+                    }
+                    const requested = std.math.cast(u29, val.data.int) orelse {
+                        return Diagnostics.Message{ .tag = .maximum_alignment, .extra = .{ .unsigned = val.data.int } };
+                    };
+                    if (!std.mem.isValidAlign(requested)) return Diagnostics.Message{ .tag = .non_pow2_align };
+
+                    @field(@field(arguments, @tagName(tag)), arg_fields[arg_i].name) = Alignment{ .requested = requested };
+                    return null;
+                },
+                else => unreachable,
+            }
+        },
+    }
+}
+
+fn diagnoseField(
+    comptime decl: ZigType.Declaration,
+    comptime field: ZigType.StructField,
+    comptime wanted: type,
+    arguments: *Arguments,
+    val: Value,
+    node: Tree.Node,
+    strings: []const u8,
+) ?Diagnostics.Message {
+    switch (val.tag) {
+        .int => {
+            if (@typeInfo(wanted) == .Int) {
+                @field(@field(arguments, decl.name), field.name) = val.getInt(wanted);
+                return null;
+            }
+        },
+        .bytes => {
+            const bytes = val.data.bytes.trim(1); // remove null terminator
+            if (wanted == Value.ByteRange) {
+                @field(@field(arguments, decl.name), field.name) = bytes;
+                return null;
+            } else if (@typeInfo(wanted) == .Enum and @hasDecl(wanted, "opts") and wanted.opts.enum_kind == .string) {
+                const str = bytes.slice(strings);
+                if (std.meta.stringToEnum(wanted, str)) |enum_val| {
+                    @field(@field(arguments, decl.name), field.name) = enum_val;
+                    return null;
+                } else {
+                    @setEvalBranchQuota(3000);
+                    return Diagnostics.Message{
+                        .tag = .unknown_attr_enum,
+                        .extra = .{ .attr_enum = .{ .tag = std.meta.stringToEnum(Tag, decl.name).? } },
+                    };
+                }
+            }
+        },
+        else => {
+            if (wanted == Identifier and node.tag == .decl_ref_expr) {
+                @field(@field(arguments, decl.name), field.name) = Identifier{ .tok = node.data.decl_ref };
+                return null;
+            }
+        },
+    }
+    return Diagnostics.Message{
+        .tag = .attribute_arg_invalid,
+        .extra = .{ .attr_arg_type = .{ .expected = ArgumentType.fromType(wanted), .actual = ArgumentType.fromVal(val) } },
+    };
+}
+
+pub fn diagnose(attr: Tag, arguments: *Arguments, arg_idx: u32, val: Value, node: Tree.Node, strings: []const u8) ?Diagnostics.Message {
+    switch (attr) {
+        inline else => |tag| {
+            const decl = @typeInfo(attributes).Struct.decls[@intFromEnum(tag)];
+            const max_arg_count = comptime maxArgCount(tag);
+            if (arg_idx >= max_arg_count) return Diagnostics.Message{
+                .tag = .attribute_too_many_args,
+                .extra = .{ .attr_arg_count = .{ .attribute = attr, .expected = max_arg_count } },
+            };
+            const arg_fields = getArguments(@field(attributes, decl.name));
+            switch (arg_idx) {
+                inline 0...arg_fields.len - 1 => |arg_i| {
+                    return diagnoseField(decl, arg_fields[arg_i], UnwrapOptional(arg_fields[arg_i].type), arguments, val, node, strings);
+                },
+                else => unreachable,
+            }
+        },
+    }
+}
+
+const EnumTypes = enum {
+    string,
+    identifier,
+};
+pub const Alignment = struct {
+    node: NodeIndex = .none,
+    requested: u29,
+};
+pub const Identifier = struct {
+    tok: TokenIndex = 0,
+};
+
+const attributes = struct {
+    pub const access = struct {
+        const gnu = "access";
+
+        const Args = struct {
+            access_mode: enum {
+                read_only,
+                read_write,
+                write_only,
+                none,
+
+                const opts = struct {
+                    const enum_kind = .identifier;
+                };
+            },
+            ref_index: u32,
+            size_index: ?u32 = null,
+        };
+    };
+    pub const alias = struct {
+        const gnu = "alias";
+        const Args = struct {
+            alias: Value.ByteRange,
+        };
+    };
+    pub const aligned = struct {
+        const gnu = "aligned";
+        const declspec = "align";
+
+        const Args = struct {
+            alignment: ?Alignment = null,
+            __name_tok: TokenIndex,
+        };
+    };
+    pub const alloc_align = struct {
+        const gnu = "alloc_align";
+
+        const Args = struct {
+            position: u32,
+        };
+    };
+    pub const alloc_size = struct {
+        const gnu = "alloc_size";
+
+        const Args = struct {
+            position_1: u32,
+            position_2: ?u32 = null,
+        };
+    };
+    pub const allocate = struct {
+        const declspec = "allocate";
+
+        const Args = struct {
+            segname: Value.ByteRange,
+        };
+    };
+    pub const allocator = struct {
+        const declspec = "allocator";
+    };
+    pub const always_inline = struct {
+        const gnu = "always_inline";
+    };
+    pub const appdomain = struct {
+        const declspec = "appdomain";
+    };
+    pub const artificial = struct {
+        const gnu = "artificial";
+    };
+    pub const assume_aligned = struct {
+        const gnu = "assume_aligned";
+        const Args = struct {
+            alignment: Alignment,
+            offset: ?u32 = null,
+        };
+    };
+    pub const cleanup = struct {
+        const gnu = "cleanup";
+        const Args = struct {
+            function: Identifier,
+        };
+    };
+    pub const code_seg = struct {
+        const declspec = "code_seg";
+        const Args = struct {
+            segname: Value.ByteRange,
+        };
+    };
+    pub const cold = struct {
+        const gnu = "cold";
+    };
+    pub const common = struct {
+        const gnu = "common";
+    };
+    pub const @"const" = struct {
+        const gnu = "const";
+    };
+    pub const constructor = struct {
+        const gnu = "constructor";
+        const Args = struct {
+            priority: ?u32 = null,
+        };
+    };
+    pub const copy = struct {
+        const gnu = "copy";
+        const Args = struct {
+            function: Identifier,
+        };
+    };
+    pub const deprecated = struct {
+        const gnu = "deprecated";
+        const declspec = "deprecated";
+        const c2x = "deprecated";
+
+        const Args = struct {
+            msg: ?Value.ByteRange = null,
+            __name_tok: TokenIndex,
+        };
+    };
+    pub const designated_init = struct {
+        const gnu = "designated_init";
+    };
+    pub const destructor = struct {
+        const gnu = "destructor";
+        const Args = struct {
+            priority: ?u32 = null,
+        };
+    };
+    pub const dllexport = struct {
+        const declspec = "dllexport";
+    };
+    pub const dllimport = struct {
+        const declspec = "dllimport";
+    };
+    pub const @"error" = struct {
+        const gnu = "error";
+        const Args = struct {
+            msg: Value.ByteRange,
+            __name_tok: TokenIndex,
+        };
+    };
+    pub const externally_visible = struct {
+        const gnu = "externally_visible";
+    };
+    pub const fallthrough = struct {
+        const gnu = "fallthrough";
+        const c2x = "fallthrough";
+    };
+    pub const flatten = struct {
+        const gnu = "flatten";
+    };
+    pub const format = struct {
+        const gnu = "format";
+        const Args = struct {
+            archetype: enum {
+                printf,
+                scanf,
+                strftime,
+                strfmon,
+
+                const opts = struct {
+                    const enum_kind = .identifier;
+                };
+            },
+            string_index: u32,
+            first_to_check: u32,
+        };
+    };
+    pub const format_arg = struct {
+        const gnu = "format_arg";
+        const Args = struct {
+            string_index: u32,
+        };
+    };
+    pub const gnu_inline = struct {
+        const gnu = "gnu_inline";
+    };
+    pub const hot = struct {
+        const gnu = "hot";
+    };
+    pub const ifunc = struct {
+        const gnu = "ifunc";
+        const Args = struct {
+            resolver: Value.ByteRange,
+        };
+    };
+    pub const interrupt = struct {
+        const gnu = "interrupt";
+    };
+    pub const interrupt_handler = struct {
+        const gnu = "interrupt_handler";
+    };
+    pub const jitintrinsic = struct {
+        const declspec = "jitintrinsic";
+    };
+    pub const leaf = struct {
+        const gnu = "leaf";
+    };
+    pub const malloc = struct {
+        const gnu = "malloc";
+    };
+    pub const may_alias = struct {
+        const gnu = "may_alias";
+    };
+    pub const mode = struct {
+        const gnu = "mode";
+        const Args = struct {
+            mode: enum {
+                // zig fmt: off
+                byte,  word,  pointer,
+                BI,    QI,    HI,
+                PSI,   SI,    PDI,
+                DI,    TI,    OI,
+                XI,    QF,    HF,
+                TQF,   SF,    DF,
+                XF,    SD,    DD,
+                TD,    TF,    QQ,
+                HQ,    SQ,    DQ,
+                TQ,    UQQ,   UHQ,
+                USQ,   UDQ,   UTQ,
+                HA,    SA,    DA,
+                TA,    UHA,   USA,
+                UDA,   UTA,   CC,
+                BLK,   VOID,  QC,
+                HC,    SC,    DC,
+                XC,    TC,    CQI,
+                CHI,   CSI,   CDI,
+                CTI,   COI,   CPSI,
+                BND32, BND64,
+                // zig fmt: on
+
+                const opts = struct {
+                    const enum_kind = .identifier;
+                };
+            },
+        };
+    };
+    pub const naked = struct {
+        const declspec = "naked";
+    };
+    pub const no_address_safety_analysis = struct {
+        const gnu = "no_address_safety_analysise";
+    };
+    pub const no_icf = struct {
+        const gnu = "no_icf";
+    };
+    pub const no_instrument_function = struct {
+        const gnu = "no_instrument_function";
+    };
+    pub const no_profile_instrument_function = struct {
+        const gnu = "no_profile_instrument_function";
+    };
+    pub const no_reorder = struct {
+        const gnu = "no_reorder";
+    };
+    pub const no_sanitize = struct {
+        const gnu = "no_sanitize";
+        /// Todo: represent args as union?
+        const Args = struct {
+            alignment: Value.ByteRange,
+            object_size: ?Value.ByteRange = null,
+        };
+    };
+    pub const no_sanitize_address = struct {
+        const gnu = "no_sanitize_address";
+        const declspec = "no_sanitize_address";
+    };
+    pub const no_sanitize_coverage = struct {
+        const gnu = "no_sanitize_coverage";
+    };
+    pub const no_sanitize_thread = struct {
+        const gnu = "no_sanitize_thread";
+    };
+    pub const no_sanitize_undefined = struct {
+        const gnu = "no_sanitize_undefined";
+    };
+    pub const no_split_stack = struct {
+        const gnu = "no_split_stack";
+    };
+    pub const no_stack_limit = struct {
+        const gnu = "no_stack_limit";
+    };
+    pub const no_stack_protector = struct {
+        const gnu = "no_stack_protector";
+    };
+    pub const @"noalias" = struct {
+        const declspec = "noalias";
+    };
+    pub const noclone = struct {
+        const gnu = "noclone";
+    };
+    pub const nocommon = struct {
+        const gnu = "nocommon";
+    };
+    pub const nodiscard = struct {
+        const c2x = "nodiscard";
+    };
+    pub const noinit = struct {
+        const gnu = "noinit";
+    };
+    pub const @"noinline" = struct {
+        const gnu = "noinline";
+        const declspec = "noinline";
+    };
+    pub const noipa = struct {
+        const gnu = "noipa";
+    };
+    // TODO: arbitrary number of arguments
+    //    const nonnull = struct {
+    //        const gnu = "nonnull";
+    //        const Args = struct {
+    //            arg_index: []const u32,
+    //        };
+    //    };
+    pub const nonstring = struct {
+        const gnu = "nonstring";
+    };
+    pub const noplt = struct {
+        const gnu = "noplt";
+    };
+    pub const @"noreturn" = struct {
+        const gnu = "noreturn";
+        const c2x = "noreturn";
+        const declspec = "noreturn";
+    };
+    // TODO: union args ?
+    //    const optimize = struct {
+    //        const gnu = "optimize";
+    //        const Args = struct {
+    //            optimize, // u32 | []const u8 -- optimize?
+    //        };
+    //    };
+    pub const @"packed" = struct {
+        const gnu = "packed";
+    };
+    pub const patchable_function_entry = struct {
+        const gnu = "patchable_function_entry";
+    };
+    pub const persistent = struct {
+        const gnu = "persistent";
+    };
+    pub const process = struct {
+        const declspec = "process";
+    };
+    pub const pure = struct {
+        const gnu = "pure";
+    };
+    pub const reproducible = struct {
+        const c2x = "reproducible";
+    };
+    pub const restrict = struct {
+        const declspec = "restrict";
+    };
+    pub const retain = struct {
+        const gnu = "retain";
+    };
+    pub const returns_nonnull = struct {
+        const gnu = "returns_nonnull";
+    };
+    pub const returns_twice = struct {
+        const gnu = "returns_twice";
+    };
+    pub const safebuffers = struct {
+        const declspec = "safebuffers";
+    };
+    pub const scalar_storage_order = struct {
+        const gnu = "scalar_storage_order";
+        const Args = struct {
+            order: enum {
+                @"little-endian",
+                @"big-endian",
+
+                const opts = struct {
+                    const enum_kind = .string;
+                };
+            },
+        };
+    };
+    pub const section = struct {
+        const gnu = "section";
+        const Args = struct {
+            name: Value.ByteRange,
+        };
+    };
+    pub const selectany = struct {
+        const declspec = "selectany";
+    };
+    pub const sentinel = struct {
+        const gnu = "sentinel";
+        const Args = struct {
+            position: ?u32 = null,
+        };
+    };
+    pub const simd = struct {
+        const gnu = "simd";
+        const Args = struct {
+            mask: ?enum {
+                notinbranch,
+                inbranch,
+
+                const opts = struct {
+                    const enum_kind = .string;
+                };
+            } = null,
+        };
+    };
+    pub const spectre = struct {
+        const declspec = "spectre";
+        const Args = struct {
+            arg: enum {
+                nomitigation,
+
+                const opts = struct {
+                    const enum_kind = .identifier;
+                };
+            },
+        };
+    };
+    pub const stack_protect = struct {
+        const gnu = "stack_protect";
+    };
+    pub const symver = struct {
+        const gnu = "symver";
+        const Args = struct {
+            version: Value.ByteRange, // TODO: validate format "name2@nodename"
+        };
+    };
+    pub const target = struct {
+        const gnu = "target";
+        const Args = struct {
+            options: Value.ByteRange, // TODO: multiple arguments
+        };
+    };
+    pub const target_clones = struct {
+        const gnu = "target_clones";
+        const Args = struct {
+            options: Value.ByteRange, // TODO: multiple arguments
+        };
+    };
+    pub const thread = struct {
+        const declspec = "thread";
+    };
+    pub const tls_model = struct {
+        const gnu = "tls_model";
+        const Args = struct {
+            model: enum {
+                @"global-dynamic",
+                @"local-dynamic",
+                @"initial-exec",
+                @"local-exec",
+
+                const opts = struct {
+                    const enum_kind = .string;
+                };
+            },
+        };
+    };
+    pub const transparent_union = struct {
+        const gnu = "transparent_union";
+    };
+    pub const unavailable = struct {
+        const gnu = "unavailable";
+        const Args = struct {
+            msg: ?Value.ByteRange = null,
+            __name_tok: TokenIndex,
+        };
+    };
+    pub const uninitialized = struct {
+        const gnu = "uninitialized";
+    };
+    pub const unsequenced = struct {
+        const c2x = "unsequenced";
+    };
+    pub const unused = struct {
+        const gnu = "unused";
+        const c2x = "maybe_unused";
+    };
+    pub const used = struct {
+        const gnu = "used";
+    };
+    pub const uuid = struct {
+        const declspec = "uuid";
+        const Args = struct {
+            uuid: Value.ByteRange,
+        };
+    };
+    pub const vector_size = struct {
+        const gnu = "vector_size";
+        const Args = struct {
+            bytes: u32, // TODO: validate "The bytes argument must be a positive power-of-two multiple of the base type size"
+        };
+    };
+    pub const visibility = struct {
+        const gnu = "visibility";
+        const Args = struct {
+            visibility_type: enum {
+                default,
+                hidden,
+                internal,
+                protected,
+
+                const opts = struct {
+                    const enum_kind = .string;
+                };
+            },
+        };
+    };
+    pub const warn_if_not_aligned = struct {
+        const gnu = "warn_if_not_aligned";
+        const Args = struct {
+            alignment: Alignment,
+        };
+    };
+    pub const warn_unused_result = struct {
+        const gnu = "warn_unused_result";
+    };
+    pub const warning = struct {
+        const gnu = "warning";
+        const Args = struct {
+            msg: Value.ByteRange,
+            __name_tok: TokenIndex,
+        };
+    };
+    pub const weak = struct {
+        const gnu = "weak";
+    };
+    pub const weakref = struct {
+        const gnu = "weakref";
+        const Args = struct {
+            target: ?Value.ByteRange = null,
+        };
+    };
+    pub const zero_call_used_regs = struct {
+        const gnu = "zero_call_used_regs";
+        const Args = struct {
+            choice: enum {
+                skip,
+                used,
+                @"used-gpr",
+                @"used-arg",
+                @"used-gpr-arg",
+                all,
+                @"all-gpr",
+                @"all-arg",
+                @"all-gpr-arg",
+
+                const opts = struct {
+                    const enum_kind = .string;
+                };
+            },
+        };
+    };
+    pub const asm_label = struct {
+        const Args = struct {
+            name: Value.ByteRange,
+        };
+    };
+    pub const calling_convention = struct {
+        const Args = struct {
+            cc: CallingConvention,
+        };
+    };
+};
+
+pub const Tag = std.meta.DeclEnum(attributes);
+
+pub const Arguments = blk: {
+    const decls = @typeInfo(attributes).Struct.decls;
+    var union_fields: [decls.len]ZigType.UnionField = undefined;
+    inline for (decls, &union_fields) |decl, *field| {
+        field.* = .{
+            .name = decl.name,
+            .type = if (@hasDecl(@field(attributes, decl.name), "Args")) @field(attributes, decl.name).Args else void,
+            .alignment = 0,
+        };
+    }
+
+    break :blk @Type(.{
+        .Union = .{
+            .layout = .Auto,
+            .tag_type = null,
+            .fields = &union_fields,
+            .decls = &.{},
+        },
+    });
+};
+
+pub fn ArgumentsForTag(comptime tag: Tag) type {
+    const decl = @typeInfo(attributes).Struct.decls[@intFromEnum(tag)];
+    return if (@hasDecl(@field(attributes, decl.name), "Args")) @field(attributes, decl.name).Args else void;
+}
+
+pub fn initArguments(tag: Tag, name_tok: TokenIndex) Arguments {
+    switch (tag) {
+        inline else => |arg_tag| {
+            const union_element = @field(attributes, @tagName(arg_tag));
+            const has_args = @hasDecl(union_element, "Args");
+            const init = if (has_args) std.mem.zeroInit(union_element.Args, .{}) else {};
+            var args = @unionInit(Arguments, @tagName(arg_tag), init);
+            if (has_args and @hasField(@field(attributes, @tagName(arg_tag)).Args, "__name_tok")) {
+                @field(args, @tagName(arg_tag)).__name_tok = name_tok;
+            }
+            return args;
+        },
+    }
+}
+
+pub fn fromString(kind: Kind, namespace: ?[]const u8, name: []const u8) ?Tag {
+    return switch (kind) {
+        .c2x => fromStringC2X(namespace, name),
+        .declspec => fromStringDeclspec(name),
+        .gnu => fromStringGnu(name),
+    };
+}
+
+fn fromStringGnu(name: []const u8) ?Tag {
+    const normalized = normalize(name);
+    const decls = @typeInfo(attributes).Struct.decls;
+    @setEvalBranchQuota(3000);
+    inline for (decls, 0..) |decl, i| {
+        if (@hasDecl(@field(attributes, decl.name), "gnu")) {
+            if (mem.eql(u8, @field(attributes, decl.name).gnu, normalized)) {
+                return @enumFromInt(i);
+            }
+        }
+    }
+    return null;
+}
+
+fn fromStringC2X(namespace: ?[]const u8, name: []const u8) ?Tag {
+    const normalized = normalize(name);
+    if (namespace) |ns| {
+        const normalized_ns = normalize(ns);
+        if (mem.eql(u8, normalized_ns, "gnu")) {
+            return fromStringGnu(normalized);
+        }
+        return null;
+    }
+    const decls = @typeInfo(attributes).Struct.decls;
+    inline for (decls, 0..) |decl, i| {
+        if (@hasDecl(@field(attributes, decl.name), "c2x")) {
+            if (mem.eql(u8, @field(attributes, decl.name).c2x, normalized)) {
+                return @enumFromInt(i);
+            }
+        }
+    }
+    return null;
+}
+
+fn fromStringDeclspec(name: []const u8) ?Tag {
+    const decls = @typeInfo(attributes).Struct.decls;
+    inline for (decls, 0..) |decl, i| {
+        if (@hasDecl(@field(attributes, decl.name), "declspec")) {
+            if (mem.eql(u8, @field(attributes, decl.name).declspec, name)) {
+                return @enumFromInt(i);
+            }
+        }
+    }
+    return null;
+}
+
+fn normalize(name: []const u8) []const u8 {
+    if (name.len >= 4 and mem.startsWith(u8, name, "__") and mem.endsWith(u8, name, "__")) {
+        return name[2 .. name.len - 2];
+    }
+    return name;
+}
+
+fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []const u8) !void {
+    const strings_top = p.strings.items.len;
+    defer p.strings.items.len = strings_top;
+
+    try p.strings.writer().print("attribute '{s}' ignored on {s}", .{ @tagName(attr), context });
+    const str = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+    try p.errStr(.ignored_attribute, tok, str);
+}
+
+pub const applyParameterAttributes = applyVariableAttributes;
+pub fn applyVariableAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type {
+    const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+    const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+    p.attr_application_buf.items.len = 0;
+    var base_ty = ty;
+    if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
+    var common = false;
+    var nocommon = false;
+    for (attrs, toks) |attr, tok| switch (attr.tag) {
+        // zig fmt: off
+        .alias, .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .weak, .used,
+        .noinit, .retain, .persistent, .section, .mode, .asm_label,
+         => try p.attr_application_buf.append(p.gpa, attr),
+        // zig fmt: on
+        .common => if (nocommon) {
+            try p.errTok(.ignore_common, tok);
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+            common = true;
+        },
+        .nocommon => if (common) {
+            try p.errTok(.ignore_nocommon, tok);
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+            nocommon = true;
+        },
+        .vector_size => try attr.applyVectorSize(p, tok, &base_ty),
+        .aligned => try attr.applyAligned(p, base_ty, tag),
+        .nonstring => if (!base_ty.isArray() or !(base_ty.is(.char) or base_ty.is(.uchar) or base_ty.is(.schar))) {
+            try p.errStr(.non_string_ignored, tok, try p.typeStr(ty));
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+        },
+        .uninitialized => if (p.func.ty == null) {
+            try p.errStr(.local_variable_attribute, tok, "uninitialized");
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+        },
+        .cleanup => if (p.func.ty == null) {
+            try p.errStr(.local_variable_attribute, tok, "cleanup");
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+        },
+        .alloc_size,
+        .copy,
+        .tls_model,
+        .visibility,
+        => std.debug.panic("apply variable attribute {s}", .{@tagName(attr.tag)}),
+        else => try ignoredAttrErr(p, tok, attr.tag, "variables"),
+    };
+    const existing = ty.getAttributes();
+    if (existing.len == 0 and p.attr_application_buf.items.len == 0) return base_ty;
+    if (existing.len == 0) return base_ty.withAttributes(p.arena, p.attr_application_buf.items);
+
+    const attributed_type = try Type.Attributed.create(p.arena, base_ty, existing, p.attr_application_buf.items);
+    return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type } };
+}
+
+pub fn applyFieldAttributes(p: *Parser, field_ty: *Type, attr_buf_start: usize) ![]const Attribute {
+    const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+    const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+    p.attr_application_buf.items.len = 0;
+    for (attrs, toks) |attr, tok| switch (attr.tag) {
+        // zig fmt: off
+        .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode,
+        => try p.attr_application_buf.append(p.gpa, attr),
+        // zig fmt: on
+        .vector_size => try attr.applyVectorSize(p, tok, field_ty),
+        .aligned => try attr.applyAligned(p, field_ty.*, null),
+        else => try ignoredAttrErr(p, tok, attr.tag, "fields"),
+    };
+    if (p.attr_application_buf.items.len == 0) return &[0]Attribute{};
+    return p.arena.dupe(Attribute, p.attr_application_buf.items);
+}
+
+pub fn applyTypeAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type {
+    const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+    const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+    p.attr_application_buf.items.len = 0;
+    var base_ty = ty;
+    if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
+    for (attrs, toks) |attr, tok| switch (attr.tag) {
+        // zig fmt: off
+        .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode,
+         => try p.attr_application_buf.append(p.gpa, attr),
+        // zig fmt: on
+        .transparent_union => try attr.applyTransparentUnion(p, tok, base_ty),
+        .vector_size => try attr.applyVectorSize(p, tok, &base_ty),
+        .aligned => try attr.applyAligned(p, base_ty, tag),
+        .designated_init => if (base_ty.is(.@"struct")) {
+            try p.attr_application_buf.append(p.gpa, attr);
+        } else {
+            try p.errTok(.designated_init_invalid, tok);
+        },
+        .alloc_size,
+        .copy,
+        .scalar_storage_order,
+        .nonstring,
+        => std.debug.panic("apply type attribute {s}", .{@tagName(attr.tag)}),
+        else => try ignoredAttrErr(p, tok, attr.tag, "types"),
+    };
+
+    const existing = ty.getAttributes();
+    // TODO: the alignment annotation on a type should override
+    // the decl it refers to. This might not be true for others.  Maybe bug.
+
+    // if there are annotations on this type def use those.
+    if (p.attr_application_buf.items.len > 0) {
+        return try base_ty.withAttributes(p.arena, p.attr_application_buf.items);
+    } else if (existing.len > 0) {
+        // else use the ones on the typedef decl we were refering to.
+        return try base_ty.withAttributes(p.arena, existing);
+    }
+    return base_ty;
+}
+
+pub fn applyFunctionAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
+    const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+    const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+    p.attr_application_buf.items.len = 0;
+    var base_ty = ty;
+    if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
+    var hot = false;
+    var cold = false;
+    var @"noinline" = false;
+    var always_inline = false;
+    for (attrs, toks) |attr, tok| switch (attr.tag) {
+        // zig fmt: off
+        .noreturn, .unused, .used, .warning, .deprecated, .unavailable, .weak, .pure, .leaf,
+        .@"const", .warn_unused_result, .section, .returns_nonnull, .returns_twice, .@"error",
+        .externally_visible, .retain, .flatten, .gnu_inline, .alias, .asm_label, .nodiscard,
+        .reproducible, .unsequenced,
+         => try p.attr_application_buf.append(p.gpa, attr),
+        // zig fmt: on
+        .hot => if (cold) {
+            try p.errTok(.ignore_hot, tok);
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+            hot = true;
+        },
+        .cold => if (hot) {
+            try p.errTok(.ignore_cold, tok);
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+            cold = true;
+        },
+        .always_inline => if (@"noinline") {
+            try p.errTok(.ignore_always_inline, tok);
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+            always_inline = true;
+        },
+        .@"noinline" => if (always_inline) {
+            try p.errTok(.ignore_noinline, tok);
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+            @"noinline" = true;
+        },
+        .aligned => try attr.applyAligned(p, base_ty, null),
+        .format => try attr.applyFormat(p, base_ty),
+        .calling_convention => switch (attr.args.calling_convention.cc) {
+            .C => continue,
+            .stdcall, .thiscall => switch (p.comp.target.cpu.arch) {
+                .x86 => try p.attr_application_buf.append(p.gpa, attr),
+                else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?),
+            },
+            .vectorcall => switch (p.comp.target.cpu.arch) {
+                .x86, .aarch64, .aarch64_be, .aarch64_32 => try p.attr_application_buf.append(p.gpa, attr),
+                else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?),
+            },
+        },
+        .access,
+        .alloc_align,
+        .alloc_size,
+        .artificial,
+        .assume_aligned,
+        .constructor,
+        .copy,
+        .destructor,
+        .format_arg,
+        .ifunc,
+        .interrupt,
+        .interrupt_handler,
+        .malloc,
+        .no_address_safety_analysis,
+        .no_icf,
+        .no_instrument_function,
+        .no_profile_instrument_function,
+        .no_reorder,
+        .no_sanitize,
+        .no_sanitize_address,
+        .no_sanitize_coverage,
+        .no_sanitize_thread,
+        .no_sanitize_undefined,
+        .no_split_stack,
+        .no_stack_limit,
+        .no_stack_protector,
+        .noclone,
+        .noipa,
+        // .nonnull,
+        .noplt,
+        // .optimize,
+        .patchable_function_entry,
+        .sentinel,
+        .simd,
+        .stack_protect,
+        .symver,
+        .target,
+        .target_clones,
+        .visibility,
+        .weakref,
+        .zero_call_used_regs,
+        => std.debug.panic("apply type attribute {s}", .{@tagName(attr.tag)}),
+        else => try ignoredAttrErr(p, tok, attr.tag, "functions"),
+    };
+    return ty.withAttributes(p.arena, p.attr_application_buf.items);
+}
+
+pub fn applyLabelAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
+    const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+    const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+    p.attr_application_buf.items.len = 0;
+    var hot = false;
+    var cold = false;
+    for (attrs, toks) |attr, tok| switch (attr.tag) {
+        .unused => try p.attr_application_buf.append(p.gpa, attr),
+        .hot => if (cold) {
+            try p.errTok(.ignore_hot, tok);
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+            hot = true;
+        },
+        .cold => if (hot) {
+            try p.errTok(.ignore_cold, tok);
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+            cold = true;
+        },
+        else => try ignoredAttrErr(p, tok, attr.tag, "labels"),
+    };
+    return ty.withAttributes(p.arena, p.attr_application_buf.items);
+}
+
+pub fn applyStatementAttributes(p: *Parser, ty: Type, expr_start: TokenIndex, attr_buf_start: usize) !Type {
+    const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+    const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+    p.attr_application_buf.items.len = 0;
+    for (attrs, toks) |attr, tok| switch (attr.tag) {
+        .fallthrough => if (p.tok_ids[p.tok_i] != .keyword_case and p.tok_ids[p.tok_i] != .keyword_default) {
+            // TODO: this condition is not completely correct; the last statement of a compound
+            // statement is also valid if it precedes a switch label (so intervening '}' are ok,
+            // but only if they close a compound statement)
+            try p.errTok(.invalid_fallthrough, expr_start);
+        } else {
+            try p.attr_application_buf.append(p.gpa, attr);
+        },
+        else => try p.errStr(.cannot_apply_attribute_to_statement, tok, @tagName(attr.tag)),
+    };
+    return ty.withAttributes(p.arena, p.attr_application_buf.items);
+}
+
+pub fn applyEnumeratorAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
+    const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
+    const toks = p.attr_buf.items(.tok)[attr_buf_start..];
+    p.attr_application_buf.items.len = 0;
+    for (attrs, toks) |attr, tok| switch (attr.tag) {
+        .deprecated, .unavailable => try p.attr_application_buf.append(p.gpa, attr),
+        else => try ignoredAttrErr(p, tok, attr.tag, "enums"),
+    };
+    return ty.withAttributes(p.arena, p.attr_application_buf.items);
+}
+
+fn applyAligned(attr: Attribute, p: *Parser, ty: Type, tag: ?Diagnostics.Tag) !void {
+    const base = ty.canonicalize(.standard);
+    if (attr.args.aligned.alignment) |alignment| alignas: {
+        if (attr.syntax != .keyword) break :alignas;
+
+        const align_tok = attr.args.aligned.__name_tok;
+        if (tag) |t| try p.errTok(t, align_tok);
+
+        const default_align = base.alignof(p.comp);
+        if (ty.isFunc()) {
+            try p.errTok(.alignas_on_func, align_tok);
+        } else if (alignment.requested < default_align) {
+            try p.errExtra(.minimum_alignment, align_tok, .{ .unsigned = default_align });
+        }
+    }
+    try p.attr_application_buf.append(p.gpa, attr);
+}
+
+fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, ty: Type) !void {
+    const union_ty = ty.get(.@"union") orelse {
+        return p.errTok(.transparent_union_wrong_type, tok);
+    };
+    // TODO validate union defined at end
+    if (union_ty.data.record.isIncomplete()) return;
+    const fields = union_ty.data.record.fields;
+    if (fields.len == 0) {
+        return p.errTok(.transparent_union_one_field, tok);
+    }
+    const first_field_size = fields[0].ty.bitSizeof(p.comp).?;
+    for (fields[1..]) |field| {
+        const field_size = field.ty.bitSizeof(p.comp).?;
+        if (field_size == first_field_size) continue;
+        const mapper = p.comp.string_interner.getSlowTypeMapper();
+        const str = try std.fmt.allocPrint(p.comp.diag.arena.allocator(), "'{s}' ({d}", .{ mapper.lookup(field.name), field_size });
+        try p.errStr(.transparent_union_size, field.name_tok, str);
+        return p.errExtra(.transparent_union_size_note, fields[0].name_tok, .{ .unsigned = first_field_size });
+    }
+
+    try p.attr_application_buf.append(p.gpa, attr);
+}
+
+fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, ty: *Type) !void {
+    if (!(ty.isInt() or ty.isFloat()) or !ty.isReal()) {
+        const orig_ty = try p.typeStr(ty.*);
+        ty.* = Type.invalid;
+        return p.errStr(.invalid_vec_elem_ty, tok, orig_ty);
+    }
+    const vec_bytes = attr.args.vector_size.bytes;
+    const ty_size = ty.sizeof(p.comp).?;
+    if (vec_bytes % ty_size != 0) {
+        return p.errTok(.vec_size_not_multiple, tok);
+    }
+    const vec_size = vec_bytes / ty_size;
+
+    const arr_ty = try p.arena.create(Type.Array);
+    arr_ty.* = .{ .elem = ty.*, .len = vec_size };
+    ty.* = Type{
+        .specifier = .vector,
+        .data = .{ .array = arr_ty },
+    };
+}
+
+fn applyFormat(attr: Attribute, p: *Parser, ty: Type) !void {
+    // TODO validate
+    _ = ty;
+    try p.attr_application_buf.append(p.gpa, attr);
+}
deps/aro/Builtins.zig
@@ -0,0 +1,337 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const Type = @import("Type.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+const TypeDescription = @import("builtins/TypeDescription.zig");
+const target_util = @import("target.zig");
+const StringId = @import("StringInterner.zig").StringId;
+const LangOpts = @import("LangOpts.zig");
+const Parser = @import("Parser.zig");
+
+const Builtins = @This();
+
+const Expanded = struct {
+    ty: Type,
+    builtin: BuiltinFunction,
+};
+
+const NameToTypeMap = std.StringHashMapUnmanaged(Type);
+
+_name_to_type_map: NameToTypeMap = .{},
+
+pub fn deinit(b: *Builtins, gpa: std.mem.Allocator) void {
+    b._name_to_type_map.deinit(gpa);
+}
+
+fn specForSize(comp: *const Compilation, size_bits: u32) Type.Builder.Specifier {
+    var ty = Type{ .specifier = .short };
+    if (ty.sizeof(comp).? * 8 == size_bits) return .short;
+
+    ty.specifier = .int;
+    if (ty.sizeof(comp).? * 8 == size_bits) return .int;
+
+    ty.specifier = .long;
+    if (ty.sizeof(comp).? * 8 == size_bits) return .long;
+
+    ty.specifier = .long_long;
+    if (ty.sizeof(comp).? * 8 == size_bits) return .long_long;
+
+    unreachable;
+}
+
+fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *const Compilation, allocator: std.mem.Allocator) !Type {
+    var builder: Type.Builder = .{ .error_on_invalid = true };
+    var require_native_int32 = false;
+    var require_native_int64 = false;
+    for (desc.prefix) |prefix| {
+        switch (prefix) {
+            .L => builder.combine(undefined, .long, 0) catch unreachable,
+            .LL => {
+                builder.combine(undefined, .long, 0) catch unreachable;
+                builder.combine(undefined, .long, 0) catch unreachable;
+            },
+            .LLL => {
+                switch (builder.specifier) {
+                    .none => builder.specifier = .int128,
+                    .signed => builder.specifier = .sint128,
+                    .unsigned => builder.specifier = .uint128,
+                    else => unreachable,
+                }
+            },
+            .Z => require_native_int32 = true,
+            .W => require_native_int64 = true,
+            .N => {
+                std.debug.assert(desc.spec == .i);
+                if (!target_util.isLP64(comp.target)) {
+                    builder.combine(undefined, .long, 0) catch unreachable;
+                }
+            },
+            .O => {
+                builder.combine(undefined, .long, 0) catch unreachable;
+                if (comp.target.os.tag != .opencl) {
+                    builder.combine(undefined, .long, 0) catch unreachable;
+                }
+            },
+            .S => builder.combine(undefined, .signed, 0) catch unreachable,
+            .U => builder.combine(undefined, .unsigned, 0) catch unreachable,
+            .I => {
+                // Todo: compile-time constant integer
+            },
+        }
+    }
+    switch (desc.spec) {
+        .v => builder.combine(undefined, .void, 0) catch unreachable,
+        .b => builder.combine(undefined, .bool, 0) catch unreachable,
+        .c => builder.combine(undefined, .char, 0) catch unreachable,
+        .s => builder.combine(undefined, .short, 0) catch unreachable,
+        .i => {
+            if (require_native_int32) {
+                builder.specifier = specForSize(comp, 32);
+            } else if (require_native_int64) {
+                builder.specifier = specForSize(comp, 64);
+            } else {
+                switch (builder.specifier) {
+                    .int128, .sint128, .uint128 => {},
+                    else => builder.combine(undefined, .int, 0) catch unreachable,
+                }
+            }
+        },
+        .h => builder.combine(undefined, .fp16, 0) catch unreachable,
+        .x => {
+            // Todo: _Float16
+            return .{ .specifier = .invalid };
+        },
+        .y => {
+            // Todo: __bf16
+            return .{ .specifier = .invalid };
+        },
+        .f => builder.combine(undefined, .float, 0) catch unreachable,
+        .d => {
+            if (builder.specifier == .long_long) {
+                builder.specifier = .float128;
+            } else {
+                builder.combine(undefined, .double, 0) catch unreachable;
+            }
+        },
+        .z => {
+            std.debug.assert(builder.specifier == .none);
+            builder.specifier = Type.Builder.fromType(comp.types.size);
+        },
+        .w => {
+            std.debug.assert(builder.specifier == .none);
+            builder.specifier = Type.Builder.fromType(comp.types.wchar);
+        },
+        .F => {
+            std.debug.assert(builder.specifier == .none);
+            builder.specifier = Type.Builder.fromType(comp.types.ns_constant_string.ty);
+        },
+        .a => {
+            std.debug.assert(builder.specifier == .none);
+            std.debug.assert(desc.suffix.len == 0);
+            builder.specifier = Type.Builder.fromType(comp.types.va_list);
+        },
+        .A => {
+            std.debug.assert(builder.specifier == .none);
+            std.debug.assert(desc.suffix.len == 0);
+            var va_list = comp.types.va_list;
+            if (va_list.isArray()) va_list.decayArray();
+            builder.specifier = Type.Builder.fromType(va_list);
+        },
+        .V => |element_count| {
+            std.debug.assert(desc.suffix.len == 0);
+            const child_desc = it.next().?;
+            const child_ty = try createType(child_desc, undefined, comp, allocator);
+            const arr_ty = try allocator.create(Type.Array);
+            arr_ty.* = .{
+                .len = element_count,
+                .elem = child_ty,
+            };
+            const vector_ty = .{ .specifier = .vector, .data = .{ .array = arr_ty } };
+            builder.specifier = Type.Builder.fromType(vector_ty);
+        },
+        .q => {
+            // Todo: scalable vector
+            return .{ .specifier = .invalid };
+        },
+        .E => {
+            // Todo: ext_vector (OpenCL vector)
+            return .{ .specifier = .invalid };
+        },
+        .X => |child| {
+            builder.combine(undefined, .complex, 0) catch unreachable;
+            switch (child) {
+                .float => builder.combine(undefined, .float, 0) catch unreachable,
+                .double => builder.combine(undefined, .double, 0) catch unreachable,
+                .longdouble => {
+                    builder.combine(undefined, .long, 0) catch unreachable;
+                    builder.combine(undefined, .double, 0) catch unreachable;
+                },
+            }
+        },
+        .Y => {
+            std.debug.assert(builder.specifier == .none);
+            std.debug.assert(desc.suffix.len == 0);
+            builder.specifier = Type.Builder.fromType(comp.types.ptrdiff);
+        },
+        .P => {
+            std.debug.assert(builder.specifier == .none);
+            if (comp.types.file.specifier == .invalid) {
+                return comp.types.file;
+            }
+            builder.specifier = Type.Builder.fromType(comp.types.file);
+        },
+        .J => {
+            std.debug.assert(builder.specifier == .none);
+            std.debug.assert(desc.suffix.len == 0);
+            if (comp.types.jmp_buf.specifier == .invalid) {
+                return comp.types.jmp_buf;
+            }
+            builder.specifier = Type.Builder.fromType(comp.types.jmp_buf);
+        },
+        .SJ => {
+            std.debug.assert(builder.specifier == .none);
+            std.debug.assert(desc.suffix.len == 0);
+            if (comp.types.sigjmp_buf.specifier == .invalid) {
+                return comp.types.sigjmp_buf;
+            }
+            builder.specifier = Type.Builder.fromType(comp.types.sigjmp_buf);
+        },
+        .K => {
+            std.debug.assert(builder.specifier == .none);
+            if (comp.types.ucontext_t.specifier == .invalid) {
+                return comp.types.ucontext_t;
+            }
+            builder.specifier = Type.Builder.fromType(comp.types.ucontext_t);
+        },
+        .p => {
+            std.debug.assert(builder.specifier == .none);
+            std.debug.assert(desc.suffix.len == 0);
+            builder.specifier = Type.Builder.fromType(comp.types.pid_t);
+        },
+        .@"!" => return .{ .specifier = .invalid },
+    }
+    for (desc.suffix) |suffix| {
+        switch (suffix) {
+            .@"*" => |address_space| {
+                _ = address_space; // TODO: handle address space
+                const elem_ty = try allocator.create(Type);
+                elem_ty.* = builder.finish(undefined) catch unreachable;
+                const ty = Type{
+                    .specifier = .pointer,
+                    .data = .{ .sub_type = elem_ty },
+                };
+                builder.qual = .{};
+                builder.specifier = Type.Builder.fromType(ty);
+            },
+            .C => builder.qual.@"const" = 0,
+            .D => builder.qual.@"volatile" = 0,
+            .R => builder.qual.restrict = 0,
+        }
+    }
+    return builder.finish(undefined) catch unreachable;
+}
+
+fn createBuiltin(comp: *const Compilation, builtin: BuiltinFunction, type_arena: std.mem.Allocator) !Type {
+    var it = TypeDescription.TypeIterator.init(builtin.param_str);
+
+    const ret_ty_desc = it.next().?;
+    if (ret_ty_desc.spec == .@"!") {
+        // Todo: handle target-dependent definition
+    }
+    const ret_ty = try createType(ret_ty_desc, &it, comp, type_arena);
+    var param_count: usize = 0;
+    var params: [BuiltinFunction.MaxParamCount]Type.Func.Param = undefined;
+    while (it.next()) |desc| : (param_count += 1) {
+        params[param_count] = .{ .name_tok = 0, .ty = try createType(desc, &it, comp, type_arena), .name = .empty };
+    }
+
+    const duped_params = try type_arena.dupe(Type.Func.Param, params[0..param_count]);
+    const func = try type_arena.create(Type.Func);
+
+    func.* = .{
+        .return_type = ret_ty,
+        .params = duped_params,
+    };
+    return .{
+        .specifier = if (builtin.isVarArgs()) .var_args_func else .func,
+        .data = .{ .func = func },
+    };
+}
+
+/// Asserts that the builtin has already been created
+pub fn lookup(b: *const Builtins, name: []const u8) Expanded {
+    @setEvalBranchQuota(10_000);
+    const builtin = BuiltinFunction.fromTag(std.meta.stringToEnum(BuiltinFunction.Tag, name).?);
+    const ty = b._name_to_type_map.get(name).?;
+    return .{
+        .builtin = builtin,
+        .ty = ty,
+    };
+}
+
+pub fn getOrCreate(b: *Builtins, comp: *Compilation, name: []const u8, type_arena: std.mem.Allocator) !?Expanded {
+    const ty = b._name_to_type_map.get(name) orelse {
+        @setEvalBranchQuota(10_000);
+        const tag = std.meta.stringToEnum(BuiltinFunction.Tag, name) orelse return null;
+        const builtin = BuiltinFunction.fromTag(tag);
+        if (!comp.hasBuiltinFunction(builtin)) return null;
+
+        try b._name_to_type_map.ensureUnusedCapacity(comp.gpa, 1);
+        const ty = try createBuiltin(comp, builtin, type_arena);
+        b._name_to_type_map.putAssumeCapacity(name, ty);
+
+        return .{
+            .builtin = builtin,
+            .ty = ty,
+        };
+    };
+    const builtin = BuiltinFunction.fromTag(std.meta.stringToEnum(BuiltinFunction.Tag, name).?);
+    return .{
+        .builtin = builtin,
+        .ty = ty,
+    };
+}
+
+test "All builtins" {
+    var comp = Compilation.init(std.testing.allocator);
+    defer comp.deinit();
+    _ = try comp.generateBuiltinMacros();
+    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
+    defer arena.deinit();
+
+    const type_arena = arena.allocator();
+
+    for (0..@typeInfo(BuiltinFunction.Tag).Enum.fields.len) |i| {
+        const tag: BuiltinFunction.Tag = @enumFromInt(i);
+        const name = @tagName(tag);
+        if (try comp.builtins.getOrCreate(&comp, name, type_arena)) |func_ty| {
+            const get_again = (try comp.builtins.getOrCreate(&comp, name, std.testing.failing_allocator)).?;
+            const found_by_lookup = comp.builtins.lookup(name);
+            try std.testing.expectEqual(func_ty.builtin.tag, get_again.builtin.tag);
+            try std.testing.expectEqual(func_ty.builtin.tag, found_by_lookup.builtin.tag);
+        }
+    }
+}
+
+test "Allocation failures" {
+    const Test = struct {
+        fn testOne(allocator: std.mem.Allocator) !void {
+            var comp = Compilation.init(allocator);
+            defer comp.deinit();
+            _ = try comp.generateBuiltinMacros();
+            var arena = std.heap.ArenaAllocator.init(comp.gpa);
+            defer arena.deinit();
+
+            const type_arena = arena.allocator();
+
+            const num_builtins = 40;
+            for (0..num_builtins) |i| {
+                const tag: BuiltinFunction.Tag = @enumFromInt(i);
+                const name = @tagName(tag);
+                _ = try comp.builtins.getOrCreate(&comp, name, type_arena);
+            }
+        }
+    };
+
+    try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.testOne, .{});
+}
deps/aro/CharInfo.zig
@@ -0,0 +1,487 @@
+//! This module provides functions for classifying characters according to
+//! various C standards. All classification routines *do not* consider
+//! characters from the basic character set; it is assumed those will be
+//! checked separately
+
+const assert = @import("std").debug.assert;
+
+/// C11 Standard Annex D
+pub fn isC11IdChar(codepoint: u21) bool {
+    assert(codepoint > 0x7F);
+    return switch (codepoint) {
+        // 1
+        0x00A8,
+        0x00AA,
+        0x00AD,
+        0x00AF,
+        0x00B2...0x00B5,
+        0x00B7...0x00BA,
+        0x00BC...0x00BE,
+        0x00C0...0x00D6,
+        0x00D8...0x00F6,
+        0x00F8...0x00FF,
+
+        // 2
+        0x0100...0x167F,
+        0x1681...0x180D,
+        0x180F...0x1FFF,
+
+        // 3
+        0x200B...0x200D,
+        0x202A...0x202E,
+        0x203F...0x2040,
+        0x2054,
+        0x2060...0x206F,
+
+        // 4
+        0x2070...0x218F,
+        0x2460...0x24FF,
+        0x2776...0x2793,
+        0x2C00...0x2DFF,
+        0x2E80...0x2FFF,
+
+        // 5
+        0x3004...0x3007,
+        0x3021...0x302F,
+        0x3031...0x303F,
+
+        // 6
+        0x3040...0xD7FF,
+
+        // 7
+        0xF900...0xFD3D,
+        0xFD40...0xFDCF,
+        0xFDF0...0xFE44,
+        0xFE47...0xFFFD,
+
+        // 8
+        0x10000...0x1FFFD,
+        0x20000...0x2FFFD,
+        0x30000...0x3FFFD,
+        0x40000...0x4FFFD,
+        0x50000...0x5FFFD,
+        0x60000...0x6FFFD,
+        0x70000...0x7FFFD,
+        0x80000...0x8FFFD,
+        0x90000...0x9FFFD,
+        0xA0000...0xAFFFD,
+        0xB0000...0xBFFFD,
+        0xC0000...0xCFFFD,
+        0xD0000...0xDFFFD,
+        0xE0000...0xEFFFD,
+        => true,
+        else => false,
+    };
+}
+
+/// C99 Standard Annex D
+pub fn isC99IdChar(codepoint: u21) bool {
+    assert(codepoint > 0x7F);
+    return switch (codepoint) {
+        // Latin
+        0x00AA,
+        0x00BA,
+        0x00C0...0x00D6,
+        0x00D8...0x00F6,
+        0x00F8...0x01F5,
+        0x01FA...0x0217,
+        0x0250...0x02A8,
+        0x1E00...0x1E9B,
+        0x1EA0...0x1EF9,
+        0x207F,
+
+        // Greek
+        0x0386,
+        0x0388...0x038A,
+        0x038C,
+        0x038E...0x03A1,
+        0x03A3...0x03CE,
+        0x03D0...0x03D6,
+        0x03DA,
+        0x03DC,
+        0x03DE,
+        0x03E0,
+        0x03E2...0x03F3,
+        0x1F00...0x1F15,
+        0x1F18...0x1F1D,
+        0x1F20...0x1F45,
+        0x1F48...0x1F4D,
+        0x1F50...0x1F57,
+        0x1F59,
+        0x1F5B,
+        0x1F5D,
+        0x1F5F...0x1F7D,
+        0x1F80...0x1FB4,
+        0x1FB6...0x1FBC,
+        0x1FC2...0x1FC4,
+        0x1FC6...0x1FCC,
+        0x1FD0...0x1FD3,
+        0x1FD6...0x1FDB,
+        0x1FE0...0x1FEC,
+        0x1FF2...0x1FF4,
+        0x1FF6...0x1FFC,
+
+        // Cyrillic
+        0x0401...0x040C,
+        0x040E...0x044F,
+        0x0451...0x045C,
+        0x045E...0x0481,
+        0x0490...0x04C4,
+        0x04C7...0x04C8,
+        0x04CB...0x04CC,
+        0x04D0...0x04EB,
+        0x04EE...0x04F5,
+        0x04F8...0x04F9,
+
+        // Armenian
+        0x0531...0x0556,
+        0x0561...0x0587,
+
+        // Hebrew
+        0x05B0...0x05B9,
+        0x05BB...0x05BD,
+        0x05BF,
+        0x05C1...0x05C2,
+        0x05D0...0x05EA,
+        0x05F0...0x05F2,
+
+        // Arabic
+        0x0621...0x063A,
+        0x0640...0x0652,
+        0x0670...0x06B7,
+        0x06BA...0x06BE,
+        0x06C0...0x06CE,
+        0x06D0...0x06DC,
+        0x06E5...0x06E8,
+        0x06EA...0x06ED,
+
+        // Devanagari
+        0x0901...0x0903,
+        0x0905...0x0939,
+        0x093E...0x094D,
+        0x0950...0x0952,
+        0x0958...0x0963,
+
+        // Bengali
+        0x0981...0x0983,
+        0x0985...0x098C,
+        0x098F...0x0990,
+        0x0993...0x09A8,
+        0x09AA...0x09B0,
+        0x09B2,
+        0x09B6...0x09B9,
+        0x09BE...0x09C4,
+        0x09C7...0x09C8,
+        0x09CB...0x09CD,
+        0x09DC...0x09DD,
+        0x09DF...0x09E3,
+        0x09F0...0x09F1,
+
+        // Gurmukhi
+        0x0A02,
+        0x0A05...0x0A0A,
+        0x0A0F...0x0A10,
+        0x0A13...0x0A28,
+        0x0A2A...0x0A30,
+        0x0A32...0x0A33,
+        0x0A35...0x0A36,
+        0x0A38...0x0A39,
+        0x0A3E...0x0A42,
+        0x0A47...0x0A48,
+        0x0A4B...0x0A4D,
+        0x0A59...0x0A5C,
+        0x0A5E,
+        0x0A74,
+
+        // Gujarati
+        0x0A81...0x0A83,
+        0x0A85...0x0A8B,
+        0x0A8D,
+        0x0A8F...0x0A91,
+        0x0A93...0x0AA8,
+        0x0AAA...0x0AB0,
+        0x0AB2...0x0AB3,
+        0x0AB5...0x0AB9,
+        0x0ABD...0x0AC5,
+        0x0AC7...0x0AC9,
+        0x0ACB...0x0ACD,
+        0x0AD0,
+        0x0AE0,
+
+        // Oriya
+        0x0B01...0x0B03,
+        0x0B05...0x0B0C,
+        0x0B0F...0x0B10,
+        0x0B13...0x0B28,
+        0x0B2A...0x0B30,
+        0x0B32...0x0B33,
+        0x0B36...0x0B39,
+        0x0B3E...0x0B43,
+        0x0B47...0x0B48,
+        0x0B4B...0x0B4D,
+        0x0B5C...0x0B5D,
+        0x0B5F...0x0B61,
+
+        // Tamil
+        0x0B82...0x0B83,
+        0x0B85...0x0B8A,
+        0x0B8E...0x0B90,
+        0x0B92...0x0B95,
+        0x0B99...0x0B9A,
+        0x0B9C,
+        0x0B9E...0x0B9F,
+        0x0BA3...0x0BA4,
+        0x0BA8...0x0BAA,
+        0x0BAE...0x0BB5,
+        0x0BB7...0x0BB9,
+        0x0BBE...0x0BC2,
+        0x0BC6...0x0BC8,
+        0x0BCA...0x0BCD,
+
+        // Telugu
+        0x0C01...0x0C03,
+        0x0C05...0x0C0C,
+        0x0C0E...0x0C10,
+        0x0C12...0x0C28,
+        0x0C2A...0x0C33,
+        0x0C35...0x0C39,
+        0x0C3E...0x0C44,
+        0x0C46...0x0C48,
+        0x0C4A...0x0C4D,
+        0x0C60...0x0C61,
+
+        // Kannada
+        0x0C82...0x0C83,
+        0x0C85...0x0C8C,
+        0x0C8E...0x0C90,
+        0x0C92...0x0CA8,
+        0x0CAA...0x0CB3,
+        0x0CB5...0x0CB9,
+        0x0CBE...0x0CC4,
+        0x0CC6...0x0CC8,
+        0x0CCA...0x0CCD,
+        0x0CDE,
+        0x0CE0...0x0CE1,
+
+        // Malayalam
+        0x0D02...0x0D03,
+        0x0D05...0x0D0C,
+        0x0D0E...0x0D10,
+        0x0D12...0x0D28,
+        0x0D2A...0x0D39,
+        0x0D3E...0x0D43,
+        0x0D46...0x0D48,
+        0x0D4A...0x0D4D,
+        0x0D60...0x0D61,
+
+        // Thai (excluding digits 0x0E50...0x0E59; originally 0x0E01...0x0E3A and 0x0E40...0x0E5B
+        0x0E01...0x0E3A,
+        0x0E40...0x0E4F,
+        0x0E5A...0x0E5B,
+
+        // Lao
+        0x0E81...0x0E82,
+        0x0E84,
+        0x0E87...0x0E88,
+        0x0E8A,
+        0x0E8D,
+        0x0E94...0x0E97,
+        0x0E99...0x0E9F,
+        0x0EA1...0x0EA3,
+        0x0EA5,
+        0x0EA7,
+        0x0EAA...0x0EAB,
+        0x0EAD...0x0EAE,
+        0x0EB0...0x0EB9,
+        0x0EBB...0x0EBD,
+        0x0EC0...0x0EC4,
+        0x0EC6,
+        0x0EC8...0x0ECD,
+        0x0EDC...0x0EDD,
+
+        // Tibetan
+        0x0F00,
+        0x0F18...0x0F19,
+        0x0F35,
+        0x0F37,
+        0x0F39,
+        0x0F3E...0x0F47,
+        0x0F49...0x0F69,
+        0x0F71...0x0F84,
+        0x0F86...0x0F8B,
+        0x0F90...0x0F95,
+        0x0F97,
+        0x0F99...0x0FAD,
+        0x0FB1...0x0FB7,
+        0x0FB9,
+
+        // Georgian
+        0x10A0...0x10C5,
+        0x10D0...0x10F6,
+
+        // Hiragana
+        0x3041...0x3093,
+        0x309B...0x309C,
+
+        // Katakana
+        0x30A1...0x30F6,
+        0x30FB...0x30FC,
+
+        // Bopomofo
+        0x3105...0x312C,
+
+        // CJK Unified Ideographs
+        0x4E00...0x9FA5,
+
+        // Hangul
+        0xAC00...0xD7A3,
+
+        // Digits
+        0x0660...0x0669,
+        0x06F0...0x06F9,
+        0x0966...0x096F,
+        0x09E6...0x09EF,
+        0x0A66...0x0A6F,
+        0x0AE6...0x0AEF,
+        0x0B66...0x0B6F,
+        0x0BE7...0x0BEF,
+        0x0C66...0x0C6F,
+        0x0CE6...0x0CEF,
+        0x0D66...0x0D6F,
+        0x0E50...0x0E59,
+        0x0ED0...0x0ED9,
+        0x0F20...0x0F33,
+
+        // Special characters
+        0x00B5,
+        0x00B7,
+        0x02B0...0x02B8,
+        0x02BB,
+        0x02BD...0x02C1,
+        0x02D0...0x02D1,
+        0x02E0...0x02E4,
+        0x037A,
+        0x0559,
+        0x093D,
+        0x0B3D,
+        0x1FBE,
+        0x203F...0x2040,
+        0x2102,
+        0x2107,
+        0x210A...0x2113,
+        0x2115,
+        0x2118...0x211D,
+        0x2124,
+        0x2126,
+        0x2128,
+        0x212A...0x2131,
+        0x2133...0x2138,
+        0x2160...0x2182,
+        0x3005...0x3007,
+        0x3021...0x3029,
+        => true,
+        else => false,
+    };
+}
+
+/// C11 standard Annex D
+pub fn isC11DisallowedInitialIdChar(codepoint: u21) bool {
+    assert(codepoint > 0x7F);
+    return switch (codepoint) {
+        0x0300...0x036F,
+        0x1DC0...0x1DFF,
+        0x20D0...0x20FF,
+        0xFE20...0xFE2F,
+        => true,
+        else => false,
+    };
+}
+
+/// These are "digit" characters; C99 disallows them as the first
+/// character of an identifier
+pub fn isC99DisallowedInitialIDChar(codepoint: u21) bool {
+    assert(codepoint > 0x7F);
+    return switch (codepoint) {
+        0x0660...0x0669,
+        0x06F0...0x06F9,
+        0x0966...0x096F,
+        0x09E6...0x09EF,
+        0x0A66...0x0A6F,
+        0x0AE6...0x0AEF,
+        0x0B66...0x0B6F,
+        0x0BE7...0x0BEF,
+        0x0C66...0x0C6F,
+        0x0CE6...0x0CEF,
+        0x0D66...0x0D6F,
+        0x0E50...0x0E59,
+        0x0ED0...0x0ED9,
+        0x0F20...0x0F33,
+        => true,
+        else => false,
+    };
+}
+
+pub fn isInvisible(codepoint: u21) bool {
+    assert(codepoint > 0x7F);
+    return switch (codepoint) {
+        0x00ad, // SOFT HYPHEN
+        0x200b, // ZERO WIDTH SPACE
+        0x200c, // ZERO WIDTH NON-JOINER
+        0x200d, // ZERO WIDTH JOINER
+        0x2060, // WORD JOINER
+        0x2061, // FUNCTION APPLICATION
+        0x2062, // INVISIBLE TIMES
+        0x2063, // INVISIBLE SEPARATOR
+        0x2064, // INVISIBLE PLUS
+        0xfeff, // ZERO WIDTH NO-BREAK SPACE
+        => true,
+        else => false,
+    };
+}
+
+/// Checks for identifier characters which resemble non-identifier characters
+pub fn homoglyph(codepoint: u21) ?u21 {
+    assert(codepoint > 0x7F);
+    return switch (codepoint) {
+        0x01c3 => '!', // LATIN LETTER RETROFLEX CLICK
+        0x037e => ';', // GREEK QUESTION MARK
+        0x2212 => '-', // MINUS SIGN
+        0x2215 => '/', // DIVISION SLASH
+        0x2216 => '\\', // SET MINUS
+        0x2217 => '*', // ASTERISK OPERATOR
+        0x2223 => '|', // DIVIDES
+        0x2227 => '^', // LOGICAL AND
+        0x2236 => ':', // RATIO
+        0x223c => '~', // TILDE OPERATOR
+        0xa789 => ':', // MODIFIER LETTER COLON
+        0xff01 => '!', // FULLWIDTH EXCLAMATION MARK
+        0xff03 => '#', // FULLWIDTH NUMBER SIGN
+        0xff04 => '$', // FULLWIDTH DOLLAR SIGN
+        0xff05 => '%', // FULLWIDTH PERCENT SIGN
+        0xff06 => '&', // FULLWIDTH AMPERSAND
+        0xff08 => '(', // FULLWIDTH LEFT PARENTHESIS
+        0xff09 => ')', // FULLWIDTH RIGHT PARENTHESIS
+        0xff0a => '*', // FULLWIDTH ASTERISK
+        0xff0b => '+', // FULLWIDTH ASTERISK
+        0xff0c => ',', // FULLWIDTH COMMA
+        0xff0d => '-', // FULLWIDTH HYPHEN-MINUS
+        0xff0e => '.', // FULLWIDTH FULL STOP
+        0xff0f => '/', // FULLWIDTH SOLIDUS
+        0xff1a => ':', // FULLWIDTH COLON
+        0xff1b => ';', // FULLWIDTH SEMICOLON
+        0xff1c => '<', // FULLWIDTH LESS-THAN SIGN
+        0xff1d => '=', // FULLWIDTH EQUALS SIGN
+        0xff1e => '>', // FULLWIDTH GREATER-THAN SIGN
+        0xff1f => '?', // FULLWIDTH QUESTION MARK
+        0xff20 => '@', // FULLWIDTH COMMERCIAL AT
+        0xff3b => '[', // FULLWIDTH LEFT SQUARE BRACKET
+        0xff3c => '\\', // FULLWIDTH REVERSE SOLIDUS
+        0xff3d => ']', // FULLWIDTH RIGHT SQUARE BRACKET
+        0xff3e => '^', // FULLWIDTH CIRCUMFLEX ACCENT
+        0xff5b => '{', // FULLWIDTH LEFT CURLY BRACKET
+        0xff5c => '|', // FULLWIDTH VERTICAL LINE
+        0xff5d => '}', // FULLWIDTH RIGHT CURLY BRACKET
+        0xff5e => '~', // FULLWIDTH TILDE
+        else => null,
+    };
+}
deps/aro/CodeGen.zig
@@ -0,0 +1,1291 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const assert = std.debug.assert;
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+const Compilation = @import("Compilation.zig");
+const Interner = @import("Interner.zig");
+const Ir = @import("Ir.zig");
+const Builder = Ir.Builder;
+const StringId = @import("StringInterner.zig").StringId;
+const Tree = @import("Tree.zig");
+const NodeIndex = Tree.NodeIndex;
+const Type = @import("Type.zig");
+const Value = @import("Value.zig");
+
+const CodeGen = @This();
+
+const WipSwitch = struct {
+    cases: Cases = .{},
+    default: ?Ir.Ref = null,
+    size: u64,
+
+    const Cases = std.MultiArrayList(struct {
+        val: Interner.Ref,
+        label: Ir.Ref,
+    });
+};
+
+const Symbol = struct {
+    name: StringId,
+    val: Ir.Ref,
+};
+
+const Error = Compilation.Error;
+
+tree: Tree,
+comp: *Compilation,
+builder: Builder,
+node_tag: []const Tree.Tag,
+node_data: []const Tree.Node.Data,
+node_ty: []const Type,
+wip_switch: *WipSwitch = undefined,
+symbols: std.ArrayListUnmanaged(Symbol) = .{},
+ret_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
+phi_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
+record_elem_buf: std.ArrayListUnmanaged(Interner.Ref) = .{},
+cond_dummy_ty: ?Interner.Ref = null,
+bool_invert: bool = false,
+bool_end_label: Ir.Ref = .none,
+cond_dummy_ref: Ir.Ref = undefined,
+continue_label: Ir.Ref = undefined,
+break_label: Ir.Ref = undefined,
+return_label: Ir.Ref = undefined,
+
+pub fn generateTree(comp: *Compilation, tree: Tree) Compilation.Error!void {
+    var c = CodeGen{
+        .builder = .{
+            .gpa = comp.gpa,
+            .arena = std.heap.ArenaAllocator.init(comp.gpa),
+        },
+        .tree = tree,
+        .comp = comp,
+        .node_tag = tree.nodes.items(.tag),
+        .node_data = tree.nodes.items(.data),
+        .node_ty = tree.nodes.items(.ty),
+    };
+    defer c.symbols.deinit(c.comp.gpa);
+    defer c.ret_nodes.deinit(c.comp.gpa);
+    defer c.phi_nodes.deinit(c.comp.gpa);
+    defer c.record_elem_buf.deinit(c.comp.gpa);
+    defer c.builder.deinit();
+
+    const node_tags = tree.nodes.items(.tag);
+    for (tree.root_decls) |decl| {
+        c.builder.arena.deinit();
+        c.builder.arena = std.heap.ArenaAllocator.init(comp.gpa);
+
+        switch (node_tags[@intFromEnum(decl)]) {
+            .static_assert,
+            .typedef,
+            .struct_decl_two,
+            .union_decl_two,
+            .enum_decl_two,
+            .struct_decl,
+            .union_decl,
+            .enum_decl,
+            => {},
+
+            .fn_proto,
+            .static_fn_proto,
+            .inline_fn_proto,
+            .inline_static_fn_proto,
+            .extern_var,
+            .threadlocal_extern_var,
+            => {},
+
+            .fn_def,
+            .static_fn_def,
+            .inline_fn_def,
+            .inline_static_fn_def,
+            => c.genFn(decl) catch |err| switch (err) {
+                error.FatalError => return error.FatalError,
+                error.OutOfMemory => return error.OutOfMemory,
+            },
+
+            .@"var",
+            .static_var,
+            .threadlocal_var,
+            .threadlocal_static_var,
+            => c.genVar(decl) catch |err| switch (err) {
+                error.FatalError => return error.FatalError,
+                error.OutOfMemory => return error.OutOfMemory,
+            },
+            else => unreachable,
+        }
+    }
+}
+
+fn genType(c: *CodeGen, base_ty: Type) !Interner.Ref {
+    var key: Interner.Key = undefined;
+    const ty = base_ty.canonicalize(.standard);
+    switch (ty.specifier) {
+        .void => return .void,
+        .bool => return .i1,
+        .@"struct" => {
+            key = .{
+                .record = .{
+                    .user_ptr = ty.data.record,
+                    .elements = undefined, // Not needed for hash lookup.
+                },
+            };
+            if (c.builder.pool.has(key)) |some| return some;
+            const elem_buf_top = c.record_elem_buf.items.len;
+            defer c.record_elem_buf.items.len = elem_buf_top;
+
+            for (ty.data.record.fields) |field| {
+                if (!field.isRegularField()) {
+                    return c.comp.diag.fatalNoSrc("TODO lower struct bitfields", .{});
+                }
+                // TODO handle padding bits
+                const field_ref = try c.genType(field.ty);
+                try c.record_elem_buf.append(c.builder.gpa, field_ref);
+            }
+
+            key.record.elements = try c.builder.arena.allocator().dupe(Interner.Ref, c.record_elem_buf.items[elem_buf_top..]);
+            return c.builder.pool.put(c.builder.gpa, key);
+        },
+        .@"union" => {
+            return c.comp.diag.fatalNoSrc("TODO lower union types", .{});
+        },
+        else => {},
+    }
+    if (ty.isPtr()) return .ptr;
+    if (ty.isFunc()) return .func;
+    if (!ty.isReal()) return c.comp.diag.fatalNoSrc("TODO lower complex types", .{});
+    if (ty.isInt()) {
+        const bits = ty.bitSizeof(c.comp).?;
+        key = .{ .int = @intCast(bits) };
+    } else if (ty.isFloat()) {
+        const bits = ty.bitSizeof(c.comp).?;
+        key = .{ .float = @intCast(bits) };
+    } else if (ty.isArray()) {
+        const elem = try c.genType(ty.elemType());
+        key = .{ .array = .{ .child = elem, .len = ty.arrayLen().? } };
+    } else if (ty.specifier == .vector) {
+        const elem = try c.genType(ty.elemType());
+        key = .{ .vector = .{ .child = elem, .len = @intCast(ty.data.array.len) } };
+    } else if (ty.is(.nullptr_t)) {
+        return c.comp.diag.fatalNoSrc("TODO lower nullptr_t", .{});
+    }
+    return c.builder.pool.put(c.builder.gpa, key);
+}
+
+fn genFn(c: *CodeGen, decl: NodeIndex) Error!void {
+    const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
+    const func_ty = c.node_ty[@intFromEnum(decl)].canonicalize(.standard);
+    c.ret_nodes.items.len = 0;
+
+    try c.builder.startFn();
+
+    for (func_ty.data.func.params) |param| {
+        // TODO handle calling convention here
+        const arg = try c.builder.addArg(try c.genType(param.ty));
+
+        const size: u32 = @intCast(param.ty.sizeof(c.comp).?); // TODO add error in parser
+        const @"align" = param.ty.alignof(c.comp);
+        const alloc = try c.builder.addAlloc(size, @"align");
+        try c.builder.addStore(alloc, arg);
+        try c.symbols.append(c.comp.gpa, .{ .name = param.name, .val = alloc });
+    }
+
+    // Generate body
+    c.return_label = try c.builder.makeLabel("return");
+    try c.genStmt(c.node_data[@intFromEnum(decl)].decl.node);
+
+    // Relocate returns
+    if (c.ret_nodes.items.len == 0) {
+        _ = try c.builder.addInst(.ret, .{ .un = .none }, .noreturn);
+    } else if (c.ret_nodes.items.len == 1) {
+        c.builder.body.items.len -= 1;
+        _ = try c.builder.addInst(.ret, .{ .un = c.ret_nodes.items[0].value }, .noreturn);
+    } else {
+        try c.builder.startBlock(c.return_label);
+        const phi = try c.builder.addPhi(c.ret_nodes.items, try c.genType(func_ty.returnType()));
+        _ = try c.builder.addInst(.ret, .{ .un = phi }, .noreturn);
+    }
+
+    var res = Ir{
+        .pool = c.builder.pool,
+        .instructions = c.builder.instructions,
+        .arena = c.builder.arena.state,
+        .body = c.builder.body,
+        .strings = c.tree.strings,
+    };
+    res.dump(c.builder.gpa, name, c.comp.diag.color, std.io.getStdOut().writer()) catch {};
+}
+
+fn addUn(c: *CodeGen, tag: Ir.Inst.Tag, operand: Ir.Ref, ty: Type) !Ir.Ref {
+    return c.builder.addInst(tag, .{ .un = operand }, try c.genType(ty));
+}
+
+fn addBin(c: *CodeGen, tag: Ir.Inst.Tag, lhs: Ir.Ref, rhs: Ir.Ref, ty: Type) !Ir.Ref {
+    return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, try c.genType(ty));
+}
+
+fn addBranch(c: *CodeGen, cond: Ir.Ref, true_label: Ir.Ref, false_label: Ir.Ref) !void {
+    if (true_label == c.bool_end_label) {
+        if (false_label == c.bool_end_label) {
+            try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = cond });
+            return;
+        }
+        try c.addBoolPhi(!c.bool_invert);
+    }
+    if (false_label == c.bool_end_label) {
+        try c.addBoolPhi(c.bool_invert);
+    }
+    return c.builder.addBranch(cond, true_label, false_label);
+}
+
+fn addBoolPhi(c: *CodeGen, value: bool) !void {
+    const val = try c.builder.addConstant(Value.int(@intFromBool(value)), .i1);
+    try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = val });
+}
+
+fn genStmt(c: *CodeGen, node: NodeIndex) Error!void {
+    _ = try c.genExpr(node);
+}
+
+fn genExpr(c: *CodeGen, node: NodeIndex) Error!Ir.Ref {
+    std.debug.assert(node != .none);
+    const ty = c.node_ty[@intFromEnum(node)];
+    if (c.tree.value_map.get(node)) |val| {
+        return c.builder.addConstant(val, try c.genType(ty));
+    }
+    const data = c.node_data[@intFromEnum(node)];
+    switch (c.node_tag[@intFromEnum(node)]) {
+        .enumeration_ref,
+        .bool_literal,
+        .int_literal,
+        .char_literal,
+        .float_literal,
+        .double_literal,
+        .imaginary_literal,
+        .string_literal_expr,
+        .alignof_expr,
+        => unreachable, // These should have an entry in value_map.
+        .fn_def,
+        .static_fn_def,
+        .inline_fn_def,
+        .inline_static_fn_def,
+        .invalid,
+        .threadlocal_var,
+        => unreachable,
+        .static_assert,
+        .fn_proto,
+        .static_fn_proto,
+        .inline_fn_proto,
+        .inline_static_fn_proto,
+        .extern_var,
+        .threadlocal_extern_var,
+        .typedef,
+        .struct_decl_two,
+        .union_decl_two,
+        .enum_decl_two,
+        .struct_decl,
+        .union_decl,
+        .enum_decl,
+        .enum_field_decl,
+        .record_field_decl,
+        .indirect_record_field_decl,
+        .struct_forward_decl,
+        .union_forward_decl,
+        .enum_forward_decl,
+        .null_stmt,
+        => {},
+        .static_var,
+        .implicit_static_var,
+        .threadlocal_static_var,
+        => try c.genVar(node), // TODO
+        .@"var" => {
+            const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser
+            const @"align" = ty.alignof(c.comp);
+            const alloc = try c.builder.addAlloc(size, @"align");
+            const name = try c.comp.intern(c.tree.tokSlice(data.decl.name));
+            try c.symbols.append(c.comp.gpa, .{ .name = name, .val = alloc });
+            if (data.decl.node != .none) {
+                try c.genInitializer(alloc, ty, data.decl.node);
+            }
+        },
+        .labeled_stmt => {
+            const label = try c.builder.makeLabel("label");
+            try c.builder.startBlock(label);
+            try c.genStmt(data.decl.node);
+        },
+        .compound_stmt_two => {
+            const old_sym_len = c.symbols.items.len;
+            c.symbols.items.len = old_sym_len;
+
+            if (data.bin.lhs != .none) try c.genStmt(data.bin.lhs);
+            if (data.bin.rhs != .none) try c.genStmt(data.bin.rhs);
+        },
+        .compound_stmt => {
+            const old_sym_len = c.symbols.items.len;
+            c.symbols.items.len = old_sym_len;
+
+            for (c.tree.data[data.range.start..data.range.end]) |stmt| try c.genStmt(stmt);
+        },
+        .if_then_else_stmt => {
+            const then_label = try c.builder.makeLabel("if.then");
+            const else_label = try c.builder.makeLabel("if.else");
+            const end_label = try c.builder.makeLabel("if.end");
+
+            try c.genBoolExpr(data.if3.cond, then_label, else_label);
+
+            try c.builder.startBlock(then_label);
+            try c.genStmt(c.tree.data[data.if3.body]); // then
+            try c.builder.addJump(end_label);
+
+            try c.builder.startBlock(else_label);
+            try c.genStmt(c.tree.data[data.if3.body + 1]); // else
+
+            try c.builder.startBlock(end_label);
+        },
+        .if_then_stmt => {
+            const then_label = try c.builder.makeLabel("if.then");
+            const end_label = try c.builder.makeLabel("if.end");
+
+            try c.genBoolExpr(data.bin.lhs, then_label, end_label);
+
+            try c.builder.startBlock(then_label);
+            try c.genStmt(data.bin.rhs); // then
+            try c.builder.startBlock(end_label);
+        },
+        .switch_stmt => {
+            var wip_switch = WipSwitch{
+                .size = c.node_ty[@intFromEnum(data.bin.lhs)].sizeof(c.comp).?,
+            };
+            defer wip_switch.cases.deinit(c.builder.gpa);
+
+            const old_wip_switch = c.wip_switch;
+            defer c.wip_switch = old_wip_switch;
+            c.wip_switch = &wip_switch;
+
+            const old_break_label = c.break_label;
+            defer c.break_label = old_break_label;
+            const end_ref = try c.builder.makeLabel("switch.end");
+            c.break_label = end_ref;
+
+            const cond = try c.genExpr(data.bin.lhs);
+            const switch_index = c.builder.instructions.len;
+            _ = try c.builder.addInst(.@"switch", undefined, .noreturn);
+
+            try c.genStmt(data.bin.rhs); // body
+
+            const default_ref = wip_switch.default orelse end_ref;
+            try c.builder.startBlock(end_ref);
+
+            const a = c.builder.arena.allocator();
+            const switch_data = try a.create(Ir.Inst.Switch);
+            switch_data.* = .{
+                .target = cond,
+                .cases_len = @intCast(wip_switch.cases.len),
+                .case_vals = (try a.dupe(Interner.Ref, wip_switch.cases.items(.val))).ptr,
+                .case_labels = (try a.dupe(Ir.Ref, wip_switch.cases.items(.label))).ptr,
+                .default = default_ref,
+            };
+            c.builder.instructions.items(.data)[switch_index] = .{ .@"switch" = switch_data };
+        },
+        .case_stmt => {
+            const val = c.tree.value_map.get(data.bin.lhs).?;
+            const label = try c.builder.makeLabel("case");
+            try c.builder.startBlock(label);
+            try c.wip_switch.cases.append(c.builder.gpa, .{
+                .val = try c.builder.pool.put(c.builder.gpa, .{ .value = val }),
+                .label = label,
+            });
+            try c.genStmt(data.bin.rhs);
+        },
+        .default_stmt => {
+            const default = try c.builder.makeLabel("default");
+            try c.builder.startBlock(default);
+            c.wip_switch.default = default;
+            try c.genStmt(data.un);
+        },
+        .while_stmt => {
+            const old_break_label = c.break_label;
+            defer c.break_label = old_break_label;
+
+            const old_continue_label = c.continue_label;
+            defer c.continue_label = old_continue_label;
+
+            const cond_label = try c.builder.makeLabel("while.cond");
+            const then_label = try c.builder.makeLabel("while.then");
+            const end_label = try c.builder.makeLabel("while.end");
+
+            c.continue_label = cond_label;
+            c.break_label = end_label;
+
+            try c.builder.startBlock(cond_label);
+            try c.genBoolExpr(data.bin.lhs, then_label, end_label);
+
+            try c.builder.startBlock(then_label);
+            try c.genStmt(data.bin.rhs);
+            try c.builder.addJump(cond_label);
+            try c.builder.startBlock(end_label);
+        },
+        .do_while_stmt => {
+            const old_break_label = c.break_label;
+            defer c.break_label = old_break_label;
+
+            const old_continue_label = c.continue_label;
+            defer c.continue_label = old_continue_label;
+
+            const then_label = try c.builder.makeLabel("do.then");
+            const cond_label = try c.builder.makeLabel("do.cond");
+            const end_label = try c.builder.makeLabel("do.end");
+
+            c.continue_label = cond_label;
+            c.break_label = end_label;
+
+            try c.builder.startBlock(then_label);
+            try c.genStmt(data.bin.rhs);
+
+            try c.builder.startBlock(cond_label);
+            try c.genBoolExpr(data.bin.lhs, then_label, end_label);
+
+            try c.builder.startBlock(end_label);
+        },
+        .for_decl_stmt => {
+            const old_break_label = c.break_label;
+            defer c.break_label = old_break_label;
+
+            const old_continue_label = c.continue_label;
+            defer c.continue_label = old_continue_label;
+
+            const for_decl = data.forDecl(c.tree);
+            for (for_decl.decls) |decl| try c.genStmt(decl);
+
+            const then_label = try c.builder.makeLabel("for.then");
+            var cond_label = then_label;
+            const cont_label = try c.builder.makeLabel("for.cont");
+            const end_label = try c.builder.makeLabel("for.end");
+
+            c.continue_label = cont_label;
+            c.break_label = end_label;
+
+            if (for_decl.cond != .none) {
+                cond_label = try c.builder.makeLabel("for.cond");
+                try c.builder.startBlock(cond_label);
+                try c.genBoolExpr(for_decl.cond, then_label, end_label);
+            }
+            try c.builder.startBlock(then_label);
+            try c.genStmt(for_decl.body);
+            if (for_decl.incr != .none) {
+                _ = try c.genExpr(for_decl.incr);
+            }
+            try c.builder.addJump(cond_label);
+            try c.builder.startBlock(end_label);
+        },
+        .forever_stmt => {
+            const old_break_label = c.break_label;
+            defer c.break_label = old_break_label;
+
+            const old_continue_label = c.continue_label;
+            defer c.continue_label = old_continue_label;
+
+            const then_label = try c.builder.makeLabel("for.then");
+            const end_label = try c.builder.makeLabel("for.end");
+
+            c.continue_label = then_label;
+            c.break_label = end_label;
+
+            try c.builder.startBlock(then_label);
+            try c.genStmt(data.un);
+            try c.builder.startBlock(end_label);
+        },
+        .for_stmt => {
+            const old_break_label = c.break_label;
+            defer c.break_label = old_break_label;
+
+            const old_continue_label = c.continue_label;
+            defer c.continue_label = old_continue_label;
+
+            const for_stmt = data.forStmt(c.tree);
+            if (for_stmt.init != .none) _ = try c.genExpr(for_stmt.init);
+
+            const then_label = try c.builder.makeLabel("for.then");
+            var cond_label = then_label;
+            const cont_label = try c.builder.makeLabel("for.cont");
+            const end_label = try c.builder.makeLabel("for.end");
+
+            c.continue_label = cont_label;
+            c.break_label = end_label;
+
+            if (for_stmt.cond != .none) {
+                cond_label = try c.builder.makeLabel("for.cond");
+                try c.builder.startBlock(cond_label);
+                try c.genBoolExpr(for_stmt.cond, then_label, end_label);
+            }
+            try c.builder.startBlock(then_label);
+            try c.genStmt(for_stmt.body);
+            if (for_stmt.incr != .none) {
+                _ = try c.genExpr(for_stmt.incr);
+            }
+            try c.builder.addJump(cond_label);
+            try c.builder.startBlock(end_label);
+        },
+        .continue_stmt => try c.builder.addJump(c.continue_label),
+        .break_stmt => try c.builder.addJump(c.break_label),
+        .return_stmt => {
+            if (data.un != .none) {
+                const operand = try c.genExpr(data.un);
+                try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label });
+            }
+            try c.builder.addJump(c.return_label);
+        },
+        .implicit_return => {
+            if (data.return_zero) {
+                const operand = try c.builder.addConstant(Value.int(0), try c.genType(ty));
+                try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label });
+            }
+            // No need to emit a jump since implicit_return is always the last instruction.
+        },
+        .case_range_stmt,
+        .goto_stmt,
+        .computed_goto_stmt,
+        .nullptr_literal,
+        => return c.comp.diag.fatalNoSrc("TODO CodeGen.genStmt {}\n", .{c.node_tag[@intFromEnum(node)]}),
+        .comma_expr => {
+            _ = try c.genExpr(data.bin.lhs);
+            return c.genExpr(data.bin.rhs);
+        },
+        .assign_expr => {
+            const rhs = try c.genExpr(data.bin.rhs);
+            const lhs = try c.genLval(data.bin.lhs);
+            try c.builder.addStore(lhs, rhs);
+            return rhs;
+        },
+        .mul_assign_expr => return c.genCompoundAssign(node, .mul),
+        .div_assign_expr => return c.genCompoundAssign(node, .div),
+        .mod_assign_expr => return c.genCompoundAssign(node, .mod),
+        .add_assign_expr => return c.genCompoundAssign(node, .add),
+        .sub_assign_expr => return c.genCompoundAssign(node, .sub),
+        .shl_assign_expr => return c.genCompoundAssign(node, .bit_shl),
+        .shr_assign_expr => return c.genCompoundAssign(node, .bit_shr),
+        .bit_and_assign_expr => return c.genCompoundAssign(node, .bit_and),
+        .bit_xor_assign_expr => return c.genCompoundAssign(node, .bit_xor),
+        .bit_or_assign_expr => return c.genCompoundAssign(node, .bit_or),
+        .bit_or_expr => return c.genBinOp(node, .bit_or),
+        .bit_xor_expr => return c.genBinOp(node, .bit_xor),
+        .bit_and_expr => return c.genBinOp(node, .bit_and),
+        .equal_expr => {
+            const cmp = try c.genComparison(node, .cmp_eq);
+            return c.addUn(.zext, cmp, ty);
+        },
+        .not_equal_expr => {
+            const cmp = try c.genComparison(node, .cmp_ne);
+            return c.addUn(.zext, cmp, ty);
+        },
+        .less_than_expr => {
+            const cmp = try c.genComparison(node, .cmp_lt);
+            return c.addUn(.zext, cmp, ty);
+        },
+        .less_than_equal_expr => {
+            const cmp = try c.genComparison(node, .cmp_lte);
+            return c.addUn(.zext, cmp, ty);
+        },
+        .greater_than_expr => {
+            const cmp = try c.genComparison(node, .cmp_gt);
+            return c.addUn(.zext, cmp, ty);
+        },
+        .greater_than_equal_expr => {
+            const cmp = try c.genComparison(node, .cmp_gte);
+            return c.addUn(.zext, cmp, ty);
+        },
+        .shl_expr => return c.genBinOp(node, .bit_shl),
+        .shr_expr => return c.genBinOp(node, .bit_shr),
+        .add_expr => {
+            if (ty.isPtr()) {
+                const lhs_ty = c.node_ty[@intFromEnum(data.bin.lhs)];
+                if (lhs_ty.isPtr()) {
+                    const ptr = try c.genExpr(data.bin.lhs);
+                    const offset = try c.genExpr(data.bin.rhs);
+                    const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)];
+                    return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
+                } else {
+                    const offset = try c.genExpr(data.bin.lhs);
+                    const ptr = try c.genExpr(data.bin.rhs);
+                    const offset_ty = lhs_ty;
+                    return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
+                }
+            }
+            return c.genBinOp(node, .add);
+        },
+        .sub_expr => {
+            if (ty.isPtr()) {
+                const ptr = try c.genExpr(data.bin.lhs);
+                const offset = try c.genExpr(data.bin.rhs);
+                const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)];
+                return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
+            }
+            return c.genBinOp(node, .sub);
+        },
+        .mul_expr => return c.genBinOp(node, .mul),
+        .div_expr => return c.genBinOp(node, .div),
+        .mod_expr => return c.genBinOp(node, .mod),
+        .addr_of_expr => return try c.genLval(data.un),
+        .deref_expr => {
+            const un_data = c.node_data[@intFromEnum(data.un)];
+            if (c.node_tag[@intFromEnum(data.un)] == .implicit_cast and un_data.cast.kind == .function_to_pointer) {
+                return c.genExpr(data.un);
+            }
+            const operand = try c.genLval(data.un);
+            return c.addUn(.load, operand, ty);
+        },
+        .plus_expr => return c.genExpr(data.un),
+        .negate_expr => {
+            const zero = try c.builder.addConstant(Value.int(0), try c.genType(ty));
+            const operand = try c.genExpr(data.un);
+            return c.addBin(.sub, zero, operand, ty);
+        },
+        .bit_not_expr => {
+            const operand = try c.genExpr(data.un);
+            return c.addUn(.bit_not, operand, ty);
+        },
+        .bool_not_expr => {
+            const zero = try c.builder.addConstant(Value.int(0), try c.genType(ty));
+            const operand = try c.genExpr(data.un);
+            return c.addBin(.cmp_ne, zero, operand, ty);
+        },
+        .pre_inc_expr => {
+            const operand = try c.genLval(data.un);
+            const val = try c.addUn(.load, operand, ty);
+            const one = try c.builder.addConstant(Value.int(1), try c.genType(ty));
+            const plus_one = try c.addBin(.add, val, one, ty);
+            try c.builder.addStore(operand, plus_one);
+            return plus_one;
+        },
+        .pre_dec_expr => {
+            const operand = try c.genLval(data.un);
+            const val = try c.addUn(.load, operand, ty);
+            const one = try c.builder.addConstant(Value.int(1), try c.genType(ty));
+            const plus_one = try c.addBin(.sub, val, one, ty);
+            try c.builder.addStore(operand, plus_one);
+            return plus_one;
+        },
+        .post_inc_expr => {
+            const operand = try c.genLval(data.un);
+            const val = try c.addUn(.load, operand, ty);
+            const one = try c.builder.addConstant(Value.int(1), try c.genType(ty));
+            const plus_one = try c.addBin(.add, val, one, ty);
+            try c.builder.addStore(operand, plus_one);
+            return val;
+        },
+        .post_dec_expr => {
+            const operand = try c.genLval(data.un);
+            const val = try c.addUn(.load, operand, ty);
+            const one = try c.builder.addConstant(Value.int(1), try c.genType(ty));
+            const plus_one = try c.addBin(.sub, val, one, ty);
+            try c.builder.addStore(operand, plus_one);
+            return val;
+        },
+        .paren_expr => return c.genExpr(data.un),
+        .decl_ref_expr => unreachable, // Lval expression.
+        .explicit_cast, .implicit_cast => switch (data.cast.kind) {
+            .no_op => return c.genExpr(data.cast.operand),
+            .to_void => {
+                _ = try c.genExpr(data.cast.operand);
+                return .none;
+            },
+            .lval_to_rval => {
+                const operand = try c.genLval(data.cast.operand);
+                return c.addUn(.load, operand, ty);
+            },
+            .function_to_pointer, .array_to_pointer => {
+                return c.genLval(data.cast.operand);
+            },
+            .int_cast => {
+                const operand = try c.genExpr(data.cast.operand);
+                const src_ty = c.node_ty[@intFromEnum(data.cast.operand)];
+                const src_bits = src_ty.bitSizeof(c.comp).?;
+                const dest_bits = ty.bitSizeof(c.comp).?;
+                if (src_bits == dest_bits) {
+                    return operand;
+                } else if (src_bits < dest_bits) {
+                    if (src_ty.isUnsignedInt(c.comp))
+                        return c.addUn(.zext, operand, ty)
+                    else
+                        return c.addUn(.sext, operand, ty);
+                } else {
+                    return c.addUn(.trunc, operand, ty);
+                }
+            },
+            .bool_to_int => {
+                const operand = try c.genExpr(data.cast.operand);
+                return c.addUn(.zext, operand, ty);
+            },
+            .pointer_to_bool, .int_to_bool, .float_to_bool => {
+                const lhs = try c.genExpr(data.cast.operand);
+                const rhs = try c.builder.addConstant(Value.int(0), try c.genType(c.node_ty[@intFromEnum(node)]));
+                return c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
+            },
+            .bitcast,
+            .pointer_to_int,
+            .bool_to_float,
+            .bool_to_pointer,
+            .int_to_float,
+            .complex_int_to_complex_float,
+            .int_to_pointer,
+            .float_to_int,
+            .complex_float_to_complex_int,
+            .complex_int_cast,
+            .complex_int_to_real,
+            .real_to_complex_int,
+            .float_cast,
+            .complex_float_cast,
+            .complex_float_to_real,
+            .real_to_complex_float,
+            .null_to_pointer,
+            .union_cast,
+            .vector_splat,
+            => return c.comp.diag.fatalNoSrc("TODO CodeGen gen CastKind {}\n", .{data.cast.kind}),
+        },
+        .binary_cond_expr => {
+            if (c.tree.value_map.get(data.if3.cond)) |cond| {
+                if (cond.getBool()) {
+                    c.cond_dummy_ref = try c.genExpr(data.if3.cond);
+                    return c.genExpr(c.tree.data[data.if3.body]); // then
+                } else {
+                    return c.genExpr(c.tree.data[data.if3.body + 1]); // else
+                }
+            }
+
+            const then_label = try c.builder.makeLabel("ternary.then");
+            const else_label = try c.builder.makeLabel("ternary.else");
+            const end_label = try c.builder.makeLabel("ternary.end");
+            const cond_ty = c.node_ty[@intFromEnum(data.if3.cond)];
+            {
+                const old_cond_dummy_ty = c.cond_dummy_ty;
+                defer c.cond_dummy_ty = old_cond_dummy_ty;
+                c.cond_dummy_ty = try c.genType(cond_ty);
+
+                try c.genBoolExpr(data.if3.cond, then_label, else_label);
+            }
+
+            try c.builder.startBlock(then_label);
+            if (c.builder.instructions.items(.ty)[@intFromEnum(c.cond_dummy_ref)] == .i1) {
+                c.cond_dummy_ref = try c.addUn(.zext, c.cond_dummy_ref, cond_ty);
+            }
+            const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then
+            try c.builder.addJump(end_label);
+            const then_exit = c.builder.current_label;
+
+            try c.builder.startBlock(else_label);
+            const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else
+            const else_exit = c.builder.current_label;
+
+            try c.builder.startBlock(end_label);
+
+            var phi_buf: [2]Ir.Inst.Phi.Input = .{
+                .{ .value = then_val, .label = then_exit },
+                .{ .value = else_val, .label = else_exit },
+            };
+            return c.builder.addPhi(&phi_buf, try c.genType(ty));
+        },
+        .cond_dummy_expr => return c.cond_dummy_ref,
+        .cond_expr => {
+            if (c.tree.value_map.get(data.if3.cond)) |cond| {
+                if (cond.getBool()) {
+                    return c.genExpr(c.tree.data[data.if3.body]); // then
+                } else {
+                    return c.genExpr(c.tree.data[data.if3.body + 1]); // else
+                }
+            }
+
+            const then_label = try c.builder.makeLabel("ternary.then");
+            const else_label = try c.builder.makeLabel("ternary.else");
+            const end_label = try c.builder.makeLabel("ternary.end");
+
+            try c.genBoolExpr(data.if3.cond, then_label, else_label);
+
+            try c.builder.startBlock(then_label);
+            const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then
+            try c.builder.addJump(end_label);
+            const then_exit = c.builder.current_label;
+
+            try c.builder.startBlock(else_label);
+            const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else
+            const else_exit = c.builder.current_label;
+
+            try c.builder.startBlock(end_label);
+
+            var phi_buf: [2]Ir.Inst.Phi.Input = .{
+                .{ .value = then_val, .label = then_exit },
+                .{ .value = else_val, .label = else_exit },
+            };
+            return c.builder.addPhi(&phi_buf, try c.genType(ty));
+        },
+        .call_expr_one => if (data.bin.rhs == .none) {
+            return c.genCall(data.bin.lhs, &.{}, ty);
+        } else {
+            return c.genCall(data.bin.lhs, &.{data.bin.rhs}, ty);
+        },
+        .call_expr => {
+            return c.genCall(c.tree.data[data.range.start], c.tree.data[data.range.start + 1 .. data.range.end], ty);
+        },
+        .bool_or_expr => {
+            if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
+                const cond = lhs.getBool();
+                if (!cond) {
+                    return c.builder.addConstant(Value.int(1), try c.genType(ty));
+                }
+                return c.genExpr(data.bin.rhs);
+            }
+
+            const false_label = try c.builder.makeLabel("bool_false");
+            const exit_label = try c.builder.makeLabel("bool_exit");
+
+            const old_bool_end_label = c.bool_end_label;
+            defer c.bool_end_label = old_bool_end_label;
+            c.bool_end_label = exit_label;
+
+            const phi_nodes_top = c.phi_nodes.items.len;
+            defer c.phi_nodes.items.len = phi_nodes_top;
+
+            try c.genBoolExpr(data.bin.lhs, exit_label, false_label);
+
+            try c.builder.startBlock(false_label);
+            try c.genBoolExpr(data.bin.rhs, exit_label, exit_label);
+
+            try c.builder.startBlock(exit_label);
+
+            const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1);
+            return c.addUn(.zext, phi, ty);
+        },
+        .bool_and_expr => {
+            if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
+                const cond = lhs.getBool();
+                if (!cond) {
+                    return c.builder.addConstant(Value.int(0), try c.genType(ty));
+                }
+                return c.genExpr(data.bin.rhs);
+            }
+
+            const true_label = try c.builder.makeLabel("bool_true");
+            const exit_label = try c.builder.makeLabel("bool_exit");
+
+            const old_bool_end_label = c.bool_end_label;
+            defer c.bool_end_label = old_bool_end_label;
+            c.bool_end_label = exit_label;
+
+            const phi_nodes_top = c.phi_nodes.items.len;
+            defer c.phi_nodes.items.len = phi_nodes_top;
+
+            try c.genBoolExpr(data.bin.lhs, true_label, exit_label);
+
+            try c.builder.startBlock(true_label);
+            try c.genBoolExpr(data.bin.rhs, exit_label, exit_label);
+
+            try c.builder.startBlock(exit_label);
+
+            const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1);
+            return c.addUn(.zext, phi, ty);
+        },
+        .builtin_choose_expr => {
+            const cond = c.tree.value_map.get(data.if3.cond).?;
+            if (cond.getBool()) {
+                return c.genExpr(c.tree.data[data.if3.body]);
+            } else {
+                return c.genExpr(c.tree.data[data.if3.body + 1]);
+            }
+        },
+        .generic_expr_one => {
+            const index = @intFromEnum(data.bin.rhs);
+            switch (c.node_tag[index]) {
+                .generic_association_expr, .generic_default_expr => {
+                    return c.genExpr(c.node_data[index].un);
+                },
+                else => unreachable,
+            }
+        },
+        .generic_expr => {
+            const index = @intFromEnum(c.tree.data[data.range.start + 1]);
+            switch (c.node_tag[index]) {
+                .generic_association_expr, .generic_default_expr => {
+                    return c.genExpr(c.node_data[index].un);
+                },
+                else => unreachable,
+            }
+        },
+        .generic_association_expr, .generic_default_expr => unreachable,
+        .stmt_expr => switch (c.node_tag[@intFromEnum(data.un)]) {
+            .compound_stmt_two => {
+                const old_sym_len = c.symbols.items.len;
+                c.symbols.items.len = old_sym_len;
+
+                const stmt_data = c.node_data[@intFromEnum(data.un)];
+                if (stmt_data.bin.rhs == .none) return c.genExpr(stmt_data.bin.lhs);
+                try c.genStmt(stmt_data.bin.lhs);
+                return c.genExpr(stmt_data.bin.rhs);
+            },
+            .compound_stmt => {
+                const old_sym_len = c.symbols.items.len;
+                c.symbols.items.len = old_sym_len;
+
+                const stmt_data = c.node_data[@intFromEnum(data.un)];
+                for (c.tree.data[stmt_data.range.start .. stmt_data.range.end - 1]) |stmt| try c.genStmt(stmt);
+                return c.genExpr(c.tree.data[stmt_data.range.end]);
+            },
+            else => unreachable,
+        },
+        .builtin_call_expr_one => {
+            const name = c.tree.tokSlice(data.decl.name);
+            const builtin = c.comp.builtins.lookup(name).builtin;
+            if (data.decl.node == .none) {
+                return c.genBuiltinCall(builtin, &.{}, ty);
+            } else {
+                return c.genBuiltinCall(builtin, &.{data.decl.node}, ty);
+            }
+        },
+        .builtin_call_expr => {
+            const name_node_idx = c.tree.data[data.range.start];
+            const name = c.tree.tokSlice(@intFromEnum(name_node_idx));
+            const builtin = c.comp.builtins.lookup(name).builtin;
+            return c.genBuiltinCall(builtin, c.tree.data[data.range.start + 1 .. data.range.end], ty);
+        },
+        .addr_of_label,
+        .imag_expr,
+        .real_expr,
+        .sizeof_expr,
+        .special_builtin_call_one,
+        => return c.comp.diag.fatalNoSrc("TODO CodeGen.genExpr {}\n", .{c.node_tag[@intFromEnum(node)]}),
+        else => unreachable, // Not an expression.
+    }
+    return .none;
+}
+
+fn genLval(c: *CodeGen, node: NodeIndex) Error!Ir.Ref {
+    std.debug.assert(node != .none);
+    assert(Tree.isLval(c.tree.nodes, c.tree.data, c.tree.value_map, node));
+    const data = c.node_data[@intFromEnum(node)];
+    switch (c.node_tag[@intFromEnum(node)]) {
+        .string_literal_expr => {
+            const val = c.tree.value_map.get(node).?;
+            return c.builder.addConstant(val, .ptr);
+        },
+        .paren_expr => return c.genLval(data.un),
+        .decl_ref_expr => {
+            const slice = c.tree.tokSlice(data.decl_ref);
+            const name = try c.comp.intern(slice);
+            var i = c.symbols.items.len;
+            while (i > 0) {
+                i -= 1;
+                if (c.symbols.items[i].name == name) {
+                    return c.symbols.items[i].val;
+                }
+            }
+
+            const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
+            const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
+            try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
+            return ref;
+        },
+        .deref_expr => return c.genExpr(data.un),
+        .compound_literal_expr => {
+            const ty = c.node_ty[@intFromEnum(node)];
+            const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser
+            const @"align" = ty.alignof(c.comp);
+            const alloc = try c.builder.addAlloc(size, @"align");
+            try c.genInitializer(alloc, ty, data.un);
+            return alloc;
+        },
+        .builtin_choose_expr => {
+            const cond = c.tree.value_map.get(data.if3.cond).?;
+            if (cond.getBool()) {
+                return c.genLval(c.tree.data[data.if3.body]);
+            } else {
+                return c.genLval(c.tree.data[data.if3.body + 1]);
+            }
+        },
+        .member_access_expr,
+        .member_access_ptr_expr,
+        .array_access_expr,
+        => return c.comp.diag.fatalNoSrc("TODO CodeGen.genLval {}\n", .{c.node_tag[@intFromEnum(node)]}),
+        else => unreachable, // Not an lval expression.
+    }
+}
+
+fn genBoolExpr(c: *CodeGen, base: NodeIndex, true_label: Ir.Ref, false_label: Ir.Ref) Error!void {
+    var node = base;
+    while (true) switch (c.node_tag[@intFromEnum(node)]) {
+        .paren_expr => {
+            node = c.node_data[@intFromEnum(node)].un;
+        },
+        else => break,
+    };
+
+    const data = c.node_data[@intFromEnum(node)];
+    switch (c.node_tag[@intFromEnum(node)]) {
+        .bool_or_expr => {
+            if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
+                const cond = lhs.getBool();
+                if (cond) {
+                    if (true_label == c.bool_end_label) {
+                        return c.addBoolPhi(!c.bool_invert);
+                    }
+                    return c.builder.addJump(true_label);
+                }
+                return c.genBoolExpr(data.bin.rhs, true_label, false_label);
+            }
+
+            const new_false_label = try c.builder.makeLabel("bool_false");
+            try c.genBoolExpr(data.bin.lhs, true_label, new_false_label);
+            try c.builder.startBlock(new_false_label);
+
+            if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(1), ty);
+            return c.genBoolExpr(data.bin.rhs, true_label, false_label);
+        },
+        .bool_and_expr => {
+            if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
+                const cond = lhs.getBool();
+                if (!cond) {
+                    if (false_label == c.bool_end_label) {
+                        return c.addBoolPhi(c.bool_invert);
+                    }
+                    return c.builder.addJump(false_label);
+                }
+                return c.genBoolExpr(data.bin.rhs, true_label, false_label);
+            }
+
+            const new_true_label = try c.builder.makeLabel("bool_true");
+            try c.genBoolExpr(data.bin.lhs, new_true_label, false_label);
+            try c.builder.startBlock(new_true_label);
+
+            if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(1), ty);
+            return c.genBoolExpr(data.bin.rhs, true_label, false_label);
+        },
+        .bool_not_expr => {
+            c.bool_invert = !c.bool_invert;
+            defer c.bool_invert = !c.bool_invert;
+
+            if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(0), ty);
+            return c.genBoolExpr(data.un, false_label, true_label);
+        },
+        .equal_expr => {
+            const cmp = try c.genComparison(node, .cmp_eq);
+            if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+            return c.addBranch(cmp, true_label, false_label);
+        },
+        .not_equal_expr => {
+            const cmp = try c.genComparison(node, .cmp_ne);
+            if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+            return c.addBranch(cmp, true_label, false_label);
+        },
+        .less_than_expr => {
+            const cmp = try c.genComparison(node, .cmp_lt);
+            if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+            return c.addBranch(cmp, true_label, false_label);
+        },
+        .less_than_equal_expr => {
+            const cmp = try c.genComparison(node, .cmp_lte);
+            if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+            return c.addBranch(cmp, true_label, false_label);
+        },
+        .greater_than_expr => {
+            const cmp = try c.genComparison(node, .cmp_gt);
+            if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+            return c.addBranch(cmp, true_label, false_label);
+        },
+        .greater_than_equal_expr => {
+            const cmp = try c.genComparison(node, .cmp_gte);
+            if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+            return c.addBranch(cmp, true_label, false_label);
+        },
+        .explicit_cast, .implicit_cast => switch (data.cast.kind) {
+            .bool_to_int => {
+                const operand = try c.genExpr(data.cast.operand);
+                if (c.cond_dummy_ty != null) c.cond_dummy_ref = operand;
+                return c.addBranch(operand, true_label, false_label);
+            },
+            else => {},
+        },
+        .binary_cond_expr => {
+            if (c.tree.value_map.get(data.if3.cond)) |cond| {
+                if (cond.getBool()) {
+                    return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
+                } else {
+                    return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
+                }
+            }
+
+            const new_false_label = try c.builder.makeLabel("ternary.else");
+            try c.genBoolExpr(data.if3.cond, true_label, new_false_label);
+
+            try c.builder.startBlock(new_false_label);
+            if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(1), ty);
+            return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
+        },
+        .cond_expr => {
+            if (c.tree.value_map.get(data.if3.cond)) |cond| {
+                if (cond.getBool()) {
+                    return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
+                } else {
+                    return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
+                }
+            }
+
+            const new_true_label = try c.builder.makeLabel("ternary.then");
+            const new_false_label = try c.builder.makeLabel("ternary.else");
+            try c.genBoolExpr(data.if3.cond, new_true_label, new_false_label);
+
+            try c.builder.startBlock(new_true_label);
+            try c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
+            try c.builder.startBlock(new_false_label);
+            if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(Value.int(1), ty);
+            return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
+        },
+        else => {},
+    }
+
+    if (c.tree.value_map.get(node)) |value| {
+        if (value.getBool()) {
+            if (true_label == c.bool_end_label) {
+                return c.addBoolPhi(!c.bool_invert);
+            }
+            return c.builder.addJump(true_label);
+        } else {
+            if (false_label == c.bool_end_label) {
+                return c.addBoolPhi(c.bool_invert);
+            }
+            return c.builder.addJump(false_label);
+        }
+    }
+
+    // Assume int operand.
+    const lhs = try c.genExpr(node);
+    const rhs = try c.builder.addConstant(Value.int(0), try c.genType(c.node_ty[@intFromEnum(node)]));
+    const cmp = try c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
+    if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
+    try c.addBranch(cmp, true_label, false_label);
+}
+
+fn genBuiltinCall(c: *CodeGen, builtin: BuiltinFunction, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref {
+    _ = arg_nodes;
+    _ = ty;
+    return c.comp.diag.fatalNoSrc("TODO CodeGen.genBuiltinCall {s}\n", .{@tagName(builtin.tag)});
+}
+
+fn genCall(c: *CodeGen, fn_node: NodeIndex, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref {
+    // Detect direct calls.
+    const fn_ref = blk: {
+        const data = c.node_data[@intFromEnum(fn_node)];
+        if (c.node_tag[@intFromEnum(fn_node)] != .implicit_cast or data.cast.kind != .function_to_pointer) {
+            break :blk try c.genExpr(fn_node);
+        }
+
+        var cur = @intFromEnum(data.cast.operand);
+        while (true) switch (c.node_tag[cur]) {
+            .paren_expr, .addr_of_expr, .deref_expr => {
+                cur = @intFromEnum(c.node_data[cur].un);
+            },
+            .implicit_cast => {
+                const cast = c.node_data[cur].cast;
+                if (cast.kind != .function_to_pointer) {
+                    break :blk try c.genExpr(fn_node);
+                }
+                cur = @intFromEnum(cast.operand);
+            },
+            .decl_ref_expr => {
+                const slice = c.tree.tokSlice(c.node_data[cur].decl_ref);
+                const name = try c.comp.intern(slice);
+                var i = c.symbols.items.len;
+                while (i > 0) {
+                    i -= 1;
+                    if (c.symbols.items[i].name == name) {
+                        break :blk try c.genExpr(fn_node);
+                    }
+                }
+
+                const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
+                const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
+                try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
+                break :blk ref;
+            },
+            else => break :blk try c.genExpr(fn_node),
+        };
+    };
+
+    const args = try c.builder.arena.allocator().alloc(Ir.Ref, arg_nodes.len);
+    for (arg_nodes, args) |node, *arg| {
+        // TODO handle calling convention here
+        arg.* = try c.genExpr(node);
+    }
+    // TODO handle variadic call
+    const call = try c.builder.arena.allocator().create(Ir.Inst.Call);
+    call.* = .{
+        .func = fn_ref,
+        .args_len = @intCast(args.len),
+        .args_ptr = args.ptr,
+    };
+    return c.builder.addInst(.call, .{ .call = call }, try c.genType(ty));
+}
+
+fn genCompoundAssign(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
+    const bin = c.node_data[@intFromEnum(node)].bin;
+    const ty = c.node_ty[@intFromEnum(node)];
+    const rhs = try c.genExpr(bin.rhs);
+    const lhs = try c.genLval(bin.lhs);
+    const res = try c.addBin(tag, lhs, rhs, ty);
+    try c.builder.addStore(lhs, res);
+    return res;
+}
+
+fn genBinOp(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
+    const bin = c.node_data[@intFromEnum(node)].bin;
+    const ty = c.node_ty[@intFromEnum(node)];
+    const lhs = try c.genExpr(bin.lhs);
+    const rhs = try c.genExpr(bin.rhs);
+    return c.addBin(tag, lhs, rhs, ty);
+}
+
+fn genComparison(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
+    const bin = c.node_data[@intFromEnum(node)].bin;
+    const lhs = try c.genExpr(bin.lhs);
+    const rhs = try c.genExpr(bin.rhs);
+
+    return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
+}
+
+fn genPtrArithmetic(c: *CodeGen, ptr: Ir.Ref, offset: Ir.Ref, offset_ty: Type, ty: Type) Error!Ir.Ref {
+    // TODO consider adding a getelemptr instruction
+    const size = ty.elemType().sizeof(c.comp).?;
+    if (size == 1) {
+        return c.builder.addInst(.add, .{ .bin = .{ .lhs = ptr, .rhs = offset } }, try c.genType(ty));
+    }
+
+    const size_inst = try c.builder.addConstant(Value.int(size), try c.genType(offset_ty));
+    const offset_inst = try c.addBin(.mul, offset, size_inst, offset_ty);
+    return c.addBin(.add, ptr, offset_inst, offset_ty);
+}
+
+fn genInitializer(c: *CodeGen, ptr: Ir.Ref, dest_ty: Type, initializer: NodeIndex) Error!void {
+    std.debug.assert(initializer != .none);
+    switch (c.node_tag[@intFromEnum(initializer)]) {
+        .array_init_expr_two,
+        .array_init_expr,
+        .struct_init_expr_two,
+        .struct_init_expr,
+        .union_init_expr,
+        .array_filler_expr,
+        .default_init_expr,
+        => return c.comp.diag.fatalNoSrc("TODO CodeGen.genInitializer {}\n", .{c.node_tag[@intFromEnum(initializer)]}),
+        .string_literal_expr => {
+            const val = c.tree.value_map.get(initializer).?;
+            const str_ptr = try c.builder.addConstant(val, .ptr);
+            if (dest_ty.isArray()) {
+                return c.comp.diag.fatalNoSrc("TODO memcpy\n", .{});
+            } else {
+                try c.builder.addStore(ptr, str_ptr);
+            }
+        },
+        else => {
+            const res = try c.genExpr(initializer);
+            try c.builder.addStore(ptr, res);
+        },
+    }
+}
+
+fn genVar(c: *CodeGen, decl: NodeIndex) Error!void {
+    _ = decl;
+    return c.comp.diag.fatalNoSrc("TODO CodeGen.genVar\n", .{});
+}
deps/aro/Codegen_legacy.zig
@@ -0,0 +1,108 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const Tree = @import("Tree.zig");
+const NodeIndex = Tree.NodeIndex;
+const Object = @import("Object.zig");
+const x86_64 = @import("codegen/x86_64.zig");
+
+const Codegen = @This();
+
+comp: *Compilation,
+tree: Tree,
+obj: *Object,
+node_tag: []const Tree.Tag,
+node_data: []const Tree.Node.Data,
+
+pub const Error = Compilation.Error || error{CodegenFailed};
+
+/// Generate tree to an object file.
+/// Caller is responsible for flushing and freeing the returned object.
+pub fn generateTree(comp: *Compilation, tree: Tree) Compilation.Error!*Object {
+    var c = Codegen{
+        .comp = comp,
+        .tree = tree,
+        .obj = try Object.create(comp),
+        .node_tag = tree.nodes.items(.tag),
+        .node_data = tree.nodes.items(.data),
+    };
+    errdefer c.obj.deinit();
+
+    const node_tags = tree.nodes.items(.tag);
+    for (tree.root_decls) |decl| {
+        switch (node_tags[@intFromEnum(decl)]) {
+            // these produce no code
+            .static_assert,
+            .typedef,
+            .struct_decl_two,
+            .union_decl_two,
+            .enum_decl_two,
+            .struct_decl,
+            .union_decl,
+            .enum_decl,
+            .struct_forward_decl,
+            .union_forward_decl,
+            .enum_forward_decl,
+            => {},
+
+            // define symbol
+            .fn_proto,
+            .static_fn_proto,
+            .inline_fn_proto,
+            .inline_static_fn_proto,
+            .extern_var,
+            .threadlocal_extern_var,
+            => {
+                const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
+                _ = try c.obj.declareSymbol(.undefined, name, .Strong, .external, 0, 0);
+            },
+
+            // function definition
+            .fn_def,
+            .static_fn_def,
+            .inline_fn_def,
+            .inline_static_fn_def,
+            => c.genFn(decl) catch |err| switch (err) {
+                error.FatalError => return error.FatalError,
+                error.OutOfMemory => return error.OutOfMemory,
+                error.CodegenFailed => continue,
+            },
+
+            .@"var",
+            .static_var,
+            .threadlocal_var,
+            .threadlocal_static_var,
+            .implicit_static_var,
+            => c.genVar(decl) catch |err| switch (err) {
+                error.FatalError => return error.FatalError,
+                error.OutOfMemory => return error.OutOfMemory,
+                error.CodegenFailed => continue,
+            },
+
+            // TODO
+            .file_scope_asm => {},
+
+            else => unreachable,
+        }
+    }
+
+    return c.obj;
+}
+
+fn genFn(c: *Codegen, decl: NodeIndex) Error!void {
+    const section: Object.Section = .func;
+    const data = try c.obj.getSection(section);
+    const start_len = data.items.len;
+    switch (c.comp.target.cpu.arch) {
+        .x86_64 => try x86_64.genFn(c, decl, data),
+        else => unreachable,
+    }
+    const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
+    _ = try c.obj.declareSymbol(section, name, .Strong, .func, start_len, data.items.len - start_len);
+}
+
+fn genVar(c: *Codegen, decl: NodeIndex) Error!void {
+    switch (c.comp.target.cpu.arch) {
+        .x86_64 => try x86_64.genVar(c, decl),
+        else => unreachable,
+    }
+}
deps/aro/Compilation.zig
@@ -0,0 +1,1491 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const EpochSeconds = std.time.epoch.EpochSeconds;
+const Builtins = @import("Builtins.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const LangOpts = @import("LangOpts.zig");
+const Source = @import("Source.zig");
+const Tokenizer = @import("Tokenizer.zig");
+const Token = Tokenizer.Token;
+const Type = @import("Type.zig");
+const Pragma = @import("Pragma.zig");
+const StringInterner = @import("StringInterner.zig");
+const record_layout = @import("record_layout.zig");
+const target_util = @import("target.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+
+const Compilation = @This();
+
+pub const Error = error{
+    /// A fatal error has ocurred and compilation has stopped.
+    FatalError,
+} || Allocator.Error;
+
+pub const bit_int_max_bits = 128;
+const path_buf_stack_limit = 1024;
+
+/// Environment variables used during compilation / linking.
+pub const Environment = struct {
+    /// Directory to use for temporary files
+    /// TODO: not implemented yet
+    tmpdir: ?[]const u8 = null,
+
+    /// PATH environment variable used to search for programs
+    path: ?[]const u8 = null,
+
+    /// Directories to try when searching for subprograms.
+    /// TODO: not implemented yet
+    compiler_path: ?[]const u8 = null,
+
+    /// Directories to try when searching for special linker files, if compiling for the native target
+    /// TODO: not implemented yet
+    library_path: ?[]const u8 = null,
+
+    /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line
+    /// Used regardless of the language being compiled
+    /// TODO: not implemented yet
+    cpath: ?[]const u8 = null,
+
+    /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line
+    /// Used if the language being compiled is C
+    /// TODO: not implemented yet
+    c_include_path: ?[]const u8 = null,
+
+    /// UNIX timestamp to be used instead of the current date and time in the __DATE__ and __TIME__ macros
+    source_date_epoch: ?[]const u8 = null,
+
+    /// Load all of the environment variables using the std.process API. Do not use if using Aro as a shared library on Linux without libc
+    /// See https://github.com/ziglang/zig/issues/4524
+    /// Assumes that `self` has been default-initialized
+    pub fn loadAll(self: *Environment, allocator: std.mem.Allocator) !void {
+        errdefer self.deinit(allocator);
+
+        inline for (@typeInfo(@TypeOf(self.*)).Struct.fields) |field| {
+            std.debug.assert(@field(self, field.name) == null);
+
+            var env_var_buf: [field.name.len]u8 = undefined;
+            const env_var_name = std.ascii.upperString(&env_var_buf, field.name);
+            const val: ?[]const u8 = std.process.getEnvVarOwned(allocator, env_var_name) catch |err| switch (err) {
+                error.OutOfMemory => |e| return e,
+                error.EnvironmentVariableNotFound => null,
+                error.InvalidUtf8 => null,
+            };
+            @field(self, field.name) = val;
+        }
+    }
+
+    /// Use this only if environment slices were allocated with `allocator` (such as via `loadAll`)
+    pub fn deinit(self: *Environment, allocator: std.mem.Allocator) void {
+        inline for (@typeInfo(@TypeOf(self.*)).Struct.fields) |field| {
+            if (@field(self, field.name)) |slice| {
+                allocator.free(slice);
+            }
+        }
+        self.* = undefined;
+    }
+};
+
+gpa: Allocator,
+environment: Environment = .{},
+sources: std.StringArrayHashMap(Source),
+diag: Diagnostics,
+include_dirs: std.ArrayList([]const u8),
+system_include_dirs: std.ArrayList([]const u8),
+target: std.Target = @import("builtin").target,
+pragma_handlers: std.StringArrayHashMap(*Pragma),
+langopts: LangOpts = .{},
+generated_buf: std.ArrayList(u8),
+builtins: Builtins = .{},
+types: struct {
+    wchar: Type = undefined,
+    ptrdiff: Type = undefined,
+    size: Type = undefined,
+    va_list: Type = undefined,
+    pid_t: Type = undefined,
+    ns_constant_string: struct {
+        ty: Type = undefined,
+        record: Type.Record = undefined,
+        fields: [4]Type.Record.Field = undefined,
+        int_ty: Type = .{ .specifier = .int, .qual = .{ .@"const" = true } },
+        char_ty: Type = .{ .specifier = .char, .qual = .{ .@"const" = true } },
+    } = .{},
+    file: Type = .{ .specifier = .invalid },
+    jmp_buf: Type = .{ .specifier = .invalid },
+    sigjmp_buf: Type = .{ .specifier = .invalid },
+    ucontext_t: Type = .{ .specifier = .invalid },
+    intmax: Type = .{ .specifier = .invalid },
+    intptr: Type = .{ .specifier = .invalid },
+    int16: Type = .{ .specifier = .invalid },
+    int64: Type = .{ .specifier = .invalid },
+} = .{},
+/// Mapping from Source.Id to byte offset of first non-utf8 byte
+invalid_utf8_locs: std.AutoHashMapUnmanaged(Source.Id, u32) = .{},
+string_interner: StringInterner = .{},
+
+pub fn init(gpa: Allocator) Compilation {
+    return .{
+        .gpa = gpa,
+        .sources = std.StringArrayHashMap(Source).init(gpa),
+        .diag = Diagnostics.init(gpa),
+        .include_dirs = std.ArrayList([]const u8).init(gpa),
+        .system_include_dirs = std.ArrayList([]const u8).init(gpa),
+        .pragma_handlers = std.StringArrayHashMap(*Pragma).init(gpa),
+        .generated_buf = std.ArrayList(u8).init(gpa),
+    };
+}
+
+pub fn deinit(comp: *Compilation) void {
+    for (comp.pragma_handlers.values()) |pragma| {
+        pragma.deinit(pragma, comp);
+    }
+    for (comp.sources.values()) |source| {
+        comp.gpa.free(source.path);
+        comp.gpa.free(source.buf);
+        comp.gpa.free(source.splice_locs);
+    }
+    comp.sources.deinit();
+    comp.diag.deinit();
+    comp.include_dirs.deinit();
+    for (comp.system_include_dirs.items) |path| comp.gpa.free(path);
+    comp.system_include_dirs.deinit();
+    comp.pragma_handlers.deinit();
+    comp.generated_buf.deinit();
+    comp.builtins.deinit(comp.gpa);
+    comp.invalid_utf8_locs.deinit(comp.gpa);
+    comp.string_interner.deinit(comp.gpa);
+}
+
+pub fn intern(comp: *Compilation, str: []const u8) !StringInterner.StringId {
+    return comp.string_interner.intern(comp.gpa, str);
+}
+
+pub fn getSourceEpoch(self: *const Compilation, max: i64) !?i64 {
+    const provided = self.environment.source_date_epoch orelse return null;
+    const parsed = std.fmt.parseInt(i64, provided, 10) catch return error.InvalidEpoch;
+    if (parsed < 0 or parsed > max) return error.InvalidEpoch;
+    return parsed;
+}
+
+/// Dec 31 9999 23:59:59
+const max_timestamp = 253402300799;
+
+fn getTimestamp(comp: *Compilation) !u47 {
+    const provided: ?i64 = comp.getSourceEpoch(max_timestamp) catch blk: {
+        try comp.diag.add(.{
+            .tag = .invalid_source_epoch,
+            .loc = .{ .id = .unused, .byte_offset = 0, .line = 0 },
+        }, &.{});
+        break :blk null;
+    };
+    const timestamp = provided orelse std.time.timestamp();
+    return @intCast(std.math.clamp(timestamp, 0, max_timestamp));
+}
+
+fn generateDateAndTime(w: anytype, timestamp: u47) !void {
+    const epoch_seconds = EpochSeconds{ .secs = timestamp };
+    const epoch_day = epoch_seconds.getEpochDay();
+    const day_seconds = epoch_seconds.getDaySeconds();
+    const year_day = epoch_day.calculateYearDay();
+    const month_day = year_day.calculateMonthDay();
+
+    const month_names = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+    std.debug.assert(std.time.epoch.Month.jan.numeric() == 1);
+
+    const month_name = month_names[month_day.month.numeric() - 1];
+    try w.print("#define __DATE__ \"{s} {d: >2} {d}\"\n", .{
+        month_name,
+        month_day.day_index + 1,
+        year_day.year,
+    });
+    try w.print("#define __TIME__ \"{d:0>2}:{d:0>2}:{d:0>2}\"\n", .{
+        day_seconds.getHoursIntoDay(),
+        day_seconds.getMinutesIntoHour(),
+        day_seconds.getSecondsIntoMinute(),
+    });
+
+    const day_names = [_][]const u8{ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+    // days since Thu Oct 1 1970
+    const day_name = day_names[@intCast((epoch_day.day + 3) % 7)];
+    try w.print("#define __TIMESTAMP__ \"{s} {s} {d: >2} {d:0>2}:{d:0>2}:{d:0>2} {d}\"\n", .{
+        day_name,
+        month_name,
+        month_day.day_index + 1,
+        day_seconds.getHoursIntoDay(),
+        day_seconds.getMinutesIntoHour(),
+        day_seconds.getSecondsIntoMinute(),
+        year_day.year,
+    });
+}
+
+/// Generate builtin macros that will be available to each source file.
+pub fn generateBuiltinMacros(comp: *Compilation) !Source {
+    try comp.generateBuiltinTypes();
+
+    var buf = std.ArrayList(u8).init(comp.gpa);
+    defer buf.deinit();
+    const w = buf.writer();
+
+    // standard macros
+    try w.writeAll(
+        \\#define __VERSION__ "Aro 
+    ++ @import("lib.zig").version_str ++ "\"\n" ++
+        \\#define __Aro__
+        \\#define __STDC__ 1
+        \\#define __STDC_HOSTED__ 1
+        \\#define __STDC_NO_ATOMICS__ 1
+        \\#define __STDC_NO_COMPLEX__ 1
+        \\#define __STDC_NO_THREADS__ 1
+        \\#define __STDC_NO_VLA__ 1
+        \\
+    );
+    if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| {
+        try w.print("#define __STDC_VERSION__ {s}\n", .{stdc_version});
+    }
+    const ptr_width = comp.target.ptrBitWidth();
+
+    // os macros
+    switch (comp.target.os.tag) {
+        .linux => try w.writeAll(
+            \\#define linux 1
+            \\#define __linux 1
+            \\#define __linux__ 1
+            \\
+        ),
+        .windows => if (ptr_width == 32) try w.writeAll(
+            \\#define WIN32 1
+            \\#define _WIN32 1
+            \\#define __WIN32 1
+            \\#define __WIN32__ 1
+            \\
+        ) else try w.writeAll(
+            \\#define WIN32 1
+            \\#define WIN64 1
+            \\#define _WIN32 1
+            \\#define _WIN64 1
+            \\#define __WIN32 1
+            \\#define __WIN64 1
+            \\#define __WIN32__ 1
+            \\#define __WIN64__ 1
+            \\
+        ),
+        .freebsd => try w.print("#define __FreeBSD__ {d}\n", .{comp.target.os.version_range.semver.min.major}),
+        .netbsd => try w.writeAll("#define __NetBSD__ 1\n"),
+        .openbsd => try w.writeAll("#define __OpenBSD__ 1\n"),
+        .dragonfly => try w.writeAll("#define __DragonFly__ 1\n"),
+        .solaris => try w.writeAll(
+            \\#define sun 1
+            \\#define __sun 1
+            \\
+        ),
+        .macos => try w.writeAll(
+            \\#define __APPLE__ 1
+            \\#define __MACH__ 1
+            \\
+        ),
+        else => {},
+    }
+
+    // unix and other additional os macros
+    switch (comp.target.os.tag) {
+        .freebsd,
+        .netbsd,
+        .openbsd,
+        .dragonfly,
+        .linux,
+        => try w.writeAll(
+            \\#define unix 1
+            \\#define __unix 1
+            \\#define __unix__ 1
+            \\
+        ),
+        else => {},
+    }
+    if (comp.target.abi == .android) {
+        try w.writeAll("#define __ANDROID__ 1\n");
+    }
+
+    // architecture macros
+    switch (comp.target.cpu.arch) {
+        .x86_64 => try w.writeAll(
+            \\#define __amd64__ 1
+            \\#define __amd64 1
+            \\#define __x86_64 1
+            \\#define __x86_64__ 1
+            \\
+        ),
+        .x86 => try w.writeAll(
+            \\#define i386 1
+            \\#define __i386 1
+            \\#define __i386__ 1
+            \\
+        ),
+        .mips,
+        .mipsel,
+        .mips64,
+        .mips64el,
+        => try w.writeAll(
+            \\#define __mips__ 1
+            \\#define mips 1
+            \\
+        ),
+        .powerpc,
+        .powerpcle,
+        => try w.writeAll(
+            \\#define __powerpc__ 1
+            \\#define __POWERPC__ 1
+            \\#define __ppc__ 1
+            \\#define __PPC__ 1
+            \\#define _ARCH_PPC 1
+            \\
+        ),
+        .powerpc64,
+        .powerpc64le,
+        => try w.writeAll(
+            \\#define __powerpc 1
+            \\#define __powerpc__ 1
+            \\#define __powerpc64__ 1
+            \\#define __POWERPC__ 1
+            \\#define __ppc__ 1
+            \\#define __ppc64__ 1
+            \\#define __PPC__ 1
+            \\#define __PPC64__ 1
+            \\#define _ARCH_PPC 1
+            \\#define _ARCH_PPC64 1
+            \\
+        ),
+        .sparc64 => try w.writeAll(
+            \\#define __sparc__ 1
+            \\#define __sparc 1
+            \\#define __sparc_v9__ 1
+            \\
+        ),
+        .sparc, .sparcel => try w.writeAll(
+            \\#define __sparc__ 1
+            \\#define __sparc 1
+            \\
+        ),
+        .arm, .armeb => try w.writeAll(
+            \\#define __arm__ 1
+            \\#define __arm 1
+            \\
+        ),
+        .thumb, .thumbeb => try w.writeAll(
+            \\#define __arm__ 1
+            \\#define __arm 1
+            \\#define __thumb__ 1
+            \\
+        ),
+        .aarch64, .aarch64_be => try w.writeAll("#define __aarch64__ 1\n"),
+        .msp430 => try w.writeAll(
+            \\#define MSP430 1
+            \\#define __MSP430__ 1
+            \\
+        ),
+        else => {},
+    }
+
+    if (comp.target.os.tag != .windows) switch (ptr_width) {
+        64 => try w.writeAll(
+            \\#define _LP64 1
+            \\#define __LP64__ 1
+            \\
+        ),
+        32 => try w.writeAll("#define _ILP32 1\n"),
+        else => {},
+    };
+
+    try w.writeAll(
+        \\#define __ORDER_LITTLE_ENDIAN__ 1234
+        \\#define __ORDER_BIG_ENDIAN__ 4321
+        \\#define __ORDER_PDP_ENDIAN__ 3412
+        \\
+    );
+    if (comp.target.cpu.arch.endian() == .Little) try w.writeAll(
+        \\#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+        \\#define __LITTLE_ENDIAN__ 1
+        \\
+    ) else try w.writeAll(
+        \\#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
+        \\#define __BIG_ENDIAN__ 1
+        \\
+    );
+
+    // timestamps
+    const timestamp = try comp.getTimestamp();
+    try generateDateAndTime(w, timestamp);
+
+    // types
+    if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");
+    try w.writeAll("#define __CHAR_BIT__ 8\n");
+
+    // int maxs
+    try comp.generateIntWidth(w, "BOOL", .{ .specifier = .bool });
+    try comp.generateIntMaxAndWidth(w, "SCHAR", .{ .specifier = .schar });
+    try comp.generateIntMaxAndWidth(w, "SHRT", .{ .specifier = .short });
+    try comp.generateIntMaxAndWidth(w, "INT", .{ .specifier = .int });
+    try comp.generateIntMaxAndWidth(w, "LONG", .{ .specifier = .long });
+    try comp.generateIntMaxAndWidth(w, "LONG_LONG", .{ .specifier = .long_long });
+    try comp.generateIntMaxAndWidth(w, "WCHAR", comp.types.wchar);
+    // try comp.generateIntMax(w, "WINT", comp.types.wchar);
+    try comp.generateIntMaxAndWidth(w, "INTMAX", comp.types.intmax);
+    try comp.generateIntMaxAndWidth(w, "SIZE", comp.types.size);
+    try comp.generateIntMaxAndWidth(w, "UINTMAX", comp.types.intmax.makeIntegerUnsigned());
+    try comp.generateIntMaxAndWidth(w, "PTRDIFF", comp.types.ptrdiff);
+    try comp.generateIntMaxAndWidth(w, "INTPTR", comp.types.intptr);
+    try comp.generateIntMaxAndWidth(w, "UINTPTR", comp.types.intptr.makeIntegerUnsigned());
+
+    // int widths
+    try w.print("#define __BITINT_MAXWIDTH__ {d}\n", .{bit_int_max_bits});
+
+    // sizeof types
+    try comp.generateSizeofType(w, "__SIZEOF_FLOAT__", .{ .specifier = .float });
+    try comp.generateSizeofType(w, "__SIZEOF_DOUBLE__", .{ .specifier = .double });
+    try comp.generateSizeofType(w, "__SIZEOF_LONG_DOUBLE__", .{ .specifier = .long_double });
+    try comp.generateSizeofType(w, "__SIZEOF_SHORT__", .{ .specifier = .short });
+    try comp.generateSizeofType(w, "__SIZEOF_INT__", .{ .specifier = .int });
+    try comp.generateSizeofType(w, "__SIZEOF_LONG__", .{ .specifier = .long });
+    try comp.generateSizeofType(w, "__SIZEOF_LONG_LONG__", .{ .specifier = .long_long });
+    try comp.generateSizeofType(w, "__SIZEOF_POINTER__", .{ .specifier = .pointer });
+    try comp.generateSizeofType(w, "__SIZEOF_PTRDIFF_T__", comp.types.ptrdiff);
+    try comp.generateSizeofType(w, "__SIZEOF_SIZE_T__", comp.types.size);
+    try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.types.wchar);
+    // try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .{ .specifier = .pointer });
+
+    // various int types
+    const mapper = comp.string_interner.getSlowTypeMapper();
+    try generateTypeMacro(w, mapper, "__INTPTR_TYPE__", comp.types.intptr, comp.langopts);
+    try generateTypeMacro(w, mapper, "__UINTPTR_TYPE__", comp.types.intptr.makeIntegerUnsigned(), comp.langopts);
+
+    try generateTypeMacro(w, mapper, "__INTMAX_TYPE__", comp.types.intmax, comp.langopts);
+    try comp.generateSuffixMacro("__INTMAX", w, comp.types.intptr);
+
+    try generateTypeMacro(w, mapper, "__UINTMAX_TYPE__", comp.types.intmax.makeIntegerUnsigned(), comp.langopts);
+    try comp.generateSuffixMacro("__UINTMAX", w, comp.types.intptr.makeIntegerUnsigned());
+
+    try generateTypeMacro(w, mapper, "__PTRDIFF_TYPE__", comp.types.ptrdiff, comp.langopts);
+    try generateTypeMacro(w, mapper, "__SIZE_TYPE__", comp.types.size, comp.langopts);
+    try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar, comp.langopts);
+
+    try comp.generateExactWidthTypes(w, mapper);
+
+    if (target_util.FPSemantics.halfPrecisionType(comp.target)) |half| {
+        try generateFloatMacros(w, "FLT16", half, "F16");
+    }
+    try generateFloatMacros(w, "FLT", target_util.FPSemantics.forType(.float, comp.target), "F");
+    try generateFloatMacros(w, "DBL", target_util.FPSemantics.forType(.double, comp.target), "");
+    try generateFloatMacros(w, "LDBL", target_util.FPSemantics.forType(.longdouble, comp.target), "L");
+
+    // TODO: clang treats __FLT_EVAL_METHOD__ as a special-cased macro because evaluating it within a scope
+    // where `#pragma clang fp eval_method(X)` has been called produces an error diagnostic.
+    const flt_eval_method = comp.langopts.fp_eval_method orelse target_util.defaultFpEvalMethod(comp.target);
+    try w.print("#define __FLT_EVAL_METHOD__ {d}\n", .{@intFromEnum(flt_eval_method)});
+
+    try w.writeAll(
+        \\#define __FLT_RADIX__ 2
+        \\#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+        \\
+    );
+
+    return comp.addSourceFromBuffer("<builtin>", buf.items);
+}
+
+fn generateFloatMacros(w: anytype, prefix: []const u8, semantics: target_util.FPSemantics, ext: []const u8) !void {
+    const denormMin = semantics.chooseValue(
+        []const u8,
+        .{
+            "5.9604644775390625e-8",
+            "1.40129846e-45",
+            "4.9406564584124654e-324",
+            "3.64519953188247460253e-4951",
+            "4.94065645841246544176568792868221e-324",
+            "6.47517511943802511092443895822764655e-4966",
+        },
+    );
+    const digits = semantics.chooseValue(i32, .{ 3, 6, 15, 18, 31, 33 });
+    const decimalDigits = semantics.chooseValue(i32, .{ 5, 9, 17, 21, 33, 36 });
+    const epsilon = semantics.chooseValue(
+        []const u8,
+        .{
+            "9.765625e-4",
+            "1.19209290e-7",
+            "2.2204460492503131e-16",
+            "1.08420217248550443401e-19",
+            "4.94065645841246544176568792868221e-324",
+            "1.92592994438723585305597794258492732e-34",
+        },
+    );
+    const mantissaDigits = semantics.chooseValue(i32, .{ 11, 24, 53, 64, 106, 113 });
+
+    const min10Exp = semantics.chooseValue(i32, .{ -4, -37, -307, -4931, -291, -4931 });
+    const max10Exp = semantics.chooseValue(i32, .{ 4, 38, 308, 4932, 308, 4932 });
+
+    const minExp = semantics.chooseValue(i32, .{ -13, -125, -1021, -16381, -968, -16381 });
+    const maxExp = semantics.chooseValue(i32, .{ 16, 128, 1024, 16384, 1024, 16384 });
+
+    const min = semantics.chooseValue(
+        []const u8,
+        .{
+            "6.103515625e-5",
+            "1.17549435e-38",
+            "2.2250738585072014e-308",
+            "3.36210314311209350626e-4932",
+            "2.00416836000897277799610805135016e-292",
+            "3.36210314311209350626267781732175260e-4932",
+        },
+    );
+    const max = semantics.chooseValue(
+        []const u8,
+        .{
+            "6.5504e+4",
+            "3.40282347e+38",
+            "1.7976931348623157e+308",
+            "1.18973149535723176502e+4932",
+            "1.79769313486231580793728971405301e+308",
+            "1.18973149535723176508575932662800702e+4932",
+        },
+    );
+
+    var defPrefix = std.BoundedArray(u8, 32).init(0) catch unreachable;
+    defPrefix.writer().print("__{s}_", .{prefix}) catch return error.OutOfMemory;
+
+    const prefix_slice = defPrefix.constSlice();
+
+    try w.print("#define {s}DENORM_MIN__ {s}{s}\n", .{ prefix_slice, denormMin, ext });
+    try w.print("#define {s}HAS_DENORM__\n", .{prefix_slice});
+    try w.print("#define {s}DIG__ {d}\n", .{ prefix_slice, digits });
+    try w.print("#define {s}DECIMAL_DIG__ {d}\n", .{ prefix_slice, decimalDigits });
+
+    try w.print("#define {s}EPSILON__ {s}{s}\n", .{ prefix_slice, epsilon, ext });
+    try w.print("#define {s}HAS_INFINITY__\n", .{prefix_slice});
+    try w.print("#define {s}HAS_QUIET_NAN__\n", .{prefix_slice});
+    try w.print("#define {s}MANT_DIG__ {d}\n", .{ prefix_slice, mantissaDigits });
+
+    try w.print("#define {s}MAX_10_EXP__ {d}\n", .{ prefix_slice, max10Exp });
+    try w.print("#define {s}MAX_EXP__ {d}\n", .{ prefix_slice, maxExp });
+    try w.print("#define {s}MAX__ {s}{s}\n", .{ prefix_slice, max, ext });
+
+    try w.print("#define {s}MIN_10_EXP__ ({d})\n", .{ prefix_slice, min10Exp });
+    try w.print("#define {s}MIN_EXP__ ({d})\n", .{ prefix_slice, minExp });
+    try w.print("#define {s}MIN__ {s}{s}\n", .{ prefix_slice, min, ext });
+}
+
+fn generateTypeMacro(w: anytype, mapper: StringInterner.TypeMapper, name: []const u8, ty: Type, langopts: LangOpts) !void {
+    try w.print("#define {s} ", .{name});
+    try ty.print(mapper, langopts, w);
+    try w.writeByte('\n');
+}
+
+fn generateBuiltinTypes(comp: *Compilation) !void {
+    const os = comp.target.os.tag;
+    const wchar: Type = switch (comp.target.cpu.arch) {
+        .xcore => .{ .specifier = .uchar },
+        .ve, .msp430 => .{ .specifier = .uint },
+        .arm, .armeb, .thumb, .thumbeb => .{
+            .specifier = if (os != .windows and os != .netbsd and os != .openbsd) .uint else .int,
+        },
+        .aarch64, .aarch64_be, .aarch64_32 => .{
+            .specifier = if (!os.isDarwin() and os != .netbsd) .uint else .int,
+        },
+        .x86_64, .x86 => .{ .specifier = if (os == .windows) .ushort else .int },
+        else => .{ .specifier = .int },
+    };
+
+    const ptr_width = comp.target.ptrBitWidth();
+    const ptrdiff = if (os == .windows and ptr_width == 64)
+        Type{ .specifier = .long_long }
+    else switch (ptr_width) {
+        16 => Type{ .specifier = .int },
+        32 => Type{ .specifier = .int },
+        64 => Type{ .specifier = .long },
+        else => unreachable,
+    };
+
+    const size = if (os == .windows and ptr_width == 64)
+        Type{ .specifier = .ulong_long }
+    else switch (ptr_width) {
+        16 => Type{ .specifier = .uint },
+        32 => Type{ .specifier = .uint },
+        64 => Type{ .specifier = .ulong },
+        else => unreachable,
+    };
+
+    const va_list = try comp.generateVaListType();
+
+    const pid_t: Type = switch (os) {
+        .haiku => .{ .specifier = .long },
+        // Todo: pid_t is required to "a signed integer type"; are there any systems
+        // on which it is `short int`?
+        else => .{ .specifier = .int },
+    };
+
+    const intmax = target_util.intMaxType(comp.target);
+    const intptr = target_util.intPtrType(comp.target);
+    const int16 = target_util.int16Type(comp.target);
+    const int64 = target_util.int64Type(comp.target);
+
+    comp.types = .{
+        .wchar = wchar,
+        .ptrdiff = ptrdiff,
+        .size = size,
+        .va_list = va_list,
+        .pid_t = pid_t,
+        .intmax = intmax,
+        .intptr = intptr,
+        .int16 = int16,
+        .int64 = int64,
+    };
+
+    try comp.generateNsConstantStringType();
+}
+
+fn intSize(comp: *const Compilation, specifier: Type.Specifier) u64 {
+    const ty = Type{ .specifier = specifier };
+    return ty.sizeof(comp).?;
+}
+
+fn generateExactWidthTypes(comp: *const Compilation, w: anytype, mapper: StringInterner.TypeMapper) !void {
+    try comp.generateExactWidthType(w, mapper, .schar);
+
+    if (comp.intSize(.short) > comp.intSize(.char)) {
+        try comp.generateExactWidthType(w, mapper, .short);
+    }
+
+    if (comp.intSize(.int) > comp.intSize(.short)) {
+        try comp.generateExactWidthType(w, mapper, .int);
+    }
+
+    if (comp.intSize(.long) > comp.intSize(.int)) {
+        try comp.generateExactWidthType(w, mapper, .long);
+    }
+
+    if (comp.intSize(.long_long) > comp.intSize(.long)) {
+        try comp.generateExactWidthType(w, mapper, .long_long);
+    }
+
+    try comp.generateExactWidthType(w, mapper, .uchar);
+    try comp.generateExactWidthIntMax(w, .uchar);
+    try comp.generateExactWidthIntMax(w, .schar);
+
+    if (comp.intSize(.short) > comp.intSize(.char)) {
+        try comp.generateExactWidthType(w, mapper, .ushort);
+        try comp.generateExactWidthIntMax(w, .ushort);
+        try comp.generateExactWidthIntMax(w, .short);
+    }
+
+    if (comp.intSize(.int) > comp.intSize(.short)) {
+        try comp.generateExactWidthType(w, mapper, .uint);
+        try comp.generateExactWidthIntMax(w, .uint);
+        try comp.generateExactWidthIntMax(w, .int);
+    }
+
+    if (comp.intSize(.long) > comp.intSize(.int)) {
+        try comp.generateExactWidthType(w, mapper, .ulong);
+        try comp.generateExactWidthIntMax(w, .ulong);
+        try comp.generateExactWidthIntMax(w, .long);
+    }
+
+    if (comp.intSize(.long_long) > comp.intSize(.long)) {
+        try comp.generateExactWidthType(w, mapper, .ulong_long);
+        try comp.generateExactWidthIntMax(w, .ulong_long);
+        try comp.generateExactWidthIntMax(w, .long_long);
+    }
+}
+
+fn generateFmt(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void {
+    const unsigned = ty.isUnsignedInt(comp);
+    const modifier = ty.formatModifier();
+    const formats = if (unsigned) "ouxX" else "di";
+    for (formats) |c| {
+        try w.print("#define {s}_FMT{c}__ \"{s}{c}\"\n", .{ prefix, c, modifier, c });
+    }
+}
+
+fn generateSuffixMacro(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void {
+    return w.print("#define {s}_C_SUFFIX__ {s}\n", .{ prefix, ty.intValueSuffix(comp) });
+}
+
+/// Generate the following for ty:
+///     Name macro (e.g. #define __UINT32_TYPE__ unsigned int)
+///     Format strings (e.g. #define __UINT32_FMTu__ "u")
+///     Suffix macro (e.g. #define __UINT32_C_SUFFIX__ U)
+fn generateExactWidthType(comp: *const Compilation, w: anytype, mapper: StringInterner.TypeMapper, specifier: Type.Specifier) !void {
+    var ty = Type{ .specifier = specifier };
+    const width = 8 * ty.sizeof(comp).?;
+    const unsigned = ty.isUnsignedInt(comp);
+
+    if (width == 16) {
+        ty = if (unsigned) comp.types.int16.makeIntegerUnsigned() else comp.types.int16;
+    } else if (width == 64) {
+        ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64;
+    }
+
+    var prefix = std.BoundedArray(u8, 16).init(0) catch unreachable;
+    prefix.writer().print("{s}{d}", .{ if (unsigned) "__UINT" else "__INT", width }) catch return error.OutOfMemory;
+
+    {
+        const len = prefix.len;
+        defer prefix.resize(len) catch unreachable; // restoring previous size
+        prefix.appendSliceAssumeCapacity("_TYPE__");
+        try generateTypeMacro(w, mapper, prefix.constSlice(), ty, comp.langopts);
+    }
+
+    try comp.generateFmt(prefix.constSlice(), w, ty);
+    try comp.generateSuffixMacro(prefix.constSlice(), w, ty);
+}
+
+pub fn hasHalfPrecisionFloatABI(comp: *const Compilation) bool {
+    return comp.langopts.allow_half_args_and_returns or target_util.hasHalfPrecisionFloatABI(comp.target);
+}
+
+fn generateNsConstantStringType(comp: *Compilation) !void {
+    comp.types.ns_constant_string.record = .{
+        .name = try comp.intern("__NSConstantString_tag"),
+        .fields = &comp.types.ns_constant_string.fields,
+        .field_attributes = null,
+        .type_layout = undefined,
+    };
+    const const_int_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.int_ty } };
+    const const_char_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.char_ty } };
+
+    comp.types.ns_constant_string.fields[0] = .{ .name = try comp.intern("isa"), .ty = const_int_ptr };
+    comp.types.ns_constant_string.fields[1] = .{ .name = try comp.intern("flags"), .ty = .{ .specifier = .int } };
+    comp.types.ns_constant_string.fields[2] = .{ .name = try comp.intern("str"), .ty = const_char_ptr };
+    comp.types.ns_constant_string.fields[3] = .{ .name = try comp.intern("length"), .ty = .{ .specifier = .long } };
+    comp.types.ns_constant_string.ty = .{ .specifier = .@"struct", .data = .{ .record = &comp.types.ns_constant_string.record } };
+    record_layout.compute(&comp.types.ns_constant_string.record, comp.types.ns_constant_string.ty, comp, null);
+}
+
+fn generateVaListType(comp: *Compilation) !Type {
+    const Kind = enum { char_ptr, void_ptr, aarch64_va_list, x86_64_va_list };
+    const kind: Kind = switch (comp.target.cpu.arch) {
+        .aarch64 => switch (comp.target.os.tag) {
+            .windows => @as(Kind, .char_ptr),
+            .ios, .macos, .tvos, .watchos => .char_ptr,
+            else => .aarch64_va_list,
+        },
+        .sparc, .wasm32, .wasm64, .bpfel, .bpfeb, .riscv32, .riscv64, .avr, .spirv32, .spirv64 => .void_ptr,
+        .powerpc => switch (comp.target.os.tag) {
+            .ios, .macos, .tvos, .watchos, .aix => @as(Kind, .char_ptr),
+            else => return Type{ .specifier = .void }, // unknown
+        },
+        .x86, .msp430 => .char_ptr,
+        .x86_64 => switch (comp.target.os.tag) {
+            .windows => @as(Kind, .char_ptr),
+            else => .x86_64_va_list,
+        },
+        else => return Type{ .specifier = .void }, // unknown
+    };
+
+    // TODO this might be bad?
+    const arena = comp.diag.arena.allocator();
+
+    var ty: Type = undefined;
+    switch (kind) {
+        .char_ptr => ty = .{ .specifier = .char },
+        .void_ptr => ty = .{ .specifier = .void },
+        .aarch64_va_list => {
+            const record_ty = try arena.create(Type.Record);
+            record_ty.* = .{
+                .name = try comp.intern("__va_list_tag"),
+                .fields = try arena.alloc(Type.Record.Field, 5),
+                .field_attributes = null,
+                .type_layout = undefined, // computed below
+            };
+            const void_ty = try arena.create(Type);
+            void_ty.* = .{ .specifier = .void };
+            const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
+            record_ty.fields[0] = .{ .name = try comp.intern("__stack"), .ty = void_ptr };
+            record_ty.fields[1] = .{ .name = try comp.intern("__gr_top"), .ty = void_ptr };
+            record_ty.fields[2] = .{ .name = try comp.intern("__vr_top"), .ty = void_ptr };
+            record_ty.fields[3] = .{ .name = try comp.intern("__gr_offs"), .ty = .{ .specifier = .int } };
+            record_ty.fields[4] = .{ .name = try comp.intern("__vr_offs"), .ty = .{ .specifier = .int } };
+            ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
+            record_layout.compute(record_ty, ty, comp, null);
+        },
+        .x86_64_va_list => {
+            const record_ty = try arena.create(Type.Record);
+            record_ty.* = .{
+                .name = try comp.intern("__va_list_tag"),
+                .fields = try arena.alloc(Type.Record.Field, 4),
+                .field_attributes = null,
+                .type_layout = undefined, // computed below
+            };
+            const void_ty = try arena.create(Type);
+            void_ty.* = .{ .specifier = .void };
+            const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
+            record_ty.fields[0] = .{ .name = try comp.intern("gp_offset"), .ty = .{ .specifier = .uint } };
+            record_ty.fields[1] = .{ .name = try comp.intern("fp_offset"), .ty = .{ .specifier = .uint } };
+            record_ty.fields[2] = .{ .name = try comp.intern("overflow_arg_area"), .ty = void_ptr };
+            record_ty.fields[3] = .{ .name = try comp.intern("reg_save_area"), .ty = void_ptr };
+            ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
+            record_layout.compute(record_ty, ty, comp, null);
+        },
+    }
+    if (kind == .char_ptr or kind == .void_ptr) {
+        const elem_ty = try arena.create(Type);
+        elem_ty.* = ty;
+        ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
+    } else {
+        const arr_ty = try arena.create(Type.Array);
+        arr_ty.* = .{ .len = 1, .elem = ty };
+        ty = Type{ .specifier = .array, .data = .{ .array = arr_ty } };
+    }
+
+    return ty;
+}
+
+fn generateIntMax(comp: *const Compilation, w: anytype, name: []const u8, ty: Type) !void {
+    const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8);
+    const unsigned = ty.isUnsignedInt(comp);
+    const max = if (bit_count == 128)
+        @as(u128, if (unsigned) std.math.maxInt(u128) else std.math.maxInt(u128))
+    else
+        ty.maxInt(comp);
+    try w.print("#define __{s}_MAX__ {d}{s}\n", .{ name, max, ty.intValueSuffix(comp) });
+}
+
+fn generateExactWidthIntMax(comp: *const Compilation, w: anytype, specifier: Type.Specifier) !void {
+    var ty = Type{ .specifier = specifier };
+    const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8);
+    const unsigned = ty.isUnsignedInt(comp);
+
+    if (bit_count == 64) {
+        ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64;
+    }
+
+    var name = std.BoundedArray(u8, 6).init(0) catch unreachable;
+    name.writer().print("{s}{d}", .{ if (unsigned) "UINT" else "INT", bit_count }) catch return error.OutOfMemory;
+
+    return comp.generateIntMax(w, name.constSlice(), ty);
+}
+
+fn generateIntWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
+    try w.print("#define __{s}_WIDTH__ {d}\n", .{ name, 8 * ty.sizeof(comp).? });
+}
+
+fn generateIntMaxAndWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
+    try comp.generateIntMax(w, name, ty);
+    try comp.generateIntWidth(w, name, ty);
+}
+
+fn generateSizeofType(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
+    try w.print("#define {s} {d}\n", .{ name, ty.sizeof(comp).? });
+}
+
+pub fn nextLargestIntSameSign(comp: *const Compilation, ty: Type) ?Type {
+    assert(ty.isInt());
+    const specifiers = if (ty.isUnsignedInt(comp))
+        [_]Type.Specifier{ .short, .int, .long, .long_long }
+    else
+        [_]Type.Specifier{ .ushort, .uint, .ulong, .ulong_long };
+    const size = ty.sizeof(comp).?;
+    for (specifiers) |specifier| {
+        const candidate = Type{ .specifier = specifier };
+        if (candidate.sizeof(comp).? > size) return candidate;
+    }
+    return null;
+}
+
+/// If `enum E { ... }` syntax has a fixed underlying integer type regardless of the presence of
+/// __attribute__((packed)) or the range of values of the corresponding enumerator constants,
+/// specify it here.
+/// TODO: likely incomplete
+pub fn fixedEnumTagSpecifier(comp: *const Compilation) ?Type.Specifier {
+    switch (comp.langopts.emulate) {
+        .msvc => return .int,
+        .clang => if (comp.target.os.tag == .windows) return .int,
+        .gcc => {},
+    }
+    return null;
+}
+
+pub fn getCharSignedness(comp: *const Compilation) std.builtin.Signedness {
+    return comp.langopts.char_signedness_override orelse comp.target.charSignedness();
+}
+
+pub fn defineSystemIncludes(comp: *Compilation, aro_dir: []const u8) !void {
+    var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
+    const allocator = stack_fallback.get();
+    var search_path = aro_dir;
+    while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) {
+        var base_dir = std.fs.cwd().openDir(dirname, .{}) catch continue;
+        defer base_dir.close();
+
+        base_dir.access("include/stddef.h", .{}) catch continue;
+        const path = try std.fs.path.join(comp.gpa, &.{ dirname, "include" });
+        errdefer comp.gpa.free(path);
+        try comp.system_include_dirs.append(path);
+        break;
+    } else return error.AroIncludeNotFound;
+
+    if (comp.target.os.tag == .linux) {
+        const triple_str = try comp.target.linuxTriple(allocator);
+        defer allocator.free(triple_str);
+
+        const multiarch_path = try std.fs.path.join(allocator, &.{ "/usr/include", triple_str });
+        defer allocator.free(multiarch_path);
+
+        if (!std.meta.isError(std.fs.accessAbsolute(multiarch_path, .{}))) {
+            const duped = try comp.gpa.dupe(u8, multiarch_path);
+            errdefer comp.gpa.free(duped);
+            try comp.system_include_dirs.append(duped);
+        }
+    }
+    const usr_include = try comp.gpa.dupe(u8, "/usr/include");
+    errdefer comp.gpa.free(usr_include);
+    try comp.system_include_dirs.append(usr_include);
+}
+
+pub fn getSource(comp: *const Compilation, id: Source.Id) Source {
+    if (id == .generated) return .{
+        .path = "<scratch space>",
+        .buf = comp.generated_buf.items,
+        .id = .generated,
+        .splice_locs = &.{},
+    };
+    return comp.sources.values()[@intFromEnum(id) - 2];
+}
+
+/// Creates a Source from the contents of `reader` and adds it to the Compilation
+/// Performs newline splicing, line-ending normalization to '\n', and UTF-8 validation.
+/// caller retains ownership of `path`
+/// `expected_size` will be allocated to hold the contents of `reader` and *must* be at least
+/// as large as the entire contents of `reader`.
+/// To add a pre-existing buffer as a Source, see addSourceFromBuffer
+/// To add a file's contents given its path, see addSourceFromPath
+pub fn addSourceFromReader(comp: *Compilation, reader: anytype, path: []const u8, expected_size: u32) !Source {
+    var contents = try comp.gpa.alloc(u8, expected_size);
+    errdefer comp.gpa.free(contents);
+
+    const duped_path = try comp.gpa.dupe(u8, path);
+    errdefer comp.gpa.free(duped_path);
+
+    var splice_list = std.ArrayList(u32).init(comp.gpa);
+    defer splice_list.deinit();
+
+    const source_id: Source.Id = @enumFromInt(comp.sources.count() + 2);
+
+    var i: u32 = 0;
+    var backslash_loc: u32 = undefined;
+    var state: enum {
+        beginning_of_file,
+        bom1,
+        bom2,
+        start,
+        back_slash,
+        cr,
+        back_slash_cr,
+        trailing_ws,
+    } = .beginning_of_file;
+    var line: u32 = 1;
+
+    while (true) {
+        const byte = reader.readByte() catch |err| switch (err) {
+            error.EndOfStream => break,
+            else => |e| return e,
+        };
+        contents[i] = byte;
+
+        switch (byte) {
+            '\r' => {
+                switch (state) {
+                    .start, .cr, .beginning_of_file => {
+                        state = .start;
+                        line += 1;
+                        state = .cr;
+                        contents[i] = '\n';
+                        i += 1;
+                    },
+                    .back_slash, .trailing_ws, .back_slash_cr => {
+                        i = backslash_loc;
+                        try splice_list.append(i);
+                        if (state == .trailing_ws) {
+                            try comp.diag.add(.{
+                                .tag = .backslash_newline_escape,
+                                .loc = .{ .id = source_id, .byte_offset = i, .line = line },
+                            }, &.{});
+                        }
+                        state = if (state == .back_slash_cr) .cr else .back_slash_cr;
+                    },
+                    .bom1, .bom2 => break, // invalid utf-8
+                }
+            },
+            '\n' => {
+                switch (state) {
+                    .start, .beginning_of_file => {
+                        state = .start;
+                        line += 1;
+                        i += 1;
+                    },
+                    .cr, .back_slash_cr => {},
+                    .back_slash, .trailing_ws => {
+                        i = backslash_loc;
+                        if (state == .back_slash or state == .trailing_ws) {
+                            try splice_list.append(i);
+                        }
+                        if (state == .trailing_ws) {
+                            try comp.diag.add(.{
+                                .tag = .backslash_newline_escape,
+                                .loc = .{ .id = source_id, .byte_offset = i, .line = line },
+                            }, &.{});
+                        }
+                    },
+                    .bom1, .bom2 => break,
+                }
+                state = .start;
+            },
+            '\\' => {
+                backslash_loc = i;
+                state = .back_slash;
+                i += 1;
+            },
+            '\t', '\x0B', '\x0C', ' ' => {
+                switch (state) {
+                    .start, .trailing_ws => {},
+                    .beginning_of_file => state = .start,
+                    .cr, .back_slash_cr => state = .start,
+                    .back_slash => state = .trailing_ws,
+                    .bom1, .bom2 => break,
+                }
+                i += 1;
+            },
+            '\xEF' => {
+                i += 1;
+                state = switch (state) {
+                    .beginning_of_file => .bom1,
+                    else => .start,
+                };
+            },
+            '\xBB' => {
+                i += 1;
+                state = switch (state) {
+                    .bom1 => .bom2,
+                    else => .start,
+                };
+            },
+            '\xBF' => {
+                switch (state) {
+                    .bom2 => i = 0, // rewind and overwrite the BOM
+                    else => i += 1,
+                }
+                state = .start;
+            },
+            else => {
+                i += 1;
+                state = .start;
+            },
+        }
+    }
+
+    const splice_locs = try splice_list.toOwnedSlice();
+    errdefer comp.gpa.free(splice_locs);
+
+    if (i != contents.len) contents = try comp.gpa.realloc(contents, i);
+
+    var source = Source{
+        .id = source_id,
+        .path = duped_path,
+        .buf = contents,
+        .splice_locs = splice_locs,
+    };
+
+    try comp.sources.put(duped_path, source);
+    if (source.offsetOfInvalidUtf8()) |offset| {
+        try comp.invalid_utf8_locs.putNoClobber(comp.gpa, source_id, offset);
+    }
+    return source;
+}
+
+/// Caller retains ownership of `path` and `buf`.
+pub fn addSourceFromBuffer(comp: *Compilation, path: []const u8, buf: []const u8) !Source {
+    if (comp.sources.get(path)) |some| return some;
+
+    const size = std.math.cast(u32, buf.len) orelse return error.StreamTooLong;
+    var buf_reader = std.io.fixedBufferStream(buf);
+
+    return comp.addSourceFromReader(buf_reader.reader(), path, size);
+}
+
+/// Caller retains ownership of `path`
+pub fn addSourceFromPath(comp: *Compilation, path: []const u8) !Source {
+    if (comp.sources.get(path)) |some| return some;
+
+    if (mem.indexOfScalar(u8, path, 0) != null) {
+        return error.FileNotFound;
+    }
+
+    const file = try std.fs.cwd().openFile(path, .{});
+    defer file.close();
+
+    const size = std.math.cast(u32, try file.getEndPos()) orelse return error.StreamTooLong;
+    var buf_reader = std.io.bufferedReader(file.reader());
+
+    return comp.addSourceFromReader(buf_reader.reader(), path, size);
+}
+
+pub const IncludeDirIterator = struct {
+    comp: *const Compilation,
+    cwd_source_id: ?Source.Id,
+    include_dirs_idx: usize = 0,
+    sys_include_dirs_idx: usize = 0,
+
+    fn next(self: *IncludeDirIterator) ?[]const u8 {
+        if (self.cwd_source_id) |source_id| {
+            self.cwd_source_id = null;
+            const path = self.comp.getSource(source_id).path;
+            return std.fs.path.dirname(path) orelse ".";
+        }
+        if (self.include_dirs_idx < self.comp.include_dirs.items.len) {
+            defer self.include_dirs_idx += 1;
+            return self.comp.include_dirs.items[self.include_dirs_idx];
+        }
+        if (self.sys_include_dirs_idx < self.comp.system_include_dirs.items.len) {
+            defer self.sys_include_dirs_idx += 1;
+            return self.comp.system_include_dirs.items[self.sys_include_dirs_idx];
+        }
+        return null;
+    }
+
+    /// Returned value must be freed by allocator
+    fn nextWithFile(self: *IncludeDirIterator, filename: []const u8, allocator: Allocator) !?[]const u8 {
+        while (self.next()) |dir| {
+            return try std.fs.path.join(allocator, &.{ dir, filename });
+        }
+        return null;
+    }
+
+    /// Advance the iterator until it finds an include directory that matches
+    /// the directory which contains `source`.
+    fn skipUntilDirMatch(self: *IncludeDirIterator, source: Source.Id) void {
+        const path = self.comp.getSource(source).path;
+        const includer_path = std.fs.path.dirname(path) orelse ".";
+        while (self.next()) |dir| {
+            if (mem.eql(u8, includer_path, dir)) break;
+        }
+    }
+};
+
+pub fn hasInclude(
+    comp: *const Compilation,
+    filename: []const u8,
+    includer_token_source: Source.Id,
+    /// angle bracket vs quotes
+    include_type: IncludeType,
+    /// __has_include vs __has_include_next
+    which: WhichInclude,
+) !bool {
+    const cwd = std.fs.cwd();
+    if (std.fs.path.isAbsolute(filename)) {
+        if (which == .next) return false;
+        return !std.meta.isError(cwd.access(filename, .{}));
+    }
+
+    const cwd_source_id = switch (include_type) {
+        .quotes => switch (which) {
+            .first => includer_token_source,
+            .next => null,
+        },
+        .angle_brackets => null,
+    };
+    var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
+    if (which == .next) {
+        it.skipUntilDirMatch(includer_token_source);
+    }
+
+    var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
+
+    while (try it.nextWithFile(filename, stack_fallback.get())) |path| {
+        defer stack_fallback.get().free(path);
+        if (!std.meta.isError(cwd.access(path, .{}))) return true;
+    }
+    return false;
+}
+
+pub const WhichInclude = enum {
+    first,
+    next,
+};
+
+pub const IncludeType = enum {
+    quotes,
+    angle_brackets,
+};
+
+fn getFileContents(comp: *Compilation, path: []const u8) ![]const u8 {
+    if (mem.indexOfScalar(u8, path, 0) != null) {
+        return error.FileNotFound;
+    }
+
+    const file = try std.fs.cwd().openFile(path, .{});
+    defer file.close();
+
+    return file.readToEndAlloc(comp.gpa, std.math.maxInt(u32));
+}
+
+pub fn findEmbed(
+    comp: *Compilation,
+    filename: []const u8,
+    includer_token_source: Source.Id,
+    /// angle bracket vs quotes
+    include_type: IncludeType,
+) !?[]const u8 {
+    if (std.fs.path.isAbsolute(filename)) {
+        return if (comp.getFileContents(filename)) |some|
+            some
+        else |err| switch (err) {
+            error.OutOfMemory => |e| return e,
+            else => null,
+        };
+    }
+
+    const cwd_source_id = switch (include_type) {
+        .quotes => includer_token_source,
+        .angle_brackets => null,
+    };
+    var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
+    var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
+
+    while (try it.nextWithFile(filename, stack_fallback.get())) |path| {
+        defer stack_fallback.get().free(path);
+        if (comp.getFileContents(path)) |some|
+            return some
+        else |err| switch (err) {
+            error.OutOfMemory => return error.OutOfMemory,
+            else => {},
+        }
+    }
+    return null;
+}
+
+pub fn findInclude(
+    comp: *Compilation,
+    filename: []const u8,
+    includer_token_source: Source.Id,
+    /// angle bracket vs quotes
+    include_type: IncludeType,
+    /// include vs include_next
+    which: WhichInclude,
+) !?Source {
+    if (std.fs.path.isAbsolute(filename)) {
+        if (which == .next) return null;
+        return if (comp.addSourceFromPath(filename)) |some|
+            some
+        else |err| switch (err) {
+            error.OutOfMemory => |e| return e,
+            else => null,
+        };
+    }
+    const cwd_source_id = switch (include_type) {
+        .quotes => switch (which) {
+            .first => includer_token_source,
+            .next => null,
+        },
+        .angle_brackets => null,
+    };
+    var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
+
+    if (which == .next) {
+        it.skipUntilDirMatch(includer_token_source);
+    }
+
+    var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
+    while (try it.nextWithFile(filename, stack_fallback.get())) |path| {
+        defer stack_fallback.get().free(path);
+        if (comp.addSourceFromPath(path)) |some|
+            return some
+        else |err| switch (err) {
+            error.OutOfMemory => return error.OutOfMemory,
+            else => {},
+        }
+    }
+    return null;
+}
+
+pub fn addPragmaHandler(comp: *Compilation, name: []const u8, handler: *Pragma) Allocator.Error!void {
+    try comp.pragma_handlers.putNoClobber(name, handler);
+}
+
+pub fn addDefaultPragmaHandlers(comp: *Compilation) Allocator.Error!void {
+    const GCC = @import("pragmas/gcc.zig");
+    var gcc = try GCC.init(comp.gpa);
+    errdefer gcc.deinit(gcc, comp);
+
+    const Once = @import("pragmas/once.zig");
+    var once = try Once.init(comp.gpa);
+    errdefer once.deinit(once, comp);
+
+    const Message = @import("pragmas/message.zig");
+    var message = try Message.init(comp.gpa);
+    errdefer message.deinit(message, comp);
+
+    const Pack = @import("pragmas/pack.zig");
+    var pack = try Pack.init(comp.gpa);
+    errdefer pack.deinit(pack, comp);
+
+    try comp.addPragmaHandler("GCC", gcc);
+    try comp.addPragmaHandler("once", once);
+    try comp.addPragmaHandler("message", message);
+    try comp.addPragmaHandler("pack", pack);
+}
+
+pub fn getPragma(comp: *Compilation, name: []const u8) ?*Pragma {
+    return comp.pragma_handlers.get(name);
+}
+
+const PragmaEvent = enum {
+    before_preprocess,
+    before_parse,
+    after_parse,
+};
+
+pub fn pragmaEvent(comp: *Compilation, event: PragmaEvent) void {
+    for (comp.pragma_handlers.values()) |pragma| {
+        const maybe_func = switch (event) {
+            .before_preprocess => pragma.beforePreprocess,
+            .before_parse => pragma.beforeParse,
+            .after_parse => pragma.afterParse,
+        };
+        if (maybe_func) |func| func(pragma, comp);
+    }
+}
+
+pub fn hasBuiltin(comp: *const Compilation, name: []const u8) bool {
+    if (std.mem.eql(u8, name, "__builtin_va_arg") or
+        std.mem.eql(u8, name, "__builtin_choose_expr") or
+        std.mem.eql(u8, name, "__builtin_bitoffsetof") or
+        std.mem.eql(u8, name, "__builtin_offsetof") or
+        std.mem.eql(u8, name, "__builtin_types_compatible_p")) return true;
+
+    @setEvalBranchQuota(10_000);
+    const tag = std.meta.stringToEnum(BuiltinFunction.Tag, name) orelse return false;
+    const builtin = BuiltinFunction.fromTag(tag);
+    return comp.hasBuiltinFunction(builtin);
+}
+
+pub fn hasBuiltinFunction(comp: *const Compilation, builtin: BuiltinFunction) bool {
+    if (!target_util.builtinEnabled(comp.target, builtin.properties.target_set)) return false;
+
+    switch (builtin.properties.language) {
+        .all_languages => return true,
+        .all_ms_languages => return comp.langopts.emulate == .msvc,
+        .gnu_lang, .all_gnu_languages => return comp.langopts.standard.isGNU(),
+    }
+}
+
+pub const renderErrors = Diagnostics.render;
+
+test "addSourceFromReader" {
+    const Test = struct {
+        fn addSourceFromReader(str: []const u8, expected: []const u8, warning_count: u32, splices: []const u32) !void {
+            var comp = Compilation.init(std.testing.allocator);
+            defer comp.deinit();
+
+            var buf_reader = std.io.fixedBufferStream(str);
+            const source = try comp.addSourceFromReader(buf_reader.reader(), "path", @intCast(str.len));
+
+            try std.testing.expectEqualStrings(expected, source.buf);
+            try std.testing.expectEqual(warning_count, @as(u32, @intCast(comp.diag.list.items.len)));
+            try std.testing.expectEqualSlices(u32, splices, source.splice_locs);
+        }
+
+        fn withAllocationFailures(allocator: std.mem.Allocator) !void {
+            var comp = Compilation.init(allocator);
+            defer comp.deinit();
+
+            _ = try comp.addSourceFromBuffer("path", "spliced\\\nbuffer\n");
+            _ = try comp.addSourceFromBuffer("path", "non-spliced buffer\n");
+        }
+    };
+    try Test.addSourceFromReader("ab\\\nc", "abc", 0, &.{2});
+    try Test.addSourceFromReader("ab\\\rc", "abc", 0, &.{2});
+    try Test.addSourceFromReader("ab\\\r\nc", "abc", 0, &.{2});
+    try Test.addSourceFromReader("ab\\ \nc", "abc", 1, &.{2});
+    try Test.addSourceFromReader("ab\\\t\nc", "abc", 1, &.{2});
+    try Test.addSourceFromReader("ab\\                     \t\nc", "abc", 1, &.{2});
+    try Test.addSourceFromReader("ab\\\r \nc", "ab \nc", 0, &.{2});
+    try Test.addSourceFromReader("ab\\\\\nc", "ab\\c", 0, &.{3});
+    try Test.addSourceFromReader("ab\\   \r\nc", "abc", 1, &.{2});
+    try Test.addSourceFromReader("ab\\ \\\nc", "ab\\ c", 0, &.{4});
+    try Test.addSourceFromReader("ab\\\r\\\nc", "abc", 0, &.{ 2, 2 });
+    try Test.addSourceFromReader("ab\\  \rc", "abc", 1, &.{2});
+    try Test.addSourceFromReader("ab\\", "ab\\", 0, &.{});
+    try Test.addSourceFromReader("ab\\\\", "ab\\\\", 0, &.{});
+    try Test.addSourceFromReader("ab\\ ", "ab\\ ", 0, &.{});
+    try Test.addSourceFromReader("ab\\\n", "ab", 0, &.{2});
+    try Test.addSourceFromReader("ab\\\r\n", "ab", 0, &.{2});
+    try Test.addSourceFromReader("ab\\\r", "ab", 0, &.{2});
+
+    // carriage return normalization
+    try Test.addSourceFromReader("ab\r", "ab\n", 0, &.{});
+    try Test.addSourceFromReader("ab\r\r", "ab\n\n", 0, &.{});
+    try Test.addSourceFromReader("ab\r\r\n", "ab\n\n", 0, &.{});
+    try Test.addSourceFromReader("ab\r\r\n\r", "ab\n\n\n", 0, &.{});
+    try Test.addSourceFromReader("\r\\", "\n\\", 0, &.{});
+    try Test.addSourceFromReader("\\\r\\", "\\", 0, &.{0});
+
+    try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.withAllocationFailures, .{});
+}
+
+test "addSourceFromReader - exhaustive check for carriage return elimination" {
+    const alphabet = [_]u8{ '\r', '\n', ' ', '\\', 'a' };
+    const alen = alphabet.len;
+    var buf: [alphabet.len]u8 = [1]u8{alphabet[0]} ** alen;
+
+    var comp = Compilation.init(std.testing.allocator);
+    defer comp.deinit();
+
+    var source_count: u32 = 0;
+
+    while (true) {
+        const source = try comp.addSourceFromBuffer(&buf, &buf);
+        source_count += 1;
+        try std.testing.expect(std.mem.indexOfScalar(u8, source.buf, '\r') == null);
+
+        if (std.mem.allEqual(u8, &buf, alphabet[alen - 1])) break;
+
+        var idx = std.mem.indexOfScalar(u8, &alphabet, buf[buf.len - 1]).?;
+        buf[buf.len - 1] = alphabet[(idx + 1) % alen];
+        var j = buf.len - 1;
+        while (j > 0) : (j -= 1) {
+            idx = std.mem.indexOfScalar(u8, &alphabet, buf[j - 1]).?;
+            if (buf[j] == alphabet[0]) buf[j - 1] = alphabet[(idx + 1) % alen] else break;
+        }
+    }
+    try std.testing.expect(source_count == std.math.powi(usize, alen, alen) catch unreachable);
+}
+
+test "ignore BOM at beginning of file" {
+    const BOM = "\xEF\xBB\xBF";
+
+    const Test = struct {
+        fn run(buf: []const u8, input_type: enum { valid_utf8, invalid_utf8 }) !void {
+            var comp = Compilation.init(std.testing.allocator);
+            defer comp.deinit();
+
+            var buf_reader = std.io.fixedBufferStream(buf);
+            const source = try comp.addSourceFromReader(buf_reader.reader(), "file.c", @intCast(buf.len));
+            switch (input_type) {
+                .valid_utf8 => {
+                    const expected_output = if (mem.startsWith(u8, buf, BOM)) buf[BOM.len..] else buf;
+                    try std.testing.expectEqualStrings(expected_output, source.buf);
+                    try std.testing.expect(!comp.invalid_utf8_locs.contains(source.id));
+                },
+                .invalid_utf8 => try std.testing.expect(comp.invalid_utf8_locs.contains(source.id)),
+            }
+        }
+    };
+
+    try Test.run(BOM, .valid_utf8);
+    try Test.run(BOM ++ "x", .valid_utf8);
+    try Test.run("x" ++ BOM, .valid_utf8);
+    try Test.run(BOM ++ " ", .valid_utf8);
+    try Test.run(BOM ++ "\n", .valid_utf8);
+    try Test.run(BOM ++ "\\", .valid_utf8);
+
+    try Test.run(BOM[0..1] ++ "x", .invalid_utf8);
+    try Test.run(BOM[0..2] ++ "x", .invalid_utf8);
+    try Test.run(BOM[1..] ++ "x", .invalid_utf8);
+    try Test.run(BOM[2..] ++ "x", .invalid_utf8);
+}
deps/aro/Diagnostics.zig
@@ -0,0 +1,2787 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const Source = @import("Source.zig");
+const Compilation = @import("Compilation.zig");
+const Attribute = @import("Attribute.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+const Header = @import("builtins/Properties.zig").Header;
+const Tree = @import("Tree.zig");
+const util = @import("util.zig");
+const is_windows = @import("builtin").os.tag == .windows;
+
+const Diagnostics = @This();
+
+const PointerSignMessage = " converts between pointers to integer types with different sign";
+
+pub const Message = struct {
+    tag: Tag,
+    kind: Kind = undefined,
+    loc: Source.Location = .{},
+    extra: Extra = .{ .none = {} },
+
+    pub const Extra = union {
+        str: []const u8,
+        tok_id: struct {
+            expected: Tree.Token.Id,
+            actual: Tree.Token.Id,
+        },
+        tok_id_expected: Tree.Token.Id,
+        arguments: struct {
+            expected: u32,
+            actual: u32,
+        },
+        codepoints: struct {
+            actual: u21,
+            resembles: u21,
+        },
+        attr_arg_count: struct {
+            attribute: Attribute.Tag,
+            expected: u32,
+        },
+        attr_arg_type: struct {
+            expected: Attribute.ArgumentType,
+            actual: Attribute.ArgumentType,
+        },
+        attr_enum: struct {
+            tag: Attribute.Tag,
+        },
+        ignored_record_attr: struct {
+            tag: Attribute.Tag,
+            specifier: enum { @"struct", @"union", @"enum" },
+        },
+        builtin_with_header: struct {
+            builtin: BuiltinFunction.Tag,
+            header: Header,
+        },
+        actual_codepoint: u21,
+        ascii: u7,
+        unsigned: u64,
+        pow_2_as_string: u8,
+        signed: i64,
+        none: void,
+    };
+};
+
+pub const Tag = std.meta.DeclEnum(messages);
+
+// u4 to avoid any possible packed struct issues
+pub const Kind = enum(u4) { @"fatal error", @"error", note, warning, off, default };
+
+pub const Options = packed struct {
+    // do not directly use these, instead add `const NAME = true;`
+    all: Kind = .default,
+    extra: Kind = .default,
+    pedantic: Kind = .default,
+
+    @"unsupported-pragma": Kind = .default,
+    @"c99-extensions": Kind = .default,
+    @"implicit-int": Kind = .default,
+    @"duplicate-decl-specifier": Kind = .default,
+    @"missing-declaration": Kind = .default,
+    @"extern-initializer": Kind = .default,
+    @"implicit-function-declaration": Kind = .default,
+    @"unused-value": Kind = .default,
+    @"unreachable-code": Kind = .default,
+    @"unknown-warning-option": Kind = .default,
+    @"gnu-empty-struct": Kind = .default,
+    @"gnu-alignof-expression": Kind = .default,
+    @"macro-redefined": Kind = .default,
+    @"generic-qual-type": Kind = .default,
+    multichar: Kind = .default,
+    @"pointer-integer-compare": Kind = .default,
+    @"compare-distinct-pointer-types": Kind = .default,
+    @"literal-conversion": Kind = .default,
+    @"cast-qualifiers": Kind = .default,
+    @"array-bounds": Kind = .default,
+    @"int-conversion": Kind = .default,
+    @"pointer-type-mismatch": Kind = .default,
+    @"c2x-extensions": Kind = .default,
+    @"incompatible-pointer-types": Kind = .default,
+    @"excess-initializers": Kind = .default,
+    @"division-by-zero": Kind = .default,
+    @"initializer-overrides": Kind = .default,
+    @"incompatible-pointer-types-discards-qualifiers": Kind = .default,
+    @"unknown-attributes": Kind = .default,
+    @"ignored-attributes": Kind = .default,
+    @"builtin-macro-redefined": Kind = .default,
+    @"gnu-label-as-value": Kind = .default,
+    @"malformed-warning-check": Kind = .default,
+    @"#pragma-messages": Kind = .default,
+    @"newline-eof": Kind = .default,
+    @"empty-translation-unit": Kind = .default,
+    @"implicitly-unsigned-literal": Kind = .default,
+    @"c99-compat": Kind = .default,
+    @"unicode-zero-width": Kind = .default,
+    @"unicode-homoglyph": Kind = .default,
+    @"return-type": Kind = .default,
+    @"dollar-in-identifier-extension": Kind = .default,
+    @"unknown-pragmas": Kind = .default,
+    @"predefined-identifier-outside-function": Kind = .default,
+    @"many-braces-around-scalar-init": Kind = .default,
+    uninitialized: Kind = .default,
+    @"gnu-statement-expression": Kind = .default,
+    @"gnu-imaginary-constant": Kind = .default,
+    @"gnu-complex-integer": Kind = .default,
+    @"ignored-qualifiers": Kind = .default,
+    @"integer-overflow": Kind = .default,
+    @"extra-semi": Kind = .default,
+    @"gnu-binary-literal": Kind = .default,
+    @"variadic-macros": Kind = .default,
+    varargs: Kind = .default,
+    @"#warnings": Kind = .default,
+    @"deprecated-declarations": Kind = .default,
+    @"backslash-newline-escape": Kind = .default,
+    @"pointer-to-int-cast": Kind = .default,
+    @"gnu-case-range": Kind = .default,
+    @"c++-compat": Kind = .default,
+    vla: Kind = .default,
+    @"float-overflow-conversion": Kind = .default,
+    @"float-zero-conversion": Kind = .default,
+    @"float-conversion": Kind = .default,
+    @"gnu-folding-constant": Kind = .default,
+    undef: Kind = .default,
+    @"ignored-pragmas": Kind = .default,
+    @"gnu-include-next": Kind = .default,
+    @"include-next-outside-header": Kind = .default,
+    @"include-next-absolute-path": Kind = .default,
+    @"enum-too-large": Kind = .default,
+    @"fixed-enum-extension": Kind = .default,
+    @"designated-init": Kind = .default,
+    @"attribute-warning": Kind = .default,
+    @"invalid-noreturn": Kind = .default,
+    @"zero-length-array": Kind = .default,
+    @"old-style-flexible-struct": Kind = .default,
+    @"gnu-zero-variadic-macro-arguments": Kind = .default,
+    @"main-return-type": Kind = .default,
+    @"expansion-to-defined": Kind = .default,
+    @"bit-int-extension": Kind = .default,
+    @"keyword-macro": Kind = .default,
+    @"pointer-arith": Kind = .default,
+    @"sizeof-array-argument": Kind = .default,
+    @"pre-c2x-compat": Kind = .default,
+    @"pointer-bool-conversion": Kind = .default,
+    @"string-conversion": Kind = .default,
+    @"gnu-auto-type": Kind = .default,
+    @"gnu-union-cast": Kind = .default,
+    @"pointer-sign": Kind = .default,
+    @"fuse-ld-path": Kind = .default,
+    @"language-extension-token": Kind = .default,
+    @"complex-component-init": Kind = .default,
+};
+
+const messages = struct {
+    pub const todo = struct { // Maybe someday this will no longer be needed.
+        const msg = "TODO: {s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const error_directive = struct {
+        const msg = "{s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const warning_directive = struct {
+        const msg = "{s}";
+        const opt = "#warnings";
+        const extra = .str;
+        const kind = .warning;
+    };
+    pub const elif_without_if = struct {
+        const msg = "#elif without #if";
+        const kind = .@"error";
+    };
+    pub const elif_after_else = struct {
+        const msg = "#elif after #else";
+        const kind = .@"error";
+    };
+    pub const elifdef_without_if = struct {
+        const msg = "#elifdef without #if";
+        const kind = .@"error";
+    };
+    pub const elifdef_after_else = struct {
+        const msg = "#elifdef after #else";
+        const kind = .@"error";
+    };
+    pub const elifndef_without_if = struct {
+        const msg = "#elifndef without #if";
+        const kind = .@"error";
+    };
+    pub const elifndef_after_else = struct {
+        const msg = "#elifndef after #else";
+        const kind = .@"error";
+    };
+    pub const else_without_if = struct {
+        const msg = "#else without #if";
+        const kind = .@"error";
+    };
+    pub const else_after_else = struct {
+        const msg = "#else after #else";
+        const kind = .@"error";
+    };
+    pub const endif_without_if = struct {
+        const msg = "#endif without #if";
+        const kind = .@"error";
+    };
+    pub const unknown_pragma = struct {
+        const msg = "unknown pragma ignored";
+        const opt = "unknown-pragmas";
+        const kind = .off;
+        const all = true;
+    };
+    pub const line_simple_digit = struct {
+        const msg = "#line directive requires a simple digit sequence";
+        const kind = .@"error";
+    };
+    pub const line_invalid_filename = struct {
+        const msg = "invalid filename for #line directive";
+        const kind = .@"error";
+    };
+    pub const unterminated_conditional_directive = struct {
+        const msg = "unterminated conditional directive";
+        const kind = .@"error";
+    };
+    pub const invalid_preprocessing_directive = struct {
+        const msg = "invalid preprocessing directive";
+        const kind = .@"error";
+    };
+    pub const macro_name_missing = struct {
+        const msg = "macro name missing";
+        const kind = .@"error";
+    };
+    pub const extra_tokens_directive_end = struct {
+        const msg = "extra tokens at end of macro directive";
+        const kind = .@"error";
+    };
+    pub const expected_value_in_expr = struct {
+        const msg = "expected value in expression";
+        const kind = .@"error";
+    };
+    pub const closing_paren = struct {
+        const msg = "expected closing ')'";
+        const kind = .@"error";
+    };
+    pub const to_match_paren = struct {
+        const msg = "to match this '('";
+        const kind = .note;
+    };
+    pub const to_match_brace = struct {
+        const msg = "to match this '{'";
+        const kind = .note;
+    };
+    pub const to_match_bracket = struct {
+        const msg = "to match this '['";
+        const kind = .note;
+    };
+    pub const header_str_closing = struct {
+        const msg = "expected closing '>'";
+        const kind = .@"error";
+    };
+    pub const header_str_match = struct {
+        const msg = "to match this '<'";
+        const kind = .note;
+    };
+    pub const string_literal_in_pp_expr = struct {
+        const msg = "string literal in preprocessor expression";
+        const kind = .@"error";
+    };
+    pub const float_literal_in_pp_expr = struct {
+        const msg = "floating point literal in preprocessor expression";
+        const kind = .@"error";
+    };
+    pub const defined_as_macro_name = struct {
+        const msg = "'defined' cannot be used as a macro name";
+        const kind = .@"error";
+    };
+    pub const macro_name_must_be_identifier = struct {
+        const msg = "macro name must be an identifier";
+        const kind = .@"error";
+    };
+    pub const whitespace_after_macro_name = struct {
+        const msg = "ISO C99 requires whitespace after the macro name";
+        const opt = "c99-extensions";
+        const kind = .warning;
+    };
+    pub const hash_hash_at_start = struct {
+        const msg = "'##' cannot appear at the start of a macro expansion";
+        const kind = .@"error";
+    };
+    pub const hash_hash_at_end = struct {
+        const msg = "'##' cannot appear at the end of a macro expansion";
+        const kind = .@"error";
+    };
+    pub const pasting_formed_invalid = struct {
+        const msg = "pasting formed '{s}', an invalid preprocessing token";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const missing_paren_param_list = struct {
+        const msg = "missing ')' in macro parameter list";
+        const kind = .@"error";
+    };
+    pub const unterminated_macro_param_list = struct {
+        const msg = "unterminated macro param list";
+        const kind = .@"error";
+    };
+    pub const invalid_token_param_list = struct {
+        const msg = "invalid token in macro parameter list";
+        const kind = .@"error";
+    };
+    pub const expected_comma_param_list = struct {
+        const msg = "expected comma in macro parameter list";
+        const kind = .@"error";
+    };
+    pub const hash_not_followed_param = struct {
+        const msg = "'#' is not followed by a macro parameter";
+        const kind = .@"error";
+    };
+    pub const expected_filename = struct {
+        const msg = "expected \"FILENAME\" or <FILENAME>";
+        const kind = .@"error";
+    };
+    pub const empty_filename = struct {
+        const msg = "empty filename";
+        const kind = .@"error";
+    };
+    pub const expected_invalid = struct {
+        const msg = "expected '{s}', found invalid bytes";
+        const extra = .tok_id_expected;
+        const kind = .@"error";
+    };
+    pub const expected_eof = struct {
+        const msg = "expected '{s}' before end of file";
+        const extra = .tok_id_expected;
+        const kind = .@"error";
+    };
+    pub const expected_token = struct {
+        const msg = "expected '{s}', found '{s}'";
+        const extra = .tok_id;
+        const kind = .@"error";
+    };
+    pub const expected_expr = struct {
+        const msg = "expected expression";
+        const kind = .@"error";
+    };
+    pub const expected_integer_constant_expr = struct {
+        const msg = "expression is not an integer constant expression";
+        const kind = .@"error";
+    };
+    pub const missing_type_specifier = struct {
+        const msg = "type specifier missing, defaults to 'int'";
+        const opt = "implicit-int";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const multiple_storage_class = struct {
+        const msg = "cannot combine with previous '{s}' declaration specifier";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const static_assert_failure = struct {
+        const msg = "static assertion failed";
+        const kind = .@"error";
+    };
+    pub const static_assert_failure_message = struct {
+        const msg = "static assertion failed {s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const expected_type = struct {
+        const msg = "expected a type";
+        const kind = .@"error";
+    };
+    pub const cannot_combine_spec = struct {
+        const msg = "cannot combine with previous '{s}' specifier";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const duplicate_decl_spec = struct {
+        const msg = "duplicate '{s}' declaration specifier";
+        const extra = .str;
+        const opt = "duplicate-decl-specifier";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const restrict_non_pointer = struct {
+        const msg = "restrict requires a pointer or reference ('{s}' is invalid)";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const expected_external_decl = struct {
+        const msg = "expected external declaration";
+        const kind = .@"error";
+    };
+    pub const expected_ident_or_l_paren = struct {
+        const msg = "expected identifier or '('";
+        const kind = .@"error";
+    };
+    pub const missing_declaration = struct {
+        const msg = "declaration does not declare anything";
+        const opt = "missing-declaration";
+        const kind = .warning;
+    };
+    pub const func_not_in_root = struct {
+        const msg = "function definition is not allowed here";
+        const kind = .@"error";
+    };
+    pub const illegal_initializer = struct {
+        const msg = "illegal initializer (only variables can be initialized)";
+        const kind = .@"error";
+    };
+    pub const extern_initializer = struct {
+        const msg = "extern variable has initializer";
+        const opt = "extern-initializer";
+        const kind = .warning;
+    };
+    pub const spec_from_typedef = struct {
+        const msg = "'{s}' came from typedef";
+        const extra = .str;
+        const kind = .note;
+    };
+    pub const param_before_var_args = struct {
+        const msg = "ISO C requires a named parameter before '...'";
+        const kind = .@"error";
+    };
+    pub const void_only_param = struct {
+        const msg = "'void' must be the only parameter if specified";
+        const kind = .@"error";
+    };
+    pub const void_param_qualified = struct {
+        const msg = "'void' parameter cannot be qualified";
+        const kind = .@"error";
+    };
+    pub const void_must_be_first_param = struct {
+        const msg = "'void' must be the first parameter if specified";
+        const kind = .@"error";
+    };
+    pub const invalid_storage_on_param = struct {
+        const msg = "invalid storage class on function parameter";
+        const kind = .@"error";
+    };
+    pub const threadlocal_non_var = struct {
+        const msg = "_Thread_local only allowed on variables";
+        const kind = .@"error";
+    };
+    pub const func_spec_non_func = struct {
+        const msg = "'{s}' can only appear on functions";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const illegal_storage_on_func = struct {
+        const msg = "illegal storage class on function";
+        const kind = .@"error";
+    };
+    pub const illegal_storage_on_global = struct {
+        const msg = "illegal storage class on global variable";
+        const kind = .@"error";
+    };
+    pub const expected_stmt = struct {
+        const msg = "expected statement";
+        const kind = .@"error";
+    };
+    pub const func_cannot_return_func = struct {
+        const msg = "function cannot return a function";
+        const kind = .@"error";
+    };
+    pub const func_cannot_return_array = struct {
+        const msg = "function cannot return an array";
+        const kind = .@"error";
+    };
+    pub const undeclared_identifier = struct {
+        const msg = "use of undeclared identifier '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const not_callable = struct {
+        const msg = "cannot call non function type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const unsupported_str_cat = struct {
+        const msg = "unsupported string literal concatenation";
+        const kind = .@"error";
+    };
+    pub const static_func_not_global = struct {
+        const msg = "static functions must be global";
+        const kind = .@"error";
+    };
+    pub const implicit_func_decl = struct {
+        const msg = "implicit declaration of function '{s}' is invalid in C99";
+        const extra = .str;
+        const opt = "implicit-function-declaration";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const unknown_builtin = struct {
+        const msg = "use of unknown builtin '{s}'";
+        const extra = .str;
+        const opt = "implicit-function-declaration";
+        const kind = .@"error";
+        const all = true;
+    };
+    pub const implicit_builtin = struct {
+        const msg = "implicitly declaring library function '{s}'";
+        const extra = .str;
+        const opt = "implicit-function-declaration";
+        const kind = .@"error";
+        const all = true;
+    };
+    pub const implicit_builtin_header_note = struct {
+        const msg = "include the header <{s}.h> or explicitly provide a declaration for '{s}'";
+        const extra = .builtin_with_header;
+        const opt = "implicit-function-declaration";
+        const kind = .note;
+        const all = true;
+    };
+    pub const expected_param_decl = struct {
+        const msg = "expected parameter declaration";
+        const kind = .@"error";
+    };
+    pub const invalid_old_style_params = struct {
+        const msg = "identifier parameter lists are only allowed in function definitions";
+        const kind = .@"error";
+    };
+    pub const expected_fn_body = struct {
+        const msg = "expected function body after function declaration";
+        const kind = .@"error";
+    };
+    pub const invalid_void_param = struct {
+        const msg = "parameter cannot have void type";
+        const kind = .@"error";
+    };
+    pub const unused_value = struct {
+        const msg = "expression result unused";
+        const opt = "unused-value";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const continue_not_in_loop = struct {
+        const msg = "'continue' statement not in a loop";
+        const kind = .@"error";
+    };
+    pub const break_not_in_loop_or_switch = struct {
+        const msg = "'break' statement not in a loop or a switch";
+        const kind = .@"error";
+    };
+    pub const unreachable_code = struct {
+        const msg = "unreachable code";
+        const opt = "unreachable-code";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const duplicate_label = struct {
+        const msg = "duplicate label '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const previous_label = struct {
+        const msg = "previous definition of label '{s}' was here";
+        const extra = .str;
+        const kind = .note;
+    };
+    pub const undeclared_label = struct {
+        const msg = "use of undeclared label '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const case_not_in_switch = struct {
+        const msg = "'{s}' statement not in a switch statement";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const duplicate_switch_case_signed = struct {
+        const msg = "duplicate case value '{d}'";
+        const extra = .signed;
+        const kind = .@"error";
+    };
+    pub const duplicate_switch_case_unsigned = struct {
+        const msg = "duplicate case value '{d}'";
+        const extra = .unsigned;
+        const kind = .@"error";
+    };
+    pub const multiple_default = struct {
+        const msg = "multiple default cases in the same switch";
+        const kind = .@"error";
+    };
+    pub const previous_case = struct {
+        const msg = "previous case defined here";
+        const kind = .note;
+    };
+    pub const expected_arguments = struct {
+        const msg = "expected {d} argument(s) got {d}";
+        const extra = .arguments;
+        const kind = .@"error";
+    };
+    pub const expected_arguments_old = struct {
+        const msg = expected_arguments.msg;
+        const extra = .arguments;
+        const kind = .warning;
+    };
+    pub const expected_at_least_arguments = struct {
+        const msg = "expected at least {d} argument(s) got {d}";
+        const extra = .arguments;
+        const kind = .warning;
+    };
+    pub const invalid_static_star = struct {
+        const msg = "'static' may not be used with an unspecified variable length array size";
+        const kind = .@"error";
+    };
+    pub const static_non_param = struct {
+        const msg = "'static' used outside of function parameters";
+        const kind = .@"error";
+    };
+    pub const array_qualifiers = struct {
+        const msg = "type qualifier in non parameter array type";
+        const kind = .@"error";
+    };
+    pub const star_non_param = struct {
+        const msg = "star modifier used outside of function parameters";
+        const kind = .@"error";
+    };
+    pub const variable_len_array_file_scope = struct {
+        const msg = "variable length arrays not allowed at file scope";
+        const kind = .@"error";
+    };
+    pub const useless_static = struct {
+        const msg = "'static' useless without a constant size";
+        const kind = .warning;
+        const w_extra = true;
+    };
+    pub const negative_array_size = struct {
+        const msg = "array size must be 0 or greater";
+        const kind = .@"error";
+    };
+    pub const array_incomplete_elem = struct {
+        const msg = "array has incomplete element type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const array_func_elem = struct {
+        const msg = "arrays cannot have functions as their element type";
+        const kind = .@"error";
+    };
+    pub const static_non_outermost_array = struct {
+        const msg = "'static' used in non-outermost array type";
+        const kind = .@"error";
+    };
+    pub const qualifier_non_outermost_array = struct {
+        const msg = "type qualifier used in non-outermost array type";
+        const kind = .@"error";
+    };
+    pub const unterminated_macro_arg_list = struct {
+        const msg = "unterminated function macro argument list";
+        const kind = .@"error";
+    };
+    pub const unknown_warning = struct {
+        const msg = "unknown warning '{s}'";
+        const extra = .str;
+        const opt = "unknown-warning-option";
+        const kind = .warning;
+    };
+    pub const overflow_signed = struct {
+        const msg = "overflow in expression; result is '{d}'";
+        const extra = .signed;
+        const opt = "integer-overflow";
+        const kind = .warning;
+    };
+    pub const overflow_unsigned = struct {
+        const msg = overflow_signed.msg;
+        const extra = .unsigned;
+        const opt = "integer-overflow";
+        const kind = .warning;
+    };
+    pub const int_literal_too_big = struct {
+        const msg = "integer literal is too large to be represented in any integer type";
+        const kind = .@"error";
+    };
+    pub const indirection_ptr = struct {
+        const msg = "indirection requires pointer operand";
+        const kind = .@"error";
+    };
+    pub const addr_of_rvalue = struct {
+        const msg = "cannot take the address of an rvalue";
+        const kind = .@"error";
+    };
+    pub const addr_of_bitfield = struct {
+        const msg = "address of bit-field requested";
+        const kind = .@"error";
+    };
+    pub const not_assignable = struct {
+        const msg = "expression is not assignable";
+        const kind = .@"error";
+    };
+    pub const ident_or_l_brace = struct {
+        const msg = "expected identifier or '{'";
+        const kind = .@"error";
+    };
+    pub const empty_enum = struct {
+        const msg = "empty enum is invalid";
+        const kind = .@"error";
+    };
+    pub const redefinition = struct {
+        const msg = "redefinition of '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const previous_definition = struct {
+        const msg = "previous definition is here";
+        const kind = .note;
+    };
+    pub const expected_identifier = struct {
+        const msg = "expected identifier";
+        const kind = .@"error";
+    };
+    pub const expected_str_literal = struct {
+        const msg = "expected string literal for diagnostic message in static_assert";
+        const kind = .@"error";
+    };
+    pub const expected_str_literal_in = struct {
+        const msg = "expected string literal in '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const parameter_missing = struct {
+        const msg = "parameter named '{s}' is missing";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const empty_record = struct {
+        const msg = "empty {s} is a GNU extension";
+        const extra = .str;
+        const opt = "gnu-empty-struct";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const empty_record_size = struct {
+        const msg = "empty {s} has size 0 in C, size 1 in C++";
+        const extra = .str;
+        const opt = "c++-compat";
+        const kind = .off;
+    };
+    pub const wrong_tag = struct {
+        const msg = "use of '{s}' with tag type that does not match previous definition";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const expected_parens_around_typename = struct {
+        const msg = "expected parentheses around type name";
+        const kind = .@"error";
+    };
+    pub const alignof_expr = struct {
+        const msg = "'_Alignof' applied to an expression is a GNU extension";
+        const opt = "gnu-alignof-expression";
+        const kind = .warning;
+        const suppress_gnu = true;
+    };
+    pub const invalid_alignof = struct {
+        const msg = "invalid application of 'alignof' to an incomplete type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_sizeof = struct {
+        const msg = "invalid application of 'sizeof' to an incomplete type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const macro_redefined = struct {
+        const msg = "'{s}' macro redefined";
+        const extra = .str;
+        const opt = "macro-redefined";
+        const kind = .warning;
+    };
+    pub const generic_qual_type = struct {
+        const msg = "generic association with qualifiers cannot be matched with";
+        const opt = "generic-qual-type";
+        const kind = .warning;
+    };
+    pub const generic_array_type = struct {
+        const msg = "generic association array type cannot be matched with";
+        const opt = "generic-qual-type";
+        const kind = .warning;
+    };
+    pub const generic_func_type = struct {
+        const msg = "generic association function type cannot be matched with";
+        const opt = "generic-qual-type";
+        const kind = .warning;
+    };
+    pub const generic_duplicate = struct {
+        const msg = "type '{s}' in generic association compatible with previously specified type";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const generic_duplicate_here = struct {
+        const msg = "compatible type '{s}' specified here";
+        const extra = .str;
+        const kind = .note;
+    };
+    pub const generic_duplicate_default = struct {
+        const msg = "duplicate default generic association";
+        const kind = .@"error";
+    };
+    pub const generic_no_match = struct {
+        const msg = "controlling expression type '{s}' not compatible with any generic association type";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const escape_sequence_overflow = struct {
+        const msg = "escape sequence out of range";
+        const kind = .@"error";
+    };
+    pub const invalid_universal_character = struct {
+        const msg = "invalid universal character";
+        const kind = .@"error";
+    };
+    pub const multichar_literal = struct {
+        const msg = "multi-character character constant";
+        const opt = "multichar";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const unicode_multichar_literal = struct {
+        const msg = "Unicode character literals may not contain multiple characters";
+        const kind = .@"error";
+    };
+    pub const wide_multichar_literal = struct {
+        const msg = "extraneous characters in character constant ignored";
+        const kind = .warning;
+    };
+    pub const char_lit_too_wide = struct {
+        const msg = "character constant too long for its type";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const char_too_large = struct {
+        const msg = "character too large for enclosing character literal type";
+        const kind = .@"error";
+    };
+    pub const must_use_struct = struct {
+        const msg = "must use 'struct' tag to refer to type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const must_use_union = struct {
+        const msg = "must use 'union' tag to refer to type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const must_use_enum = struct {
+        const msg = "must use 'enum' tag to refer to type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const redefinition_different_sym = struct {
+        const msg = "redefinition of '{s}' as different kind of symbol";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const redefinition_incompatible = struct {
+        const msg = "redefinition of '{s}' with a different type";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const redefinition_of_parameter = struct {
+        const msg = "redefinition of parameter '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_bin_types = struct {
+        const msg = "invalid operands to binary expression ({s})";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const comparison_ptr_int = struct {
+        const msg = "comparison between pointer and integer ({s})";
+        const extra = .str;
+        const opt = "pointer-integer-compare";
+        const kind = .warning;
+    };
+    pub const comparison_distinct_ptr = struct {
+        const msg = "comparison of distinct pointer types ({s})";
+        const extra = .str;
+        const opt = "compare-distinct-pointer-types";
+        const kind = .warning;
+    };
+    pub const incompatible_pointers = struct {
+        const msg = "incompatible pointer types ({s})";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_argument_un = struct {
+        const msg = "invalid argument type '{s}' to unary expression";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const incompatible_assign = struct {
+        const msg = "assignment to {s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const implicit_ptr_to_int = struct {
+        const msg = "implicit pointer to integer conversion from {s}";
+        const extra = .str;
+        const opt = "int-conversion";
+        const kind = .warning;
+    };
+    pub const invalid_cast_to_float = struct {
+        const msg = "pointer cannot be cast to type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_cast_to_pointer = struct {
+        const msg = "operand of type '{s}' cannot be cast to a pointer type";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_cast_type = struct {
+        const msg = "cannot cast to non arithmetic or pointer type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const qual_cast = struct {
+        const msg = "cast to type '{s}' will not preserve qualifiers";
+        const extra = .str;
+        const opt = "cast-qualifiers";
+        const kind = .warning;
+    };
+    pub const invalid_index = struct {
+        const msg = "array subscript is not an integer";
+        const kind = .@"error";
+    };
+    pub const invalid_subscript = struct {
+        const msg = "subscripted value is not an array or pointer";
+        const kind = .@"error";
+    };
+    pub const array_after = struct {
+        const msg = "array index {d} is past the end of the array";
+        const extra = .unsigned;
+        const opt = "array-bounds";
+        const kind = .warning;
+    };
+    pub const array_before = struct {
+        const msg = "array index {d} is before the beginning of the array";
+        const extra = .signed;
+        const opt = "array-bounds";
+        const kind = .warning;
+    };
+    pub const statement_int = struct {
+        const msg = "statement requires expression with integer type ('{s}' invalid)";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const statement_scalar = struct {
+        const msg = "statement requires expression with scalar type ('{s}' invalid)";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const func_should_return = struct {
+        const msg = "non-void function '{s}' should return a value";
+        const extra = .str;
+        const opt = "return-type";
+        const kind = .@"error";
+        const all = true;
+    };
+    pub const incompatible_return = struct {
+        const msg = "returning {s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const incompatible_return_sign = struct {
+        const msg = "returning {s}" ++ PointerSignMessage;
+        const extra = .str;
+        const kind = .warning;
+        const opt = "pointer-sign";
+    };
+    pub const implicit_int_to_ptr = struct {
+        const msg = "implicit integer to pointer conversion from {s}";
+        const extra = .str;
+        const opt = "int-conversion";
+        const kind = .warning;
+    };
+    pub const func_does_not_return = struct {
+        const msg = "non-void function '{s}' does not return a value";
+        const extra = .str;
+        const opt = "return-type";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const void_func_returns_value = struct {
+        const msg = "void function '{s}' should not return a value";
+        const extra = .str;
+        const opt = "return-type";
+        const kind = .@"error";
+        const all = true;
+    };
+    pub const incompatible_arg = struct {
+        const msg = "passing {s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const incompatible_ptr_arg = struct {
+        const msg = "passing {s}";
+        const extra = .str;
+        const kind = .warning;
+        const opt = "incompatible-pointer-types";
+    };
+    pub const incompatible_ptr_arg_sign = struct {
+        const msg = "passing {s}" ++ PointerSignMessage;
+        const extra = .str;
+        const kind = .warning;
+        const opt = "pointer-sign";
+    };
+    pub const parameter_here = struct {
+        const msg = "passing argument to parameter here";
+        const kind = .note;
+    };
+    pub const atomic_array = struct {
+        const msg = "atomic cannot be applied to array type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const atomic_func = struct {
+        const msg = "atomic cannot be applied to function type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const atomic_incomplete = struct {
+        const msg = "atomic cannot be applied to incomplete type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const addr_of_register = struct {
+        const msg = "address of register variable requested";
+        const kind = .@"error";
+    };
+    pub const variable_incomplete_ty = struct {
+        const msg = "variable has incomplete type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const parameter_incomplete_ty = struct {
+        const msg = "parameter has incomplete type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const tentative_array = struct {
+        const msg = "tentative array definition assumed to have one element";
+        const kind = .warning;
+    };
+    pub const deref_incomplete_ty_ptr = struct {
+        const msg = "dereferencing pointer to incomplete type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const alignas_on_func = struct {
+        const msg = "'_Alignas' attribute only applies to variables and fields";
+        const kind = .@"error";
+    };
+    pub const alignas_on_param = struct {
+        const msg = "'_Alignas' attribute cannot be applied to a function parameter";
+        const kind = .@"error";
+    };
+    pub const minimum_alignment = struct {
+        const msg = "requested alignment is less than minimum alignment of {d}";
+        const extra = .unsigned;
+        const kind = .@"error";
+    };
+    pub const maximum_alignment = struct {
+        const msg = "requested alignment of {d} is too large";
+        const extra = .unsigned;
+        const kind = .@"error";
+    };
+    pub const negative_alignment = struct {
+        const msg = "requested negative alignment of {d} is invalid";
+        const extra = .signed;
+        const kind = .@"error";
+    };
+    pub const align_ignored = struct {
+        const msg = "'_Alignas' attribute is ignored here";
+        const kind = .warning;
+    };
+    pub const zero_align_ignored = struct {
+        const msg = "requested alignment of zero is ignored";
+        const kind = .warning;
+    };
+    pub const non_pow2_align = struct {
+        const msg = "requested alignment is not a power of 2";
+        const kind = .@"error";
+    };
+    pub const pointer_mismatch = struct {
+        const msg = "pointer type mismatch ({s})";
+        const extra = .str;
+        const opt = "pointer-type-mismatch";
+        const kind = .warning;
+    };
+    pub const static_assert_not_constant = struct {
+        const msg = "static_assert expression is not an integral constant expression";
+        const kind = .@"error";
+    };
+    pub const static_assert_missing_message = struct {
+        const msg = "static_assert with no message is a C2X extension";
+        const opt = "c2x-extensions";
+        const kind = .warning;
+        const suppress_version = .c2x;
+    };
+    pub const pre_c2x_compat = struct {
+        const msg = "{s} is incompatible with C standards before C2x";
+        const extra = .str;
+        const kind = .off;
+        const suppress_unless_version = .c2x;
+        const opt = "pre-c2x-compat";
+    };
+    pub const unbound_vla = struct {
+        const msg = "variable length array must be bound in function definition";
+        const kind = .@"error";
+    };
+    pub const array_too_large = struct {
+        const msg = "array is too large";
+        const kind = .@"error";
+    };
+    pub const incompatible_ptr_init = struct {
+        const msg = "incompatible pointer types initializing {s}";
+        const extra = .str;
+        const opt = "incompatible-pointer-types";
+        const kind = .warning;
+    };
+    pub const incompatible_ptr_init_sign = struct {
+        const msg = "incompatible pointer types initializing {s}" ++ PointerSignMessage;
+        const extra = .str;
+        const opt = "pointer-sign";
+        const kind = .warning;
+    };
+    pub const incompatible_ptr_assign = struct {
+        const msg = "incompatible pointer types assigning to {s}";
+        const extra = .str;
+        const opt = "incompatible-pointer-types";
+        const kind = .warning;
+    };
+    pub const incompatible_ptr_assign_sign = struct {
+        const msg = "incompatible pointer types assigning to {s} " ++ PointerSignMessage;
+        const extra = .str;
+        const opt = "pointer-sign";
+        const kind = .warning;
+    };
+    pub const vla_init = struct {
+        const msg = "variable-sized object may not be initialized";
+        const kind = .@"error";
+    };
+    pub const func_init = struct {
+        const msg = "illegal initializer type";
+        const kind = .@"error";
+    };
+    pub const incompatible_init = struct {
+        const msg = "initializing {s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const empty_scalar_init = struct {
+        const msg = "scalar initializer cannot be empty";
+        const kind = .@"error";
+    };
+    pub const excess_scalar_init = struct {
+        const msg = "excess elements in scalar initializer";
+        const opt = "excess-initializers";
+        const kind = .warning;
+    };
+    pub const excess_str_init = struct {
+        const msg = "excess elements in string initializer";
+        const opt = "excess-initializers";
+        const kind = .warning;
+    };
+    pub const excess_struct_init = struct {
+        const msg = "excess elements in struct initializer";
+        const opt = "excess-initializers";
+        const kind = .warning;
+    };
+    pub const excess_array_init = struct {
+        const msg = "excess elements in array initializer";
+        const opt = "excess-initializers";
+        const kind = .warning;
+    };
+    pub const str_init_too_long = struct {
+        const msg = "initializer-string for char array is too long";
+        const opt = "excess-initializers";
+        const kind = .warning;
+    };
+    pub const arr_init_too_long = struct {
+        const msg = "cannot initialize type ({s})";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_typeof = struct {
+        const msg = "'{s} typeof' is invalid";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const division_by_zero = struct {
+        const msg = "{s} by zero is undefined";
+        const extra = .str;
+        const opt = "division-by-zero";
+        const kind = .warning;
+    };
+    pub const division_by_zero_macro = struct {
+        const msg = "{s} by zero in preprocessor expression";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const builtin_choose_cond = struct {
+        const msg = "'__builtin_choose_expr' requires a constant expression";
+        const kind = .@"error";
+    };
+    pub const alignas_unavailable = struct {
+        const msg = "'_Alignas' attribute requires integer constant expression";
+        const kind = .@"error";
+    };
+    pub const case_val_unavailable = struct {
+        const msg = "case value must be an integer constant expression";
+        const kind = .@"error";
+    };
+    pub const enum_val_unavailable = struct {
+        const msg = "enum value must be an integer constant expression";
+        const kind = .@"error";
+    };
+    pub const incompatible_array_init = struct {
+        const msg = "cannot initialize array of type {s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const array_init_str = struct {
+        const msg = "array initializer must be an initializer list or wide string literal";
+        const kind = .@"error";
+    };
+    pub const initializer_overrides = struct {
+        const msg = "initializer overrides previous initialization";
+        const opt = "initializer-overrides";
+        const kind = .warning;
+        const w_extra = true;
+    };
+    pub const previous_initializer = struct {
+        const msg = "previous initialization";
+        const kind = .note;
+    };
+    pub const invalid_array_designator = struct {
+        const msg = "array designator used for non-array type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const negative_array_designator = struct {
+        const msg = "array designator value {d} is negative";
+        const extra = .signed;
+        const kind = .@"error";
+    };
+    pub const oob_array_designator = struct {
+        const msg = "array designator index {d} exceeds array bounds";
+        const extra = .unsigned;
+        const kind = .@"error";
+    };
+    pub const invalid_field_designator = struct {
+        const msg = "field designator used for non-record type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const no_such_field_designator = struct {
+        const msg = "record type has no field named '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const empty_aggregate_init_braces = struct {
+        const msg = "initializer for aggregate with no elements requires explicit braces";
+        const kind = .@"error";
+    };
+    pub const ptr_init_discards_quals = struct {
+        const msg = "initializing {s} discards qualifiers";
+        const extra = .str;
+        const opt = "incompatible-pointer-types-discards-qualifiers";
+        const kind = .warning;
+    };
+    pub const ptr_assign_discards_quals = struct {
+        const msg = "assigning to {s} discards qualifiers";
+        const extra = .str;
+        const opt = "incompatible-pointer-types-discards-qualifiers";
+        const kind = .warning;
+    };
+    pub const ptr_ret_discards_quals = struct {
+        const msg = "returning {s} discards qualifiers";
+        const extra = .str;
+        const opt = "incompatible-pointer-types-discards-qualifiers";
+        const kind = .warning;
+    };
+    pub const ptr_arg_discards_quals = struct {
+        const msg = "passing {s} discards qualifiers";
+        const extra = .str;
+        const opt = "incompatible-pointer-types-discards-qualifiers";
+        const kind = .warning;
+    };
+    pub const unknown_attribute = struct {
+        const msg = "unknown attribute '{s}' ignored";
+        const extra = .str;
+        const opt = "unknown-attributes";
+        const kind = .warning;
+    };
+    pub const ignored_attribute = struct {
+        const msg = "{s}";
+        const extra = .str;
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const invalid_fallthrough = struct {
+        const msg = "fallthrough annotation does not directly precede switch label";
+        const kind = .@"error";
+    };
+    pub const cannot_apply_attribute_to_statement = struct {
+        const msg = "'{s}' attribute cannot be applied to a statement";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const builtin_macro_redefined = struct {
+        const msg = "redefining builtin macro";
+        const opt = "builtin-macro-redefined";
+        const kind = .warning;
+    };
+    pub const feature_check_requires_identifier = struct {
+        const msg = "builtin feature check macro requires a parenthesized identifier";
+        const kind = .@"error";
+    };
+    pub const missing_tok_builtin = struct {
+        const msg = "missing '{s}', after builtin feature-check macro";
+        const extra = .tok_id_expected;
+        const kind = .@"error";
+    };
+    pub const gnu_label_as_value = struct {
+        const msg = "use of GNU address-of-label extension";
+        const opt = "gnu-label-as-value";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const expected_record_ty = struct {
+        const msg = "member reference base type '{s}' is not a structure or union";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const member_expr_not_ptr = struct {
+        const msg = "member reference type '{s}' is not a pointer; did you mean to use '.'?";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const member_expr_ptr = struct {
+        const msg = "member reference type '{s}' is a pointer; did you mean to use '->'?";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const no_such_member = struct {
+        const msg = "no member named {s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const malformed_warning_check = struct {
+        const msg = "{s} expected option name (e.g. \"-Wundef\")";
+        const extra = .str;
+        const opt = "malformed-warning-check";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const invalid_computed_goto = struct {
+        const msg = "computed goto in function with no address-of-label expressions";
+        const kind = .@"error";
+    };
+    pub const pragma_warning_message = struct {
+        const msg = "{s}";
+        const extra = .str;
+        const opt = "#pragma-messages";
+        const kind = .warning;
+    };
+    pub const pragma_error_message = struct {
+        const msg = "{s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const pragma_message = struct {
+        const msg = "#pragma message: {s}";
+        const extra = .str;
+        const kind = .note;
+    };
+    pub const pragma_requires_string_literal = struct {
+        const msg = "pragma {s} requires string literal";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const poisoned_identifier = struct {
+        const msg = "attempt to use a poisoned identifier";
+        const kind = .@"error";
+    };
+    pub const pragma_poison_identifier = struct {
+        const msg = "can only poison identifier tokens";
+        const kind = .@"error";
+    };
+    pub const pragma_poison_macro = struct {
+        const msg = "poisoning existing macro";
+        const kind = .warning;
+    };
+    pub const newline_eof = struct {
+        const msg = "no newline at end of file";
+        const opt = "newline-eof";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const empty_translation_unit = struct {
+        const msg = "ISO C requires a translation unit to contain at least one declaration";
+        const opt = "empty-translation-unit";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const omitting_parameter_name = struct {
+        const msg = "omitting the parameter name in a function definition is a C2x extension";
+        const opt = "c2x-extensions";
+        const kind = .warning;
+        const suppress_version = .c2x;
+    };
+    pub const non_int_bitfield = struct {
+        const msg = "bit-field has non-integer type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const negative_bitwidth = struct {
+        const msg = "bit-field has negative width ({d})";
+        const extra = .signed;
+        const kind = .@"error";
+    };
+    pub const zero_width_named_field = struct {
+        const msg = "named bit-field has zero width";
+        const kind = .@"error";
+    };
+    pub const bitfield_too_big = struct {
+        const msg = "width of bit-field exceeds width of its type";
+        const kind = .@"error";
+    };
+    pub const invalid_utf8 = struct {
+        const msg = "source file is not valid UTF-8";
+        const kind = .@"error";
+    };
+    pub const implicitly_unsigned_literal = struct {
+        const msg = "integer literal is too large to be represented in a signed integer type, interpreting as unsigned";
+        const opt = "implicitly-unsigned-literal";
+        const kind = .warning;
+    };
+    pub const invalid_preproc_operator = struct {
+        const msg = "token is not a valid binary operator in a preprocessor subexpression";
+        const kind = .@"error";
+    };
+    pub const invalid_preproc_expr_start = struct {
+        const msg = "invalid token at start of a preprocessor expression";
+        const kind = .@"error";
+    };
+    pub const c99_compat = struct {
+        const msg = "using this character in an identifier is incompatible with C99";
+        const opt = "c99-compat";
+        const kind = .off;
+    };
+    pub const unicode_zero_width = struct {
+        const msg = "identifier contains Unicode character <U+{X:0>4}> that is invisible in some environments";
+        const opt = "unicode-homoglyph";
+        const extra = .actual_codepoint;
+        const kind = .warning;
+    };
+    pub const unicode_homoglyph = struct {
+        const msg = "treating Unicode character <U+{X:0>4}> as identifier character rather than as '{u}' symbol";
+        const extra = .codepoints;
+        const opt = "unicode-homoglyph";
+        const kind = .warning;
+    };
+    pub const meaningless_asm_qual = struct {
+        const msg = "meaningless '{s}' on assembly outside function";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const duplicate_asm_qual = struct {
+        const msg = "duplicate asm qualifier '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_asm_str = struct {
+        const msg = "cannot use {s} string literal in assembly";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const dollar_in_identifier_extension = struct {
+        const msg = "'$' in identifier";
+        const opt = "dollar-in-identifier-extension";
+        const kind = .off;
+        const suppress_language_option = "dollars_in_identifiers";
+        const pedantic = true;
+    };
+    pub const dollars_in_identifiers = struct {
+        const msg = "illegal character '$' in identifier";
+        const kind = .@"error";
+    };
+    pub const expanded_from_here = struct {
+        const msg = "expanded from here";
+        const kind = .note;
+    };
+    pub const skipping_macro_backtrace = struct {
+        const msg = "(skipping {d} expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)";
+        const extra = .unsigned;
+        const kind = .note;
+    };
+    pub const pragma_operator_string_literal = struct {
+        const msg = "_Pragma requires exactly one string literal token";
+        const kind = .@"error";
+    };
+    pub const unknown_gcc_pragma = struct {
+        const msg = "pragma GCC expected 'error', 'warning', 'diagnostic', 'poison'";
+        const opt = "unknown-pragmas";
+        const kind = .off;
+        const all = true;
+    };
+    pub const unknown_gcc_pragma_directive = struct {
+        const msg = "pragma GCC diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop'";
+        const opt = "unknown-pragmas";
+        const kind = .warning;
+        const all = true;
+    };
+    pub const predefined_top_level = struct {
+        const msg = "predefined identifier is only valid inside function";
+        const opt = "predefined-identifier-outside-function";
+        const kind = .warning;
+    };
+    pub const incompatible_va_arg = struct {
+        const msg = "first argument to va_arg, is of type '{s}' and not 'va_list'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const too_many_scalar_init_braces = struct {
+        const msg = "too many braces around scalar initializer";
+        const opt = "many-braces-around-scalar-init";
+        const kind = .warning;
+    };
+    pub const uninitialized_in_own_init = struct {
+        const msg = "variable '{s}' is uninitialized when used within its own initialization";
+        const extra = .str;
+        const opt = "uninitialized";
+        const kind = .off;
+        const all = true;
+    };
+    pub const gnu_statement_expression = struct {
+        const msg = "use of GNU statement expression extension";
+        const opt = "gnu-statement-expression";
+        const kind = .off;
+        const suppress_gnu = true;
+        const pedantic = true;
+    };
+    pub const stmt_expr_not_allowed_file_scope = struct {
+        const msg = "statement expression not allowed at file scope";
+        const kind = .@"error";
+    };
+    pub const gnu_imaginary_constant = struct {
+        const msg = "imaginary constants are a GNU extension";
+        const opt = "gnu-imaginary-constant";
+        const kind = .off;
+        const suppress_gnu = true;
+        const pedantic = true;
+    };
+    pub const plain_complex = struct {
+        const msg = "plain '_Complex' requires a type specifier; assuming '_Complex double'";
+        const kind = .warning;
+    };
+    pub const complex_int = struct {
+        const msg = "complex integer types are a GNU extension";
+        const opt = "gnu-complex-integer";
+        const suppress_gnu = true;
+        const kind = .off;
+    };
+    pub const qual_on_ret_type = struct {
+        const msg = "'{s}' type qualifier on return type has no effect";
+        const opt = "ignored-qualifiers";
+        const extra = .str;
+        const kind = .off;
+        const all = true;
+    };
+    pub const cli_invalid_standard = struct {
+        const msg = "invalid standard '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const cli_invalid_target = struct {
+        const msg = "invalid target '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const cli_invalid_emulate = struct {
+        const msg = "invalid compiler '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const cli_unknown_arg = struct {
+        const msg = "unknown argument '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const cli_error = struct {
+        const msg = "{s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const cli_unused_link_object = struct {
+        const msg = "{s}: linker input file unused because linking not done";
+        const extra = .str;
+        const kind = .warning;
+    };
+    pub const cli_unknown_linker = struct {
+        const msg = "unrecognized linker '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const extra_semi = struct {
+        const msg = "extra ';' outside of a function";
+        const opt = "extra-semi";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const func_field = struct {
+        const msg = "field declared as a function";
+        const kind = .@"error";
+    };
+    pub const vla_field = struct {
+        const msg = "variable length array fields extension is not supported";
+        const kind = .@"error";
+    };
+    pub const field_incomplete_ty = struct {
+        const msg = "field has incomplete type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const flexible_in_union = struct {
+        const msg = "flexible array member in union is not allowed";
+        const kind = .@"error";
+        const suppress_msvc = true;
+    };
+    pub const flexible_non_final = struct {
+        const msg = "flexible array member is not at the end of struct";
+        const kind = .@"error";
+    };
+    pub const flexible_in_empty = struct {
+        const msg = "flexible array member in otherwise empty struct";
+        const kind = .@"error";
+        const suppress_msvc = true;
+    };
+    pub const duplicate_member = struct {
+        const msg = "duplicate member '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const binary_integer_literal = struct {
+        const msg = "binary integer literals are a GNU extension";
+        const kind = .off;
+        const opt = "gnu-binary-literal";
+        const pedantic = true;
+    };
+    pub const gnu_va_macro = struct {
+        const msg = "named variadic macros are a GNU extension";
+        const opt = "variadic-macros";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const builtin_must_be_called = struct {
+        const msg = "builtin function must be directly called";
+        const kind = .@"error";
+    };
+    pub const va_start_not_in_func = struct {
+        const msg = "'va_start' cannot be used outside a function";
+        const kind = .@"error";
+    };
+    pub const va_start_fixed_args = struct {
+        const msg = "'va_start' used in a function with fixed args";
+        const kind = .@"error";
+    };
+    pub const va_start_not_last_param = struct {
+        const msg = "second argument to 'va_start' is not the last named parameter";
+        const opt = "varargs";
+        const kind = .warning;
+    };
+    pub const attribute_not_enough_args = struct {
+        const msg = "'{s}' attribute takes at least {d} argument(s)";
+        const kind = .@"error";
+        const extra = .attr_arg_count;
+    };
+    pub const attribute_too_many_args = struct {
+        const msg = "'{s}' attribute takes at most {d} argument(s)";
+        const kind = .@"error";
+        const extra = .attr_arg_count;
+    };
+    pub const attribute_arg_invalid = struct {
+        const msg = "Attribute argument is invalid, expected {s} but got {s}";
+        const kind = .@"error";
+        const extra = .attr_arg_type;
+    };
+    pub const unknown_attr_enum = struct {
+        const msg = "Unknown `{s}` argument. Possible values are: {s}";
+        const kind = .@"error";
+        const extra = .attr_enum;
+    };
+    pub const attribute_requires_identifier = struct {
+        const msg = "'{s}' attribute requires an identifier";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const declspec_not_enabled = struct {
+        const msg = "'__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes";
+        const kind = .@"error";
+    };
+    pub const declspec_attr_not_supported = struct {
+        const msg = "__declspec attribute '{s}' is not supported";
+        const extra = .str;
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const deprecated_declarations = struct {
+        const msg = "{s}";
+        const extra = .str;
+        const opt = "deprecated-declarations";
+        const kind = .warning;
+    };
+    pub const deprecated_note = struct {
+        const msg = "'{s}' has been explicitly marked deprecated here";
+        const extra = .str;
+        const opt = "deprecated-declarations";
+        const kind = .note;
+    };
+    pub const unavailable = struct {
+        const msg = "{s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const unavailable_note = struct {
+        const msg = "'{s}' has been explicitly marked unavailable here";
+        const extra = .str;
+        const kind = .note;
+    };
+    pub const warning_attribute = struct {
+        const msg = "{s}";
+        const extra = .str;
+        const kind = .warning;
+        const opt = "attribute-warning";
+    };
+    pub const error_attribute = struct {
+        const msg = "{s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const ignored_record_attr = struct {
+        const msg = "attribute '{s}' is ignored, place it after \"{s}\" to apply attribute to type declaration";
+        const extra = .ignored_record_attr;
+        const kind = .warning;
+        const opt = "ignored-attributes";
+    };
+    pub const backslash_newline_escape = struct {
+        const msg = "backslash and newline separated by space";
+        const kind = .warning;
+        const opt = "backslash-newline-escape";
+    };
+    pub const array_size_non_int = struct {
+        const msg = "size of array has non-integer type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const cast_to_smaller_int = struct {
+        const msg = "cast to smaller integer type {s}";
+        const extra = .str;
+        const kind = .warning;
+        const opt = "pointer-to-int-cast";
+    };
+    pub const gnu_switch_range = struct {
+        const msg = "use of GNU case range extension";
+        const opt = "gnu-case-range";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const empty_case_range = struct {
+        const msg = "empty case range specified";
+        const kind = .warning;
+    };
+    pub const non_standard_escape_char = struct {
+        const msg = "use of non-standard escape character '\\e'";
+        const kind = .off;
+        const opt = "pedantic";
+    };
+    pub const invalid_pp_stringify_escape = struct {
+        const msg = "invalid string literal, ignoring final '\\'";
+        const kind = .warning;
+    };
+    pub const vla = struct {
+        const msg = "variable length array used";
+        const kind = .off;
+        const opt = "vla";
+    };
+    pub const float_overflow_conversion = struct {
+        const msg = "implicit conversion of non-finite value from {s} is undefined";
+        const extra = .str;
+        const kind = .off;
+        const opt = "float-overflow-conversion";
+    };
+    pub const float_out_of_range = struct {
+        const msg = "implicit conversion of out of range value from {s} is undefined";
+        const extra = .str;
+        const kind = .warning;
+        const opt = "literal-conversion";
+    };
+    pub const float_zero_conversion = struct {
+        const msg = "implicit conversion from {s}";
+        const extra = .str;
+        const kind = .off;
+        const opt = "float-zero-conversion";
+    };
+    pub const float_value_changed = struct {
+        const msg = "implicit conversion from {s}";
+        const extra = .str;
+        const kind = .warning;
+        const opt = "float-conversion";
+    };
+    pub const float_to_int = struct {
+        const msg = "implicit conversion turns floating-point number into integer: {s}";
+        const extra = .str;
+        const kind = .off;
+        const opt = "literal-conversion";
+    };
+    pub const const_decl_folded = struct {
+        const msg = "expression is not an integer constant expression; folding it to a constant is a GNU extension";
+        const kind = .off;
+        const opt = "gnu-folding-constant";
+        const pedantic = true;
+    };
+    pub const const_decl_folded_vla = struct {
+        const msg = "variable length array folded to constant array as an extension";
+        const kind = .off;
+        const opt = "gnu-folding-constant";
+        const pedantic = true;
+    };
+    pub const redefinition_of_typedef = struct {
+        const msg = "typedef redefinition with different types ({s})";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const undefined_macro = struct {
+        const msg = "'{s}' is not defined, evaluates to 0";
+        const extra = .str;
+        const kind = .off;
+        const opt = "undef";
+    };
+    pub const fn_macro_undefined = struct {
+        const msg = "function-like macro '{s}' is not defined";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const preprocessing_directive_only = struct {
+        const msg = "'{s}' must be used within a preprocessing directive";
+        const extra = .tok_id_expected;
+        const kind = .@"error";
+    };
+    pub const missing_lparen_after_builtin = struct {
+        const msg = "Missing '(' after built-in macro '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const offsetof_ty = struct {
+        const msg = "offsetof requires struct or union type, '{s}' invalid";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const offsetof_incomplete = struct {
+        const msg = "offsetof of incomplete type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const offsetof_array = struct {
+        const msg = "offsetof requires array type, '{s}' invalid";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const pragma_pack_lparen = struct {
+        const msg = "missing '(' after '#pragma pack' - ignoring";
+        const kind = .warning;
+        const opt = "ignored-pragmas";
+    };
+    pub const pragma_pack_rparen = struct {
+        const msg = "missing ')' after '#pragma pack' - ignoring";
+        const kind = .warning;
+        const opt = "ignored-pragmas";
+    };
+    pub const pragma_pack_unknown_action = struct {
+        const msg = "unknown action for '#pragma pack' - ignoring";
+        const opt = "ignored-pragmas";
+        const kind = .warning;
+    };
+    pub const pragma_pack_show = struct {
+        const msg = "value of #pragma pack(show) == {d}";
+        const extra = .unsigned;
+        const kind = .warning;
+    };
+    pub const pragma_pack_int = struct {
+        const msg = "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'";
+        const opt = "ignored-pragmas";
+        const kind = .warning;
+    };
+    pub const pragma_pack_int_ident = struct {
+        const msg = "expected integer or identifier in '#pragma pack' - ignored";
+        const opt = "ignored-pragmas";
+        const kind = .warning;
+    };
+    pub const pragma_pack_undefined_pop = struct {
+        const msg = "specifying both a name and alignment to 'pop' is undefined";
+        const kind = .warning;
+    };
+    pub const pragma_pack_empty_stack = struct {
+        const msg = "#pragma pack(pop, ...) failed: stack empty";
+        const opt = "ignored-pragmas";
+        const kind = .warning;
+    };
+    pub const cond_expr_type = struct {
+        const msg = "used type '{s}' where arithmetic or pointer type is required";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const too_many_includes = struct {
+        const msg = "#include nested too deeply";
+        const kind = .@"error";
+    };
+    pub const enumerator_too_small = struct {
+        const msg = "ISO C restricts enumerator values to range of 'int' ({d} is too small)";
+        const extra = .signed;
+        const kind = .off;
+        const opt = "pedantic";
+    };
+    pub const enumerator_too_large = struct {
+        const msg = "ISO C restricts enumerator values to range of 'int' ({d} is too large)";
+        const extra = .unsigned;
+        const kind = .off;
+        const opt = "pedantic";
+    };
+    pub const include_next = struct {
+        const msg = "#include_next is a language extension";
+        const kind = .off;
+        const pedantic = true;
+        const opt = "gnu-include-next";
+    };
+    pub const include_next_outside_header = struct {
+        const msg = "#include_next in primary source file; will search from start of include path";
+        const kind = .warning;
+        const opt = "include-next-outside-header";
+    };
+    pub const enumerator_overflow = struct {
+        const msg = "overflow in enumeration value";
+        const kind = .warning;
+    };
+    pub const enum_not_representable = struct {
+        const msg = "incremented enumerator value {s} is not representable in the largest integer type";
+        const kind = .warning;
+        const opt = "enum-too-large";
+        const extra = .pow_2_as_string;
+    };
+    pub const enum_too_large = struct {
+        const msg = "enumeration values exceed range of largest integer";
+        const kind = .warning;
+        const opt = "enum-too-large";
+    };
+    pub const enum_fixed = struct {
+        const msg = "enumeration types with a fixed underlying type are a Clang extension";
+        const kind = .off;
+        const pedantic = true;
+        const opt = "fixed-enum-extension";
+    };
+    pub const enum_prev_nonfixed = struct {
+        const msg = "enumeration previously declared with nonfixed underlying type";
+        const kind = .@"error";
+    };
+    pub const enum_prev_fixed = struct {
+        const msg = "enumeration previously declared with fixed underlying type";
+        const kind = .@"error";
+    };
+    pub const enum_different_explicit_ty = struct {
+        // str will be like 'new' (was 'old'
+        const msg = "enumeration redeclared with different underlying type {s})";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const enum_not_representable_fixed = struct {
+        const msg = "enumerator value is not representable in the underlying type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const transparent_union_wrong_type = struct {
+        const msg = "'transparent_union' attribute only applies to unions";
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const transparent_union_one_field = struct {
+        const msg = "transparent union definition must contain at least one field; transparent_union attribute ignored";
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const transparent_union_size = struct {
+        const msg = "size of field {s} bits) does not match the size of the first field in transparent union; transparent_union attribute ignored";
+        const extra = .str;
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const transparent_union_size_note = struct {
+        const msg = "size of first field is {d}";
+        const extra = .unsigned;
+        const kind = .note;
+    };
+    pub const designated_init_invalid = struct {
+        const msg = "'designated_init' attribute is only valid on 'struct' type'";
+        const kind = .@"error";
+    };
+    pub const designated_init_needed = struct {
+        const msg = "positional initialization of field in 'struct' declared with 'designated_init' attribute";
+        const opt = "designated-init";
+        const kind = .warning;
+    };
+    pub const ignore_common = struct {
+        const msg = "ignoring attribute 'common' because it conflicts with attribute 'nocommon'";
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const ignore_nocommon = struct {
+        const msg = "ignoring attribute 'nocommon' because it conflicts with attribute 'common'";
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const non_string_ignored = struct {
+        const msg = "'nonstring' attribute ignored on objects of type '{s}'";
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const local_variable_attribute = struct {
+        const msg = "'{s}' attribute only applies to local variables";
+        const extra = .str;
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const ignore_cold = struct {
+        const msg = "ignoring attribute 'cold' because it conflicts with attribute 'hot'";
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const ignore_hot = struct {
+        const msg = "ignoring attribute 'hot' because it conflicts with attribute 'cold'";
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const ignore_noinline = struct {
+        const msg = "ignoring attribute 'noinline' because it conflicts with attribute 'always_inline'";
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const ignore_always_inline = struct {
+        const msg = "ignoring attribute 'always_inline' because it conflicts with attribute 'noinline'";
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const invalid_noreturn = struct {
+        const msg = "function '{s}' declared 'noreturn' should not return";
+        const extra = .str;
+        const kind = .warning;
+        const opt = "invalid-noreturn";
+    };
+    pub const nodiscard_unused = struct {
+        const msg = "ignoring return value of '{s}', declared with 'nodiscard' attribute";
+        const extra = .str;
+        const kind = .warning;
+        const op = "unused-result";
+    };
+    pub const warn_unused_result = struct {
+        const msg = "ignoring return value of '{s}', declared with 'warn_unused_result' attribute";
+        const extra = .str;
+        const kind = .warning;
+        const op = "unused-result";
+    };
+    pub const invalid_vec_elem_ty = struct {
+        const msg = "invalid vector element type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const vec_size_not_multiple = struct {
+        const msg = "vector size not an integral multiple of component size";
+        const kind = .@"error";
+    };
+    pub const invalid_imag = struct {
+        const msg = "invalid type '{s}' to __imag operator";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_real = struct {
+        const msg = "invalid type '{s}' to __real operator";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const zero_length_array = struct {
+        const msg = "zero size arrays are an extension";
+        const kind = .off;
+        const pedantic = true;
+        const opt = "zero-length-array";
+    };
+    pub const old_style_flexible_struct = struct {
+        const msg = "array index {d} is past the end of the array";
+        const extra = .unsigned;
+        const kind = .off;
+        const pedantic = true;
+        const opt = "old-style-flexible-struct";
+    };
+    pub const comma_deletion_va_args = struct {
+        const msg = "token pasting of ',' and __VA_ARGS__ is a GNU extension";
+        const kind = .off;
+        const pedantic = true;
+        const opt = "gnu-zero-variadic-macro-arguments";
+        const suppress_gcc = true;
+    };
+    pub const main_return_type = struct {
+        const msg = "return type of 'main' is not 'int'";
+        const kind = .warning;
+        const opt = "main-return-type";
+    };
+    pub const expansion_to_defined = struct {
+        const msg = "macro expansion producing 'defined' has undefined behavior";
+        const kind = .off;
+        const pedantic = true;
+        const opt = "expansion-to-defined";
+    };
+    pub const invalid_int_suffix = struct {
+        const msg = "invalid suffix '{s}' on integer constant";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_float_suffix = struct {
+        const msg = "invalid suffix '{s}' on floating constant";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const invalid_octal_digit = struct {
+        const msg = "invalid digit '{c}' in octal constant";
+        const extra = .ascii;
+        const kind = .@"error";
+    };
+    pub const invalid_binary_digit = struct {
+        const msg = "invalid digit '{c}' in binary constant";
+        const extra = .ascii;
+        const kind = .@"error";
+    };
+    pub const exponent_has_no_digits = struct {
+        const msg = "exponent has no digits";
+        const kind = .@"error";
+    };
+    pub const hex_floating_constant_requires_exponent = struct {
+        const msg = "hexadecimal floating constant requires an exponent";
+        const kind = .@"error";
+    };
+    pub const sizeof_returns_zero = struct {
+        const msg = "sizeof returns 0";
+        const kind = .warning;
+        const suppress_gcc = true;
+        const suppress_clang = true;
+    };
+    pub const declspec_not_allowed_after_declarator = struct {
+        const msg = "'declspec' attribute not allowed after declarator";
+        const kind = .@"error";
+    };
+    pub const declarator_name_tok = struct {
+        const msg = "this declarator";
+        const kind = .note;
+    };
+    pub const type_not_supported_on_target = struct {
+        const msg = "{s} is not supported on this target";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const bit_int = struct {
+        const msg = "'_BitInt' in C17 and earlier is a Clang extension'";
+        const kind = .off;
+        const pedantic = true;
+        const opt = "bit-int-extension";
+        const suppress_version = .c2x;
+    };
+    pub const unsigned_bit_int_too_small = struct {
+        const msg = "{s} must have a bit size of at least 1";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const signed_bit_int_too_small = struct {
+        const msg = "{s} must have a bit size of at least 2";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const bit_int_too_big = struct {
+        const msg = "{s} of bit sizes greater than " ++ std.fmt.comptimePrint("{d}", .{Compilation.bit_int_max_bits}) ++ " not supported";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const keyword_macro = struct {
+        const msg = "keyword is hidden by macro definition";
+        const kind = .off;
+        const pedantic = true;
+        const opt = "keyword-macro";
+    };
+    pub const ptr_arithmetic_incomplete = struct {
+        const msg = "arithmetic on a pointer to an incomplete type '{s}'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const callconv_not_supported = struct {
+        const msg = "'{s}' calling convention is not supported for this target";
+        const extra = .str;
+        const opt = "ignored-attributes";
+        const kind = .warning;
+    };
+    pub const pointer_arith_void = struct {
+        const msg = "invalid application of '{s}' to a void type";
+        const extra = .str;
+        const kind = .off;
+        const pedantic = true;
+        const opt = "pointer-arith";
+    };
+    pub const sizeof_array_arg = struct {
+        const msg = "sizeof on array function parameter will return size of {s}";
+        const extra = .str;
+        const kind = .warning;
+        const opt = "sizeof-array-argument";
+    };
+    pub const array_address_to_bool = struct {
+        const msg = "address of array '{s}' will always evaluate to 'true'";
+        const extra = .str;
+        const kind = .warning;
+        const opt = "pointer-bool-conversion";
+    };
+    pub const string_literal_to_bool = struct {
+        const msg = "implicit conversion turns string literal into bool: {s}";
+        const extra = .str;
+        const kind = .off;
+        const opt = "string-conversion";
+    };
+    pub const constant_expression_conversion_not_allowed = struct {
+        const msg = "this conversion is not allowed in a constant expression";
+        const kind = .note;
+    };
+    pub const invalid_object_cast = struct {
+        const msg = "cannot cast an object of type {s}";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const cli_invalid_fp_eval_method = struct {
+        const msg = "unsupported argument '{s}' to option '-ffp-eval-method='; expected 'source', 'double', or 'extended'";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const suggest_pointer_for_invalid_fp16 = struct {
+        const msg = "{s} cannot have __fp16 type; did you forget * ?";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const bitint_suffix = struct {
+        const msg = "'_BitInt' suffix for literals is a C2x extension";
+        const opt = "c2x-extensions";
+        const kind = .warning;
+        const suppress_version = .c2x;
+    };
+    pub const auto_type_extension = struct {
+        const msg = "'__auto_type' is a GNU extension";
+        const opt = "gnu-auto-type";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const auto_type_not_allowed = struct {
+        const msg = "'__auto_type' not allowed in {s}";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const auto_type_requires_initializer = struct {
+        const msg = "declaration of variable '{s}' with deduced type requires an initializer";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const auto_type_requires_single_declarator = struct {
+        const msg = "'__auto_type' may only be used with a single declarator";
+        const kind = .@"error";
+    };
+    pub const auto_type_requires_plain_declarator = struct {
+        const msg = "'__auto_type' requires a plain identifier as declarator";
+        const kind = .@"error";
+    };
+    pub const invalid_cast_to_auto_type = struct {
+        const msg = "invalid cast to '__auto_type'";
+        const kind = .@"error";
+    };
+    pub const auto_type_from_bitfield = struct {
+        const msg = "cannot use bit-field as '__auto_type' initializer";
+        const kind = .@"error";
+    };
+    pub const array_of_auto_type = struct {
+        const msg = "'{s}' declared as array of '__auto_type'";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const auto_type_with_init_list = struct {
+        const msg = "cannot use '__auto_type' with initializer list";
+        const kind = .@"error";
+    };
+    pub const missing_semicolon = struct {
+        const msg = "expected ';' at end of declaration list";
+        const kind = .warning;
+    };
+    pub const tentative_definition_incomplete = struct {
+        const msg = "tentative definition has type '{s}' that is never completed";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const forward_declaration_here = struct {
+        const msg = "forward declaration of '{s}'";
+        const kind = .note;
+        const extra = .str;
+    };
+    pub const gnu_union_cast = struct {
+        const msg = "cast to union type is a GNU extension";
+        const opt = "gnu-union-cast";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const invalid_union_cast = struct {
+        const msg = "cast to union type from type '{s}' not present in union";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const cast_to_incomplete_type = struct {
+        const msg = "cast to incomplete type '{s}'";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const invalid_source_epoch = struct {
+        const msg = "environment variable SOURCE_DATE_EPOCH must expand to a non-negative integer less than or equal to 253402300799";
+        const kind = .@"error";
+    };
+    pub const fuse_ld_path = struct {
+        const msg = "'-fuse-ld=' taking a path is deprecated; use '--ld-path=' instead";
+        const kind = .off;
+        const opt = "fuse-ld-path";
+    };
+    pub const invalid_rtlib = struct {
+        const msg = "invalid runtime library name '{s}'";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const unsupported_rtlib_gcc = struct {
+        const msg = "unsupported runtime library 'libgcc' for platform '{s}'";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const invalid_unwindlib = struct {
+        const msg = "invalid unwind library name '{s}'";
+        const kind = .@"error";
+        const extra = .str;
+    };
+    pub const incompatible_unwindlib = struct {
+        const msg = "--rtlib=libgcc requires --unwindlib=libgcc";
+        const kind = .@"error";
+    };
+    pub const gnu_asm_disabled = struct {
+        const msg = "GNU-style inline assembly is disabled";
+        const kind = .@"error";
+    };
+    pub const extension_token_used = struct {
+        const msg = "extension used";
+        const kind = .off;
+        const pedantic = true;
+        const opt = "language-extension-token";
+    };
+    pub const complex_component_init = struct {
+        const msg = "complex initialization specifying real and imaginary components is an extension";
+        const opt = "complex-component-init";
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const complex_prefix_postfix_op = struct {
+        const msg = "ISO C does not support '++'/'--' on complex type '{s}'";
+        const opt = "pedantic";
+        const extra = .str;
+        const kind = .off;
+        const pedantic = true;
+    };
+    pub const not_floating_type = struct {
+        const msg = "argument type '{s}' is not a real floating point type";
+        const extra = .str;
+        const kind = .@"error";
+    };
+    pub const argument_types_differ = struct {
+        const msg = "arguments are of different types ({s})";
+        const extra = .str;
+        const kind = .@"error";
+    };
+};
+
+list: std.ArrayListUnmanaged(Message) = .{},
+arena: std.heap.ArenaAllocator,
+color: bool = true,
+fatal_errors: bool = false,
+options: Options = .{},
+errors: u32 = 0,
+macro_backtrace_limit: u32 = 6,
+
+pub fn warningExists(name: []const u8) bool {
+    inline for (std.meta.fields(Options)) |f| {
+        if (mem.eql(u8, f.name, name)) return true;
+    }
+    return false;
+}
+
+pub fn set(diag: *Diagnostics, name: []const u8, to: Kind) !void {
+    inline for (std.meta.fields(Options)) |f| {
+        if (mem.eql(u8, f.name, name)) {
+            @field(diag.options, f.name) = to;
+            return;
+        }
+    }
+    try diag.add(.{
+        .tag = .unknown_warning,
+        .extra = .{ .str = name },
+    }, &.{});
+}
+
+pub fn init(gpa: Allocator) Diagnostics {
+    return .{
+        .arena = std.heap.ArenaAllocator.init(gpa),
+    };
+}
+
+pub fn deinit(diag: *Diagnostics) void {
+    diag.list.deinit(diag.arena.allocator());
+    diag.arena.deinit();
+}
+
+pub fn add(diag: *Diagnostics, msg: Message, expansion_locs: []const Source.Location) Compilation.Error!void {
+    const kind = diag.tagKind(msg.tag);
+    if (kind == .off) return;
+    var copy = msg;
+    copy.kind = kind;
+
+    if (expansion_locs.len != 0) copy.loc = expansion_locs[expansion_locs.len - 1];
+    try diag.list.append(diag.arena.allocator(), copy);
+    if (expansion_locs.len != 0) {
+        // Add macro backtrace notes in reverse order omitting from the middle if needed.
+        var i = expansion_locs.len - 1;
+        const half = diag.macro_backtrace_limit / 2;
+        const limit = if (i < diag.macro_backtrace_limit) 0 else i - half;
+        try diag.list.ensureUnusedCapacity(
+            diag.arena.allocator(),
+            if (limit == 0) expansion_locs.len else diag.macro_backtrace_limit + 1,
+        );
+        while (i > limit) {
+            i -= 1;
+            diag.list.appendAssumeCapacity(.{
+                .tag = .expanded_from_here,
+                .kind = .note,
+                .loc = expansion_locs[i],
+            });
+        }
+        if (limit != 0) {
+            diag.list.appendAssumeCapacity(.{
+                .tag = .skipping_macro_backtrace,
+                .kind = .note,
+                .extra = .{ .unsigned = expansion_locs.len - diag.macro_backtrace_limit },
+            });
+            i = half - 1;
+            while (i > 0) {
+                i -= 1;
+                diag.list.appendAssumeCapacity(.{
+                    .tag = .expanded_from_here,
+                    .kind = .note,
+                    .loc = expansion_locs[i],
+                });
+            }
+        }
+
+        diag.list.appendAssumeCapacity(.{
+            .tag = .expanded_from_here,
+            .kind = .note,
+            .loc = msg.loc,
+        });
+    }
+    if (kind == .@"fatal error" or (kind == .@"error" and diag.fatal_errors))
+        return error.FatalError;
+}
+
+pub fn fatal(
+    diag: *Diagnostics,
+    path: []const u8,
+    line: []const u8,
+    line_no: u32,
+    col: u32,
+    comptime fmt: []const u8,
+    args: anytype,
+) Compilation.Error {
+    var m = MsgWriter.init(diag.color);
+    defer m.deinit();
+
+    m.location(path, line_no, col);
+    m.start(.@"fatal error");
+    m.print(fmt, args);
+    m.end(line, col, false);
+
+    diag.errors += 1;
+    return error.FatalError;
+}
+
+pub fn fatalNoSrc(diag: *Diagnostics, comptime fmt: []const u8, args: anytype) error{FatalError} {
+    if (!diag.color) {
+        std.debug.print("fatal error: " ++ fmt ++ "\n", args);
+    } else {
+        const std_err = std.io.getStdErr().writer();
+        util.setColor(.red, std_err);
+        std_err.writeAll("fatal error: ") catch {};
+        util.setColor(.white, std_err);
+        std_err.print(fmt ++ "\n", args) catch {};
+        util.setColor(.reset, std_err);
+    }
+    diag.errors += 1;
+    return error.FatalError;
+}
+
+pub fn render(comp: *Compilation) void {
+    if (comp.diag.list.items.len == 0) return;
+    var m = defaultMsgWriter(comp);
+    defer m.deinit();
+    renderMessages(comp, &m);
+}
+pub fn defaultMsgWriter(comp: *const Compilation) MsgWriter {
+    return MsgWriter.init(comp.diag.color);
+}
+
+pub fn renderMessages(comp: *Compilation, m: anytype) void {
+    var errors: u32 = 0;
+    var warnings: u32 = 0;
+    for (comp.diag.list.items) |msg| {
+        switch (msg.kind) {
+            .@"fatal error", .@"error" => errors += 1,
+            .warning => warnings += 1,
+            .note => {},
+            .off => continue, // happens if an error is added before it is disabled
+            .default => unreachable,
+        }
+        renderMessage(comp, m, msg);
+    }
+    const w_s: []const u8 = if (warnings == 1) "" else "s";
+    const e_s: []const u8 = if (errors == 1) "" else "s";
+    if (errors != 0 and warnings != 0) {
+        m.print("{d} warning{s} and {d} error{s} generated.\n", .{ warnings, w_s, errors, e_s });
+    } else if (warnings != 0) {
+        m.print("{d} warning{s} generated.\n", .{ warnings, w_s });
+    } else if (errors != 0) {
+        m.print("{d} error{s} generated.\n", .{ errors, e_s });
+    }
+
+    comp.diag.list.items.len = 0;
+    comp.diag.errors += errors;
+}
+
+pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void {
+    var line: ?[]const u8 = null;
+    var end_with_splice = false;
+    const width = if (msg.loc.id != .unused) blk: {
+        var loc = msg.loc;
+        switch (msg.tag) {
+            .escape_sequence_overflow,
+            .invalid_universal_character,
+            .non_standard_escape_char,
+            // use msg.extra.unsigned for index into string literal
+            => loc.byte_offset += @truncate(msg.extra.unsigned),
+            else => {},
+        }
+        const source = comp.getSource(loc.id);
+        var line_col = source.lineCol(loc);
+        line = line_col.line;
+        end_with_splice = line_col.end_with_splice;
+        if (msg.tag == .backslash_newline_escape) {
+            line = line_col.line[0 .. line_col.col - 1];
+            line_col.col += 1;
+            line_col.width += 1;
+        }
+        m.location(source.path, line_col.line_no, line_col.col);
+        break :blk line_col.width;
+    } else 0;
+
+    m.start(msg.kind);
+    @setEvalBranchQuota(1500);
+    switch (msg.tag) {
+        inline else => |tag| {
+            const info = @field(messages, @tagName(tag));
+            if (@hasDecl(info, "extra")) {
+                switch (info.extra) {
+                    .str => m.print(info.msg, .{msg.extra.str}),
+                    .tok_id => m.print(info.msg, .{
+                        msg.extra.tok_id.expected.symbol(),
+                        msg.extra.tok_id.actual.symbol(),
+                    }),
+                    .tok_id_expected => m.print(info.msg, .{msg.extra.tok_id_expected.symbol()}),
+                    .arguments => m.print(info.msg, .{ msg.extra.arguments.expected, msg.extra.arguments.actual }),
+                    .codepoints => m.print(info.msg, .{
+                        msg.extra.codepoints.actual,
+                        msg.extra.codepoints.resembles,
+                    }),
+                    .attr_arg_count => m.print(info.msg, .{
+                        @tagName(msg.extra.attr_arg_count.attribute),
+                        msg.extra.attr_arg_count.expected,
+                    }),
+                    .attr_arg_type => m.print(info.msg, .{
+                        msg.extra.attr_arg_type.expected.toString(),
+                        msg.extra.attr_arg_type.actual.toString(),
+                    }),
+                    .actual_codepoint => m.print(info.msg, .{msg.extra.actual_codepoint}),
+                    .ascii => m.print(info.msg, .{msg.extra.ascii}),
+                    .unsigned => m.print(info.msg, .{msg.extra.unsigned}),
+                    .pow_2_as_string => m.print(info.msg, .{switch (msg.extra.pow_2_as_string) {
+                        63 => "9223372036854775808",
+                        64 => "18446744073709551616",
+                        127 => "170141183460469231731687303715884105728",
+                        128 => "340282366920938463463374607431768211456",
+                        else => unreachable,
+                    }}),
+                    .signed => m.print(info.msg, .{msg.extra.signed}),
+                    .attr_enum => m.print(info.msg, .{
+                        @tagName(msg.extra.attr_enum.tag),
+                        Attribute.Formatting.choices(msg.extra.attr_enum.tag),
+                    }),
+                    .ignored_record_attr => m.print(info.msg, .{
+                        @tagName(msg.extra.ignored_record_attr.tag),
+                        @tagName(msg.extra.ignored_record_attr.specifier),
+                    }),
+                    .builtin_with_header => m.print(info.msg, .{
+                        @tagName(msg.extra.builtin_with_header.header),
+                        @tagName(msg.extra.builtin_with_header.builtin),
+                    }),
+                    else => @compileError("invalid extra kind " ++ @tagName(info.extra)),
+                }
+            } else {
+                m.write(info.msg);
+            }
+
+            if (@hasDecl(info, "opt")) {
+                if (msg.kind == .@"error" and info.kind != .@"error") {
+                    m.print(" [-Werror,-W{s}]", .{info.opt});
+                } else if (msg.kind != .note) {
+                    m.print(" [-W{s}]", .{info.opt});
+                }
+            }
+        },
+    }
+
+    m.end(line, width, end_with_splice);
+}
+
+fn tagKind(diag: *Diagnostics, tag: Tag) Kind {
+    // XXX: horrible hack, do not do this
+    const comp = @fieldParentPtr(Compilation, "diag", diag);
+
+    var kind: Kind = undefined;
+    switch (tag) {
+        inline else => |tag_val| {
+            const info = @field(messages, @tagName(tag_val));
+            kind = info.kind;
+
+            // stage1 doesn't like when I combine these ifs
+            if (@hasDecl(info, "all")) {
+                if (diag.options.all != .default) kind = diag.options.all;
+            }
+            if (@hasDecl(info, "w_extra")) {
+                if (diag.options.extra != .default) kind = diag.options.extra;
+            }
+            if (@hasDecl(info, "pedantic")) {
+                if (diag.options.pedantic != .default) kind = diag.options.pedantic;
+            }
+            if (@hasDecl(info, "opt")) {
+                if (@field(diag.options, info.opt) != .default) kind = @field(diag.options, info.opt);
+            }
+            if (@hasDecl(info, "suppress_version")) if (comp.langopts.standard.atLeast(info.suppress_version)) return .off;
+            if (@hasDecl(info, "suppress_unless_version")) if (!comp.langopts.standard.atLeast(info.suppress_unless_version)) return .off;
+            if (@hasDecl(info, "suppress_gnu")) if (comp.langopts.standard.isExplicitGNU()) return .off;
+            if (@hasDecl(info, "suppress_language_option")) if (!@field(comp.langopts, info.suppress_language_option)) return .off;
+            if (@hasDecl(info, "suppress_gcc")) if (comp.langopts.emulate == .gcc) return .off;
+            if (@hasDecl(info, "suppress_clang")) if (comp.langopts.emulate == .clang) return .off;
+            if (@hasDecl(info, "suppress_msvc")) if (comp.langopts.emulate == .msvc) return .off;
+            if (kind == .@"error" and diag.fatal_errors) kind = .@"fatal error";
+            return kind;
+        },
+    }
+}
+
+const MsgWriter = struct {
+    w: std.io.BufferedWriter(4096, std.fs.File.Writer),
+    color: bool,
+
+    fn init(color: bool) MsgWriter {
+        std.debug.getStderrMutex().lock();
+        return .{
+            .w = std.io.bufferedWriter(std.io.getStdErr().writer()),
+            .color = color,
+        };
+    }
+
+    pub fn deinit(m: *MsgWriter) void {
+        m.w.flush() catch {};
+        std.debug.getStderrMutex().unlock();
+    }
+
+    pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void {
+        m.w.writer().print(fmt, args) catch {};
+    }
+
+    fn write(m: *MsgWriter, msg: []const u8) void {
+        m.w.writer().writeAll(msg) catch {};
+    }
+
+    fn setColor(m: *MsgWriter, color: util.Color) void {
+        util.setColor(color, m.w.writer());
+    }
+
+    fn location(m: *MsgWriter, path: []const u8, line: u32, col: u32) void {
+        const prefix = if (std.fs.path.dirname(path) == null and path[0] != '<') "." ++ std.fs.path.sep_str else "";
+        if (!m.color) {
+            m.print("{s}{s}:{d}:{d}: ", .{ prefix, path, line, col });
+        } else {
+            m.setColor(.white);
+            m.print("{s}{s}:{d}:{d}: ", .{ prefix, path, line, col });
+        }
+    }
+
+    fn start(m: *MsgWriter, kind: Kind) void {
+        if (!m.color) {
+            m.print("{s}: ", .{@tagName(kind)});
+        } else {
+            switch (kind) {
+                .@"fatal error", .@"error" => m.setColor(.red),
+                .note => m.setColor(.cyan),
+                .warning => m.setColor(.purple),
+                .off, .default => unreachable,
+            }
+            m.write(switch (kind) {
+                .@"fatal error" => "fatal error: ",
+                .@"error" => "error: ",
+                .note => "note: ",
+                .warning => "warning: ",
+                .off, .default => unreachable,
+            });
+            m.setColor(.white);
+        }
+    }
+
+    fn end(m: *MsgWriter, maybe_line: ?[]const u8, col: u32, end_with_splice: bool) void {
+        const line = maybe_line orelse {
+            m.write("\n");
+            return;
+        };
+        const trailer = if (end_with_splice) "\\ " else "";
+        if (!m.color) {
+            m.print("\n{s}{s}\n", .{ line, trailer });
+            m.print("{s: >[1]}^\n", .{ "", col });
+        } else {
+            m.setColor(.reset);
+            m.print("\n{s}{s}\n{s: >[3]}", .{ line, trailer, "", col });
+            m.setColor(.green);
+            m.write("^\n");
+            m.setColor(.reset);
+        }
+    }
+};
deps/aro/Driver.zig
@@ -0,0 +1,683 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const process = std.process;
+const Codegen = @import("Codegen_legacy.zig");
+const Compilation = @import("Compilation.zig");
+const LangOpts = @import("LangOpts.zig");
+const Preprocessor = @import("Preprocessor.zig");
+const Parser = @import("Parser.zig");
+const Source = @import("Source.zig");
+const Toolchain = @import("Toolchain.zig");
+const util = @import("util.zig");
+const target_util = @import("target.zig");
+
+const Driver = @This();
+
+pub const Linker = enum {
+    ld,
+    bfd,
+    gold,
+    lld,
+    mold,
+};
+
+comp: *Compilation,
+inputs: std.ArrayListUnmanaged(Source) = .{},
+link_objects: std.ArrayListUnmanaged([]const u8) = .{},
+output_name: ?[]const u8 = null,
+sysroot: ?[]const u8 = null,
+temp_file_count: u32 = 0,
+only_preprocess: bool = false,
+only_syntax: bool = false,
+only_compile: bool = false,
+only_preprocess_and_compile: bool = false,
+verbose_ast: bool = false,
+verbose_pp: bool = false,
+verbose_ir: bool = false,
+verbose_linker_args: bool = false,
+
+/// Full path to the aro executable
+aro_name: []const u8 = "",
+
+/// Value of --triple= passed via CLI
+raw_target_triple: ?[]const u8 = null,
+
+// linker options
+use_linker: ?[]const u8 = null,
+linker_path: ?[]const u8 = null,
+nodefaultlibs: bool = false,
+nolibc: bool = false,
+nostartfiles: bool = false,
+nostdlib: bool = false,
+pie: ?bool = null,
+rdynamic: bool = false,
+relocatable: bool = false,
+rtlib: ?[]const u8 = null,
+shared: bool = false,
+shared_libgcc: bool = false,
+static: bool = false,
+static_libgcc: bool = false,
+static_pie: bool = false,
+strip: bool = false,
+unwindlib: ?[]const u8 = null,
+
+pub fn deinit(d: *Driver) void {
+    for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| {
+        std.fs.deleteFileAbsolute(obj) catch {};
+        d.comp.gpa.free(obj);
+    }
+    d.inputs.deinit(d.comp.gpa);
+    d.link_objects.deinit(d.comp.gpa);
+    d.* = undefined;
+}
+
+pub const usage =
+    \\Usage {s}: [options] file..
+    \\
+    \\General options:
+    \\  -h, --help      Print this message.
+    \\  -v, --version   Print aro version.
+    \\
+    \\Compile options:
+    \\  -c, --compile           Only run preprocess, compile, and assemble steps
+    \\  -D <macro>=<value>      Define <macro> to <value> (defaults to 1)
+    \\  -E                      Only run the preprocessor
+    \\  -fchar8_t               Enable char8_t (enabled by default in C2X and later)
+    \\  -fno-char8_t            Disable char8_t (disabled by default for pre-C2X)
+    \\  -fcolor-diagnostics     Enable colors in diagnostics
+    \\  -fno-color-diagnostics  Disable colors in diagnostics
+    \\  -fdeclspec              Enable support for __declspec attributes
+    \\  -fno-declspec           Disable support for __declspec attributes
+    \\  -ffp-eval-method=[source|double|extended]
+    \\                          Evaluation method to use for floating-point arithmetic
+    \\  -fgnu-inline-asm        Enable GNU style inline asm (default: enabled)
+    \\  -fno-gnu-inline-asm     Disable GNU style inline asm
+    \\  -fms-extensions         Enable support for Microsoft extensions
+    \\  -fno-ms-extensions      Disable support for Microsoft extensions
+    \\  -fdollars-in-identifiers        
+    \\                          Allow '$' in identifiers
+    \\  -fno-dollars-in-identifiers     
+    \\                          Disallow '$' in identifiers
+    \\  -fmacro-backtrace-limit=<limit>
+    \\                          Set limit on how many macro expansion traces are shown in errors (default 6)
+    \\  -fnative-half-type      Use the native half type for __fp16 instead of promoting to float
+    \\  -fnative-half-arguments-and-returns
+    \\                          Allow half-precision function arguments and return values
+    \\  -fshort-enums           Use the narrowest possible integer type for enums
+    \\  -fno-short-enums        Use "int" as the tag type for enums
+    \\  -fsigned-char           "char" is signed
+    \\  -fno-signed-char        "char" is unsigned
+    \\  -fsyntax-only           Only run the preprocessor, parser, and semantic analysis stages
+    \\  -funsigned-char         "char" is unsigned
+    \\  -fno-unsigned-char      "char" is signed
+    \\  -I <dir>                Add directory to include search path
+    \\  -isystem                Add directory to SYSTEM include search path
+    \\  --emulate=[clang|gcc|msvc]
+    \\                          Select which C compiler to emulate (default clang)
+    \\  -o <file>               Write output to <file>
+    \\  -pedantic               Warn on language extensions
+    \\  --rtlib=<arg>           Compiler runtime library to use (libgcc or compiler-rt)
+    \\  -std=<standard>         Specify language standard
+    \\  -S, --assemble          Only run preprocess and compilation steps
+    \\  --sysroot=<dir>         Use dir as the logical root directory for headers and libraries (not fully implemented)
+    \\  --target=<value>        Generate code for the given target
+    \\  -U <macro>              Undefine <macro>
+    \\  -Werror                 Treat all warnings as errors
+    \\  -Werror=<warning>       Treat warning as error
+    \\  -W<warning>             Enable the specified warning
+    \\  -Wno-<warning>          Disable the specified warning
+    \\
+    \\Link options:
+    \\  -fuse-ld=[bfd|gold|lld|mold]
+    \\                          Use specific linker
+    \\  -nodefaultlibs          Do not use the standard system libraries when linking.
+    \\  -nolibc                 Do not use the C library or system libraries tightly coupled with it when linking.
+    \\  -nostdlib               Do not use the standard system startup files or libraries when linking
+    \\  -nostartfiles           Do not use the standard system startup files when linking.
+    \\  -pie                    Produce a dynamically linked position independent executable on targets that support it.
+    \\  --ld-path=<path>        Use linker specified by <path>
+    \\  -r                      Produce a relocatable object as output.
+    \\  -rdynamic               Pass the flag -export-dynamic to the ELF linker, on targets that support it.
+    \\  -s                      Remove all symbol table and relocation information from the executable.
+    \\  -shared                 Produce a shared object which can then be linked with other objects to form an executable.
+    \\  -shared-libgcc          On systems that provide libgcc as a shared library, force the use of the shared version
+    \\  -static                 On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries.
+    \\  -static-libgcc          On systems that provide libgcc as a shared library, force the use of the static version
+    \\  -static-pie             Produce a static position independent executable on targets that support it.
+    \\  --unwindlib=<arg>       Unwind library to use ("none", "libgcc", or "libunwind") If not specified, will match runtime library
+    \\
+    \\Debug options:
+    \\  --verbose-ast           Dump produced AST to stdout
+    \\  --verbose-pp            Dump preprocessor state
+    \\  --verbose-ir            Dump ir to stdout
+    \\  --verbose-linker-args   Dump linker args to stdout
+    \\
+    \\
+;
+
+/// Process command line arguments, returns true if something was written to std_out.
+pub fn parseArgs(
+    d: *Driver,
+    std_out: anytype,
+    macro_buf: anytype,
+    args: []const []const u8,
+) !bool {
+    var i: usize = 1;
+    var color_setting: enum {
+        on,
+        off,
+        unset,
+    } = .unset;
+    while (i < args.len) : (i += 1) {
+        const arg = args[i];
+        if (mem.startsWith(u8, arg, "-") and arg.len > 1) {
+            if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
+                std_out.print(usage, .{args[0]}) catch |er| {
+                    return d.fatal("unable to print usage: {s}", .{util.errorDescription(er)});
+                };
+                return true;
+            } else if (mem.eql(u8, arg, "-v") or mem.eql(u8, arg, "--version")) {
+                std_out.writeAll(@import("lib.zig").version_str ++ "\n") catch |er| {
+                    return d.fatal("unable to print version: {s}", .{util.errorDescription(er)});
+                };
+                return true;
+            } else if (mem.startsWith(u8, arg, "-D")) {
+                var macro = arg["-D".len..];
+                if (macro.len == 0) {
+                    i += 1;
+                    if (i >= args.len) {
+                        try d.err("expected argument after -I");
+                        continue;
+                    }
+                    macro = args[i];
+                }
+                var value: []const u8 = "1";
+                if (mem.indexOfScalar(u8, macro, '=')) |some| {
+                    value = macro[some + 1 ..];
+                    macro = macro[0..some];
+                }
+                try macro_buf.print("#define {s} {s}\n", .{ macro, value });
+            } else if (mem.startsWith(u8, arg, "-U")) {
+                var macro = arg["-U".len..];
+                if (macro.len == 0) {
+                    i += 1;
+                    if (i >= args.len) {
+                        try d.err("expected argument after -I");
+                        continue;
+                    }
+                    macro = args[i];
+                }
+                try macro_buf.print("#undef {s}\n", .{macro});
+            } else if (mem.eql(u8, arg, "-c") or mem.eql(u8, arg, "--compile")) {
+                d.only_compile = true;
+            } else if (mem.eql(u8, arg, "-E")) {
+                d.only_preprocess = true;
+            } else if (mem.eql(u8, arg, "-fchar8_t")) {
+                d.comp.langopts.has_char8_t_override = true;
+            } else if (mem.eql(u8, arg, "-fno-char8_t")) {
+                d.comp.langopts.has_char8_t_override = false;
+            } else if (mem.eql(u8, arg, "-fcolor-diagnostics")) {
+                color_setting = .on;
+            } else if (mem.eql(u8, arg, "-fno-color-diagnostics")) {
+                color_setting = .off;
+            } else if (mem.eql(u8, arg, "-fdollars-in-identifiers")) {
+                d.comp.langopts.dollars_in_identifiers = true;
+            } else if (mem.eql(u8, arg, "-fno-dollars-in-identifiers")) {
+                d.comp.langopts.dollars_in_identifiers = false;
+            } else if (mem.eql(u8, arg, "-fdigraphs")) {
+                d.comp.langopts.digraphs = true;
+            } else if (mem.eql(u8, arg, "-fgnu-inline-asm")) {
+                d.comp.langopts.gnu_asm = true;
+            } else if (mem.eql(u8, arg, "-fno-gnu-inline-asm")) {
+                d.comp.langopts.gnu_asm = false;
+            } else if (mem.eql(u8, arg, "-fno-digraphs")) {
+                d.comp.langopts.digraphs = false;
+            } else if (option(arg, "-fmacro-backtrace-limit=")) |limit_str| {
+                var limit = std.fmt.parseInt(u32, limit_str, 10) catch {
+                    try d.err("-fmacro-backtrace-limit takes a number argument");
+                    continue;
+                };
+
+                if (limit == 0) limit = std.math.maxInt(u32);
+                d.comp.diag.macro_backtrace_limit = limit;
+            } else if (mem.eql(u8, arg, "-fnative-half-type")) {
+                d.comp.langopts.use_native_half_type = true;
+            } else if (mem.eql(u8, arg, "-fnative-half-arguments-and-returns")) {
+                d.comp.langopts.allow_half_args_and_returns = true;
+            } else if (mem.eql(u8, arg, "-fshort-enums")) {
+                d.comp.langopts.short_enums = true;
+            } else if (mem.eql(u8, arg, "-fno-short-enums")) {
+                d.comp.langopts.short_enums = false;
+            } else if (mem.eql(u8, arg, "-fsigned-char")) {
+                d.comp.langopts.setCharSignedness(.signed);
+            } else if (mem.eql(u8, arg, "-fno-signed-char")) {
+                d.comp.langopts.setCharSignedness(.unsigned);
+            } else if (mem.eql(u8, arg, "-funsigned-char")) {
+                d.comp.langopts.setCharSignedness(.unsigned);
+            } else if (mem.eql(u8, arg, "-fno-unsigned-char")) {
+                d.comp.langopts.setCharSignedness(.signed);
+            } else if (mem.eql(u8, arg, "-fdeclspec")) {
+                d.comp.langopts.declspec_attrs = true;
+            } else if (mem.eql(u8, arg, "-fno-declspec")) {
+                d.comp.langopts.declspec_attrs = false;
+            } else if (mem.eql(u8, arg, "-fms-extensions")) {
+                d.comp.langopts.enableMSExtensions();
+            } else if (mem.eql(u8, arg, "-fno-ms-extensions")) {
+                d.comp.langopts.disableMSExtensions();
+            } else if (mem.startsWith(u8, arg, "-I")) {
+                var path = arg["-I".len..];
+                if (path.len == 0) {
+                    i += 1;
+                    if (i >= args.len) {
+                        try d.err("expected argument after -I");
+                        continue;
+                    }
+                    path = args[i];
+                }
+                try d.comp.include_dirs.append(path);
+            } else if (mem.startsWith(u8, arg, "-fsyntax-only")) {
+                d.only_syntax = true;
+            } else if (mem.startsWith(u8, arg, "-fno-syntax-only")) {
+                d.only_syntax = false;
+            } else if (mem.startsWith(u8, arg, "-isystem")) {
+                var path = arg["-isystem".len..];
+                if (path.len == 0) {
+                    i += 1;
+                    if (i >= args.len) {
+                        try d.err("expected argument after -isystem");
+                        continue;
+                    }
+                    path = args[i];
+                }
+                const duped = try d.comp.gpa.dupe(u8, path);
+                errdefer d.comp.gpa.free(duped);
+                try d.comp.system_include_dirs.append(duped);
+            } else if (option(arg, "--emulate=")) |compiler_str| {
+                const compiler = std.meta.stringToEnum(LangOpts.Compiler, compiler_str) orelse {
+                    try d.comp.diag.add(.{ .tag = .cli_invalid_emulate, .extra = .{ .str = arg } }, &.{});
+                    continue;
+                };
+                d.comp.langopts.setEmulatedCompiler(compiler);
+            } else if (option(arg, "-ffp-eval-method=")) |fp_method_str| {
+                const fp_eval_method = std.meta.stringToEnum(LangOpts.FPEvalMethod, fp_method_str) orelse .indeterminate;
+                if (fp_eval_method == .indeterminate) {
+                    try d.comp.diag.add(.{ .tag = .cli_invalid_fp_eval_method, .extra = .{ .str = fp_method_str } }, &.{});
+                    continue;
+                }
+                d.comp.langopts.setFpEvalMethod(fp_eval_method);
+            } else if (mem.startsWith(u8, arg, "-o")) {
+                var file = arg["-o".len..];
+                if (file.len == 0) {
+                    i += 1;
+                    if (i >= args.len) {
+                        try d.err("expected argument after -o");
+                        continue;
+                    }
+                    file = args[i];
+                }
+                d.output_name = file;
+            } else if (option(arg, "--sysroot=")) |sysroot| {
+                d.sysroot = sysroot;
+            } else if (mem.eql(u8, arg, "-pedantic")) {
+                d.comp.diag.options.pedantic = .warning;
+            } else if (option(arg, "--rtlib=")) |rtlib| {
+                if (mem.eql(u8, rtlib, "compiler-rt") or mem.eql(u8, rtlib, "libgcc") or mem.eql(u8, rtlib, "platform")) {
+                    d.rtlib = rtlib;
+                } else {
+                    try d.comp.diag.add(.{ .tag = .invalid_rtlib, .extra = .{ .str = rtlib } }, &.{});
+                }
+            } else if (option(arg, "-Werror=")) |err_name| {
+                try d.comp.diag.set(err_name, .@"error");
+            } else if (mem.eql(u8, arg, "-Wno-fatal-errors")) {
+                d.comp.diag.fatal_errors = false;
+            } else if (option(arg, "-Wno-")) |err_name| {
+                try d.comp.diag.set(err_name, .off);
+            } else if (mem.eql(u8, arg, "-Wfatal-errors")) {
+                d.comp.diag.fatal_errors = true;
+            } else if (option(arg, "-W")) |err_name| {
+                try d.comp.diag.set(err_name, .warning);
+            } else if (option(arg, "-std=")) |standard| {
+                d.comp.langopts.setStandard(standard) catch
+                    try d.comp.diag.add(.{ .tag = .cli_invalid_standard, .extra = .{ .str = arg } }, &.{});
+            } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--assemble")) {
+                d.only_preprocess_and_compile = true;
+            } else if (option(arg, "--target=")) |triple| {
+                const cross = std.zig.CrossTarget.parse(.{ .arch_os_abi = triple }) catch {
+                    try d.comp.diag.add(.{ .tag = .cli_invalid_target, .extra = .{ .str = arg } }, &.{});
+                    continue;
+                };
+                d.comp.target = cross.toTarget(); // TODO deprecated
+                d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(d.comp.target));
+                d.raw_target_triple = triple;
+            } else if (mem.eql(u8, arg, "--verbose-ast")) {
+                d.verbose_ast = true;
+            } else if (mem.eql(u8, arg, "--verbose-pp")) {
+                d.verbose_pp = true;
+            } else if (mem.eql(u8, arg, "--verbose-ir")) {
+                d.verbose_ir = true;
+            } else if (mem.eql(u8, arg, "--verbose-linker-args")) {
+                d.verbose_linker_args = true;
+            } else if (option(arg, "-fuse-ld=")) |linker_name| {
+                d.use_linker = linker_name;
+            } else if (mem.eql(u8, arg, "-fuse-ld=")) {
+                d.use_linker = null;
+            } else if (option(arg, "--ld-path=")) |linker_path| {
+                d.linker_path = linker_path;
+            } else if (mem.eql(u8, arg, "-r")) {
+                d.relocatable = true;
+            } else if (mem.eql(u8, arg, "-shared")) {
+                d.shared = true;
+            } else if (mem.eql(u8, arg, "-shared-libgcc")) {
+                d.shared_libgcc = true;
+            } else if (mem.eql(u8, arg, "-static")) {
+                d.static = true;
+            } else if (mem.eql(u8, arg, "-static-libgcc")) {
+                d.static_libgcc = true;
+            } else if (mem.eql(u8, arg, "-static-pie")) {
+                d.static_pie = true;
+            } else if (mem.eql(u8, arg, "-pie")) {
+                d.pie = true;
+            } else if (mem.eql(u8, arg, "-no-pie") or mem.eql(u8, arg, "-nopie")) {
+                d.pie = false;
+            } else if (mem.eql(u8, arg, "-rdynamic")) {
+                d.rdynamic = true;
+            } else if (mem.eql(u8, arg, "-s")) {
+                d.strip = true;
+            } else if (mem.eql(u8, arg, "-nodefaultlibs")) {
+                d.nodefaultlibs = true;
+            } else if (mem.eql(u8, arg, "-nolibc")) {
+                d.nolibc = true;
+            } else if (mem.eql(u8, arg, "-nostdlib")) {
+                d.nostdlib = true;
+            } else if (mem.eql(u8, arg, "-nostartfiles")) {
+                d.nostartfiles = true;
+            } else if (option(arg, "--unwindlib=")) |unwindlib| {
+                const valid_unwindlibs: [5][]const u8 = .{ "", "none", "platform", "libunwind", "libgcc" };
+                for (valid_unwindlibs) |name| {
+                    if (mem.eql(u8, name, unwindlib)) {
+                        d.unwindlib = unwindlib;
+                        break;
+                    }
+                } else {
+                    try d.comp.diag.add(.{ .tag = .invalid_unwindlib, .extra = .{ .str = unwindlib } }, &.{});
+                }
+            } else {
+                try d.comp.diag.add(.{ .tag = .cli_unknown_arg, .extra = .{ .str = arg } }, &.{});
+            }
+        } else if (std.mem.endsWith(u8, arg, ".o") or std.mem.endsWith(u8, arg, ".obj")) {
+            try d.link_objects.append(d.comp.gpa, arg);
+        } else {
+            const source = d.addSource(arg) catch |er| {
+                return d.fatal("unable to add source file '{s}': {s}", .{ arg, util.errorDescription(er) });
+            };
+            try d.inputs.append(d.comp.gpa, source);
+        }
+    }
+    d.comp.diag.color = switch (color_setting) {
+        .on => true,
+        .off => false,
+        .unset => util.fileSupportsColor(std.io.getStdErr()) and !std.process.hasEnvVarConstant("NO_COLOR"),
+    };
+    return false;
+}
+
+fn option(arg: []const u8, name: []const u8) ?[]const u8 {
+    if (std.mem.startsWith(u8, arg, name) and arg.len > name.len) {
+        return arg[name.len..];
+    }
+    return null;
+}
+
+fn addSource(d: *Driver, path: []const u8) !Source {
+    if (mem.eql(u8, "-", path)) {
+        const stdin = std.io.getStdIn().reader();
+        const input = try stdin.readAllAlloc(d.comp.gpa, std.math.maxInt(u32));
+        defer d.comp.gpa.free(input);
+        return d.comp.addSourceFromBuffer("<stdin>", input);
+    }
+    return d.comp.addSourceFromPath(path);
+}
+
+pub fn err(d: *Driver, msg: []const u8) !void {
+    try d.comp.diag.add(.{ .tag = .cli_error, .extra = .{ .str = msg } }, &.{});
+}
+
+pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{FatalError} {
+    d.comp.renderErrors();
+    return d.comp.diag.fatalNoSrc(fmt, args);
+}
+
+pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8) !void {
+    var macro_buf = std.ArrayList(u8).init(d.comp.gpa);
+    defer macro_buf.deinit();
+
+    const std_out = std.io.getStdOut().writer();
+    if (try parseArgs(d, std_out, macro_buf.writer(), args)) return;
+
+    const linking = !(d.only_preprocess or d.only_syntax or d.only_compile or d.only_preprocess_and_compile);
+
+    if (d.inputs.items.len == 0) {
+        return d.fatal("no input files", .{});
+    } else if (d.inputs.items.len != 1 and d.output_name != null and !linking) {
+        return d.fatal("cannot specify -o when generating multiple output files", .{});
+    }
+
+    if (!linking) for (d.link_objects.items) |obj| {
+        try d.comp.diag.add(.{ .tag = .cli_unused_link_object, .extra = .{ .str = obj } }, &.{});
+    };
+
+    d.comp.defineSystemIncludes(d.aro_name) catch |er| switch (er) {
+        error.OutOfMemory => return error.OutOfMemory,
+        error.AroIncludeNotFound => return d.fatal("unable to find Aro builtin headers", .{}),
+    };
+
+    const builtin = try d.comp.generateBuiltinMacros();
+    const user_macros = try d.comp.addSourceFromBuffer("<command line>", macro_buf.items);
+
+    const fast_exit = @import("builtin").mode != .Debug;
+
+    if (fast_exit and d.inputs.items.len == 1) {
+        d.processSource(tc, d.inputs.items[0], builtin, user_macros, fast_exit) catch |e| switch (e) {
+            error.FatalError => {
+                d.comp.renderErrors();
+                d.exitWithCleanup(1);
+            },
+            else => |er| return er,
+        };
+        unreachable;
+    }
+
+    for (d.inputs.items) |source| {
+        d.processSource(tc, source, builtin, user_macros, fast_exit) catch |e| switch (e) {
+            error.FatalError => {
+                d.comp.renderErrors();
+            },
+            else => |er| return er,
+        };
+    }
+    if (d.comp.diag.errors != 0) {
+        if (fast_exit) d.exitWithCleanup(1);
+        return;
+    }
+    if (linking) {
+        try d.invokeLinker(tc, fast_exit);
+    }
+    if (fast_exit) std.process.exit(0);
+}
+
+fn processSource(
+    d: *Driver,
+    tc: *Toolchain,
+    source: Source,
+    builtin: Source,
+    user_macros: Source,
+    comptime fast_exit: bool,
+) !void {
+    d.comp.generated_buf.items.len = 0;
+    var pp = Preprocessor.init(d.comp);
+    defer pp.deinit();
+
+    if (d.verbose_pp) pp.verbose = true;
+    if (d.only_preprocess) pp.preserve_whitespace = true;
+    try pp.addBuiltinMacros();
+
+    _ = try pp.preprocess(builtin);
+    _ = try pp.preprocess(user_macros);
+    const eof = try pp.preprocess(source);
+    try pp.tokens.append(pp.comp.gpa, eof);
+
+    if (d.only_preprocess) {
+        d.comp.renderErrors();
+
+        const file = if (d.output_name) |some|
+            std.fs.cwd().createFile(some, .{}) catch |er|
+                return d.fatal("unable to create output file '{s}': {s}", .{ some, util.errorDescription(er) })
+        else
+            std.io.getStdOut();
+        defer if (d.output_name != null) file.close();
+
+        var buf_w = std.io.bufferedWriter(file.writer());
+        pp.prettyPrintTokens(buf_w.writer()) catch |er|
+            return d.fatal("unable to write result: {s}", .{util.errorDescription(er)});
+
+        buf_w.flush() catch |er|
+            return d.fatal("unable to write result: {s}", .{util.errorDescription(er)});
+        if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
+        return;
+    }
+
+    var tree = try Parser.parse(&pp);
+    defer tree.deinit();
+
+    if (d.verbose_ast) {
+        const stdout = std.io.getStdOut();
+        var buf_writer = std.io.bufferedWriter(stdout.writer());
+        const color = d.comp.diag.color and util.fileSupportsColor(stdout);
+        tree.dump(color, buf_writer.writer()) catch {};
+        buf_writer.flush() catch {};
+    }
+
+    const prev_errors = d.comp.diag.errors;
+    d.comp.renderErrors();
+
+    if (d.comp.diag.errors != prev_errors) {
+        if (fast_exit) d.exitWithCleanup(1);
+        return; // do not compile if there were errors
+    }
+
+    if (d.only_syntax) {
+        if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
+        return;
+    }
+
+    if (d.comp.target.ofmt != .elf or d.comp.target.cpu.arch != .x86_64) {
+        return d.fatal(
+            "unsupported target {s}-{s}-{s}, currently only x86-64 elf is supported",
+            .{ @tagName(d.comp.target.cpu.arch), @tagName(d.comp.target.os.tag), @tagName(d.comp.target.abi) },
+        );
+    }
+
+    if (d.verbose_ir) {
+        try @import("CodeGen.zig").generateTree(d.comp, tree);
+    }
+
+    const obj = try Codegen.generateTree(d.comp, tree);
+    defer obj.deinit();
+
+    // If it's used, name_buf will either hold a filename or `/tmp/<12 random bytes with base-64 encoding>.<extension>`
+    // both of which should fit into MAX_NAME_BYTES for all systems
+    var name_buf: [std.fs.MAX_NAME_BYTES]u8 = undefined;
+
+    const out_file_name = if (d.only_compile) blk: {
+        const fmt_template = "{s}{s}";
+        const fmt_args = .{
+            std.fs.path.stem(source.path),
+            d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch),
+        };
+        break :blk d.output_name orelse
+            std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
+    } else blk: {
+        const random_bytes_count = 12;
+        const sub_path_len = comptime std.fs.base64_encoder.calcSize(random_bytes_count);
+
+        var random_bytes: [random_bytes_count]u8 = undefined;
+        std.crypto.random.bytes(&random_bytes);
+        var random_name: [sub_path_len]u8 = undefined;
+        _ = std.fs.base64_encoder.encode(&random_name, &random_bytes);
+
+        const fmt_template = "/tmp/{s}{s}";
+        const fmt_args = .{
+            random_name,
+            d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch),
+        };
+        break :blk std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
+    };
+
+    const out_file = std.fs.cwd().createFile(out_file_name, .{}) catch |er|
+        return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, util.errorDescription(er) });
+    defer out_file.close();
+
+    obj.finish(out_file) catch |er|
+        return d.fatal("could not output to object file '{s}': {s}", .{ out_file_name, util.errorDescription(er) });
+
+    if (d.only_compile) {
+        if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
+        return;
+    }
+    try d.link_objects.ensureUnusedCapacity(d.comp.gpa, 1);
+    d.link_objects.appendAssumeCapacity(try d.comp.gpa.dupe(u8, out_file_name));
+    d.temp_file_count += 1;
+    if (fast_exit) {
+        try d.invokeLinker(tc, fast_exit);
+    }
+}
+
+fn dumpLinkerArgs(items: []const []const u8) !void {
+    const stdout = std.io.getStdOut().writer();
+    for (items, 0..) |item, i| {
+        if (i > 0) try stdout.writeByte(' ');
+        try stdout.print("\"{}\"", .{std.zig.fmtEscapes(item)});
+    }
+    try stdout.writeByte('\n');
+}
+
+pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) !void {
+    try tc.discover();
+
+    var argv = std.ArrayList([]const u8).init(d.comp.gpa);
+    defer argv.deinit();
+
+    var linker_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+    const linker_path = try tc.getLinkerPath(&linker_path_buf);
+    try argv.append(linker_path);
+
+    try tc.buildLinkerArgs(&argv);
+
+    if (d.verbose_linker_args) {
+        dumpLinkerArgs(argv.items) catch |er| {
+            return d.fatal("unable to dump linker args: {s}", .{util.errorDescription(er)});
+        };
+    }
+    var child = std.ChildProcess.init(argv.items, d.comp.gpa);
+    // TODO handle better
+    child.stdin_behavior = .Inherit;
+    child.stdout_behavior = .Inherit;
+    child.stderr_behavior = .Inherit;
+
+    const term = child.spawnAndWait() catch |er| {
+        return d.fatal("unable to spawn linker: {s}", .{util.errorDescription(er)});
+    };
+    switch (term) {
+        .Exited => |code| if (code != 0) d.exitWithCleanup(code),
+        else => std.process.abort(),
+    }
+    if (fast_exit) d.exitWithCleanup(0);
+}
+
+fn exitWithCleanup(d: *Driver, code: u8) noreturn {
+    for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| {
+        std.fs.deleteFileAbsolute(obj) catch {};
+    }
+    std.process.exit(code);
+}
deps/aro/features.zig
@@ -0,0 +1,76 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const target_util = @import("target.zig");
+
+/// Used to implement the __has_feature macro.
+pub fn hasFeature(comp: *Compilation, ext: []const u8) bool {
+    const list = .{
+        .assume_nonnull = true,
+        .attribute_analyzer_noreturn = true,
+        .attribute_availability = true,
+        .attribute_availability_with_message = true,
+        .attribute_availability_app_extension = true,
+        .attribute_availability_with_version_underscores = true,
+        .attribute_availability_tvos = true,
+        .attribute_availability_watchos = true,
+        .attribute_availability_with_strict = true,
+        .attribute_availability_with_replacement = true,
+        .attribute_availability_in_templates = true,
+        .attribute_availability_swift = true,
+        .attribute_cf_returns_not_retained = true,
+        .attribute_cf_returns_retained = true,
+        .attribute_cf_returns_on_parameters = true,
+        .attribute_deprecated_with_message = true,
+        .attribute_deprecated_with_replacement = true,
+        .attribute_ext_vector_type = true,
+        .attribute_ns_returns_not_retained = true,
+        .attribute_ns_returns_retained = true,
+        .attribute_ns_consumes_self = true,
+        .attribute_ns_consumed = true,
+        .attribute_cf_consumed = true,
+        .attribute_overloadable = true,
+        .attribute_unavailable_with_message = true,
+        .attribute_unused_on_fields = true,
+        .attribute_diagnose_if_objc = true,
+        .blocks = false, // TODO
+        .c_thread_safety_attributes = true,
+        .enumerator_attributes = true,
+        .nullability = true,
+        .nullability_on_arrays = true,
+        .nullability_nullable_result = true,
+        .c_alignas = comp.langopts.standard.atLeast(.c11),
+        .c_alignof = comp.langopts.standard.atLeast(.c11),
+        .c_atomic = comp.langopts.standard.atLeast(.c11),
+        .c_generic_selections = comp.langopts.standard.atLeast(.c11),
+        .c_static_assert = comp.langopts.standard.atLeast(.c11),
+        .c_thread_local = comp.langopts.standard.atLeast(.c11) and target_util.isTlsSupported(comp.target),
+    };
+    inline for (std.meta.fields(@TypeOf(list))) |f| {
+        if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name);
+    }
+    return false;
+}
+
+/// Used to implement the __has_extension macro.
+pub fn hasExtension(comp: *Compilation, ext: []const u8) bool {
+    const list = .{
+        // C11 features
+        .c_alignas = true,
+        .c_alignof = true,
+        .c_atomic = false, // TODO
+        .c_generic_selections = true,
+        .c_static_assert = true,
+        .c_thread_local = target_util.isTlsSupported(comp.target),
+        // misc
+        .overloadable_unmarked = false, // TODO
+        .statement_attributes_with_gnu_syntax = false, // TODO
+        .gnu_asm = true,
+        .gnu_asm_goto_with_outputs = true,
+        .matrix_types = false, // TODO
+        .matrix_types_scalar_division = false, // TODO
+    };
+    inline for (std.meta.fields(@TypeOf(list))) |f| {
+        if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name);
+    }
+    return false;
+}
deps/aro/InitList.zig
@@ -0,0 +1,153 @@
+//! Sparsely populated list of used indexes.
+//! Used for detecting duplicate initializers.
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const testing = std.testing;
+const Tree = @import("Tree.zig");
+const Token = Tree.Token;
+const TokenIndex = Tree.TokenIndex;
+const NodeIndex = Tree.NodeIndex;
+const Type = @import("Type.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const NodeList = std.ArrayList(NodeIndex);
+const Parser = @import("Parser.zig");
+
+const InitList = @This();
+
+const Item = struct {
+    list: InitList = .{},
+    index: u64,
+
+    fn order(_: void, a: Item, b: Item) std.math.Order {
+        return std.math.order(a.index, b.index);
+    }
+};
+
+list: std.ArrayListUnmanaged(Item) = .{},
+node: NodeIndex = .none,
+tok: TokenIndex = 0,
+
+/// Deinitialize freeing all memory.
+pub fn deinit(il: *InitList, gpa: Allocator) void {
+    for (il.list.items) |*item| item.list.deinit(gpa);
+    il.list.deinit(gpa);
+    il.* = undefined;
+}
+
+/// Insert initializer at index, returning previous entry if one exists.
+pub fn put(il: *InitList, gpa: Allocator, index: usize, node: NodeIndex, tok: TokenIndex) !?TokenIndex {
+    const items = il.list.items;
+    var left: usize = 0;
+    var right: usize = items.len;
+
+    // Append new value to empty list
+    if (left == right) {
+        const item = try il.list.addOne(gpa);
+        item.* = .{
+            .list = .{ .node = node, .tok = tok },
+            .index = index,
+        };
+        return null;
+    }
+
+    while (left < right) {
+        // Avoid overflowing in the midpoint calculation
+        const mid = left + (right - left) / 2;
+        // Compare the key with the midpoint element
+        switch (std.math.order(index, items[mid].index)) {
+            .eq => {
+                // Replace previous entry.
+                const prev = items[mid].list.tok;
+                items[mid].list.deinit(gpa);
+                items[mid] = .{
+                    .list = .{ .node = node, .tok = tok },
+                    .index = index,
+                };
+                return prev;
+            },
+            .gt => left = mid + 1,
+            .lt => right = mid,
+        }
+    }
+
+    // Insert a new value into a sorted position.
+    try il.list.insert(gpa, left, .{
+        .list = .{ .node = node, .tok = tok },
+        .index = index,
+    });
+    return null;
+}
+
+/// Find item at index, create new if one does not exist.
+pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
+    const items = il.list.items;
+    var left: usize = 0;
+    var right: usize = items.len;
+
+    // Append new value to empty list
+    if (left == right) {
+        const item = try il.list.addOne(gpa);
+        item.* = .{
+            .list = .{ .node = .none, .tok = 0 },
+            .index = index,
+        };
+        return &item.list;
+    }
+
+    while (left < right) {
+        // Avoid overflowing in the midpoint calculation
+        const mid = left + (right - left) / 2;
+        // Compare the key with the midpoint element
+        switch (std.math.order(index, items[mid].index)) {
+            .eq => return &items[mid].list,
+            .gt => left = mid + 1,
+            .lt => right = mid,
+        }
+    }
+
+    // Insert a new value into a sorted position.
+    try il.list.insert(gpa, left, .{
+        .list = .{ .node = .none, .tok = 0 },
+        .index = index,
+    });
+    return &il.list.items[left].list;
+}
+
+test "basic usage" {
+    const gpa = testing.allocator;
+    var il: InitList = .{};
+    defer il.deinit(gpa);
+
+    {
+        var i: usize = 0;
+        while (i < 5) : (i += 1) {
+            const prev = try il.put(gpa, i, .none, 0);
+            try testing.expect(prev == null);
+        }
+    }
+
+    {
+        const failing = testing.failing_allocator;
+        var i: usize = 0;
+        while (i < 5) : (i += 1) {
+            _ = try il.find(failing, i);
+        }
+    }
+
+    {
+        var item = try il.find(gpa, 0);
+        var i: usize = 1;
+        while (i < 5) : (i += 1) {
+            item = try item.find(gpa, i);
+        }
+    }
+
+    {
+        const failing = testing.failing_allocator;
+        var item = try il.find(failing, 0);
+        var i: usize = 1;
+        while (i < 5) : (i += 1) {
+            item = try item.find(failing, i);
+        }
+    }
+}
deps/aro/Interner.zig
@@ -0,0 +1,180 @@
+const Interner = @This();
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const assert = std.debug.assert;
+const Value = @import("Value.zig");
+
+map: std.ArrayHashMapUnmanaged(Key, void, KeyContext, false) = .{},
+
+const KeyContext = struct {
+    pub fn eql(_: @This(), a: Key, b: Key, _: usize) bool {
+        return b.eql(a);
+    }
+
+    pub fn hash(_: @This(), a: Key) u32 {
+        return a.hash();
+    }
+};
+
+pub const Key = union(enum) {
+    int: u16,
+    float: u16,
+    ptr,
+    noreturn,
+    void,
+    func,
+    array: struct {
+        len: u64,
+        child: Ref,
+    },
+    vector: struct {
+        len: u32,
+        child: Ref,
+    },
+    value: Value,
+    record: struct {
+        /// Pointer to user data, value used for hash and equality check.
+        user_ptr: *anyopaque,
+        /// TODO make smaller if Value is made smaller
+        elements: []const Ref,
+    },
+
+    pub fn hash(key: Key) u32 {
+        var hasher = std.hash.Wyhash.init(0);
+        switch (key) {
+            .value => |val| {
+                std.hash.autoHash(&hasher, val.tag);
+                switch (val.tag) {
+                    .unavailable => unreachable,
+                    .nullptr_t => std.hash.autoHash(&hasher, @as(u64, 0)),
+                    .int => std.hash.autoHash(&hasher, val.data.int),
+                    .float => std.hash.autoHash(&hasher, @as(u64, @bitCast(val.data.float))),
+                    .bytes => std.hash.autoHashStrat(&hasher, val.data.bytes, .Shallow),
+                }
+            },
+            .record => |info| {
+                std.hash.autoHash(&hasher, @intFromPtr(info.user_ptr));
+            },
+            inline else => |info| {
+                std.hash.autoHash(&hasher, info);
+            },
+        }
+        return @truncate(hasher.final());
+    }
+
+    pub fn eql(a: Key, b: Key) bool {
+        const KeyTag = std.meta.Tag(Key);
+        const a_tag: KeyTag = a;
+        const b_tag: KeyTag = b;
+        if (a_tag != b_tag) return false;
+        switch (a) {
+            .value => |a_info| {
+                const b_info = b.value;
+                if (a_info.tag != b_info.tag) return false;
+                switch (a_info.tag) {
+                    .unavailable => unreachable,
+                    .nullptr_t => return true,
+                    .int => return a_info.data.int == b_info.data.int,
+                    .float => return a_info.data.float == b_info.data.float,
+                    .bytes => return a_info.data.bytes.start == b_info.data.bytes.start and a_info.data.bytes.end == b_info.data.bytes.end,
+                }
+            },
+            .record => |a_info| {
+                return a_info.user_ptr == b.record.user_ptr;
+            },
+            inline else => |a_info, tag| {
+                const b_info = @field(b, @tagName(tag));
+                return std.meta.eql(a_info, b_info);
+            },
+        }
+    }
+
+    fn toRef(key: Key) ?Ref {
+        switch (key) {
+            .int => |bits| switch (bits) {
+                1 => return .i1,
+                8 => return .i8,
+                16 => return .i16,
+                32 => return .i32,
+                64 => return .i64,
+                128 => return .i128,
+                else => {},
+            },
+            .float => |bits| switch (bits) {
+                16 => return .f16,
+                32 => return .f32,
+                64 => return .f64,
+                80 => return .f80,
+                128 => return .f128,
+                else => unreachable,
+            },
+            .ptr => return .ptr,
+            .func => return .func,
+            .noreturn => return .noreturn,
+            .void => return .void,
+            else => {},
+        }
+        return null;
+    }
+};
+
+pub const Ref = enum(u32) {
+    const max = std.math.maxInt(u32);
+
+    ptr = max - 0,
+    noreturn = max - 1,
+    void = max - 2,
+    i1 = max - 3,
+    i8 = max - 4,
+    i16 = max - 5,
+    i32 = max - 6,
+    i64 = max - 7,
+    i128 = max - 8,
+    f16 = max - 9,
+    f32 = max - 10,
+    f64 = max - 11,
+    f80 = max - 12,
+    f128 = max - 13,
+    func = max - 14,
+    _,
+};
+
+pub fn deinit(ip: *Interner, gpa: Allocator) void {
+    ip.map.deinit(gpa);
+}
+
+pub fn put(ip: *Interner, gpa: Allocator, key: Key) !Ref {
+    if (key.toRef()) |some| return some;
+    const gop = try ip.map.getOrPut(gpa, key);
+    return @enumFromInt(gop.index);
+}
+
+pub fn has(ip: *Interner, key: Key) ?Ref {
+    if (key.toRef()) |some| return some;
+    if (ip.map.getIndex(key)) |index| {
+        return @enumFromInt(index);
+    }
+    return null;
+}
+
+pub fn get(ip: Interner, ref: Ref) Key {
+    switch (ref) {
+        .ptr => return .ptr,
+        .func => return .func,
+        .noreturn => return .noreturn,
+        .void => return .void,
+        .i1 => return .{ .int = 1 },
+        .i8 => return .{ .int = 8 },
+        .i16 => return .{ .int = 16 },
+        .i32 => return .{ .int = 32 },
+        .i64 => return .{ .int = 64 },
+        .i128 => return .{ .int = 128 },
+        .f16 => return .{ .float = 16 },
+        .f32 => return .{ .float = 32 },
+        .f64 => return .{ .float = 64 },
+        .f80 => return .{ .float = 80 },
+        .f128 => return .{ .float = 128 },
+        else => {},
+    }
+    return ip.map.keys()[@intFromEnum(ref)];
+}
deps/aro/Ir.zig
@@ -0,0 +1,601 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const Allocator = std.mem.Allocator;
+const Compilation = @import("Compilation.zig");
+const Interner = @import("Interner.zig");
+const StringId = @import("StringInterner.zig").StringId;
+const Value = @import("Value.zig");
+
+const Ir = @This();
+
+pool: Interner,
+strings: []const u8,
+// decls: std.StringArrayHashMapUnmanaged(Decl),
+
+// pub const Decl = struct {
+instructions: std.MultiArrayList(Inst),
+body: std.ArrayListUnmanaged(Ref),
+arena: std.heap.ArenaAllocator.State,
+// };
+
+pub const Builder = struct {
+    gpa: Allocator,
+    arena: std.heap.ArenaAllocator,
+    instructions: std.MultiArrayList(Ir.Inst) = .{},
+    body: std.ArrayListUnmanaged(Ref) = .{},
+    alloc_count: u32 = 0,
+    arg_count: u32 = 0,
+    pool: Interner = .{},
+    current_label: Ref = undefined,
+
+    pub fn deinit(b: *Builder) void {
+        b.arena.deinit();
+        b.instructions.deinit(b.gpa);
+        b.body.deinit(b.gpa);
+        b.pool.deinit(b.gpa);
+        b.* = undefined;
+    }
+
+    pub fn startFn(b: *Builder) Allocator.Error!void {
+        b.alloc_count = 0;
+        b.arg_count = 0;
+        b.instructions.len = 0;
+        b.body.items.len = 0;
+        const entry = try b.makeLabel("entry");
+        try b.body.append(b.gpa, entry);
+        b.current_label = entry;
+    }
+
+    pub fn startBlock(b: *Builder, label: Ref) !void {
+        try b.body.append(b.gpa, label);
+        b.current_label = label;
+    }
+
+    pub fn addArg(b: *Builder, ty: Interner.Ref) Allocator.Error!Ref {
+        const ref: Ref = @enumFromInt(b.instructions.len);
+        try b.instructions.append(b.gpa, .{ .tag = .arg, .data = .{ .none = {} }, .ty = ty });
+        try b.body.insert(b.gpa, b.arg_count, ref);
+        b.arg_count += 1;
+        return ref;
+    }
+
+    pub fn addAlloc(b: *Builder, size: u32, @"align": u32) Allocator.Error!Ref {
+        const ref: Ref = @enumFromInt(b.instructions.len);
+        try b.instructions.append(b.gpa, .{
+            .tag = .alloc,
+            .data = .{ .alloc = .{ .size = size, .@"align" = @"align" } },
+            .ty = .ptr,
+        });
+        try b.body.insert(b.gpa, b.alloc_count + b.arg_count + 1, ref);
+        b.alloc_count += 1;
+        return ref;
+    }
+
+    pub fn addInst(b: *Builder, tag: Ir.Inst.Tag, data: Ir.Inst.Data, ty: Interner.Ref) Allocator.Error!Ref {
+        const ref: Ref = @enumFromInt(b.instructions.len);
+        try b.instructions.append(b.gpa, .{ .tag = tag, .data = data, .ty = ty });
+        try b.body.append(b.gpa, ref);
+        return ref;
+    }
+
+    pub fn makeLabel(b: *Builder, name: [*:0]const u8) Allocator.Error!Ref {
+        const ref: Ref = @enumFromInt(b.instructions.len);
+        try b.instructions.append(b.gpa, .{ .tag = .label, .data = .{ .label = name }, .ty = .void });
+        return ref;
+    }
+
+    pub fn addJump(b: *Builder, label: Ref) Allocator.Error!void {
+        _ = try b.addInst(.jmp, .{ .un = label }, .noreturn);
+    }
+
+    pub fn addBranch(b: *Builder, cond: Ref, true_label: Ref, false_label: Ref) Allocator.Error!void {
+        const branch = try b.arena.allocator().create(Ir.Inst.Branch);
+        branch.* = .{
+            .cond = cond,
+            .then = true_label,
+            .@"else" = false_label,
+        };
+        _ = try b.addInst(.branch, .{ .branch = branch }, .noreturn);
+    }
+
+    pub fn addSwitch(b: *Builder, target: Ref, values: []Interner.Ref, labels: []Ref, default: Ref) Allocator.Error!void {
+        assert(values.len == labels.len);
+        const a = b.arena.allocator();
+        const @"switch" = try a.create(Ir.Inst.Switch);
+        @"switch".* = .{
+            .target = target,
+            .cases_len = @intCast(values.len),
+            .case_vals = (try a.dupe(Interner.Ref, values)).ptr,
+            .case_labels = (try a.dupe(Ref, labels)).ptr,
+            .default = default,
+        };
+        _ = try b.addInst(.@"switch", .{ .@"switch" = @"switch" }, .noreturn);
+    }
+
+    pub fn addStore(b: *Builder, ptr: Ref, val: Ref) Allocator.Error!void {
+        _ = try b.addInst(.store, .{ .bin = .{ .lhs = ptr, .rhs = val } }, .void);
+    }
+
+    pub fn addConstant(b: *Builder, val: Value, ty: Interner.Ref) Allocator.Error!Ref {
+        const ref: Ref = @enumFromInt(b.instructions.len);
+        const key: Interner.Key = .{
+            .value = val,
+        };
+        const val_ref = try b.pool.put(b.gpa, key);
+        try b.instructions.append(b.gpa, .{ .tag = .constant, .data = .{
+            .constant = val_ref,
+        }, .ty = ty });
+        return ref;
+    }
+
+    pub fn addPhi(b: *Builder, inputs: []const Inst.Phi.Input, ty: Interner.Ref) Allocator.Error!Ref {
+        const a = b.arena.allocator();
+        const input_refs = try a.alloc(Ref, inputs.len * 2 + 1);
+        input_refs[0] = @enumFromInt(inputs.len);
+        std.mem.copy(Ref, input_refs[1..], std.mem.bytesAsSlice(Ref, std.mem.sliceAsBytes(inputs)));
+
+        return b.addInst(.phi, .{ .phi = .{ .ptr = input_refs.ptr } }, ty);
+    }
+
+    pub fn addSelect(b: *Builder, cond: Ref, then: Ref, @"else": Ref, ty: Interner.Ref) Allocator.Error!Ref {
+        const branch = try b.arena.allocator().create(Ir.Inst.Branch);
+        branch.* = .{
+            .cond = cond,
+            .then = then,
+            .@"else" = @"else",
+        };
+        return b.addInst(.select, .{ .branch = branch }, ty);
+    }
+};
+
+pub const Ref = enum(u32) { none = std.math.maxInt(u32), _ };
+
+pub const Inst = struct {
+    tag: Tag,
+    data: Data,
+    ty: Interner.Ref,
+
+    pub const Tag = enum {
+        // data.constant
+        // not included in blocks
+        constant,
+
+        // data.arg
+        // not included in blocks
+        arg,
+        symbol,
+
+        // data.label
+        label,
+
+        // data.block
+        label_addr,
+        jmp,
+
+        // data.switch
+        @"switch",
+
+        // data.branch
+        branch,
+        select,
+
+        // data.un
+        jmp_val,
+
+        // data.call
+        call,
+
+        // data.alloc
+        alloc,
+
+        // data.phi
+        phi,
+
+        // data.bin
+        store,
+        bit_or,
+        bit_xor,
+        bit_and,
+        bit_shl,
+        bit_shr,
+        cmp_eq,
+        cmp_ne,
+        cmp_lt,
+        cmp_lte,
+        cmp_gt,
+        cmp_gte,
+        add,
+        sub,
+        mul,
+        div,
+        mod,
+
+        // data.un
+        ret,
+        load,
+        bit_not,
+        negate,
+        trunc,
+        zext,
+        sext,
+    };
+
+    pub const Data = union {
+        constant: Interner.Ref,
+        none: void,
+        bin: struct {
+            lhs: Ref,
+            rhs: Ref,
+        },
+        un: Ref,
+        arg: u32,
+        alloc: struct {
+            size: u32,
+            @"align": u32,
+        },
+        @"switch": *Switch,
+        call: *Call,
+        label: [*:0]const u8,
+        branch: *Branch,
+        phi: Phi,
+    };
+
+    pub const Branch = struct {
+        cond: Ref,
+        then: Ref,
+        @"else": Ref,
+    };
+
+    pub const Switch = struct {
+        target: Ref,
+        cases_len: u32,
+        default: Ref,
+        case_vals: [*]Interner.Ref,
+        case_labels: [*]Ref,
+    };
+
+    pub const Call = struct {
+        func: Ref,
+        args_len: u32,
+        args_ptr: [*]Ref,
+
+        pub fn args(c: Call) []Ref {
+            return c.args_ptr[0..c.args_len];
+        }
+    };
+
+    pub const Phi = struct {
+        ptr: [*]Ir.Ref,
+
+        pub const Input = struct {
+            label: Ir.Ref,
+            value: Ir.Ref,
+        };
+
+        pub fn inputs(p: Phi) []Input {
+            const len = @intFromEnum(p.ptr[0]) * 2;
+            const slice = (p.ptr + 1)[0..len];
+            return std.mem.bytesAsSlice(Input, std.mem.sliceAsBytes(slice));
+        }
+    };
+};
+
+pub fn deinit(ir: *Ir, gpa: std.mem.Allocator) void {
+    ir.arena.promote(gpa).deinit();
+    ir.instructions.deinit(gpa);
+    ir.* = undefined;
+}
+
+const util = @import("util.zig");
+const TYPE = util.Color.purple;
+const INST = util.Color.cyan;
+const REF = util.Color.blue;
+const LITERAL = util.Color.green;
+const ATTRIBUTE = util.Color.yellow;
+
+const RefMap = std.AutoArrayHashMap(Ref, void);
+
+pub fn dump(ir: Ir, gpa: Allocator, name: []const u8, color: bool, w: anytype) !void {
+    const tags = ir.instructions.items(.tag);
+    const data = ir.instructions.items(.data);
+
+    var ref_map = RefMap.init(gpa);
+    defer ref_map.deinit();
+
+    var label_map = RefMap.init(gpa);
+    defer label_map.deinit();
+
+    const ret_inst = ir.body.items[ir.body.items.len - 1];
+    const ret_operand = data[@intFromEnum(ret_inst)].un;
+    const ret_ty = ir.instructions.items(.ty)[@intFromEnum(ret_operand)];
+    try ir.writeType(ret_ty, color, w);
+    if (color) util.setColor(REF, w);
+    try w.print(" @{s}", .{name});
+    if (color) util.setColor(.reset, w);
+    try w.writeAll("(");
+
+    var arg_count: u32 = 0;
+    while (true) : (arg_count += 1) {
+        const ref = ir.body.items[arg_count];
+        if (tags[@intFromEnum(ref)] != .arg) break;
+        if (arg_count != 0) try w.writeAll(", ");
+        try ref_map.put(ref, {});
+        try ir.writeRef(&ref_map, ref, color, w);
+        if (color) util.setColor(.reset, w);
+    }
+    try w.writeAll(") {\n");
+    for (ir.body.items[arg_count..]) |ref| {
+        switch (tags[@intFromEnum(ref)]) {
+            .label => try label_map.put(ref, {}),
+            else => {},
+        }
+    }
+
+    for (ir.body.items[arg_count..]) |ref| {
+        const i = @intFromEnum(ref);
+        const tag = tags[i];
+        switch (tag) {
+            .arg, .constant, .symbol => unreachable,
+            .label => {
+                const label_index = label_map.getIndex(ref).?;
+                if (color) util.setColor(REF, w);
+                try w.print("{s}.{d}:\n", .{ data[i].label, label_index });
+            },
+            // .label_val => {
+            //     const un = data[i].un;
+            //     try w.print("    %{d} = label.{d}\n", .{ i, @intFromEnum(un) });
+            // },
+            .jmp => {
+                const un = data[i].un;
+                if (color) util.setColor(INST, w);
+                try w.writeAll("    jmp ");
+                try ir.writeLabel(&label_map, un, color, w);
+                try w.writeByte('\n');
+            },
+            .branch => {
+                const br = data[i].branch;
+                if (color) util.setColor(INST, w);
+                try w.writeAll("    branch ");
+                try ir.writeRef(&ref_map, br.cond, color, w);
+                if (color) util.setColor(.reset, w);
+                try w.writeAll(", ");
+                try ir.writeLabel(&label_map, br.then, color, w);
+                if (color) util.setColor(.reset, w);
+                try w.writeAll(", ");
+                try ir.writeLabel(&label_map, br.@"else", color, w);
+                try w.writeByte('\n');
+            },
+            .select => {
+                const br = data[i].branch;
+                try ir.writeNewRef(&ref_map, ref, color, w);
+                try w.writeAll("select ");
+                try ir.writeRef(&ref_map, br.cond, color, w);
+                if (color) util.setColor(.reset, w);
+                try w.writeAll(", ");
+                try ir.writeRef(&ref_map, br.then, color, w);
+                if (color) util.setColor(.reset, w);
+                try w.writeAll(", ");
+                try ir.writeRef(&ref_map, br.@"else", color, w);
+                try w.writeByte('\n');
+            },
+            // .jmp_val => {
+            //     const bin = data[i].bin;
+            //     try w.print("    %{s} %{d} label.{d}\n", .{ @tagName(tag), @intFromEnum(bin.lhs), @intFromEnum(bin.rhs) });
+            // },
+            .@"switch" => {
+                const @"switch" = data[i].@"switch";
+                if (color) util.setColor(INST, w);
+                try w.writeAll("    switch ");
+                try ir.writeRef(&ref_map, @"switch".target, color, w);
+                if (color) util.setColor(.reset, w);
+                try w.writeAll(" {");
+                for (@"switch".case_vals[0..@"switch".cases_len], @"switch".case_labels) |val_ref, label_ref| {
+                    try w.writeAll("\n        ");
+                    try ir.writeValue(val_ref, color, w);
+                    if (color) util.setColor(.reset, w);
+                    try w.writeAll(" => ");
+                    try ir.writeLabel(&label_map, label_ref, color, w);
+                    if (color) util.setColor(.reset, w);
+                }
+                if (color) util.setColor(LITERAL, w);
+                try w.writeAll("\n        default ");
+                if (color) util.setColor(.reset, w);
+                try w.writeAll("=> ");
+                try ir.writeLabel(&label_map, @"switch".default, color, w);
+                if (color) util.setColor(.reset, w);
+                try w.writeAll("\n    }\n");
+            },
+            .call => {
+                const call = data[i].call;
+                try ir.writeNewRef(&ref_map, ref, color, w);
+                try w.writeAll("call ");
+                try ir.writeRef(&ref_map, call.func, color, w);
+                if (color) util.setColor(.reset, w);
+                try w.writeAll("(");
+                for (call.args(), 0..) |arg, arg_i| {
+                    if (arg_i != 0) try w.writeAll(", ");
+                    try ir.writeRef(&ref_map, arg, color, w);
+                    if (color) util.setColor(.reset, w);
+                }
+                try w.writeAll(")\n");
+            },
+            .alloc => {
+                const alloc = data[i].alloc;
+                try ir.writeNewRef(&ref_map, ref, color, w);
+                try w.writeAll("alloc ");
+                if (color) util.setColor(ATTRIBUTE, w);
+                try w.writeAll("size ");
+                if (color) util.setColor(LITERAL, w);
+                try w.print("{d}", .{alloc.size});
+                if (color) util.setColor(ATTRIBUTE, w);
+                try w.writeAll(" align ");
+                if (color) util.setColor(LITERAL, w);
+                try w.print("{d}", .{alloc.@"align"});
+                try w.writeByte('\n');
+            },
+            .phi => {
+                try ir.writeNewRef(&ref_map, ref, color, w);
+                try w.writeAll("phi");
+                if (color) util.setColor(.reset, w);
+                try w.writeAll(" {");
+                for (data[i].phi.inputs()) |input| {
+                    try w.writeAll("\n        ");
+                    try ir.writeLabel(&label_map, input.label, color, w);
+                    if (color) util.setColor(.reset, w);
+                    try w.writeAll(" => ");
+                    try ir.writeRef(&ref_map, input.value, color, w);
+                    if (color) util.setColor(.reset, w);
+                }
+                if (color) util.setColor(.reset, w);
+                try w.writeAll("\n    }\n");
+            },
+            .store => {
+                const bin = data[i].bin;
+                if (color) util.setColor(INST, w);
+                try w.writeAll("    store ");
+                try ir.writeRef(&ref_map, bin.lhs, color, w);
+                if (color) util.setColor(.reset, w);
+                try w.writeAll(", ");
+                try ir.writeRef(&ref_map, bin.rhs, color, w);
+                try w.writeByte('\n');
+            },
+            .ret => {
+                if (color) util.setColor(INST, w);
+                try w.writeAll("    ret ");
+                if (data[i].un != .none) try ir.writeRef(&ref_map, data[i].un, color, w);
+                try w.writeByte('\n');
+            },
+            .load => {
+                try ir.writeNewRef(&ref_map, ref, color, w);
+                try w.writeAll("load ");
+                try ir.writeRef(&ref_map, data[i].un, color, w);
+                try w.writeByte('\n');
+            },
+            .bit_or,
+            .bit_xor,
+            .bit_and,
+            .bit_shl,
+            .bit_shr,
+            .cmp_eq,
+            .cmp_ne,
+            .cmp_lt,
+            .cmp_lte,
+            .cmp_gt,
+            .cmp_gte,
+            .add,
+            .sub,
+            .mul,
+            .div,
+            .mod,
+            => {
+                const bin = data[i].bin;
+                try ir.writeNewRef(&ref_map, ref, color, w);
+                try w.print("{s} ", .{@tagName(tag)});
+                try ir.writeRef(&ref_map, bin.lhs, color, w);
+                if (color) util.setColor(.reset, w);
+                try w.writeAll(", ");
+                try ir.writeRef(&ref_map, bin.rhs, color, w);
+                try w.writeByte('\n');
+            },
+            .bit_not,
+            .negate,
+            .trunc,
+            .zext,
+            .sext,
+            => {
+                const un = data[i].un;
+                try ir.writeNewRef(&ref_map, ref, color, w);
+                try w.print("{s} ", .{@tagName(tag)});
+                try ir.writeRef(&ref_map, un, color, w);
+                try w.writeByte('\n');
+            },
+            .label_addr, .jmp_val => {},
+        }
+    }
+    if (color) util.setColor(.reset, w);
+    try w.writeAll("}\n\n");
+}
+
+fn writeType(ir: Ir, ty_ref: Interner.Ref, color: bool, w: anytype) !void {
+    const ty = ir.pool.get(ty_ref);
+    if (color) util.setColor(TYPE, w);
+    switch (ty) {
+        .value => unreachable,
+        .ptr, .noreturn, .void, .func => try w.writeAll(@tagName(ty)),
+        .int => |bits| try w.print("i{d}", .{bits}),
+        .float => |bits| try w.print("f{d}", .{bits}),
+        .array => |info| {
+            try w.print("[{d} * ", .{info.len});
+            try ir.writeType(info.child, false, w);
+            try w.writeByte(']');
+        },
+        .vector => |info| {
+            try w.print("<{d} * ", .{info.len});
+            try ir.writeType(info.child, false, w);
+            try w.writeByte('>');
+        },
+        .record => |info| {
+            // TODO collect into buffer and only print once
+            try w.writeAll("{ ");
+            for (info.elements, 0..) |elem, i| {
+                if (i != 0) try w.writeAll(", ");
+                try ir.writeType(elem, color, w);
+            }
+            try w.writeAll(" }");
+        },
+    }
+}
+
+fn writeValue(ir: Ir, val_ref: Interner.Ref, color: bool, w: anytype) !void {
+    const v = ir.pool.get(val_ref).value;
+    if (color) util.setColor(LITERAL, w);
+    switch (v.tag) {
+        .unavailable => try w.writeAll(" unavailable"),
+        .int => try w.print("{d}", .{v.data.int}),
+        .bytes => try w.print("\"{s}\"", .{v.data.bytes.slice(ir.strings)}),
+        // std.fmt does @as instead of @floatCast
+        .float => try w.print("{d}", .{@as(f64, @floatCast(v.data.float))}),
+        else => try w.print("({s})", .{@tagName(v.tag)}),
+    }
+}
+
+fn writeRef(ir: Ir, ref_map: *RefMap, ref: Ref, color: bool, w: anytype) !void {
+    assert(ref != .none);
+    const index = @intFromEnum(ref);
+    const ty_ref = ir.instructions.items(.ty)[index];
+    if (ir.instructions.items(.tag)[index] == .constant) {
+        try ir.writeType(ty_ref, color, w);
+        const v_ref = ir.instructions.items(.data)[index].constant;
+        try w.writeByte(' ');
+        try ir.writeValue(v_ref, color, w);
+        return;
+    } else if (ir.instructions.items(.tag)[index] == .symbol) {
+        const name = ir.instructions.items(.data)[index].label;
+        try ir.writeType(ty_ref, color, w);
+        if (color) util.setColor(REF, w);
+        try w.print(" @{s}", .{name});
+        return;
+    }
+    try ir.writeType(ty_ref, color, w);
+    if (color) util.setColor(REF, w);
+    const ref_index = ref_map.getIndex(ref).?;
+    try w.print(" %{d}", .{ref_index});
+}
+
+fn writeNewRef(ir: Ir, ref_map: *RefMap, ref: Ref, color: bool, w: anytype) !void {
+    try ref_map.put(ref, {});
+    try w.writeAll("    ");
+    try ir.writeRef(ref_map, ref, color, w);
+    if (color) util.setColor(.reset, w);
+    try w.writeAll(" = ");
+    if (color) util.setColor(INST, w);
+}
+
+fn writeLabel(ir: Ir, label_map: *RefMap, ref: Ref, color: bool, w: anytype) !void {
+    assert(ref != .none);
+    const index = @intFromEnum(ref);
+    const label = ir.instructions.items(.data)[index].label;
+    if (color) util.setColor(REF, w);
+    const label_index = label_map.getIndex(ref).?;
+    try w.print("{s}.{d}", .{ label, label_index });
+}
deps/aro/LangOpts.zig
@@ -0,0 +1,146 @@
+const std = @import("std");
+const DiagnosticTag = @import("Diagnostics.zig").Tag;
+
+const LangOpts = @This();
+
+pub const Compiler = enum {
+    clang,
+    gcc,
+    msvc,
+};
+
+/// The floating-point evaluation method for intermediate results within a single expression
+pub const FPEvalMethod = enum(i8) {
+    /// The evaluation method cannot be determined or is inconsistent for this target.
+    indeterminate = -1,
+    /// Use the type declared in the source
+    source = 0,
+    /// Use double as the floating-point evaluation method for all float expressions narrower than double.
+    double = 1,
+    /// Use long double as the floating-point evaluation method for all float expressions narrower than long double.
+    extended = 2,
+};
+
+pub const Standard = enum {
+    /// ISO C 1990
+    c89,
+    /// ISO C 1990 with amendment 1
+    iso9899,
+    /// ISO C 1990 with GNU extensions
+    gnu89,
+    /// ISO C 1999
+    c99,
+    /// ISO C 1999 with GNU extensions
+    gnu99,
+    /// ISO C 2011
+    c11,
+    /// ISO C 2011 with GNU extensions
+    gnu11,
+    /// ISO C 2017
+    c17,
+    /// Default value if nothing specified; adds the GNU keywords to
+    /// C17 but does not suppress warnings about using GNU extensions
+    default,
+    /// ISO C 2017 with GNU extensions
+    gnu17,
+    /// Working Draft for ISO C2x
+    c2x,
+    /// Working Draft for ISO C2x with GNU extensions
+    gnu2x,
+
+    const NameMap = std.ComptimeStringMap(Standard, .{
+        .{ "c89", .c89 },                .{ "c90", .c89 },          .{ "iso9899:1990", .c89 },
+        .{ "iso9899:199409", .iso9899 }, .{ "gnu89", .gnu89 },      .{ "gnu90", .gnu89 },
+        .{ "c99", .c99 },                .{ "iso9899:1999", .c99 }, .{ "gnu99", .gnu99 },
+        .{ "c11", .c11 },                .{ "iso9899:2011", .c11 }, .{ "gnu11", .gnu11 },
+        .{ "c17", .c17 },                .{ "iso9899:2017", .c17 }, .{ "c18", .c17 },
+        .{ "iso9899:2018", .c17 },       .{ "gnu17", .gnu17 },      .{ "gnu18", .gnu17 },
+        .{ "c2x", .c2x },                .{ "gnu2x", .gnu2x },
+    });
+
+    pub fn atLeast(self: Standard, other: Standard) bool {
+        return @intFromEnum(self) >= @intFromEnum(other);
+    }
+
+    pub fn isGNU(standard: Standard) bool {
+        return switch (standard) {
+            .gnu89, .gnu99, .gnu11, .default, .gnu17, .gnu2x => true,
+            else => false,
+        };
+    }
+
+    pub fn isExplicitGNU(standard: Standard) bool {
+        return standard.isGNU() and standard != .default;
+    }
+
+    /// Value reported by __STDC_VERSION__ macro
+    pub fn StdCVersionMacro(standard: Standard) ?[]const u8 {
+        return switch (standard) {
+            .c89, .gnu89 => null,
+            .iso9899 => "199409L",
+            .c99, .gnu99 => "199901L",
+            .c11, .gnu11 => "201112L",
+            .default, .c17, .gnu17 => "201710L",
+            // todo: subject to change, verify once c23 finalized
+            .c2x, .gnu2x => "202311L",
+        };
+    }
+};
+
+emulate: Compiler = .clang,
+standard: Standard = .default,
+/// -fshort-enums option, makes enums only take up as much space as they need to hold all the values.
+short_enums: bool = false,
+dollars_in_identifiers: bool = true,
+declspec_attrs: bool = false,
+ms_extensions: bool = false,
+/// true or false if digraph support explicitly enabled/disabled with -fdigraphs/-fno-digraphs
+digraphs: ?bool = null,
+/// If set, use the native half type instead of promoting to float
+use_native_half_type: bool = false,
+/// If set, function arguments and return values may be of type __fp16 even if there is no standard ABI for it
+allow_half_args_and_returns: bool = false,
+/// null indicates that the user did not select a value, use target to determine default
+fp_eval_method: ?FPEvalMethod = null,
+/// If set, use specified signedness for `char` instead of the target's default char signedness
+char_signedness_override: ?std.builtin.Signedness = null,
+/// If set, override the default availability of char8_t (by default, enabled in C2X and later; disabled otherwise)
+has_char8_t_override: ?bool = null,
+
+/// Whether to allow GNU-style inline assembly
+gnu_asm: bool = true,
+
+pub fn setStandard(self: *LangOpts, name: []const u8) error{InvalidStandard}!void {
+    self.standard = Standard.NameMap.get(name) orelse return error.InvalidStandard;
+}
+
+pub fn enableMSExtensions(self: *LangOpts) void {
+    self.declspec_attrs = true;
+    self.ms_extensions = true;
+}
+
+pub fn disableMSExtensions(self: *LangOpts) void {
+    self.declspec_attrs = false;
+    self.ms_extensions = true;
+}
+
+pub fn hasChar8_T(self: *const LangOpts) bool {
+    return self.has_char8_t_override orelse self.standard.atLeast(.c2x);
+}
+
+pub fn hasDigraphs(self: *const LangOpts) bool {
+    return self.digraphs orelse self.standard.atLeast(.gnu89);
+}
+
+pub fn setEmulatedCompiler(self: *LangOpts, compiler: Compiler) void {
+    self.emulate = compiler;
+    if (compiler == .msvc) self.enableMSExtensions();
+}
+
+pub fn setFpEvalMethod(self: *LangOpts, fp_eval_method: FPEvalMethod) void {
+    self.fp_eval_method = fp_eval_method;
+}
+
+pub fn setCharSignedness(self: *LangOpts, signedness: std.builtin.Signedness) void {
+    self.char_signedness_override = signedness;
+}
deps/aro/lib.zig
@@ -0,0 +1,27 @@
+/// Deprecated
+pub const Codegen = @import("Codegen_legacy.zig");
+pub const CodeGen = @import("CodeGen.zig");
+pub const Compilation = @import("Compilation.zig");
+pub const Diagnostics = @import("Diagnostics.zig");
+pub const Driver = @import("Driver.zig");
+pub const Interner = @import("Interner.zig");
+pub const Ir = @import("Ir.zig");
+pub const Object = @import("Object.zig");
+pub const Parser = @import("Parser.zig");
+pub const Preprocessor = @import("Preprocessor.zig");
+pub const Source = @import("Source.zig");
+pub const Tokenizer = @import("Tokenizer.zig");
+pub const Tree = @import("Tree.zig");
+pub const Type = @import("Type.zig");
+pub const TypeMapper = @import("StringInterner.zig").TypeMapper;
+pub const target_util = @import("target.zig");
+
+pub const version_str = "0.0.0-dev";
+pub const version = @import("std").SemanticVersion.parse(version_str) catch unreachable;
+
+pub const CallingConvention = enum {
+    C,
+    stdcall,
+    thiscall,
+    vectorcall,
+};
deps/aro/number_affixes.zig
@@ -0,0 +1,169 @@
+const std = @import("std");
+const mem = std.mem;
+
+pub const Prefix = enum(u8) {
+    binary = 2,
+    octal = 8,
+    decimal = 10,
+    hex = 16,
+
+    pub fn digitAllowed(prefix: Prefix, c: u8) bool {
+        return switch (c) {
+            '0', '1' => true,
+            '2'...'7' => prefix != .binary,
+            '8'...'9' => prefix == .decimal or prefix == .hex,
+            'a'...'f', 'A'...'F' => prefix == .hex,
+            else => false,
+        };
+    }
+
+    pub fn fromString(buf: []const u8) Prefix {
+        if (buf.len == 1) return .decimal;
+        // tokenizer enforces that first byte is a decimal digit or period
+        switch (buf[0]) {
+            '.', '1'...'9' => return .decimal,
+            '0' => {},
+            else => unreachable,
+        }
+        switch (buf[1]) {
+            'x', 'X' => return if (buf.len == 2) .decimal else .hex,
+            'b', 'B' => return if (buf.len == 2) .decimal else .binary,
+            else => {
+                if (mem.indexOfAny(u8, buf, "eE.")) |_| {
+                    // This is a decimal floating point number that happens to start with zero
+                    return .decimal;
+                } else if (Suffix.fromString(buf[1..], .int)) |_| {
+                    // This is `0` with a valid suffix
+                    return .decimal;
+                } else {
+                    return .octal;
+                }
+            },
+        }
+    }
+
+    /// Length of this prefix as a string
+    pub fn stringLen(prefix: Prefix) usize {
+        return switch (prefix) {
+            .binary => 2,
+            .octal => 1,
+            .decimal => 0,
+            .hex => 2,
+        };
+    }
+};
+
+pub const Suffix = enum {
+    // zig fmt: off
+
+    // int and imaginary int
+    None, I,
+
+    // unsigned real integers
+    U, UL, ULL,
+
+    // unsigned imaginary integers
+    IU, IUL, IULL,
+
+    // long or long double, real and imaginary
+    L, IL,
+
+    // long long and imaginary long long
+    LL, ILL,
+
+    // float and imaginary float
+    F, IF,
+
+    // _Float16
+    F16,
+
+    // Imaginary _Bitint
+    IWB, IUWB,
+
+    // _Bitint
+    WB, UWB,
+
+    // zig fmt: on
+
+    const Tuple = struct { Suffix, []const []const u8 };
+
+    const IntSuffixes = &[_]Tuple{
+        .{ .U, &.{"U"} },
+        .{ .L, &.{"L"} },
+        .{ .WB, &.{"WB"} },
+        .{ .UL, &.{ "U", "L" } },
+        .{ .UWB, &.{ "U", "WB" } },
+        .{ .LL, &.{"LL"} },
+        .{ .ULL, &.{ "U", "LL" } },
+
+        .{ .I, &.{"I"} },
+
+        .{ .IWB, &.{ "I", "WB" } },
+        .{ .IU, &.{ "I", "U" } },
+        .{ .IL, &.{ "I", "L" } },
+        .{ .IUL, &.{ "I", "U", "L" } },
+        .{ .IUWB, &.{ "I", "U", "WB" } },
+        .{ .ILL, &.{ "I", "LL" } },
+        .{ .IULL, &.{ "I", "U", "LL" } },
+    };
+
+    const FloatSuffixes = &[_]Tuple{
+        .{ .F16, &.{"F16"} },
+        .{ .F, &.{"F"} },
+        .{ .L, &.{"L"} },
+
+        .{ .I, &.{"I"} },
+        .{ .IL, &.{ "I", "L" } },
+        .{ .IF, &.{ "I", "F" } },
+    };
+
+    pub fn fromString(buf: []const u8, suffix_kind: enum { int, float }) ?Suffix {
+        if (buf.len == 0) return .None;
+
+        const suffixes = switch (suffix_kind) {
+            .float => FloatSuffixes,
+            .int => IntSuffixes,
+        };
+        var scratch: [3]u8 = undefined;
+        top: for (suffixes) |candidate| {
+            const tag = candidate[0];
+            const parts = candidate[1];
+            var len: usize = 0;
+            for (parts) |part| len += part.len;
+            if (len != buf.len) continue;
+
+            for (parts) |part| {
+                const lower = std.ascii.lowerString(&scratch, part);
+                if (mem.indexOf(u8, buf, part) == null and mem.indexOf(u8, buf, lower) == null) continue :top;
+            }
+            return tag;
+        }
+        return null;
+    }
+
+    pub fn isImaginary(suffix: Suffix) bool {
+        return switch (suffix) {
+            .I, .IL, .IF, .IU, .IUL, .ILL, .IULL, .IWB, .IUWB => true,
+            .None, .L, .F16, .F, .U, .UL, .LL, .ULL, .WB, .UWB => false,
+        };
+    }
+
+    pub fn isSignedInteger(suffix: Suffix) bool {
+        return switch (suffix) {
+            .None, .L, .LL, .I, .IL, .ILL, .WB, .IWB => true,
+            .U, .UL, .ULL, .IU, .IUL, .IULL, .UWB, .IUWB => false,
+            .F, .IF, .F16 => unreachable,
+        };
+    }
+
+    pub fn signedness(suffix: Suffix) std.builtin.Signedness {
+        return if (suffix.isSignedInteger()) .signed else .unsigned;
+    }
+
+    pub fn isBitInt(suffix: Suffix) bool {
+        return switch (suffix) {
+            .WB, .UWB, .IWB, .IUWB => true,
+            else => false,
+        };
+    }
+};
deps/aro/Object.zig
@@ -0,0 +1,73 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const Elf = @import("object/Elf.zig");
+
+const Object = @This();
+
+format: std.Target.ObjectFormat,
+comp: *Compilation,
+
+pub fn create(comp: *Compilation) !*Object {
+    switch (comp.target.ofmt) {
+        .elf => return Elf.create(comp),
+        else => unreachable,
+    }
+}
+
+pub fn deinit(obj: *Object) void {
+    switch (obj.format) {
+        .elf => @fieldParentPtr(Elf, "obj", obj).deinit(),
+        else => unreachable,
+    }
+}
+
+pub const Section = union(enum) {
+    undefined,
+    data,
+    read_only_data,
+    func,
+    strings,
+    custom: []const u8,
+};
+
+pub fn getSection(obj: *Object, section: Section) !*std.ArrayList(u8) {
+    switch (obj.format) {
+        .elf => return @fieldParentPtr(Elf, "obj", obj).getSection(section),
+        else => unreachable,
+    }
+}
+
+pub const SymbolType = enum {
+    func,
+    variable,
+    external,
+};
+
+pub fn declareSymbol(
+    obj: *Object,
+    section: Section,
+    name: ?[]const u8,
+    linkage: std.builtin.GlobalLinkage,
+    @"type": SymbolType,
+    offset: u64,
+    size: u64,
+) ![]const u8 {
+    switch (obj.format) {
+        .elf => return @fieldParentPtr(Elf, "obj", obj).declareSymbol(section, name, linkage, @"type", offset, size),
+        else => unreachable,
+    }
+}
+
+pub fn addRelocation(obj: *Object, name: []const u8, section: Section, address: u64, addend: i64) !void {
+    switch (obj.format) {
+        .elf => return @fieldParentPtr(Elf, "obj", obj).addRelocation(name, section, address, addend),
+        else => unreachable,
+    }
+}
+
+pub fn finish(obj: *Object, file: std.fs.File) !void {
+    switch (obj.format) {
+        .elf => return @fieldParentPtr(Elf, "obj", obj).finish(file),
+        else => unreachable,
+    }
+}
deps/aro/Parser.zig
@@ -0,0 +1,8200 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const assert = std.debug.assert;
+const big = std.math.big;
+const Compilation = @import("Compilation.zig");
+const Source = @import("Source.zig");
+const Tokenizer = @import("Tokenizer.zig");
+const Preprocessor = @import("Preprocessor.zig");
+const Tree = @import("Tree.zig");
+const Token = Tree.Token;
+const TokenIndex = Tree.TokenIndex;
+const NodeIndex = Tree.NodeIndex;
+const Type = @import("Type.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const NodeList = std.ArrayList(NodeIndex);
+const InitList = @import("InitList.zig");
+const Attribute = @import("Attribute.zig");
+const CharInfo = @import("CharInfo.zig");
+const Value = @import("Value.zig");
+const SymbolStack = @import("SymbolStack.zig");
+const Symbol = SymbolStack.Symbol;
+const record_layout = @import("record_layout.zig");
+const StringId = @import("StringInterner.zig").StringId;
+const number_affixes = @import("number_affixes.zig");
+const NumberPrefix = number_affixes.Prefix;
+const NumberSuffix = number_affixes.Suffix;
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+const target_util = @import("target.zig");
+
+const Parser = @This();
+
+const Switch = struct {
+    default: ?TokenIndex = null,
+    ranges: std.ArrayList(Range),
+    ty: Type,
+
+    const Range = struct {
+        first: Value,
+        last: Value,
+        tok: TokenIndex,
+    };
+
+    fn add(
+        self: *Switch,
+        comp: *Compilation,
+        first: Value,
+        last: Value,
+        tok: TokenIndex,
+    ) !?Range {
+        for (self.ranges.items) |range| {
+            if (last.compare(.gte, range.first, self.ty, comp) and first.compare(.lte, range.last, self.ty, comp)) {
+                return range; // They overlap.
+            }
+        }
+        try self.ranges.append(.{
+            .first = first,
+            .last = last,
+            .tok = tok,
+        });
+        return null;
+    }
+};
+
+const Label = union(enum) {
+    unresolved_goto: TokenIndex,
+    label: TokenIndex,
+};
+
+pub const Error = Compilation.Error || error{ParsingFailed};
+
+/// An attribute that has been parsed but not yet validated in its context
+const TentativeAttribute = struct {
+    attr: Attribute,
+    tok: TokenIndex,
+};
+
+/// How the parser handles const int decl references when it is expecting an integer
+/// constant expression.
+const ConstDeclFoldingMode = enum {
+    /// fold const decls as if they were literals
+    fold_const_decls,
+    /// fold const decls as if they were literals and issue GNU extension diagnostic
+    gnu_folding_extension,
+    /// fold const decls as if they were literals and issue VLA diagnostic
+    gnu_vla_folding_extension,
+    /// folding const decls is prohibited; return an unavailable value
+    no_const_decl_folding,
+};
+
+// values from preprocessor
+pp: *Preprocessor,
+comp: *Compilation,
+gpa: mem.Allocator,
+tok_ids: []const Token.Id,
+tok_i: TokenIndex = 0,
+
+// values of the incomplete Tree
+arena: Allocator,
+nodes: Tree.Node.List = .{},
+data: NodeList,
+retained_strings: std.ArrayList(u8),
+value_map: Tree.ValueMap,
+
+// buffers used during compilation
+syms: SymbolStack = .{},
+strings: std.ArrayList(u8),
+labels: std.ArrayList(Label),
+list_buf: NodeList,
+decl_buf: NodeList,
+param_buf: std.ArrayList(Type.Func.Param),
+enum_buf: std.ArrayList(Type.Enum.Field),
+record_buf: std.ArrayList(Type.Record.Field),
+attr_buf: std.MultiArrayList(TentativeAttribute) = .{},
+attr_application_buf: std.ArrayListUnmanaged(Attribute) = .{},
+field_attr_buf: std.ArrayList([]const Attribute),
+/// type name -> variable name location for tentative definitions (top-level defs with thus-far-incomplete types)
+/// e.g. `struct Foo bar;` where `struct Foo` is not defined yet.
+/// The key is the StringId of `Foo` and the value is the TokenIndex of `bar`
+/// Items are removed if the type is subsequently completed with a definition.
+/// We only store the first tentative definition that uses a given type because this map is only used
+/// for issuing an error message, and correcting the first error for a type will fix all of them for that type.
+tentative_defs: std.AutoHashMapUnmanaged(StringId, TokenIndex) = .{},
+
+// configuration and miscellaneous info
+no_eval: bool = false,
+in_macro: bool = false,
+extension_suppressed: bool = false,
+contains_address_of_label: bool = false,
+label_count: u32 = 0,
+const_decl_folding: ConstDeclFoldingMode = .fold_const_decls,
+/// location of first computed goto in function currently being parsed
+/// if a computed goto is used, the function must contain an
+/// address-of-label expression (tracked with contains_address_of_label)
+computed_goto_tok: ?TokenIndex = null,
+
+/// Various variables that are different for each function.
+func: struct {
+    /// null if not in function, will always be plain func, var_args_func or old_style_func
+    ty: ?Type = null,
+    name: TokenIndex = 0,
+    ident: ?Result = null,
+    pretty_ident: ?Result = null,
+} = .{},
+/// Various variables that are different for each record.
+record: struct {
+    // invalid means we're not parsing a record
+    kind: Token.Id = .invalid,
+    flexible_field: ?TokenIndex = null,
+    start: usize = 0,
+    field_attr_start: usize = 0,
+
+    fn addField(r: @This(), p: *Parser, name: StringId, tok: TokenIndex) Error!void {
+        var i = p.record_members.items.len;
+        while (i > r.start) {
+            i -= 1;
+            if (p.record_members.items[i].name == name) {
+                try p.errStr(.duplicate_member, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, p.record_members.items[i].tok);
+                break;
+            }
+        }
+        try p.record_members.append(p.gpa, .{ .name = name, .tok = tok });
+    }
+
+    fn addFieldsFromAnonymous(r: @This(), p: *Parser, ty: Type) Error!void {
+        for (ty.data.record.fields) |f| {
+            if (f.isAnonymousRecord()) {
+                try r.addFieldsFromAnonymous(p, f.ty.canonicalize(.standard));
+            } else if (f.name_tok != 0) {
+                try r.addField(p, f.name, f.name_tok);
+            }
+        }
+    }
+} = .{},
+record_members: std.ArrayListUnmanaged(struct { tok: TokenIndex, name: StringId }) = .{},
+@"switch": ?*Switch = null,
+in_loop: bool = false,
+pragma_pack: ?u8 = null,
+string_ids: struct {
+    declspec_id: StringId,
+    main_id: StringId,
+    file: StringId,
+    jmp_buf: StringId,
+    sigjmp_buf: StringId,
+    ucontext_t: StringId,
+},
+
+fn checkIdentifierCodepoint(comp: *Compilation, codepoint: u21, loc: Source.Location) Compilation.Error!bool {
+    if (codepoint <= 0x7F) return false;
+    var diagnosed = false;
+    if (!CharInfo.isC99IdChar(codepoint)) {
+        try comp.diag.add(.{
+            .tag = .c99_compat,
+            .loc = loc,
+        }, &.{});
+        diagnosed = true;
+    }
+    if (CharInfo.isInvisible(codepoint)) {
+        try comp.diag.add(.{
+            .tag = .unicode_zero_width,
+            .loc = loc,
+            .extra = .{ .actual_codepoint = codepoint },
+        }, &.{});
+        diagnosed = true;
+    }
+    if (CharInfo.homoglyph(codepoint)) |resembles| {
+        try comp.diag.add(.{
+            .tag = .unicode_homoglyph,
+            .loc = loc,
+            .extra = .{ .codepoints = .{ .actual = codepoint, .resembles = resembles } },
+        }, &.{});
+        diagnosed = true;
+    }
+    return diagnosed;
+}
+
+fn eatIdentifier(p: *Parser) !?TokenIndex {
+    switch (p.tok_ids[p.tok_i]) {
+        .identifier => {},
+        .extended_identifier => {
+            const slice = p.tokSlice(p.tok_i);
+            var it = std.unicode.Utf8View.initUnchecked(slice).iterator();
+            var loc = p.pp.tokens.items(.loc)[p.tok_i];
+
+            if (mem.indexOfScalar(u8, slice, '$')) |i| {
+                loc.byte_offset += @intCast(i);
+                try p.comp.diag.add(.{
+                    .tag = .dollar_in_identifier_extension,
+                    .loc = loc,
+                }, &.{});
+                loc = p.pp.tokens.items(.loc)[p.tok_i];
+            }
+
+            while (it.nextCodepoint()) |c| {
+                if (try checkIdentifierCodepoint(p.comp, c, loc)) break;
+                loc.byte_offset += std.unicode.utf8CodepointSequenceLength(c) catch unreachable;
+            }
+        },
+        else => return null,
+    }
+    p.tok_i += 1;
+
+    // Handle illegal '$' characters in identifiers
+    if (!p.comp.langopts.dollars_in_identifiers) {
+        if (p.tok_ids[p.tok_i] == .invalid and p.tokSlice(p.tok_i)[0] == '$') {
+            try p.err(.dollars_in_identifiers);
+            p.tok_i += 1;
+            return error.ParsingFailed;
+        }
+    }
+
+    return p.tok_i - 1;
+}
+
+fn expectIdentifier(p: *Parser) Error!TokenIndex {
+    const actual = p.tok_ids[p.tok_i];
+    if (actual != .identifier and actual != .extended_identifier) {
+        return p.errExpectedToken(.identifier, actual);
+    }
+
+    return (try p.eatIdentifier()) orelse unreachable;
+}
+
+fn eatToken(p: *Parser, id: Token.Id) ?TokenIndex {
+    assert(id != .identifier and id != .extended_identifier); // use eatIdentifier
+    if (p.tok_ids[p.tok_i] == id) {
+        defer p.tok_i += 1;
+        return p.tok_i;
+    } else return null;
+}
+
+fn expectToken(p: *Parser, expected: Token.Id) Error!TokenIndex {
+    assert(expected != .identifier and expected != .extended_identifier); // use expectIdentifier
+    const actual = p.tok_ids[p.tok_i];
+    if (actual != expected) return p.errExpectedToken(expected, actual);
+    defer p.tok_i += 1;
+    return p.tok_i;
+}
+
+pub fn tokSlice(p: *Parser, tok: TokenIndex) []const u8 {
+    if (p.tok_ids[tok].lexeme()) |some| return some;
+    const loc = p.pp.tokens.items(.loc)[tok];
+    var tmp_tokenizer = Tokenizer{
+        .buf = p.comp.getSource(loc.id).buf,
+        .comp = p.comp,
+        .index = loc.byte_offset,
+        .source = .generated,
+    };
+    const res = tmp_tokenizer.next();
+    return tmp_tokenizer.buf[res.start..res.end];
+}
+
+fn expectClosing(p: *Parser, opening: TokenIndex, id: Token.Id) Error!void {
+    _ = p.expectToken(id) catch |e| {
+        if (e == error.ParsingFailed) {
+            try p.errTok(switch (id) {
+                .r_paren => .to_match_paren,
+                .r_brace => .to_match_brace,
+                .r_bracket => .to_match_brace,
+                else => unreachable,
+            }, opening);
+        }
+        return e;
+    };
+}
+
+fn errOverflow(p: *Parser, op_tok: TokenIndex, res: Result) !void {
+    if (res.ty.isUnsignedInt(p.comp)) {
+        try p.errExtra(.overflow_unsigned, op_tok, .{ .unsigned = res.val.data.int });
+    } else {
+        try p.errExtra(.overflow_signed, op_tok, .{ .signed = res.val.signExtend(res.ty, p.comp) });
+    }
+}
+
+fn errExpectedToken(p: *Parser, expected: Token.Id, actual: Token.Id) Error {
+    switch (actual) {
+        .invalid => try p.errExtra(.expected_invalid, p.tok_i, .{ .tok_id_expected = expected }),
+        .eof => try p.errExtra(.expected_eof, p.tok_i, .{ .tok_id_expected = expected }),
+        else => try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{
+            .expected = expected,
+            .actual = actual,
+        } }),
+    }
+    return error.ParsingFailed;
+}
+
+pub fn errStr(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, str: []const u8) Compilation.Error!void {
+    @setCold(true);
+    return p.errExtra(tag, tok_i, .{ .str = str });
+}
+
+pub fn errExtra(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, extra: Diagnostics.Message.Extra) Compilation.Error!void {
+    @setCold(true);
+    const tok = p.pp.tokens.get(tok_i);
+    var loc = tok.loc;
+    if (tok_i != 0 and tok.id == .eof) {
+        // if the token is EOF, point at the end of the previous token instead
+        const prev = p.pp.tokens.get(tok_i - 1);
+        loc = prev.loc;
+        loc.byte_offset += @intCast(p.tokSlice(tok_i - 1).len);
+    }
+    try p.comp.diag.add(.{
+        .tag = tag,
+        .loc = loc,
+        .extra = extra,
+    }, tok.expansionSlice());
+}
+
+pub fn errTok(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex) Compilation.Error!void {
+    @setCold(true);
+    return p.errExtra(tag, tok_i, .{ .none = {} });
+}
+
+pub fn err(p: *Parser, tag: Diagnostics.Tag) Compilation.Error!void {
+    @setCold(true);
+    return p.errExtra(tag, p.tok_i, .{ .none = {} });
+}
+
+pub fn todo(p: *Parser, msg: []const u8) Error {
+    try p.errStr(.todo, p.tok_i, msg);
+    return error.ParsingFailed;
+}
+
+pub fn typeStr(p: *Parser, ty: Type) ![]const u8 {
+    if (Type.Builder.fromType(ty).str(p.comp.langopts)) |str| return str;
+    const strings_top = p.strings.items.len;
+    defer p.strings.items.len = strings_top;
+
+    const mapper = p.comp.string_interner.getSlowTypeMapper();
+    try ty.print(mapper, p.comp.langopts, p.strings.writer());
+    return try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+}
+
+pub fn typePairStr(p: *Parser, a: Type, b: Type) ![]const u8 {
+    return p.typePairStrExtra(a, " and ", b);
+}
+
+pub fn typePairStrExtra(p: *Parser, a: Type, msg: []const u8, b: Type) ![]const u8 {
+    const strings_top = p.strings.items.len;
+    defer p.strings.items.len = strings_top;
+
+    try p.strings.append('\'');
+    const mapper = p.comp.string_interner.getSlowTypeMapper();
+    try a.print(mapper, p.comp.langopts, p.strings.writer());
+    try p.strings.append('\'');
+    try p.strings.appendSlice(msg);
+    try p.strings.append('\'');
+    try b.print(mapper, p.comp.langopts, p.strings.writer());
+    try p.strings.append('\'');
+    return try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+}
+
+pub fn floatValueChangedStr(p: *Parser, res: *Result, old_value: f64, int_ty: Type) ![]const u8 {
+    const strings_top = p.strings.items.len;
+    defer p.strings.items.len = strings_top;
+
+    var w = p.strings.writer();
+    const type_pair_str = try p.typePairStrExtra(res.ty, " to ", int_ty);
+    try w.writeAll(type_pair_str);
+    const is_zero = res.val.isZero();
+    const non_zero_str: []const u8 = if (is_zero) "non-zero " else "";
+    if (int_ty.is(.bool)) {
+        try w.print(" changes {s}value from {d} to {}", .{ non_zero_str, old_value, res.val.getBool() });
+    } else if (int_ty.isUnsignedInt(p.comp)) {
+        try w.print(" changes {s}value from {d} to {d}", .{ non_zero_str, old_value, res.val.getInt(u64) });
+    } else {
+        try w.print(" changes {s}value from {d} to {d}", .{ non_zero_str, old_value, res.val.getInt(i64) });
+    }
+
+    return try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+}
+
+fn checkDeprecatedUnavailable(p: *Parser, ty: Type, usage_tok: TokenIndex, decl_tok: TokenIndex) !void {
+    if (ty.getAttribute(.@"error")) |@"error"| {
+        const strings_top = p.strings.items.len;
+        defer p.strings.items.len = strings_top;
+
+        const w = p.strings.writer();
+        const msg_str = p.retainedString(@"error".msg);
+        try w.print("call to '{s}' declared with attribute error: {s}", .{ p.tokSlice(@"error".__name_tok), msg_str });
+        const str = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+        try p.errStr(.error_attribute, usage_tok, str);
+    }
+    if (ty.getAttribute(.warning)) |warning| {
+        const strings_top = p.strings.items.len;
+        defer p.strings.items.len = strings_top;
+
+        const w = p.strings.writer();
+        const msg_str = p.retainedString(warning.msg);
+        try w.print("call to '{s}' declared with attribute warning: {s}", .{ p.tokSlice(warning.__name_tok), msg_str });
+        const str = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+        try p.errStr(.warning_attribute, usage_tok, str);
+    }
+    if (ty.getAttribute(.unavailable)) |unavailable| {
+        try p.errDeprecated(.unavailable, usage_tok, unavailable.msg);
+        try p.errStr(.unavailable_note, unavailable.__name_tok, p.tokSlice(decl_tok));
+        return error.ParsingFailed;
+    } else if (ty.getAttribute(.deprecated)) |deprecated| {
+        try p.errDeprecated(.deprecated_declarations, usage_tok, deprecated.msg);
+        try p.errStr(.deprecated_note, deprecated.__name_tok, p.tokSlice(decl_tok));
+    }
+}
+
+/// Returned slice is invalidated if additional strings are added to p.retained_strings
+fn retainedString(p: *Parser, range: Value.ByteRange) []const u8 {
+    return range.slice(p.retained_strings.items);
+}
+
+fn errDeprecated(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, msg: ?Value.ByteRange) Compilation.Error!void {
+    const strings_top = p.strings.items.len;
+    defer p.strings.items.len = strings_top;
+
+    const w = p.strings.writer();
+    try w.print("'{s}' is ", .{p.tokSlice(tok_i)});
+    const reason: []const u8 = switch (tag) {
+        .unavailable => "unavailable",
+        .deprecated_declarations => "deprecated",
+        else => unreachable,
+    };
+    try w.writeAll(reason);
+    if (msg) |m| {
+        const str = p.retainedString(m);
+        try w.print(": {s}", .{str});
+    }
+    const str = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
+    return p.errStr(tag, tok_i, str);
+}
+
+fn addNode(p: *Parser, node: Tree.Node) Allocator.Error!NodeIndex {
+    if (p.in_macro) return .none;
+    const res = p.nodes.len;
+    try p.nodes.append(p.gpa, node);
+    return @enumFromInt(res);
+}
+
+fn addList(p: *Parser, nodes: []const NodeIndex) Allocator.Error!Tree.Node.Range {
+    if (p.in_macro) return Tree.Node.Range{ .start = 0, .end = 0 };
+    const start: u32 = @intCast(p.data.items.len);
+    try p.data.appendSlice(nodes);
+    const end: u32 = @intCast(p.data.items.len);
+    return Tree.Node.Range{ .start = start, .end = end };
+}
+
+fn findLabel(p: *Parser, name: []const u8) ?TokenIndex {
+    for (p.labels.items) |item| {
+        switch (item) {
+            .label => |l| if (mem.eql(u8, p.tokSlice(l), name)) return l,
+            .unresolved_goto => {},
+        }
+    }
+    return null;
+}
+
+fn nodeIs(p: *Parser, node: NodeIndex, tag: Tree.Tag) bool {
+    return p.getNode(node, tag) != null;
+}
+
+fn getNode(p: *Parser, node: NodeIndex, tag: Tree.Tag) ?NodeIndex {
+    var cur = node;
+    const tags = p.nodes.items(.tag);
+    const data = p.nodes.items(.data);
+    while (true) {
+        const cur_tag = tags[@intFromEnum(cur)];
+        if (cur_tag == .paren_expr) {
+            cur = data[@intFromEnum(cur)].un;
+        } else if (cur_tag == tag) {
+            return cur;
+        } else {
+            return null;
+        }
+    }
+}
+
+fn pragma(p: *Parser) Compilation.Error!bool {
+    var found_pragma = false;
+    while (p.eatToken(.keyword_pragma)) |_| {
+        found_pragma = true;
+
+        const name_tok = p.tok_i;
+        const name = p.tokSlice(name_tok);
+
+        const end_idx = mem.indexOfScalarPos(Token.Id, p.tok_ids, p.tok_i, .nl).?;
+        const pragma_len = @as(TokenIndex, @intCast(end_idx)) - p.tok_i;
+        defer p.tok_i += pragma_len + 1; // skip past .nl as well
+        if (p.comp.getPragma(name)) |prag| {
+            try prag.parserCB(p, p.tok_i);
+        }
+    }
+    return found_pragma;
+}
+
+/// Issue errors for top-level definitions whose type was never completed.
+fn diagnoseIncompleteDefinitions(p: *Parser) !void {
+    @setCold(true);
+
+    const node_slices = p.nodes.slice();
+    const tags = node_slices.items(.tag);
+    const tys = node_slices.items(.ty);
+    const data = node_slices.items(.data);
+
+    const err_start = p.comp.diag.list.items.len;
+    for (p.decl_buf.items) |decl_node| {
+        const idx = @intFromEnum(decl_node);
+        switch (tags[idx]) {
+            .struct_forward_decl, .union_forward_decl, .enum_forward_decl => {},
+            else => continue,
+        }
+
+        const ty = tys[idx];
+        const decl_type_name = if (ty.getRecord()) |rec|
+            rec.name
+        else if (ty.get(.@"enum")) |en|
+            en.data.@"enum".name
+        else
+            unreachable;
+
+        const tentative_def_tok = p.tentative_defs.get(decl_type_name) orelse continue;
+        const type_str = try p.typeStr(ty);
+        try p.errStr(.tentative_definition_incomplete, tentative_def_tok, type_str);
+        try p.errStr(.forward_declaration_here, data[idx].decl_ref, type_str);
+    }
+    const errors_added = p.comp.diag.list.items.len - err_start;
+    assert(errors_added == 2 * p.tentative_defs.count()); // Each tentative def should add an error + note
+}
+
+/// root : (decl | assembly ';' | staticAssert)*
+pub fn parse(pp: *Preprocessor) Compilation.Error!Tree {
+    pp.comp.pragmaEvent(.before_parse);
+
+    var arena = std.heap.ArenaAllocator.init(pp.comp.gpa);
+    errdefer arena.deinit();
+    var p = Parser{
+        .pp = pp,
+        .comp = pp.comp,
+        .gpa = pp.comp.gpa,
+        .arena = arena.allocator(),
+        .tok_ids = pp.tokens.items(.id),
+        .strings = std.ArrayList(u8).init(pp.comp.gpa),
+        .retained_strings = std.ArrayList(u8).init(pp.comp.gpa),
+        .value_map = Tree.ValueMap.init(pp.comp.gpa),
+        .data = NodeList.init(pp.comp.gpa),
+        .labels = std.ArrayList(Label).init(pp.comp.gpa),
+        .list_buf = NodeList.init(pp.comp.gpa),
+        .decl_buf = NodeList.init(pp.comp.gpa),
+        .param_buf = std.ArrayList(Type.Func.Param).init(pp.comp.gpa),
+        .enum_buf = std.ArrayList(Type.Enum.Field).init(pp.comp.gpa),
+        .record_buf = std.ArrayList(Type.Record.Field).init(pp.comp.gpa),
+        .field_attr_buf = std.ArrayList([]const Attribute).init(pp.comp.gpa),
+        .string_ids = .{
+            .declspec_id = try pp.comp.intern("__declspec"),
+            .main_id = try pp.comp.intern("main"),
+            .file = try pp.comp.intern("FILE"),
+            .jmp_buf = try pp.comp.intern("jmp_buf"),
+            .sigjmp_buf = try pp.comp.intern("sigjmp_buf"),
+            .ucontext_t = try pp.comp.intern("ucontext_t"),
+        },
+    };
+    errdefer {
+        p.nodes.deinit(pp.comp.gpa);
+        p.retained_strings.deinit();
+        p.value_map.deinit();
+    }
+    defer {
+        p.data.deinit();
+        p.labels.deinit();
+        p.strings.deinit();
+        p.syms.deinit(pp.comp.gpa);
+        p.list_buf.deinit();
+        p.decl_buf.deinit();
+        p.param_buf.deinit();
+        p.enum_buf.deinit();
+        p.record_buf.deinit();
+        p.record_members.deinit(pp.comp.gpa);
+        p.attr_buf.deinit(pp.comp.gpa);
+        p.attr_application_buf.deinit(pp.comp.gpa);
+        p.tentative_defs.deinit(pp.comp.gpa);
+        assert(p.field_attr_buf.items.len == 0);
+        p.field_attr_buf.deinit();
+    }
+
+    // NodeIndex 0 must be invalid
+    _ = try p.addNode(.{ .tag = .invalid, .ty = undefined, .data = undefined });
+
+    {
+        if (p.comp.langopts.hasChar8_T()) {
+            try p.syms.defineTypedef(&p, try p.comp.intern("char8_t"), .{ .specifier = .uchar }, 0, .none);
+        }
+        try p.syms.defineTypedef(&p, try p.comp.intern("__int128_t"), .{ .specifier = .int128 }, 0, .none);
+        try p.syms.defineTypedef(&p, try p.comp.intern("__uint128_t"), .{ .specifier = .uint128 }, 0, .none);
+
+        const elem_ty = try p.arena.create(Type);
+        elem_ty.* = .{ .specifier = .char };
+        try p.syms.defineTypedef(&p, try p.comp.intern("__builtin_ms_va_list"), .{
+            .specifier = .pointer,
+            .data = .{ .sub_type = elem_ty },
+        }, 0, .none);
+
+        const ty = &pp.comp.types.va_list;
+        try p.syms.defineTypedef(&p, try p.comp.intern("__builtin_va_list"), ty.*, 0, .none);
+
+        if (ty.isArray()) ty.decayArray();
+
+        try p.syms.defineTypedef(&p, try p.comp.intern("__NSConstantString"), pp.comp.types.ns_constant_string.ty, 0, .none);
+    }
+
+    while (p.eatToken(.eof) == null) {
+        if (try p.pragma()) continue;
+        if (try p.parseOrNextDecl(staticAssert)) continue;
+        if (try p.parseOrNextDecl(decl)) continue;
+        if (p.eatToken(.keyword_extension)) |_| {
+            const saved_extension = p.extension_suppressed;
+            defer p.extension_suppressed = saved_extension;
+            p.extension_suppressed = true;
+
+            if (try p.parseOrNextDecl(decl)) continue;
+            switch (p.tok_ids[p.tok_i]) {
+                .semicolon => p.tok_i += 1,
+                .keyword_static_assert,
+                .keyword_c23_static_assert,
+                .keyword_pragma,
+                .keyword_extension,
+                .keyword_asm,
+                .keyword_asm1,
+                .keyword_asm2,
+                => {},
+                else => try p.err(.expected_external_decl),
+            }
+            continue;
+        }
+        if (p.assembly(.global) catch |er| switch (er) {
+            error.ParsingFailed => {
+                p.nextExternDecl();
+                continue;
+            },
+            else => |e| return e,
+        }) |node| {
+            try p.decl_buf.append(node);
+            continue;
+        }
+        if (p.eatToken(.semicolon)) |tok| {
+            try p.errTok(.extra_semi, tok);
+            continue;
+        }
+        try p.err(.expected_external_decl);
+        p.tok_i += 1;
+    }
+    if (p.tentative_defs.count() > 0) {
+        try p.diagnoseIncompleteDefinitions();
+    }
+
+    const root_decls = try p.decl_buf.toOwnedSlice();
+    errdefer pp.comp.gpa.free(root_decls);
+    if (root_decls.len == 0) {
+        try p.errTok(.empty_translation_unit, p.tok_i - 1);
+    }
+    pp.comp.pragmaEvent(.after_parse);
+
+    const data = try p.data.toOwnedSlice();
+    errdefer pp.comp.gpa.free(data);
+    const strings = try p.retained_strings.toOwnedSlice();
+    errdefer pp.comp.gpa.free(strings);
+    return Tree{
+        .comp = pp.comp,
+        .tokens = pp.tokens.slice(),
+        .arena = arena,
+        .generated = pp.comp.generated_buf.items,
+        .nodes = p.nodes.toOwnedSlice(),
+        .data = data,
+        .root_decls = root_decls,
+        .strings = strings,
+        .value_map = p.value_map,
+    };
+}
+
+fn skipToPragmaSentinel(p: *Parser) void {
+    while (true) : (p.tok_i += 1) {
+        if (p.tok_ids[p.tok_i] == .nl) return;
+        if (p.tok_ids[p.tok_i] == .eof) {
+            p.tok_i -= 1;
+            return;
+        }
+    }
+}
+
+fn parseOrNextDecl(p: *Parser, comptime func: fn (*Parser) Error!bool) Compilation.Error!bool {
+    return func(p) catch |er| switch (er) {
+        error.ParsingFailed => {
+            p.nextExternDecl();
+            return true;
+        },
+        else => |e| return e,
+    };
+}
+
+fn nextExternDecl(p: *Parser) void {
+    var parens: u32 = 0;
+    while (true) : (p.tok_i += 1) {
+        switch (p.tok_ids[p.tok_i]) {
+            .l_paren, .l_brace, .l_bracket => parens += 1,
+            .r_paren, .r_brace, .r_bracket => if (parens != 0) {
+                parens -= 1;
+            },
+            .keyword_typedef,
+            .keyword_extern,
+            .keyword_static,
+            .keyword_auto,
+            .keyword_register,
+            .keyword_thread_local,
+            .keyword_c23_thread_local,
+            .keyword_inline,
+            .keyword_inline1,
+            .keyword_inline2,
+            .keyword_noreturn,
+            .keyword_void,
+            .keyword_bool,
+            .keyword_c23_bool,
+            .keyword_char,
+            .keyword_short,
+            .keyword_int,
+            .keyword_long,
+            .keyword_signed,
+            .keyword_unsigned,
+            .keyword_float,
+            .keyword_double,
+            .keyword_complex,
+            .keyword_atomic,
+            .keyword_enum,
+            .keyword_struct,
+            .keyword_union,
+            .keyword_alignas,
+            .keyword_c23_alignas,
+            .identifier,
+            .extended_identifier,
+            .keyword_typeof,
+            .keyword_typeof1,
+            .keyword_typeof2,
+            .keyword_extension,
+            .keyword_bit_int,
+            => if (parens == 0) return,
+            .keyword_pragma => p.skipToPragmaSentinel(),
+            .eof => return,
+            .semicolon => if (parens == 0) {
+                p.tok_i += 1;
+                return;
+            },
+            else => {},
+        }
+    }
+}
+
+fn skipTo(p: *Parser, id: Token.Id) void {
+    var parens: u32 = 0;
+    while (true) : (p.tok_i += 1) {
+        if (p.tok_ids[p.tok_i] == id and parens == 0) {
+            p.tok_i += 1;
+            return;
+        }
+        switch (p.tok_ids[p.tok_i]) {
+            .l_paren, .l_brace, .l_bracket => parens += 1,
+            .r_paren, .r_brace, .r_bracket => if (parens != 0) {
+                parens -= 1;
+            },
+            .keyword_pragma => p.skipToPragmaSentinel(),
+            .eof => return,
+            else => {},
+        }
+    }
+}
+
+/// Called after a typedef is defined
+fn typedefDefined(p: *Parser, name: StringId, ty: Type) void {
+    if (name == p.string_ids.file) {
+        p.comp.types.file = ty;
+    } else if (name == p.string_ids.jmp_buf) {
+        p.comp.types.jmp_buf = ty;
+    } else if (name == p.string_ids.sigjmp_buf) {
+        p.comp.types.sigjmp_buf = ty;
+    } else if (name == p.string_ids.ucontext_t) {
+        p.comp.types.ucontext_t = ty;
+    }
+}
+
+// ====== declarations ======
+
+/// decl
+///  : declSpec (initDeclarator ( ',' initDeclarator)*)? ';'
+///  | declSpec declarator decl* compoundStmt
+fn decl(p: *Parser) Error!bool {
+    _ = try p.pragma();
+    const first_tok = p.tok_i;
+    const attr_buf_top = p.attr_buf.len;
+    defer p.attr_buf.len = attr_buf_top;
+
+    try p.attributeSpecifier();
+
+    var decl_spec = if (try p.declSpec()) |some| some else blk: {
+        if (p.func.ty != null) {
+            p.tok_i = first_tok;
+            return false;
+        }
+        switch (p.tok_ids[first_tok]) {
+            .asterisk, .l_paren, .identifier, .extended_identifier => {},
+            else => if (p.tok_i != first_tok) {
+                try p.err(.expected_ident_or_l_paren);
+                return error.ParsingFailed;
+            } else return false,
+        }
+        var spec: Type.Builder = .{};
+        break :blk DeclSpec{ .ty = try spec.finish(p) };
+    };
+    if (decl_spec.noreturn) |tok| {
+        const attr = Attribute{ .tag = .noreturn, .args = .{ .noreturn = {} }, .syntax = .keyword };
+        try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = tok });
+    }
+    var init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse {
+        _ = try p.expectToken(.semicolon);
+        if (decl_spec.ty.is(.@"enum") or
+            (decl_spec.ty.isRecord() and !decl_spec.ty.isAnonymousRecord(p.comp) and
+            !decl_spec.ty.isTypeof())) // we follow GCC and clang's behavior here
+        {
+            const specifier = decl_spec.ty.canonicalize(.standard).specifier;
+            const attrs = p.attr_buf.items(.attr)[attr_buf_top..];
+            const toks = p.attr_buf.items(.tok)[attr_buf_top..];
+            for (attrs, toks) |attr, tok| {
+                try p.errExtra(.ignored_record_attr, tok, .{
+                    .ignored_record_attr = .{ .tag = attr.tag, .specifier = switch (specifier) {
+                        .@"enum" => .@"enum",
+                        .@"struct" => .@"struct",
+                        .@"union" => .@"union",
+                        else => unreachable,
+                    } },
+                });
+            }
+            return true;
+        }
+
+        try p.errTok(.missing_declaration, first_tok);
+        return true;
+    };
+
+    // Check for function definition.
+    if (init_d.d.func_declarator != null and init_d.initializer.node == .none and init_d.d.ty.isFunc()) fn_def: {
+        if (decl_spec.auto_type) |tok_i| {
+            try p.errStr(.auto_type_not_allowed, tok_i, "function return type");
+            return error.ParsingFailed;
+        }
+
+        switch (p.tok_ids[p.tok_i]) {
+            .comma, .semicolon => break :fn_def,
+            .l_brace => {},
+            else => if (init_d.d.old_style_func == null) {
+                try p.err(.expected_fn_body);
+                return true;
+            },
+        }
+        if (p.func.ty != null) try p.err(.func_not_in_root);
+
+        const node = try p.addNode(undefined); // reserve space
+        const interned_declarator_name = try p.comp.intern(p.tokSlice(init_d.d.name));
+        try p.syms.defineSymbol(p, interned_declarator_name, init_d.d.ty, init_d.d.name, node, .{}, false);
+
+        const func = p.func;
+        p.func = .{
+            .ty = init_d.d.ty,
+            .name = init_d.d.name,
+        };
+        if (interned_declarator_name == p.string_ids.main_id and !init_d.d.ty.returnType().is(.int)) {
+            try p.errTok(.main_return_type, init_d.d.name);
+        }
+        defer p.func = func;
+
+        try p.syms.pushScope(p);
+        defer p.syms.popScope();
+
+        // Collect old style parameter declarations.
+        if (init_d.d.old_style_func != null) {
+            const attrs = init_d.d.ty.getAttributes();
+            var base_ty = if (init_d.d.ty.specifier == .attributed) init_d.d.ty.elemType() else init_d.d.ty;
+            base_ty.specifier = .func;
+            init_d.d.ty = try base_ty.withAttributes(p.arena, attrs);
+
+            const param_buf_top = p.param_buf.items.len;
+            defer p.param_buf.items.len = param_buf_top;
+
+            param_loop: while (true) {
+                const param_decl_spec = (try p.declSpec()) orelse break;
+                if (p.eatToken(.semicolon)) |semi| {
+                    try p.errTok(.missing_declaration, semi);
+                    continue :param_loop;
+                }
+
+                while (true) {
+                    const attr_buf_top_declarator = p.attr_buf.len;
+                    defer p.attr_buf.len = attr_buf_top_declarator;
+
+                    var d = (try p.declarator(param_decl_spec.ty, .normal)) orelse {
+                        try p.errTok(.missing_declaration, first_tok);
+                        _ = try p.expectToken(.semicolon);
+                        continue :param_loop;
+                    };
+                    try p.attributeSpecifier();
+
+                    if (d.ty.hasIncompleteSize() and !d.ty.is(.void)) try p.errStr(.parameter_incomplete_ty, d.name, try p.typeStr(d.ty));
+                    if (d.ty.isFunc()) {
+                        // Params declared as functions are converted to function pointers.
+                        const elem_ty = try p.arena.create(Type);
+                        elem_ty.* = d.ty;
+                        d.ty = Type{
+                            .specifier = .pointer,
+                            .data = .{ .sub_type = elem_ty },
+                        };
+                    } else if (d.ty.isArray()) {
+                        // params declared as arrays are converted to pointers
+                        d.ty.decayArray();
+                    } else if (d.ty.is(.void)) {
+                        try p.errTok(.invalid_void_param, d.name);
+                    }
+
+                    // find and correct parameter types
+                    // TODO check for missing declarations and redefinitions
+                    const name_str = p.tokSlice(d.name);
+                    const interned_name = try p.comp.intern(name_str);
+                    for (init_d.d.ty.params()) |*param| {
+                        if (param.name == interned_name) {
+                            param.ty = d.ty;
+                            break;
+                        }
+                    } else {
+                        try p.errStr(.parameter_missing, d.name, name_str);
+                    }
+                    d.ty = try Attribute.applyParameterAttributes(p, d.ty, attr_buf_top_declarator, .alignas_on_param);
+
+                    // bypass redefinition check to avoid duplicate errors
+                    try p.syms.syms.append(p.gpa, .{
+                        .kind = .def,
+                        .name = interned_name,
+                        .tok = d.name,
+                        .ty = d.ty,
+                        .val = .{},
+                    });
+                    if (p.eatToken(.comma) == null) break;
+                }
+                _ = try p.expectToken(.semicolon);
+            }
+        } else {
+            for (init_d.d.ty.params()) |param| {
+                if (param.ty.hasUnboundVLA()) try p.errTok(.unbound_vla, param.name_tok);
+                if (param.ty.hasIncompleteSize() and !param.ty.is(.void) and param.ty.specifier != .invalid) try p.errStr(.parameter_incomplete_ty, param.name_tok, try p.typeStr(param.ty));
+
+                if (param.name == .empty) {
+                    try p.errTok(.omitting_parameter_name, param.name_tok);
+                    continue;
+                }
+
+                // bypass redefinition check to avoid duplicate errors
+                try p.syms.syms.append(p.gpa, .{
+                    .kind = .def,
+                    .name = param.name,
+                    .tok = param.name_tok,
+                    .ty = param.ty,
+                    .val = .{},
+                });
+            }
+        }
+
+        const body = (try p.compoundStmt(true, null)) orelse {
+            assert(init_d.d.old_style_func != null);
+            try p.err(.expected_fn_body);
+            return true;
+        };
+        p.nodes.set(@intFromEnum(node), .{
+            .ty = init_d.d.ty,
+            .tag = try decl_spec.validateFnDef(p),
+            .data = .{ .decl = .{ .name = init_d.d.name, .node = body } },
+        });
+        try p.decl_buf.append(node);
+
+        // check gotos
+        if (func.ty == null) {
+            for (p.labels.items) |item| {
+                if (item == .unresolved_goto)
+                    try p.errStr(.undeclared_label, item.unresolved_goto, p.tokSlice(item.unresolved_goto));
+            }
+            if (p.computed_goto_tok) |goto_tok| {
+                if (!p.contains_address_of_label) try p.errTok(.invalid_computed_goto, goto_tok);
+            }
+            p.labels.items.len = 0;
+            p.label_count = 0;
+            p.contains_address_of_label = false;
+            p.computed_goto_tok = null;
+        }
+        return true;
+    }
+
+    // Declare all variable/typedef declarators.
+    while (true) {
+        if (init_d.d.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
+        const tag = try decl_spec.validate(p, &init_d.d.ty, init_d.initializer.node != .none);
+
+        const node = try p.addNode(.{ .ty = init_d.d.ty, .tag = tag, .data = .{
+            .decl = .{ .name = init_d.d.name, .node = init_d.initializer.node },
+        } });
+        try p.decl_buf.append(node);
+
+        const interned_name = try p.comp.intern(p.tokSlice(init_d.d.name));
+        if (decl_spec.storage_class == .typedef) {
+            try p.syms.defineTypedef(p, interned_name, init_d.d.ty, init_d.d.name, node);
+            p.typedefDefined(interned_name, init_d.d.ty);
+        } else if (init_d.initializer.node != .none or
+            (p.func.ty != null and decl_spec.storage_class != .@"extern"))
+        {
+            // TODO validate global variable/constexpr initializer comptime known
+            try p.syms.defineSymbol(
+                p,
+                interned_name,
+                init_d.d.ty,
+                init_d.d.name,
+                node,
+                if (init_d.d.ty.isConst() or decl_spec.constexpr != null) init_d.initializer.val else .{},
+                decl_spec.constexpr != null,
+            );
+        } else {
+            try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, node);
+        }
+
+        if (p.eatToken(.comma) == null) break;
+
+        if (decl_spec.auto_type) |tok_i| try p.errTok(.auto_type_requires_single_declarator, tok_i);
+
+        init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse {
+            try p.err(.expected_ident_or_l_paren);
+            continue;
+        };
+    }
+
+    _ = try p.expectToken(.semicolon);
+    return true;
+}
+
+fn staticAssertMessage(p: *Parser, cond_node: NodeIndex, message: Result) !?[]const u8 {
+    const cond_tag = p.nodes.items(.tag)[@intFromEnum(cond_node)];
+    if (cond_tag != .builtin_types_compatible_p and message.node == .none) return null;
+
+    var buf = std.ArrayList(u8).init(p.gpa);
+    defer buf.deinit();
+
+    if (cond_tag == .builtin_types_compatible_p) {
+        const mapper = p.comp.string_interner.getSlowTypeMapper();
+        const data = p.nodes.items(.data)[@intFromEnum(cond_node)].bin;
+
+        try buf.appendSlice("'__builtin_types_compatible_p(");
+
+        const lhs_ty = p.nodes.items(.ty)[@intFromEnum(data.lhs)];
+        try lhs_ty.print(mapper, p.comp.langopts, buf.writer());
+        try buf.appendSlice(", ");
+
+        const rhs_ty = p.nodes.items(.ty)[@intFromEnum(data.rhs)];
+        try rhs_ty.print(mapper, p.comp.langopts, buf.writer());
+
+        try buf.appendSlice(")'");
+    }
+    if (message.node != .none) {
+        if (buf.items.len > 0) {
+            try buf.append(' ');
+        }
+        const data = message.val.data.bytes;
+        try buf.ensureUnusedCapacity(data.len());
+        try Tree.dumpStr(
+            p.retained_strings.items,
+            data,
+            p.nodes.items(.tag)[@intFromEnum(message.node)],
+            buf.writer(),
+        );
+    }
+    return try p.comp.diag.arena.allocator().dupe(u8, buf.items);
+}
+
+/// staticAssert
+///    : keyword_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';'
+///    | keyword_c23_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';'
+fn staticAssert(p: *Parser) Error!bool {
+    const static_assert = p.eatToken(.keyword_static_assert) orelse p.eatToken(.keyword_c23_static_assert) orelse return false;
+    const l_paren = try p.expectToken(.l_paren);
+    const res_token = p.tok_i;
+    var res = try p.constExpr(.gnu_folding_extension);
+    const res_node = res.node;
+    const str = if (p.eatToken(.comma) != null)
+        switch (p.tok_ids[p.tok_i]) {
+            .string_literal,
+            .string_literal_utf_16,
+            .string_literal_utf_8,
+            .string_literal_utf_32,
+            .string_literal_wide,
+            => try p.stringLiteral(),
+            else => {
+                try p.err(.expected_str_literal);
+                return error.ParsingFailed;
+            },
+        }
+    else
+        Result{};
+    try p.expectClosing(l_paren, .r_paren);
+    _ = try p.expectToken(.semicolon);
+    if (str.node == .none) {
+        try p.errTok(.static_assert_missing_message, static_assert);
+        try p.errStr(.pre_c2x_compat, static_assert, "'_Static_assert' with no message");
+    }
+
+    // Array will never be zero; a value of zero for a pointer is a null pointer constant
+    if ((res.ty.isArray() or res.ty.isPtr()) and !res.val.isZero()) {
+        const err_start = p.comp.diag.list.items.len;
+        try p.errTok(.const_decl_folded, res_token);
+        if (res.ty.isPtr() and err_start != p.comp.diag.list.items.len) {
+            // Don't show the note if the .const_decl_folded diagnostic was not added
+            try p.errTok(.constant_expression_conversion_not_allowed, res_token);
+        }
+    }
+    try res.boolCast(p, .{ .specifier = .bool }, res_token);
+    if (res.val.tag == .unavailable) {
+        if (res.ty.specifier != .invalid) {
+            try p.errTok(.static_assert_not_constant, res_token);
+        }
+    } else {
+        if (!res.val.getBool()) {
+            if (try p.staticAssertMessage(res_node, str)) |message| {
+                try p.errStr(.static_assert_failure_message, static_assert, message);
+            } else {
+                try p.errTok(.static_assert_failure, static_assert);
+            }
+        }
+    }
+
+    const node = try p.addNode(.{
+        .tag = .static_assert,
+        .data = .{ .bin = .{
+            .lhs = res.node,
+            .rhs = str.node,
+        } },
+    });
+    try p.decl_buf.append(node);
+    return true;
+}
+
+pub const DeclSpec = struct {
+    storage_class: union(enum) {
+        auto: TokenIndex,
+        @"extern": TokenIndex,
+        register: TokenIndex,
+        static: TokenIndex,
+        typedef: TokenIndex,
+        none,
+    } = .none,
+    thread_local: ?TokenIndex = null,
+    constexpr: ?TokenIndex = null,
+    @"inline": ?TokenIndex = null,
+    noreturn: ?TokenIndex = null,
+    auto_type: ?TokenIndex = null,
+    ty: Type,
+
+    fn validateParam(d: DeclSpec, p: *Parser, ty: *Type) Error!void {
+        switch (d.storage_class) {
+            .none => {},
+            .register => ty.qual.register = true,
+            .auto, .@"extern", .static, .typedef => |tok_i| try p.errTok(.invalid_storage_on_param, tok_i),
+        }
+        if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
+        if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline");
+        if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn");
+        if (d.constexpr) |tok_i| try p.errTok(.invalid_storage_on_param, tok_i);
+        if (d.auto_type) |tok_i| {
+            try p.errStr(.auto_type_not_allowed, tok_i, "function prototype");
+            ty.* = Type.invalid;
+        }
+    }
+
+    fn validateFnDef(d: DeclSpec, p: *Parser) Error!Tree.Tag {
+        switch (d.storage_class) {
+            .none, .@"extern", .static => {},
+            .auto, .register, .typedef => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i),
+        }
+        if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
+        if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i);
+
+        const is_static = d.storage_class == .static;
+        const is_inline = d.@"inline" != null;
+        if (is_static) {
+            if (is_inline) return .inline_static_fn_def;
+            return .static_fn_def;
+        } else {
+            if (is_inline) return .inline_fn_def;
+            return .fn_def;
+        }
+    }
+
+    fn validate(d: DeclSpec, p: *Parser, ty: *Type, has_init: bool) Error!Tree.Tag {
+        const is_static = d.storage_class == .static;
+        if (ty.isFunc() and d.storage_class != .typedef) {
+            switch (d.storage_class) {
+                .none, .@"extern" => {},
+                .static => |tok_i| if (p.func.ty != null) try p.errTok(.static_func_not_global, tok_i),
+                .typedef => unreachable,
+                .auto, .register => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i),
+            }
+            if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
+            if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i);
+
+            const is_inline = d.@"inline" != null;
+            if (is_static) {
+                if (is_inline) return .inline_static_fn_proto;
+                return .static_fn_proto;
+            } else {
+                if (is_inline) return .inline_fn_proto;
+                return .fn_proto;
+            }
+        } else {
+            if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline");
+            // TODO move to attribute validation
+            if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn");
+            switch (d.storage_class) {
+                .auto, .register => if (p.func.ty == null) try p.err(.illegal_storage_on_global),
+                .typedef => return .typedef,
+                else => {},
+            }
+            ty.qual.register = d.storage_class == .register;
+
+            const is_extern = d.storage_class == .@"extern" and !has_init;
+            if (d.thread_local != null) {
+                if (is_static) return .threadlocal_static_var;
+                if (is_extern) return .threadlocal_extern_var;
+                return .threadlocal_var;
+            } else {
+                if (is_static) return .static_var;
+                if (is_extern) return .extern_var;
+                return .@"var";
+            }
+        }
+    }
+};
+
+/// typeof
+///   : keyword_typeof '(' typeName ')'
+///   | keyword_typeof '(' expr ')'
+fn typeof(p: *Parser) Error!?Type {
+    switch (p.tok_ids[p.tok_i]) {
+        .keyword_typeof, .keyword_typeof1, .keyword_typeof2 => p.tok_i += 1,
+        else => return null,
+    }
+    const l_paren = try p.expectToken(.l_paren);
+    if (try p.typeName()) |ty| {
+        try p.expectClosing(l_paren, .r_paren);
+        const typeof_ty = try p.arena.create(Type);
+        typeof_ty.* = .{
+            .data = ty.data,
+            .qual = ty.qual.inheritFromTypeof(),
+            .specifier = ty.specifier,
+        };
+
+        return Type{
+            .data = .{ .sub_type = typeof_ty },
+            .specifier = .typeof_type,
+        };
+    }
+    const typeof_expr = try p.parseNoEval(expr);
+    try typeof_expr.expect(p);
+    try p.expectClosing(l_paren, .r_paren);
+    // Special case nullptr_t since it's defined as typeof(nullptr)
+    if (typeof_expr.ty.is(.nullptr_t)) {
+        return Type{ .specifier = .nullptr_t, .qual = typeof_expr.ty.qual.inheritFromTypeof() };
+    }
+
+    const inner = try p.arena.create(Type.Expr);
+    inner.* = .{
+        .node = typeof_expr.node,
+        .ty = .{
+            .data = typeof_expr.ty.data,
+            .qual = typeof_expr.ty.qual.inheritFromTypeof(),
+            .specifier = typeof_expr.ty.specifier,
+        },
+    };
+
+    return Type{
+        .data = .{ .expr = inner },
+        .specifier = .typeof_expr,
+    };
+}
+
+/// declSpec: (storageClassSpec | typeSpec | typeQual | funcSpec | alignSpec)+
+/// storageClassSpec:
+///  : keyword_typedef
+///  | keyword_extern
+///  | keyword_static
+///  | keyword_threadlocal
+///  | keyword_auto
+///  | keyword_register
+/// funcSpec : keyword_inline | keyword_noreturn
+fn declSpec(p: *Parser) Error!?DeclSpec {
+    var d: DeclSpec = .{ .ty = .{ .specifier = undefined } };
+    var spec: Type.Builder = .{};
+
+    const start = p.tok_i;
+    while (true) {
+        if (try p.typeSpec(&spec)) continue;
+        const id = p.tok_ids[p.tok_i];
+        switch (id) {
+            .keyword_typedef,
+            .keyword_extern,
+            .keyword_static,
+            .keyword_auto,
+            .keyword_register,
+            => {
+                if (d.storage_class != .none) {
+                    try p.errStr(.multiple_storage_class, p.tok_i, @tagName(d.storage_class));
+                    return error.ParsingFailed;
+                }
+                if (d.thread_local != null) {
+                    switch (id) {
+                        .keyword_extern, .keyword_static => {},
+                        else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?),
+                    }
+                    if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
+                }
+                if (d.constexpr != null) {
+                    switch (id) {
+                        .keyword_auto, .keyword_register, .keyword_static => {},
+                        else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?),
+                    }
+                    if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
+                }
+                switch (id) {
+                    .keyword_typedef => d.storage_class = .{ .typedef = p.tok_i },
+                    .keyword_extern => d.storage_class = .{ .@"extern" = p.tok_i },
+                    .keyword_static => d.storage_class = .{ .static = p.tok_i },
+                    .keyword_auto => d.storage_class = .{ .auto = p.tok_i },
+                    .keyword_register => d.storage_class = .{ .register = p.tok_i },
+                    else => unreachable,
+                }
+            },
+            .keyword_thread_local,
+            .keyword_c23_thread_local,
+            => {
+                if (d.thread_local != null) {
+                    try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?);
+                }
+                if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
+                switch (d.storage_class) {
+                    .@"extern", .none, .static => {},
+                    else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)),
+                }
+                d.thread_local = p.tok_i;
+            },
+            .keyword_constexpr => {
+                if (d.constexpr != null) {
+                    try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?);
+                }
+                if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
+                switch (d.storage_class) {
+                    .auto, .register, .none, .static => {},
+                    else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)),
+                }
+                d.constexpr = p.tok_i;
+            },
+            .keyword_inline, .keyword_inline1, .keyword_inline2 => {
+                if (d.@"inline" != null) {
+                    try p.errStr(.duplicate_decl_spec, p.tok_i, "inline");
+                }
+                d.@"inline" = p.tok_i;
+            },
+            .keyword_noreturn => {
+                if (d.noreturn != null) {
+                    try p.errStr(.duplicate_decl_spec, p.tok_i, "_Noreturn");
+                }
+                d.noreturn = p.tok_i;
+            },
+            else => break,
+        }
+        p.tok_i += 1;
+    }
+
+    if (p.tok_i == start) return null;
+
+    d.ty = try spec.finish(p);
+    d.auto_type = spec.auto_type_tok;
+    return d;
+}
+
+const InitDeclarator = struct { d: Declarator, initializer: Result = .{} };
+
+/// attribute
+///  : attrIdentifier
+///  | attrIdentifier '(' identifier ')'
+///  | attrIdentifier '(' identifier (',' expr)+ ')'
+///  | attrIdentifier '(' (expr (',' expr)*)? ')'
+fn attribute(p: *Parser, kind: Attribute.Kind, namespace: ?[]const u8) Error!?TentativeAttribute {
+    const name_tok = p.tok_i;
+    switch (p.tok_ids[p.tok_i]) {
+        .keyword_const, .keyword_const1, .keyword_const2 => p.tok_i += 1,
+        else => _ = try p.expectIdentifier(),
+    }
+    const name = p.tokSlice(name_tok);
+
+    const attr = Attribute.fromString(kind, namespace, name) orelse {
+        const tag: Diagnostics.Tag = if (kind == .declspec) .declspec_attr_not_supported else .unknown_attribute;
+        try p.errStr(tag, name_tok, name);
+        if (p.eatToken(.l_paren)) |_| p.skipTo(.r_paren);
+        return null;
+    };
+
+    const required_count = Attribute.requiredArgCount(attr);
+    var arguments = Attribute.initArguments(attr, name_tok);
+    var arg_idx: u32 = 0;
+
+    switch (p.tok_ids[p.tok_i]) {
+        .comma, .r_paren => {}, // will be consumed in attributeList
+        .l_paren => blk: {
+            p.tok_i += 1;
+            if (p.eatToken(.r_paren)) |_| break :blk;
+
+            if (Attribute.wantsIdentEnum(attr)) {
+                if (try p.eatIdentifier()) |ident| {
+                    if (Attribute.diagnoseIdent(attr, &arguments, p.tokSlice(ident))) |msg| {
+                        try p.errExtra(msg.tag, ident, msg.extra);
+                        p.skipTo(.r_paren);
+                        return error.ParsingFailed;
+                    }
+                } else {
+                    try p.errExtra(.attribute_requires_identifier, name_tok, .{ .str = name });
+                    return error.ParsingFailed;
+                }
+            } else {
+                const arg_start = p.tok_i;
+                var first_expr = try p.assignExpr();
+                try first_expr.expect(p);
+                if (p.diagnose(attr, &arguments, arg_idx, first_expr)) |msg| {
+                    try p.errExtra(msg.tag, arg_start, msg.extra);
+                    p.skipTo(.r_paren);
+                    return error.ParsingFailed;
+                }
+            }
+            arg_idx += 1;
+            while (p.eatToken(.r_paren) == null) : (arg_idx += 1) {
+                _ = try p.expectToken(.comma);
+
+                const arg_start = p.tok_i;
+                var arg_expr = try p.assignExpr();
+                try arg_expr.expect(p);
+                if (p.diagnose(attr, &arguments, arg_idx, arg_expr)) |msg| {
+                    try p.errExtra(msg.tag, arg_start, msg.extra);
+                    p.skipTo(.r_paren);
+                    return error.ParsingFailed;
+                }
+            }
+        },
+        else => {},
+    }
+    if (arg_idx < required_count) {
+        try p.errExtra(.attribute_not_enough_args, name_tok, .{ .attr_arg_count = .{ .attribute = attr, .expected = required_count } });
+        return error.ParsingFailed;
+    }
+    return TentativeAttribute{ .attr = .{ .tag = attr, .args = arguments, .syntax = kind.toSyntax() }, .tok = name_tok };
+}
+
+fn diagnose(p: *Parser, attr: Attribute.Tag, arguments: *Attribute.Arguments, arg_idx: u32, res: Result) ?Diagnostics.Message {
+    if (Attribute.wantsAlignment(attr, arg_idx)) {
+        return Attribute.diagnoseAlignment(attr, arguments, arg_idx, res.val, res.ty, p.comp);
+    }
+    const node = p.nodes.get(@intFromEnum(res.node));
+    return Attribute.diagnose(attr, arguments, arg_idx, res.val, node, p.retained_strings.items);
+}
+
+/// attributeList : (attribute (',' attribute)*)?
+fn gnuAttributeList(p: *Parser) Error!void {
+    if (p.tok_ids[p.tok_i] == .r_paren) return;
+
+    if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr);
+    while (p.tok_ids[p.tok_i] != .r_paren) {
+        _ = try p.expectToken(.comma);
+        if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr);
+    }
+}
+
+fn c2xAttributeList(p: *Parser) Error!void {
+    while (p.tok_ids[p.tok_i] != .r_bracket) {
+        var namespace_tok = try p.expectIdentifier();
+        var namespace: ?[]const u8 = null;
+        if (p.eatToken(.colon_colon)) |_| {
+            namespace = p.tokSlice(namespace_tok);
+        } else {
+            p.tok_i -= 1;
+        }
+        if (try p.attribute(.c2x, namespace)) |attr| try p.attr_buf.append(p.gpa, attr);
+        _ = p.eatToken(.comma);
+    }
+}
+
+fn msvcAttributeList(p: *Parser) Error!void {
+    while (p.tok_ids[p.tok_i] != .r_paren) {
+        if (try p.attribute(.declspec, null)) |attr| try p.attr_buf.append(p.gpa, attr);
+        _ = p.eatToken(.comma);
+    }
+}
+
+fn c2xAttribute(p: *Parser) !bool {
+    if (!p.comp.langopts.standard.atLeast(.c2x)) return false;
+    const bracket1 = p.eatToken(.l_bracket) orelse return false;
+    const bracket2 = p.eatToken(.l_bracket) orelse {
+        p.tok_i -= 1;
+        return false;
+    };
+
+    try p.c2xAttributeList();
+
+    _ = try p.expectClosing(bracket2, .r_bracket);
+    _ = try p.expectClosing(bracket1, .r_bracket);
+
+    return true;
+}
+
+fn msvcAttribute(p: *Parser) !bool {
+    _ = p.eatToken(.keyword_declspec) orelse return false;
+    const l_paren = try p.expectToken(.l_paren);
+    try p.msvcAttributeList();
+    _ = try p.expectClosing(l_paren, .r_paren);
+
+    return true;
+}
+
+fn gnuAttribute(p: *Parser) !bool {
+    switch (p.tok_ids[p.tok_i]) {
+        .keyword_attribute1, .keyword_attribute2 => p.tok_i += 1,
+        else => return false,
+    }
+    const paren1 = try p.expectToken(.l_paren);
+    const paren2 = try p.expectToken(.l_paren);
+
+    try p.gnuAttributeList();
+
+    _ = try p.expectClosing(paren2, .r_paren);
+    _ = try p.expectClosing(paren1, .r_paren);
+    return true;
+}
+
+fn attributeSpecifier(p: *Parser) Error!void {
+    return attributeSpecifierExtra(p, null);
+}
+
+/// attributeSpecifier : (keyword_attribute '( '(' attributeList ')' ')')*
+fn attributeSpecifierExtra(p: *Parser, declarator_name: ?TokenIndex) Error!void {
+    while (true) {
+        if (try p.gnuAttribute()) continue;
+        if (try p.c2xAttribute()) continue;
+        const maybe_declspec_tok = p.tok_i;
+        const attr_buf_top = p.attr_buf.len;
+        if (try p.msvcAttribute()) {
+            if (declarator_name) |name_tok| {
+                try p.errTok(.declspec_not_allowed_after_declarator, maybe_declspec_tok);
+                try p.errTok(.declarator_name_tok, name_tok);
+                p.attr_buf.len = attr_buf_top;
+            }
+            continue;
+        }
+        break;
+    }
+}
+
+/// initDeclarator : declarator assembly? attributeSpecifier? ('=' initializer)?
+fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize) Error!?InitDeclarator {
+    const this_attr_buf_top = p.attr_buf.len;
+    defer p.attr_buf.len = this_attr_buf_top;
+
+    var init_d = InitDeclarator{
+        .d = (try p.declarator(decl_spec.ty, .normal)) orelse return null,
+    };
+
+    try p.attributeSpecifierExtra(init_d.d.name);
+    _ = try p.assembly(.decl_label);
+    try p.attributeSpecifierExtra(init_d.d.name);
+
+    var apply_var_attributes = false;
+    if (decl_spec.storage_class == .typedef) {
+        if (decl_spec.auto_type) |tok_i| {
+            try p.errStr(.auto_type_not_allowed, tok_i, "typedef");
+            return error.ParsingFailed;
+        }
+        init_d.d.ty = try Attribute.applyTypeAttributes(p, init_d.d.ty, attr_buf_top, null);
+    } else if (init_d.d.ty.isFunc()) {
+        init_d.d.ty = try Attribute.applyFunctionAttributes(p, init_d.d.ty, attr_buf_top);
+    } else {
+        apply_var_attributes = true;
+    }
+
+    if (p.eatToken(.equal)) |eq| init: {
+        if (decl_spec.storage_class == .typedef or init_d.d.func_declarator != null) {
+            try p.errTok(.illegal_initializer, eq);
+        } else if (init_d.d.ty.is(.variable_len_array)) {
+            try p.errTok(.vla_init, eq);
+        } else if (decl_spec.storage_class == .@"extern") {
+            try p.err(.extern_initializer);
+            decl_spec.storage_class = .none;
+        }
+
+        if (init_d.d.ty.hasIncompleteSize() and !init_d.d.ty.is(.incomplete_array)) {
+            try p.errStr(.variable_incomplete_ty, init_d.d.name, try p.typeStr(init_d.d.ty));
+            return error.ParsingFailed;
+        }
+
+        try p.syms.pushScope(p);
+        defer p.syms.popScope();
+
+        const interned_name = try p.comp.intern(p.tokSlice(init_d.d.name));
+        try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, .none);
+        var init_list_expr = try p.initializer(init_d.d.ty);
+        init_d.initializer = init_list_expr;
+        if (!init_list_expr.ty.isArray()) break :init;
+        if (init_d.d.ty.specifier == .incomplete_array) {
+            // Modifying .data is exceptionally allowed for .incomplete_array.
+            init_d.d.ty.data.array.len = init_list_expr.ty.arrayLen() orelse break :init;
+            init_d.d.ty.specifier = .array;
+        }
+    }
+
+    const name = init_d.d.name;
+    if (init_d.d.ty.is(.auto_type)) {
+        if (init_d.initializer.node == .none) {
+            init_d.d.ty = Type.invalid;
+            try p.errStr(.auto_type_requires_initializer, name, p.tokSlice(name));
+            return init_d;
+        } else {
+            init_d.d.ty.specifier = init_d.initializer.ty.specifier;
+            init_d.d.ty.data = init_d.initializer.ty.data;
+        }
+    }
+    if (apply_var_attributes) {
+        init_d.d.ty = try Attribute.applyVariableAttributes(p, init_d.d.ty, attr_buf_top, null);
+    }
+    if (decl_spec.storage_class != .typedef and init_d.d.ty.hasIncompleteSize()) incomplete: {
+        const specifier = init_d.d.ty.canonicalize(.standard).specifier;
+        if (decl_spec.storage_class == .@"extern") switch (specifier) {
+            .@"struct", .@"union", .@"enum" => break :incomplete,
+            .incomplete_array => {
+                init_d.d.ty.decayArray();
+                break :incomplete;
+            },
+            else => {},
+        };
+        // if there was an initializer expression it must have contained an error
+        if (init_d.initializer.node != .none) break :incomplete;
+
+        if (p.func.ty == null) {
+            if (specifier == .incomplete_array) {
+                // TODO properly check this after finishing parsing
+                try p.errStr(.tentative_array, name, try p.typeStr(init_d.d.ty));
+                break :incomplete;
+            } else if (init_d.d.ty.getRecord()) |record| {
+                _ = try p.tentative_defs.getOrPutValue(p.comp.gpa, record.name, init_d.d.name);
+                break :incomplete;
+            } else if (init_d.d.ty.get(.@"enum")) |en| {
+                _ = try p.tentative_defs.getOrPutValue(p.comp.gpa, en.data.@"enum".name, init_d.d.name);
+                break :incomplete;
+            }
+        }
+        try p.errStr(.variable_incomplete_ty, name, try p.typeStr(init_d.d.ty));
+    }
+    return init_d;
+}
+
+/// typeSpec
+///  : keyword_void
+///  | keyword_auto_type
+///  | keyword_char
+///  | keyword_short
+///  | keyword_int
+///  | keyword_long
+///  | keyword_float
+///  | keyword_double
+///  | keyword_signed
+///  | keyword_unsigned
+///  | keyword_bool
+///  | keyword_c23_bool
+///  | keyword_complex
+///  | atomicTypeSpec
+///  | recordSpec
+///  | enumSpec
+///  | typedef  // IDENTIFIER
+///  | typeof
+///  | keyword_bit_int '(' integerConstExpr ')'
+/// atomicTypeSpec : keyword_atomic '(' typeName ')'
+/// alignSpec
+///   : keyword_alignas '(' typeName ')'
+///   | keyword_alignas '(' integerConstExpr ')'
+///   | keyword_c23_alignas '(' typeName ')'
+///   | keyword_c23_alignas '(' integerConstExpr ')'
+fn typeSpec(p: *Parser, ty: *Type.Builder) Error!bool {
+    const start = p.tok_i;
+    while (true) {
+        try p.attributeSpecifier();
+
+        if (try p.typeof()) |inner_ty| {
+            try ty.combineFromTypeof(p, inner_ty, start);
+            continue;
+        }
+        if (try p.typeQual(&ty.qual)) continue;
+        switch (p.tok_ids[p.tok_i]) {
+            .keyword_void => try ty.combine(p, .void, p.tok_i),
+            .keyword_auto_type => {
+                try p.errTok(.auto_type_extension, p.tok_i);
+                try ty.combine(p, .auto_type, p.tok_i);
+            },
+            .keyword_bool, .keyword_c23_bool => try ty.combine(p, .bool, p.tok_i),
+            .keyword_int8, .keyword_int8_2, .keyword_char => try ty.combine(p, .char, p.tok_i),
+            .keyword_int16, .keyword_int16_2, .keyword_short => try ty.combine(p, .short, p.tok_i),
+            .keyword_int32, .keyword_int32_2, .keyword_int => try ty.combine(p, .int, p.tok_i),
+            .keyword_long => try ty.combine(p, .long, p.tok_i),
+            .keyword_int64, .keyword_int64_2 => try ty.combine(p, .long_long, p.tok_i),
+            .keyword_int128 => try ty.combine(p, .int128, p.tok_i),
+            .keyword_signed => try ty.combine(p, .signed, p.tok_i),
+            .keyword_unsigned => try ty.combine(p, .unsigned, p.tok_i),
+            .keyword_fp16 => try ty.combine(p, .fp16, p.tok_i),
+            .keyword_float16 => try ty.combine(p, .float16, p.tok_i),
+            .keyword_float => try ty.combine(p, .float, p.tok_i),
+            .keyword_double => try ty.combine(p, .double, p.tok_i),
+            .keyword_complex => try ty.combine(p, .complex, p.tok_i),
+            .keyword_float80 => try ty.combine(p, .float80, p.tok_i),
+            .keyword_float128 => try ty.combine(p, .float128, p.tok_i),
+            .keyword_atomic => {
+                const atomic_tok = p.tok_i;
+                p.tok_i += 1;
+                const l_paren = p.eatToken(.l_paren) orelse {
+                    // _Atomic qualifier not _Atomic(typeName)
+                    p.tok_i = atomic_tok;
+                    break;
+                };
+                const inner_ty = (try p.typeName()) orelse {
+                    try p.err(.expected_type);
+                    return error.ParsingFailed;
+                };
+                try p.expectClosing(l_paren, .r_paren);
+
+                const new_spec = Type.Builder.fromType(inner_ty);
+                try ty.combine(p, new_spec, atomic_tok);
+
+                if (ty.qual.atomic != null)
+                    try p.errStr(.duplicate_decl_spec, atomic_tok, "atomic")
+                else
+                    ty.qual.atomic = atomic_tok;
+                continue;
+            },
+            .keyword_alignas,
+            .keyword_c23_alignas,
+            => {
+                const align_tok = p.tok_i;
+                p.tok_i += 1;
+                const l_paren = try p.expectToken(.l_paren);
+                const typename_start = p.tok_i;
+                if (try p.typeName()) |inner_ty| {
+                    if (!inner_ty.alignable()) {
+                        try p.errStr(.invalid_alignof, typename_start, try p.typeStr(inner_ty));
+                    }
+                    const alignment = Attribute.Alignment{ .requested = inner_ty.alignof(p.comp) };
+                    try p.attr_buf.append(p.gpa, .{
+                        .attr = .{ .tag = .aligned, .args = .{
+                            .aligned = .{ .alignment = alignment, .__name_tok = align_tok },
+                        }, .syntax = .keyword },
+                        .tok = align_tok,
+                    });
+                } else {
+                    const arg_start = p.tok_i;
+                    const res = try p.integerConstExpr(.no_const_decl_folding);
+                    if (!res.val.isZero()) {
+                        var args = Attribute.initArguments(.aligned, align_tok);
+                        if (p.diagnose(.aligned, &args, 0, res)) |msg| {
+                            try p.errExtra(msg.tag, arg_start, msg.extra);
+                            p.skipTo(.r_paren);
+                            return error.ParsingFailed;
+                        }
+                        args.aligned.alignment.?.node = res.node;
+                        try p.attr_buf.append(p.gpa, .{
+                            .attr = .{ .tag = .aligned, .args = args, .syntax = .keyword },
+                            .tok = align_tok,
+                        });
+                    }
+                }
+                try p.expectClosing(l_paren, .r_paren);
+                continue;
+            },
+            .keyword_stdcall,
+            .keyword_stdcall2,
+            .keyword_thiscall,
+            .keyword_thiscall2,
+            .keyword_vectorcall,
+            .keyword_vectorcall2,
+            => try p.attr_buf.append(p.gpa, .{
+                .attr = .{ .tag = .calling_convention, .args = .{
+                    .calling_convention = .{ .cc = switch (p.tok_ids[p.tok_i]) {
+                        .keyword_stdcall,
+                        .keyword_stdcall2,
+                        => .stdcall,
+                        .keyword_thiscall,
+                        .keyword_thiscall2,
+                        => .thiscall,
+                        .keyword_vectorcall,
+                        .keyword_vectorcall2,
+                        => .vectorcall,
+                        else => unreachable,
+                    } },
+                }, .syntax = .keyword },
+                .tok = p.tok_i,
+            }),
+            .keyword_struct, .keyword_union => {
+                const tag_tok = p.tok_i;
+                const record_ty = try p.recordSpec();
+                try ty.combine(p, Type.Builder.fromType(record_ty), tag_tok);
+                continue;
+            },
+            .keyword_enum => {
+                const tag_tok = p.tok_i;
+                const enum_ty = try p.enumSpec();
+                try ty.combine(p, Type.Builder.fromType(enum_ty), tag_tok);
+                continue;
+            },
+            .identifier, .extended_identifier => {
+                var interned_name = try p.comp.intern(p.tokSlice(p.tok_i));
+                var declspec_found = false;
+
+                if (interned_name == p.string_ids.declspec_id) {
+                    try p.errTok(.declspec_not_enabled, p.tok_i);
+                    p.tok_i += 1;
+                    if (p.eatToken(.l_paren)) |_| {
+                        p.skipTo(.r_paren);
+                        continue;
+                    }
+                    declspec_found = true;
+                }
+                if (ty.typedef != null) break;
+                if (declspec_found) {
+                    interned_name = try p.comp.intern(p.tokSlice(p.tok_i));
+                }
+                const typedef = (try p.syms.findTypedef(p, interned_name, p.tok_i, ty.specifier != .none)) orelse break;
+                if (!ty.combineTypedef(p, typedef.ty, typedef.tok)) break;
+            },
+            .keyword_bit_int => {
+                try p.err(.bit_int);
+                const bit_int_tok = p.tok_i;
+                p.tok_i += 1;
+                const l_paren = try p.expectToken(.l_paren);
+                const res = try p.integerConstExpr(.gnu_folding_extension);
+                try p.expectClosing(l_paren, .r_paren);
+
+                var bits: i16 = undefined;
+                if (res.val.tag == .unavailable) {
+                    try p.errTok(.expected_integer_constant_expr, bit_int_tok);
+                    return error.ParsingFailed;
+                } else if (res.val.compare(.lte, Value.int(0), res.ty, p.comp)) {
+                    bits = -1;
+                } else if (res.val.compare(.gt, Value.int(128), res.ty, p.comp)) {
+                    bits = 129;
+                } else {
+                    bits = res.val.getInt(i16);
+                }
+
+                try ty.combine(p, .{ .bit_int = bits }, bit_int_tok);
+                continue;
+            },
+            else => break,
+        }
+        // consume single token specifiers here
+        p.tok_i += 1;
+    }
+    return p.tok_i != start;
+}
+
+fn getAnonymousName(p: *Parser, kind_tok: TokenIndex) !StringId {
+    const loc = p.pp.tokens.items(.loc)[kind_tok];
+    const source = p.comp.getSource(loc.id);
+    const line_col = source.lineCol(loc);
+
+    const kind_str = switch (p.tok_ids[kind_tok]) {
+        .keyword_struct, .keyword_union, .keyword_enum => p.tokSlice(kind_tok),
+        else => "record field",
+    };
+
+    const str = try std.fmt.allocPrint(
+        p.arena,
+        "(anonymous {s} at {s}:{d}:{d})",
+        .{ kind_str, source.path, line_col.line_no, line_col.col },
+    );
+    return p.comp.intern(str);
+}
+
+/// recordSpec
+///  : (keyword_struct | keyword_union) IDENTIFIER? { recordDecl* }
+///  | (keyword_struct | keyword_union) IDENTIFIER
+fn recordSpec(p: *Parser) Error!Type {
+    const starting_pragma_pack = p.pragma_pack;
+    const kind_tok = p.tok_i;
+    const is_struct = p.tok_ids[kind_tok] == .keyword_struct;
+    p.tok_i += 1;
+    const attr_buf_top = p.attr_buf.len;
+    defer p.attr_buf.len = attr_buf_top;
+    try p.attributeSpecifier();
+
+    const maybe_ident = try p.eatIdentifier();
+    const l_brace = p.eatToken(.l_brace) orelse {
+        const ident = maybe_ident orelse {
+            try p.err(.ident_or_l_brace);
+            return error.ParsingFailed;
+        };
+        // check if this is a reference to a previous type
+        const interned_name = try p.comp.intern(p.tokSlice(ident));
+        if (try p.syms.findTag(p, interned_name, p.tok_ids[kind_tok], ident, p.tok_ids[p.tok_i])) |prev| {
+            return prev.ty;
+        } else {
+            // this is a forward declaration, create a new record Type.
+            const record_ty = try Type.Record.create(p.arena, interned_name);
+            const ty = try Attribute.applyTypeAttributes(p, .{
+                .specifier = if (is_struct) .@"struct" else .@"union",
+                .data = .{ .record = record_ty },
+            }, attr_buf_top, null);
+            try p.syms.syms.append(p.gpa, .{
+                .kind = if (is_struct) .@"struct" else .@"union",
+                .name = interned_name,
+                .tok = ident,
+                .ty = ty,
+                .val = .{},
+            });
+            try p.decl_buf.append(try p.addNode(.{
+                .tag = if (is_struct) .struct_forward_decl else .union_forward_decl,
+                .ty = ty,
+                .data = .{ .decl_ref = ident },
+            }));
+            return ty;
+        }
+    };
+
+    var done = false;
+    errdefer if (!done) p.skipTo(.r_brace);
+
+    // Get forward declared type or create a new one
+    var defined = false;
+    const record_ty: *Type.Record = if (maybe_ident) |ident| record_ty: {
+        const ident_str = p.tokSlice(ident);
+        const interned_name = try p.comp.intern(ident_str);
+        if (try p.syms.defineTag(p, interned_name, p.tok_ids[kind_tok], ident)) |prev| {
+            if (!prev.ty.hasIncompleteSize()) {
+                // if the record isn't incomplete, this is a redefinition
+                try p.errStr(.redefinition, ident, ident_str);
+                try p.errTok(.previous_definition, prev.tok);
+            } else {
+                defined = true;
+                break :record_ty prev.ty.get(if (is_struct) .@"struct" else .@"union").?.data.record;
+            }
+        }
+        break :record_ty try Type.Record.create(p.arena, interned_name);
+    } else try Type.Record.create(p.arena, try p.getAnonymousName(kind_tok));
+
+    // Initially create ty as a regular non-attributed type, since attributes for a record
+    // can be specified after the closing rbrace, which we haven't encountered yet.
+    var ty = Type{
+        .specifier = if (is_struct) .@"struct" else .@"union",
+        .data = .{ .record = record_ty },
+    };
+
+    // declare a symbol for the type
+    // We need to replace the symbol's type if it has attributes
+    var symbol_index: ?usize = null;
+    if (maybe_ident != null and !defined) {
+        symbol_index = p.syms.syms.len;
+        try p.syms.syms.append(p.gpa, .{
+            .kind = if (is_struct) .@"struct" else .@"union",
+            .name = record_ty.name,
+            .tok = maybe_ident.?,
+            .ty = ty,
+            .val = .{},
+        });
+    }
+
+    // reserve space for this record
+    try p.decl_buf.append(.none);
+    const decl_buf_top = p.decl_buf.items.len;
+    const record_buf_top = p.record_buf.items.len;
+    errdefer p.decl_buf.items.len = decl_buf_top - 1;
+    defer {
+        p.decl_buf.items.len = decl_buf_top;
+        p.record_buf.items.len = record_buf_top;
+    }
+
+    const old_record = p.record;
+    const old_members = p.record_members.items.len;
+    const old_field_attr_start = p.field_attr_buf.items.len;
+    p.record = .{
+        .kind = p.tok_ids[kind_tok],
+        .start = p.record_members.items.len,
+        .field_attr_start = p.field_attr_buf.items.len,
+    };
+    defer p.record = old_record;
+    defer p.record_members.items.len = old_members;
+    defer p.field_attr_buf.items.len = old_field_attr_start;
+
+    try p.recordDecls();
+
+    if (p.record.flexible_field) |some| {
+        if (p.record_buf.items[record_buf_top..].len == 1 and is_struct) {
+            try p.errTok(.flexible_in_empty, some);
+        }
+    }
+
+    for (p.record_buf.items[record_buf_top..]) |field| {
+        if (field.ty.hasIncompleteSize() and !field.ty.is(.incomplete_array)) break;
+    } else {
+        record_ty.fields = try p.arena.dupe(Type.Record.Field, p.record_buf.items[record_buf_top..]);
+    }
+    if (old_field_attr_start < p.field_attr_buf.items.len) {
+        const field_attr_slice = p.field_attr_buf.items[old_field_attr_start..];
+        const duped = try p.arena.dupe([]const Attribute, field_attr_slice);
+        record_ty.field_attributes = duped.ptr;
+    }
+
+    if (p.record_buf.items.len == record_buf_top) {
+        try p.errStr(.empty_record, kind_tok, p.tokSlice(kind_tok));
+        try p.errStr(.empty_record_size, kind_tok, p.tokSlice(kind_tok));
+    }
+    try p.expectClosing(l_brace, .r_brace);
+    done = true;
+    try p.attributeSpecifier();
+
+    ty = try Attribute.applyTypeAttributes(p, .{
+        .specifier = if (is_struct) .@"struct" else .@"union",
+        .data = .{ .record = record_ty },
+    }, attr_buf_top, null);
+    if (ty.specifier == .attributed and symbol_index != null) {
+        p.syms.syms.items(.ty)[symbol_index.?] = ty;
+    }
+
+    if (!ty.hasIncompleteSize()) {
+        const pragma_pack_value = switch (p.comp.langopts.emulate) {
+            .clang => starting_pragma_pack,
+            .gcc => p.pragma_pack,
+            // TODO: msvc considers `#pragma pack` on a per-field basis
+            .msvc => p.pragma_pack,
+        };
+        record_layout.compute(record_ty, ty, p.pp.comp, pragma_pack_value);
+    }
+
+    // finish by creating a node
+    var node: Tree.Node = .{
+        .tag = if (is_struct) .struct_decl_two else .union_decl_two,
+        .ty = ty,
+        .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
+    };
+    const record_decls = p.decl_buf.items[decl_buf_top..];
+    switch (record_decls.len) {
+        0 => {},
+        1 => node.data = .{ .bin = .{ .lhs = record_decls[0], .rhs = .none } },
+        2 => node.data = .{ .bin = .{ .lhs = record_decls[0], .rhs = record_decls[1] } },
+        else => {
+            node.tag = if (is_struct) .struct_decl else .union_decl;
+            node.data = .{ .range = try p.addList(record_decls) };
+        },
+    }
+    p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node);
+    if (p.func.ty == null) {
+        _ = p.tentative_defs.remove(record_ty.name);
+    }
+    return ty;
+}
+
+/// recordDecl
+///  : specQual (recordDeclarator (',' recordDeclarator)*)? ;
+///  | staticAssert
+fn recordDecls(p: *Parser) Error!void {
+    while (true) {
+        if (try p.pragma()) continue;
+        if (try p.parseOrNextDecl(staticAssert)) continue;
+        if (p.eatToken(.keyword_extension)) |_| {
+            const saved_extension = p.extension_suppressed;
+            defer p.extension_suppressed = saved_extension;
+            p.extension_suppressed = true;
+
+            if (try p.parseOrNextDecl(recordDeclarator)) continue;
+            try p.err(.expected_type);
+            p.nextExternDecl();
+            continue;
+        }
+        if (try p.parseOrNextDecl(recordDeclarator)) continue;
+        break;
+    }
+}
+
+/// recordDeclarator : keyword_extension? declarator (':' integerConstExpr)?
+fn recordDeclarator(p: *Parser) Error!bool {
+    const attr_buf_top = p.attr_buf.len;
+    defer p.attr_buf.len = attr_buf_top;
+    const base_ty = (try p.specQual()) orelse return false;
+
+    try p.attributeSpecifier(); // .record
+    while (true) {
+        const this_decl_top = p.attr_buf.len;
+        defer p.attr_buf.len = this_decl_top;
+
+        try p.attributeSpecifier();
+
+        // 0 means unnamed
+        var name_tok: TokenIndex = 0;
+        var ty = base_ty;
+        if (ty.is(.auto_type)) {
+            try p.errStr(.auto_type_not_allowed, p.tok_i, if (p.record.kind == .keyword_struct) "struct member" else "union member");
+            ty = Type.invalid;
+        }
+        var bits_node: NodeIndex = .none;
+        var bits: ?u32 = null;
+        const first_tok = p.tok_i;
+        if (try p.declarator(ty, .record)) |d| {
+            name_tok = d.name;
+            ty = d.ty;
+        }
+
+        if (p.eatToken(.colon)) |_| bits: {
+            const bits_tok = p.tok_i;
+            const res = try p.integerConstExpr(.gnu_folding_extension);
+            if (!ty.isInt()) {
+                try p.errStr(.non_int_bitfield, first_tok, try p.typeStr(ty));
+                break :bits;
+            }
+
+            if (res.val.tag == .unavailable) {
+                try p.errTok(.expected_integer_constant_expr, bits_tok);
+                break :bits;
+            } else if (res.val.compare(.lt, Value.int(0), res.ty, p.comp)) {
+                try p.errExtra(.negative_bitwidth, first_tok, .{
+                    .signed = res.val.signExtend(res.ty, p.comp),
+                });
+                break :bits;
+            }
+
+            // incomplete size error is reported later
+            const bit_size = ty.bitSizeof(p.comp) orelse break :bits;
+            if (res.val.compare(.gt, Value.int(bit_size), res.ty, p.comp)) {
+                try p.errTok(.bitfield_too_big, name_tok);
+                break :bits;
+            } else if (res.val.isZero() and name_tok != 0) {
+                try p.errTok(.zero_width_named_field, name_tok);
+                break :bits;
+            }
+
+            bits = res.val.getInt(u32);
+            bits_node = res.node;
+        }
+
+        try p.attributeSpecifier(); // .record
+        const to_append = try Attribute.applyFieldAttributes(p, &ty, attr_buf_top);
+
+        const any_fields_have_attrs = p.field_attr_buf.items.len > p.record.field_attr_start;
+
+        if (any_fields_have_attrs) {
+            try p.field_attr_buf.append(to_append);
+        } else {
+            if (to_append.len > 0) {
+                const preceding = p.record_members.items.len - p.record.start;
+                if (preceding > 0) {
+                    try p.field_attr_buf.appendNTimes(&.{}, preceding);
+                }
+                try p.field_attr_buf.append(to_append);
+            }
+        }
+
+        if (name_tok == 0 and bits_node == .none) unnamed: {
+            if (ty.is(.@"enum") or ty.hasIncompleteSize()) break :unnamed;
+            if (ty.isAnonymousRecord(p.comp)) {
+                // An anonymous record appears as indirect fields on the parent
+                try p.record_buf.append(.{
+                    .name = try p.getAnonymousName(first_tok),
+                    .ty = ty,
+                });
+                const node = try p.addNode(.{
+                    .tag = .indirect_record_field_decl,
+                    .ty = ty,
+                    .data = undefined,
+                });
+                try p.decl_buf.append(node);
+                try p.record.addFieldsFromAnonymous(p, ty);
+                break; // must be followed by a semicolon
+            }
+            try p.err(.missing_declaration);
+        } else {
+            const interned_name = if (name_tok != 0) try p.comp.intern(p.tokSlice(name_tok)) else try p.getAnonymousName(first_tok);
+            try p.record_buf.append(.{
+                .name = interned_name,
+                .ty = ty,
+                .name_tok = name_tok,
+                .bit_width = bits,
+            });
+            if (name_tok != 0) try p.record.addField(p, interned_name, name_tok);
+            const node = try p.addNode(.{
+                .tag = .record_field_decl,
+                .ty = ty,
+                .data = .{ .decl = .{ .name = name_tok, .node = bits_node } },
+            });
+            try p.decl_buf.append(node);
+        }
+
+        if (ty.isFunc()) {
+            try p.errTok(.func_field, first_tok);
+        } else if (ty.is(.variable_len_array)) {
+            try p.errTok(.vla_field, first_tok);
+        } else if (ty.is(.incomplete_array)) {
+            if (p.record.kind == .keyword_union) {
+                try p.errTok(.flexible_in_union, first_tok);
+            }
+            if (p.record.flexible_field) |some| {
+                if (p.record.kind == .keyword_struct) {
+                    try p.errTok(.flexible_non_final, some);
+                }
+            }
+            p.record.flexible_field = first_tok;
+        } else if (ty.specifier != .invalid and ty.hasIncompleteSize()) {
+            try p.errStr(.field_incomplete_ty, first_tok, try p.typeStr(ty));
+        } else if (p.record.flexible_field) |some| {
+            if (some != first_tok and p.record.kind == .keyword_struct) try p.errTok(.flexible_non_final, some);
+        }
+        if (p.eatToken(.comma) == null) break;
+    }
+
+    if (p.eatToken(.semicolon) == null) {
+        const tok_id = p.tok_ids[p.tok_i];
+        if (tok_id == .r_brace) {
+            try p.err(.missing_semicolon);
+        } else {
+            return p.errExpectedToken(.semicolon, tok_id);
+        }
+    }
+
+    return true;
+}
+
+/// specQual : (typeSpec | typeQual | alignSpec)+
+fn specQual(p: *Parser) Error!?Type {
+    var spec: Type.Builder = .{};
+    if (try p.typeSpec(&spec)) {
+        return try spec.finish(p);
+    }
+    return null;
+}
+
+/// enumSpec
+///  : keyword_enum IDENTIFIER? (: typeName)? { enumerator (',' enumerator)? ',') }
+///  | keyword_enum IDENTIFIER (: typeName)?
+fn enumSpec(p: *Parser) Error!Type {
+    const enum_tok = p.tok_i;
+    p.tok_i += 1;
+    const attr_buf_top = p.attr_buf.len;
+    defer p.attr_buf.len = attr_buf_top;
+    try p.attributeSpecifier();
+
+    const maybe_ident = try p.eatIdentifier();
+    const fixed_ty = if (p.eatToken(.colon)) |colon| fixed: {
+        const fixed = (try p.typeName()) orelse {
+            if (p.record.kind != .invalid) {
+                // This is a bit field.
+                p.tok_i -= 1;
+                break :fixed null;
+            }
+            try p.err(.expected_type);
+            try p.errTok(.enum_fixed, colon);
+            break :fixed null;
+        };
+        try p.errTok(.enum_fixed, colon);
+        break :fixed fixed;
+    } else null;
+
+    const l_brace = p.eatToken(.l_brace) orelse {
+        const ident = maybe_ident orelse {
+            try p.err(.ident_or_l_brace);
+            return error.ParsingFailed;
+        };
+        // check if this is a reference to a previous type
+        const interned_name = try p.comp.intern(p.tokSlice(ident));
+        if (try p.syms.findTag(p, interned_name, .keyword_enum, ident, p.tok_ids[p.tok_i])) |prev| {
+            try p.checkEnumFixedTy(fixed_ty, ident, prev);
+            return prev.ty;
+        } else {
+            // this is a forward declaration, create a new enum Type.
+            const enum_ty = try Type.Enum.create(p.arena, interned_name, fixed_ty);
+            const ty = try Attribute.applyTypeAttributes(p, .{
+                .specifier = .@"enum",
+                .data = .{ .@"enum" = enum_ty },
+            }, attr_buf_top, null);
+            try p.syms.syms.append(p.gpa, .{
+                .kind = .@"enum",
+                .name = interned_name,
+                .tok = ident,
+                .ty = ty,
+                .val = .{},
+            });
+            try p.decl_buf.append(try p.addNode(.{
+                .tag = .enum_forward_decl,
+                .ty = ty,
+                .data = .{ .decl_ref = ident },
+            }));
+            return ty;
+        }
+    };
+
+    var done = false;
+    errdefer if (!done) p.skipTo(.r_brace);
+
+    // Get forward declared type or create a new one
+    var defined = false;
+    const enum_ty: *Type.Enum = if (maybe_ident) |ident| enum_ty: {
+        const ident_str = p.tokSlice(ident);
+        const interned_name = try p.comp.intern(ident_str);
+        if (try p.syms.defineTag(p, interned_name, .keyword_enum, ident)) |prev| {
+            const enum_ty = prev.ty.get(.@"enum").?.data.@"enum";
+            if (!enum_ty.isIncomplete() and !enum_ty.fixed) {
+                // if the enum isn't incomplete, this is a redefinition
+                try p.errStr(.redefinition, ident, ident_str);
+                try p.errTok(.previous_definition, prev.tok);
+            } else {
+                try p.checkEnumFixedTy(fixed_ty, ident, prev);
+                defined = true;
+                break :enum_ty enum_ty;
+            }
+        }
+        break :enum_ty try Type.Enum.create(p.arena, interned_name, fixed_ty);
+    } else try Type.Enum.create(p.arena, try p.getAnonymousName(enum_tok), fixed_ty);
+
+    // reserve space for this enum
+    try p.decl_buf.append(.none);
+    const decl_buf_top = p.decl_buf.items.len;
+    const list_buf_top = p.list_buf.items.len;
+    const enum_buf_top = p.enum_buf.items.len;
+    errdefer p.decl_buf.items.len = decl_buf_top - 1;
+    defer {
+        p.decl_buf.items.len = decl_buf_top;
+        p.list_buf.items.len = list_buf_top;
+        p.enum_buf.items.len = enum_buf_top;
+    }
+
+    const sym_stack_top = p.syms.syms.len;
+    var e = Enumerator.init(fixed_ty);
+    while (try p.enumerator(&e)) |field_and_node| {
+        try p.enum_buf.append(field_and_node.field);
+        try p.list_buf.append(field_and_node.node);
+        if (p.eatToken(.comma) == null) break;
+    }
+
+    if (p.enum_buf.items.len == enum_buf_top) try p.err(.empty_enum);
+    try p.expectClosing(l_brace, .r_brace);
+    done = true;
+    try p.attributeSpecifier();
+
+    const ty = try Attribute.applyTypeAttributes(p, .{
+        .specifier = .@"enum",
+        .data = .{ .@"enum" = enum_ty },
+    }, attr_buf_top, null);
+    if (!enum_ty.fixed) {
+        const tag_specifier = try e.getTypeSpecifier(p, ty.enumIsPacked(p.comp), maybe_ident orelse enum_tok);
+        enum_ty.tag_ty = .{ .specifier = tag_specifier };
+    }
+
+    const enum_fields = p.enum_buf.items[enum_buf_top..];
+    const field_nodes = p.list_buf.items[list_buf_top..];
+
+    if (fixed_ty == null) {
+        const vals = p.syms.syms.items(.val)[sym_stack_top..];
+        const types = p.syms.syms.items(.ty)[sym_stack_top..];
+
+        for (enum_fields, 0..) |*field, i| {
+            if (field.ty.eql(Type.int, p.comp, false)) continue;
+
+            var res = Result{ .node = field.node, .ty = field.ty, .val = vals[i] };
+            const dest_ty = if (p.comp.fixedEnumTagSpecifier()) |some|
+                Type{ .specifier = some }
+            else if (res.intFitsInType(p, Type.int))
+                Type.int
+            else if (!res.ty.eql(enum_ty.tag_ty, p.comp, false))
+                enum_ty.tag_ty
+            else
+                continue;
+
+            vals[i].intCast(field.ty, dest_ty, p.comp);
+            types[i] = dest_ty;
+            p.nodes.items(.ty)[@intFromEnum(field_nodes[i])] = dest_ty;
+            field.ty = dest_ty;
+            res.ty = dest_ty;
+
+            if (res.node != .none) {
+                try res.implicitCast(p, .int_cast);
+                field.node = res.node;
+                p.nodes.items(.data)[@intFromEnum(field_nodes[i])].decl.node = res.node;
+            }
+        }
+    }
+
+    enum_ty.fields = try p.arena.dupe(Type.Enum.Field, enum_fields);
+
+    // declare a symbol for the type
+    if (maybe_ident != null and !defined) {
+        try p.syms.syms.append(p.gpa, .{
+            .kind = .@"enum",
+            .name = enum_ty.name,
+            .ty = ty,
+            .tok = maybe_ident.?,
+            .val = .{},
+        });
+    }
+
+    // finish by creating a node
+    var node: Tree.Node = .{ .tag = .enum_decl_two, .ty = ty, .data = .{
+        .bin = .{ .lhs = .none, .rhs = .none },
+    } };
+    switch (field_nodes.len) {
+        0 => {},
+        1 => node.data = .{ .bin = .{ .lhs = field_nodes[0], .rhs = .none } },
+        2 => node.data = .{ .bin = .{ .lhs = field_nodes[0], .rhs = field_nodes[1] } },
+        else => {
+            node.tag = .enum_decl;
+            node.data = .{ .range = try p.addList(field_nodes) };
+        },
+    }
+    p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node);
+    if (p.func.ty == null) {
+        _ = p.tentative_defs.remove(enum_ty.name);
+    }
+    return ty;
+}
+
+fn checkEnumFixedTy(p: *Parser, fixed_ty: ?Type, ident_tok: TokenIndex, prev: Symbol) !void {
+    const enum_ty = prev.ty.get(.@"enum").?.data.@"enum";
+    if (fixed_ty) |some| {
+        if (!enum_ty.fixed) {
+            try p.errTok(.enum_prev_nonfixed, ident_tok);
+            try p.errTok(.previous_definition, prev.tok);
+            return error.ParsingFailed;
+        }
+
+        if (!enum_ty.tag_ty.eql(some, p.comp, false)) {
+            const str = try p.typePairStrExtra(some, " (was ", enum_ty.tag_ty);
+            try p.errStr(.enum_different_explicit_ty, ident_tok, str);
+            try p.errTok(.previous_definition, prev.tok);
+            return error.ParsingFailed;
+        }
+    } else if (enum_ty.fixed) {
+        try p.errTok(.enum_prev_fixed, ident_tok);
+        try p.errTok(.previous_definition, prev.tok);
+        return error.ParsingFailed;
+    }
+}
+
+const Enumerator = struct {
+    res: Result,
+    num_positive_bits: usize = 0,
+    num_negative_bits: usize = 0,
+    fixed: bool,
+
+    fn init(fixed_ty: ?Type) Enumerator {
+        return .{
+            .res = .{
+                .ty = fixed_ty orelse .{ .specifier = .int },
+                .val = .{ .tag = .unavailable },
+            },
+            .fixed = fixed_ty != null,
+        };
+    }
+
+    /// Increment enumerator value adjusting type if needed.
+    fn incr(e: *Enumerator, p: *Parser, tok: TokenIndex) !void {
+        e.res.node = .none;
+        const old_val = e.res.val;
+        if (old_val.tag == .unavailable) {
+            // First enumerator, set to 0 fits in all types.
+            e.res.val = Value.int(0);
+            return;
+        }
+        if (e.res.val.add(e.res.val, Value.int(1), e.res.ty, p.comp)) {
+            const byte_size = e.res.ty.sizeof(p.comp).?;
+            const bit_size: u8 = @intCast(if (e.res.ty.isUnsignedInt(p.comp)) byte_size * 8 else byte_size * 8 - 1);
+            if (e.fixed) {
+                try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty));
+                return;
+            }
+            const new_ty = if (p.comp.nextLargestIntSameSign(e.res.ty)) |larger| blk: {
+                try p.errTok(.enumerator_overflow, tok);
+                break :blk larger;
+            } else blk: {
+                try p.errExtra(.enum_not_representable, tok, .{ .pow_2_as_string = bit_size });
+                break :blk Type{ .specifier = .ulong_long };
+            };
+            e.res.ty = new_ty;
+            _ = e.res.val.add(old_val, Value.int(1), e.res.ty, p.comp);
+        }
+    }
+
+    /// Set enumerator value to specified value.
+    fn set(e: *Enumerator, p: *Parser, res: Result, tok: TokenIndex) !void {
+        if (res.ty.specifier == .invalid) return;
+        if (e.fixed and !res.ty.eql(e.res.ty, p.comp, false)) {
+            if (!res.intFitsInType(p, e.res.ty)) {
+                try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty));
+                return error.ParsingFailed;
+            }
+            var copy = res;
+            copy.ty = e.res.ty;
+            try copy.implicitCast(p, .int_cast);
+            e.res = copy;
+        } else {
+            e.res = res;
+            try e.res.intCast(p, e.res.ty.integerPromotion(p.comp), tok);
+        }
+    }
+
+    fn getTypeSpecifier(e: *const Enumerator, p: *Parser, is_packed: bool, tok: TokenIndex) !Type.Specifier {
+        if (p.comp.fixedEnumTagSpecifier()) |tag_specifier| return tag_specifier;
+
+        const char_width = (Type{ .specifier = .schar }).sizeof(p.comp).? * 8;
+        const short_width = (Type{ .specifier = .short }).sizeof(p.comp).? * 8;
+        const int_width = (Type{ .specifier = .int }).sizeof(p.comp).? * 8;
+        if (e.num_negative_bits > 0) {
+            if (is_packed and e.num_negative_bits <= char_width and e.num_positive_bits < char_width) {
+                return .schar;
+            } else if (is_packed and e.num_negative_bits <= short_width and e.num_positive_bits < short_width) {
+                return .short;
+            } else if (e.num_negative_bits <= int_width and e.num_positive_bits < int_width) {
+                return .int;
+            }
+            const long_width = (Type{ .specifier = .long }).sizeof(p.comp).? * 8;
+            if (e.num_negative_bits <= long_width and e.num_positive_bits < long_width) {
+                return .long;
+            }
+            const long_long_width = (Type{ .specifier = .long_long }).sizeof(p.comp).? * 8;
+            if (e.num_negative_bits > long_long_width or e.num_positive_bits >= long_long_width) {
+                try p.errTok(.enum_too_large, tok);
+            }
+            return .long_long;
+        }
+        if (is_packed and e.num_positive_bits <= char_width) {
+            return .uchar;
+        } else if (is_packed and e.num_positive_bits <= short_width) {
+            return .ushort;
+        } else if (e.num_positive_bits <= int_width) {
+            return .uint;
+        } else if (e.num_positive_bits <= (Type{ .specifier = .long }).sizeof(p.comp).? * 8) {
+            return .ulong;
+        }
+        return .ulong_long;
+    }
+};
+
+const EnumFieldAndNode = struct { field: Type.Enum.Field, node: NodeIndex };
+
+/// enumerator : IDENTIFIER ('=' integerConstExpr)
+fn enumerator(p: *Parser, e: *Enumerator) Error!?EnumFieldAndNode {
+    _ = try p.pragma();
+    const name_tok = (try p.eatIdentifier()) orelse {
+        if (p.tok_ids[p.tok_i] == .r_brace) return null;
+        try p.err(.expected_identifier);
+        p.skipTo(.r_brace);
+        return error.ParsingFailed;
+    };
+    const attr_buf_top = p.attr_buf.len;
+    defer p.attr_buf.len = attr_buf_top;
+    try p.attributeSpecifier();
+
+    const err_start = p.comp.diag.list.items.len;
+    if (p.eatToken(.equal)) |_| {
+        const specified = try p.integerConstExpr(.gnu_folding_extension);
+        if (specified.val.tag == .unavailable) {
+            try p.errTok(.enum_val_unavailable, name_tok + 2);
+            try e.incr(p, name_tok);
+        } else {
+            try e.set(p, specified, name_tok);
+        }
+    } else {
+        try e.incr(p, name_tok);
+    }
+
+    var res = e.res;
+    res.ty = try Attribute.applyEnumeratorAttributes(p, res.ty, attr_buf_top);
+
+    if (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, Value.int(0), res.ty, p.comp)) {
+        e.num_positive_bits = @max(e.num_positive_bits, res.val.minUnsignedBits(res.ty, p.comp));
+    } else {
+        e.num_negative_bits = @max(e.num_negative_bits, res.val.minSignedBits(res.ty, p.comp));
+    }
+
+    if (err_start == p.comp.diag.list.items.len) {
+        // only do these warnings if we didn't already warn about overflow or non-representable values
+        if (e.res.val.compare(.lt, Value.int(0), e.res.ty, p.comp)) {
+            const val = e.res.val.getInt(i64);
+            if (val < (Type{ .specifier = .int }).minInt(p.comp)) {
+                try p.errExtra(.enumerator_too_small, name_tok, .{
+                    .signed = val,
+                });
+            }
+        } else {
+            const val = e.res.val.getInt(u64);
+            if (val > (Type{ .specifier = .int }).maxInt(p.comp)) {
+                try p.errExtra(.enumerator_too_large, name_tok, .{
+                    .unsigned = val,
+                });
+            }
+        }
+    }
+
+    const interned_name = try p.comp.intern(p.tokSlice(name_tok));
+    try p.syms.defineEnumeration(p, interned_name, res.ty, name_tok, e.res.val);
+    const node = try p.addNode(.{
+        .tag = .enum_field_decl,
+        .ty = res.ty,
+        .data = .{ .decl = .{
+            .name = name_tok,
+            .node = res.node,
+        } },
+    });
+    return EnumFieldAndNode{ .field = .{
+        .name = interned_name,
+        .ty = res.ty,
+        .name_tok = name_tok,
+        .node = res.node,
+    }, .node = node };
+}
+
+/// typeQual : keyword_const | keyword_restrict | keyword_volatile | keyword_atomic
+fn typeQual(p: *Parser, b: *Type.Qualifiers.Builder) Error!bool {
+    var any = false;
+    while (true) {
+        switch (p.tok_ids[p.tok_i]) {
+            .keyword_restrict, .keyword_restrict1, .keyword_restrict2 => {
+                if (b.restrict != null)
+                    try p.errStr(.duplicate_decl_spec, p.tok_i, "restrict")
+                else
+                    b.restrict = p.tok_i;
+            },
+            .keyword_const, .keyword_const1, .keyword_const2 => {
+                if (b.@"const" != null)
+                    try p.errStr(.duplicate_decl_spec, p.tok_i, "const")
+                else
+                    b.@"const" = p.tok_i;
+            },
+            .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => {
+                if (b.@"volatile" != null)
+                    try p.errStr(.duplicate_decl_spec, p.tok_i, "volatile")
+                else
+                    b.@"volatile" = p.tok_i;
+            },
+            .keyword_atomic => {
+                // _Atomic(typeName) instead of just _Atomic
+                if (p.tok_ids[p.tok_i + 1] == .l_paren) break;
+                if (b.atomic != null)
+                    try p.errStr(.duplicate_decl_spec, p.tok_i, "atomic")
+                else
+                    b.atomic = p.tok_i;
+            },
+            else => break,
+        }
+        p.tok_i += 1;
+        any = true;
+    }
+    return any;
+}
+
+const Declarator = struct {
+    name: TokenIndex,
+    ty: Type,
+    func_declarator: ?TokenIndex = null,
+    old_style_func: ?TokenIndex = null,
+};
+const DeclaratorKind = enum { normal, abstract, param, record };
+
+/// declarator : pointer? (IDENTIFIER | '(' declarator ')') directDeclarator*
+/// abstractDeclarator
+/// : pointer? ('(' abstractDeclarator ')')? directAbstractDeclarator*
+fn declarator(
+    p: *Parser,
+    base_type: Type,
+    kind: DeclaratorKind,
+) Error!?Declarator {
+    const start = p.tok_i;
+    var d = Declarator{ .name = 0, .ty = try p.pointer(base_type) };
+    if (base_type.is(.auto_type) and !d.ty.is(.auto_type)) {
+        try p.errTok(.auto_type_requires_plain_declarator, start);
+        return error.ParsingFailed;
+    }
+
+    const maybe_ident = p.tok_i;
+    if (kind != .abstract and (try p.eatIdentifier()) != null) {
+        d.name = maybe_ident;
+        const combine_tok = p.tok_i;
+        d.ty = try p.directDeclarator(d.ty, &d, kind);
+        try d.ty.validateCombinedType(p, combine_tok);
+        return d;
+    } else if (p.eatToken(.l_paren)) |l_paren| blk: {
+        var res = (try p.declarator(.{ .specifier = .void }, kind)) orelse {
+            p.tok_i = l_paren;
+            break :blk;
+        };
+        try p.expectClosing(l_paren, .r_paren);
+        const suffix_start = p.tok_i;
+        const outer = try p.directDeclarator(d.ty, &d, kind);
+        try res.ty.combine(outer);
+        try res.ty.validateCombinedType(p, suffix_start);
+        res.old_style_func = d.old_style_func;
+        return res;
+    }
+
+    const expected_ident = p.tok_i;
+
+    d.ty = try p.directDeclarator(d.ty, &d, kind);
+
+    if (kind == .normal and !d.ty.isEnumOrRecord()) {
+        try p.errTok(.expected_ident_or_l_paren, expected_ident);
+        return error.ParsingFailed;
+    }
+    try d.ty.validateCombinedType(p, expected_ident);
+    if (start == p.tok_i) return null;
+    return d;
+}
+
+/// directDeclarator
+///  : '[' typeQual* assignExpr? ']' directDeclarator?
+///  | '[' keyword_static typeQual* assignExpr ']' directDeclarator?
+///  | '[' typeQual+ keyword_static assignExpr ']' directDeclarator?
+///  | '[' typeQual* '*' ']' directDeclarator?
+///  | '(' paramDecls ')' directDeclarator?
+///  | '(' (IDENTIFIER (',' IDENTIFIER))? ')' directDeclarator?
+/// directAbstractDeclarator
+///  : '[' typeQual* assignExpr? ']'
+///  | '[' keyword_static typeQual* assignExpr ']'
+///  | '[' typeQual+ keyword_static assignExpr ']'
+///  | '[' '*' ']'
+///  | '(' paramDecls? ')'
+fn directDeclarator(p: *Parser, base_type: Type, d: *Declarator, kind: DeclaratorKind) Error!Type {
+    if (p.eatToken(.l_bracket)) |l_bracket| {
+        if (p.tok_ids[p.tok_i] == .l_bracket) {
+            switch (kind) {
+                .normal, .record => if (p.comp.langopts.standard.atLeast(.c2x)) {
+                    p.tok_i -= 1;
+                    return base_type;
+                },
+                .param, .abstract => {},
+            }
+            try p.err(.expected_expr);
+            return error.ParsingFailed;
+        }
+        var res_ty = Type{
+            // so that we can get any restrict type that might be present
+            .specifier = .pointer,
+        };
+        var quals = Type.Qualifiers.Builder{};
+
+        var got_quals = try p.typeQual(&quals);
+        var static = p.eatToken(.keyword_static);
+        if (static != null and !got_quals) got_quals = try p.typeQual(&quals);
+        var star = p.eatToken(.asterisk);
+        const size_tok = p.tok_i;
+
+        const const_decl_folding = p.const_decl_folding;
+        p.const_decl_folding = .gnu_vla_folding_extension;
+        const size = if (star) |_| Result{} else try p.assignExpr();
+        p.const_decl_folding = const_decl_folding;
+
+        try p.expectClosing(l_bracket, .r_bracket);
+
+        if (star != null and static != null) {
+            try p.errTok(.invalid_static_star, static.?);
+            static = null;
+        }
+        if (kind != .param) {
+            if (static != null)
+                try p.errTok(.static_non_param, l_bracket)
+            else if (got_quals)
+                try p.errTok(.array_qualifiers, l_bracket);
+            if (star) |some| try p.errTok(.star_non_param, some);
+            static = null;
+            quals = .{};
+            star = null;
+        } else {
+            try quals.finish(p, &res_ty);
+        }
+        if (static) |_| try size.expect(p);
+
+        if (base_type.is(.auto_type)) {
+            try p.errStr(.array_of_auto_type, d.name, p.tokSlice(d.name));
+            return error.ParsingFailed;
+        }
+        const outer = try p.directDeclarator(base_type, d, kind);
+        var max_bits = p.comp.target.ptrBitWidth();
+        if (max_bits > 61) max_bits = 61;
+        const max_bytes = (@as(u64, 1) << @truncate(max_bits)) - 1;
+        // `outer` is validated later so it may be invalid here
+        const outer_size = outer.sizeof(p.comp);
+        const max_elems = max_bytes / @max(1, outer_size orelse 1);
+
+        if (!size.ty.isInt()) {
+            try p.errStr(.array_size_non_int, size_tok, try p.typeStr(size.ty));
+            return error.ParsingFailed;
+        }
+        if (size.val.tag == .unavailable) {
+            if (size.node != .none) {
+                try p.errTok(.vla, size_tok);
+                if (p.func.ty == null and kind != .param and p.record.kind == .invalid) {
+                    try p.errTok(.variable_len_array_file_scope, d.name);
+                }
+                const expr_ty = try p.arena.create(Type.Expr);
+                expr_ty.ty = .{ .specifier = .void };
+                expr_ty.node = size.node;
+                res_ty.data = .{ .expr = expr_ty };
+                res_ty.specifier = .variable_len_array;
+
+                if (static) |some| try p.errTok(.useless_static, some);
+            } else if (star) |_| {
+                const elem_ty = try p.arena.create(Type);
+                elem_ty.* = .{ .specifier = .void };
+                res_ty.data = .{ .sub_type = elem_ty };
+                res_ty.specifier = .unspecified_variable_len_array;
+            } else {
+                const arr_ty = try p.arena.create(Type.Array);
+                arr_ty.elem = .{ .specifier = .void };
+                arr_ty.len = 0;
+                res_ty.data = .{ .array = arr_ty };
+                res_ty.specifier = .incomplete_array;
+            }
+        } else {
+            var size_val = size.val;
+            const size_t = p.comp.types.size;
+            if (size_val.isZero()) {
+                try p.errTok(.zero_length_array, l_bracket);
+            } else if (size_val.compare(.lt, Value.int(0), size_t, p.comp)) {
+                try p.errTok(.negative_array_size, l_bracket);
+                return error.ParsingFailed;
+            }
+            const arr_ty = try p.arena.create(Type.Array);
+            arr_ty.elem = .{ .specifier = .void };
+            if (size_val.compare(.gt, Value.int(max_elems), size_t, p.comp)) {
+                try p.errTok(.array_too_large, l_bracket);
+                arr_ty.len = max_elems;
+            } else {
+                arr_ty.len = size_val.getInt(u64);
+            }
+            res_ty.data = .{ .array = arr_ty };
+            res_ty.specifier = .array;
+        }
+
+        try res_ty.combine(outer);
+        return res_ty;
+    } else if (p.eatToken(.l_paren)) |l_paren| {
+        d.func_declarator = l_paren;
+
+        const func_ty = try p.arena.create(Type.Func);
+        func_ty.params = &.{};
+        func_ty.return_type.specifier = .void;
+        var specifier: Type.Specifier = .func;
+
+        if (p.eatToken(.ellipsis)) |_| {
+            try p.err(.param_before_var_args);
+            try p.expectClosing(l_paren, .r_paren);
+            var res_ty = Type{ .specifier = .func, .data = .{ .func = func_ty } };
+
+            const outer = try p.directDeclarator(base_type, d, kind);
+            try res_ty.combine(outer);
+            return res_ty;
+        }
+
+        if (try p.paramDecls()) |params| {
+            func_ty.params = params;
+            if (p.eatToken(.ellipsis)) |_| specifier = .var_args_func;
+        } else if (p.tok_ids[p.tok_i] == .r_paren) {
+            specifier = .var_args_func;
+        } else if (p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) {
+            d.old_style_func = p.tok_i;
+            const param_buf_top = p.param_buf.items.len;
+            try p.syms.pushScope(p);
+            defer {
+                p.param_buf.items.len = param_buf_top;
+                p.syms.popScope();
+            }
+
+            specifier = .old_style_func;
+            while (true) {
+                const name_tok = try p.expectIdentifier();
+                const interned_name = try p.comp.intern(p.tokSlice(name_tok));
+                try p.syms.defineParam(p, interned_name, undefined, name_tok);
+                try p.param_buf.append(.{
+                    .name = interned_name,
+                    .name_tok = name_tok,
+                    .ty = .{ .specifier = .int },
+                });
+                if (p.eatToken(.comma) == null) break;
+            }
+            func_ty.params = try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]);
+        } else {
+            try p.err(.expected_param_decl);
+        }
+
+        try p.expectClosing(l_paren, .r_paren);
+        var res_ty = Type{
+            .specifier = specifier,
+            .data = .{ .func = func_ty },
+        };
+
+        const outer = try p.directDeclarator(base_type, d, kind);
+        try res_ty.combine(outer);
+        return res_ty;
+    } else return base_type;
+}
+
+/// pointer : '*' typeQual* pointer?
+fn pointer(p: *Parser, base_ty: Type) Error!Type {
+    var ty = base_ty;
+    while (p.eatToken(.asterisk)) |_| {
+        const elem_ty = try p.arena.create(Type);
+        elem_ty.* = ty;
+        ty = Type{
+            .specifier = .pointer,
+            .data = .{ .sub_type = elem_ty },
+        };
+        var quals = Type.Qualifiers.Builder{};
+        _ = try p.typeQual(&quals);
+        try quals.finish(p, &ty);
+    }
+    return ty;
+}
+
+/// paramDecls : paramDecl (',' paramDecl)* (',' '...')
+/// paramDecl : declSpec (declarator | abstractDeclarator)
+fn paramDecls(p: *Parser) Error!?[]Type.Func.Param {
+    // TODO warn about visibility of types declared here
+    const param_buf_top = p.param_buf.items.len;
+    defer p.param_buf.items.len = param_buf_top;
+    try p.syms.pushScope(p);
+    defer p.syms.popScope();
+
+    while (true) {
+        const attr_buf_top = p.attr_buf.len;
+        defer p.attr_buf.len = attr_buf_top;
+        const param_decl_spec = if (try p.declSpec()) |some|
+            some
+        else if (p.param_buf.items.len == param_buf_top)
+            return null
+        else blk: {
+            var spec: Type.Builder = .{};
+            break :blk DeclSpec{ .ty = try spec.finish(p) };
+        };
+
+        var name_tok: TokenIndex = 0;
+        const first_tok = p.tok_i;
+        var param_ty = param_decl_spec.ty;
+        if (try p.declarator(param_decl_spec.ty, .param)) |some| {
+            if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
+            try p.attributeSpecifier();
+
+            name_tok = some.name;
+            param_ty = some.ty;
+            if (some.name != 0) {
+                const interned_name = try p.comp.intern(p.tokSlice(name_tok));
+                try p.syms.defineParam(p, interned_name, param_ty, name_tok);
+            }
+        }
+        param_ty = try Attribute.applyParameterAttributes(p, param_ty, attr_buf_top, .alignas_on_param);
+
+        if (param_ty.isFunc()) {
+            // params declared as functions are converted to function pointers
+            const elem_ty = try p.arena.create(Type);
+            elem_ty.* = param_ty;
+            param_ty = Type{
+                .specifier = .pointer,
+                .data = .{ .sub_type = elem_ty },
+            };
+        } else if (param_ty.isArray()) {
+            // params declared as arrays are converted to pointers
+            param_ty.decayArray();
+        } else if (param_ty.is(.void)) {
+            // validate void parameters
+            if (p.param_buf.items.len == param_buf_top) {
+                if (p.tok_ids[p.tok_i] != .r_paren) {
+                    try p.err(.void_only_param);
+                    if (param_ty.anyQual()) try p.err(.void_param_qualified);
+                    return error.ParsingFailed;
+                }
+                return &[0]Type.Func.Param{};
+            }
+            try p.err(.void_must_be_first_param);
+            return error.ParsingFailed;
+        }
+
+        try param_decl_spec.validateParam(p, &param_ty);
+        try p.param_buf.append(.{
+            .name = if (name_tok == 0) .empty else try p.comp.intern(p.tokSlice(name_tok)),
+            .name_tok = if (name_tok == 0) first_tok else name_tok,
+            .ty = param_ty,
+        });
+
+        if (p.eatToken(.comma) == null) break;
+        if (p.tok_ids[p.tok_i] == .ellipsis) break;
+    }
+    return try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]);
+}
+
+/// typeName : specQual abstractDeclarator
+fn typeName(p: *Parser) Error!?Type {
+    const attr_buf_top = p.attr_buf.len;
+    defer p.attr_buf.len = attr_buf_top;
+    var ty = (try p.specQual()) orelse return null;
+    if (try p.declarator(ty, .abstract)) |some| {
+        if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
+        return try Attribute.applyTypeAttributes(p, some.ty, attr_buf_top, .align_ignored);
+    }
+    return try Attribute.applyTypeAttributes(p, ty, attr_buf_top, .align_ignored);
+}
+
+/// initializer
+///  : assignExpr
+///  | '{' initializerItems '}'
+fn initializer(p: *Parser, init_ty: Type) Error!Result {
+    // fast path for non-braced initializers
+    if (p.tok_ids[p.tok_i] != .l_brace) {
+        const tok = p.tok_i;
+        var res = try p.assignExpr();
+        try res.expect(p);
+        if (try p.coerceArrayInit(&res, tok, init_ty)) return res;
+        try p.coerceInit(&res, tok, init_ty);
+        return res;
+    }
+    if (init_ty.is(.auto_type)) {
+        try p.err(.auto_type_with_init_list);
+        return error.ParsingFailed;
+    }
+
+    var il: InitList = .{};
+    defer il.deinit(p.gpa);
+
+    _ = try p.initializerItem(&il, init_ty);
+
+    const res = try p.convertInitList(il, init_ty);
+    var res_ty = p.nodes.items(.ty)[@intFromEnum(res)];
+    res_ty.qual = init_ty.qual;
+    return Result{ .ty = res_ty, .node = res };
+}
+
+/// initializerItems : designation? initializer (',' designation? initializer)* ','?
+/// designation : designator+ '='
+/// designator
+///  : '[' integerConstExpr ']'
+///  | '.' identifier
+fn initializerItem(p: *Parser, il: *InitList, init_ty: Type) Error!bool {
+    const l_brace = p.eatToken(.l_brace) orelse {
+        const tok = p.tok_i;
+        var res = try p.assignExpr();
+        if (res.empty(p)) return false;
+
+        const arr = try p.coerceArrayInit(&res, tok, init_ty);
+        if (!arr) try p.coerceInit(&res, tok, init_ty);
+        if (il.tok != 0) {
+            try p.errTok(.initializer_overrides, tok);
+            try p.errTok(.previous_initializer, il.tok);
+        }
+        il.node = res.node;
+        il.tok = tok;
+        return true;
+    };
+
+    const is_scalar = init_ty.isScalar();
+    const is_complex = init_ty.isComplex();
+    const scalar_inits_needed: usize = if (is_complex) 2 else 1;
+    if (p.eatToken(.r_brace)) |_| {
+        if (is_scalar) try p.errTok(.empty_scalar_init, l_brace);
+        if (il.tok != 0) {
+            try p.errTok(.initializer_overrides, l_brace);
+            try p.errTok(.previous_initializer, il.tok);
+        }
+        il.node = .none;
+        il.tok = l_brace;
+        return true;
+    }
+
+    var count: u64 = 0;
+    var warned_excess = false;
+    var is_str_init = false;
+    var index_hint: ?u64 = null;
+    while (true) : (count += 1) {
+        errdefer p.skipTo(.r_brace);
+
+        var first_tok = p.tok_i;
+        var cur_ty = init_ty;
+        var cur_il = il;
+        var designation = false;
+        var cur_index_hint: ?u64 = null;
+        while (true) {
+            if (p.eatToken(.l_bracket)) |l_bracket| {
+                if (!cur_ty.isArray()) {
+                    try p.errStr(.invalid_array_designator, l_bracket, try p.typeStr(cur_ty));
+                    return error.ParsingFailed;
+                }
+                const expr_tok = p.tok_i;
+                const index_res = try p.integerConstExpr(.gnu_folding_extension);
+                try p.expectClosing(l_bracket, .r_bracket);
+
+                if (index_res.val.tag == .unavailable) {
+                    try p.errTok(.expected_integer_constant_expr, expr_tok);
+                    return error.ParsingFailed;
+                } else if (index_res.val.compare(.lt, index_res.val.zero(), index_res.ty, p.comp)) {
+                    try p.errExtra(.negative_array_designator, l_bracket + 1, .{
+                        .signed = index_res.val.signExtend(index_res.ty, p.comp),
+                    });
+                    return error.ParsingFailed;
+                }
+
+                const max_len = cur_ty.arrayLen() orelse std.math.maxInt(usize);
+                if (index_res.val.data.int >= max_len) {
+                    try p.errExtra(.oob_array_designator, l_bracket + 1, .{ .unsigned = index_res.val.data.int });
+                    return error.ParsingFailed;
+                }
+                const checked = index_res.val.getInt(u64);
+                cur_index_hint = cur_index_hint orelse checked;
+
+                cur_il = try cur_il.find(p.gpa, checked);
+                cur_ty = cur_ty.elemType();
+                designation = true;
+            } else if (p.eatToken(.period)) |period| {
+                const field_tok = try p.expectIdentifier();
+                const field_str = p.tokSlice(field_tok);
+                const field_name = try p.comp.intern(field_str);
+                cur_ty = cur_ty.canonicalize(.standard);
+                if (!cur_ty.isRecord()) {
+                    try p.errStr(.invalid_field_designator, period, try p.typeStr(cur_ty));
+                    return error.ParsingFailed;
+                } else if (!cur_ty.hasField(field_name)) {
+                    try p.errStr(.no_such_field_designator, period, field_str);
+                    return error.ParsingFailed;
+                }
+
+                // TODO check if union already has field set
+                outer: while (true) {
+                    for (cur_ty.data.record.fields, 0..) |f, i| {
+                        if (f.isAnonymousRecord()) {
+                            // Recurse into anonymous field if it has a field by the name.
+                            if (!f.ty.hasField(field_name)) continue;
+                            cur_ty = f.ty.canonicalize(.standard);
+                            cur_il = try il.find(p.gpa, i);
+                            cur_index_hint = cur_index_hint orelse i;
+                            continue :outer;
+                        }
+                        if (field_name == f.name) {
+                            cur_il = try cur_il.find(p.gpa, i);
+                            cur_ty = f.ty;
+                            cur_index_hint = cur_index_hint orelse i;
+                            break :outer;
+                        }
+                    }
+                    unreachable; // we already checked that the starting type has this field
+                }
+                designation = true;
+            } else break;
+        }
+        if (designation) index_hint = null;
+        defer index_hint = cur_index_hint orelse null;
+
+        if (designation) _ = try p.expectToken(.equal);
+
+        if (!designation and cur_ty.hasAttribute(.designated_init)) {
+            try p.err(.designated_init_needed);
+        }
+
+        var saw = false;
+        if (is_str_init and p.isStringInit(init_ty)) {
+            // discard further strings
+            var tmp_il = InitList{};
+            defer tmp_il.deinit(p.gpa);
+            saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
+        } else if (count == 0 and p.isStringInit(init_ty)) {
+            is_str_init = true;
+            saw = try p.initializerItem(il, init_ty);
+        } else if (is_scalar and count >= scalar_inits_needed) {
+            // discard further scalars
+            var tmp_il = InitList{};
+            defer tmp_il.deinit(p.gpa);
+            saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
+        } else if (p.tok_ids[p.tok_i] == .l_brace) {
+            if (designation) {
+                // designation overrides previous value, let existing mechanism handle it
+                saw = try p.initializerItem(cur_il, cur_ty);
+            } else if (try p.findAggregateInitializer(&cur_il, &cur_ty, &index_hint)) {
+                saw = try p.initializerItem(cur_il, cur_ty);
+            } else {
+                // discard further values
+                var tmp_il = InitList{};
+                defer tmp_il.deinit(p.gpa);
+                saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
+                if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok);
+                warned_excess = true;
+            }
+        } else single_item: {
+            first_tok = p.tok_i;
+            var res = try p.assignExpr();
+            saw = !res.empty(p);
+            if (!saw) break :single_item;
+
+            excess: {
+                if (index_hint) |*hint| {
+                    if (try p.findScalarInitializerAt(&cur_il, &cur_ty, res.ty, first_tok, hint)) break :excess;
+                } else if (try p.findScalarInitializer(&cur_il, &cur_ty, res.ty, first_tok)) break :excess;
+
+                if (designation) break :excess;
+                if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok);
+                warned_excess = true;
+
+                break :single_item;
+            }
+
+            const arr = try p.coerceArrayInit(&res, first_tok, cur_ty);
+            if (!arr) try p.coerceInit(&res, first_tok, cur_ty);
+            if (cur_il.tok != 0) {
+                try p.errTok(.initializer_overrides, first_tok);
+                try p.errTok(.previous_initializer, cur_il.tok);
+            }
+            cur_il.node = res.node;
+            cur_il.tok = first_tok;
+        }
+
+        if (!saw) {
+            if (designation) {
+                try p.err(.expected_expr);
+                return error.ParsingFailed;
+            }
+            break;
+        } else if (count == 1) {
+            if (is_str_init) try p.errTok(.excess_str_init, first_tok);
+            if (is_scalar and !is_complex) try p.errTok(.excess_scalar_init, first_tok);
+        } else if (count == 2) {
+            if (is_scalar and is_complex) try p.errTok(.excess_scalar_init, first_tok);
+        }
+
+        if (p.eatToken(.comma) == null) break;
+    }
+    try p.expectClosing(l_brace, .r_brace);
+
+    if (is_complex and count == 1) { // count of 1 means we saw exactly 2 items in the initializer list
+        try p.errTok(.complex_component_init, l_brace);
+    }
+    if (is_scalar or is_str_init) return true;
+    if (il.tok != 0) {
+        try p.errTok(.initializer_overrides, l_brace);
+        try p.errTok(.previous_initializer, il.tok);
+    }
+    il.node = .none;
+    il.tok = l_brace;
+    return true;
+}
+
+/// Returns true if the value is unused.
+fn findScalarInitializerAt(p: *Parser, il: **InitList, ty: *Type, actual_ty: Type, first_tok: TokenIndex, start_index: *u64) Error!bool {
+    if (ty.isArray()) {
+        if (il.*.node != .none) return false;
+        start_index.* += 1;
+
+        const arr_ty = ty.*;
+        const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64);
+        if (elem_count == 0) {
+            try p.errTok(.empty_aggregate_init_braces, first_tok);
+            return error.ParsingFailed;
+        }
+        const elem_ty = arr_ty.elemType();
+        const arr_il = il.*;
+        if (start_index.* < elem_count) {
+            ty.* = elem_ty;
+            il.* = try arr_il.find(p.gpa, start_index.*);
+            _ = try p.findScalarInitializer(il, ty, actual_ty, first_tok);
+            return true;
+        }
+        return false;
+    } else if (ty.get(.@"struct")) |struct_ty| {
+        if (il.*.node != .none) return false;
+        start_index.* += 1;
+
+        const fields = struct_ty.data.record.fields;
+        if (fields.len == 0) {
+            try p.errTok(.empty_aggregate_init_braces, first_tok);
+            return error.ParsingFailed;
+        }
+        const struct_il = il.*;
+        if (start_index.* < fields.len) {
+            const field = fields[@intCast(start_index.*)];
+            ty.* = field.ty;
+            il.* = try struct_il.find(p.gpa, start_index.*);
+            _ = try p.findScalarInitializer(il, ty, actual_ty, first_tok);
+            return true;
+        }
+        return false;
+    } else if (ty.get(.@"union")) |_| {
+        return false;
+    }
+    return il.*.node == .none;
+}
+
+/// Returns true if the value is unused.
+fn findScalarInitializer(p: *Parser, il: **InitList, ty: *Type, actual_ty: Type, first_tok: TokenIndex) Error!bool {
+    if (ty.isArray() or ty.isComplex()) {
+        if (il.*.node != .none) return false;
+        const start_index = il.*.list.items.len;
+        var index = if (start_index != 0) il.*.list.items[start_index - 1].index else start_index;
+
+        const arr_ty = ty.*;
+        const elem_count: u64 = arr_ty.expectedInitListSize() orelse std.math.maxInt(u64);
+        if (elem_count == 0) {
+            try p.errTok(.empty_aggregate_init_braces, first_tok);
+            return error.ParsingFailed;
+        }
+        const elem_ty = arr_ty.elemType();
+        const arr_il = il.*;
+        while (index < elem_count) : (index += 1) {
+            ty.* = elem_ty;
+            il.* = try arr_il.find(p.gpa, index);
+            if (il.*.node == .none and actual_ty.eql(elem_ty, p.comp, false)) return true;
+            if (try p.findScalarInitializer(il, ty, actual_ty, first_tok)) return true;
+        }
+        return false;
+    } else if (ty.get(.@"struct")) |struct_ty| {
+        if (il.*.node != .none) return false;
+        if (actual_ty.eql(ty.*, p.pp.comp, false)) return true;
+        const start_index = il.*.list.items.len;
+        var index = if (start_index != 0) il.*.list.items[start_index - 1].index + 1 else start_index;
+
+        const fields = struct_ty.data.record.fields;
+        if (fields.len == 0) {
+            try p.errTok(.empty_aggregate_init_braces, first_tok);
+            return error.ParsingFailed;
+        }
+        const struct_il = il.*;
+        while (index < fields.len) : (index += 1) {
+            const field = fields[@intCast(index)];
+            ty.* = field.ty;
+            il.* = try struct_il.find(p.gpa, index);
+            if (il.*.node == .none and actual_ty.eql(field.ty, p.comp, false)) return true;
+            if (try p.findScalarInitializer(il, ty, actual_ty, first_tok)) return true;
+        }
+        return false;
+    } else if (ty.get(.@"union")) |union_ty| {
+        if (il.*.node != .none) return false;
+        if (actual_ty.eql(ty.*, p.pp.comp, false)) return true;
+        if (union_ty.data.record.fields.len == 0) {
+            try p.errTok(.empty_aggregate_init_braces, first_tok);
+            return error.ParsingFailed;
+        }
+        ty.* = union_ty.data.record.fields[0].ty;
+        il.* = try il.*.find(p.gpa, 0);
+        // if (il.*.node == .none and actual_ty.eql(ty, p.pp.comp, false)) return true;
+        if (try p.findScalarInitializer(il, ty, actual_ty, first_tok)) return true;
+        return false;
+    }
+    return il.*.node == .none;
+}
+
+fn findAggregateInitializer(p: *Parser, il: **InitList, ty: *Type, start_index: *?u64) Error!bool {
+    if (ty.isArray()) {
+        if (il.*.node != .none) return false;
+        const list_index = il.*.list.items.len;
+        const index = if (start_index.*) |*some| blk: {
+            some.* += 1;
+            break :blk some.*;
+        } else if (list_index != 0)
+            il.*.list.items[list_index - 1].index + 1
+        else
+            list_index;
+
+        const arr_ty = ty.*;
+        const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64);
+        const elem_ty = arr_ty.elemType();
+        if (index < elem_count) {
+            ty.* = elem_ty;
+            il.* = try il.*.find(p.gpa, index);
+            return true;
+        }
+        return false;
+    } else if (ty.get(.@"struct")) |struct_ty| {
+        if (il.*.node != .none) return false;
+        const list_index = il.*.list.items.len;
+        const index = if (start_index.*) |*some| blk: {
+            some.* += 1;
+            break :blk some.*;
+        } else if (list_index != 0)
+            il.*.list.items[list_index - 1].index + 1
+        else
+            list_index;
+
+        const field_count = struct_ty.data.record.fields.len;
+        if (index < field_count) {
+            ty.* = struct_ty.data.record.fields[@intCast(index)].ty;
+            il.* = try il.*.find(p.gpa, index);
+            return true;
+        }
+        return false;
+    } else if (ty.get(.@"union")) |union_ty| {
+        if (il.*.node != .none) return false;
+        if (start_index.*) |_| return false; // overrides
+        if (union_ty.data.record.fields.len == 0) return false;
+
+        ty.* = union_ty.data.record.fields[0].ty;
+        il.* = try il.*.find(p.gpa, 0);
+        return true;
+    } else {
+        try p.err(.too_many_scalar_init_braces);
+        return il.*.node == .none;
+    }
+}
+
+fn coerceArrayInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !bool {
+    if (!target.isArray()) return false;
+
+    const is_str_lit = p.nodeIs(item.node, .string_literal_expr);
+    if (!is_str_lit and !p.nodeIs(item.node, .compound_literal_expr) or !item.ty.isArray()) {
+        try p.errTok(.array_init_str, tok);
+        return true; // do not do further coercion
+    }
+
+    const target_spec = target.elemType().canonicalize(.standard).specifier;
+    const item_spec = item.ty.elemType().canonicalize(.standard).specifier;
+
+    const compatible = target.elemType().eql(item.ty.elemType(), p.comp, false) or
+        (is_str_lit and item_spec == .char and (target_spec == .uchar or target_spec == .schar)) or
+        (is_str_lit and item_spec == .uchar and (target_spec == .uchar or target_spec == .schar or target_spec == .char));
+    if (!compatible) {
+        const e_msg = " with array of type ";
+        try p.errStr(.incompatible_array_init, tok, try p.typePairStrExtra(target, e_msg, item.ty));
+        return true; // do not do further coercion
+    }
+
+    if (target.get(.array)) |arr_ty| {
+        assert(item.ty.specifier == .array);
+        var len = item.ty.arrayLen().?;
+        const array_len = arr_ty.arrayLen().?;
+        if (is_str_lit) {
+            // the null byte of a string can be dropped
+            if (len - 1 > array_len)
+                try p.errTok(.str_init_too_long, tok);
+        } else if (len > array_len) {
+            try p.errStr(
+                .arr_init_too_long,
+                tok,
+                try p.typePairStrExtra(target, " with array of type ", item.ty),
+            );
+        }
+    }
+    return true;
+}
+
+fn coerceInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !void {
+    if (target.is(.void)) return; // Do not do type coercion on excess items
+
+    const node = item.node;
+    try item.lvalConversion(p);
+    if (target.is(.auto_type)) {
+        if (p.getNode(node, .member_access_expr) orelse p.getNode(node, .member_access_ptr_expr)) |member_node| {
+            if (Tree.isBitfield(p.nodes.slice(), member_node)) try p.errTok(.auto_type_from_bitfield, tok);
+        }
+        return;
+    }
+
+    try item.coerce(p, target, tok, .init);
+}
+
+fn isStringInit(p: *Parser, ty: Type) bool {
+    if (!ty.isArray() or !ty.elemType().isInt()) return false;
+    var i = p.tok_i;
+    while (true) : (i += 1) {
+        switch (p.tok_ids[i]) {
+            .l_paren => {},
+            .string_literal,
+            .string_literal_utf_16,
+            .string_literal_utf_8,
+            .string_literal_utf_32,
+            .string_literal_wide,
+            => return true,
+            else => return false,
+        }
+    }
+}
+
+/// Convert InitList into an AST
+fn convertInitList(p: *Parser, il: InitList, init_ty: Type) Error!NodeIndex {
+    const is_complex = init_ty.isComplex();
+    if (init_ty.isScalar() and !is_complex) {
+        if (il.node == .none) {
+            return p.addNode(.{ .tag = .default_init_expr, .ty = init_ty, .data = undefined });
+        }
+        return il.node;
+    } else if (init_ty.is(.variable_len_array)) {
+        return error.ParsingFailed; // vla invalid, reported earlier
+    } else if (init_ty.isArray() or is_complex) {
+        if (il.node != .none) {
+            return il.node;
+        }
+        const list_buf_top = p.list_buf.items.len;
+        defer p.list_buf.items.len = list_buf_top;
+
+        const elem_ty = init_ty.elemType();
+
+        const max_items: u64 = init_ty.expectedInitListSize() orelse std.math.maxInt(usize);
+        var start: u64 = 0;
+        for (il.list.items) |*init| {
+            if (init.index > start) {
+                const elem = try p.addNode(.{
+                    .tag = .array_filler_expr,
+                    .ty = elem_ty,
+                    .data = .{ .int = init.index - start },
+                });
+                try p.list_buf.append(elem);
+            }
+            start = init.index + 1;
+
+            const elem = try p.convertInitList(init.list, elem_ty);
+            try p.list_buf.append(elem);
+        }
+
+        var arr_init_node: Tree.Node = .{
+            .tag = .array_init_expr_two,
+            .ty = init_ty,
+            .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
+        };
+
+        if (init_ty.specifier == .incomplete_array) {
+            arr_init_node.ty.specifier = .array;
+            arr_init_node.ty.data.array.len = start;
+        } else if (init_ty.is(.incomplete_array)) {
+            const arr_ty = try p.arena.create(Type.Array);
+            arr_ty.* = .{ .elem = init_ty.elemType(), .len = start };
+            arr_init_node.ty = .{
+                .specifier = .array,
+                .data = .{ .array = arr_ty },
+            };
+            const attrs = init_ty.getAttributes();
+            arr_init_node.ty = try arr_init_node.ty.withAttributes(p.arena, attrs);
+        } else if (start < max_items) {
+            const elem = try p.addNode(.{
+                .tag = .array_filler_expr,
+                .ty = elem_ty,
+                .data = .{ .int = max_items - start },
+            });
+            try p.list_buf.append(elem);
+        }
+
+        const items = p.list_buf.items[list_buf_top..];
+        switch (items.len) {
+            0 => {},
+            1 => arr_init_node.data.bin.lhs = items[0],
+            2 => arr_init_node.data.bin = .{ .lhs = items[0], .rhs = items[1] },
+            else => {
+                arr_init_node.tag = .array_init_expr;
+                arr_init_node.data = .{ .range = try p.addList(items) };
+            },
+        }
+        return try p.addNode(arr_init_node);
+    } else if (init_ty.get(.@"struct")) |struct_ty| {
+        assert(!struct_ty.hasIncompleteSize());
+        if (il.node != .none) {
+            return il.node;
+        }
+
+        const list_buf_top = p.list_buf.items.len;
+        defer p.list_buf.items.len = list_buf_top;
+
+        var init_index: usize = 0;
+        for (struct_ty.data.record.fields, 0..) |f, i| {
+            if (init_index < il.list.items.len and il.list.items[init_index].index == i) {
+                const item = try p.convertInitList(il.list.items[init_index].list, f.ty);
+                try p.list_buf.append(item);
+                init_index += 1;
+            } else {
+                const item = try p.addNode(.{ .tag = .default_init_expr, .ty = f.ty, .data = undefined });
+                try p.list_buf.append(item);
+            }
+        }
+
+        var struct_init_node: Tree.Node = .{
+            .tag = .struct_init_expr_two,
+            .ty = init_ty,
+            .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
+        };
+        const items = p.list_buf.items[list_buf_top..];
+        switch (items.len) {
+            0 => {},
+            1 => struct_init_node.data.bin.lhs = items[0],
+            2 => struct_init_node.data.bin = .{ .lhs = items[0], .rhs = items[1] },
+            else => {
+                struct_init_node.tag = .struct_init_expr;
+                struct_init_node.data = .{ .range = try p.addList(items) };
+            },
+        }
+        return try p.addNode(struct_init_node);
+    } else if (init_ty.get(.@"union")) |union_ty| {
+        if (il.node != .none) {
+            return il.node;
+        }
+
+        var union_init_node: Tree.Node = .{
+            .tag = .union_init_expr,
+            .ty = init_ty,
+            .data = .{ .union_init = .{ .field_index = 0, .node = .none } },
+        };
+        if (union_ty.data.record.fields.len == 0) {
+            // do nothing for empty unions
+        } else if (il.list.items.len == 0) {
+            union_init_node.data.union_init.node = try p.addNode(.{
+                .tag = .default_init_expr,
+                .ty = init_ty,
+                .data = undefined,
+            });
+        } else {
+            const init = il.list.items[0];
+            const index: u32 = @truncate(init.index);
+            const field_ty = union_ty.data.record.fields[index].ty;
+            union_init_node.data.union_init = .{
+                .field_index = index,
+                .node = try p.convertInitList(init.list, field_ty),
+            };
+        }
+        return try p.addNode(union_init_node);
+    } else {
+        return error.ParsingFailed; // initializer target is invalid, reported earlier
+    }
+}
+
+fn msvcAsmStmt(p: *Parser) Error!?NodeIndex {
+    return p.todo("MSVC assembly statements");
+}
+
+/// asmOperand : ('[' IDENTIFIER ']')? asmStr '(' expr ')'
+fn asmOperand(p: *Parser, names: *std.ArrayList(?TokenIndex), constraints: *NodeList, exprs: *NodeList) Error!void {
+    if (p.eatToken(.l_bracket)) |l_bracket| {
+        const ident = (try p.eatIdentifier()) orelse {
+            try p.err(.expected_identifier);
+            return error.ParsingFailed;
+        };
+        try names.append(ident);
+        try p.expectClosing(l_bracket, .r_bracket);
+    } else {
+        try names.append(null);
+    }
+    const constraint = try p.asmStr();
+    try constraints.append(constraint.node);
+
+    const l_paren = p.eatToken(.l_paren) orelse {
+        try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .l_paren } });
+        return error.ParsingFailed;
+    };
+    const res = try p.expr();
+    try p.expectClosing(l_paren, .r_paren);
+    try res.expect(p);
+    try exprs.append(res.node);
+}
+
+/// gnuAsmStmt
+///  : asmStr
+///  | asmStr ':' asmOperand*
+///  | asmStr ':' asmOperand* ':' asmOperand*
+///  | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)*
+///  | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)* : IDENTIFIER (',' IDENTIFIER)*
+fn gnuAsmStmt(p: *Parser, quals: Tree.GNUAssemblyQualifiers, l_paren: TokenIndex) Error!NodeIndex {
+    const asm_str = try p.asmStr();
+    try p.checkAsmStr(asm_str.val, l_paren);
+
+    if (p.tok_ids[p.tok_i] == .r_paren) {
+        return p.addNode(.{
+            .tag = .gnu_asm_simple,
+            .ty = .{ .specifier = .void },
+            .data = .{ .un = asm_str.node },
+        });
+    }
+
+    const expected_items = 8; // arbitrarily chosen, most assembly will have fewer than 8 inputs/outputs/constraints/names
+    const bytes_needed = expected_items * @sizeOf(?TokenIndex) + expected_items * 3 * @sizeOf(NodeIndex);
+
+    var stack_fallback = std.heap.stackFallback(bytes_needed, p.comp.gpa);
+    const allocator = stack_fallback.get();
+
+    // TODO: Consider using a TokenIndex of 0 instead of null if we need to store the names in the tree
+    var names = std.ArrayList(?TokenIndex).initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded
+    defer names.deinit();
+    var constraints = NodeList.initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded
+    defer constraints.deinit();
+    var exprs = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded
+    defer exprs.deinit();
+    var clobbers = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded
+    defer clobbers.deinit();
+
+    // Outputs
+    var ate_extra_colon = false;
+    if (p.eatToken(.colon) orelse p.eatToken(.colon_colon)) |tok_i| {
+        ate_extra_colon = p.tok_ids[tok_i] == .colon_colon;
+        if (!ate_extra_colon) {
+            if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) {
+                while (true) {
+                    try p.asmOperand(&names, &constraints, &exprs);
+                    if (p.eatToken(.comma) == null) break;
+                }
+            }
+        }
+    }
+
+    const num_outputs = names.items.len;
+
+    // Inputs
+    if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) {
+        if (ate_extra_colon) {
+            ate_extra_colon = false;
+        } else {
+            ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon;
+            p.tok_i += 1;
+        }
+        if (!ate_extra_colon) {
+            if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) {
+                while (true) {
+                    try p.asmOperand(&names, &constraints, &exprs);
+                    if (p.eatToken(.comma) == null) break;
+                }
+            }
+        }
+    }
+    std.debug.assert(names.items.len == constraints.items.len and constraints.items.len == exprs.items.len);
+    const num_inputs = names.items.len - num_outputs;
+    _ = num_inputs;
+
+    // Clobbers
+    if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) {
+        if (ate_extra_colon) {
+            ate_extra_colon = false;
+        } else {
+            ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon;
+            p.tok_i += 1;
+        }
+        if (!ate_extra_colon and p.tok_ids[p.tok_i].isStringLiteral()) {
+            while (true) {
+                const clobber = try p.asmStr();
+                try clobbers.append(clobber.node);
+                if (p.eatToken(.comma) == null) break;
+            }
+        }
+    }
+
+    if (!quals.goto and (p.tok_ids[p.tok_i] != .r_paren or ate_extra_colon)) {
+        try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .r_paren } });
+        return error.ParsingFailed;
+    }
+
+    // Goto labels
+    var num_labels: u32 = 0;
+    if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon) {
+        if (!ate_extra_colon) {
+            p.tok_i += 1;
+        }
+        while (true) {
+            const ident = (try p.eatIdentifier()) orelse {
+                try p.err(.expected_identifier);
+                return error.ParsingFailed;
+            };
+            const ident_str = p.tokSlice(ident);
+            const label = p.findLabel(ident_str) orelse blk: {
+                try p.labels.append(.{ .unresolved_goto = ident });
+                break :blk ident;
+            };
+            try names.append(ident);
+
+            const elem_ty = try p.arena.create(Type);
+            elem_ty.* = .{ .specifier = .void };
+            const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
+
+            const label_addr_node = try p.addNode(.{
+                .tag = .addr_of_label,
+                .data = .{ .decl_ref = label },
+                .ty = result_ty,
+            });
+            try exprs.append(label_addr_node);
+
+            num_labels += 1;
+            if (p.eatToken(.comma) == null) break;
+        }
+    } else if (quals.goto) {
+        try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .colon } });
+        return error.ParsingFailed;
+    }
+
+    // TODO: validate and insert into AST
+    return .none;
+}
+
+fn checkAsmStr(p: *Parser, asm_str: Value, tok: TokenIndex) !void {
+    if (!p.comp.langopts.gnu_asm) {
+        const str = asm_str.data.bytes;
+        if (str.len() > 1) {
+            // Empty string (just a NUL byte) is ok because it does not emit any assembly
+            try p.errTok(.gnu_asm_disabled, tok);
+        }
+    }
+}
+
+/// assembly
+///  : keyword_asm asmQual* '(' asmStr ')'
+///  | keyword_asm asmQual* '(' gnuAsmStmt ')'
+///  | keyword_asm msvcAsmStmt
+fn assembly(p: *Parser, kind: enum { global, decl_label, stmt }) Error!?NodeIndex {
+    const asm_tok = p.tok_i;
+    switch (p.tok_ids[p.tok_i]) {
+        .keyword_asm => {
+            try p.err(.extension_token_used);
+            p.tok_i += 1;
+        },
+        .keyword_asm1, .keyword_asm2 => p.tok_i += 1,
+        else => return null,
+    }
+
+    if (!p.tok_ids[p.tok_i].canOpenGCCAsmStmt()) {
+        return p.msvcAsmStmt();
+    }
+
+    var quals: Tree.GNUAssemblyQualifiers = .{};
+    while (true) : (p.tok_i += 1) switch (p.tok_ids[p.tok_i]) {
+        .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => {
+            if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "volatile");
+            if (quals.@"volatile") try p.errStr(.duplicate_asm_qual, p.tok_i, "volatile");
+            quals.@"volatile" = true;
+        },
+        .keyword_inline, .keyword_inline1, .keyword_inline2 => {
+            if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "inline");
+            if (quals.@"inline") try p.errStr(.duplicate_asm_qual, p.tok_i, "inline");
+            quals.@"inline" = true;
+        },
+        .keyword_goto => {
+            if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "goto");
+            if (quals.goto) try p.errStr(.duplicate_asm_qual, p.tok_i, "goto");
+            quals.goto = true;
+        },
+        else => break,
+    };
+
+    const l_paren = try p.expectToken(.l_paren);
+    var result_node: NodeIndex = .none;
+    switch (kind) {
+        .decl_label => {
+            const asm_str = try p.asmStr();
+            const str = asm_str.val.data.bytes.trim(1); // remove null-terminator
+            const attr = Attribute{ .tag = .asm_label, .args = .{ .asm_label = .{ .name = str } }, .syntax = .keyword };
+            try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = asm_tok });
+        },
+        .global => {
+            const asm_str = try p.asmStr();
+            try p.checkAsmStr(asm_str.val, l_paren);
+            result_node = try p.addNode(.{
+                .tag = .file_scope_asm,
+                .ty = .{ .specifier = .void },
+                .data = .{ .decl = .{ .name = asm_tok, .node = asm_str.node } },
+            });
+        },
+        .stmt => result_node = try p.gnuAsmStmt(quals, l_paren),
+    }
+    try p.expectClosing(l_paren, .r_paren);
+
+    if (kind != .decl_label) _ = try p.expectToken(.semicolon);
+    return result_node;
+}
+
+/// Same as stringLiteral but errors on unicode and wide string literals
+fn asmStr(p: *Parser) Error!Result {
+    var i = p.tok_i;
+    while (true) : (i += 1) switch (p.tok_ids[i]) {
+        .string_literal => {},
+        .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32 => {
+            try p.errStr(.invalid_asm_str, p.tok_i, "unicode");
+            return error.ParsingFailed;
+        },
+        .string_literal_wide => {
+            try p.errStr(.invalid_asm_str, p.tok_i, "wide");
+            return error.ParsingFailed;
+        },
+        else => break,
+    };
+    return try p.stringLiteral();
+}
+
+// ====== statements ======
+
+/// stmt
+///  : labeledStmt
+///  | compoundStmt
+///  | keyword_if '(' expr ')' stmt (keyword_else stmt)?
+///  | keyword_switch '(' expr ')' stmt
+///  | keyword_while '(' expr ')' stmt
+///  | keyword_do stmt while '(' expr ')' ';'
+///  | keyword_for '(' (decl | expr? ';') expr? ';' expr? ')' stmt
+///  | keyword_goto (IDENTIFIER | ('*' expr)) ';'
+///  | keyword_continue ';'
+///  | keyword_break ';'
+///  | keyword_return expr? ';'
+///  | assembly ';'
+///  | expr? ';'
+fn stmt(p: *Parser) Error!NodeIndex {
+    if (try p.labeledStmt()) |some| return some;
+    if (try p.compoundStmt(false, null)) |some| return some;
+    if (p.eatToken(.keyword_if)) |_| {
+        const l_paren = try p.expectToken(.l_paren);
+        const cond_tok = p.tok_i;
+        var cond = try p.expr();
+        try cond.expect(p);
+        try cond.lvalConversion(p);
+        try cond.usualUnaryConversion(p, cond_tok);
+        if (!cond.ty.isScalar())
+            try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
+        try cond.saveValue(p);
+        try p.expectClosing(l_paren, .r_paren);
+
+        const then = try p.stmt();
+        const @"else" = if (p.eatToken(.keyword_else)) |_| try p.stmt() else .none;
+
+        if (then != .none and @"else" != .none)
+            return try p.addNode(.{
+                .tag = .if_then_else_stmt,
+                .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then, @"else" })).start } },
+            })
+        else
+            return try p.addNode(.{
+                .tag = .if_then_stmt,
+                .data = .{ .bin = .{ .lhs = cond.node, .rhs = then } },
+            });
+    }
+    if (p.eatToken(.keyword_switch)) |_| {
+        const l_paren = try p.expectToken(.l_paren);
+        const cond_tok = p.tok_i;
+        var cond = try p.expr();
+        try cond.expect(p);
+        try cond.lvalConversion(p);
+        try cond.usualUnaryConversion(p, cond_tok);
+
+        if (!cond.ty.isInt())
+            try p.errStr(.statement_int, l_paren + 1, try p.typeStr(cond.ty));
+        try cond.saveValue(p);
+        try p.expectClosing(l_paren, .r_paren);
+
+        const old_switch = p.@"switch";
+        var @"switch" = Switch{
+            .ranges = std.ArrayList(Switch.Range).init(p.gpa),
+            .ty = cond.ty,
+        };
+        p.@"switch" = &@"switch";
+        defer {
+            @"switch".ranges.deinit();
+            p.@"switch" = old_switch;
+        }
+
+        const body = try p.stmt();
+
+        return try p.addNode(.{
+            .tag = .switch_stmt,
+            .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
+        });
+    }
+    if (p.eatToken(.keyword_while)) |_| {
+        const l_paren = try p.expectToken(.l_paren);
+        const cond_tok = p.tok_i;
+        var cond = try p.expr();
+        try cond.expect(p);
+        try cond.lvalConversion(p);
+        try cond.usualUnaryConversion(p, cond_tok);
+        if (!cond.ty.isScalar())
+            try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
+        try cond.saveValue(p);
+        try p.expectClosing(l_paren, .r_paren);
+
+        const body = body: {
+            const old_loop = p.in_loop;
+            p.in_loop = true;
+            defer p.in_loop = old_loop;
+            break :body try p.stmt();
+        };
+
+        return try p.addNode(.{
+            .tag = .while_stmt,
+            .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
+        });
+    }
+    if (p.eatToken(.keyword_do)) |_| {
+        const body = body: {
+            const old_loop = p.in_loop;
+            p.in_loop = true;
+            defer p.in_loop = old_loop;
+            break :body try p.stmt();
+        };
+
+        _ = try p.expectToken(.keyword_while);
+        const l_paren = try p.expectToken(.l_paren);
+        const cond_tok = p.tok_i;
+        var cond = try p.expr();
+        try cond.expect(p);
+        try cond.lvalConversion(p);
+        try cond.usualUnaryConversion(p, cond_tok);
+
+        if (!cond.ty.isScalar())
+            try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
+        try cond.saveValue(p);
+        try p.expectClosing(l_paren, .r_paren);
+
+        _ = try p.expectToken(.semicolon);
+        return try p.addNode(.{
+            .tag = .do_while_stmt,
+            .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
+        });
+    }
+    if (p.eatToken(.keyword_for)) |_| {
+        try p.syms.pushScope(p);
+        defer p.syms.popScope();
+        const decl_buf_top = p.decl_buf.items.len;
+        defer p.decl_buf.items.len = decl_buf_top;
+
+        const l_paren = try p.expectToken(.l_paren);
+        const got_decl = try p.decl();
+
+        // for (init
+        const init_start = p.tok_i;
+        var err_start = p.comp.diag.list.items.len;
+        var init = if (!got_decl) try p.expr() else Result{};
+        try init.saveValue(p);
+        try init.maybeWarnUnused(p, init_start, err_start);
+        if (!got_decl) _ = try p.expectToken(.semicolon);
+
+        // for (init; cond
+        const cond_tok = p.tok_i;
+        var cond = try p.expr();
+        if (cond.node != .none) {
+            try cond.lvalConversion(p);
+            try cond.usualUnaryConversion(p, cond_tok);
+            if (!cond.ty.isScalar())
+                try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
+        }
+        try cond.saveValue(p);
+        _ = try p.expectToken(.semicolon);
+
+        // for (init; cond; incr
+        const incr_start = p.tok_i;
+        err_start = p.comp.diag.list.items.len;
+        var incr = try p.expr();
+        try incr.maybeWarnUnused(p, incr_start, err_start);
+        try incr.saveValue(p);
+        try p.expectClosing(l_paren, .r_paren);
+
+        const body = body: {
+            const old_loop = p.in_loop;
+            p.in_loop = true;
+            defer p.in_loop = old_loop;
+            break :body try p.stmt();
+        };
+
+        if (got_decl) {
+            const start = (try p.addList(p.decl_buf.items[decl_buf_top..])).start;
+            const end = (try p.addList(&.{ cond.node, incr.node, body })).end;
+
+            return try p.addNode(.{
+                .tag = .for_decl_stmt,
+                .data = .{ .range = .{ .start = start, .end = end } },
+            });
+        } else if (init.node == .none and cond.node == .none and incr.node == .none) {
+            return try p.addNode(.{
+                .tag = .forever_stmt,
+                .data = .{ .un = body },
+            });
+        } else return try p.addNode(.{ .tag = .for_stmt, .data = .{ .if3 = .{
+            .cond = body,
+            .body = (try p.addList(&.{ init.node, cond.node, incr.node })).start,
+        } } });
+    }
+    if (p.eatToken(.keyword_goto)) |goto_tok| {
+        if (p.eatToken(.asterisk)) |_| {
+            const expr_tok = p.tok_i;
+            var e = try p.expr();
+            try e.expect(p);
+            try e.lvalConversion(p);
+            p.computed_goto_tok = p.computed_goto_tok orelse goto_tok;
+            if (!e.ty.isPtr()) {
+                const elem_ty = try p.arena.create(Type);
+                elem_ty.* = .{ .specifier = .void, .qual = .{ .@"const" = true } };
+                const result_ty = Type{
+                    .specifier = .pointer,
+                    .data = .{ .sub_type = elem_ty },
+                };
+                if (!e.ty.isInt()) {
+                    try p.errStr(.incompatible_arg, expr_tok, try p.typePairStrExtra(e.ty, " to parameter of incompatible type ", result_ty));
+                    return error.ParsingFailed;
+                }
+                if (e.val.isZero()) {
+                    try e.nullCast(p, result_ty);
+                } else {
+                    try p.errStr(.implicit_int_to_ptr, expr_tok, try p.typePairStrExtra(e.ty, " to ", result_ty));
+                    try e.ptrCast(p, result_ty);
+                }
+            }
+
+            try e.un(p, .computed_goto_stmt);
+            _ = try p.expectToken(.semicolon);
+            return e.node;
+        }
+        const name_tok = try p.expectIdentifier();
+        const str = p.tokSlice(name_tok);
+        if (p.findLabel(str) == null) {
+            try p.labels.append(.{ .unresolved_goto = name_tok });
+        }
+        _ = try p.expectToken(.semicolon);
+        return try p.addNode(.{
+            .tag = .goto_stmt,
+            .data = .{ .decl_ref = name_tok },
+        });
+    }
+    if (p.eatToken(.keyword_continue)) |cont| {
+        if (!p.in_loop) try p.errTok(.continue_not_in_loop, cont);
+        _ = try p.expectToken(.semicolon);
+        return try p.addNode(.{ .tag = .continue_stmt, .data = undefined });
+    }
+    if (p.eatToken(.keyword_break)) |br| {
+        if (!p.in_loop and p.@"switch" == null) try p.errTok(.break_not_in_loop_or_switch, br);
+        _ = try p.expectToken(.semicolon);
+        return try p.addNode(.{ .tag = .break_stmt, .data = undefined });
+    }
+    if (try p.returnStmt()) |some| return some;
+    if (try p.assembly(.stmt)) |some| return some;
+
+    const expr_start = p.tok_i;
+    const err_start = p.comp.diag.list.items.len;
+
+    const e = try p.expr();
+    if (e.node != .none) {
+        _ = try p.expectToken(.semicolon);
+        try e.maybeWarnUnused(p, expr_start, err_start);
+        return e.node;
+    }
+
+    const attr_buf_top = p.attr_buf.len;
+    defer p.attr_buf.len = attr_buf_top;
+    try p.attributeSpecifier();
+
+    if (p.eatToken(.semicolon)) |_| {
+        var null_node: Tree.Node = .{ .tag = .null_stmt, .data = undefined };
+        null_node.ty = try Attribute.applyStatementAttributes(p, null_node.ty, expr_start, attr_buf_top);
+        return p.addNode(null_node);
+    }
+
+    try p.err(.expected_stmt);
+    return error.ParsingFailed;
+}
+
+/// labeledStmt
+/// : IDENTIFIER ':' stmt
+/// | keyword_case integerConstExpr ':' stmt
+/// | keyword_default ':' stmt
+fn labeledStmt(p: *Parser) Error!?NodeIndex {
+    if ((p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) and p.tok_ids[p.tok_i + 1] == .colon) {
+        const name_tok = p.expectIdentifier() catch unreachable;
+        const str = p.tokSlice(name_tok);
+        if (p.findLabel(str)) |some| {
+            try p.errStr(.duplicate_label, name_tok, str);
+            try p.errStr(.previous_label, some, str);
+        } else {
+            p.label_count += 1;
+            try p.labels.append(.{ .label = name_tok });
+            var i: usize = 0;
+            while (i < p.labels.items.len) {
+                if (p.labels.items[i] == .unresolved_goto and
+                    mem.eql(u8, p.tokSlice(p.labels.items[i].unresolved_goto), str))
+                {
+                    _ = p.labels.swapRemove(i);
+                } else i += 1;
+            }
+        }
+
+        p.tok_i += 1;
+        const attr_buf_top = p.attr_buf.len;
+        defer p.attr_buf.len = attr_buf_top;
+        try p.attributeSpecifier();
+
+        var labeled_stmt = Tree.Node{
+            .tag = .labeled_stmt,
+            .data = .{ .decl = .{ .name = name_tok, .node = try p.stmt() } },
+        };
+        labeled_stmt.ty = try Attribute.applyLabelAttributes(p, labeled_stmt.ty, attr_buf_top);
+        return try p.addNode(labeled_stmt);
+    } else if (p.eatToken(.keyword_case)) |case| {
+        const first_item = try p.integerConstExpr(.gnu_folding_extension);
+        const ellipsis = p.tok_i;
+        const second_item = if (p.eatToken(.ellipsis) != null) blk: {
+            try p.errTok(.gnu_switch_range, ellipsis);
+            break :blk try p.integerConstExpr(.gnu_folding_extension);
+        } else null;
+        _ = try p.expectToken(.colon);
+
+        if (p.@"switch") |some| check: {
+            if (some.ty.hasIncompleteSize()) break :check; // error already reported for incomplete size
+
+            const first = first_item.val;
+            const last = if (second_item) |second| second.val else first;
+            if (first.tag == .unavailable) {
+                try p.errTok(.case_val_unavailable, case + 1);
+                break :check;
+            } else if (last.tag == .unavailable) {
+                try p.errTok(.case_val_unavailable, ellipsis + 1);
+                break :check;
+            } else if (last.compare(.lt, first, some.ty, p.comp)) {
+                try p.errTok(.empty_case_range, case + 1);
+                break :check;
+            }
+
+            // TODO cast to target type
+            const prev = (try some.add(p.comp, first, last, case + 1)) orelse break :check;
+
+            // TODO check which value was already handled
+            if (some.ty.isUnsignedInt(p.comp)) {
+                try p.errExtra(.duplicate_switch_case_unsigned, case + 1, .{
+                    .unsigned = first.data.int,
+                });
+            } else {
+                try p.errExtra(.duplicate_switch_case_signed, case + 1, .{
+                    .signed = first.signExtend(some.ty, p.comp),
+                });
+            }
+            try p.errTok(.previous_case, prev.tok);
+        } else {
+            try p.errStr(.case_not_in_switch, case, "case");
+        }
+
+        const s = try p.stmt();
+        if (second_item) |some| return try p.addNode(.{
+            .tag = .case_range_stmt,
+            .data = .{ .if3 = .{ .cond = s, .body = (try p.addList(&.{ first_item.node, some.node })).start } },
+        }) else return try p.addNode(.{
+            .tag = .case_stmt,
+            .data = .{ .bin = .{ .lhs = first_item.node, .rhs = s } },
+        });
+    } else if (p.eatToken(.keyword_default)) |default| {
+        _ = try p.expectToken(.colon);
+        const s = try p.stmt();
+        const node = try p.addNode(.{
+            .tag = .default_stmt,
+            .data = .{ .un = s },
+        });
+        const @"switch" = p.@"switch" orelse {
+            try p.errStr(.case_not_in_switch, default, "default");
+            return node;
+        };
+        if (@"switch".default) |previous| {
+            try p.errTok(.multiple_default, default);
+            try p.errTok(.previous_case, previous);
+        } else {
+            @"switch".default = default;
+        }
+        return node;
+    } else return null;
+}
+
+const StmtExprState = struct {
+    last_expr_tok: TokenIndex = 0,
+    last_expr_res: Result = .{ .ty = .{ .specifier = .void } },
+};
+
+/// compoundStmt : '{' ( decl | keyword_extension decl | staticAssert | stmt)* '}'
+fn compoundStmt(p: *Parser, is_fn_body: bool, stmt_expr_state: ?*StmtExprState) Error!?NodeIndex {
+    const l_brace = p.eatToken(.l_brace) orelse return null;
+
+    const decl_buf_top = p.decl_buf.items.len;
+    defer p.decl_buf.items.len = decl_buf_top;
+
+    // the parameters of a function are in the same scope as the body
+    if (!is_fn_body) try p.syms.pushScope(p);
+    defer if (!is_fn_body) p.syms.popScope();
+
+    var noreturn_index: ?TokenIndex = null;
+    var noreturn_label_count: u32 = 0;
+
+    while (p.eatToken(.r_brace) == null) : (_ = try p.pragma()) {
+        if (stmt_expr_state) |state| state.* = .{};
+        if (try p.parseOrNextStmt(staticAssert, l_brace)) continue;
+        if (try p.parseOrNextStmt(decl, l_brace)) continue;
+        if (p.eatToken(.keyword_extension)) |ext| {
+            const saved_extension = p.extension_suppressed;
+            defer p.extension_suppressed = saved_extension;
+            p.extension_suppressed = true;
+
+            if (try p.parseOrNextStmt(decl, l_brace)) continue;
+            p.tok_i = ext;
+        }
+        const stmt_tok = p.tok_i;
+        const s = p.stmt() catch |er| switch (er) {
+            error.ParsingFailed => {
+                try p.nextStmt(l_brace);
+                continue;
+            },
+            else => |e| return e,
+        };
+        if (s == .none) continue;
+        if (stmt_expr_state) |state| {
+            state.* = .{
+                .last_expr_tok = stmt_tok,
+                .last_expr_res = .{
+                    .node = s,
+                    .ty = p.nodes.items(.ty)[@intFromEnum(s)],
+                },
+            };
+        }
+        try p.decl_buf.append(s);
+
+        if (noreturn_index == null and p.nodeIsNoreturn(s) == .yes) {
+            noreturn_index = p.tok_i;
+            noreturn_label_count = p.label_count;
+        }
+        switch (p.nodes.items(.tag)[@intFromEnum(s)]) {
+            .case_stmt, .default_stmt, .labeled_stmt => noreturn_index = null,
+            else => {},
+        }
+    }
+
+    if (noreturn_index) |some| {
+        // if new labels were defined we cannot be certain that the code is unreachable
+        if (some != p.tok_i - 1 and noreturn_label_count == p.label_count) try p.errTok(.unreachable_code, some);
+    }
+    if (is_fn_body) {
+        const last_noreturn = if (p.decl_buf.items.len == decl_buf_top)
+            .no
+        else
+            p.nodeIsNoreturn(p.decl_buf.items[p.decl_buf.items.len - 1]);
+
+        if (last_noreturn != .yes) {
+            const ret_ty = p.func.ty.?.returnType();
+            var return_zero = false;
+            if (last_noreturn == .no and !ret_ty.is(.void) and !ret_ty.isFunc() and !ret_ty.isArray()) {
+                const func_name = p.tokSlice(p.func.name);
+                const interned_name = try p.comp.intern(func_name);
+                if (interned_name == p.string_ids.main_id and ret_ty.is(.int)) {
+                    return_zero = true;
+                } else {
+                    try p.errStr(.func_does_not_return, p.tok_i - 1, func_name);
+                }
+            }
+            try p.decl_buf.append(try p.addNode(.{ .tag = .implicit_return, .ty = p.func.ty.?.returnType(), .data = .{ .return_zero = return_zero } }));
+        }
+        if (p.func.ident) |some| try p.decl_buf.insert(decl_buf_top, some.node);
+        if (p.func.pretty_ident) |some| try p.decl_buf.insert(decl_buf_top, some.node);
+    }
+
+    var node: Tree.Node = .{
+        .tag = .compound_stmt_two,
+        .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
+    };
+    const statements = p.decl_buf.items[decl_buf_top..];
+    switch (statements.len) {
+        0 => {},
+        1 => node.data = .{ .bin = .{ .lhs = statements[0], .rhs = .none } },
+        2 => node.data = .{ .bin = .{ .lhs = statements[0], .rhs = statements[1] } },
+        else => {
+            node.tag = .compound_stmt;
+            node.data = .{ .range = try p.addList(statements) };
+        },
+    }
+    return try p.addNode(node);
+}
+
+const NoreturnKind = enum { no, yes, complex };
+
+fn nodeIsNoreturn(p: *Parser, node: NodeIndex) NoreturnKind {
+    switch (p.nodes.items(.tag)[@intFromEnum(node)]) {
+        .break_stmt, .continue_stmt, .return_stmt => return .yes,
+        .if_then_else_stmt => {
+            const data = p.data.items[p.nodes.items(.data)[@intFromEnum(node)].if3.body..];
+            const then_type = p.nodeIsNoreturn(data[0]);
+            const else_type = p.nodeIsNoreturn(data[1]);
+            if (then_type == .complex or else_type == .complex) return .complex;
+            if (then_type == .yes and else_type == .yes) return .yes;
+            return .no;
+        },
+        .compound_stmt_two => {
+            const data = p.nodes.items(.data)[@intFromEnum(node)];
+            if (data.bin.rhs != .none) return p.nodeIsNoreturn(data.bin.rhs);
+            if (data.bin.lhs != .none) return p.nodeIsNoreturn(data.bin.lhs);
+            return .no;
+        },
+        .compound_stmt => {
+            const data = p.nodes.items(.data)[@intFromEnum(node)];
+            return p.nodeIsNoreturn(p.data.items[data.range.end - 1]);
+        },
+        .labeled_stmt => {
+            const data = p.nodes.items(.data)[@intFromEnum(node)];
+            return p.nodeIsNoreturn(data.decl.node);
+        },
+        .switch_stmt => {
+            const data = p.nodes.items(.data)[@intFromEnum(node)];
+            if (data.bin.rhs == .none) return .complex;
+            if (p.nodeIsNoreturn(data.bin.rhs) == .yes) return .yes;
+            return .complex;
+        },
+        else => return .no,
+    }
+}
+
+fn parseOrNextStmt(p: *Parser, comptime func: fn (*Parser) Error!bool, l_brace: TokenIndex) !bool {
+    return func(p) catch |er| switch (er) {
+        error.ParsingFailed => {
+            try p.nextStmt(l_brace);
+            return true;
+        },
+        else => |e| return e,
+    };
+}
+
+fn nextStmt(p: *Parser, l_brace: TokenIndex) !void {
+    var parens: u32 = 0;
+    while (p.tok_i < p.tok_ids.len) : (p.tok_i += 1) {
+        switch (p.tok_ids[p.tok_i]) {
+            .l_paren, .l_brace, .l_bracket => parens += 1,
+            .r_paren, .r_bracket => if (parens != 0) {
+                parens -= 1;
+            },
+            .r_brace => if (parens == 0)
+                return
+            else {
+                parens -= 1;
+            },
+            .semicolon,
+            .keyword_for,
+            .keyword_while,
+            .keyword_do,
+            .keyword_if,
+            .keyword_goto,
+            .keyword_switch,
+            .keyword_case,
+            .keyword_default,
+            .keyword_continue,
+            .keyword_break,
+            .keyword_return,
+            .keyword_typedef,
+            .keyword_extern,
+            .keyword_static,
+            .keyword_auto,
+            .keyword_register,
+            .keyword_thread_local,
+            .keyword_c23_thread_local,
+            .keyword_inline,
+            .keyword_inline1,
+            .keyword_inline2,
+            .keyword_noreturn,
+            .keyword_void,
+            .keyword_bool,
+            .keyword_c23_bool,
+            .keyword_char,
+            .keyword_short,
+            .keyword_int,
+            .keyword_long,
+            .keyword_signed,
+            .keyword_unsigned,
+            .keyword_float,
+            .keyword_double,
+            .keyword_complex,
+            .keyword_atomic,
+            .keyword_enum,
+            .keyword_struct,
+            .keyword_union,
+            .keyword_alignas,
+            .keyword_c23_alignas,
+            .keyword_typeof,
+            .keyword_typeof1,
+            .keyword_typeof2,
+            .keyword_extension,
+            => if (parens == 0) return,
+            .keyword_pragma => p.skipToPragmaSentinel(),
+            else => {},
+        }
+    }
+    p.tok_i -= 1; // So we can consume EOF
+    try p.expectClosing(l_brace, .r_brace);
+    unreachable;
+}
+
+fn returnStmt(p: *Parser) Error!?NodeIndex {
+    const ret_tok = p.eatToken(.keyword_return) orelse return null;
+
+    const e_tok = p.tok_i;
+    var e = try p.expr();
+    _ = try p.expectToken(.semicolon);
+    const ret_ty = p.func.ty.?.returnType();
+
+    if (p.func.ty.?.hasAttribute(.noreturn)) {
+        try p.errStr(.invalid_noreturn, e_tok, p.tokSlice(p.func.name));
+    }
+
+    if (e.node == .none) {
+        if (!ret_ty.is(.void)) try p.errStr(.func_should_return, ret_tok, p.tokSlice(p.func.name));
+        return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
+    } else if (ret_ty.is(.void)) {
+        try p.errStr(.void_func_returns_value, e_tok, p.tokSlice(p.func.name));
+        return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
+    }
+
+    try e.lvalConversion(p);
+    try e.coerce(p, ret_ty, e_tok, .ret);
+
+    try e.saveValue(p);
+    return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
+}
+
+// ====== expressions ======
+
+pub fn macroExpr(p: *Parser) Compilation.Error!bool {
+    const res = p.condExpr() catch |e| switch (e) {
+        error.OutOfMemory => return error.OutOfMemory,
+        error.FatalError => return error.FatalError,
+        error.ParsingFailed => return false,
+    };
+    if (res.val.tag == .unavailable) {
+        try p.errTok(.expected_expr, p.tok_i);
+        return false;
+    }
+    return res.val.getBool();
+}
+
+const CallExpr = union(enum) {
+    standard: NodeIndex,
+    builtin: struct {
+        node: NodeIndex,
+        tag: BuiltinFunction.Tag,
+    },
+
+    fn init(p: *Parser, call_node: NodeIndex, func_node: NodeIndex) CallExpr {
+        if (p.getNode(call_node, .builtin_call_expr_one)) |node| {
+            const data = p.nodes.items(.data)[@intFromEnum(node)];
+            const name = p.tokSlice(data.decl.name);
+            const builtin_ty = p.comp.builtins.lookup(name);
+            return .{ .builtin = .{ .node = node, .tag = builtin_ty.builtin.tag } };
+        }
+        return .{ .standard = func_node };
+    }
+
+    fn shouldPerformLvalConversion(self: CallExpr, arg_idx: u32) bool {
+        return switch (self) {
+            .standard => true,
+            .builtin => |builtin| switch (builtin.tag) {
+                .__builtin_va_start, .__va_start, .va_start => arg_idx != 1,
+                else => true,
+            },
+        };
+    }
+
+    fn shouldPromoteVarArg(self: CallExpr, arg_idx: u32) bool {
+        return switch (self) {
+            .standard => true,
+            .builtin => |builtin| switch (builtin.tag) {
+                .__builtin_va_start, .__va_start, .va_start => arg_idx != 1,
+                .__builtin_complex => false,
+                else => true,
+            },
+        };
+    }
+
+    fn shouldCoerceArg(self: CallExpr, arg_idx: u32) bool {
+        _ = self;
+        _ = arg_idx;
+        return true;
+    }
+
+    fn checkVarArg(self: CallExpr, p: *Parser, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, arg_idx: u32) !void {
+        if (self == .standard) return;
+
+        const builtin_tok = p.nodes.items(.data)[@intFromEnum(self.builtin.node)].decl.name;
+        switch (self.builtin.tag) {
+            .__builtin_va_start, .__va_start, .va_start => return p.checkVaStartArg(builtin_tok, first_after, param_tok, arg, arg_idx),
+            .__builtin_complex => return p.checkComplexArg(builtin_tok, first_after, param_tok, arg, arg_idx),
+            else => {},
+        }
+    }
+
+    /// Some functions cannot be expressed as standard C prototypes. For example `__builtin_complex` requires
+    /// two arguments of the same real floating point type (e.g. two doubles or two floats). These functions are
+    /// encoded as varargs functions with custom typechecking. Since varargs functions do not have a fixed number
+    /// of arguments, `paramCountOverride` is used to tell us how many arguments we should actually expect to see for
+    /// these custom-typechecked functions.
+    fn paramCountOverride(self: CallExpr) ?u32 {
+        return switch (self) {
+            .standard => null,
+            .builtin => |builtin| switch (builtin.tag) {
+                .__builtin_complex => 2,
+                else => null,
+            },
+        };
+    }
+
+    fn returnType(self: CallExpr, p: *Parser, callable_ty: Type) Type {
+        return switch (self) {
+            .standard => callable_ty.returnType(),
+            .builtin => |builtin| switch (builtin.tag) {
+                .__builtin_complex => {
+                    const last_param = p.list_buf.items[p.list_buf.items.len - 1];
+                    return p.nodes.items(.ty)[@intFromEnum(last_param)].makeComplex();
+                },
+                else => callable_ty.returnType(),
+            },
+        };
+    }
+
+    fn finish(self: CallExpr, p: *Parser, ty: Type, list_buf_top: usize, arg_count: u32) Error!Result {
+        const ret_ty = self.returnType(p, ty);
+        switch (self) {
+            .standard => |func_node| {
+                var call_node: Tree.Node = .{
+                    .tag = .call_expr_one,
+                    .ty = ret_ty,
+                    .data = .{ .bin = .{ .lhs = func_node, .rhs = .none } },
+                };
+                const args = p.list_buf.items[list_buf_top..];
+                switch (arg_count) {
+                    0 => {},
+                    1 => call_node.data.bin.rhs = args[1], // args[0] == func.node
+                    else => {
+                        call_node.tag = .call_expr;
+                        call_node.data = .{ .range = try p.addList(args) };
+                    },
+                }
+                return Result{ .node = try p.addNode(call_node), .ty = ret_ty };
+            },
+            .builtin => |builtin| {
+                const index = @intFromEnum(builtin.node);
+                var call_node = p.nodes.get(index);
+                defer p.nodes.set(index, call_node);
+                call_node.ty = ret_ty;
+                const args = p.list_buf.items[list_buf_top..];
+                switch (arg_count) {
+                    0 => {},
+                    1 => call_node.data.decl.node = args[1], // args[0] == func.node
+                    else => {
+                        call_node.tag = .builtin_call_expr;
+                        args[0] = @enumFromInt(call_node.data.decl.name);
+                        call_node.data = .{ .range = try p.addList(args) };
+                    },
+                }
+                return Result{ .node = builtin.node, .ty = ret_ty };
+            },
+        }
+    }
+};
+
+const Result = struct {
+    node: NodeIndex = .none,
+    ty: Type = .{ .specifier = .int },
+    val: Value = .{},
+
+    fn expect(res: Result, p: *Parser) Error!void {
+        if (p.in_macro) {
+            if (res.val.tag == .unavailable) {
+                try p.errTok(.expected_expr, p.tok_i);
+                return error.ParsingFailed;
+            }
+            return;
+        }
+        if (res.node == .none) {
+            try p.errTok(.expected_expr, p.tok_i);
+            return error.ParsingFailed;
+        }
+    }
+
+    fn empty(res: Result, p: *Parser) bool {
+        if (p.in_macro) return res.val.tag == .unavailable;
+        return res.node == .none;
+    }
+
+    fn maybeWarnUnused(res: Result, p: *Parser, expr_start: TokenIndex, err_start: usize) Error!void {
+        if (res.ty.is(.void) or res.node == .none) return;
+        // don't warn about unused result if the expression contained errors besides other unused results
+        for (p.comp.diag.list.items[err_start..]) |err_item| {
+            if (err_item.tag != .unused_value) return;
+        }
+        var cur_node = res.node;
+        while (true) switch (p.nodes.items(.tag)[@intFromEnum(cur_node)]) {
+            .invalid, // So that we don't need to check for node == 0
+            .assign_expr,
+            .mul_assign_expr,
+            .div_assign_expr,
+            .mod_assign_expr,
+            .add_assign_expr,
+            .sub_assign_expr,
+            .shl_assign_expr,
+            .shr_assign_expr,
+            .bit_and_assign_expr,
+            .bit_xor_assign_expr,
+            .bit_or_assign_expr,
+            .pre_inc_expr,
+            .pre_dec_expr,
+            .post_inc_expr,
+            .post_dec_expr,
+            => return,
+            .call_expr_one => {
+                const fn_ptr = p.nodes.items(.data)[@intFromEnum(cur_node)].bin.lhs;
+                const fn_ty = p.nodes.items(.ty)[@intFromEnum(fn_ptr)].elemType();
+                if (fn_ty.hasAttribute(.nodiscard)) try p.errStr(.nodiscard_unused, expr_start, "TODO get name");
+                if (fn_ty.hasAttribute(.warn_unused_result)) try p.errStr(.warn_unused_result, expr_start, "TODO get name");
+                return;
+            },
+            .call_expr => {
+                const fn_ptr = p.data.items[p.nodes.items(.data)[@intFromEnum(cur_node)].range.start];
+                const fn_ty = p.nodes.items(.ty)[@intFromEnum(fn_ptr)].elemType();
+                if (fn_ty.hasAttribute(.nodiscard)) try p.errStr(.nodiscard_unused, expr_start, "TODO get name");
+                if (fn_ty.hasAttribute(.warn_unused_result)) try p.errStr(.warn_unused_result, expr_start, "TODO get name");
+                return;
+            },
+            .stmt_expr => {
+                const body = p.nodes.items(.data)[@intFromEnum(cur_node)].un;
+                switch (p.nodes.items(.tag)[@intFromEnum(body)]) {
+                    .compound_stmt_two => {
+                        const body_stmt = p.nodes.items(.data)[@intFromEnum(body)].bin;
+                        cur_node = if (body_stmt.rhs != .none) body_stmt.rhs else body_stmt.lhs;
+                    },
+                    .compound_stmt => {
+                        const data = p.nodes.items(.data)[@intFromEnum(body)];
+                        cur_node = p.data.items[data.range.end - 1];
+                    },
+                    else => unreachable,
+                }
+            },
+            .comma_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].bin.rhs,
+            .paren_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].un,
+            else => break,
+        };
+        try p.errTok(.unused_value, expr_start);
+    }
+
+    fn boolRes(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result) !void {
+        if (lhs.val.tag == .nullptr_t) {
+            lhs.val = Value.int(0);
+        }
+        if (lhs.ty.specifier != .invalid) {
+            lhs.ty = Type.int;
+        }
+        return lhs.bin(p, tag, rhs);
+    }
+
+    fn bin(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result) !void {
+        lhs.node = try p.addNode(.{
+            .tag = tag,
+            .ty = lhs.ty,
+            .data = .{ .bin = .{ .lhs = lhs.node, .rhs = rhs.node } },
+        });
+    }
+
+    fn un(operand: *Result, p: *Parser, tag: Tree.Tag) Error!void {
+        operand.node = try p.addNode(.{
+            .tag = tag,
+            .ty = operand.ty,
+            .data = .{ .un = operand.node },
+        });
+    }
+
+    fn implicitCast(operand: *Result, p: *Parser, kind: Tree.CastKind) Error!void {
+        operand.node = try p.addNode(.{
+            .tag = .implicit_cast,
+            .ty = operand.ty,
+            .data = .{ .cast = .{ .operand = operand.node, .kind = kind } },
+        });
+    }
+
+    fn adjustCondExprPtrs(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) !bool {
+        assert(a.ty.isPtr() and b.ty.isPtr());
+
+        const a_elem = a.ty.elemType();
+        const b_elem = b.ty.elemType();
+        if (a_elem.eql(b_elem, p.comp, true)) return true;
+
+        var adjusted_elem_ty = try p.arena.create(Type);
+        adjusted_elem_ty.* = a_elem;
+
+        const has_void_star_branch = a.ty.isVoidStar() or b.ty.isVoidStar();
+        const only_quals_differ = a_elem.eql(b_elem, p.comp, false);
+        const pointers_compatible = only_quals_differ or has_void_star_branch;
+
+        if (!pointers_compatible or has_void_star_branch) {
+            if (!pointers_compatible) {
+                try p.errStr(.pointer_mismatch, tok, try p.typePairStrExtra(a.ty, " and ", b.ty));
+            }
+            adjusted_elem_ty.* = .{ .specifier = .void };
+        }
+        if (pointers_compatible) {
+            adjusted_elem_ty.qual = a_elem.qual.mergeCV(b_elem.qual);
+        }
+        if (!adjusted_elem_ty.eql(a_elem, p.comp, true)) {
+            a.ty = .{
+                .data = .{ .sub_type = adjusted_elem_ty },
+                .specifier = .pointer,
+            };
+            try a.implicitCast(p, .bitcast);
+        }
+        if (!adjusted_elem_ty.eql(b_elem, p.comp, true)) {
+            b.ty = .{
+                .data = .{ .sub_type = adjusted_elem_ty },
+                .specifier = .pointer,
+            };
+            try b.implicitCast(p, .bitcast);
+        }
+        return true;
+    }
+
+    /// Adjust types for binary operation, returns true if the result can and should be evaluated.
+    fn adjustTypes(a: *Result, tok: TokenIndex, b: *Result, p: *Parser, kind: enum {
+        integer,
+        arithmetic,
+        boolean_logic,
+        relational,
+        equality,
+        conditional,
+        add,
+        sub,
+    }) !bool {
+        if (b.ty.specifier == .invalid) {
+            try a.saveValue(p);
+            a.ty = Type.invalid;
+        }
+        if (a.ty.specifier == .invalid) {
+            return false;
+        }
+        try a.lvalConversion(p);
+        try b.lvalConversion(p);
+
+        const a_vec = a.ty.is(.vector);
+        const b_vec = b.ty.is(.vector);
+        if (a_vec and b_vec) {
+            if (a.ty.eql(b.ty, p.comp, false)) {
+                return a.shouldEval(b, p);
+            }
+            return a.invalidBinTy(tok, b, p);
+        } else if (a_vec) {
+            if (b.coerceExtra(p, a.ty.elemType(), tok, .test_coerce)) {
+                try b.saveValue(p);
+                try b.implicitCast(p, .vector_splat);
+                return a.shouldEval(b, p);
+            } else |er| switch (er) {
+                error.CoercionFailed => return a.invalidBinTy(tok, b, p),
+                else => |e| return e,
+            }
+        } else if (b_vec) {
+            if (a.coerceExtra(p, b.ty.elemType(), tok, .test_coerce)) {
+                try a.saveValue(p);
+                try a.implicitCast(p, .vector_splat);
+                return a.shouldEval(b, p);
+            } else |er| switch (er) {
+                error.CoercionFailed => return a.invalidBinTy(tok, b, p),
+                else => |e| return e,
+            }
+        }
+
+        const a_int = a.ty.isInt();
+        const b_int = b.ty.isInt();
+        if (a_int and b_int) {
+            try a.usualArithmeticConversion(b, p, tok);
+            return a.shouldEval(b, p);
+        }
+        if (kind == .integer) return a.invalidBinTy(tok, b, p);
+
+        const a_float = a.ty.isFloat();
+        const b_float = b.ty.isFloat();
+        const a_arithmetic = a_int or a_float;
+        const b_arithmetic = b_int or b_float;
+        if (a_arithmetic and b_arithmetic) {
+            // <, <=, >, >= only work on real types
+            if (kind == .relational and (!a.ty.isReal() or !b.ty.isReal()))
+                return a.invalidBinTy(tok, b, p);
+
+            try a.usualArithmeticConversion(b, p, tok);
+            return a.shouldEval(b, p);
+        }
+        if (kind == .arithmetic) return a.invalidBinTy(tok, b, p);
+
+        const a_nullptr = a.ty.is(.nullptr_t);
+        const b_nullptr = b.ty.is(.nullptr_t);
+        const a_ptr = a.ty.isPtr();
+        const b_ptr = b.ty.isPtr();
+        const a_scalar = a_arithmetic or a_ptr;
+        const b_scalar = b_arithmetic or b_ptr;
+        switch (kind) {
+            .boolean_logic => {
+                if (!(a_scalar or a_nullptr) or !(b_scalar or b_nullptr)) return a.invalidBinTy(tok, b, p);
+
+                // Do integer promotions but nothing else
+                if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok);
+                if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
+                return a.shouldEval(b, p);
+            },
+            .relational, .equality => {
+                if (kind == .equality and (a_nullptr or b_nullptr)) {
+                    if (a_nullptr and b_nullptr) return a.shouldEval(b, p);
+                    const nullptr_res = if (a_nullptr) a else b;
+                    const other_res = if (a_nullptr) b else a;
+                    if (other_res.ty.isPtr()) {
+                        try nullptr_res.nullCast(p, other_res.ty);
+                        return other_res.shouldEval(nullptr_res, p);
+                    } else if (other_res.val.isZero()) {
+                        other_res.val = .{ .tag = .nullptr_t };
+                        try other_res.nullCast(p, nullptr_res.ty);
+                        return other_res.shouldEval(nullptr_res, p);
+                    }
+                    return a.invalidBinTy(tok, b, p);
+                }
+                // comparisons between floats and pointes not allowed
+                if (!a_scalar or !b_scalar or (a_float and b_ptr) or (b_float and a_ptr))
+                    return a.invalidBinTy(tok, b, p);
+
+                if ((a_int or b_int) and !(a.val.isZero() or b.val.isZero())) {
+                    try p.errStr(.comparison_ptr_int, tok, try p.typePairStr(a.ty, b.ty));
+                } else if (a_ptr and b_ptr) {
+                    if (!a.ty.isVoidStar() and !b.ty.isVoidStar() and !a.ty.eql(b.ty, p.comp, false))
+                        try p.errStr(.comparison_distinct_ptr, tok, try p.typePairStr(a.ty, b.ty));
+                } else if (a_ptr) {
+                    try b.ptrCast(p, a.ty);
+                } else {
+                    assert(b_ptr);
+                    try a.ptrCast(p, b.ty);
+                }
+
+                return a.shouldEval(b, p);
+            },
+            .conditional => {
+                // doesn't matter what we return here, as the result is ignored
+                if (a.ty.is(.void) or b.ty.is(.void)) {
+                    try a.toVoid(p);
+                    try b.toVoid(p);
+                    return true;
+                }
+                if (a_nullptr and b_nullptr) return true;
+                if ((a_ptr and b_int) or (a_int and b_ptr)) {
+                    if (a.val.isZero() or b.val.isZero()) {
+                        try a.nullCast(p, b.ty);
+                        try b.nullCast(p, a.ty);
+                        return true;
+                    }
+                    const int_ty = if (a_int) a else b;
+                    const ptr_ty = if (a_ptr) a else b;
+                    try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(int_ty.ty, " to ", ptr_ty.ty));
+                    try int_ty.ptrCast(p, ptr_ty.ty);
+
+                    return true;
+                }
+                if (a_ptr and b_ptr) return a.adjustCondExprPtrs(tok, b, p);
+                if ((a_ptr and b_nullptr) or (a_nullptr and b_ptr)) {
+                    const nullptr_res = if (a_nullptr) a else b;
+                    const ptr_res = if (a_nullptr) b else a;
+                    try nullptr_res.nullCast(p, ptr_res.ty);
+                    return true;
+                }
+                if (a.ty.isRecord() and b.ty.isRecord() and a.ty.eql(b.ty, p.comp, false)) {
+                    return true;
+                }
+                return a.invalidBinTy(tok, b, p);
+            },
+            .add => {
+                // if both aren't arithmetic one should be pointer and the other an integer
+                if (a_ptr == b_ptr or a_int == b_int) return a.invalidBinTy(tok, b, p);
+
+                // Do integer promotions but nothing else
+                if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok);
+                if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
+
+                // The result type is the type of the pointer operand
+                if (a_int) a.ty = b.ty else b.ty = a.ty;
+                return a.shouldEval(b, p);
+            },
+            .sub => {
+                // if both aren't arithmetic then either both should be pointers or just a
+                if (!a_ptr or !(b_ptr or b_int)) return a.invalidBinTy(tok, b, p);
+
+                if (a_ptr and b_ptr) {
+                    if (!a.ty.eql(b.ty, p.comp, false)) try p.errStr(.incompatible_pointers, tok, try p.typePairStr(a.ty, b.ty));
+                    a.ty = p.comp.types.ptrdiff;
+                }
+
+                // Do integer promotion on b if needed
+                if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
+                return a.shouldEval(b, p);
+            },
+            else => return a.invalidBinTy(tok, b, p),
+        }
+    }
+
+    fn lvalConversion(res: *Result, p: *Parser) Error!void {
+        if (res.ty.isFunc()) {
+            var elem_ty = try p.arena.create(Type);
+            elem_ty.* = res.ty;
+            res.ty.specifier = .pointer;
+            res.ty.data = .{ .sub_type = elem_ty };
+            try res.implicitCast(p, .function_to_pointer);
+        } else if (res.ty.isArray()) {
+            res.val.tag = .unavailable;
+            res.ty.decayArray();
+            try res.implicitCast(p, .array_to_pointer);
+        } else if (!p.in_macro and Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, res.node)) {
+            res.ty.qual = .{};
+            try res.implicitCast(p, .lval_to_rval);
+        }
+    }
+
+    fn boolCast(res: *Result, p: *Parser, bool_ty: Type, tok: TokenIndex) Error!void {
+        if (res.ty.isArray()) {
+            if (res.val.tag == .bytes) {
+                try p.errStr(.string_literal_to_bool, tok, try p.typePairStrExtra(res.ty, " to ", bool_ty));
+            } else {
+                try p.errStr(.array_address_to_bool, tok, p.tokSlice(tok));
+            }
+            try res.lvalConversion(p);
+            res.val = Value.int(1);
+            res.ty = bool_ty;
+            try res.implicitCast(p, .pointer_to_bool);
+        } else if (res.ty.isPtr()) {
+            res.val.toBool();
+            res.ty = bool_ty;
+            try res.implicitCast(p, .pointer_to_bool);
+        } else if (res.ty.isInt() and !res.ty.is(.bool)) {
+            res.val.toBool();
+            res.ty = bool_ty;
+            try res.implicitCast(p, .int_to_bool);
+        } else if (res.ty.isFloat()) {
+            const old_value = res.val;
+            const value_change_kind = res.val.floatToInt(res.ty, bool_ty, p.comp);
+            try res.floatToIntWarning(p, bool_ty, old_value, value_change_kind, tok);
+            if (!res.ty.isReal()) {
+                res.ty = res.ty.makeReal();
+                try res.implicitCast(p, .complex_float_to_real);
+            }
+            res.ty = bool_ty;
+            try res.implicitCast(p, .float_to_bool);
+        }
+    }
+
+    fn intCast(res: *Result, p: *Parser, int_ty: Type, tok: TokenIndex) Error!void {
+        if (int_ty.hasIncompleteSize()) return error.ParsingFailed; // Diagnostic already issued
+        if (res.ty.is(.bool)) {
+            res.ty = int_ty.makeReal();
+            try res.implicitCast(p, .bool_to_int);
+            if (!int_ty.isReal()) {
+                res.ty = int_ty;
+                try res.implicitCast(p, .real_to_complex_int);
+            }
+        } else if (res.ty.isPtr()) {
+            res.ty = int_ty.makeReal();
+            try res.implicitCast(p, .pointer_to_int);
+            if (!int_ty.isReal()) {
+                res.ty = int_ty;
+                try res.implicitCast(p, .real_to_complex_int);
+            }
+        } else if (res.ty.isFloat()) {
+            const old_value = res.val;
+            const value_change_kind = res.val.floatToInt(res.ty, int_ty, p.comp);
+            try res.floatToIntWarning(p, int_ty, old_value, value_change_kind, tok);
+            const old_real = res.ty.isReal();
+            const new_real = int_ty.isReal();
+            if (old_real and new_real) {
+                res.ty = int_ty;
+                try res.implicitCast(p, .float_to_int);
+            } else if (old_real) {
+                res.ty = int_ty.makeReal();
+                try res.implicitCast(p, .float_to_int);
+                res.ty = int_ty;
+                try res.implicitCast(p, .real_to_complex_int);
+            } else if (new_real) {
+                res.ty = res.ty.makeReal();
+                try res.implicitCast(p, .complex_float_to_real);
+                res.ty = int_ty;
+                try res.implicitCast(p, .float_to_int);
+            } else {
+                res.ty = int_ty;
+                try res.implicitCast(p, .complex_float_to_complex_int);
+            }
+        } else if (!res.ty.eql(int_ty, p.comp, true)) {
+            res.val.intCast(res.ty, int_ty, p.comp);
+            const old_real = res.ty.isReal();
+            const new_real = int_ty.isReal();
+            if (old_real and new_real) {
+                res.ty = int_ty;
+                try res.implicitCast(p, .int_cast);
+            } else if (old_real) {
+                const real_int_ty = int_ty.makeReal();
+                if (!res.ty.eql(real_int_ty, p.comp, false)) {
+                    res.ty = real_int_ty;
+                    try res.implicitCast(p, .int_cast);
+                }
+                res.ty = int_ty;
+                try res.implicitCast(p, .real_to_complex_int);
+            } else if (new_real) {
+                res.ty = res.ty.makeReal();
+                try res.implicitCast(p, .complex_int_to_real);
+                res.ty = int_ty;
+                try res.implicitCast(p, .int_cast);
+            } else {
+                res.ty = int_ty;
+                try res.implicitCast(p, .complex_int_cast);
+            }
+        }
+    }
+
+    fn floatToIntWarning(res: *Result, p: *Parser, int_ty: Type, old_value: Value, change_kind: Value.FloatToIntChangeKind, tok: TokenIndex) !void {
+        switch (change_kind) {
+            .none => return p.errStr(.float_to_int, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
+            .out_of_range => return p.errStr(.float_out_of_range, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
+            .overflow => return p.errStr(.float_overflow_conversion, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
+            .nonzero_to_zero => return p.errStr(.float_zero_conversion, tok, try p.floatValueChangedStr(res, old_value.getFloat(f64), int_ty)),
+            .value_changed => return p.errStr(.float_value_changed, tok, try p.floatValueChangedStr(res, old_value.getFloat(f64), int_ty)),
+        }
+    }
+
+    fn floatCast(res: *Result, p: *Parser, float_ty: Type) Error!void {
+        if (res.ty.is(.bool)) {
+            res.val.intToFloat(res.ty, float_ty, p.comp);
+            res.ty = float_ty.makeReal();
+            try res.implicitCast(p, .bool_to_float);
+            if (!float_ty.isReal()) {
+                res.ty = float_ty;
+                try res.implicitCast(p, .real_to_complex_float);
+            }
+        } else if (res.ty.isInt()) {
+            res.val.intToFloat(res.ty, float_ty, p.comp);
+            const old_real = res.ty.isReal();
+            const new_real = float_ty.isReal();
+            if (old_real and new_real) {
+                res.ty = float_ty;
+                try res.implicitCast(p, .int_to_float);
+            } else if (old_real) {
+                res.ty = float_ty.makeReal();
+                try res.implicitCast(p, .int_to_float);
+                res.ty = float_ty;
+                try res.implicitCast(p, .real_to_complex_float);
+            } else if (new_real) {
+                res.ty = res.ty.makeReal();
+                try res.implicitCast(p, .complex_int_to_real);
+                res.ty = float_ty;
+                try res.implicitCast(p, .int_to_float);
+            } else {
+                res.ty = float_ty;
+                try res.implicitCast(p, .complex_int_to_complex_float);
+            }
+        } else if (!res.ty.eql(float_ty, p.comp, true)) {
+            res.val.floatCast(res.ty, float_ty, p.comp);
+            const old_real = res.ty.isReal();
+            const new_real = float_ty.isReal();
+            if (old_real and new_real) {
+                res.ty = float_ty;
+                try res.implicitCast(p, .float_cast);
+            } else if (old_real) {
+                if (res.ty.floatRank() != float_ty.floatRank()) {
+                    res.ty = float_ty.makeReal();
+                    try res.implicitCast(p, .float_cast);
+                }
+                res.ty = float_ty;
+                try res.implicitCast(p, .real_to_complex_float);
+            } else if (new_real) {
+                res.ty = res.ty.makeReal();
+                try res.implicitCast(p, .complex_float_to_real);
+                if (res.ty.floatRank() != float_ty.floatRank()) {
+                    res.ty = float_ty;
+                    try res.implicitCast(p, .float_cast);
+                }
+            } else {
+                res.ty = float_ty;
+                try res.implicitCast(p, .complex_float_cast);
+            }
+        }
+    }
+
+    /// Converts a bool or integer to a pointer
+    fn ptrCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
+        if (res.ty.is(.bool)) {
+            res.ty = ptr_ty;
+            try res.implicitCast(p, .bool_to_pointer);
+        } else if (res.ty.isInt()) {
+            res.val.intCast(res.ty, ptr_ty, p.comp);
+            res.ty = ptr_ty;
+            try res.implicitCast(p, .int_to_pointer);
+        }
+    }
+
+    /// Convert pointer to one with a different child type
+    fn ptrChildTypeCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
+        res.ty = ptr_ty;
+        return res.implicitCast(p, .bitcast);
+    }
+
+    fn toVoid(res: *Result, p: *Parser) Error!void {
+        if (!res.ty.is(.void)) {
+            res.ty = .{ .specifier = .void };
+            try res.implicitCast(p, .to_void);
+        }
+    }
+
+    fn nullCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
+        if (!res.ty.is(.nullptr_t) and !res.val.isZero()) return;
+        res.ty = ptr_ty;
+        try res.implicitCast(p, .null_to_pointer);
+    }
+
+    fn usualUnaryConversion(res: *Result, p: *Parser, tok: TokenIndex) Error!void {
+        if (res.ty.isFloat()) fp_eval: {
+            const eval_method = p.comp.langopts.fp_eval_method orelse break :fp_eval;
+            switch (eval_method) {
+                .source => {},
+                .indeterminate => unreachable,
+                .double => {
+                    if (res.ty.floatRank() < (Type{ .specifier = .double }).floatRank()) {
+                        const spec: Type.Specifier = if (res.ty.isReal()) .double else .complex_double;
+                        return res.floatCast(p, .{ .specifier = spec });
+                    }
+                },
+                .extended => {
+                    if (res.ty.floatRank() < (Type{ .specifier = .long_double }).floatRank()) {
+                        const spec: Type.Specifier = if (res.ty.isReal()) .long_double else .complex_long_double;
+                        return res.floatCast(p, .{ .specifier = spec });
+                    }
+                },
+            }
+        }
+
+        if (res.ty.is(.fp16) and !p.comp.langopts.use_native_half_type) {
+            return res.floatCast(p, .{ .specifier = .float });
+        }
+        if (res.ty.isInt()) {
+            const slice = p.nodes.slice();
+            if (Tree.bitfieldWidth(slice, res.node, true)) |width| {
+                if (res.ty.bitfieldPromotion(p.comp, width)) |promotion_ty| {
+                    return res.intCast(p, promotion_ty, tok);
+                }
+            }
+            return res.intCast(p, res.ty.integerPromotion(p.comp), tok);
+        }
+    }
+
+    fn usualArithmeticConversion(a: *Result, b: *Result, p: *Parser, tok: TokenIndex) Error!void {
+        try a.usualUnaryConversion(p, tok);
+        try b.usualUnaryConversion(p, tok);
+
+        // if either is a float cast to that type
+        if (a.ty.isFloat() or b.ty.isFloat()) {
+            const float_types = [7][2]Type.Specifier{
+                .{ .complex_long_double, .long_double },
+                .{ .complex_float128, .float128 },
+                .{ .complex_float80, .float80 },
+                .{ .complex_double, .double },
+                .{ .complex_float, .float },
+                // No `_Complex __fp16` type
+                .{ .invalid, .fp16 },
+                // No `_Complex _Float16`
+                .{ .invalid, .float16 },
+            };
+            const a_spec = a.ty.canonicalize(.standard).specifier;
+            const b_spec = b.ty.canonicalize(.standard).specifier;
+            if (p.comp.target.c_type_bit_size(.longdouble) == 128) {
+                if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
+            }
+            if (try a.floatConversion(b, a_spec, b_spec, p, float_types[1])) return;
+            if (p.comp.target.c_type_bit_size(.longdouble) == 80) {
+                if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
+            }
+            if (try a.floatConversion(b, a_spec, b_spec, p, float_types[2])) return;
+            if (p.comp.target.c_type_bit_size(.longdouble) == 64) {
+                if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
+            }
+            if (try a.floatConversion(b, a_spec, b_spec, p, float_types[3])) return;
+            if (try a.floatConversion(b, a_spec, b_spec, p, float_types[4])) return;
+            if (try a.floatConversion(b, a_spec, b_spec, p, float_types[5])) return;
+            if (try a.floatConversion(b, a_spec, b_spec, p, float_types[6])) return;
+        }
+
+        if (a.ty.eql(b.ty, p.comp, true)) {
+            // cast to promoted type
+            try a.intCast(p, a.ty, tok);
+            try b.intCast(p, b.ty, tok);
+            return;
+        }
+
+        const target = a.ty.integerConversion(b.ty, p.comp);
+        if (!target.isReal()) {
+            try a.saveValue(p);
+            try b.saveValue(p);
+        }
+        try a.intCast(p, target, tok);
+        try b.intCast(p, target, tok);
+    }
+
+    fn floatConversion(a: *Result, b: *Result, a_spec: Type.Specifier, b_spec: Type.Specifier, p: *Parser, pair: [2]Type.Specifier) !bool {
+        if (a_spec == pair[0] or a_spec == pair[1] or
+            b_spec == pair[0] or b_spec == pair[1])
+        {
+            const both_real = a.ty.isReal() and b.ty.isReal();
+            const res_spec = pair[@intFromBool(both_real)];
+            const ty = Type{ .specifier = res_spec };
+            try a.floatCast(p, ty);
+            try b.floatCast(p, ty);
+            return true;
+        }
+        return false;
+    }
+
+    fn invalidBinTy(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) Error!bool {
+        try p.errStr(.invalid_bin_types, tok, try p.typePairStr(a.ty, b.ty));
+        a.val.tag = .unavailable;
+        b.val.tag = .unavailable;
+        a.ty = Type.invalid;
+        return false;
+    }
+
+    fn shouldEval(a: *Result, b: *Result, p: *Parser) Error!bool {
+        if (p.no_eval) return false;
+        if (a.val.tag != .unavailable and b.val.tag != .unavailable)
+            return true;
+
+        try a.saveValue(p);
+        try b.saveValue(p);
+        return p.no_eval;
+    }
+
+    /// Saves value and replaces it with `.unavailable`.
+    fn saveValue(res: *Result, p: *Parser) !void {
+        assert(!p.in_macro);
+        if (res.val.tag == .unavailable or res.val.tag == .nullptr_t) return;
+        if (!p.in_macro) try p.value_map.put(res.node, res.val);
+        res.val.tag = .unavailable;
+    }
+
+    fn castType(res: *Result, p: *Parser, to: Type, tok: TokenIndex) !void {
+        var cast_kind: Tree.CastKind = undefined;
+
+        if (to.is(.void)) {
+            // everything can cast to void
+            cast_kind = .to_void;
+            res.val.tag = .unavailable;
+        } else if (to.is(.nullptr_t)) {
+            if (res.ty.is(.nullptr_t)) {
+                cast_kind = .no_op;
+            } else {
+                try p.errStr(.invalid_object_cast, tok, try p.typePairStrExtra(res.ty, " to ", to));
+                return error.ParsingFailed;
+            }
+        } else if (res.ty.is(.nullptr_t)) {
+            if (to.is(.bool)) {
+                try res.nullCast(p, res.ty);
+                res.val.toBool();
+                res.ty = .{ .specifier = .bool };
+                try res.implicitCast(p, .pointer_to_bool);
+                try res.saveValue(p);
+            } else if (to.isPtr()) {
+                try res.nullCast(p, to);
+            } else {
+                try p.errStr(.invalid_object_cast, tok, try p.typePairStrExtra(res.ty, " to ", to));
+                return error.ParsingFailed;
+            }
+            cast_kind = .no_op;
+        } else if (res.val.isZero() and to.isPtr()) {
+            cast_kind = .null_to_pointer;
+        } else if (to.isScalar()) cast: {
+            const old_float = res.ty.isFloat();
+            const new_float = to.isFloat();
+
+            if (new_float and res.ty.isPtr()) {
+                try p.errStr(.invalid_cast_to_float, tok, try p.typeStr(to));
+                return error.ParsingFailed;
+            } else if (old_float and to.isPtr()) {
+                try p.errStr(.invalid_cast_to_pointer, tok, try p.typeStr(res.ty));
+                return error.ParsingFailed;
+            }
+            const old_real = res.ty.isReal();
+            const new_real = to.isReal();
+
+            if (to.eql(res.ty, p.comp, false)) {
+                cast_kind = .no_op;
+            } else if (to.is(.bool)) {
+                if (res.ty.isPtr()) {
+                    cast_kind = .pointer_to_bool;
+                } else if (res.ty.isInt()) {
+                    if (!old_real) {
+                        res.ty = res.ty.makeReal();
+                        try res.implicitCast(p, .complex_int_to_real);
+                    }
+                    cast_kind = .int_to_bool;
+                } else if (old_float) {
+                    if (!old_real) {
+                        res.ty = res.ty.makeReal();
+                        try res.implicitCast(p, .complex_float_to_real);
+                    }
+                    cast_kind = .float_to_bool;
+                }
+            } else if (to.isInt()) {
+                if (res.ty.is(.bool)) {
+                    if (!new_real) {
+                        res.ty = to.makeReal();
+                        try res.implicitCast(p, .bool_to_int);
+                        cast_kind = .real_to_complex_int;
+                    } else {
+                        cast_kind = .bool_to_int;
+                    }
+                } else if (res.ty.isInt()) {
+                    if (old_real and new_real) {
+                        cast_kind = .int_cast;
+                    } else if (old_real) {
+                        res.ty = to.makeReal();
+                        try res.implicitCast(p, .int_cast);
+                        cast_kind = .real_to_complex_int;
+                    } else if (new_real) {
+                        res.ty = res.ty.makeReal();
+                        try res.implicitCast(p, .complex_int_to_real);
+                        cast_kind = .int_cast;
+                    } else {
+                        cast_kind = .complex_int_cast;
+                    }
+                } else if (res.ty.isPtr()) {
+                    if (!new_real) {
+                        res.ty = to.makeReal();
+                        try res.implicitCast(p, .pointer_to_int);
+                        cast_kind = .real_to_complex_int;
+                    } else {
+                        cast_kind = .pointer_to_int;
+                    }
+                } else if (old_real and new_real) {
+                    cast_kind = .float_to_int;
+                } else if (old_real) {
+                    res.ty = to.makeReal();
+                    try res.implicitCast(p, .float_to_int);
+                    cast_kind = .real_to_complex_int;
+                } else if (new_real) {
+                    res.ty = res.ty.makeReal();
+                    try res.implicitCast(p, .complex_float_to_real);
+                    cast_kind = .float_to_int;
+                } else {
+                    cast_kind = .complex_float_to_complex_int;
+                }
+            } else if (to.isPtr()) {
+                if (res.ty.isArray())
+                    cast_kind = .array_to_pointer
+                else if (res.ty.isPtr())
+                    cast_kind = .bitcast
+                else if (res.ty.isFunc())
+                    cast_kind = .function_to_pointer
+                else if (res.ty.is(.bool))
+                    cast_kind = .bool_to_pointer
+                else if (res.ty.isInt()) {
+                    if (!old_real) {
+                        res.ty = res.ty.makeReal();
+                        try res.implicitCast(p, .complex_int_to_real);
+                    }
+                    cast_kind = .int_to_pointer;
+                }
+            } else if (new_float) {
+                if (res.ty.is(.bool)) {
+                    if (!new_real) {
+                        res.ty = to.makeReal();
+                        try res.implicitCast(p, .bool_to_float);
+                        cast_kind = .real_to_complex_float;
+                    } else {
+                        cast_kind = .bool_to_float;
+                    }
+                } else if (res.ty.isInt()) {
+                    if (old_real and new_real) {
+                        cast_kind = .int_to_float;
+                    } else if (old_real) {
+                        res.ty = to.makeReal();
+                        try res.implicitCast(p, .int_to_float);
+                        cast_kind = .real_to_complex_float;
+                    } else if (new_real) {
+                        res.ty = res.ty.makeReal();
+                        try res.implicitCast(p, .complex_int_to_real);
+                        cast_kind = .int_to_float;
+                    } else {
+                        cast_kind = .complex_int_to_complex_float;
+                    }
+                } else if (old_real and new_real) {
+                    cast_kind = .float_cast;
+                } else if (old_real) {
+                    res.ty = to.makeReal();
+                    try res.implicitCast(p, .float_cast);
+                    cast_kind = .real_to_complex_float;
+                } else if (new_real) {
+                    res.ty = res.ty.makeReal();
+                    try res.implicitCast(p, .complex_float_to_real);
+                    cast_kind = .float_cast;
+                } else {
+                    cast_kind = .complex_float_cast;
+                }
+            }
+            if (res.val.tag == .unavailable) break :cast;
+
+            const old_int = res.ty.isInt() or res.ty.isPtr();
+            const new_int = to.isInt() or to.isPtr();
+            if (to.is(.bool)) {
+                res.val.toBool();
+            } else if (old_float and new_int) {
+                // Explicit cast, no conversion warning
+                _ = res.val.floatToInt(res.ty, to, p.comp);
+            } else if (new_float and old_int) {
+                res.val.intToFloat(res.ty, to, p.comp);
+            } else if (new_float and old_float) {
+                res.val.floatCast(res.ty, to, p.comp);
+            } else if (old_int and new_int) {
+                if (to.hasIncompleteSize()) {
+                    try p.errStr(.cast_to_incomplete_type, tok, try p.typeStr(to));
+                    return error.ParsingFailed;
+                }
+                res.val.intCast(res.ty, to, p.comp);
+            }
+        } else if (to.get(.@"union")) |union_ty| {
+            if (union_ty.data.record.hasFieldOfType(res.ty, p.comp)) {
+                cast_kind = .union_cast;
+                try p.errTok(.gnu_union_cast, tok);
+            } else {
+                if (union_ty.data.record.isIncomplete()) {
+                    try p.errStr(.cast_to_incomplete_type, tok, try p.typeStr(to));
+                } else {
+                    try p.errStr(.invalid_union_cast, tok, try p.typeStr(res.ty));
+                }
+                return error.ParsingFailed;
+            }
+        } else {
+            if (to.is(.auto_type)) {
+                try p.errTok(.invalid_cast_to_auto_type, tok);
+            } else {
+                try p.errStr(.invalid_cast_type, tok, try p.typeStr(to));
+            }
+            return error.ParsingFailed;
+        }
+        if (to.anyQual()) try p.errStr(.qual_cast, tok, try p.typeStr(to));
+        if (to.isInt() and res.ty.isPtr() and to.sizeCompare(res.ty, p.comp) == .lt) {
+            try p.errStr(.cast_to_smaller_int, tok, try p.typePairStrExtra(to, " from ", res.ty));
+        }
+        res.ty = to;
+        res.ty.qual = .{};
+        res.node = try p.addNode(.{
+            .tag = .explicit_cast,
+            .ty = res.ty,
+            .data = .{ .cast = .{ .operand = res.node, .kind = cast_kind } },
+        });
+    }
+
+    fn intFitsInType(res: Result, p: *Parser, ty: Type) bool {
+        const max_int = Value.int(ty.maxInt(p.comp));
+        const min_int = Value.int(ty.minInt(p.comp));
+        return res.val.compare(.lte, max_int, res.ty, p.comp) and
+            (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, min_int, res.ty, p.comp));
+    }
+
+    const CoerceContext = union(enum) {
+        assign,
+        init,
+        ret,
+        arg: TokenIndex,
+        test_coerce,
+
+        fn note(ctx: CoerceContext, p: *Parser) !void {
+            switch (ctx) {
+                .arg => |tok| try p.errTok(.parameter_here, tok),
+                .test_coerce => unreachable,
+                else => {},
+            }
+        }
+
+        fn typePairStr(ctx: CoerceContext, p: *Parser, dest_ty: Type, src_ty: Type) ![]const u8 {
+            switch (ctx) {
+                .assign, .init => return p.typePairStrExtra(dest_ty, " from incompatible type ", src_ty),
+                .ret => return p.typePairStrExtra(src_ty, " from a function with incompatible result type ", dest_ty),
+                .arg => return p.typePairStrExtra(src_ty, " to parameter of incompatible type ", dest_ty),
+                .test_coerce => unreachable,
+            }
+        }
+    };
+
+    /// Perform assignment-like coercion to `dest_ty`.
+    fn coerce(res: *Result, p: *Parser, dest_ty: Type, tok: TokenIndex, ctx: CoerceContext) Error!void {
+        if (res.ty.specifier == .invalid or dest_ty.specifier == .invalid) {
+            res.ty = Type.invalid;
+            return;
+        }
+        return res.coerceExtra(p, dest_ty, tok, ctx) catch |er| switch (er) {
+            error.CoercionFailed => unreachable,
+            else => |e| return e,
+        };
+    }
+
+    const Stage1Limitation = Error || error{CoercionFailed};
+    fn coerceExtra(res: *Result, p: *Parser, dest_ty: Type, tok: TokenIndex, ctx: CoerceContext) Stage1Limitation!void {
+        // Subject of the coercion does not need to be qualified.
+        var unqual_ty = dest_ty.canonicalize(.standard);
+        unqual_ty.qual = .{};
+        if (unqual_ty.is(.nullptr_t)) {
+            if (res.ty.is(.nullptr_t)) return;
+        } else if (unqual_ty.is(.bool)) {
+            if (res.ty.isScalar() and !res.ty.is(.nullptr_t)) {
+                // this is ridiculous but it's what clang does
+                try res.boolCast(p, unqual_ty, tok);
+                return;
+            }
+        } else if (unqual_ty.isInt()) {
+            if (res.ty.isInt() or res.ty.isFloat()) {
+                try res.intCast(p, unqual_ty, tok);
+                return;
+            } else if (res.ty.isPtr()) {
+                if (ctx == .test_coerce) return error.CoercionFailed;
+                try p.errStr(.implicit_ptr_to_int, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty));
+                try ctx.note(p);
+                try res.intCast(p, unqual_ty, tok);
+                return;
+            }
+        } else if (unqual_ty.isFloat()) {
+            if (res.ty.isInt() or res.ty.isFloat()) {
+                try res.floatCast(p, unqual_ty);
+                return;
+            }
+        } else if (unqual_ty.isPtr()) {
+            if (res.ty.is(.nullptr_t) or res.val.isZero()) {
+                try res.nullCast(p, dest_ty);
+                return;
+            } else if (res.ty.isInt() and res.ty.isReal()) {
+                if (ctx == .test_coerce) return error.CoercionFailed;
+                try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty));
+                try ctx.note(p);
+                try res.ptrCast(p, unqual_ty);
+                return;
+            } else if (res.ty.isVoidStar() or unqual_ty.eql(res.ty, p.comp, true)) {
+                return; // ok
+            } else if (unqual_ty.isVoidStar() and res.ty.isPtr() or (res.ty.isInt() and res.ty.isReal())) {
+                return; // ok
+            } else if (unqual_ty.eql(res.ty, p.comp, false)) {
+                if (!unqual_ty.elemType().qual.hasQuals(res.ty.elemType().qual)) {
+                    try p.errStr(switch (ctx) {
+                        .assign => .ptr_assign_discards_quals,
+                        .init => .ptr_init_discards_quals,
+                        .ret => .ptr_ret_discards_quals,
+                        .arg => .ptr_arg_discards_quals,
+                        .test_coerce => return error.CoercionFailed,
+                    }, tok, try ctx.typePairStr(p, dest_ty, res.ty));
+                }
+                try res.ptrCast(p, unqual_ty);
+                return;
+            } else if (res.ty.isPtr()) {
+                const different_sign_only = unqual_ty.elemType().sameRankDifferentSign(res.ty.elemType(), p.comp);
+                try p.errStr(switch (ctx) {
+                    .assign => ([2]Diagnostics.Tag{ .incompatible_ptr_assign, .incompatible_ptr_assign_sign })[@intFromBool(different_sign_only)],
+                    .init => ([2]Diagnostics.Tag{ .incompatible_ptr_init, .incompatible_ptr_init_sign })[@intFromBool(different_sign_only)],
+                    .ret => ([2]Diagnostics.Tag{ .incompatible_return, .incompatible_return_sign })[@intFromBool(different_sign_only)],
+                    .arg => ([2]Diagnostics.Tag{ .incompatible_ptr_arg, .incompatible_ptr_arg_sign })[@intFromBool(different_sign_only)],
+                    .test_coerce => return error.CoercionFailed,
+                }, tok, try ctx.typePairStr(p, dest_ty, res.ty));
+                try ctx.note(p);
+                try res.ptrChildTypeCast(p, unqual_ty);
+                return;
+            }
+        } else if (unqual_ty.isRecord()) {
+            if (unqual_ty.eql(res.ty, p.comp, false)) {
+                return; // ok
+            }
+
+            if (ctx == .arg) if (unqual_ty.get(.@"union")) |union_ty| {
+                if (dest_ty.hasAttribute(.transparent_union)) transparent_union: {
+                    res.coerceExtra(p, union_ty.data.record.fields[0].ty, tok, .test_coerce) catch |er| switch (er) {
+                        error.CoercionFailed => break :transparent_union,
+                        else => |e| return e,
+                    };
+                    res.node = try p.addNode(.{
+                        .tag = .union_init_expr,
+                        .ty = dest_ty,
+                        .data = .{ .union_init = .{ .field_index = 0, .node = res.node } },
+                    });
+                    res.ty = dest_ty;
+                    return;
+                }
+            };
+        } else if (unqual_ty.is(.vector)) {
+            if (unqual_ty.eql(res.ty, p.comp, false)) {
+                return; // ok
+            }
+        } else {
+            if (ctx == .assign and (unqual_ty.isArray() or unqual_ty.isFunc())) {
+                try p.errTok(.not_assignable, tok);
+                return;
+            } else if (ctx == .test_coerce) {
+                return error.CoercionFailed;
+            }
+            // This case should not be possible and an error should have already been emitted but we
+            // might still have attempted to parse further so return error.ParsingFailed here to stop.
+            return error.ParsingFailed;
+        }
+
+        try p.errStr(switch (ctx) {
+            .assign => .incompatible_assign,
+            .init => .incompatible_init,
+            .ret => .incompatible_return,
+            .arg => .incompatible_arg,
+            .test_coerce => return error.CoercionFailed,
+        }, tok, try ctx.typePairStr(p, dest_ty, res.ty));
+        try ctx.note(p);
+    }
+};
+
+/// expr : assignExpr (',' assignExpr)*
+fn expr(p: *Parser) Error!Result {
+    var expr_start = p.tok_i;
+    var err_start = p.comp.diag.list.items.len;
+    var lhs = try p.assignExpr();
+    if (p.tok_ids[p.tok_i] == .comma) try lhs.expect(p);
+    while (p.eatToken(.comma)) |_| {
+        try lhs.maybeWarnUnused(p, expr_start, err_start);
+        expr_start = p.tok_i;
+        err_start = p.comp.diag.list.items.len;
+
+        var rhs = try p.assignExpr();
+        try rhs.expect(p);
+        try rhs.lvalConversion(p);
+        lhs.val = rhs.val;
+        lhs.ty = rhs.ty;
+        try lhs.bin(p, .comma_expr, rhs);
+    }
+    return lhs;
+}
+
+fn tokToTag(p: *Parser, tok: TokenIndex) Tree.Tag {
+    return switch (p.tok_ids[tok]) {
+        .equal => .assign_expr,
+        .asterisk_equal => .mul_assign_expr,
+        .slash_equal => .div_assign_expr,
+        .percent_equal => .mod_assign_expr,
+        .plus_equal => .add_assign_expr,
+        .minus_equal => .sub_assign_expr,
+        .angle_bracket_angle_bracket_left_equal => .shl_assign_expr,
+        .angle_bracket_angle_bracket_right_equal => .shr_assign_expr,
+        .ampersand_equal => .bit_and_assign_expr,
+        .caret_equal => .bit_xor_assign_expr,
+        .pipe_equal => .bit_or_assign_expr,
+        .equal_equal => .equal_expr,
+        .bang_equal => .not_equal_expr,
+        .angle_bracket_left => .less_than_expr,
+        .angle_bracket_left_equal => .less_than_equal_expr,
+        .angle_bracket_right => .greater_than_expr,
+        .angle_bracket_right_equal => .greater_than_equal_expr,
+        .angle_bracket_angle_bracket_left => .shl_expr,
+        .angle_bracket_angle_bracket_right => .shr_expr,
+        .plus => .add_expr,
+        .minus => .sub_expr,
+        .asterisk => .mul_expr,
+        .slash => .div_expr,
+        .percent => .mod_expr,
+        else => unreachable,
+    };
+}
+
+/// assignExpr
+///  : condExpr
+///  | unExpr ('=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=') assignExpr
+fn assignExpr(p: *Parser) Error!Result {
+    var lhs = try p.condExpr();
+    if (lhs.empty(p)) return lhs;
+
+    const tok = p.tok_i;
+    const eq = p.eatToken(.equal);
+    const mul = eq orelse p.eatToken(.asterisk_equal);
+    const div = mul orelse p.eatToken(.slash_equal);
+    const mod = div orelse p.eatToken(.percent_equal);
+    const add = mod orelse p.eatToken(.plus_equal);
+    const sub = add orelse p.eatToken(.minus_equal);
+    const shl = sub orelse p.eatToken(.angle_bracket_angle_bracket_left_equal);
+    const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right_equal);
+    const bit_and = shr orelse p.eatToken(.ampersand_equal);
+    const bit_xor = bit_and orelse p.eatToken(.caret_equal);
+    const bit_or = bit_xor orelse p.eatToken(.pipe_equal);
+
+    const tag = p.tokToTag(bit_or orelse return lhs);
+    var rhs = try p.assignExpr();
+    try rhs.expect(p);
+    try rhs.lvalConversion(p);
+
+    var is_const: bool = undefined;
+    if (!Tree.isLvalExtra(p.nodes.slice(), p.data.items, p.value_map, lhs.node, &is_const) or is_const) {
+        try p.errTok(.not_assignable, tok);
+        return error.ParsingFailed;
+    }
+
+    // adjustTypes will do do lvalue conversion but we do not want that
+    var lhs_copy = lhs;
+    switch (tag) {
+        .assign_expr => {}, // handle plain assignment separately
+        .mul_assign_expr,
+        .div_assign_expr,
+        .mod_assign_expr,
+        => {
+            if (rhs.val.isZero() and lhs.ty.isInt() and rhs.ty.isInt()) {
+                switch (tag) {
+                    .div_assign_expr => try p.errStr(.division_by_zero, div.?, "division"),
+                    .mod_assign_expr => try p.errStr(.division_by_zero, mod.?, "remainder"),
+                    else => {},
+                }
+            }
+            _ = try lhs_copy.adjustTypes(tok, &rhs, p, if (tag == .mod_assign_expr) .integer else .arithmetic);
+            try lhs.bin(p, tag, rhs);
+            return lhs;
+        },
+        .sub_assign_expr,
+        .add_assign_expr,
+        => {
+            if (lhs.ty.isPtr() and rhs.ty.isInt()) {
+                try rhs.ptrCast(p, lhs.ty);
+            } else {
+                _ = try lhs_copy.adjustTypes(tok, &rhs, p, .arithmetic);
+            }
+            try lhs.bin(p, tag, rhs);
+            return lhs;
+        },
+        .shl_assign_expr,
+        .shr_assign_expr,
+        .bit_and_assign_expr,
+        .bit_xor_assign_expr,
+        .bit_or_assign_expr,
+        => {
+            _ = try lhs_copy.adjustTypes(tok, &rhs, p, .integer);
+            try lhs.bin(p, tag, rhs);
+            return lhs;
+        },
+        else => unreachable,
+    }
+
+    try rhs.coerce(p, lhs.ty, tok, .assign);
+
+    try lhs.bin(p, tag, rhs);
+    return lhs;
+}
+
+/// Returns a parse error if the expression is not an integer constant
+/// integerConstExpr : constExpr
+fn integerConstExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result {
+    const start = p.tok_i;
+    const res = try p.constExpr(decl_folding);
+    if (!res.ty.isInt() and res.ty.specifier != .invalid) {
+        try p.errTok(.expected_integer_constant_expr, start);
+        return error.ParsingFailed;
+    }
+    return res;
+}
+
+/// Caller is responsible for issuing a diagnostic if result is invalid/unavailable
+/// constExpr : condExpr
+fn constExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result {
+    const const_decl_folding = p.const_decl_folding;
+    defer p.const_decl_folding = const_decl_folding;
+    p.const_decl_folding = decl_folding;
+
+    const res = try p.condExpr();
+    try res.expect(p);
+
+    if (res.ty.specifier == .invalid or res.val.tag == .unavailable) return res;
+
+    // saveValue sets val to unavailable
+    var copy = res;
+    try copy.saveValue(p);
+    return res;
+}
+
+/// condExpr : lorExpr ('?' expression? ':' condExpr)?
+fn condExpr(p: *Parser) Error!Result {
+    const cond_tok = p.tok_i;
+    var cond = try p.lorExpr();
+    if (cond.empty(p) or p.eatToken(.question_mark) == null) return cond;
+    try cond.lvalConversion(p);
+    const saved_eval = p.no_eval;
+
+    if (!cond.ty.isScalar()) {
+        try p.errStr(.cond_expr_type, cond_tok, try p.typeStr(cond.ty));
+        return error.ParsingFailed;
+    }
+
+    // Prepare for possible binary conditional expression.
+    var maybe_colon = p.eatToken(.colon);
+
+    // Depending on the value of the condition, avoid evaluating unreachable branches.
+    var then_expr = blk: {
+        defer p.no_eval = saved_eval;
+        if (cond.val.tag != .unavailable and !cond.val.getBool()) p.no_eval = true;
+        break :blk try p.expr();
+    };
+    try then_expr.expect(p);
+
+    // If we saw a colon then this is a binary conditional expression.
+    if (maybe_colon) |colon| {
+        var cond_then = cond;
+        cond_then.node = try p.addNode(.{ .tag = .cond_dummy_expr, .ty = cond.ty, .data = .{ .un = cond.node } });
+        _ = try cond_then.adjustTypes(colon, &then_expr, p, .conditional);
+        cond.ty = then_expr.ty;
+        cond.node = try p.addNode(.{
+            .tag = .binary_cond_expr,
+            .ty = cond.ty,
+            .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ cond_then.node, then_expr.node })).start } },
+        });
+        return cond;
+    }
+
+    const colon = try p.expectToken(.colon);
+    var else_expr = blk: {
+        defer p.no_eval = saved_eval;
+        if (cond.val.tag != .unavailable and cond.val.getBool()) p.no_eval = true;
+        break :blk try p.condExpr();
+    };
+    try else_expr.expect(p);
+
+    _ = try then_expr.adjustTypes(colon, &else_expr, p, .conditional);
+
+    if (cond.val.tag != .unavailable) {
+        cond.val = if (cond.val.getBool()) then_expr.val else else_expr.val;
+    } else {
+        try then_expr.saveValue(p);
+        try else_expr.saveValue(p);
+    }
+    cond.ty = then_expr.ty;
+    cond.node = try p.addNode(.{
+        .tag = .cond_expr,
+        .ty = cond.ty,
+        .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } },
+    });
+    return cond;
+}
+
+/// lorExpr : landExpr ('||' landExpr)*
+fn lorExpr(p: *Parser) Error!Result {
+    var lhs = try p.landExpr();
+    if (lhs.empty(p)) return lhs;
+    const saved_eval = p.no_eval;
+    defer p.no_eval = saved_eval;
+
+    while (p.eatToken(.pipe_pipe)) |tok| {
+        if (lhs.val.tag != .unavailable and lhs.val.getBool()) p.no_eval = true;
+        var rhs = try p.landExpr();
+        try rhs.expect(p);
+
+        if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) {
+            const res = @intFromBool(lhs.val.getBool() or rhs.val.getBool());
+            lhs.val = Value.int(res);
+        }
+        try lhs.boolRes(p, .bool_or_expr, rhs);
+    }
+    return lhs;
+}
+
+/// landExpr : orExpr ('&&' orExpr)*
+fn landExpr(p: *Parser) Error!Result {
+    var lhs = try p.orExpr();
+    if (lhs.empty(p)) return lhs;
+    const saved_eval = p.no_eval;
+    defer p.no_eval = saved_eval;
+
+    while (p.eatToken(.ampersand_ampersand)) |tok| {
+        if (lhs.val.tag != .unavailable and !lhs.val.getBool()) p.no_eval = true;
+        var rhs = try p.orExpr();
+        try rhs.expect(p);
+
+        if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) {
+            const res = @intFromBool(lhs.val.getBool() and rhs.val.getBool());
+            lhs.val = Value.int(res);
+        }
+        try lhs.boolRes(p, .bool_and_expr, rhs);
+    }
+    return lhs;
+}
+
+/// orExpr : xorExpr ('|' xorExpr)*
+fn orExpr(p: *Parser) Error!Result {
+    var lhs = try p.xorExpr();
+    if (lhs.empty(p)) return lhs;
+    while (p.eatToken(.pipe)) |tok| {
+        var rhs = try p.xorExpr();
+        try rhs.expect(p);
+
+        if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
+            lhs.val = lhs.val.bitOr(rhs.val, lhs.ty, p.comp);
+        }
+        try lhs.bin(p, .bit_or_expr, rhs);
+    }
+    return lhs;
+}
+
+/// xorExpr : andExpr ('^' andExpr)*
+fn xorExpr(p: *Parser) Error!Result {
+    var lhs = try p.andExpr();
+    if (lhs.empty(p)) return lhs;
+    while (p.eatToken(.caret)) |tok| {
+        var rhs = try p.andExpr();
+        try rhs.expect(p);
+
+        if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
+            lhs.val = lhs.val.bitXor(rhs.val, lhs.ty, p.comp);
+        }
+        try lhs.bin(p, .bit_xor_expr, rhs);
+    }
+    return lhs;
+}
+
+/// andExpr : eqExpr ('&' eqExpr)*
+fn andExpr(p: *Parser) Error!Result {
+    var lhs = try p.eqExpr();
+    if (lhs.empty(p)) return lhs;
+    while (p.eatToken(.ampersand)) |tok| {
+        var rhs = try p.eqExpr();
+        try rhs.expect(p);
+
+        if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
+            lhs.val = lhs.val.bitAnd(rhs.val, lhs.ty, p.comp);
+        }
+        try lhs.bin(p, .bit_and_expr, rhs);
+    }
+    return lhs;
+}
+
+/// eqExpr : compExpr (('==' | '!=') compExpr)*
+fn eqExpr(p: *Parser) Error!Result {
+    var lhs = try p.compExpr();
+    if (lhs.empty(p)) return lhs;
+    while (true) {
+        const eq = p.eatToken(.equal_equal);
+        const ne = eq orelse p.eatToken(.bang_equal);
+        const tag = p.tokToTag(ne orelse break);
+        var rhs = try p.compExpr();
+        try rhs.expect(p);
+
+        if (try lhs.adjustTypes(ne.?, &rhs, p, .equality)) {
+            const op: std.math.CompareOperator = if (tag == .equal_expr) .eq else .neq;
+            const res = lhs.val.compare(op, rhs.val, lhs.ty, p.comp);
+            lhs.val = Value.int(@intFromBool(res));
+        }
+        try lhs.boolRes(p, tag, rhs);
+    }
+    return lhs;
+}
+
+/// compExpr : shiftExpr (('<' | '<=' | '>' | '>=') shiftExpr)*
+fn compExpr(p: *Parser) Error!Result {
+    var lhs = try p.shiftExpr();
+    if (lhs.empty(p)) return lhs;
+    while (true) {
+        const lt = p.eatToken(.angle_bracket_left);
+        const le = lt orelse p.eatToken(.angle_bracket_left_equal);
+        const gt = le orelse p.eatToken(.angle_bracket_right);
+        const ge = gt orelse p.eatToken(.angle_bracket_right_equal);
+        const tag = p.tokToTag(ge orelse break);
+        var rhs = try p.shiftExpr();
+        try rhs.expect(p);
+
+        if (try lhs.adjustTypes(ge.?, &rhs, p, .relational)) {
+            const op: std.math.CompareOperator = switch (tag) {
+                .less_than_expr => .lt,
+                .less_than_equal_expr => .lte,
+                .greater_than_expr => .gt,
+                .greater_than_equal_expr => .gte,
+                else => unreachable,
+            };
+            const res = lhs.val.compare(op, rhs.val, lhs.ty, p.comp);
+            lhs.val = Value.int(@intFromBool(res));
+        }
+        try lhs.boolRes(p, tag, rhs);
+    }
+    return lhs;
+}
+
+/// shiftExpr : addExpr (('<<' | '>>') addExpr)*
+fn shiftExpr(p: *Parser) Error!Result {
+    var lhs = try p.addExpr();
+    if (lhs.empty(p)) return lhs;
+    while (true) {
+        const shl = p.eatToken(.angle_bracket_angle_bracket_left);
+        const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right);
+        const tag = p.tokToTag(shr orelse break);
+        var rhs = try p.addExpr();
+        try rhs.expect(p);
+
+        if (try lhs.adjustTypes(shr.?, &rhs, p, .integer)) {
+            if (shl != null) {
+                lhs.val = lhs.val.shl(rhs.val, lhs.ty, p.comp);
+            } else {
+                lhs.val = lhs.val.shr(rhs.val, lhs.ty, p.comp);
+            }
+        }
+        try lhs.bin(p, tag, rhs);
+    }
+    return lhs;
+}
+
+/// addExpr : mulExpr (('+' | '-') mulExpr)*
+fn addExpr(p: *Parser) Error!Result {
+    var lhs = try p.mulExpr();
+    if (lhs.empty(p)) return lhs;
+    while (true) {
+        const plus = p.eatToken(.plus);
+        const minus = plus orelse p.eatToken(.minus);
+        const tag = p.tokToTag(minus orelse break);
+        var rhs = try p.mulExpr();
+        try rhs.expect(p);
+
+        const lhs_ty = lhs.ty;
+        if (try lhs.adjustTypes(minus.?, &rhs, p, if (plus != null) .add else .sub)) {
+            if (plus != null) {
+                if (lhs.val.add(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(plus.?, lhs);
+            } else {
+                if (lhs.val.sub(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(minus.?, lhs);
+            }
+        }
+        if (lhs.ty.specifier != .invalid and lhs_ty.isPtr() and !lhs_ty.isVoidStar() and lhs_ty.elemType().hasIncompleteSize()) {
+            try p.errStr(.ptr_arithmetic_incomplete, minus.?, try p.typeStr(lhs_ty.elemType()));
+            lhs.ty = Type.invalid;
+        }
+        try lhs.bin(p, tag, rhs);
+    }
+    return lhs;
+}
+
+/// mulExpr : castExpr (('*' | '/' | '%') castExpr)*ยด
+fn mulExpr(p: *Parser) Error!Result {
+    var lhs = try p.castExpr();
+    if (lhs.empty(p)) return lhs;
+    while (true) {
+        const mul = p.eatToken(.asterisk);
+        const div = mul orelse p.eatToken(.slash);
+        const percent = div orelse p.eatToken(.percent);
+        const tag = p.tokToTag(percent orelse break);
+        var rhs = try p.castExpr();
+        try rhs.expect(p);
+
+        if (rhs.val.isZero() and mul == null and !p.no_eval and lhs.ty.isInt() and rhs.ty.isInt()) {
+            const err_tag: Diagnostics.Tag = if (p.in_macro) .division_by_zero_macro else .division_by_zero;
+            lhs.val.tag = .unavailable;
+            if (div != null) {
+                try p.errStr(err_tag, div.?, "division");
+            } else {
+                try p.errStr(err_tag, percent.?, "remainder");
+            }
+            if (p.in_macro) return error.ParsingFailed;
+        }
+
+        if (try lhs.adjustTypes(percent.?, &rhs, p, if (tag == .mod_expr) .integer else .arithmetic)) {
+            if (mul != null) {
+                if (lhs.val.mul(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(mul.?, lhs);
+            } else if (div != null) {
+                lhs.val = Value.div(lhs.val, rhs.val, lhs.ty, p.comp);
+            } else {
+                var res = Value.rem(lhs.val, rhs.val, lhs.ty, p.comp);
+                if (res.tag == .unavailable) {
+                    if (p.in_macro) {
+                        // match clang behavior by defining invalid remainder to be zero in macros
+                        res = Value.int(0);
+                    } else {
+                        try lhs.saveValue(p);
+                        try rhs.saveValue(p);
+                    }
+                }
+                lhs.val = res;
+            }
+        }
+
+        try lhs.bin(p, tag, rhs);
+    }
+    return lhs;
+}
+
+/// This will always be the last message, if present
+fn removeUnusedWarningForTok(p: *Parser, last_expr_tok: TokenIndex) void {
+    if (last_expr_tok == 0) return;
+    if (p.comp.diag.list.items.len == 0) return;
+
+    const last_expr_loc = p.pp.tokens.items(.loc)[last_expr_tok];
+    const last_msg = p.comp.diag.list.items[p.comp.diag.list.items.len - 1];
+
+    if (last_msg.tag == .unused_value and last_msg.loc.eql(last_expr_loc)) {
+        p.comp.diag.list.items.len = p.comp.diag.list.items.len - 1;
+    }
+}
+
+/// castExpr
+///  :  '(' compoundStmt ')'
+///  |  '(' typeName ')' castExpr
+///  | '(' typeName ')' '{' initializerItems '}'
+///  | __builtin_choose_expr '(' integerConstExpr ',' assignExpr ',' assignExpr ')'
+///  | __builtin_va_arg '(' assignExpr ',' typeName ')'
+///  | __builtin_offsetof '(' typeName ',' offsetofMemberDesignator ')'
+///  | __builtin_bitoffsetof '(' typeName ',' offsetofMemberDesignator ')'
+///  | unExpr
+fn castExpr(p: *Parser) Error!Result {
+    if (p.eatToken(.l_paren)) |l_paren| cast_expr: {
+        if (p.tok_ids[p.tok_i] == .l_brace) {
+            try p.err(.gnu_statement_expression);
+            if (p.func.ty == null) {
+                try p.err(.stmt_expr_not_allowed_file_scope);
+                return error.ParsingFailed;
+            }
+            var stmt_expr_state: StmtExprState = .{};
+            const body_node = (try p.compoundStmt(false, &stmt_expr_state)).?; // compoundStmt only returns null if .l_brace isn't the first token
+            p.removeUnusedWarningForTok(stmt_expr_state.last_expr_tok);
+
+            var res = Result{
+                .node = body_node,
+                .ty = stmt_expr_state.last_expr_res.ty,
+                .val = stmt_expr_state.last_expr_res.val,
+            };
+            try p.expectClosing(l_paren, .r_paren);
+            try res.un(p, .stmt_expr);
+            return res;
+        }
+        const ty = (try p.typeName()) orelse {
+            p.tok_i -= 1;
+            break :cast_expr;
+        };
+        try p.expectClosing(l_paren, .r_paren);
+
+        if (p.tok_ids[p.tok_i] == .l_brace) {
+            // Compound literal; handled in unExpr
+            p.tok_i = l_paren;
+            break :cast_expr;
+        }
+
+        var operand = try p.castExpr();
+        try operand.expect(p);
+        try operand.lvalConversion(p);
+        try operand.castType(p, ty, l_paren);
+        return operand;
+    }
+    switch (p.tok_ids[p.tok_i]) {
+        .builtin_choose_expr => return p.builtinChooseExpr(),
+        .builtin_va_arg => return p.builtinVaArg(),
+        .builtin_offsetof => return p.builtinOffsetof(false),
+        .builtin_bitoffsetof => return p.builtinOffsetof(true),
+        .builtin_types_compatible_p => return p.typesCompatible(),
+        // TODO: other special-cased builtins
+        else => {},
+    }
+    return p.unExpr();
+}
+
+fn typesCompatible(p: *Parser) Error!Result {
+    p.tok_i += 1;
+    const l_paren = try p.expectToken(.l_paren);
+
+    const first = (try p.typeName()) orelse {
+        try p.err(.expected_type);
+        p.skipTo(.r_paren);
+        return error.ParsingFailed;
+    };
+    const lhs = try p.addNode(.{ .tag = .invalid, .ty = first, .data = undefined });
+    _ = try p.expectToken(.comma);
+
+    const second = (try p.typeName()) orelse {
+        try p.err(.expected_type);
+        p.skipTo(.r_paren);
+        return error.ParsingFailed;
+    };
+    const rhs = try p.addNode(.{ .tag = .invalid, .ty = second, .data = undefined });
+
+    try p.expectClosing(l_paren, .r_paren);
+
+    const compatible = first.compatible(second, p.comp);
+
+    var res = Result{
+        .val = Value.int(@intFromBool(compatible)),
+        .node = try p.addNode(.{ .tag = .builtin_types_compatible_p, .ty = Type.int, .data = .{ .bin = .{
+            .lhs = lhs,
+            .rhs = rhs,
+        } } }),
+    };
+    try p.value_map.put(res.node, res.val);
+    return res;
+}
+
+fn builtinChooseExpr(p: *Parser) Error!Result {
+    p.tok_i += 1;
+    const l_paren = try p.expectToken(.l_paren);
+    const cond_tok = p.tok_i;
+    var cond = try p.integerConstExpr(.no_const_decl_folding);
+    if (cond.val.tag == .unavailable) {
+        try p.errTok(.builtin_choose_cond, cond_tok);
+        return error.ParsingFailed;
+    }
+
+    _ = try p.expectToken(.comma);
+
+    var then_expr = if (cond.val.getBool()) try p.assignExpr() else try p.parseNoEval(assignExpr);
+    try then_expr.expect(p);
+
+    _ = try p.expectToken(.comma);
+
+    var else_expr = if (!cond.val.getBool()) try p.assignExpr() else try p.parseNoEval(assignExpr);
+    try else_expr.expect(p);
+
+    try p.expectClosing(l_paren, .r_paren);
+
+    if (cond.val.getBool()) {
+        cond.val = then_expr.val;
+        cond.ty = then_expr.ty;
+    } else {
+        cond.val = else_expr.val;
+        cond.ty = else_expr.ty;
+    }
+    cond.node = try p.addNode(.{
+        .tag = .builtin_choose_expr,
+        .ty = cond.ty,
+        .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } },
+    });
+    return cond;
+}
+
+fn builtinVaArg(p: *Parser) Error!Result {
+    const builtin_tok = p.tok_i;
+    p.tok_i += 1;
+
+    const l_paren = try p.expectToken(.l_paren);
+    const va_list_tok = p.tok_i;
+    var va_list = try p.assignExpr();
+    try va_list.expect(p);
+    try va_list.lvalConversion(p);
+
+    _ = try p.expectToken(.comma);
+
+    const ty = (try p.typeName()) orelse {
+        try p.err(.expected_type);
+        return error.ParsingFailed;
+    };
+    try p.expectClosing(l_paren, .r_paren);
+
+    if (!va_list.ty.eql(p.comp.types.va_list, p.comp, true)) {
+        try p.errStr(.incompatible_va_arg, va_list_tok, try p.typeStr(va_list.ty));
+        return error.ParsingFailed;
+    }
+
+    return Result{ .ty = ty, .node = try p.addNode(.{
+        .tag = .special_builtin_call_one,
+        .ty = ty,
+        .data = .{ .decl = .{ .name = builtin_tok, .node = va_list.node } },
+    }) };
+}
+
+fn builtinOffsetof(p: *Parser, want_bits: bool) Error!Result {
+    const builtin_tok = p.tok_i;
+    p.tok_i += 1;
+
+    const l_paren = try p.expectToken(.l_paren);
+    const ty_tok = p.tok_i;
+
+    const ty = (try p.typeName()) orelse {
+        try p.err(.expected_type);
+        p.skipTo(.r_paren);
+        return error.ParsingFailed;
+    };
+
+    if (!ty.isRecord()) {
+        try p.errStr(.offsetof_ty, ty_tok, try p.typeStr(ty));
+        p.skipTo(.r_paren);
+        return error.ParsingFailed;
+    } else if (ty.hasIncompleteSize()) {
+        try p.errStr(.offsetof_incomplete, ty_tok, try p.typeStr(ty));
+        p.skipTo(.r_paren);
+        return error.ParsingFailed;
+    }
+
+    _ = try p.expectToken(.comma);
+
+    const offsetof_expr = try p.offsetofMemberDesignator(ty);
+
+    try p.expectClosing(l_paren, .r_paren);
+
+    return Result{
+        .ty = p.comp.types.size,
+        .val = if (offsetof_expr.val.tag == .int and !want_bits)
+            Value.int(offsetof_expr.val.data.int / 8)
+        else
+            offsetof_expr.val,
+        .node = try p.addNode(.{
+            .tag = .special_builtin_call_one,
+            .ty = p.comp.types.size,
+            .data = .{ .decl = .{ .name = builtin_tok, .node = offsetof_expr.node } },
+        }),
+    };
+}
+
+/// offsetofMemberDesignator: IDENTIFIER ('.' IDENTIFIER | '[' expr ']' )*
+fn offsetofMemberDesignator(p: *Parser, base_ty: Type) Error!Result {
+    errdefer p.skipTo(.r_paren);
+    const base_field_name_tok = try p.expectIdentifier();
+    const base_field_name = try p.comp.intern(p.tokSlice(base_field_name_tok));
+    try p.validateFieldAccess(base_ty, base_ty, base_field_name_tok, base_field_name);
+    const base_node = try p.addNode(.{ .tag = .default_init_expr, .ty = base_ty, .data = undefined });
+
+    var offset_num: u64 = 0;
+    const base_record_ty = base_ty.canonicalize(.standard);
+    var lhs = try p.fieldAccessExtra(base_node, base_record_ty, base_field_name, false, &offset_num);
+    var bit_offset = Value.int(offset_num);
+
+    while (true) switch (p.tok_ids[p.tok_i]) {
+        .period => {
+            p.tok_i += 1;
+            const field_name_tok = try p.expectIdentifier();
+            const field_name = try p.comp.intern(p.tokSlice(field_name_tok));
+
+            if (!lhs.ty.isRecord()) {
+                try p.errStr(.offsetof_ty, field_name_tok, try p.typeStr(lhs.ty));
+                return error.ParsingFailed;
+            }
+            try p.validateFieldAccess(lhs.ty, lhs.ty, field_name_tok, field_name);
+            const record_ty = lhs.ty.canonicalize(.standard);
+            lhs = try p.fieldAccessExtra(lhs.node, record_ty, field_name, false, &offset_num);
+            if (bit_offset.tag != .unavailable) {
+                bit_offset = Value.int(offset_num + bit_offset.getInt(u64));
+            }
+        },
+        .l_bracket => {
+            const l_bracket_tok = p.tok_i;
+            p.tok_i += 1;
+            var index = try p.expr();
+            try index.expect(p);
+            _ = try p.expectClosing(l_bracket_tok, .r_bracket);
+
+            if (!lhs.ty.isArray()) {
+                try p.errStr(.offsetof_array, l_bracket_tok, try p.typeStr(lhs.ty));
+                return error.ParsingFailed;
+            }
+            var ptr = lhs;
+            try ptr.lvalConversion(p);
+            try index.lvalConversion(p);
+
+            if (!index.ty.isInt()) try p.errTok(.invalid_index, l_bracket_tok);
+            try p.checkArrayBounds(index, lhs, l_bracket_tok);
+
+            try index.saveValue(p);
+            try ptr.bin(p, .array_access_expr, index);
+            lhs = ptr;
+        },
+        else => break,
+    };
+
+    return Result{ .ty = base_ty, .val = bit_offset, .node = lhs.node };
+}
+
+/// unExpr
+///  : (compoundLiteral | primaryExpr) suffixExpr*
+///  | '&&' IDENTIFIER
+///  | ('&' | '*' | '+' | '-' | '~' | '!' | '++' | '--' | keyword_extension | keyword_imag | keyword_real) castExpr
+///  | keyword_sizeof unExpr
+///  | keyword_sizeof '(' typeName ')'
+///  | keyword_alignof '(' typeName ')'
+///  | keyword_c23_alignof '(' typeName ')'
+fn unExpr(p: *Parser) Error!Result {
+    const tok = p.tok_i;
+    switch (p.tok_ids[tok]) {
+        .ampersand_ampersand => {
+            const address_tok = p.tok_i;
+            p.tok_i += 1;
+            const name_tok = try p.expectIdentifier();
+            try p.errTok(.gnu_label_as_value, address_tok);
+            p.contains_address_of_label = true;
+
+            const str = p.tokSlice(name_tok);
+            if (p.findLabel(str) == null) {
+                try p.labels.append(.{ .unresolved_goto = name_tok });
+            }
+            const elem_ty = try p.arena.create(Type);
+            elem_ty.* = .{ .specifier = .void };
+            const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
+            return Result{
+                .node = try p.addNode(.{
+                    .tag = .addr_of_label,
+                    .data = .{ .decl_ref = name_tok },
+                    .ty = result_ty,
+                }),
+                .ty = result_ty,
+            };
+        },
+        .ampersand => {
+            if (p.in_macro) {
+                try p.err(.invalid_preproc_operator);
+                return error.ParsingFailed;
+            }
+            p.tok_i += 1;
+            var operand = try p.castExpr();
+            try operand.expect(p);
+
+            const slice = p.nodes.slice();
+            if (p.getNode(operand.node, .member_access_expr) orelse p.getNode(operand.node, .member_access_ptr_expr)) |member_node| {
+                if (Tree.isBitfield(slice, member_node)) try p.errTok(.addr_of_bitfield, tok);
+            }
+            if (!Tree.isLval(slice, p.data.items, p.value_map, operand.node)) {
+                try p.errTok(.addr_of_rvalue, tok);
+            }
+            if (operand.ty.qual.register) try p.errTok(.addr_of_register, tok);
+
+            const elem_ty = try p.arena.create(Type);
+            elem_ty.* = operand.ty;
+            operand.ty = Type{
+                .specifier = .pointer,
+                .data = .{ .sub_type = elem_ty },
+            };
+            try operand.saveValue(p);
+            try operand.un(p, .addr_of_expr);
+            return operand;
+        },
+        .asterisk => {
+            const asterisk_loc = p.tok_i;
+            p.tok_i += 1;
+            var operand = try p.castExpr();
+            try operand.expect(p);
+
+            if (operand.ty.isArray() or operand.ty.isPtr() or operand.ty.isFunc()) {
+                try operand.lvalConversion(p);
+                operand.ty = operand.ty.elemType();
+            } else {
+                try p.errTok(.indirection_ptr, tok);
+            }
+            if (operand.ty.hasIncompleteSize() and !operand.ty.is(.void)) {
+                try p.errStr(.deref_incomplete_ty_ptr, asterisk_loc, try p.typeStr(operand.ty));
+            }
+            operand.ty.qual = .{};
+            try operand.un(p, .deref_expr);
+            return operand;
+        },
+        .plus => {
+            p.tok_i += 1;
+
+            var operand = try p.castExpr();
+            try operand.expect(p);
+            try operand.lvalConversion(p);
+            if (!operand.ty.isInt() and !operand.ty.isFloat())
+                try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+
+            try operand.usualUnaryConversion(p, tok);
+
+            return operand;
+        },
+        .minus => {
+            p.tok_i += 1;
+
+            var operand = try p.castExpr();
+            try operand.expect(p);
+            try operand.lvalConversion(p);
+            if (!operand.ty.isInt() and !operand.ty.isFloat())
+                try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+
+            try operand.usualUnaryConversion(p, tok);
+            if (operand.val.tag == .int or operand.val.tag == .float) {
+                _ = operand.val.sub(operand.val.zero(), operand.val, operand.ty, p.comp);
+            } else {
+                operand.val.tag = .unavailable;
+            }
+            try operand.un(p, .negate_expr);
+            return operand;
+        },
+        .plus_plus => {
+            p.tok_i += 1;
+
+            var operand = try p.castExpr();
+            try operand.expect(p);
+            if (!operand.ty.isScalar())
+                try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+            if (operand.ty.isComplex())
+                try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
+
+            if (!Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, operand.node) or operand.ty.isConst()) {
+                try p.errTok(.not_assignable, tok);
+                return error.ParsingFailed;
+            }
+            try operand.usualUnaryConversion(p, tok);
+
+            if (operand.val.tag == .int or operand.val.tag == .float) {
+                if (operand.val.add(operand.val, operand.val.one(), operand.ty, p.comp))
+                    try p.errOverflow(tok, operand);
+            } else {
+                operand.val.tag = .unavailable;
+            }
+
+            try operand.un(p, .pre_inc_expr);
+            return operand;
+        },
+        .minus_minus => {
+            p.tok_i += 1;
+
+            var operand = try p.castExpr();
+            try operand.expect(p);
+            if (!operand.ty.isScalar())
+                try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+            if (operand.ty.isComplex())
+                try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
+
+            if (!Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, operand.node) or operand.ty.isConst()) {
+                try p.errTok(.not_assignable, tok);
+                return error.ParsingFailed;
+            }
+            try operand.usualUnaryConversion(p, tok);
+
+            if (operand.val.tag == .int or operand.val.tag == .float) {
+                if (operand.val.sub(operand.val, operand.val.one(), operand.ty, p.comp))
+                    try p.errOverflow(tok, operand);
+            } else {
+                operand.val.tag = .unavailable;
+            }
+
+            try operand.un(p, .pre_dec_expr);
+            return operand;
+        },
+        .tilde => {
+            p.tok_i += 1;
+
+            var operand = try p.castExpr();
+            try operand.expect(p);
+            try operand.lvalConversion(p);
+            try operand.usualUnaryConversion(p, tok);
+            if (operand.ty.isInt()) {
+                if (operand.val.tag == .int) {
+                    operand.val = operand.val.bitNot(operand.ty, p.comp);
+                }
+            } else {
+                try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+                operand.val.tag = .unavailable;
+            }
+            try operand.un(p, .bit_not_expr);
+            return operand;
+        },
+        .bang => {
+            p.tok_i += 1;
+
+            var operand = try p.castExpr();
+            try operand.expect(p);
+            try operand.lvalConversion(p);
+            if (!operand.ty.isScalar())
+                try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
+
+            try operand.usualUnaryConversion(p, tok);
+            if (operand.val.tag == .int) {
+                const res = Value.int(@intFromBool(!operand.val.getBool()));
+                operand.val = res;
+            } else if (operand.val.tag == .nullptr_t) {
+                operand.val = Value.int(1);
+            } else {
+                if (operand.ty.isDecayed()) {
+                    operand.val = Value.int(0);
+                } else {
+                    operand.val.tag = .unavailable;
+                }
+            }
+            operand.ty = .{ .specifier = .int };
+            try operand.un(p, .bool_not_expr);
+            return operand;
+        },
+        .keyword_sizeof => {
+            p.tok_i += 1;
+            const expected_paren = p.tok_i;
+            var res = Result{};
+            if (try p.typeName()) |ty| {
+                res.ty = ty;
+                try p.errTok(.expected_parens_around_typename, expected_paren);
+            } else if (p.eatToken(.l_paren)) |l_paren| {
+                if (try p.typeName()) |ty| {
+                    res.ty = ty;
+                    try p.expectClosing(l_paren, .r_paren);
+                } else {
+                    p.tok_i = expected_paren;
+                    res = try p.parseNoEval(unExpr);
+                }
+            } else {
+                res = try p.parseNoEval(unExpr);
+            }
+
+            if (res.ty.is(.void)) {
+                try p.errStr(.pointer_arith_void, tok, "sizeof");
+            } else if (res.ty.isDecayed()) {
+                const array_ty = res.ty.originalTypeOfDecayedArray();
+                const err_str = try p.typePairStrExtra(res.ty, " instead of ", array_ty);
+                try p.errStr(.sizeof_array_arg, tok, err_str);
+            }
+            if (res.ty.sizeof(p.comp)) |size| {
+                if (size == 0) {
+                    try p.errTok(.sizeof_returns_zero, tok);
+                }
+                res.val = Value.int(size);
+                res.ty = p.comp.types.size;
+            } else {
+                res.val.tag = .unavailable;
+                if (res.ty.hasIncompleteSize()) {
+                    try p.errStr(.invalid_sizeof, expected_paren - 1, try p.typeStr(res.ty));
+                    res.ty = Type.invalid;
+                } else {
+                    res.ty = p.comp.types.size;
+                }
+            }
+            try res.un(p, .sizeof_expr);
+            return res;
+        },
+        .keyword_alignof,
+        .keyword_alignof1,
+        .keyword_alignof2,
+        .keyword_c23_alignof,
+        => {
+            p.tok_i += 1;
+            const expected_paren = p.tok_i;
+            var res = Result{};
+            if (try p.typeName()) |ty| {
+                res.ty = ty;
+                try p.errTok(.expected_parens_around_typename, expected_paren);
+            } else if (p.eatToken(.l_paren)) |l_paren| {
+                if (try p.typeName()) |ty| {
+                    res.ty = ty;
+                    try p.expectClosing(l_paren, .r_paren);
+                } else {
+                    p.tok_i = expected_paren;
+                    res = try p.parseNoEval(unExpr);
+                    try p.errTok(.alignof_expr, expected_paren);
+                }
+            } else {
+                res = try p.parseNoEval(unExpr);
+                try p.errTok(.alignof_expr, expected_paren);
+            }
+
+            if (res.ty.is(.void)) {
+                try p.errStr(.pointer_arith_void, tok, "alignof");
+            }
+            if (res.ty.alignable()) {
+                res.val = Value.int(res.ty.alignof(p.comp));
+                res.ty = p.comp.types.size;
+            } else {
+                try p.errStr(.invalid_alignof, expected_paren, try p.typeStr(res.ty));
+                res.ty = Type.invalid;
+            }
+            try res.un(p, .alignof_expr);
+            return res;
+        },
+        .keyword_extension => {
+            p.tok_i += 1;
+            const saved_extension = p.extension_suppressed;
+            defer p.extension_suppressed = saved_extension;
+            p.extension_suppressed = true;
+
+            var child = try p.castExpr();
+            try child.expect(p);
+            return child;
+        },
+        .keyword_imag1, .keyword_imag2 => {
+            const imag_tok = p.tok_i;
+            p.tok_i += 1;
+
+            var operand = try p.castExpr();
+            try operand.expect(p);
+            try operand.lvalConversion(p);
+            if (!operand.ty.isInt() and !operand.ty.isFloat()) {
+                try p.errStr(.invalid_imag, imag_tok, try p.typeStr(operand.ty));
+            }
+            if (operand.ty.isReal()) {
+                switch (p.comp.langopts.emulate) {
+                    .msvc => {}, // Doesn't support `_Complex` or `__imag` in the first place
+                    .gcc => {
+                        if (operand.ty.isInt()) {
+                            operand.val = Value.int(0);
+                        } else if (operand.ty.isFloat()) {
+                            operand.val = Value.float(0);
+                        }
+                    },
+                    .clang => {
+                        if (operand.val.tag == .int) {
+                            operand.val = Value.int(0);
+                        } else {
+                            operand.val.tag = .unavailable;
+                        }
+                    },
+                }
+            }
+            // convert _Complex T to T
+            operand.ty = operand.ty.makeReal();
+            try operand.un(p, .imag_expr);
+            return operand;
+        },
+        .keyword_real1, .keyword_real2 => {
+            const real_tok = p.tok_i;
+            p.tok_i += 1;
+
+            var operand = try p.castExpr();
+            try operand.expect(p);
+            try operand.lvalConversion(p);
+            if (!operand.ty.isInt() and !operand.ty.isFloat()) {
+                try p.errStr(.invalid_real, real_tok, try p.typeStr(operand.ty));
+            }
+            // convert _Complex T to T
+            operand.ty = operand.ty.makeReal();
+            try operand.un(p, .real_expr);
+            return operand;
+        },
+        else => {
+            var lhs = try p.compoundLiteral();
+            if (lhs.empty(p)) {
+                lhs = try p.primaryExpr();
+                if (lhs.empty(p)) return lhs;
+            }
+            while (true) {
+                const suffix = try p.suffixExpr(lhs);
+                if (suffix.empty(p)) break;
+                lhs = suffix;
+            }
+            return lhs;
+        },
+    }
+}
+
+/// compoundLiteral
+///  : '(' type_name ')' '{' initializer_list '}'
+///  | '(' type_name ')' '{' initializer_list ',' '}'
+fn compoundLiteral(p: *Parser) Error!Result {
+    const l_paren = p.eatToken(.l_paren) orelse return Result{};
+    const ty = (try p.typeName()) orelse {
+        p.tok_i = l_paren;
+        return Result{};
+    };
+    try p.expectClosing(l_paren, .r_paren);
+
+    if (ty.isFunc()) {
+        try p.err(.func_init);
+    } else if (ty.is(.variable_len_array)) {
+        try p.err(.vla_init);
+    } else if (ty.hasIncompleteSize() and !ty.is(.incomplete_array)) {
+        try p.errStr(.variable_incomplete_ty, p.tok_i, try p.typeStr(ty));
+        return error.ParsingFailed;
+    }
+    var init_list_expr = try p.initializer(ty);
+    try init_list_expr.un(p, .compound_literal_expr);
+    return init_list_expr;
+}
+
+/// suffixExpr
+///  : '[' expr ']'
+///  | '(' argumentExprList? ')'
+///  | '.' IDENTIFIER
+///  | '->' IDENTIFIER
+///  | '++'
+///  | '--'
+/// argumentExprList : assignExpr (',' assignExpr)*
+fn suffixExpr(p: *Parser, lhs: Result) Error!Result {
+    assert(!lhs.empty(p));
+    switch (p.tok_ids[p.tok_i]) {
+        .l_paren => return p.callExpr(lhs),
+        .plus_plus => {
+            defer p.tok_i += 1;
+
+            var operand = lhs;
+            if (!operand.ty.isScalar())
+                try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
+            if (operand.ty.isComplex())
+                try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
+
+            if (!Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, operand.node) or operand.ty.isConst()) {
+                try p.err(.not_assignable);
+                return error.ParsingFailed;
+            }
+            try operand.usualUnaryConversion(p, p.tok_i);
+
+            try operand.un(p, .post_inc_expr);
+            return operand;
+        },
+        .minus_minus => {
+            defer p.tok_i += 1;
+
+            var operand = lhs;
+            if (!operand.ty.isScalar())
+                try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
+            if (operand.ty.isComplex())
+                try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
+
+            if (!Tree.isLval(p.nodes.slice(), p.data.items, p.value_map, operand.node) or operand.ty.isConst()) {
+                try p.err(.not_assignable);
+                return error.ParsingFailed;
+            }
+            try operand.usualUnaryConversion(p, p.tok_i);
+
+            try operand.un(p, .post_dec_expr);
+            return operand;
+        },
+        .l_bracket => {
+            const l_bracket = p.tok_i;
+            p.tok_i += 1;
+            var index = try p.expr();
+            try index.expect(p);
+            try p.expectClosing(l_bracket, .r_bracket);
+
+            const array_before_conversion = lhs;
+            const index_before_conversion = index;
+            var ptr = lhs;
+            try ptr.lvalConversion(p);
+            try index.lvalConversion(p);
+            if (ptr.ty.isPtr()) {
+                ptr.ty = ptr.ty.elemType();
+                if (!index.ty.isInt()) try p.errTok(.invalid_index, l_bracket);
+                try p.checkArrayBounds(index_before_conversion, array_before_conversion, l_bracket);
+            } else if (index.ty.isPtr()) {
+                index.ty = index.ty.elemType();
+                if (!ptr.ty.isInt()) try p.errTok(.invalid_index, l_bracket);
+                try p.checkArrayBounds(array_before_conversion, index_before_conversion, l_bracket);
+                std.mem.swap(Result, &ptr, &index);
+            } else {
+                try p.errTok(.invalid_subscript, l_bracket);
+            }
+
+            try ptr.saveValue(p);
+            try index.saveValue(p);
+            try ptr.bin(p, .array_access_expr, index);
+            return ptr;
+        },
+        .period => {
+            p.tok_i += 1;
+            const name = try p.expectIdentifier();
+            return p.fieldAccess(lhs, name, false);
+        },
+        .arrow => {
+            p.tok_i += 1;
+            const name = try p.expectIdentifier();
+            if (lhs.ty.isArray()) {
+                var copy = lhs;
+                copy.ty.decayArray();
+                try copy.implicitCast(p, .array_to_pointer);
+                return p.fieldAccess(copy, name, true);
+            }
+            return p.fieldAccess(lhs, name, true);
+        },
+        else => return Result{},
+    }
+}
+
+fn fieldAccess(
+    p: *Parser,
+    lhs: Result,
+    field_name_tok: TokenIndex,
+    is_arrow: bool,
+) !Result {
+    const expr_ty = lhs.ty;
+    const is_ptr = expr_ty.isPtr();
+    const expr_base_ty = if (is_ptr) expr_ty.elemType() else expr_ty;
+    const record_ty = expr_base_ty.canonicalize(.standard);
+
+    switch (record_ty.specifier) {
+        .@"struct", .@"union" => {},
+        else => {
+            try p.errStr(.expected_record_ty, field_name_tok, try p.typeStr(expr_ty));
+            return error.ParsingFailed;
+        },
+    }
+    if (record_ty.hasIncompleteSize()) {
+        try p.errStr(.deref_incomplete_ty_ptr, field_name_tok - 2, try p.typeStr(expr_base_ty));
+        return error.ParsingFailed;
+    }
+    if (is_arrow and !is_ptr) try p.errStr(.member_expr_not_ptr, field_name_tok, try p.typeStr(expr_ty));
+    if (!is_arrow and is_ptr) try p.errStr(.member_expr_ptr, field_name_tok, try p.typeStr(expr_ty));
+
+    const field_name = try p.comp.intern(p.tokSlice(field_name_tok));
+    try p.validateFieldAccess(record_ty, expr_ty, field_name_tok, field_name);
+    var discard: u64 = 0;
+    return p.fieldAccessExtra(lhs.node, record_ty, field_name, is_arrow, &discard);
+}
+
+fn validateFieldAccess(p: *Parser, record_ty: Type, expr_ty: Type, field_name_tok: TokenIndex, field_name: StringId) Error!void {
+    if (record_ty.hasField(field_name)) return;
+
+    p.strings.items.len = 0;
+
+    try p.strings.writer().print("'{s}' in '", .{p.tokSlice(field_name_tok)});
+    const mapper = p.comp.string_interner.getSlowTypeMapper();
+    try expr_ty.print(mapper, p.comp.langopts, p.strings.writer());
+    try p.strings.append('\'');
+
+    const duped = try p.comp.diag.arena.allocator().dupe(u8, p.strings.items);
+    try p.errStr(.no_such_member, field_name_tok, duped);
+    return error.ParsingFailed;
+}
+
+fn fieldAccessExtra(p: *Parser, lhs: NodeIndex, record_ty: Type, field_name: StringId, is_arrow: bool, offset_bits: *u64) Error!Result {
+    for (record_ty.data.record.fields, 0..) |f, i| {
+        if (f.isAnonymousRecord()) {
+            if (!f.ty.hasField(field_name)) continue;
+            const inner = try p.addNode(.{
+                .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr,
+                .ty = f.ty,
+                .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } },
+            });
+            const ret = p.fieldAccessExtra(inner, f.ty, field_name, false, offset_bits);
+            offset_bits.* += f.layout.offset_bits;
+            return ret;
+        }
+        if (field_name == f.name) {
+            offset_bits.* = f.layout.offset_bits;
+            return Result{
+                .ty = f.ty,
+                .node = try p.addNode(.{
+                    .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr,
+                    .ty = f.ty,
+                    .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } },
+                }),
+            };
+        }
+    }
+    // We already checked that this container has a field by the name.
+    unreachable;
+}
+
+fn checkVaStartArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void {
+    assert(idx != 0);
+    if (idx > 1) {
+        try p.errTok(.closing_paren, first_after);
+        return error.ParsingFailed;
+    }
+
+    var func_ty = p.func.ty orelse {
+        try p.errTok(.va_start_not_in_func, builtin_tok);
+        return;
+    };
+    const func_params = func_ty.params();
+    if (func_ty.specifier != .var_args_func or func_params.len == 0) {
+        return p.errTok(.va_start_fixed_args, builtin_tok);
+    }
+    const last_param_name = func_params[func_params.len - 1].name;
+    const decl_ref = p.getNode(arg.node, .decl_ref_expr);
+    if (decl_ref == null or last_param_name != try p.comp.intern(p.tokSlice(p.nodes.items(.data)[@intFromEnum(decl_ref.?)].decl_ref))) {
+        try p.errTok(.va_start_not_last_param, param_tok);
+    }
+}
+
+fn checkComplexArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void {
+    _ = builtin_tok;
+    _ = first_after;
+    if (idx <= 1 and !arg.ty.isFloat()) {
+        try p.errStr(.not_floating_type, param_tok, try p.typeStr(arg.ty));
+    } else if (idx == 1) {
+        const prev_idx = p.list_buf.items[p.list_buf.items.len - 1];
+        const prev_ty = p.nodes.items(.ty)[@intFromEnum(prev_idx)];
+        if (!prev_ty.eql(arg.ty, p.comp, false)) {
+            try p.errStr(.argument_types_differ, param_tok, try p.typePairStrExtra(prev_ty, " vs ", arg.ty));
+        }
+    }
+}
+
+fn checkVariableBuiltinArgument(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, arg_idx: u32, tag: BuiltinFunction.Tag) !void {
+    switch (tag) {
+        .__builtin_va_start, .__va_start, .va_start => return p.checkVaStartArg(builtin_tok, first_after, param_tok, arg, arg_idx),
+        else => {},
+    }
+}
+
+fn callExpr(p: *Parser, lhs: Result) Error!Result {
+    const l_paren = p.tok_i;
+    p.tok_i += 1;
+    const ty = lhs.ty.isCallable() orelse {
+        try p.errStr(.not_callable, l_paren, try p.typeStr(lhs.ty));
+        return error.ParsingFailed;
+    };
+    const params = ty.params();
+    var func = lhs;
+    try func.lvalConversion(p);
+
+    const list_buf_top = p.list_buf.items.len;
+    defer p.list_buf.items.len = list_buf_top;
+    try p.list_buf.append(func.node);
+    var arg_count: u32 = 0;
+    var first_after = l_paren;
+
+    const call_expr = CallExpr.init(p, lhs.node, func.node);
+
+    while (p.eatToken(.r_paren) == null) {
+        const param_tok = p.tok_i;
+        if (arg_count == params.len) first_after = p.tok_i;
+        var arg = try p.assignExpr();
+        try arg.expect(p);
+
+        if (call_expr.shouldPerformLvalConversion(arg_count)) {
+            try arg.lvalConversion(p);
+        }
+        if (arg.ty.hasIncompleteSize() and !arg.ty.is(.void)) return error.ParsingFailed;
+
+        if (arg_count >= params.len) {
+            if (call_expr.shouldPromoteVarArg(arg_count)) {
+                if (arg.ty.isInt()) try arg.intCast(p, arg.ty.integerPromotion(p.comp), param_tok);
+                if (arg.ty.is(.float)) try arg.floatCast(p, .{ .specifier = .double });
+            }
+            try call_expr.checkVarArg(p, first_after, param_tok, &arg, arg_count);
+            try arg.saveValue(p);
+            try p.list_buf.append(arg.node);
+            arg_count += 1;
+
+            _ = p.eatToken(.comma) orelse {
+                try p.expectClosing(l_paren, .r_paren);
+                break;
+            };
+            continue;
+        }
+        const p_ty = params[arg_count].ty;
+        if (call_expr.shouldCoerceArg(arg_count)) {
+            try arg.coerce(p, p_ty, param_tok, .{ .arg = params[arg_count].name_tok });
+        }
+        try arg.saveValue(p);
+        try p.list_buf.append(arg.node);
+        arg_count += 1;
+
+        _ = p.eatToken(.comma) orelse {
+            try p.expectClosing(l_paren, .r_paren);
+            break;
+        };
+    }
+
+    const actual: u32 = @intCast(arg_count);
+    const extra = Diagnostics.Message.Extra{ .arguments = .{
+        .expected = @intCast(params.len),
+        .actual = actual,
+    } };
+    if (call_expr.paramCountOverride()) |expected| {
+        if (expected != actual) {
+            try p.errExtra(.expected_arguments, first_after, .{ .arguments = .{ .expected = expected, .actual = actual } });
+        }
+    } else if (ty.is(.func) and params.len != arg_count) {
+        try p.errExtra(.expected_arguments, first_after, extra);
+    } else if (ty.is(.old_style_func) and params.len != arg_count) {
+        try p.errExtra(.expected_arguments_old, first_after, extra);
+    } else if (ty.is(.var_args_func) and arg_count < params.len) {
+        try p.errExtra(.expected_at_least_arguments, first_after, extra);
+    }
+
+    return call_expr.finish(p, ty, list_buf_top, arg_count);
+}
+
+fn checkArrayBounds(p: *Parser, index: Result, array: Result, tok: TokenIndex) !void {
+    if (index.val.tag == .unavailable) return;
+
+    const array_len = array.ty.arrayLen() orelse return;
+    if (array_len == 0) return;
+
+    if (array_len == 1) {
+        if (p.getNode(array.node, .member_access_expr) orelse p.getNode(array.node, .member_access_ptr_expr)) |node| {
+            const data = p.nodes.items(.data)[@intFromEnum(node)];
+            var lhs = p.nodes.items(.ty)[@intFromEnum(data.member.lhs)];
+            if (lhs.get(.pointer)) |ptr| {
+                lhs = ptr.data.sub_type.*;
+            }
+            if (lhs.is(.@"struct")) {
+                const record = lhs.getRecord().?;
+                if (data.member.index + 1 == record.fields.len) {
+                    if (!index.val.isZero()) {
+                        try p.errExtra(.old_style_flexible_struct, tok, .{
+                            .unsigned = index.val.data.int,
+                        });
+                    }
+                    return;
+                }
+            }
+        }
+    }
+    const len = Value.int(array_len);
+
+    if (index.ty.isUnsignedInt(p.comp)) {
+        if (index.val.compare(.gte, len, p.comp.types.size, p.comp))
+            try p.errExtra(.array_after, tok, .{ .unsigned = index.val.data.int });
+    } else {
+        if (index.val.compare(.lt, Value.int(0), index.ty, p.comp)) {
+            try p.errExtra(.array_before, tok, .{
+                .signed = index.val.signExtend(index.ty, p.comp),
+            });
+        } else if (index.val.compare(.gte, len, p.comp.types.size, p.comp)) {
+            try p.errExtra(.array_after, tok, .{ .unsigned = index.val.data.int });
+        }
+    }
+}
+
+/// primaryExpr
+///  : IDENTIFIER
+///  | keyword_true
+///  | keyword_false
+///  | keyword_nullptr
+///  | INTEGER_LITERAL
+///  | FLOAT_LITERAL
+///  | IMAGINARY_LITERAL
+///  | CHAR_LITERAL
+///  | STRING_LITERAL
+///  | '(' expr ')'
+///  | genericSelection
+fn primaryExpr(p: *Parser) Error!Result {
+    if (p.eatToken(.l_paren)) |l_paren| {
+        var e = try p.expr();
+        try e.expect(p);
+        try p.expectClosing(l_paren, .r_paren);
+        try e.un(p, .paren_expr);
+        return e;
+    }
+    switch (p.tok_ids[p.tok_i]) {
+        .identifier, .extended_identifier => {
+            const name_tok = p.expectIdentifier() catch unreachable;
+            const name = p.tokSlice(name_tok);
+            const interned_name = try p.comp.intern(name);
+            if (p.syms.findSymbol(interned_name)) |sym| {
+                try p.checkDeprecatedUnavailable(sym.ty, name_tok, sym.tok);
+                if (sym.kind == .constexpr) {
+                    return Result{
+                        .val = sym.val,
+                        .ty = sym.ty,
+                        .node = try p.addNode(.{
+                            .tag = .decl_ref_expr,
+                            .ty = sym.ty,
+                            .data = .{ .decl_ref = name_tok },
+                        }),
+                    };
+                }
+                if (sym.val.tag == .int) {
+                    switch (p.const_decl_folding) {
+                        .gnu_folding_extension => try p.errTok(.const_decl_folded, name_tok),
+                        .gnu_vla_folding_extension => try p.errTok(.const_decl_folded_vla, name_tok),
+                        else => {},
+                    }
+                }
+                return Result{
+                    .val = if (p.const_decl_folding == .no_const_decl_folding and sym.kind != .enumeration) Value{} else sym.val,
+                    .ty = sym.ty,
+                    .node = try p.addNode(.{
+                        .tag = if (sym.kind == .enumeration) .enumeration_ref else .decl_ref_expr,
+                        .ty = sym.ty,
+                        .data = .{ .decl_ref = name_tok },
+                    }),
+                };
+            }
+            if (try p.comp.builtins.getOrCreate(p.comp, name, p.arena)) |some| {
+                for (p.tok_ids[p.tok_i..]) |id| switch (id) {
+                    .r_paren => {}, // closing grouped expr
+                    .l_paren => break, // beginning of a call
+                    else => {
+                        try p.errTok(.builtin_must_be_called, name_tok);
+                        return error.ParsingFailed;
+                    },
+                };
+                if (some.builtin.properties.header != .none) {
+                    try p.errStr(.implicit_builtin, name_tok, name);
+                    try p.errExtra(.implicit_builtin_header_note, name_tok, .{ .builtin_with_header = .{
+                        .builtin = some.builtin.tag,
+                        .header = some.builtin.properties.header,
+                    } });
+                }
+
+                return Result{
+                    .ty = some.ty,
+                    .node = try p.addNode(.{
+                        .tag = .builtin_call_expr_one,
+                        .ty = some.ty,
+                        .data = .{ .decl = .{ .name = name_tok, .node = .none } },
+                    }),
+                };
+            }
+            if (p.tok_ids[p.tok_i] == .l_paren) {
+                // allow implicitly declaring functions before C99 like `puts("foo")`
+                if (mem.startsWith(u8, name, "__builtin_"))
+                    try p.errStr(.unknown_builtin, name_tok, name)
+                else
+                    try p.errStr(.implicit_func_decl, name_tok, name);
+
+                const func_ty = try p.arena.create(Type.Func);
+                func_ty.* = .{ .return_type = .{ .specifier = .int }, .params = &.{} };
+                const ty: Type = .{ .specifier = .old_style_func, .data = .{ .func = func_ty } };
+                const node = try p.addNode(.{
+                    .ty = ty,
+                    .tag = .fn_proto,
+                    .data = .{ .decl = .{ .name = name_tok } },
+                });
+
+                try p.decl_buf.append(node);
+                try p.syms.declareSymbol(p, interned_name, ty, name_tok, node);
+
+                return Result{
+                    .ty = ty,
+                    .node = try p.addNode(.{
+                        .tag = .decl_ref_expr,
+                        .ty = ty,
+                        .data = .{ .decl_ref = name_tok },
+                    }),
+                };
+            }
+            try p.errStr(.undeclared_identifier, name_tok, p.tokSlice(name_tok));
+            return error.ParsingFailed;
+        },
+        .keyword_true, .keyword_false => |id| {
+            p.tok_i += 1;
+            const numeric_value = @intFromBool(id == .keyword_true);
+            const res = Result{
+                .val = Value.int(numeric_value),
+                .ty = .{ .specifier = .bool },
+                .node = try p.addNode(.{
+                    .tag = .bool_literal,
+                    .ty = .{ .specifier = .bool },
+                    .data = .{ .int = numeric_value },
+                }),
+            };
+            std.debug.assert(!p.in_macro); // Should have been replaced with .one / .zero
+            try p.value_map.put(res.node, res.val);
+            return res;
+        },
+        .keyword_nullptr => {
+            defer p.tok_i += 1;
+            try p.errStr(.pre_c2x_compat, p.tok_i, "'nullptr'");
+            return Result{
+                .val = .{ .tag = .nullptr_t },
+                .ty = .{ .specifier = .nullptr_t },
+                .node = try p.addNode(.{
+                    .tag = .nullptr_literal,
+                    .ty = .{ .specifier = .nullptr_t },
+                    .data = undefined,
+                }),
+            };
+        },
+        .macro_func, .macro_function => {
+            defer p.tok_i += 1;
+            var ty: Type = undefined;
+            var tok = p.tok_i;
+            if (p.func.ident) |some| {
+                ty = some.ty;
+                tok = p.nodes.items(.data)[@intFromEnum(some.node)].decl.name;
+            } else if (p.func.ty) |_| {
+                const start: u32 = @intCast(p.retained_strings.items.len);
+                try p.retained_strings.appendSlice(p.tokSlice(p.func.name));
+                try p.retained_strings.append(0);
+                const predef = try p.makePredefinedIdentifier(start);
+                ty = predef.ty;
+                p.func.ident = predef;
+            } else {
+                const start: u32 = @intCast(p.retained_strings.items.len);
+                try p.retained_strings.append(0);
+                const predef = try p.makePredefinedIdentifier(start);
+                ty = predef.ty;
+                p.func.ident = predef;
+                try p.decl_buf.append(predef.node);
+            }
+            if (p.func.ty == null) try p.err(.predefined_top_level);
+            return Result{
+                .ty = ty,
+                .node = try p.addNode(.{
+                    .tag = .decl_ref_expr,
+                    .ty = ty,
+                    .data = .{ .decl_ref = tok },
+                }),
+            };
+        },
+        .macro_pretty_func => {
+            defer p.tok_i += 1;
+            var ty: Type = undefined;
+            if (p.func.pretty_ident) |some| {
+                ty = some.ty;
+            } else if (p.func.ty) |func_ty| {
+                const mapper = p.comp.string_interner.getSlowTypeMapper();
+                const start: u32 = @intCast(p.retained_strings.items.len);
+                try Type.printNamed(func_ty, p.tokSlice(p.func.name), mapper, p.comp.langopts, p.retained_strings.writer());
+                try p.retained_strings.append(0);
+                const predef = try p.makePredefinedIdentifier(start);
+                ty = predef.ty;
+                p.func.pretty_ident = predef;
+            } else {
+                const start: u32 = @intCast(p.retained_strings.items.len);
+                try p.retained_strings.appendSlice("top level\x00");
+                const predef = try p.makePredefinedIdentifier(start);
+                ty = predef.ty;
+                p.func.pretty_ident = predef;
+                try p.decl_buf.append(predef.node);
+            }
+            if (p.func.ty == null) try p.err(.predefined_top_level);
+            return Result{
+                .ty = ty,
+                .node = try p.addNode(.{
+                    .tag = .decl_ref_expr,
+                    .ty = ty,
+                    .data = .{ .decl_ref = p.tok_i },
+                }),
+            };
+        },
+        .string_literal,
+        .string_literal_utf_16,
+        .string_literal_utf_8,
+        .string_literal_utf_32,
+        .string_literal_wide,
+        => return p.stringLiteral(),
+        .char_literal,
+        .char_literal_utf_8,
+        .char_literal_utf_16,
+        .char_literal_utf_32,
+        .char_literal_wide,
+        => return p.charLiteral(),
+        .zero => {
+            p.tok_i += 1;
+            var res: Result = .{ .val = Value.int(0), .ty = if (p.in_macro) p.comp.types.intmax else Type.int };
+            res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
+            if (!p.in_macro) try p.value_map.put(res.node, res.val);
+            return res;
+        },
+        .one => {
+            p.tok_i += 1;
+            var res: Result = .{ .val = Value.int(1), .ty = if (p.in_macro) p.comp.types.intmax else Type.int };
+            res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
+            if (!p.in_macro) try p.value_map.put(res.node, res.val);
+            return res;
+        },
+        .pp_num => return p.ppNum(),
+        .embed_byte => {
+            assert(!p.in_macro);
+            const loc = p.pp.tokens.items(.loc)[p.tok_i];
+            p.tok_i += 1;
+            const buf = p.comp.getSource(.generated).buf[loc.byte_offset..];
+            var byte: u8 = buf[0] - '0';
+            for (buf[1..]) |c| {
+                if (!std.ascii.isDigit(c)) break;
+                byte *= 10;
+                byte += c - '0';
+            }
+            var res: Result = .{ .val = Value.int(byte) };
+            res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
+            try p.value_map.put(res.node, res.val);
+            return res;
+        },
+        .keyword_generic => return p.genericSelection(),
+        else => return Result{},
+    }
+}
+
+fn makePredefinedIdentifier(p: *Parser, start: u32) !Result {
+    const end: u32 = @intCast(p.retained_strings.items.len);
+    const elem_ty = .{ .specifier = .char, .qual = .{ .@"const" = true } };
+    const arr_ty = try p.arena.create(Type.Array);
+    arr_ty.* = .{ .elem = elem_ty, .len = end - start };
+    const ty: Type = .{ .specifier = .array, .data = .{ .array = arr_ty } };
+
+    const val = Value.bytes(start, end);
+    const str_lit = try p.addNode(.{ .tag = .string_literal_expr, .ty = ty, .data = undefined });
+    if (!p.in_macro) try p.value_map.put(str_lit, val);
+
+    return Result{ .ty = ty, .node = try p.addNode(.{
+        .tag = .implicit_static_var,
+        .ty = ty,
+        .data = .{ .decl = .{ .name = p.tok_i, .node = str_lit } },
+    }) };
+}
+
+fn stringLiteral(p: *Parser) Error!Result {
+    var start = p.tok_i;
+    // use 1 for wchar_t
+    var width: ?u8 = null;
+    var is_u8_literal = false;
+    while (true) {
+        switch (p.tok_ids[p.tok_i]) {
+            .string_literal => {},
+            .string_literal_utf_16 => if (width) |some| {
+                if (some != 16) try p.err(.unsupported_str_cat);
+            } else {
+                width = 16;
+            },
+            .string_literal_utf_8 => {
+                is_u8_literal = true;
+                if (width) |some| {
+                    if (some != 8) try p.err(.unsupported_str_cat);
+                } else {
+                    width = 8;
+                }
+            },
+            .string_literal_utf_32 => if (width) |some| {
+                if (some != 32) try p.err(.unsupported_str_cat);
+            } else {
+                width = 32;
+            },
+            .string_literal_wide => if (width) |some| {
+                if (some != 1) try p.err(.unsupported_str_cat);
+            } else {
+                width = 1;
+            },
+            else => break,
+        }
+        p.tok_i += 1;
+    }
+    if (width == null) width = 8;
+    if (width.? != 8) return p.todo("unicode string literals");
+
+    const string_start = p.retained_strings.items.len;
+    while (start < p.tok_i) : (start += 1) {
+        var slice = p.tokSlice(start);
+        slice = slice[0 .. slice.len - 1];
+        var i = mem.indexOf(u8, slice, "\"").? + 1;
+        try p.retained_strings.ensureUnusedCapacity(slice.len);
+        while (i < slice.len) : (i += 1) {
+            switch (slice[i]) {
+                '\\' => {
+                    i += 1;
+                    switch (slice[i]) {
+                        '\n' => i += 1,
+                        '\r' => i += 2,
+                        '\'', '\"', '\\', '?' => |c| p.retained_strings.appendAssumeCapacity(c),
+                        'n' => p.retained_strings.appendAssumeCapacity('\n'),
+                        'r' => p.retained_strings.appendAssumeCapacity('\r'),
+                        't' => p.retained_strings.appendAssumeCapacity('\t'),
+                        'a' => p.retained_strings.appendAssumeCapacity(0x07),
+                        'b' => p.retained_strings.appendAssumeCapacity(0x08),
+                        'e' => {
+                            try p.errExtra(.non_standard_escape_char, start, .{ .unsigned = i - 1 });
+                            p.retained_strings.appendAssumeCapacity(0x1B);
+                        },
+                        'f' => p.retained_strings.appendAssumeCapacity(0x0C),
+                        'v' => p.retained_strings.appendAssumeCapacity(0x0B),
+                        'x' => p.retained_strings.appendAssumeCapacity(try p.parseNumberEscape(start, 16, slice, &i)),
+                        '0'...'7' => p.retained_strings.appendAssumeCapacity(try p.parseNumberEscape(start, 8, slice, &i)),
+                        'u' => try p.parseUnicodeEscape(start, 4, slice, &i),
+                        'U' => try p.parseUnicodeEscape(start, 8, slice, &i),
+                        else => unreachable,
+                    }
+                },
+                else => |c| p.retained_strings.appendAssumeCapacity(c),
+            }
+        }
+    }
+    try p.retained_strings.append(0);
+    const slice = p.retained_strings.items[string_start..];
+
+    const arr_ty = try p.arena.create(Type.Array);
+    const specifier: Type.Specifier = if (is_u8_literal and p.comp.langopts.hasChar8_T()) .uchar else .char;
+
+    arr_ty.* = .{ .elem = .{ .specifier = specifier }, .len = slice.len };
+    var res: Result = .{
+        .ty = .{
+            .specifier = .array,
+            .data = .{ .array = arr_ty },
+        },
+        .val = Value.bytes(@intCast(string_start), @intCast(p.retained_strings.items.len)),
+    };
+    res.node = try p.addNode(.{ .tag = .string_literal_expr, .ty = res.ty, .data = undefined });
+    if (!p.in_macro) try p.value_map.put(res.node, res.val);
+    return res;
+}
+
+fn parseNumberEscape(p: *Parser, tok: TokenIndex, base: u8, slice: []const u8, i: *usize) !u8 {
+    if (base == 16) i.* += 1; // skip x
+    var char: u8 = 0;
+    var reported = false;
+    while (i.* < slice.len) : (i.* += 1) {
+        const val = std.fmt.charToDigit(slice[i.*], base) catch break; // validated by Tokenizer
+        const product, const overflowed = @mulWithOverflow(char, base);
+        if (overflowed != 0 and !reported) {
+            try p.errExtra(.escape_sequence_overflow, tok, .{ .unsigned = i.* });
+            reported = true;
+        }
+        char = product + val;
+    }
+    i.* -= 1;
+    return char;
+}
+
+fn parseUnicodeEscape(p: *Parser, tok: TokenIndex, count: u8, slice: []const u8, i: *usize) !void {
+    const c = std.fmt.parseInt(u21, slice[i.* + 1 ..][0..count], 16) catch 0x110000; // count validated by tokenizer
+    i.* += count + 1;
+    if (!std.unicode.utf8ValidCodepoint(c) or (c < 0xa0 and c != '$' and c != '@' and c != '`')) {
+        try p.errExtra(.invalid_universal_character, tok, .{ .unsigned = i.* - count - 2 });
+        return;
+    }
+    var buf: [4]u8 = undefined;
+    const to_write = std.unicode.utf8Encode(c, &buf) catch unreachable; // validated above
+    p.retained_strings.appendSliceAssumeCapacity(buf[0..to_write]);
+}
+
+fn charLiteral(p: *Parser) Error!Result {
+    defer p.tok_i += 1;
+    const allow_multibyte = switch (p.tok_ids[p.tok_i]) {
+        .char_literal => false,
+        .char_literal_utf_8 => false,
+        .char_literal_wide => true,
+        .char_literal_utf_16 => true,
+        .char_literal_utf_32 => true,
+        else => unreachable,
+    };
+    const ty: Type = switch (p.tok_ids[p.tok_i]) {
+        .char_literal => .{ .specifier = .int },
+        .char_literal_utf_8 => .{ .specifier = .uchar },
+        .char_literal_wide => p.comp.types.wchar,
+        .char_literal_utf_16 => .{ .specifier = .ushort },
+        .char_literal_utf_32 => .{ .specifier = .ulong },
+        else => unreachable,
+    };
+    const max: u32 = switch (p.tok_ids[p.tok_i]) {
+        .char_literal => std.math.maxInt(u8),
+        .char_literal_wide => @intCast(p.comp.types.wchar.maxInt(p.comp)),
+        .char_literal_utf_8 => std.math.maxInt(u8),
+        .char_literal_utf_16 => std.math.maxInt(u16),
+        .char_literal_utf_32 => std.math.maxInt(u32),
+        else => unreachable,
+    };
+    var multichar: u8 = switch (p.tok_ids[p.tok_i]) {
+        .char_literal => 0,
+        .char_literal_wide => 4,
+        .char_literal_utf_8 => 2,
+        .char_literal_utf_16 => 2,
+        .char_literal_utf_32 => 2,
+        else => unreachable,
+    };
+
+    var val: u32 = 0;
+    var overflow_reported = false;
+    var slice = p.tokSlice(p.tok_i);
+    slice = slice[0 .. slice.len - 1];
+    var i = mem.indexOf(u8, slice, "\'").? + 1;
+    while (i < slice.len) : (i += 1) {
+        var c: u32 = slice[i];
+        var multibyte = false;
+        switch (c) {
+            '\\' => {
+                i += 1;
+                switch (slice[i]) {
+                    '\n' => i += 1,
+                    '\r' => i += 2,
+                    '\'', '\"', '\\', '?' => c = slice[i],
+                    'n' => c = '\n',
+                    'r' => c = '\r',
+                    't' => c = '\t',
+                    'a' => c = 0x07,
+                    'b' => c = 0x08,
+                    'e' => {
+                        try p.errExtra(.non_standard_escape_char, p.tok_i, .{ .unsigned = i - 1 });
+                        c = 0x1B;
+                    },
+                    'f' => c = 0x0C,
+                    'v' => c = 0x0B,
+                    'x' => c = try p.parseNumberEscape(p.tok_i, 16, slice, &i),
+                    '0'...'7' => c = try p.parseNumberEscape(p.tok_i, 8, slice, &i),
+                    'u', 'U' => return p.todo("unicode escapes in char literals"),
+                    else => unreachable,
+                }
+            },
+            // These are safe since the source is checked to be valid utf8.
+            0b1100_0000...0b1101_1111 => {
+                c &= 0b00011111;
+                c <<= 6;
+                c |= slice[i + 1] & 0b00111111;
+                i += 1;
+                multibyte = true;
+            },
+            0b1110_0000...0b1110_1111 => {
+                c &= 0b00001111;
+                c <<= 6;
+                c |= slice[i + 1] & 0b00111111;
+                c <<= 6;
+                c |= slice[i + 2] & 0b00111111;
+                i += 2;
+                multibyte = true;
+            },
+            0b1111_0000...0b1111_0111 => {
+                c &= 0b00000111;
+                c <<= 6;
+                c |= slice[i + 1] & 0b00111111;
+                c <<= 6;
+                c |= slice[i + 2] & 0b00111111;
+                c <<= 6;
+                c |= slice[i + 3] & 0b00111111;
+                i += 3;
+                multibyte = true;
+            },
+            else => {},
+        }
+        if (c > max or (multibyte and !allow_multibyte)) try p.err(.char_too_large);
+        switch (multichar) {
+            0, 2, 4 => multichar += 1,
+            1 => {
+                multichar = 99;
+                try p.err(.multichar_literal);
+            },
+            3 => {
+                try p.err(.unicode_multichar_literal);
+                return error.ParsingFailed;
+            },
+            5 => {
+                try p.err(.wide_multichar_literal);
+                val = 0;
+                multichar = 6;
+            },
+            6 => val = 0,
+            else => {},
+        }
+        const product, const overflowed = @mulWithOverflow(val, max +% 1);
+        if (overflowed != 0 and !overflow_reported) {
+            try p.errExtra(.char_lit_too_wide, p.tok_i, .{ .unsigned = i });
+            overflow_reported = true;
+        }
+        val = product + c;
+    }
+
+    // This is the type the literal will have if we're in a macro; macros always operate on intmax_t/uintmax_t values
+    const macro_ty = if (ty.isUnsignedInt(p.comp) or (p.tok_ids[p.tok_i] == .char_literal and p.comp.getCharSignedness() == .unsigned))
+        p.comp.types.intmax.makeIntegerUnsigned()
+    else
+        p.comp.types.intmax;
+
+    var res = Result{
+        .ty = if (p.in_macro) macro_ty else ty,
+        .val = Value.int(val),
+        .node = try p.addNode(.{ .tag = .char_literal, .ty = ty, .data = undefined }),
+    };
+    if (!p.in_macro) try p.value_map.put(res.node, res.val);
+    return res;
+}
+
+fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {
+    switch (suffix) {
+        .L => return p.todo("long double literals"),
+        .IL => {
+            try p.err(.gnu_imaginary_constant);
+            return p.todo("long double imaginary literals");
+        },
+        .None, .I, .F, .IF, .F16 => {
+            const ty = Type{ .specifier = switch (suffix) {
+                .None, .I => .double,
+                .F, .IF => .float,
+                .F16 => .float16,
+                else => unreachable,
+            } };
+            const d_val = std.fmt.parseFloat(f64, buf) catch |er| switch (er) {
+                error.InvalidCharacter => return p.todo("c2x digit separators in floats"),
+                else => unreachable,
+            };
+            const tag: Tree.Tag = switch (suffix) {
+                .None, .I => .double_literal,
+                .F, .IF => .float_literal,
+                .F16 => .float16_literal,
+                else => unreachable,
+            };
+            var res = Result{
+                .ty = ty,
+                .node = try p.addNode(.{ .tag = tag, .ty = ty, .data = undefined }),
+                .val = Value.float(d_val),
+            };
+            if (suffix.isImaginary()) {
+                try p.err(.gnu_imaginary_constant);
+                res.ty = .{ .specifier = switch (suffix) {
+                    .I => .complex_double,
+                    .IF => .complex_float,
+                    else => unreachable,
+                } };
+                res.val.tag = .unavailable;
+                try res.un(p, .imaginary_literal);
+            }
+            return res;
+        },
+        else => unreachable,
+    }
+}
+
+fn getIntegerPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
+    if (buf[0] == '.') return "";
+
+    if (!prefix.digitAllowed(buf[0])) {
+        switch (prefix) {
+            .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(buf[0]) }),
+            .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(buf[0]) }),
+            .hex => try p.errStr(.invalid_int_suffix, tok_i, buf),
+            .decimal => unreachable,
+        }
+        return error.ParsingFailed;
+    }
+
+    for (buf, 0..) |c, idx| {
+        if (idx == 0) continue;
+        switch (c) {
+            '.' => return buf[0..idx],
+            'p', 'P' => return if (prefix == .hex) buf[0..idx] else {
+                try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]);
+                return error.ParsingFailed;
+            },
+            'e', 'E' => {
+                switch (prefix) {
+                    .hex => continue,
+                    .decimal => return buf[0..idx],
+                    .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }),
+                    .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }),
+                }
+                return error.ParsingFailed;
+            },
+            '0'...'9', 'a'...'d', 'A'...'D', 'f', 'F' => {
+                if (!prefix.digitAllowed(c)) {
+                    switch (prefix) {
+                        .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }),
+                        .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }),
+                        .decimal, .hex => try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]),
+                    }
+                    return error.ParsingFailed;
+                }
+            },
+            '\'' => {},
+            else => return buf[0..idx],
+        }
+    }
+    return buf;
+}
+
+fn fixedSizeInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result {
+    var val: u64 = 0;
+    var overflow = false;
+    for (buf) |c| {
+        const digit: u64 = switch (c) {
+            '0'...'9' => c - '0',
+            'A'...'Z' => c - 'A' + 10,
+            'a'...'z' => c - 'a' + 10,
+            '\'' => continue,
+            else => unreachable,
+        };
+
+        if (val != 0) {
+            const product, const overflowed = @mulWithOverflow(val, base);
+            if (overflowed != 0) {
+                overflow = true;
+            }
+            val = product;
+        }
+        const sum, const overflowed = @addWithOverflow(val, digit);
+        if (overflowed != 0) overflow = true;
+        val = sum;
+    }
+    if (overflow) {
+        try p.errTok(.int_literal_too_big, tok_i);
+        var res: Result = .{ .ty = .{ .specifier = .ulong_long }, .val = Value.int(val) };
+        res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
+        if (!p.in_macro) try p.value_map.put(res.node, res.val);
+        return res;
+    }
+    if (suffix.isSignedInteger()) {
+        if (val > p.comp.types.intmax.maxInt(p.comp)) {
+            try p.errTok(.implicitly_unsigned_literal, tok_i);
+        }
+    }
+    return if (base == 10)
+        switch (suffix) {
+            .None, .I => p.castInt(val, &.{ .int, .long, .long_long }),
+            .U, .IU => p.castInt(val, &.{ .uint, .ulong, .ulong_long }),
+            .L, .IL => p.castInt(val, &.{ .long, .long_long }),
+            .UL, .IUL => p.castInt(val, &.{ .ulong, .ulong_long }),
+            .LL, .ILL => p.castInt(val, &.{.long_long}),
+            .ULL, .IULL => p.castInt(val, &.{.ulong_long}),
+            else => unreachable,
+        }
+    else switch (suffix) {
+        .None, .I => p.castInt(val, &.{ .int, .uint, .long, .ulong, .long_long, .ulong_long }),
+        .U, .IU => p.castInt(val, &.{ .uint, .ulong, .ulong_long }),
+        .L, .IL => p.castInt(val, &.{ .long, .ulong, .long_long, .ulong_long }),
+        .UL, .IUL => p.castInt(val, &.{ .ulong, .ulong_long }),
+        .LL, .ILL => p.castInt(val, &.{ .long_long, .ulong_long }),
+        .ULL, .IULL => p.castInt(val, &.{.ulong_long}),
+        else => unreachable,
+    };
+}
+
+fn parseInt(p: *Parser, prefix: NumberPrefix, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result {
+    if (prefix == .binary) {
+        try p.errTok(.binary_integer_literal, tok_i);
+    }
+    const base = @intFromEnum(prefix);
+    var res = if (suffix.isBitInt())
+        try p.bitInt(base, buf, suffix, tok_i)
+    else
+        try p.fixedSizeInt(base, buf, suffix, tok_i);
+
+    if (suffix.isImaginary()) {
+        try p.errTok(.gnu_imaginary_constant, tok_i);
+        res.ty = res.ty.makeComplex();
+        res.val.tag = .unavailable;
+        try res.un(p, .imaginary_literal);
+    }
+    return res;
+}
+
+fn bitInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) Error!Result {
+    try p.errStr(.pre_c2x_compat, tok_i, "'_BitInt' suffix for literals");
+    try p.errTok(.bitint_suffix, tok_i);
+
+    var managed = try big.int.Managed.init(p.comp.gpa);
+    defer managed.deinit();
+
+    managed.setString(base, buf) catch |e| switch (e) {
+        error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 16
+        error.InvalidCharacter => unreachable, // digits validated by Tokenizer
+        else => |er| return er,
+    };
+    const c = managed.toConst();
+    const bits_needed: std.math.IntFittingRange(0, Compilation.bit_int_max_bits) = blk: {
+        // Literal `0` requires at least 1 bit
+        const count = @max(1, c.bitCountTwosComp());
+        // The wb suffix results in a _BitInt that includes space for the sign bit even if the
+        // value of the constant is positive or was specified in hexadecimal or octal notation.
+        const sign_bits = @intFromBool(suffix.isSignedInteger());
+        const bits_needed = count + sign_bits;
+        if (bits_needed > Compilation.bit_int_max_bits) {
+            const specifier: Type.Builder.Specifier = switch (suffix) {
+                .WB => .{ .bit_int = 0 },
+                .UWB => .{ .ubit_int = 0 },
+                .IWB => .{ .complex_bit_int = 0 },
+                .IUWB => .{ .complex_ubit_int = 0 },
+                else => unreachable,
+            };
+            try p.errStr(.bit_int_too_big, tok_i, specifier.str(p.comp.langopts).?);
+            return error.ParsingFailed;
+        }
+        if (bits_needed > 64) {
+            return p.todo("_BitInt constants > 64 bits");
+        }
+        break :blk @intCast(bits_needed);
+    };
+
+    const val = c.to(u64) catch |e| switch (e) {
+        error.NegativeIntoUnsigned => unreachable, // unary minus parsed elsewhere; we only see positive integers
+        error.TargetTooSmall => unreachable, // Validated above but Todo: handle larger _BitInt
+    };
+
+    var res: Result = .{
+        .val = Value.int(val),
+        .ty = .{
+            .specifier = .bit_int,
+            .data = .{ .int = .{ .bits = bits_needed, .signedness = suffix.signedness() } },
+        },
+    };
+    res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = .{ .int = val } });
+    if (!p.in_macro) try p.value_map.put(res.node, res.val);
+    return res;
+}
+
+fn getFracPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
+    if (buf.len == 0 or buf[0] != '.') return "";
+    assert(prefix != .octal);
+    if (prefix == .binary) {
+        try p.errStr(.invalid_int_suffix, tok_i, buf);
+        return error.ParsingFailed;
+    }
+    for (buf, 0..) |c, idx| {
+        if (idx == 0) continue;
+        if (c == '\'') continue;
+        if (!prefix.digitAllowed(c)) return buf[0..idx];
+    }
+    return buf;
+}
+
+fn getExponent(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
+    if (buf.len == 0) return "";
+
+    switch (buf[0]) {
+        'e', 'E' => assert(prefix == .decimal),
+        'p', 'P' => if (prefix != .hex) {
+            try p.errStr(.invalid_float_suffix, tok_i, buf);
+            return error.ParsingFailed;
+        },
+        else => return "",
+    }
+    const end = for (buf, 0..) |c, idx| {
+        if (idx == 0) continue;
+        if (idx == 1 and (c == '+' or c == '-')) continue;
+        switch (c) {
+            '0'...'9' => {},
+            '\'' => continue,
+            else => break idx,
+        }
+    } else buf.len;
+    const exponent = buf[0..end];
+    if (std.mem.indexOfAny(u8, exponent, "0123456789") == null) {
+        try p.errTok(.exponent_has_no_digits, tok_i);
+        return error.ParsingFailed;
+    }
+    return exponent;
+}
+
+/// Using an explicit `tok_i` parameter instead of `p.tok_i` makes it easier
+/// to parse numbers in pragma handlers.
+pub fn parseNumberToken(p: *Parser, tok_i: TokenIndex) !Result {
+    const buf = p.tokSlice(tok_i);
+    const prefix = NumberPrefix.fromString(buf);
+    const after_prefix = buf[prefix.stringLen()..];
+
+    const int_part = try p.getIntegerPart(after_prefix, prefix, tok_i);
+
+    const after_int = after_prefix[int_part.len..];
+
+    const frac = try p.getFracPart(after_int, prefix, tok_i);
+    const after_frac = after_int[frac.len..];
+
+    const exponent = try p.getExponent(after_frac, prefix, tok_i);
+    const suffix_str = after_frac[exponent.len..];
+    const is_float = (exponent.len > 0 or frac.len > 0);
+    const suffix = NumberSuffix.fromString(suffix_str, if (is_float) .float else .int) orelse {
+        if (is_float) {
+            try p.errStr(.invalid_float_suffix, tok_i, suffix_str);
+        } else {
+            try p.errStr(.invalid_int_suffix, tok_i, suffix_str);
+        }
+        return error.ParsingFailed;
+    };
+
+    if (is_float) {
+        assert(prefix == .hex or prefix == .decimal);
+        if (prefix == .hex and exponent.len == 0) {
+            try p.errTok(.hex_floating_constant_requires_exponent, tok_i);
+            return error.ParsingFailed;
+        }
+        const number = buf[0 .. buf.len - suffix_str.len];
+        return p.parseFloat(number, suffix);
+    } else {
+        return p.parseInt(prefix, int_part, suffix, tok_i);
+    }
+}
+
+fn ppNum(p: *Parser) Error!Result {
+    defer p.tok_i += 1;
+    var res = try p.parseNumberToken(p.tok_i);
+    if (p.in_macro) {
+        if (res.ty.isFloat() or !res.ty.isReal()) {
+            try p.errTok(.float_literal_in_pp_expr, p.tok_i);
+            return error.ParsingFailed;
+        }
+        res.ty = if (res.ty.isUnsignedInt(p.comp)) p.comp.types.intmax.makeIntegerUnsigned() else p.comp.types.intmax;
+    } else {
+        try p.value_map.put(res.node, res.val);
+    }
+    return res;
+}
+
+fn castInt(p: *Parser, val: u64, specs: []const Type.Specifier) Error!Result {
+    var res: Result = .{ .val = Value.int(val) };
+    for (specs) |spec| {
+        const ty = Type{ .specifier = spec };
+        const unsigned = ty.isUnsignedInt(p.comp);
+        const size = ty.sizeof(p.comp).?;
+        res.ty = ty;
+
+        if (unsigned) {
+            switch (size) {
+                2 => if (val <= std.math.maxInt(u16)) break,
+                4 => if (val <= std.math.maxInt(u32)) break,
+                8 => if (val <= std.math.maxInt(u64)) break,
+                else => unreachable,
+            }
+        } else {
+            switch (size) {
+                2 => if (val <= std.math.maxInt(i16)) break,
+                4 => if (val <= std.math.maxInt(i32)) break,
+                8 => if (val <= std.math.maxInt(i64)) break,
+                else => unreachable,
+            }
+        }
+    } else {
+        res.ty = .{ .specifier = .ulong_long };
+    }
+    res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = .{ .int = val } });
+    if (!p.in_macro) try p.value_map.put(res.node, res.val);
+    return res;
+}
+
+/// Run a parser function but do not evaluate the result
+fn parseNoEval(p: *Parser, comptime func: fn (*Parser) Error!Result) Error!Result {
+    const no_eval = p.no_eval;
+    defer p.no_eval = no_eval;
+    p.no_eval = true;
+    const parsed = try func(p);
+    try parsed.expect(p);
+    return parsed;
+}
+
+/// genericSelection : keyword_generic '(' assignExpr ',' genericAssoc (',' genericAssoc)* ')'
+/// genericAssoc
+///  : typeName ':' assignExpr
+///  | keyword_default ':' assignExpr
+fn genericSelection(p: *Parser) Error!Result {
+    p.tok_i += 1;
+    const l_paren = try p.expectToken(.l_paren);
+    const controlling_tok = p.tok_i;
+    const controlling = try p.parseNoEval(assignExpr);
+    _ = try p.expectToken(.comma);
+    var controlling_ty = controlling.ty;
+    if (controlling_ty.isArray()) controlling_ty.decayArray();
+
+    const list_buf_top = p.list_buf.items.len;
+    defer p.list_buf.items.len = list_buf_top;
+    try p.list_buf.append(controlling.node);
+
+    // Use decl_buf to store the token indexes of previous cases
+    const decl_buf_top = p.decl_buf.items.len;
+    defer p.decl_buf.items.len = decl_buf_top;
+
+    var default_tok: ?TokenIndex = null;
+    var default: Result = undefined;
+    var chosen_tok: TokenIndex = undefined;
+    var chosen: Result = .{};
+    while (true) {
+        const start = p.tok_i;
+        if (try p.typeName()) |ty| blk: {
+            if (ty.isArray()) {
+                try p.errTok(.generic_array_type, start);
+            } else if (ty.isFunc()) {
+                try p.errTok(.generic_func_type, start);
+            } else if (ty.anyQual()) {
+                try p.errTok(.generic_qual_type, start);
+            }
+            _ = try p.expectToken(.colon);
+            const node = try p.assignExpr();
+            try node.expect(p);
+
+            if (ty.eql(controlling_ty, p.comp, false)) {
+                if (chosen.node == .none) {
+                    chosen = node;
+                    chosen_tok = start;
+                    break :blk;
+                }
+                try p.errStr(.generic_duplicate, start, try p.typeStr(ty));
+                try p.errStr(.generic_duplicate_here, chosen_tok, try p.typeStr(ty));
+            }
+            for (p.list_buf.items[list_buf_top + 1 ..], p.decl_buf.items[decl_buf_top..]) |item, prev_tok| {
+                const prev_ty = p.nodes.items(.ty)[@intFromEnum(item)];
+                if (prev_ty.eql(ty, p.comp, true)) {
+                    try p.errStr(.generic_duplicate, start, try p.typeStr(ty));
+                    try p.errStr(.generic_duplicate_here, @intFromEnum(prev_tok), try p.typeStr(ty));
+                }
+            }
+            try p.list_buf.append(try p.addNode(.{
+                .tag = .generic_association_expr,
+                .ty = ty,
+                .data = .{ .un = node.node },
+            }));
+            try p.decl_buf.append(@enumFromInt(start));
+        } else if (p.eatToken(.keyword_default)) |tok| {
+            if (default_tok) |prev| {
+                try p.errTok(.generic_duplicate_default, tok);
+                try p.errTok(.previous_case, prev);
+            }
+            default_tok = tok;
+            _ = try p.expectToken(.colon);
+            default = try p.assignExpr();
+            try default.expect(p);
+        } else {
+            if (p.list_buf.items.len == list_buf_top + 1) {
+                try p.err(.expected_type);
+                return error.ParsingFailed;
+            }
+            break;
+        }
+        if (p.eatToken(.comma) == null) break;
+    }
+    try p.expectClosing(l_paren, .r_paren);
+
+    if (chosen.node == .none) {
+        if (default_tok != null) {
+            try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{
+                .tag = .generic_default_expr,
+                .data = .{ .un = default.node },
+            }));
+            chosen = default;
+        } else {
+            try p.errStr(.generic_no_match, controlling_tok, try p.typeStr(controlling_ty));
+            return error.ParsingFailed;
+        }
+    } else {
+        try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{
+            .tag = .generic_association_expr,
+            .data = .{ .un = chosen.node },
+        }));
+        if (default_tok != null) {
+            try p.list_buf.append(try p.addNode(.{
+                .tag = .generic_default_expr,
+                .data = .{ .un = chosen.node },
+            }));
+        }
+    }
+
+    var generic_node: Tree.Node = .{
+        .tag = .generic_expr_one,
+        .ty = chosen.ty,
+        .data = .{ .bin = .{ .lhs = controlling.node, .rhs = chosen.node } },
+    };
+    const associations = p.list_buf.items[list_buf_top..];
+    if (associations.len > 2) { // associations[0] == controlling.node
+        generic_node.tag = .generic_expr;
+        generic_node.data = .{ .range = try p.addList(associations) };
+    }
+    chosen.node = try p.addNode(generic_node);
+    return chosen;
+}
deps/aro/Pragma.zig
@@ -0,0 +1,83 @@
+const std = @import("std");
+const Compilation = @import("Compilation.zig");
+const Preprocessor = @import("Preprocessor.zig");
+const Parser = @import("Parser.zig");
+const TokenIndex = @import("Tree.zig").TokenIndex;
+
+const Pragma = @This();
+
+pub const Error = Compilation.Error || error{ UnknownPragma, StopPreprocessing };
+
+/// Called during Preprocessor.init
+beforePreprocess: ?*const fn (*Pragma, *Compilation) void = null,
+
+/// Called at the beginning of Parser.parse
+beforeParse: ?*const fn (*Pragma, *Compilation) void = null,
+
+/// Called at the end of Parser.parse if a Tree was successfully parsed
+afterParse: ?*const fn (*Pragma, *Compilation) void = null,
+
+/// Called during Compilation.deinit
+deinit: *const fn (*Pragma, *Compilation) void,
+
+/// Called whenever the preprocessor encounters this pragma. `start_idx` is the index
+/// within `pp.tokens` of the pragma name token. The pragma end is indicated by a
+/// .nl token (which may be generated if the source ends with a pragma with no newline)
+/// As an example, given the following line:
+///     #pragma GCC diagnostic error "-Wnewline-eof" \n
+/// Then pp.tokens.get(start_idx) will return the `GCC` token.
+/// Return error.UnknownPragma to emit an `unknown_pragma` diagnostic
+/// Return error.StopPreprocessing to stop preprocessing the current file (see once.zig)
+preprocessorHandler: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) Error!void = null,
+
+/// Called during token pretty-printing (`-E` option). If this returns true, the pragma will
+/// be printed; otherwise it will be omitted. start_idx is the index of the pragma name token
+preserveTokens: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) bool = null,
+
+/// Same as preprocessorHandler except called during parsing
+/// The parser's `p.tok_i` field must not be changed
+parserHandler: ?*const fn (*Pragma, *Parser, start_idx: TokenIndex) Compilation.Error!void = null,
+
+pub fn pasteTokens(pp: *Preprocessor, start_idx: TokenIndex) ![]const u8 {
+    if (pp.tokens.get(start_idx).id == .nl) return error.ExpectedStringLiteral;
+
+    const char_top = pp.char_buf.items.len;
+    defer pp.char_buf.items.len = char_top;
+    var i: usize = 0;
+    var lparen_count: u32 = 0;
+    var rparen_count: u32 = 0;
+    while (true) : (i += 1) {
+        const tok = pp.tokens.get(start_idx + i);
+        if (tok.id == .nl) break;
+        switch (tok.id) {
+            .l_paren => {
+                if (lparen_count != i) return error.ExpectedStringLiteral;
+                lparen_count += 1;
+            },
+            .r_paren => rparen_count += 1,
+            .string_literal => {
+                if (rparen_count != 0) return error.ExpectedStringLiteral;
+                const str = pp.expandedSlice(tok);
+                try pp.char_buf.appendSlice(str[1 .. str.len - 1]);
+            },
+            else => return error.ExpectedStringLiteral,
+        }
+    }
+    if (lparen_count != rparen_count) return error.ExpectedStringLiteral;
+    return pp.char_buf.items[char_top..];
+}
+
+pub fn shouldPreserveTokens(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
+    if (self.preserveTokens) |func| return func(self, pp, start_idx);
+    return false;
+}
+
+pub fn preprocessorCB(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Error!void {
+    if (self.preprocessorHandler) |func| return func(self, pp, start_idx);
+}
+
+pub fn parserCB(self: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
+    const tok_index = p.tok_i;
+    defer std.debug.assert(tok_index == p.tok_i);
+    if (self.parserHandler) |func| return func(self, p, start_idx);
+}
deps/aro/Preprocessor.zig
@@ -0,0 +1,2691 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const assert = std.debug.assert;
+const Compilation = @import("Compilation.zig");
+const Error = Compilation.Error;
+const Source = @import("Source.zig");
+const Tokenizer = @import("Tokenizer.zig");
+const RawToken = Tokenizer.Token;
+const Parser = @import("Parser.zig");
+const Diagnostics = @import("Diagnostics.zig");
+const Token = @import("Tree.zig").Token;
+const Attribute = @import("Attribute.zig");
+const features = @import("features.zig");
+
+const Preprocessor = @This();
+const DefineMap = std.StringHashMap(Macro);
+const RawTokenList = std.ArrayList(RawToken);
+const max_include_depth = 200;
+
+/// Errors that can be returned when expanding a macro.
+/// error.UnknownPragma can occur within Preprocessor.pragma() but
+/// it is handled there and doesn't escape that function
+const MacroError = Error || error{StopPreprocessing};
+
+const Macro = struct {
+    /// Parameters of the function type macro
+    params: []const []const u8,
+
+    /// Token constituting the macro body
+    tokens: []const RawToken,
+
+    /// If the function type macro has variable number of arguments
+    var_args: bool,
+
+    /// Is a function type macro
+    is_func: bool,
+
+    /// Is a predefined macro
+    is_builtin: bool = false,
+
+    /// Location of macro in the source
+    /// `byte_offset` and `line` are used to define the range of tokens included
+    /// in the macro.
+    loc: Source.Location,
+
+    fn eql(a: Macro, b: Macro, pp: *Preprocessor) bool {
+        if (a.tokens.len != b.tokens.len) return false;
+        if (a.is_builtin != b.is_builtin) return false;
+        for (a.tokens, b.tokens) |a_tok, b_tok| if (!tokEql(pp, a_tok, b_tok)) return false;
+
+        if (a.is_func and b.is_func) {
+            if (a.var_args != b.var_args) return false;
+            if (a.params.len != b.params.len) return false;
+            for (a.params, b.params) |a_param, b_param| if (!mem.eql(u8, a_param, b_param)) return false;
+        }
+
+        return true;
+    }
+
+    fn tokEql(pp: *Preprocessor, a: RawToken, b: RawToken) bool {
+        return mem.eql(u8, pp.tokSlice(a), pp.tokSlice(b));
+    }
+};
+
+comp: *Compilation,
+gpa: mem.Allocator,
+arena: std.heap.ArenaAllocator,
+defines: DefineMap,
+tokens: Token.List = .{},
+token_buf: RawTokenList,
+char_buf: std.ArrayList(u8),
+/// Counter that is incremented each time preprocess() is called
+/// Can be used to distinguish multiple preprocessings of the same file
+preprocess_count: u32 = 0,
+generated_line: u32 = 1,
+add_expansion_nl: u32 = 0,
+include_depth: u8 = 0,
+counter: u32 = 0,
+expansion_source_loc: Source.Location = undefined,
+poisoned_identifiers: std.StringHashMap(void),
+/// Map from Source.Id to macro name in the `#ifndef` condition which guards the source, if any
+include_guards: std.AutoHashMapUnmanaged(Source.Id, []const u8) = .{},
+
+/// Memory is retained to avoid allocation on every single token.
+top_expansion_buf: ExpandBuf,
+
+/// Dump current state to stderr.
+verbose: bool = false,
+preserve_whitespace: bool = false,
+
+pub fn init(comp: *Compilation) Preprocessor {
+    const pp = Preprocessor{
+        .comp = comp,
+        .gpa = comp.gpa,
+        .arena = std.heap.ArenaAllocator.init(comp.gpa),
+        .defines = DefineMap.init(comp.gpa),
+        .token_buf = RawTokenList.init(comp.gpa),
+        .char_buf = std.ArrayList(u8).init(comp.gpa),
+        .poisoned_identifiers = std.StringHashMap(void).init(comp.gpa),
+        .top_expansion_buf = ExpandBuf.init(comp.gpa),
+    };
+    comp.pragmaEvent(.before_preprocess);
+    return pp;
+}
+
+const builtin_macros = struct {
+    const args = [1][]const u8{"X"};
+
+    const has_attribute = [1]RawToken{.{
+        .id = .macro_param_has_attribute,
+        .source = .generated,
+    }};
+    const has_warning = [1]RawToken{.{
+        .id = .macro_param_has_warning,
+        .source = .generated,
+    }};
+    const has_feature = [1]RawToken{.{
+        .id = .macro_param_has_feature,
+        .source = .generated,
+    }};
+    const has_extension = [1]RawToken{.{
+        .id = .macro_param_has_extension,
+        .source = .generated,
+    }};
+    const has_builtin = [1]RawToken{.{
+        .id = .macro_param_has_builtin,
+        .source = .generated,
+    }};
+    const has_include = [1]RawToken{.{
+        .id = .macro_param_has_include,
+        .source = .generated,
+    }};
+    const has_include_next = [1]RawToken{.{
+        .id = .macro_param_has_include_next,
+        .source = .generated,
+    }};
+
+    const is_identifier = [1]RawToken{.{
+        .id = .macro_param_is_identifier,
+        .source = .generated,
+    }};
+
+    const pragma_operator = [1]RawToken{.{
+        .id = .macro_param_pragma_operator,
+        .source = .generated,
+    }};
+
+    const file = [1]RawToken{.{
+        .id = .macro_file,
+        .source = .generated,
+    }};
+    const line = [1]RawToken{.{
+        .id = .macro_line,
+        .source = .generated,
+    }};
+    const counter = [1]RawToken{.{
+        .id = .macro_counter,
+        .source = .generated,
+    }};
+};
+
+fn addBuiltinMacro(pp: *Preprocessor, name: []const u8, is_func: bool, tokens: []const RawToken) !void {
+    try pp.defines.putNoClobber(name, .{
+        .params = &builtin_macros.args,
+        .tokens = tokens,
+        .var_args = false,
+        .is_func = is_func,
+        .loc = .{ .id = .generated },
+        .is_builtin = true,
+    });
+}
+
+pub fn addBuiltinMacros(pp: *Preprocessor) !void {
+    try pp.addBuiltinMacro("__has_attribute", true, &builtin_macros.has_attribute);
+    try pp.addBuiltinMacro("__has_warning", true, &builtin_macros.has_warning);
+    try pp.addBuiltinMacro("__has_feature", true, &builtin_macros.has_feature);
+    try pp.addBuiltinMacro("__has_extension", true, &builtin_macros.has_extension);
+    try pp.addBuiltinMacro("__has_builtin", true, &builtin_macros.has_builtin);
+    try pp.addBuiltinMacro("__has_include", true, &builtin_macros.has_include);
+    try pp.addBuiltinMacro("__has_include_next", true, &builtin_macros.has_include_next);
+    try pp.addBuiltinMacro("__is_identifier", true, &builtin_macros.is_identifier);
+    try pp.addBuiltinMacro("_Pragma", true, &builtin_macros.pragma_operator);
+
+    try pp.addBuiltinMacro("__FILE__", false, &builtin_macros.file);
+    try pp.addBuiltinMacro("__LINE__", false, &builtin_macros.line);
+    try pp.addBuiltinMacro("__COUNTER__", false, &builtin_macros.counter);
+}
+
+pub fn deinit(pp: *Preprocessor) void {
+    pp.defines.deinit();
+    for (pp.tokens.items(.expansion_locs)) |loc| Token.free(loc, pp.gpa);
+    pp.tokens.deinit(pp.gpa);
+    pp.arena.deinit();
+    pp.token_buf.deinit();
+    pp.char_buf.deinit();
+    pp.poisoned_identifiers.deinit();
+    pp.include_guards.deinit(pp.gpa);
+    pp.top_expansion_buf.deinit();
+}
+
+/// Preprocess a source file, returns eof token.
+pub fn preprocess(pp: *Preprocessor, source: Source) Error!Token {
+    return pp.preprocessExtra(source) catch |er| switch (er) {
+        // This cannot occur in the main file and is handled in `include`.
+        error.StopPreprocessing => unreachable,
+        else => |e| return e,
+    };
+}
+
+/// Return the name of the #ifndef guard macro that starts a source, if any.
+fn findIncludeGuard(pp: *Preprocessor, source: Source) ?[]const u8 {
+    var tokenizer = Tokenizer{
+        .buf = source.buf,
+        .comp = pp.comp,
+        .source = source.id,
+    };
+    var hash = tokenizer.nextNoWS();
+    while (hash.id == .nl) hash = tokenizer.nextNoWS();
+    if (hash.id != .hash) return null;
+    const ifndef = tokenizer.nextNoWS();
+    if (ifndef.id != .keyword_ifndef) return null;
+    const guard = tokenizer.nextNoWS();
+    if (guard.id != .identifier) return null;
+    return pp.tokSlice(guard);
+}
+
+fn preprocessExtra(pp: *Preprocessor, source: Source) MacroError!Token {
+    if (pp.comp.invalid_utf8_locs.get(source.id)) |offset| {
+        try pp.comp.diag.add(.{
+            .tag = .invalid_utf8,
+            // Todo: compute line number
+            .loc = .{ .id = source.id, .byte_offset = offset },
+        }, &.{});
+        return error.FatalError;
+    }
+    var guard_name = pp.findIncludeGuard(source);
+
+    pp.preprocess_count += 1;
+    var tokenizer = Tokenizer{
+        .buf = source.buf,
+        .comp = pp.comp,
+        .source = source.id,
+    };
+
+    // Estimate how many new tokens this source will contain.
+    const estimated_token_count = source.buf.len / 8;
+    try pp.tokens.ensureTotalCapacity(pp.gpa, pp.tokens.len + estimated_token_count);
+
+    var if_level: u8 = 0;
+    var if_kind = std.PackedIntArray(u2, 256).init([1]u2{0} ** 256);
+    const until_else = 0;
+    const until_endif = 1;
+    const until_endif_seen_else = 2;
+
+    var start_of_line = true;
+    while (true) {
+        var tok = tokenizer.next();
+        switch (tok.id) {
+            .hash => if (!start_of_line) try pp.tokens.append(pp.gpa, tokFromRaw(tok)) else {
+                const directive = tokenizer.nextNoWS();
+                switch (directive.id) {
+                    .keyword_error, .keyword_warning => {
+                        // #error tokens..
+                        pp.top_expansion_buf.items.len = 0;
+                        const char_top = pp.char_buf.items.len;
+                        defer pp.char_buf.items.len = char_top;
+
+                        while (true) {
+                            tok = tokenizer.next();
+                            if (tok.id == .nl or tok.id == .eof) break;
+                            if (tok.id == .whitespace) tok.id = .macro_ws;
+                            try pp.top_expansion_buf.append(tokFromRaw(tok));
+                        }
+                        try pp.stringify(pp.top_expansion_buf.items);
+                        const slice = pp.char_buf.items[char_top + 1 .. pp.char_buf.items.len - 2];
+                        const duped = try pp.comp.diag.arena.allocator().dupe(u8, slice);
+
+                        try pp.comp.diag.add(.{
+                            .tag = if (directive.id == .keyword_error) .error_directive else .warning_directive,
+                            .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
+                            .extra = .{ .str = duped },
+                        }, &.{});
+                    },
+                    .keyword_if => {
+                        const sum, const overflowed = @addWithOverflow(if_level, 1);
+                        if (overflowed != 0)
+                            return pp.fatal(directive, "too many #if nestings", .{});
+                        if_level = sum;
+
+                        if (try pp.expr(&tokenizer)) {
+                            if_kind.set(if_level, until_endif);
+                            if (pp.verbose) {
+                                pp.verboseLog(directive, "entering then branch of #if", .{});
+                            }
+                        } else {
+                            if_kind.set(if_level, until_else);
+                            try pp.skip(&tokenizer, .until_else);
+                            if (pp.verbose) {
+                                pp.verboseLog(directive, "entering else branch of #if", .{});
+                            }
+                        }
+                    },
+                    .keyword_ifdef => {
+                        const sum, const overflowed = @addWithOverflow(if_level, 1);
+                        if (overflowed != 0)
+                            return pp.fatal(directive, "too many #if nestings", .{});
+                        if_level = sum;
+
+                        const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
+                        try pp.expectNl(&tokenizer);
+                        if (pp.defines.get(macro_name) != null) {
+                            if_kind.set(if_level, until_endif);
+                            if (pp.verbose) {
+                                pp.verboseLog(directive, "entering then branch of #ifdef", .{});
+                            }
+                        } else {
+                            if_kind.set(if_level, until_else);
+                            try pp.skip(&tokenizer, .until_else);
+                            if (pp.verbose) {
+                                pp.verboseLog(directive, "entering else branch of #ifdef", .{});
+                            }
+                        }
+                    },
+                    .keyword_ifndef => {
+                        const sum, const overflowed = @addWithOverflow(if_level, 1);
+                        if (overflowed != 0)
+                            return pp.fatal(directive, "too many #if nestings", .{});
+                        if_level = sum;
+
+                        const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
+                        try pp.expectNl(&tokenizer);
+                        if (pp.defines.get(macro_name) == null) {
+                            if_kind.set(if_level, until_endif);
+                        } else {
+                            if_kind.set(if_level, until_else);
+                            try pp.skip(&tokenizer, .until_else);
+                        }
+                    },
+                    .keyword_elif => {
+                        if (if_level == 0) {
+                            try pp.err(directive, .elif_without_if);
+                            if_level += 1;
+                            if_kind.set(if_level, until_else);
+                        } else if (if_level == 1) {
+                            guard_name = null;
+                        }
+                        switch (if_kind.get(if_level)) {
+                            until_else => if (try pp.expr(&tokenizer)) {
+                                if_kind.set(if_level, until_endif);
+                                if (pp.verbose) {
+                                    pp.verboseLog(directive, "entering then branch of #elif", .{});
+                                }
+                            } else {
+                                try pp.skip(&tokenizer, .until_else);
+                                if (pp.verbose) {
+                                    pp.verboseLog(directive, "entering else branch of #elif", .{});
+                                }
+                            },
+                            until_endif => try pp.skip(&tokenizer, .until_endif),
+                            until_endif_seen_else => {
+                                try pp.err(directive, .elif_after_else);
+                                skipToNl(&tokenizer);
+                            },
+                            else => unreachable,
+                        }
+                    },
+                    .keyword_elifdef => {
+                        if (if_level == 0) {
+                            try pp.err(directive, .elifdef_without_if);
+                            if_level += 1;
+                            if_kind.set(if_level, until_else);
+                        } else if (if_level == 1) {
+                            guard_name = null;
+                        }
+                        switch (if_kind.get(if_level)) {
+                            until_else => {
+                                const macro_name = try pp.expectMacroName(&tokenizer);
+                                if (macro_name == null) {
+                                    if_kind.set(if_level, until_else);
+                                    try pp.skip(&tokenizer, .until_else);
+                                    if (pp.verbose) {
+                                        pp.verboseLog(directive, "entering else branch of #elifdef", .{});
+                                    }
+                                } else {
+                                    try pp.expectNl(&tokenizer);
+                                    if (pp.defines.get(macro_name.?) != null) {
+                                        if_kind.set(if_level, until_endif);
+                                        if (pp.verbose) {
+                                            pp.verboseLog(directive, "entering then branch of #elifdef", .{});
+                                        }
+                                    } else {
+                                        if_kind.set(if_level, until_else);
+                                        try pp.skip(&tokenizer, .until_else);
+                                        if (pp.verbose) {
+                                            pp.verboseLog(directive, "entering else branch of #elifdef", .{});
+                                        }
+                                    }
+                                }
+                            },
+                            until_endif => try pp.skip(&tokenizer, .until_endif),
+                            until_endif_seen_else => {
+                                try pp.err(directive, .elifdef_after_else);
+                                skipToNl(&tokenizer);
+                            },
+                            else => unreachable,
+                        }
+                    },
+                    .keyword_elifndef => {
+                        if (if_level == 0) {
+                            try pp.err(directive, .elifdef_without_if);
+                            if_level += 1;
+                            if_kind.set(if_level, until_else);
+                        } else if (if_level == 1) {
+                            guard_name = null;
+                        }
+                        switch (if_kind.get(if_level)) {
+                            until_else => {
+                                const macro_name = try pp.expectMacroName(&tokenizer);
+                                if (macro_name == null) {
+                                    if_kind.set(if_level, until_else);
+                                    try pp.skip(&tokenizer, .until_else);
+                                    if (pp.verbose) {
+                                        pp.verboseLog(directive, "entering else branch of #elifndef", .{});
+                                    }
+                                } else {
+                                    try pp.expectNl(&tokenizer);
+                                    if (pp.defines.get(macro_name.?) == null) {
+                                        if_kind.set(if_level, until_endif);
+                                        if (pp.verbose) {
+                                            pp.verboseLog(directive, "entering then branch of #elifndef", .{});
+                                        }
+                                    } else {
+                                        if_kind.set(if_level, until_else);
+                                        try pp.skip(&tokenizer, .until_else);
+                                        if (pp.verbose) {
+                                            pp.verboseLog(directive, "entering else branch of #elifndef", .{});
+                                        }
+                                    }
+                                }
+                            },
+                            until_endif => try pp.skip(&tokenizer, .until_endif),
+                            until_endif_seen_else => {
+                                try pp.err(directive, .elifdef_after_else);
+                                skipToNl(&tokenizer);
+                            },
+                            else => unreachable,
+                        }
+                    },
+                    .keyword_else => {
+                        try pp.expectNl(&tokenizer);
+                        if (if_level == 0) {
+                            try pp.err(directive, .else_without_if);
+                            continue;
+                        } else if (if_level == 1) {
+                            guard_name = null;
+                        }
+                        switch (if_kind.get(if_level)) {
+                            until_else => {
+                                if_kind.set(if_level, until_endif_seen_else);
+                                if (pp.verbose) {
+                                    pp.verboseLog(directive, "#else branch here", .{});
+                                }
+                            },
+                            until_endif => try pp.skip(&tokenizer, .until_endif_seen_else),
+                            until_endif_seen_else => {
+                                try pp.err(directive, .else_after_else);
+                                skipToNl(&tokenizer);
+                            },
+                            else => unreachable,
+                        }
+                    },
+                    .keyword_endif => {
+                        try pp.expectNl(&tokenizer);
+                        if (if_level == 0) {
+                            guard_name = null;
+                            try pp.err(directive, .endif_without_if);
+                            continue;
+                        } else if (if_level == 1) {
+                            const saved_tokenizer = tokenizer;
+                            defer tokenizer = saved_tokenizer;
+
+                            var next = tokenizer.nextNoWS();
+                            while (next.id == .nl) : (next = tokenizer.nextNoWS()) {}
+                            if (next.id != .eof) guard_name = null;
+                        }
+                        if_level -= 1;
+                    },
+                    .keyword_define => try pp.define(&tokenizer),
+                    .keyword_undef => {
+                        const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
+
+                        _ = pp.defines.remove(macro_name);
+                        try pp.expectNl(&tokenizer);
+                    },
+                    .keyword_include => try pp.include(&tokenizer, .first),
+                    .keyword_include_next => {
+                        try pp.comp.diag.add(.{
+                            .tag = .include_next,
+                            .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
+                        }, &.{});
+                        if (pp.include_depth == 0) {
+                            try pp.comp.diag.add(.{
+                                .tag = .include_next_outside_header,
+                                .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
+                            }, &.{});
+                            try pp.include(&tokenizer, .first);
+                        } else {
+                            try pp.include(&tokenizer, .next);
+                        }
+                    },
+                    .keyword_embed => try pp.embed(&tokenizer),
+                    .keyword_pragma => try pp.pragma(&tokenizer, directive, null, &.{}),
+                    .keyword_line => {
+                        // #line number "file"
+                        const digits = tokenizer.nextNoWS();
+                        if (digits.id != .pp_num) try pp.err(digits, .line_simple_digit);
+                        // TODO: validate that the pp_num token is solely digits
+
+                        if (digits.id == .eof or digits.id == .nl) continue;
+                        const name = tokenizer.nextNoWS();
+                        if (name.id == .eof or name.id == .nl) continue;
+                        if (name.id != .string_literal) try pp.err(name, .line_invalid_filename);
+                        try pp.expectNl(&tokenizer);
+                    },
+                    .pp_num => {
+                        // # number "file" flags
+                        // TODO: validate that the pp_num token is solely digits
+                        // if not, emit `GNU line marker directive requires a simple digit sequence`
+                        const name = tokenizer.nextNoWS();
+                        if (name.id == .eof or name.id == .nl) continue;
+                        if (name.id != .string_literal) try pp.err(name, .line_invalid_filename);
+
+                        const flag_1 = tokenizer.nextNoWS();
+                        if (flag_1.id == .eof or flag_1.id == .nl) continue;
+                        const flag_2 = tokenizer.nextNoWS();
+                        if (flag_2.id == .eof or flag_2.id == .nl) continue;
+                        const flag_3 = tokenizer.nextNoWS();
+                        if (flag_3.id == .eof or flag_3.id == .nl) continue;
+                        const flag_4 = tokenizer.nextNoWS();
+                        if (flag_4.id == .eof or flag_4.id == .nl) continue;
+                        try pp.expectNl(&tokenizer);
+                    },
+                    .nl => {},
+                    .eof => {
+                        if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive);
+                        return tokFromRaw(directive);
+                    },
+                    else => {
+                        try pp.err(tok, .invalid_preprocessing_directive);
+                        skipToNl(&tokenizer);
+                    },
+                }
+            },
+            .whitespace => if (pp.preserve_whitespace) try pp.tokens.append(pp.gpa, tokFromRaw(tok)),
+            .nl => {
+                start_of_line = true;
+                if (pp.preserve_whitespace) try pp.tokens.append(pp.gpa, tokFromRaw(tok));
+            },
+            .eof => {
+                if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive);
+                // The following check needs to occur here and not at the top of the function
+                // because a pragma may change the level during preprocessing
+                if (source.buf.len > 0 and source.buf[source.buf.len - 1] != '\n') {
+                    try pp.err(tok, .newline_eof);
+                }
+                if (guard_name) |name| {
+                    if (try pp.include_guards.fetchPut(pp.gpa, source.id, name)) |prev| {
+                        assert(mem.eql(u8, name, prev.value));
+                    }
+                }
+                return tokFromRaw(tok);
+            },
+            else => {
+                if (tok.id.isMacroIdentifier() and pp.poisoned_identifiers.get(pp.tokSlice(tok)) != null) {
+                    try pp.err(tok, .poisoned_identifier);
+                }
+                // Add the token to the buffer doing any necessary expansions.
+                start_of_line = false;
+                try pp.expandMacro(&tokenizer, tok);
+            },
+        }
+    }
+}
+
+/// Get raw token source string.
+/// Returned slice is invalidated when comp.generated_buf is updated.
+pub fn tokSlice(pp: *Preprocessor, token: RawToken) []const u8 {
+    if (token.id.lexeme()) |some| return some;
+    const source = pp.comp.getSource(token.source);
+    return source.buf[token.start..token.end];
+}
+
+/// Convert a token from the Tokenizer into a token used by the parser.
+fn tokFromRaw(raw: RawToken) Token {
+    return .{
+        .id = raw.id,
+        .loc = .{
+            .id = raw.source,
+            .byte_offset = raw.start,
+            .line = raw.line,
+        },
+    };
+}
+
+fn err(pp: *Preprocessor, raw: RawToken, tag: Diagnostics.Tag) !void {
+    try pp.comp.diag.add(.{
+        .tag = tag,
+        .loc = .{
+            .id = raw.source,
+            .byte_offset = raw.start,
+            .line = raw.line,
+        },
+    }, &.{});
+}
+
+fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) Compilation.Error {
+    const source = pp.comp.getSource(raw.source);
+    const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start });
+    return pp.comp.diag.fatal(source.path, line_col.line, raw.line, line_col.col, fmt, args);
+}
+
+fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void {
+    const source = pp.comp.getSource(raw.source);
+    const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start });
+
+    const stderr = std.io.getStdErr().writer();
+    var buf_writer = std.io.bufferedWriter(stderr);
+    const writer = buf_writer.writer();
+    defer buf_writer.flush() catch {};
+    writer.print("{s}:{d}:{d}: ", .{ source.path, line_col.line_no, line_col.col }) catch return;
+    writer.print(fmt, args) catch return;
+    writer.writeByte('\n') catch return;
+    writer.writeAll(line_col.line) catch return;
+    writer.writeByte('\n') catch return;
+}
+
+/// Consume next token, error if it is not an identifier.
+fn expectMacroName(pp: *Preprocessor, tokenizer: *Tokenizer) Error!?[]const u8 {
+    const macro_name = tokenizer.nextNoWS();
+    if (!macro_name.id.isMacroIdentifier()) {
+        try pp.err(macro_name, .macro_name_missing);
+        skipToNl(tokenizer);
+        return null;
+    }
+    return pp.tokSlice(macro_name);
+}
+
+/// Skip until after a newline, error if extra tokens before it.
+fn expectNl(pp: *Preprocessor, tokenizer: *Tokenizer) Error!void {
+    var sent_err = false;
+    while (true) {
+        const tok = tokenizer.next();
+        if (tok.id == .nl or tok.id == .eof) return;
+        if (tok.id == .whitespace) continue;
+        if (!sent_err) {
+            sent_err = true;
+            try pp.err(tok, .extra_tokens_directive_end);
+        }
+    }
+}
+
+/// Consume all tokens until a newline and parse the result into a boolean.
+fn expr(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!bool {
+    const start = pp.tokens.len;
+    defer {
+        for (pp.top_expansion_buf.items) |tok| Token.free(tok.expansion_locs, pp.gpa);
+        pp.tokens.len = start;
+    }
+
+    pp.top_expansion_buf.items.len = 0;
+    const eof = while (true) {
+        var tok = tokenizer.next();
+        switch (tok.id) {
+            .nl, .eof => break tok,
+            .whitespace => if (pp.top_expansion_buf.items.len == 0) continue,
+            else => {},
+        }
+        try pp.top_expansion_buf.append(tokFromRaw(tok));
+    } else unreachable;
+    if (pp.top_expansion_buf.items.len != 0) {
+        pp.expansion_source_loc = pp.top_expansion_buf.items[0].loc;
+        try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, pp.top_expansion_buf.items.len, false, .expr);
+    }
+    for (pp.top_expansion_buf.items) |tok| {
+        if (tok.id == .macro_ws) continue;
+        if (!tok.id.validPreprocessorExprStart()) {
+            try pp.comp.diag.add(.{
+                .tag = .invalid_preproc_expr_start,
+                .loc = tok.loc,
+            }, tok.expansionSlice());
+            return false;
+        }
+        break;
+    } else {
+        try pp.err(eof, .expected_value_in_expr);
+        return false;
+    }
+
+    // validate the tokens in the expression
+    try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.top_expansion_buf.items.len);
+    var i: usize = 0;
+    const items = pp.top_expansion_buf.items;
+    while (i < items.len) : (i += 1) {
+        var tok = items[i];
+        switch (tok.id) {
+            .string_literal,
+            .string_literal_utf_16,
+            .string_literal_utf_8,
+            .string_literal_utf_32,
+            .string_literal_wide,
+            => {
+                try pp.comp.diag.add(.{
+                    .tag = .string_literal_in_pp_expr,
+                    .loc = tok.loc,
+                }, tok.expansionSlice());
+                return false;
+            },
+            .plus_plus,
+            .minus_minus,
+            .plus_equal,
+            .minus_equal,
+            .asterisk_equal,
+            .slash_equal,
+            .percent_equal,
+            .angle_bracket_angle_bracket_left_equal,
+            .angle_bracket_angle_bracket_right_equal,
+            .ampersand_equal,
+            .caret_equal,
+            .pipe_equal,
+            .l_bracket,
+            .r_bracket,
+            .l_brace,
+            .r_brace,
+            .ellipsis,
+            .semicolon,
+            .hash,
+            .hash_hash,
+            .equal,
+            .arrow,
+            .period,
+            => {
+                try pp.comp.diag.add(.{
+                    .tag = .invalid_preproc_operator,
+                    .loc = tok.loc,
+                }, tok.expansionSlice());
+                return false;
+            },
+            .macro_ws, .whitespace => continue,
+            .keyword_false => tok.id = .zero,
+            .keyword_true => tok.id = .one,
+            else => if (tok.id.isMacroIdentifier()) {
+                if (tok.id == .keyword_defined) {
+                    const tokens_consumed = try pp.handleKeywordDefined(&tok, items[i + 1 ..], eof);
+                    i += tokens_consumed;
+                } else {
+                    try pp.comp.diag.add(.{
+                        .tag = .undefined_macro,
+                        .loc = tok.loc,
+                        .extra = .{ .str = pp.expandedSlice(tok) },
+                    }, tok.expansionSlice());
+
+                    if (i + 1 < pp.top_expansion_buf.items.len and
+                        pp.top_expansion_buf.items[i + 1].id == .l_paren)
+                    {
+                        try pp.comp.diag.add(.{
+                            .tag = .fn_macro_undefined,
+                            .loc = tok.loc,
+                            .extra = .{ .str = pp.expandedSlice(tok) },
+                        }, tok.expansionSlice());
+                        return false;
+                    }
+
+                    tok.id = .zero; // undefined macro
+                }
+            },
+        }
+        pp.tokens.appendAssumeCapacity(tok);
+    }
+    try pp.tokens.append(pp.gpa, .{
+        .id = .eof,
+        .loc = tokFromRaw(eof).loc,
+    });
+
+    // Actually parse it.
+    var parser = Parser{
+        .pp = pp,
+        .comp = pp.comp,
+        .gpa = pp.gpa,
+        .tok_ids = pp.tokens.items(.id),
+        .tok_i = @intCast(start),
+        .arena = pp.arena.allocator(),
+        .in_macro = true,
+        .data = undefined,
+        .strings = undefined,
+        .retained_strings = undefined,
+        .value_map = undefined,
+        .labels = undefined,
+        .decl_buf = undefined,
+        .list_buf = undefined,
+        .param_buf = undefined,
+        .enum_buf = undefined,
+        .record_buf = undefined,
+        .attr_buf = undefined,
+        .field_attr_buf = undefined,
+        .string_ids = undefined,
+    };
+    return parser.macroExpr();
+}
+
+/// Turns macro_tok from .keyword_defined into .zero or .one depending on whether the argument is defined
+/// Returns the number of tokens consumed
+fn handleKeywordDefined(pp: *Preprocessor, macro_tok: *Token, tokens: []const Token, eof: RawToken) !usize {
+    std.debug.assert(macro_tok.id == .keyword_defined);
+    var it = TokenIterator.init(tokens);
+    const first = it.nextNoWS() orelse {
+        try pp.err(eof, .macro_name_missing);
+        return it.i;
+    };
+    switch (first.id) {
+        .l_paren => {},
+        else => {
+            if (!first.id.isMacroIdentifier()) {
+                try pp.comp.diag.add(.{
+                    .tag = .macro_name_must_be_identifier,
+                    .loc = first.loc,
+                    .extra = .{ .str = pp.expandedSlice(first) },
+                }, first.expansionSlice());
+            }
+            macro_tok.id = if (pp.defines.contains(pp.expandedSlice(first))) .one else .zero;
+            return it.i;
+        },
+    }
+    const second = it.nextNoWS() orelse {
+        try pp.err(eof, .macro_name_missing);
+        return it.i;
+    };
+    if (!second.id.isMacroIdentifier()) {
+        try pp.comp.diag.add(.{
+            .tag = .macro_name_must_be_identifier,
+            .loc = second.loc,
+        }, second.expansionSlice());
+        return it.i;
+    }
+    macro_tok.id = if (pp.defines.contains(pp.expandedSlice(second))) .one else .zero;
+
+    const last = it.nextNoWS();
+    if (last == null or last.?.id != .r_paren) {
+        const tok = last orelse tokFromRaw(eof);
+        try pp.comp.diag.add(.{
+            .tag = .closing_paren,
+            .loc = tok.loc,
+        }, tok.expansionSlice());
+        try pp.comp.diag.add(.{
+            .tag = .to_match_paren,
+            .loc = first.loc,
+        }, first.expansionSlice());
+    }
+
+    return it.i;
+}
+
+/// Skip until #else #elif #endif, return last directive token id.
+/// Also skips nested #if ... #endifs.
+fn skip(
+    pp: *Preprocessor,
+    tokenizer: *Tokenizer,
+    cont: enum { until_else, until_endif, until_endif_seen_else },
+) Error!void {
+    var ifs_seen: u32 = 0;
+    var line_start = true;
+    while (tokenizer.index < tokenizer.buf.len) {
+        if (line_start) {
+            const saved_tokenizer = tokenizer.*;
+            const hash = tokenizer.nextNoWS();
+            if (hash.id == .nl) continue;
+            line_start = false;
+            if (hash.id != .hash) continue;
+            const directive = tokenizer.nextNoWS();
+            switch (directive.id) {
+                .keyword_else => {
+                    if (ifs_seen != 0) continue;
+                    if (cont == .until_endif_seen_else) {
+                        try pp.err(directive, .else_after_else);
+                        continue;
+                    }
+                    tokenizer.* = saved_tokenizer;
+                    return;
+                },
+                .keyword_elif => {
+                    if (ifs_seen != 0 or cont == .until_endif) continue;
+                    if (cont == .until_endif_seen_else) {
+                        try pp.err(directive, .elif_after_else);
+                        continue;
+                    }
+                    tokenizer.* = saved_tokenizer;
+                    return;
+                },
+                .keyword_elifdef => {
+                    if (ifs_seen != 0 or cont == .until_endif) continue;
+                    if (cont == .until_endif_seen_else) {
+                        try pp.err(directive, .elifdef_after_else);
+                        continue;
+                    }
+                    tokenizer.* = saved_tokenizer;
+                    return;
+                },
+                .keyword_elifndef => {
+                    if (ifs_seen != 0 or cont == .until_endif) continue;
+                    if (cont == .until_endif_seen_else) {
+                        try pp.err(directive, .elifndef_after_else);
+                        continue;
+                    }
+                    tokenizer.* = saved_tokenizer;
+                    return;
+                },
+                .keyword_endif => {
+                    if (ifs_seen == 0) {
+                        tokenizer.* = saved_tokenizer;
+                        return;
+                    }
+                    ifs_seen -= 1;
+                },
+                .keyword_if, .keyword_ifdef, .keyword_ifndef => ifs_seen += 1,
+                else => {},
+            }
+        } else if (tokenizer.buf[tokenizer.index] == '\n') {
+            line_start = true;
+            tokenizer.index += 1;
+            tokenizer.line += 1;
+        } else {
+            line_start = false;
+            tokenizer.index += 1;
+        }
+    } else {
+        const eof = tokenizer.next();
+        return pp.err(eof, .unterminated_conditional_directive);
+    }
+}
+
+// Skip until newline, ignore other tokens.
+fn skipToNl(tokenizer: *Tokenizer) void {
+    while (true) {
+        const tok = tokenizer.next();
+        if (tok.id == .nl or tok.id == .eof) return;
+    }
+}
+
+const ExpandBuf = std.ArrayList(Token);
+fn removePlacemarkers(buf: *ExpandBuf) void {
+    var i: usize = buf.items.len -% 1;
+    while (i < buf.items.len) : (i -%= 1) {
+        if (buf.items[i].id == .placemarker) {
+            const placemarker = buf.orderedRemove(i);
+            Token.free(placemarker.expansion_locs, buf.allocator);
+        }
+    }
+}
+
+const MacroArguments = std.ArrayList([]const Token);
+fn deinitMacroArguments(allocator: Allocator, args: *const MacroArguments) void {
+    for (args.items) |item| {
+        for (item) |tok| Token.free(tok.expansion_locs, allocator);
+        allocator.free(item);
+    }
+    args.deinit();
+}
+
+fn expandObjMacro(pp: *Preprocessor, simple_macro: *const Macro) Error!ExpandBuf {
+    var buf = ExpandBuf.init(pp.gpa);
+    errdefer buf.deinit();
+    try buf.ensureTotalCapacity(simple_macro.tokens.len);
+
+    // Add all of the simple_macros tokens to the new buffer handling any concats.
+    var i: usize = 0;
+    while (i < simple_macro.tokens.len) : (i += 1) {
+        const raw = simple_macro.tokens[i];
+        const tok = tokFromRaw(raw);
+        switch (raw.id) {
+            .hash_hash => {
+                var rhs = tokFromRaw(simple_macro.tokens[i + 1]);
+                i += 1;
+                while (rhs.id == .whitespace) {
+                    rhs = tokFromRaw(simple_macro.tokens[i + 1]);
+                    i += 1;
+                }
+                try pp.pasteTokens(&buf, &.{rhs});
+            },
+            .whitespace => if (pp.preserve_whitespace) buf.appendAssumeCapacity(tok),
+            .macro_file => {
+                const start = pp.comp.generated_buf.items.len;
+                const source = pp.comp.getSource(pp.expansion_source_loc.id);
+                try pp.comp.generated_buf.writer().print("\"{s}\"\n", .{source.path});
+
+                buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .string_literal, tok));
+            },
+            .macro_line => {
+                const start = pp.comp.generated_buf.items.len;
+                const source = pp.comp.getSource(pp.expansion_source_loc.id);
+                try pp.comp.generated_buf.writer().print("{d}\n", .{source.physicalLine(pp.expansion_source_loc)});
+
+                buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok));
+            },
+            .macro_counter => {
+                defer pp.counter += 1;
+                const start = pp.comp.generated_buf.items.len;
+                try pp.comp.generated_buf.writer().print("{d}\n", .{pp.counter});
+
+                buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok));
+            },
+            else => buf.appendAssumeCapacity(tok),
+        }
+    }
+
+    return buf;
+}
+
+/// Join a possibly-parenthesized series of string literal tokens into a single string without
+/// leading or trailing quotes. The returned slice is invalidated if pp.char_buf changes.
+/// Returns error.ExpectedStringLiteral if parentheses are not balanced, a non-string-literal
+/// is encountered, or if no string literals are encountered
+/// TODO: destringize (replace all '\\' with a single `\` and all '\"' with a '"')
+fn pasteStringsUnsafe(pp: *Preprocessor, toks: []const Token) ![]const u8 {
+    const char_top = pp.char_buf.items.len;
+    defer pp.char_buf.items.len = char_top;
+    var unwrapped = toks;
+    if (toks.len >= 2 and toks[0].id == .l_paren and toks[toks.len - 1].id == .r_paren) {
+        unwrapped = toks[1 .. toks.len - 1];
+    }
+    if (unwrapped.len == 0) return error.ExpectedStringLiteral;
+
+    for (unwrapped) |tok| {
+        if (tok.id == .macro_ws) continue;
+        if (tok.id != .string_literal) return error.ExpectedStringLiteral;
+        const str = pp.expandedSlice(tok);
+        try pp.char_buf.appendSlice(str[1 .. str.len - 1]);
+    }
+    return pp.char_buf.items[char_top..];
+}
+
+/// Handle the _Pragma operator (implemented as a builtin macro)
+fn pragmaOperator(pp: *Preprocessor, arg_tok: Token, operator_loc: Source.Location) !void {
+    const arg_slice = pp.expandedSlice(arg_tok);
+    const content = arg_slice[1 .. arg_slice.len - 1];
+    const directive = "#pragma ";
+
+    pp.char_buf.clearRetainingCapacity();
+    const total_len = directive.len + content.len + 1; // destringify can never grow the string, + 1 for newline
+    try pp.char_buf.ensureUnusedCapacity(total_len);
+    pp.char_buf.appendSliceAssumeCapacity(directive);
+    pp.destringify(content);
+    pp.char_buf.appendAssumeCapacity('\n');
+
+    const start = pp.comp.generated_buf.items.len;
+    try pp.comp.generated_buf.appendSlice(pp.char_buf.items);
+    var tmp_tokenizer = Tokenizer{
+        .buf = pp.comp.generated_buf.items,
+        .comp = pp.comp,
+        .index = @intCast(start),
+        .source = .generated,
+        .line = pp.generated_line,
+    };
+    pp.generated_line += 1;
+    const hash_tok = tmp_tokenizer.next();
+    assert(hash_tok.id == .hash);
+    const pragma_tok = tmp_tokenizer.next();
+    assert(pragma_tok.id == .keyword_pragma);
+    try pp.pragma(&tmp_tokenizer, pragma_tok, operator_loc, arg_tok.expansionSlice());
+}
+
+/// Inverts the output of the preprocessor stringify (#) operation
+/// (except all whitespace is condensed to a single space)
+/// writes output to pp.char_buf; assumes capacity is sufficient
+/// backslash backslash -> backslash
+/// backslash doublequote -> doublequote
+/// All other characters remain the same
+fn destringify(pp: *Preprocessor, str: []const u8) void {
+    var state: enum { start, backslash_seen } = .start;
+    for (str) |c| {
+        switch (c) {
+            '\\' => {
+                if (state == .backslash_seen) pp.char_buf.appendAssumeCapacity(c);
+                state = if (state == .start) .backslash_seen else .start;
+            },
+            else => {
+                if (state == .backslash_seen and c != '"') pp.char_buf.appendAssumeCapacity('\\');
+                pp.char_buf.appendAssumeCapacity(c);
+                state = .start;
+            },
+        }
+    }
+}
+
+/// Stringify `tokens` into pp.char_buf.
+/// See https://gcc.gnu.org/onlinedocs/gcc-11.2.0/cpp/Stringizing.html#Stringizing
+fn stringify(pp: *Preprocessor, tokens: []const Token) !void {
+    try pp.char_buf.append('"');
+    var ws_state: enum { start, need, not_needed } = .start;
+    for (tokens) |tok| {
+        if (tok.id == .macro_ws) {
+            if (ws_state == .start) continue;
+            ws_state = .need;
+            continue;
+        }
+        if (ws_state == .need) try pp.char_buf.append(' ');
+        ws_state = .not_needed;
+
+        // backslashes not inside strings are not escaped
+        const is_str = switch (tok.id) {
+            .string_literal,
+            .string_literal_utf_16,
+            .string_literal_utf_8,
+            .string_literal_utf_32,
+            .string_literal_wide,
+            .char_literal,
+            .char_literal_utf_16,
+            .char_literal_utf_32,
+            .char_literal_wide,
+            => true,
+            else => false,
+        };
+
+        for (pp.expandedSlice(tok)) |c| {
+            if (c == '"')
+                try pp.char_buf.appendSlice("\\\"")
+            else if (c == '\\' and is_str)
+                try pp.char_buf.appendSlice("\\\\")
+            else
+                try pp.char_buf.append(c);
+        }
+    }
+    if (pp.char_buf.items[pp.char_buf.items.len - 1] == '\\') {
+        const tok = tokens[tokens.len - 1];
+        try pp.comp.diag.add(.{
+            .tag = .invalid_pp_stringify_escape,
+            .loc = tok.loc,
+        }, tok.expansionSlice());
+        pp.char_buf.items.len -= 1;
+    }
+    try pp.char_buf.appendSlice("\"\n");
+}
+
+fn reconstructIncludeString(pp: *Preprocessor, param_toks: []const Token) !?[]const u8 {
+    const char_top = pp.char_buf.items.len;
+    defer pp.char_buf.items.len = char_top;
+
+    // Trim leading/trailing whitespace
+    var begin: usize = 0;
+    var end: usize = param_toks.len;
+    while (begin < end and param_toks[begin].id == .macro_ws) : (begin += 1) {}
+    while (end > begin and param_toks[end - 1].id == .macro_ws) : (end -= 1) {}
+    const params = param_toks[begin..end];
+
+    if (params.len == 0) {
+        try pp.comp.diag.add(.{
+            .tag = .expected_filename,
+            .loc = param_toks[0].loc,
+        }, param_toks[0].expansionSlice());
+        return null;
+    }
+    // no string pasting
+    if (params[0].id == .string_literal and params.len > 1) {
+        try pp.comp.diag.add(.{
+            .tag = .closing_paren,
+            .loc = params[1].loc,
+        }, params[1].expansionSlice());
+        return null;
+    }
+
+    for (params) |tok| {
+        const str = pp.expandedSliceExtra(tok, .preserve_macro_ws);
+        try pp.char_buf.appendSlice(str);
+    }
+
+    const include_str = pp.char_buf.items[char_top..];
+    if (include_str.len < 3) {
+        try pp.comp.diag.add(.{
+            .tag = .empty_filename,
+            .loc = params[0].loc,
+        }, params[0].expansionSlice());
+        return null;
+    }
+
+    switch (include_str[0]) {
+        '<' => {
+            if (include_str[include_str.len - 1] != '>') {
+                // Ugly hack to find out where the '>' should go, since we don't have the closing ')' location
+                const start = params[0].loc;
+                try pp.comp.diag.add(.{
+                    .tag = .header_str_closing,
+                    .loc = .{ .id = start.id, .byte_offset = start.byte_offset + @as(u32, @intCast(include_str.len)) + 1, .line = start.line },
+                }, params[0].expansionSlice());
+                try pp.comp.diag.add(.{
+                    .tag = .header_str_match,
+                    .loc = params[0].loc,
+                }, params[0].expansionSlice());
+                return null;
+            }
+            return include_str;
+        },
+        '"' => return include_str,
+        else => {
+            try pp.comp.diag.add(.{
+                .tag = .expected_filename,
+                .loc = params[0].loc,
+            }, params[0].expansionSlice());
+            return null;
+        },
+    }
+}
+
+fn handleBuiltinMacro(pp: *Preprocessor, builtin: RawToken.Id, param_toks: []const Token, src_loc: Source.Location) Error!bool {
+    switch (builtin) {
+        .macro_param_has_attribute,
+        .macro_param_has_feature,
+        .macro_param_has_extension,
+        .macro_param_has_builtin,
+        => {
+            var invalid: ?Token = null;
+            var identifier: ?Token = null;
+            for (param_toks) |tok| {
+                if (tok.id == .macro_ws) continue;
+                if (!tok.id.isMacroIdentifier()) {
+                    invalid = tok;
+                    break;
+                }
+                if (identifier) |_| invalid = tok else identifier = tok;
+            }
+            if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc };
+            if (invalid) |some| {
+                try pp.comp.diag.add(
+                    .{ .tag = .feature_check_requires_identifier, .loc = some.loc },
+                    some.expansionSlice(),
+                );
+                return false;
+            }
+
+            const ident_str = pp.expandedSlice(identifier.?);
+            return switch (builtin) {
+                .macro_param_has_attribute => Attribute.fromString(.gnu, null, ident_str) != null,
+                .macro_param_has_feature => features.hasFeature(pp.comp, ident_str),
+                .macro_param_has_extension => features.hasExtension(pp.comp, ident_str),
+                .macro_param_has_builtin => pp.comp.hasBuiltin(ident_str),
+                else => unreachable,
+            };
+        },
+        .macro_param_has_warning => {
+            const actual_param = pp.pasteStringsUnsafe(param_toks) catch |er| switch (er) {
+                error.ExpectedStringLiteral => {
+                    try pp.comp.diag.add(.{
+                        .tag = .expected_str_literal_in,
+                        .loc = param_toks[0].loc,
+                        .extra = .{ .str = "__has_warning" },
+                    }, param_toks[0].expansionSlice());
+                    return false;
+                },
+                else => |e| return e,
+            };
+            if (!mem.startsWith(u8, actual_param, "-W")) {
+                try pp.comp.diag.add(.{
+                    .tag = .malformed_warning_check,
+                    .loc = param_toks[0].loc,
+                    .extra = .{ .str = "__has_warning" },
+                }, param_toks[0].expansionSlice());
+                return false;
+            }
+            const warning_name = actual_param[2..];
+            return Diagnostics.warningExists(warning_name);
+        },
+        .macro_param_is_identifier => {
+            var invalid: ?Token = null;
+            var identifier: ?Token = null;
+            for (param_toks) |tok| switch (tok.id) {
+                .macro_ws => continue,
+                else => {
+                    if (identifier) |_| invalid = tok else identifier = tok;
+                },
+            };
+            if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc };
+            if (invalid) |some| {
+                try pp.comp.diag.add(.{
+                    .tag = .missing_tok_builtin,
+                    .loc = some.loc,
+                    .extra = .{ .tok_id_expected = .r_paren },
+                }, some.expansionSlice());
+                return false;
+            }
+
+            const id = identifier.?.id;
+            return id == .identifier or id == .extended_identifier;
+        },
+        .macro_param_has_include, .macro_param_has_include_next => {
+            const include_str = (try pp.reconstructIncludeString(param_toks)) orelse return false;
+            const include_type: Compilation.IncludeType = switch (include_str[0]) {
+                '"' => .quotes,
+                '<' => .angle_brackets,
+                else => unreachable,
+            };
+            const filename = include_str[1 .. include_str.len - 1];
+            if (builtin == .macro_param_has_include or pp.include_depth == 0) {
+                if (builtin == .macro_param_has_include_next) {
+                    try pp.comp.diag.add(.{
+                        .tag = .include_next_outside_header,
+                        .loc = src_loc,
+                    }, &.{});
+                }
+                return pp.comp.hasInclude(filename, src_loc.id, include_type, .first);
+            }
+            return pp.comp.hasInclude(filename, src_loc.id, include_type, .next);
+        },
+        else => unreachable,
+    }
+}
+
+fn expandFuncMacro(
+    pp: *Preprocessor,
+    loc: Source.Location,
+    func_macro: *const Macro,
+    args: *const MacroArguments,
+    expanded_args: *const MacroArguments,
+) MacroError!ExpandBuf {
+    var buf = ExpandBuf.init(pp.gpa);
+    try buf.ensureTotalCapacity(func_macro.tokens.len);
+    errdefer buf.deinit();
+
+    var expanded_variable_arguments = ExpandBuf.init(pp.gpa);
+    defer expanded_variable_arguments.deinit();
+    var variable_arguments = ExpandBuf.init(pp.gpa);
+    defer variable_arguments.deinit();
+
+    if (func_macro.var_args) {
+        var i: usize = func_macro.params.len;
+        while (i < expanded_args.items.len) : (i += 1) {
+            try variable_arguments.appendSlice(args.items[i]);
+            try expanded_variable_arguments.appendSlice(expanded_args.items[i]);
+            if (i != expanded_args.items.len - 1) {
+                const comma = Token{ .id = .comma, .loc = .{ .id = .generated } };
+                try variable_arguments.append(comma);
+                try expanded_variable_arguments.append(comma);
+            }
+        }
+    }
+
+    // token concatenation and expansion phase
+    var tok_i: usize = 0;
+    while (tok_i < func_macro.tokens.len) : (tok_i += 1) {
+        const raw = func_macro.tokens[tok_i];
+        switch (raw.id) {
+            .hash_hash => while (tok_i + 1 < func_macro.tokens.len) {
+                const raw_next = func_macro.tokens[tok_i + 1];
+                tok_i += 1;
+
+                const next = switch (raw_next.id) {
+                    .macro_ws => continue,
+                    .hash_hash => continue,
+                    .macro_param, .macro_param_no_expand => if (args.items[raw_next.end].len > 0)
+                        args.items[raw_next.end]
+                    else
+                        &[1]Token{tokFromRaw(.{ .id = .placemarker, .source = .generated })},
+                    .keyword_va_args => variable_arguments.items,
+                    else => &[1]Token{tokFromRaw(raw_next)},
+                };
+
+                try pp.pasteTokens(&buf, next);
+                if (next.len != 0) break;
+            },
+            .macro_param_no_expand => {
+                const slice = if (args.items[raw.end].len > 0)
+                    args.items[raw.end]
+                else
+                    &[1]Token{tokFromRaw(.{ .id = .placemarker, .source = .generated })};
+                const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
+                try bufCopyTokens(&buf, slice, &.{raw_loc});
+            },
+            .macro_param => {
+                const arg = expanded_args.items[raw.end];
+                const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
+                try bufCopyTokens(&buf, arg, &.{raw_loc});
+            },
+            .keyword_va_args => {
+                const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
+                try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc});
+            },
+            .stringify_param, .stringify_va_args => {
+                const arg = if (raw.id == .stringify_va_args)
+                    variable_arguments.items
+                else
+                    args.items[raw.end];
+
+                pp.char_buf.clearRetainingCapacity();
+                try pp.stringify(arg);
+
+                const start = pp.comp.generated_buf.items.len;
+                try pp.comp.generated_buf.appendSlice(pp.char_buf.items);
+
+                try buf.append(try pp.makeGeneratedToken(start, .string_literal, tokFromRaw(raw)));
+            },
+            .macro_param_has_attribute,
+            .macro_param_has_warning,
+            .macro_param_has_feature,
+            .macro_param_has_extension,
+            .macro_param_has_builtin,
+            .macro_param_has_include,
+            .macro_param_has_include_next,
+            .macro_param_is_identifier,
+            => {
+                const arg = expanded_args.items[0];
+                const result = if (arg.len == 0) blk: {
+                    const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } };
+                    try pp.comp.diag.add(.{ .tag = .expected_arguments, .loc = loc, .extra = extra }, &.{});
+                    break :blk false;
+                } else try pp.handleBuiltinMacro(raw.id, arg, loc);
+                const start = pp.comp.generated_buf.items.len;
+                try pp.comp.generated_buf.writer().print("{}\n", .{@intFromBool(result)});
+                try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
+            },
+            .macro_param_pragma_operator => {
+                const param_toks = expanded_args.items[0];
+                // Clang and GCC require exactly one token (so, no parentheses or string pasting)
+                // even though their error messages indicate otherwise. Ours is slightly more
+                // descriptive.
+                var invalid: ?Token = null;
+                var string: ?Token = null;
+                for (param_toks) |tok| switch (tok.id) {
+                    .string_literal => {
+                        if (string) |_| invalid = tok else string = tok;
+                    },
+                    .macro_ws => continue,
+                    else => {
+                        invalid = tok;
+                        break;
+                    },
+                };
+                if (string == null and invalid == null) invalid = .{ .loc = loc, .id = .eof };
+                if (invalid) |some| try pp.comp.diag.add(
+                    .{ .tag = .pragma_operator_string_literal, .loc = some.loc },
+                    some.expansionSlice(),
+                ) else try pp.pragmaOperator(string.?, loc);
+            },
+            .comma => {
+                if (tok_i + 2 < func_macro.tokens.len and func_macro.tokens[tok_i + 1].id == .hash_hash) {
+                    const hash_hash = func_macro.tokens[tok_i + 1];
+                    var maybe_va_args = func_macro.tokens[tok_i + 2];
+                    var consumed: usize = 2;
+                    if (maybe_va_args.id == .macro_ws and tok_i + 3 < func_macro.tokens.len) {
+                        consumed = 3;
+                        maybe_va_args = func_macro.tokens[tok_i + 3];
+                    }
+                    if (maybe_va_args.id == .keyword_va_args) {
+                        // GNU extension: `, ##__VA_ARGS__` deletes the comma if __VA_ARGS__ is empty
+                        tok_i += consumed;
+                        if (func_macro.params.len == expanded_args.items.len) {
+                            // Empty __VA_ARGS__, drop the comma
+                            try pp.err(hash_hash, .comma_deletion_va_args);
+                        } else if (func_macro.params.len == 0 and expanded_args.items.len == 1 and expanded_args.items[0].len == 0) {
+                            // Ambiguous whether this is "empty __VA_ARGS__" or "__VA_ARGS__ omitted"
+                            if (pp.comp.langopts.standard.isGNU()) {
+                                // GNU standard, drop the comma
+                                try pp.err(hash_hash, .comma_deletion_va_args);
+                            } else {
+                                // C standard, retain the comma
+                                try buf.append(tokFromRaw(raw));
+                            }
+                        } else {
+                            try buf.append(tokFromRaw(raw));
+                            if (expanded_variable_arguments.items.len > 0 or variable_arguments.items.len == func_macro.params.len) {
+                                try pp.err(hash_hash, .comma_deletion_va_args);
+                            }
+                            const raw_loc = Source.Location{
+                                .id = maybe_va_args.source,
+                                .byte_offset = maybe_va_args.start,
+                                .line = maybe_va_args.line,
+                            };
+                            try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc});
+                        }
+                        continue;
+                    }
+                }
+                // Regular comma, no token pasting with __VA_ARGS__
+                try buf.append(tokFromRaw(raw));
+            },
+            else => try buf.append(tokFromRaw(raw)),
+        }
+    }
+    removePlacemarkers(&buf);
+
+    return buf;
+}
+
+fn shouldExpand(tok: Token, macro: *Macro) bool {
+    // macro.loc.line contains the macros end index
+    if (tok.loc.id == macro.loc.id and
+        tok.loc.byte_offset >= macro.loc.byte_offset and
+        tok.loc.byte_offset <= macro.loc.line)
+        return false;
+    for (tok.expansionSlice()) |loc| {
+        if (loc.id == macro.loc.id and
+            loc.byte_offset >= macro.loc.byte_offset and
+            loc.byte_offset <= macro.loc.line)
+            return false;
+    }
+    if (tok.flags.expansion_disabled) return false;
+
+    return true;
+}
+
+fn bufCopyTokens(buf: *ExpandBuf, tokens: []const Token, src: []const Source.Location) !void {
+    try buf.ensureUnusedCapacity(tokens.len);
+    for (tokens) |tok| {
+        var copy = try tok.dupe(buf.allocator);
+        errdefer Token.free(copy.expansion_locs, buf.allocator);
+        try copy.addExpansionLocation(buf.allocator, src);
+        buf.appendAssumeCapacity(copy);
+    }
+}
+
+fn nextBufToken(
+    pp: *Preprocessor,
+    tokenizer: *Tokenizer,
+    buf: *ExpandBuf,
+    start_idx: *usize,
+    end_idx: *usize,
+    extend_buf: bool,
+) Error!Token {
+    start_idx.* += 1;
+    if (start_idx.* == buf.items.len and start_idx.* >= end_idx.*) {
+        if (extend_buf) {
+            const raw_tok = tokenizer.next();
+            if (raw_tok.id.isMacroIdentifier() and
+                pp.poisoned_identifiers.get(pp.tokSlice(raw_tok)) != null)
+                try pp.err(raw_tok, .poisoned_identifier);
+
+            if (raw_tok.id == .nl) pp.add_expansion_nl += 1;
+
+            const new_tok = tokFromRaw(raw_tok);
+            end_idx.* += 1;
+            try buf.append(new_tok);
+            return new_tok;
+        } else {
+            return Token{ .id = .eof, .loc = .{ .id = .generated } };
+        }
+    } else {
+        return buf.items[start_idx.*];
+    }
+}
+
+fn collectMacroFuncArguments(
+    pp: *Preprocessor,
+    tokenizer: *Tokenizer,
+    buf: *ExpandBuf,
+    start_idx: *usize,
+    end_idx: *usize,
+    extend_buf: bool,
+    is_builtin: bool,
+) !MacroArguments {
+    const name_tok = buf.items[start_idx.*];
+    const saved_tokenizer = tokenizer.*;
+    const old_end = end_idx.*;
+
+    while (true) {
+        const tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf);
+        switch (tok.id) {
+            .nl, .whitespace, .macro_ws => {},
+            .l_paren => break,
+            else => {
+                if (is_builtin) {
+                    try pp.comp.diag.add(.{
+                        .tag = .missing_lparen_after_builtin,
+                        .loc = name_tok.loc,
+                        .extra = .{ .str = pp.expandedSlice(name_tok) },
+                    }, tok.expansionSlice());
+                }
+                // Not a macro function call, go over normal identifier, rewind
+                tokenizer.* = saved_tokenizer;
+                end_idx.* = old_end;
+                return error.MissingLParen;
+            },
+        }
+    }
+
+    // collect the arguments.
+    var parens: u32 = 0;
+    var args = MacroArguments.init(pp.gpa);
+    errdefer deinitMacroArguments(pp.gpa, &args);
+    var curArgument = std.ArrayList(Token).init(pp.gpa);
+    defer curArgument.deinit();
+    while (true) {
+        var tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf);
+        tok.flags.is_macro_arg = true;
+        switch (tok.id) {
+            .comma => {
+                if (parens == 0) {
+                    const owned = try curArgument.toOwnedSlice();
+                    errdefer pp.gpa.free(owned);
+                    try args.append(owned);
+                } else {
+                    const duped = try tok.dupe(pp.gpa);
+                    errdefer Token.free(duped.expansion_locs, pp.gpa);
+                    try curArgument.append(duped);
+                }
+            },
+            .l_paren => {
+                const duped = try tok.dupe(pp.gpa);
+                errdefer Token.free(duped.expansion_locs, pp.gpa);
+                try curArgument.append(duped);
+                parens += 1;
+            },
+            .r_paren => {
+                if (parens == 0) {
+                    const owned = try curArgument.toOwnedSlice();
+                    errdefer pp.gpa.free(owned);
+                    try args.append(owned);
+                    break;
+                } else {
+                    const duped = try tok.dupe(pp.gpa);
+                    errdefer Token.free(duped.expansion_locs, pp.gpa);
+                    try curArgument.append(duped);
+                    parens -= 1;
+                }
+            },
+            .eof => {
+                {
+                    const owned = try curArgument.toOwnedSlice();
+                    errdefer pp.gpa.free(owned);
+                    try args.append(owned);
+                }
+                tokenizer.* = saved_tokenizer;
+                try pp.comp.diag.add(
+                    .{ .tag = .unterminated_macro_arg_list, .loc = name_tok.loc },
+                    name_tok.expansionSlice(),
+                );
+                return error.Unterminated;
+            },
+            .nl, .whitespace => {
+                try curArgument.append(.{ .id = .macro_ws, .loc = tok.loc });
+            },
+            else => {
+                const duped = try tok.dupe(pp.gpa);
+                errdefer Token.free(duped.expansion_locs, pp.gpa);
+                try curArgument.append(duped);
+            },
+        }
+    }
+
+    return args;
+}
+
+fn removeExpandedTokens(pp: *Preprocessor, buf: *ExpandBuf, start: usize, len: usize, moving_end_idx: *usize) !void {
+    for (buf.items[start .. start + len]) |tok| Token.free(tok.expansion_locs, pp.gpa);
+    try buf.replaceRange(start, len, &.{});
+    moving_end_idx.* -|= len;
+}
+
+/// The behavior of `defined` depends on whether we are in a preprocessor
+/// expression context (#if or #elif) or not.
+/// In a non-expression context it's just an identifier. Within a preprocessor
+/// expression it is a unary operator or one-argument function.
+const EvalContext = enum {
+    expr,
+    non_expr,
+};
+
+/// Helper for safely iterating over a slice of tokens while skipping whitespace
+const TokenIterator = struct {
+    toks: []const Token,
+    i: usize,
+
+    fn init(toks: []const Token) TokenIterator {
+        return .{ .toks = toks, .i = 0 };
+    }
+
+    fn nextNoWS(self: *TokenIterator) ?Token {
+        while (self.i < self.toks.len) : (self.i += 1) {
+            const tok = self.toks[self.i];
+            if (tok.id == .whitespace or tok.id == .macro_ws) continue;
+
+            self.i += 1;
+            return tok;
+        }
+        return null;
+    }
+};
+
+fn expandMacroExhaustive(
+    pp: *Preprocessor,
+    tokenizer: *Tokenizer,
+    buf: *ExpandBuf,
+    start_idx: usize,
+    end_idx: usize,
+    extend_buf: bool,
+    eval_ctx: EvalContext,
+) MacroError!void {
+    var moving_end_idx = end_idx;
+    var advance_index: usize = 0;
+    // rescan loop
+    var do_rescan = true;
+    while (do_rescan) {
+        do_rescan = false;
+        // expansion loop
+        var idx: usize = start_idx + advance_index;
+        while (idx < moving_end_idx) {
+            const macro_tok = buf.items[idx];
+            if (macro_tok.id == .keyword_defined and eval_ctx == .expr) {
+                idx += 1;
+                var it = TokenIterator.init(buf.items[idx..moving_end_idx]);
+                if (it.nextNoWS()) |tok| {
+                    switch (tok.id) {
+                        .l_paren => {
+                            _ = it.nextNoWS(); // eat (what should be) identifier
+                            _ = it.nextNoWS(); // eat (what should be) r paren
+                        },
+                        .identifier, .extended_identifier => {},
+                        else => {},
+                    }
+                }
+                idx += it.i;
+                continue;
+            }
+            const macro_entry = pp.defines.getPtr(pp.expandedSlice(macro_tok));
+            if (macro_entry == null or !shouldExpand(buf.items[idx], macro_entry.?)) {
+                idx += 1;
+                continue;
+            }
+            if (macro_entry) |macro| macro_handler: {
+                if (macro.is_func) {
+                    var macro_scan_idx = idx;
+                    // to be saved in case this doesn't turn out to be a call
+                    const args = pp.collectMacroFuncArguments(
+                        tokenizer,
+                        buf,
+                        &macro_scan_idx,
+                        &moving_end_idx,
+                        extend_buf,
+                        macro.is_builtin,
+                    ) catch |er| switch (er) {
+                        error.MissingLParen => {
+                            if (!buf.items[idx].flags.is_macro_arg) buf.items[idx].flags.expansion_disabled = true;
+                            idx += 1;
+                            break :macro_handler;
+                        },
+                        error.Unterminated => {
+                            if (pp.comp.langopts.emulate == .gcc) idx += 1;
+                            try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx, &moving_end_idx);
+                            break :macro_handler;
+                        },
+                        else => |e| return e,
+                    };
+                    defer {
+                        for (args.items) |item| {
+                            pp.gpa.free(item);
+                        }
+                        args.deinit();
+                    }
+
+                    var args_count: u32 = @intCast(args.items.len);
+                    // if the macro has zero arguments g() args_count is still 1
+                    // an empty token list g() and a whitespace-only token list g(    )
+                    // counts as zero arguments for the purposes of argument-count validation
+                    if (args_count == 1 and macro.params.len == 0) {
+                        for (args.items[0]) |tok| {
+                            if (tok.id != .macro_ws) break;
+                        } else {
+                            args_count = 0;
+                        }
+                    }
+
+                    // Validate argument count.
+                    const extra = Diagnostics.Message.Extra{
+                        .arguments = .{ .expected = @intCast(macro.params.len), .actual = args_count },
+                    };
+                    if (macro.var_args and args_count < macro.params.len) {
+                        try pp.comp.diag.add(
+                            .{ .tag = .expected_at_least_arguments, .loc = buf.items[idx].loc, .extra = extra },
+                            buf.items[idx].expansionSlice(),
+                        );
+                        idx += 1;
+                        try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx);
+                        continue;
+                    }
+                    if (!macro.var_args and args_count != macro.params.len) {
+                        try pp.comp.diag.add(
+                            .{ .tag = .expected_arguments, .loc = buf.items[idx].loc, .extra = extra },
+                            buf.items[idx].expansionSlice(),
+                        );
+                        idx += 1;
+                        try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx);
+                        continue;
+                    }
+                    var expanded_args = MacroArguments.init(pp.gpa);
+                    defer deinitMacroArguments(pp.gpa, &expanded_args);
+                    try expanded_args.ensureTotalCapacity(args.items.len);
+                    for (args.items) |arg| {
+                        var expand_buf = ExpandBuf.init(pp.gpa);
+                        errdefer expand_buf.deinit();
+                        try expand_buf.appendSlice(arg);
+
+                        try pp.expandMacroExhaustive(tokenizer, &expand_buf, 0, expand_buf.items.len, false, eval_ctx);
+
+                        expanded_args.appendAssumeCapacity(try expand_buf.toOwnedSlice());
+                    }
+
+                    var res = try pp.expandFuncMacro(macro_tok.loc, macro, &args, &expanded_args);
+                    defer res.deinit();
+                    const tokens_added = res.items.len;
+
+                    const macro_expansion_locs = macro_tok.expansionSlice();
+                    for (res.items) |*tok| {
+                        try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc});
+                        try tok.addExpansionLocation(pp.gpa, macro_expansion_locs);
+                    }
+
+                    const tokens_removed = macro_scan_idx - idx + 1;
+                    for (buf.items[idx .. idx + tokens_removed]) |tok| Token.free(tok.expansion_locs, pp.gpa);
+                    try buf.replaceRange(idx, tokens_removed, res.items);
+
+                    moving_end_idx += tokens_added;
+                    // Overflow here means that we encountered an unterminated argument list
+                    // while expanding the body of this macro.
+                    moving_end_idx -|= tokens_removed;
+                    idx += tokens_added;
+                    do_rescan = true;
+                } else {
+                    const res = try pp.expandObjMacro(macro);
+                    defer res.deinit();
+
+                    const macro_expansion_locs = macro_tok.expansionSlice();
+                    var increment_idx_by = res.items.len;
+                    for (res.items, 0..) |*tok, i| {
+                        tok.flags.is_macro_arg = macro_tok.flags.is_macro_arg;
+                        try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc});
+                        try tok.addExpansionLocation(pp.gpa, macro_expansion_locs);
+                        if (tok.id == .keyword_defined and eval_ctx == .expr) {
+                            try pp.comp.diag.add(.{
+                                .tag = .expansion_to_defined,
+                                .loc = tok.loc,
+                            }, tok.expansionSlice());
+                        }
+
+                        if (i < increment_idx_by and (tok.id == .keyword_defined or pp.defines.contains(pp.expandedSlice(tok.*)))) {
+                            increment_idx_by = i;
+                        }
+                    }
+
+                    Token.free(buf.items[idx].expansion_locs, pp.gpa);
+                    try buf.replaceRange(idx, 1, res.items);
+                    idx += increment_idx_by;
+                    moving_end_idx = moving_end_idx + res.items.len - 1;
+                    do_rescan = true;
+                }
+            }
+            if (idx - start_idx == advance_index + 1 and !do_rescan) {
+                advance_index += 1;
+            }
+        } // end of replacement phase
+    }
+    // end of scanning phase
+
+    // trim excess buffer
+    for (buf.items[moving_end_idx..]) |item| {
+        Token.free(item.expansion_locs, pp.gpa);
+    }
+    buf.items.len = moving_end_idx;
+}
+
+/// Try to expand a macro after a possible candidate has been read from the `tokenizer`
+/// into the `raw` token passed as argument
+fn expandMacro(pp: *Preprocessor, tokenizer: *Tokenizer, raw: RawToken) MacroError!void {
+    var source_tok = tokFromRaw(raw);
+    if (!raw.id.isMacroIdentifier()) {
+        source_tok.id.simplifyMacroKeyword();
+        return pp.tokens.append(pp.gpa, source_tok);
+    }
+    pp.top_expansion_buf.items.len = 0;
+    try pp.top_expansion_buf.append(source_tok);
+    pp.expansion_source_loc = source_tok.loc;
+
+    try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr);
+    try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.top_expansion_buf.items.len);
+    for (pp.top_expansion_buf.items) |*tok| {
+        if (tok.id == .macro_ws and !pp.preserve_whitespace) {
+            Token.free(tok.expansion_locs, pp.gpa);
+            continue;
+        }
+        tok.id.simplifyMacroKeywordExtra(true);
+        pp.tokens.appendAssumeCapacity(tok.*);
+    }
+    if (pp.preserve_whitespace) {
+        try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.add_expansion_nl);
+        while (pp.add_expansion_nl > 0) : (pp.add_expansion_nl -= 1) {
+            pp.tokens.appendAssumeCapacity(.{ .id = .nl, .loc = .{ .id = .generated } });
+        }
+    }
+}
+
+fn expandedSliceExtra(pp: *const Preprocessor, tok: Token, macro_ws_handling: enum { single_macro_ws, preserve_macro_ws }) []const u8 {
+    if (tok.id.lexeme()) |some| {
+        if (!tok.id.allowsDigraphs(pp.comp) and !(tok.id == .macro_ws and macro_ws_handling == .preserve_macro_ws)) return some;
+    }
+    var tmp_tokenizer = Tokenizer{
+        .buf = pp.comp.getSource(tok.loc.id).buf,
+        .comp = pp.comp,
+        .index = tok.loc.byte_offset,
+        .source = .generated,
+    };
+    if (tok.id == .macro_string) {
+        while (true) : (tmp_tokenizer.index += 1) {
+            if (tmp_tokenizer.buf[tmp_tokenizer.index] == '>') break;
+        }
+        return tmp_tokenizer.buf[tok.loc.byte_offset .. tmp_tokenizer.index + 1];
+    }
+    const res = tmp_tokenizer.next();
+    return tmp_tokenizer.buf[res.start..res.end];
+}
+
+/// Get expanded token source string.
+pub fn expandedSlice(pp: *Preprocessor, tok: Token) []const u8 {
+    return pp.expandedSliceExtra(tok, .single_macro_ws);
+}
+
+/// Concat two tokens and add the result to pp.generated
+fn pasteTokens(pp: *Preprocessor, lhs_toks: *ExpandBuf, rhs_toks: []const Token) Error!void {
+    const lhs = while (lhs_toks.popOrNull()) |lhs| {
+        if (lhs.id == .macro_ws)
+            Token.free(lhs.expansion_locs, pp.gpa)
+        else
+            break lhs;
+    } else {
+        return bufCopyTokens(lhs_toks, rhs_toks, &.{});
+    };
+
+    var rhs_rest: u32 = 1;
+    const rhs = for (rhs_toks) |rhs| {
+        if (rhs.id != .macro_ws) break rhs;
+        rhs_rest += 1;
+    } else {
+        return lhs_toks.appendAssumeCapacity(lhs);
+    };
+    defer Token.free(lhs.expansion_locs, pp.gpa);
+
+    const start = pp.comp.generated_buf.items.len;
+    const end = start + pp.expandedSlice(lhs).len + pp.expandedSlice(rhs).len;
+    try pp.comp.generated_buf.ensureTotalCapacity(end + 1); // +1 for a newline
+    // We cannot use the same slices here since they might be invalidated by `ensureCapacity`
+    pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(lhs));
+    pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(rhs));
+    pp.comp.generated_buf.appendAssumeCapacity('\n');
+
+    // Try to tokenize the result.
+    var tmp_tokenizer = Tokenizer{
+        .buf = pp.comp.generated_buf.items,
+        .comp = pp.comp,
+        .index = @intCast(start),
+        .source = .generated,
+    };
+    const pasted_token = tmp_tokenizer.nextNoWS();
+    const next = tmp_tokenizer.nextNoWS().id;
+    if (next != .nl and next != .eof) {
+        try pp.comp.diag.add(.{
+            .tag = .pasting_formed_invalid,
+            .loc = lhs.loc,
+            .extra = .{ .str = try pp.comp.diag.arena.allocator().dupe(
+                u8,
+                pp.comp.generated_buf.items[start..end],
+            ) },
+        }, lhs.expansionSlice());
+    }
+
+    const pasted_id = if (lhs.id == .placemarker and rhs.id == .placemarker)
+        .placemarker
+    else
+        pasted_token.id;
+    try lhs_toks.append(try pp.makeGeneratedToken(start, pasted_id, lhs));
+    try bufCopyTokens(lhs_toks, rhs_toks[rhs_rest..], &.{});
+}
+
+fn makeGeneratedToken(pp: *Preprocessor, start: usize, id: Token.Id, source: Token) !Token {
+    var pasted_token = Token{ .id = id, .loc = .{
+        .id = .generated,
+        .byte_offset = @intCast(start),
+        .line = pp.generated_line,
+    } };
+    pp.generated_line += 1;
+    try pasted_token.addExpansionLocation(pp.gpa, &.{source.loc});
+    try pasted_token.addExpansionLocation(pp.gpa, source.expansionSlice());
+    return pasted_token;
+}
+
+/// Defines a new macro and warns if it is a duplicate
+fn defineMacro(pp: *Preprocessor, name_tok: RawToken, macro: Macro) Error!void {
+    const name_str = pp.tokSlice(name_tok);
+    const gop = try pp.defines.getOrPut(name_str);
+    if (gop.found_existing and !gop.value_ptr.eql(macro, pp)) {
+        try pp.comp.diag.add(.{
+            .tag = if (gop.value_ptr.is_builtin) .builtin_macro_redefined else .macro_redefined,
+            .loc = .{ .id = name_tok.source, .byte_offset = name_tok.start, .line = name_tok.line },
+            .extra = .{ .str = name_str },
+        }, &.{});
+        // TODO add a previous definition note
+    }
+    if (pp.verbose) {
+        pp.verboseLog(name_tok, "macro {s} defined", .{name_str});
+    }
+    gop.value_ptr.* = macro;
+}
+
+/// Handle a #define directive.
+fn define(pp: *Preprocessor, tokenizer: *Tokenizer) Error!void {
+    // Get macro name and validate it.
+    const macro_name = tokenizer.nextNoWS();
+    if (macro_name.id == .keyword_defined) {
+        try pp.err(macro_name, .defined_as_macro_name);
+        return skipToNl(tokenizer);
+    }
+    if (!macro_name.id.isMacroIdentifier()) {
+        try pp.err(macro_name, .macro_name_must_be_identifier);
+        return skipToNl(tokenizer);
+    }
+    var macro_name_token_id = macro_name.id;
+    macro_name_token_id.simplifyMacroKeyword();
+    switch (macro_name_token_id) {
+        .identifier, .extended_identifier => {},
+        else => if (macro_name_token_id.isMacroIdentifier()) {
+            try pp.err(macro_name, .keyword_macro);
+        },
+    }
+
+    // Check for function macros and empty defines.
+    var first = tokenizer.next();
+    switch (first.id) {
+        .nl, .eof => return pp.defineMacro(macro_name, .{
+            .params = undefined,
+            .tokens = undefined,
+            .var_args = false,
+            .loc = undefined,
+            .is_func = false,
+        }),
+        .whitespace => first = tokenizer.next(),
+        .l_paren => return pp.defineFn(tokenizer, macro_name, first),
+        else => try pp.err(first, .whitespace_after_macro_name),
+    }
+    if (first.id == .hash_hash) {
+        try pp.err(first, .hash_hash_at_start);
+        return skipToNl(tokenizer);
+    }
+    first.id.simplifyMacroKeyword();
+
+    pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time.
+
+    var need_ws = false;
+    // Collect the token body and validate any ## found.
+    var tok = first;
+    const end_index = while (true) {
+        tok.id.simplifyMacroKeyword();
+        switch (tok.id) {
+            .hash_hash => {
+                const next = tokenizer.nextNoWS();
+                switch (next.id) {
+                    .nl, .eof => {
+                        try pp.err(tok, .hash_hash_at_end);
+                        return;
+                    },
+                    .hash_hash => {
+                        try pp.err(next, .hash_hash_at_end);
+                        return;
+                    },
+                    else => {},
+                }
+                try pp.token_buf.append(tok);
+                try pp.token_buf.append(next);
+            },
+            .nl, .eof => break tok.start,
+            .whitespace => need_ws = true,
+            else => {
+                if (tok.id != .whitespace and need_ws) {
+                    need_ws = false;
+                    try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
+                }
+                try pp.token_buf.append(tok);
+            },
+        }
+        tok = tokenizer.next();
+    } else unreachable;
+
+    const list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items);
+    try pp.defineMacro(macro_name, .{
+        .loc = .{
+            .id = macro_name.source,
+            .byte_offset = first.start,
+            .line = end_index,
+        },
+        .tokens = list,
+        .params = undefined,
+        .is_func = false,
+        .var_args = false,
+    });
+}
+
+/// Handle a function like #define directive.
+fn defineFn(pp: *Preprocessor, tokenizer: *Tokenizer, macro_name: RawToken, l_paren: RawToken) Error!void {
+    assert(macro_name.id.isMacroIdentifier());
+    var params = std.ArrayList([]const u8).init(pp.gpa);
+    defer params.deinit();
+
+    // Parse the parameter list.
+    var gnu_var_args: []const u8 = "";
+    var var_args = false;
+    const start_index = while (true) {
+        var tok = tokenizer.nextNoWS();
+        if (tok.id == .r_paren) break tok.end;
+        if (tok.id == .eof) return pp.err(tok, .unterminated_macro_param_list);
+        if (tok.id == .ellipsis) {
+            var_args = true;
+            const r_paren = tokenizer.nextNoWS();
+            if (r_paren.id != .r_paren) {
+                try pp.err(r_paren, .missing_paren_param_list);
+                try pp.err(l_paren, .to_match_paren);
+                return skipToNl(tokenizer);
+            }
+            break r_paren.end;
+        }
+        if (!tok.id.isMacroIdentifier()) {
+            try pp.err(tok, .invalid_token_param_list);
+            return skipToNl(tokenizer);
+        }
+
+        try params.append(pp.tokSlice(tok));
+
+        tok = tokenizer.nextNoWS();
+        if (tok.id == .ellipsis) {
+            try pp.err(tok, .gnu_va_macro);
+            gnu_var_args = params.pop();
+            const r_paren = tokenizer.nextNoWS();
+            if (r_paren.id != .r_paren) {
+                try pp.err(r_paren, .missing_paren_param_list);
+                try pp.err(l_paren, .to_match_paren);
+                return skipToNl(tokenizer);
+            }
+            break r_paren.end;
+        } else if (tok.id == .r_paren) {
+            break tok.end;
+        } else if (tok.id != .comma) {
+            try pp.err(tok, .expected_comma_param_list);
+            return skipToNl(tokenizer);
+        }
+    } else unreachable;
+
+    var need_ws = false;
+    // Collect the body tokens and validate # and ##'s found.
+    pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time.
+    const end_index = tok_loop: while (true) {
+        var tok = tokenizer.next();
+        switch (tok.id) {
+            .nl, .eof => break tok.start,
+            .whitespace => need_ws = pp.token_buf.items.len != 0,
+            .hash => {
+                if (tok.id != .whitespace and need_ws) {
+                    need_ws = false;
+                    try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
+                }
+                const param = tokenizer.nextNoWS();
+                blk: {
+                    if (var_args and param.id == .keyword_va_args) {
+                        tok.id = .stringify_va_args;
+                        try pp.token_buf.append(tok);
+                        continue :tok_loop;
+                    }
+                    if (!param.id.isMacroIdentifier()) break :blk;
+                    const s = pp.tokSlice(param);
+                    if (mem.eql(u8, s, gnu_var_args)) {
+                        tok.id = .stringify_va_args;
+                        try pp.token_buf.append(tok);
+                        continue :tok_loop;
+                    }
+                    for (params.items, 0..) |p, i| {
+                        if (mem.eql(u8, p, s)) {
+                            tok.id = .stringify_param;
+                            tok.end = @intCast(i);
+                            try pp.token_buf.append(tok);
+                            continue :tok_loop;
+                        }
+                    }
+                }
+                try pp.err(param, .hash_not_followed_param);
+                return skipToNl(tokenizer);
+            },
+            .hash_hash => {
+                need_ws = false;
+                // if ## appears at the beginning, the token buf is still empty
+                // in this case, error out
+                if (pp.token_buf.items.len == 0) {
+                    try pp.err(tok, .hash_hash_at_start);
+                    return skipToNl(tokenizer);
+                }
+                const saved_tokenizer = tokenizer.*;
+                const next = tokenizer.nextNoWS();
+                if (next.id == .nl or next.id == .eof) {
+                    try pp.err(tok, .hash_hash_at_end);
+                    return;
+                }
+                tokenizer.* = saved_tokenizer;
+                // convert the previous token to .macro_param_no_expand if it was .macro_param
+                if (pp.token_buf.items[pp.token_buf.items.len - 1].id == .macro_param) {
+                    pp.token_buf.items[pp.token_buf.items.len - 1].id = .macro_param_no_expand;
+                }
+                try pp.token_buf.append(tok);
+            },
+            else => {
+                if (tok.id != .whitespace and need_ws) {
+                    need_ws = false;
+                    try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
+                }
+                if (var_args and tok.id == .keyword_va_args) {
+                    // do nothing
+                } else if (tok.id.isMacroIdentifier()) {
+                    tok.id.simplifyMacroKeyword();
+                    const s = pp.tokSlice(tok);
+                    if (mem.eql(u8, gnu_var_args, s)) {
+                        tok.id = .keyword_va_args;
+                    } else for (params.items, 0..) |param, i| {
+                        if (mem.eql(u8, param, s)) {
+                            // NOTE: it doesn't matter to assign .macro_param_no_expand
+                            // here in case a ## was the previous token, because
+                            // ## processing will eat this token with the same semantics
+                            tok.id = .macro_param;
+                            tok.end = @intCast(i);
+                            break;
+                        }
+                    }
+                }
+                try pp.token_buf.append(tok);
+            },
+        }
+    } else unreachable;
+
+    const param_list = try pp.arena.allocator().dupe([]const u8, params.items);
+    const token_list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items);
+    try pp.defineMacro(macro_name, .{
+        .is_func = true,
+        .params = param_list,
+        .var_args = var_args or gnu_var_args.len != 0,
+        .tokens = token_list,
+        .loc = .{
+            .id = macro_name.source,
+            .byte_offset = start_index,
+            .line = end_index,
+        },
+    });
+}
+
+/// Handle an #embed directive
+fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {
+    const first = tokenizer.nextNoWS();
+    const filename_tok = pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof) catch |er| switch (er) {
+        error.InvalidInclude => return,
+        else => |e| return e,
+    };
+
+    // Check for empty filename.
+    const tok_slice = pp.expandedSlice(filename_tok);
+    if (tok_slice.len < 3) {
+        try pp.err(first, .empty_filename);
+        return;
+    }
+    const filename = tok_slice[1 .. tok_slice.len - 1];
+    const include_type: Compilation.IncludeType = switch (filename_tok.id) {
+        .string_literal => .quotes,
+        .macro_string => .angle_brackets,
+        else => unreachable,
+    };
+
+    const embed_bytes = (try pp.comp.findEmbed(filename, first.source, include_type)) orelse return pp.fatal(first, "'{s}' not found", .{filename});
+    defer pp.comp.gpa.free(embed_bytes);
+
+    if (embed_bytes.len == 0) return;
+
+    try pp.tokens.ensureUnusedCapacity(pp.comp.gpa, 2 * embed_bytes.len - 1); // N bytes and N-1 commas
+
+    // TODO: We currently only support systems with CHAR_BIT == 8
+    // If the target's CHAR_BIT is not 8, we need to write out correctly-sized embed_bytes
+    // and correctly account for the target's endianness
+    const writer = pp.comp.generated_buf.writer();
+
+    {
+        const byte = embed_bytes[0];
+        const start = pp.comp.generated_buf.items.len;
+        try writer.print("{d}", .{byte});
+        pp.tokens.appendAssumeCapacity(try pp.makeGeneratedToken(start, .embed_byte, filename_tok));
+    }
+
+    for (embed_bytes[1..]) |byte| {
+        const start = pp.comp.generated_buf.items.len;
+        try writer.print(",{d}", .{byte});
+        pp.tokens.appendAssumeCapacity(.{ .id = .comma, .loc = .{ .id = .generated, .byte_offset = @intCast(start) } });
+        pp.tokens.appendAssumeCapacity(try pp.makeGeneratedToken(start + 1, .embed_byte, filename_tok));
+    }
+    try pp.comp.generated_buf.append('\n');
+}
+
+// Handle a #include directive.
+fn include(pp: *Preprocessor, tokenizer: *Tokenizer, which: Compilation.WhichInclude) MacroError!void {
+    const first = tokenizer.nextNoWS();
+    const new_source = findIncludeSource(pp, tokenizer, first, which) catch |er| switch (er) {
+        error.InvalidInclude => return,
+        else => |e| return e,
+    };
+
+    // Prevent stack overflow
+    pp.include_depth += 1;
+    defer pp.include_depth -= 1;
+    if (pp.include_depth > max_include_depth) {
+        try pp.comp.diag.add(.{
+            .tag = .too_many_includes,
+            .loc = .{ .id = first.source, .byte_offset = first.start, .line = first.line },
+        }, &.{});
+        return error.StopPreprocessing;
+    }
+
+    if (pp.include_guards.get(new_source.id)) |guard| {
+        if (pp.defines.contains(guard)) return;
+    }
+
+    if (pp.verbose) {
+        pp.verboseLog(first, "include file {s}", .{new_source.path});
+    }
+
+    _ = pp.preprocessExtra(new_source) catch |er| switch (er) {
+        error.StopPreprocessing => {},
+        else => |e| return e,
+    };
+}
+
+/// tokens that are part of a pragma directive can happen in 3 ways:
+///     1. directly in the text via `#pragma ...`
+///     2. Via a string literal argument to `_Pragma`
+///     3. Via a stringified macro argument which is used as an argument to `_Pragma`
+/// operator_loc: Location of `_Pragma`; null if this is from #pragma
+/// arg_locs: expansion locations of the argument to _Pragma. empty if #pragma or a raw string literal was used
+fn makePragmaToken(pp: *Preprocessor, raw: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !Token {
+    var tok = tokFromRaw(raw);
+    if (operator_loc) |loc| {
+        try tok.addExpansionLocation(pp.gpa, &.{loc});
+    }
+    try tok.addExpansionLocation(pp.gpa, arg_locs);
+    return tok;
+}
+
+/// Handle a pragma directive
+fn pragma(pp: *Preprocessor, tokenizer: *Tokenizer, pragma_tok: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !void {
+    const name_tok = tokenizer.nextNoWS();
+    if (name_tok.id == .nl or name_tok.id == .eof) return;
+
+    const name = pp.tokSlice(name_tok);
+    try pp.tokens.append(pp.gpa, try pp.makePragmaToken(pragma_tok, operator_loc, arg_locs));
+    const pragma_start: u32 = @intCast(pp.tokens.len);
+
+    const pragma_name_tok = try pp.makePragmaToken(name_tok, operator_loc, arg_locs);
+    try pp.tokens.append(pp.gpa, pragma_name_tok);
+    while (true) {
+        const next_tok = tokenizer.next();
+        if (next_tok.id == .whitespace) continue;
+        if (next_tok.id == .eof) {
+            try pp.tokens.append(pp.gpa, .{
+                .id = .nl,
+                .loc = .{ .id = .generated },
+            });
+            break;
+        }
+        try pp.tokens.append(pp.gpa, try pp.makePragmaToken(next_tok, operator_loc, arg_locs));
+        if (next_tok.id == .nl) break;
+    }
+    if (pp.comp.getPragma(name)) |prag| unknown: {
+        return prag.preprocessorCB(pp, pragma_start) catch |er| switch (er) {
+            error.UnknownPragma => break :unknown,
+            else => |e| return e,
+        };
+    }
+    return pp.comp.diag.add(.{
+        .tag = .unknown_pragma,
+        .loc = pragma_name_tok.loc,
+    }, pragma_name_tok.expansionSlice());
+}
+
+fn findIncludeFilenameToken(
+    pp: *Preprocessor,
+    first_token: RawToken,
+    tokenizer: *Tokenizer,
+    trailing_token_behavior: enum { ignore_trailing_tokens, expect_nl_eof },
+) !Token {
+    const start = pp.tokens.len;
+    defer pp.tokens.len = start;
+    var first = first_token;
+
+    if (first.id == .angle_bracket_left) to_end: {
+        // The tokenizer does not handle <foo> include strings so do it here.
+        while (tokenizer.index < tokenizer.buf.len) : (tokenizer.index += 1) {
+            switch (tokenizer.buf[tokenizer.index]) {
+                '>' => {
+                    tokenizer.index += 1;
+                    first.end = tokenizer.index;
+                    first.id = .macro_string;
+                    break :to_end;
+                },
+                '\n' => break,
+                else => {},
+            }
+        }
+        try pp.comp.diag.add(.{
+            .tag = .header_str_closing,
+            .loc = .{ .id = first.source, .byte_offset = tokenizer.index, .line = first.line },
+        }, &.{});
+        try pp.err(first, .header_str_match);
+    }
+    // Try to expand if the argument is a macro.
+    try pp.expandMacro(tokenizer, first);
+
+    // Check that we actually got a string.
+    const filename_tok = pp.tokens.get(start);
+    switch (filename_tok.id) {
+        .string_literal, .macro_string => {},
+        else => {
+            try pp.err(first, .expected_filename);
+            try pp.expectNl(tokenizer);
+            return error.InvalidInclude;
+        },
+    }
+    switch (trailing_token_behavior) {
+        .expect_nl_eof => {
+            // Error on extra tokens.
+            const nl = tokenizer.nextNoWS();
+            if ((nl.id != .nl and nl.id != .eof) or pp.tokens.len > start + 1) {
+                skipToNl(tokenizer);
+                try pp.err(first, .extra_tokens_directive_end);
+            }
+        },
+        .ignore_trailing_tokens => {},
+    }
+    return filename_tok;
+}
+
+fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, which: Compilation.WhichInclude) !Source {
+    const filename_tok = try pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof);
+
+    // Check for empty filename.
+    const tok_slice = pp.expandedSlice(filename_tok);
+    if (tok_slice.len < 3) {
+        try pp.err(first, .empty_filename);
+        return error.InvalidInclude;
+    }
+
+    // Find the file.
+    const filename = tok_slice[1 .. tok_slice.len - 1];
+    const include_type: Compilation.IncludeType = switch (filename_tok.id) {
+        .string_literal => .quotes,
+        .macro_string => .angle_brackets,
+        else => unreachable,
+    };
+
+    return (try pp.comp.findInclude(filename, first.source, include_type, which)) orelse
+        pp.fatal(first, "'{s}' not found", .{filename});
+}
+
+/// Pretty print tokens and try to preserve whitespace.
+pub fn prettyPrintTokens(pp: *Preprocessor, w: anytype) !void {
+    var i: u32 = 0;
+    while (true) : (i += 1) {
+        var cur: Token = pp.tokens.get(i);
+        switch (cur.id) {
+            .eof => {
+                if (pp.tokens.len > 1 and pp.tokens.items(.id)[i - 1] != .nl) try w.writeByte('\n');
+                break;
+            },
+            .nl => try w.writeAll("\n"),
+            .keyword_pragma => {
+                const pragma_name = pp.expandedSlice(pp.tokens.get(i + 1));
+                const end_idx = mem.indexOfScalarPos(Token.Id, pp.tokens.items(.id), i, .nl) orelse i + 1;
+                const pragma_len = @as(u32, @intCast(end_idx)) - i;
+
+                if (pp.comp.getPragma(pragma_name)) |prag| {
+                    if (!prag.shouldPreserveTokens(pp, i + 1)) {
+                        i += pragma_len;
+                        cur = pp.tokens.get(i);
+                        continue;
+                    }
+                }
+                try w.writeAll("#pragma");
+                i += 1;
+                while (true) : (i += 1) {
+                    cur = pp.tokens.get(i);
+                    if (cur.id == .nl) {
+                        try w.writeByte('\n');
+                        break;
+                    }
+                    try w.writeByte(' ');
+                    const slice = pp.expandedSlice(cur);
+                    try w.writeAll(slice);
+                }
+            },
+            .whitespace => {
+                var slice = pp.expandedSlice(cur);
+                while (mem.indexOfScalar(u8, slice, '\n')) |some| {
+                    try w.writeByte('\n');
+                    slice = slice[some + 1 ..];
+                }
+                for (slice) |_| try w.writeByte(' ');
+            },
+            else => {
+                const slice = pp.expandedSlice(cur);
+                try w.writeAll(slice);
+            },
+        }
+    }
+}
+
+test "Preserve pragma tokens sometimes" {
+    const allocator = std.testing.allocator;
+    const Test = struct {
+        fn runPreprocessor(source_text: []const u8) ![]const u8 {
+            var buf = std.ArrayList(u8).init(allocator);
+            defer buf.deinit();
+
+            var comp = Compilation.init(allocator);
+            defer comp.deinit();
+
+            try comp.addDefaultPragmaHandlers();
+
+            var pp = Preprocessor.init(&comp);
+            defer pp.deinit();
+
+            pp.preserve_whitespace = true;
+
+            const test_runner_macros = try comp.addSourceFromBuffer("<test_runner>", source_text);
+            const eof = try pp.preprocess(test_runner_macros);
+            try pp.tokens.append(pp.gpa, eof);
+            try pp.prettyPrintTokens(buf.writer());
+            return allocator.dupe(u8, buf.items);
+        }
+
+        fn check(source_text: []const u8, expected: []const u8) !void {
+            const output = try runPreprocessor(source_text);
+            defer allocator.free(output);
+
+            try std.testing.expectEqualStrings(expected, output);
+        }
+    };
+    const preserve_gcc_diagnostic =
+        \\#pragma GCC diagnostic error "-Wnewline-eof"
+        \\#pragma GCC warning error "-Wnewline-eof"
+        \\int x;
+        \\#pragma GCC ignored error "-Wnewline-eof"
+        \\
+    ;
+    try Test.check(preserve_gcc_diagnostic, preserve_gcc_diagnostic);
+
+    const omit_once =
+        \\#pragma once
+        \\int x;
+        \\#pragma once
+        \\
+    ;
+    try Test.check(omit_once, "int x;\n");
+
+    const omit_poison =
+        \\#pragma GCC poison foobar
+        \\
+    ;
+    try Test.check(omit_poison, "");
+}
+
+test "destringify" {
+    const allocator = std.testing.allocator;
+    const Test = struct {
+        fn testDestringify(pp: *Preprocessor, stringified: []const u8, destringified: []const u8) !void {
+            pp.char_buf.clearRetainingCapacity();
+            try pp.char_buf.ensureUnusedCapacity(stringified.len);
+            pp.destringify(stringified);
+            try std.testing.expectEqualStrings(destringified, pp.char_buf.items);
+        }
+    };
+    var comp = Compilation.init(allocator);
+    defer comp.deinit();
+    var pp = Preprocessor.init(&comp);
+    defer pp.deinit();
+
+    try Test.testDestringify(&pp, "hello\tworld\n", "hello\tworld\n");
+    try Test.testDestringify(&pp,
+        \\ \"FOO BAR BAZ\"
+    ,
+        \\ "FOO BAR BAZ"
+    );
+    try Test.testDestringify(&pp,
+        \\ \\t\\n
+        \\
+    ,
+        \\ \t\n
+        \\
+    );
+}
+
+test "Include guards" {
+    const Test = struct {
+        /// This is here so that when #elifdef / #elifndef are added we don't forget
+        /// to test that they don't accidentally break include guard detection
+        fn pairsWithIfndef(tok_id: RawToken.Id) bool {
+            return switch (tok_id) {
+                .keyword_elif,
+                .keyword_elifdef,
+                .keyword_elifndef,
+                .keyword_else,
+                => true,
+
+                .keyword_include,
+                .keyword_include_next,
+                .keyword_embed,
+                .keyword_define,
+                .keyword_defined,
+                .keyword_undef,
+                .keyword_ifdef,
+                .keyword_ifndef,
+                .keyword_error,
+                .keyword_warning,
+                .keyword_pragma,
+                .keyword_line,
+                .keyword_endif,
+                => false,
+                else => unreachable,
+            };
+        }
+
+        fn skippable(tok_id: RawToken.Id) bool {
+            return switch (tok_id) {
+                .keyword_defined, .keyword_va_args, .keyword_endif => true,
+                else => false,
+            };
+        }
+
+        fn testIncludeGuard(allocator: std.mem.Allocator, comptime template: []const u8, tok_id: RawToken.Id, expected_guards: u32) !void {
+            var comp = Compilation.init(allocator);
+            defer comp.deinit();
+            var pp = Preprocessor.init(&comp);
+            defer pp.deinit();
+
+            const path = try std.fs.path.join(allocator, &.{ ".", "bar.h" });
+            defer allocator.free(path);
+
+            _ = try comp.addSourceFromBuffer(path, "int bar = 5;\n");
+
+            var buf = std.ArrayList(u8).init(allocator);
+            defer buf.deinit();
+
+            var writer = buf.writer();
+            switch (tok_id) {
+                .keyword_include, .keyword_include_next => try writer.print(template, .{ tok_id.lexeme().?, " \"bar.h\"" }),
+                .keyword_define, .keyword_undef => try writer.print(template, .{ tok_id.lexeme().?, " BAR" }),
+                .keyword_ifndef,
+                .keyword_ifdef,
+                .keyword_elifdef,
+                .keyword_elifndef,
+                => try writer.print(template, .{ tok_id.lexeme().?, " BAR\n#endif" }),
+                else => try writer.print(template, .{ tok_id.lexeme().?, "" }),
+            }
+            const source = try comp.addSourceFromBuffer("test.h", buf.items);
+            _ = try pp.preprocess(source);
+
+            try std.testing.expectEqual(expected_guards, pp.include_guards.count());
+        }
+    };
+    const tags = std.meta.tags(RawToken.Id);
+    for (tags) |tag| {
+        if (Test.skippable(tag)) continue;
+        var copy = tag;
+        copy.simplifyMacroKeyword();
+        if (copy != tag or tag == .keyword_else) {
+            const inside_ifndef_template =
+                \\//Leading comment (should be ignored)
+                \\
+                \\#ifndef FOO
+                \\#{s}{s}
+                \\#endif
+            ;
+            const expected_guards: u32 = if (Test.pairsWithIfndef(tag)) 0 else 1;
+            try Test.testIncludeGuard(std.testing.allocator, inside_ifndef_template, tag, expected_guards);
+
+            const outside_ifndef_template =
+                \\#ifndef FOO
+                \\#endif
+                \\#{s}{s}
+            ;
+            try Test.testIncludeGuard(std.testing.allocator, outside_ifndef_template, tag, 0);
+        }
+    }
+}
deps/aro/record_layout.zig
@@ -0,0 +1,669 @@
+//! Record layout code adapted from https://github.com/mahkoh/repr-c
+//! Licensed under MIT license: https://github.com/mahkoh/repr-c/tree/master/repc/facade
+
+const std = @import("std");
+const Type = @import("Type.zig");
+const Attribute = @import("Attribute.zig");
+const Compilation = @import("Compilation.zig");
+const Parser = @import("Parser.zig");
+const Record = Type.Record;
+const Field = Record.Field;
+const TypeLayout = Type.TypeLayout;
+const FieldLayout = Type.FieldLayout;
+const target_util = @import("target.zig");
+
+const BITS_PER_BYTE = 8;
+
+const OngoingBitfield = struct {
+    size_bits: u64,
+    unused_size_bits: u64,
+};
+
+const SysVContext = struct {
+    /// Does the record have an __attribute__((packed)) annotation.
+    attr_packed: bool,
+    /// The value of #pragma pack(N) at the type level if any.
+    max_field_align_bits: ?u64,
+    /// The alignment of this record.
+    aligned_bits: u32,
+    is_union: bool,
+    /// The size of the record. This might not be a multiple of 8 if the record contains bit-fields.
+    /// For structs, this is also the offset of the first bit after the last field.
+    size_bits: u64,
+    /// non-null if the previous field was a non-zero-sized bit-field. Only used by MinGW.
+    ongoing_bitfield: ?OngoingBitfield,
+
+    comp: *const Compilation,
+
+    fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) SysVContext {
+        var pack_value: ?u64 = null;
+        if (pragma_pack) |pak| {
+            pack_value = pak * BITS_PER_BYTE;
+        }
+        var req_align: u29 = BITS_PER_BYTE;
+        if (ty.requestedAlignment(comp)) |aln| {
+            req_align = aln * BITS_PER_BYTE;
+        }
+        return SysVContext{
+            .attr_packed = ty.hasAttribute(.@"packed"),
+            .max_field_align_bits = pack_value,
+            .aligned_bits = req_align,
+            .is_union = ty.is(.@"union"),
+            .size_bits = 0,
+            .comp = comp,
+            .ongoing_bitfield = null,
+        };
+    }
+
+    fn layoutFields(self: *SysVContext, rec: *const Record) void {
+        for (rec.fields, 0..) |*fld, fld_indx| {
+            const type_layout = computeLayout(fld.ty, self.comp);
+
+            var field_attrs: ?[]const Attribute = null;
+            if (rec.field_attributes) |attrs| {
+                field_attrs = attrs[fld_indx];
+            }
+            if (self.comp.target.isMinGW()) {
+                fld.layout = self.layoutMinGWField(fld, field_attrs, type_layout);
+            } else {
+                if (fld.isRegularField()) {
+                    fld.layout = self.layoutRegularField(field_attrs, type_layout);
+                } else {
+                    fld.layout = self.layoutBitField(field_attrs, type_layout, fld.isNamed(), fld.specifiedBitWidth());
+                }
+            }
+        }
+    }
+
+    /// On MinGW the alignment of the field is calculated in the usual way except that the alignment of
+    /// the underlying type is ignored in three cases
+    /// - the field is packed
+    /// - the field is a bit-field and the previous field was a non-zero-sized bit-field with the same type size
+    /// - the field is a zero-sized bit-field and the previous field was not a non-zero-sized bit-field
+    /// See test case 0068.
+    fn ignoreTypeAlignment(is_attr_packed: bool, bit_width: ?u32, ongoing_bitfield: ?OngoingBitfield, fld_layout: TypeLayout) bool {
+        if (is_attr_packed) return true;
+        if (bit_width) |width| {
+            if (ongoing_bitfield) |ongoing| {
+                if (ongoing.size_bits == fld_layout.size_bits) return true;
+            } else {
+                if (width == 0) return true;
+            }
+        }
+        return false;
+    }
+
+    fn layoutMinGWField(
+        self: *SysVContext,
+        field: *const Field,
+        field_attrs: ?[]const Attribute,
+        field_layout: TypeLayout,
+    ) FieldLayout {
+        const annotation_alignment_bits = BITS_PER_BYTE * (Type.annotationAlignment(self.comp, field_attrs) orelse 1);
+        const is_attr_packed = self.attr_packed or isPacked(field_attrs);
+        const ignore_type_alignment = ignoreTypeAlignment(is_attr_packed, field.bit_width, self.ongoing_bitfield, field_layout);
+
+        var field_alignment_bits: u64 = field_layout.field_alignment_bits;
+        if (ignore_type_alignment) {
+            field_alignment_bits = BITS_PER_BYTE;
+        }
+        field_alignment_bits = @max(field_alignment_bits, annotation_alignment_bits);
+        if (self.max_field_align_bits) |bits| {
+            field_alignment_bits = @min(field_alignment_bits, bits);
+        }
+
+        // The field affects the record alignment in one of three cases
+        // - the field is a regular field
+        // - the field is a zero-width bit-field following a non-zero-width bit-field
+        // - the field is a non-zero-width bit-field and not packed.
+        // See test case 0069.
+        const update_record_alignment =
+            field.isRegularField() or
+            (field.specifiedBitWidth() == 0 and self.ongoing_bitfield != null) or
+            (field.specifiedBitWidth() != 0 and !is_attr_packed);
+
+        // If a field affects the alignment of a record, the alignment is calculated in the
+        // usual way except that __attribute__((packed)) is ignored on a zero-width bit-field.
+        // See test case 0068.
+        if (update_record_alignment) {
+            var ty_alignment_bits = field_layout.field_alignment_bits;
+            if (is_attr_packed and (field.isRegularField() or field.specifiedBitWidth() != 0)) {
+                ty_alignment_bits = BITS_PER_BYTE;
+            }
+            ty_alignment_bits = @max(ty_alignment_bits, annotation_alignment_bits);
+            if (self.max_field_align_bits) |bits| {
+                ty_alignment_bits = @intCast(@min(ty_alignment_bits, bits));
+            }
+            self.aligned_bits = @max(self.aligned_bits, ty_alignment_bits);
+        }
+
+        // NOTE: ty_alignment_bits and field_alignment_bits are different in the following case:
+        // Y = { size: 64, alignment: 64 }struct {
+        //     { offset: 0, size: 1 }c { size: 8, alignment: 8 }char:1,
+        //     @attr_packed _ { size: 64, alignment: 64 }long long:0,
+        //     { offset: 8, size: 8 }d { size: 8, alignment: 8 }char,
+        // }
+        if (field.isRegularField()) {
+            return self.layoutRegularFieldMinGW(field_layout.size_bits, field_alignment_bits);
+        } else {
+            return self.layoutBitFieldMinGW(field_layout.size_bits, field_alignment_bits, field.isNamed(), field.specifiedBitWidth());
+        }
+    }
+
+    fn layoutBitFieldMinGW(
+        self: *SysVContext,
+        ty_size_bits: u64,
+        field_alignment_bits: u64,
+        is_named: bool,
+        width: u64,
+    ) FieldLayout {
+        std.debug.assert(width <= ty_size_bits); // validated in parser
+
+        // In a union, the size of the underlying type does not affect the size of the union.
+        // See test case 0070.
+        if (self.is_union) {
+            self.size_bits = @max(self.size_bits, width);
+            if (!is_named) return .{};
+            return .{
+                .offset_bits = 0,
+                .size_bits = width,
+            };
+        }
+        if (width == 0) {
+            self.ongoing_bitfield = null;
+        } else {
+            // If there is an ongoing bit-field in a struct whose underlying type has the same size and
+            // if there is enough space left to place this bit-field, then this bit-field is placed in
+            // the ongoing bit-field and the size of the struct is not affected by this
+            // bit-field. See test case 0037.
+            if (self.ongoing_bitfield) |*ongoing| {
+                if (ongoing.size_bits == ty_size_bits and ongoing.unused_size_bits >= width) {
+                    const offset_bits = self.size_bits - ongoing.unused_size_bits;
+                    ongoing.unused_size_bits -= width;
+                    if (!is_named) return .{};
+                    return .{
+                        .offset_bits = offset_bits,
+                        .size_bits = width,
+                    };
+                }
+            }
+            // Otherwise this field is part of a new ongoing bit-field.
+            self.ongoing_bitfield = .{
+                .size_bits = ty_size_bits,
+                .unused_size_bits = ty_size_bits - width,
+            };
+        }
+        const offset_bits = std.mem.alignForward(u64, self.size_bits, field_alignment_bits);
+        self.size_bits = if (width == 0) offset_bits else offset_bits + ty_size_bits;
+        if (!is_named) return .{};
+        return .{
+            .offset_bits = offset_bits,
+            .size_bits = width,
+        };
+    }
+
+    fn layoutRegularFieldMinGW(
+        self: *SysVContext,
+        ty_size_bits: u64,
+        field_alignment_bits: u64,
+    ) FieldLayout {
+        self.ongoing_bitfield = null;
+        // A struct field starts at the next offset in the struct that is properly
+        // aligned with respect to the start of the struct. See test case 0033.
+        // A union field always starts at offset 0.
+        const offset_bits = if (self.is_union) 0 else std.mem.alignForward(u64, self.size_bits, field_alignment_bits);
+
+        // Set the size of the record to the maximum of the current size and the end of
+        // the field. See test case 0034.
+        self.size_bits = @max(self.size_bits, offset_bits + ty_size_bits);
+
+        return .{
+            .offset_bits = offset_bits,
+            .size_bits = ty_size_bits,
+        };
+    }
+
+    fn layoutRegularField(
+        self: *SysVContext,
+        fld_attrs: ?[]const Attribute,
+        fld_layout: TypeLayout,
+    ) FieldLayout {
+        var fld_align_bits = fld_layout.field_alignment_bits;
+
+        // If the struct or the field is packed, then the alignment of the underlying type is
+        // ignored. See test case 0084.
+        if (self.attr_packed or isPacked(fld_attrs)) {
+            fld_align_bits = BITS_PER_BYTE;
+        }
+
+        // The field alignment can be increased by __attribute__((aligned)) annotations on the
+        // field. See test case 0085.
+        if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| {
+            fld_align_bits = @max(fld_align_bits, anno * BITS_PER_BYTE);
+        }
+
+        // #pragma pack takes precedence over all other attributes. See test cases 0084 and
+        // 0085.
+        if (self.max_field_align_bits) |req_bits| {
+            fld_align_bits = @intCast(@min(fld_align_bits, req_bits));
+        }
+
+        // A struct field starts at the next offset in the struct that is properly
+        // aligned with respect to the start of the struct.
+        const offset_bits = if (self.is_union) 0 else std.mem.alignForward(u64, self.size_bits, fld_align_bits);
+        const size_bits = fld_layout.size_bits;
+
+        // The alignment of a record is the maximum of its field alignments. See test cases
+        // 0084, 0085, 0086.
+        self.size_bits = @max(self.size_bits, offset_bits + size_bits);
+        self.aligned_bits = @max(self.aligned_bits, fld_align_bits);
+
+        return .{
+            .offset_bits = offset_bits,
+            .size_bits = size_bits,
+        };
+    }
+
+    fn layoutBitField(
+        self: *SysVContext,
+        fld_attrs: ?[]const Attribute,
+        fld_layout: TypeLayout,
+        is_named: bool,
+        bit_width: u64,
+    ) FieldLayout {
+        const ty_size_bits = fld_layout.size_bits;
+        var ty_fld_algn_bits: u32 = fld_layout.field_alignment_bits;
+
+        if (bit_width > 0) {
+            std.debug.assert(bit_width <= ty_size_bits); // Checked in parser
+            // Some targets ignore the alignment of the underlying type when laying out
+            // non-zero-sized bit-fields. See test case 0072. On such targets, bit-fields never
+            // cross a storage boundary. See test case 0081.
+            if (target_util.ignoreNonZeroSizedBitfieldTypeAlignment(self.comp.target)) {
+                ty_fld_algn_bits = 1;
+            }
+        } else {
+            // Some targets ignore the alignment of the underlying type when laying out
+            // zero-sized bit-fields. See test case 0073.
+            if (target_util.ignoreZeroSizedBitfieldTypeAlignment(self.comp.target)) {
+                ty_fld_algn_bits = 1;
+            }
+            // Some targets have a minimum alignment of zero-sized bit-fields. See test case
+            // 0074.
+            if (target_util.minZeroWidthBitfieldAlignment(self.comp.target)) |target_align| {
+                ty_fld_algn_bits = @max(ty_fld_algn_bits, target_align);
+            }
+        }
+
+        // __attribute__((packed)) on the record is identical to __attribute__((packed)) on each
+        // field. See test case 0067.
+        const attr_packed = self.attr_packed or isPacked(fld_attrs);
+        const has_packing_annotation = attr_packed or self.max_field_align_bits != null;
+
+        const annotation_alignment: u32 = if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| anno * BITS_PER_BYTE else 1;
+
+        const first_unused_bit: u64 = if (self.is_union) 0 else self.size_bits;
+        var field_align_bits: u64 = 1;
+
+        if (bit_width == 0) {
+            field_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
+        } else if (self.comp.langopts.emulate == .gcc) {
+            // On GCC, the field alignment is at least the alignment requested by annotations
+            // except as restricted by #pragma pack. See test case 0083.
+            field_align_bits = annotation_alignment;
+            if (self.max_field_align_bits) |max_bits| {
+                field_align_bits = @min(annotation_alignment, max_bits);
+            }
+
+            // On GCC, if there are no packing annotations and
+            // - the field would otherwise start at an offset such that it would cross a
+            //   storage boundary or
+            // - the alignment of the type is larger than its size,
+            // then it is aligned to the type's field alignment. See test case 0083.
+            if (!has_packing_annotation) {
+                const start_bit = std.mem.alignForward(u64, first_unused_bit, field_align_bits);
+
+                const does_field_cross_boundary = start_bit % ty_fld_algn_bits + bit_width > ty_size_bits;
+
+                if (ty_fld_algn_bits > ty_size_bits or does_field_cross_boundary) {
+                    field_align_bits = @max(field_align_bits, ty_fld_algn_bits);
+                }
+            }
+        } else {
+            std.debug.assert(self.comp.langopts.emulate == .clang);
+
+            // On Clang, the alignment requested by annotations is not respected if it is
+            // larger than the value of #pragma pack. See test case 0083.
+            if (annotation_alignment <= self.max_field_align_bits orelse std.math.maxInt(u29)) {
+                field_align_bits = @max(field_align_bits, annotation_alignment);
+            }
+            // On Clang, if there are no packing annotations and the field would cross a
+            // storage boundary if it were positioned at the first unused bit in the record,
+            // it is aligned to the type's field alignment. See test case 0083.
+            if (!has_packing_annotation) {
+                const does_field_cross_boundary = first_unused_bit % ty_fld_algn_bits + bit_width > ty_size_bits;
+
+                if (does_field_cross_boundary)
+                    field_align_bits = @max(field_align_bits, ty_fld_algn_bits);
+            }
+        }
+
+        const offset_bits = std.mem.alignForward(u64, first_unused_bit, field_align_bits);
+        self.size_bits = @max(self.size_bits, offset_bits + bit_width);
+
+        // Unnamed fields do not contribute to the record alignment except on a few targets.
+        // See test case 0079.
+        if (is_named or target_util.unnamedFieldAffectsAlignment(self.comp.target)) {
+            var inherited_align_bits: u32 = undefined;
+
+            if (bit_width == 0) {
+                // If the width is 0, #pragma pack and __attribute__((packed)) are ignored.
+                // See test case 0075.
+                inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
+            } else if (self.max_field_align_bits) |max_align_bits| {
+                // Otherwise, if a #pragma pack is in effect, __attribute__((packed)) on the field or
+                // record is ignored. See test case 0076.
+                inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
+                inherited_align_bits = @intCast(@min(inherited_align_bits, max_align_bits));
+            } else if (attr_packed) {
+                // Otherwise, if the field or the record is packed, the field alignment is 1 bit unless
+                // it is explicitly increased with __attribute__((aligned)). See test case 0077.
+                inherited_align_bits = annotation_alignment;
+            } else {
+                // Otherwise, the field alignment is the field alignment of the underlying type unless
+                // it is explicitly increased with __attribute__((aligned)). See test case 0078.
+                inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
+            }
+            self.aligned_bits = @max(self.aligned_bits, inherited_align_bits);
+        }
+
+        if (!is_named) return .{};
+        return .{
+            .size_bits = bit_width,
+            .offset_bits = offset_bits,
+        };
+    }
+};
+
+const MsvcContext = struct {
+    req_align_bits: u32,
+    max_field_align_bits: ?u32,
+    /// The alignment of pointers that point to an object of this type. This is greater than or equal
+    /// to the required alignment. Once all fields have been laid out, the size of the record will be
+    /// rounded up to this value.
+    pointer_align_bits: u32,
+    /// The alignment of this type when it is used as a record field. This is greater than or equal to
+    /// the pointer alignment.
+    field_align_bits: u32,
+    size_bits: u64,
+    ongoing_bitfield: ?OngoingBitfield,
+    contains_non_bitfield: bool,
+    is_union: bool,
+    comp: *const Compilation,
+
+    fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) MsvcContext {
+        var pack_value: ?u32 = null;
+        if (ty.hasAttribute(.@"packed")) {
+            // __attribute__((packed)) behaves like #pragma pack(1) in clang. See test case 0056.
+            pack_value = BITS_PER_BYTE;
+        }
+        if (pack_value == null) {
+            if (pragma_pack) |pack| {
+                pack_value = pack * BITS_PER_BYTE;
+            }
+        }
+        if (pack_value) |pack| {
+            pack_value = msvcPragmaPack(comp, pack);
+        }
+
+        // The required alignment can be increased by adding a __declspec(align)
+        // annotation. See test case 0023.
+        var must_align: u29 = BITS_PER_BYTE;
+        if (ty.requestedAlignment(comp)) |req_align| {
+            must_align = req_align * BITS_PER_BYTE;
+        }
+        return MsvcContext{
+            .req_align_bits = must_align,
+            .pointer_align_bits = must_align,
+            .field_align_bits = must_align,
+            .size_bits = 0,
+            .max_field_align_bits = pack_value,
+            .ongoing_bitfield = null,
+            .contains_non_bitfield = false,
+            .is_union = ty.is(.@"union"),
+            .comp = comp,
+        };
+    }
+
+    fn layoutField(self: *MsvcContext, fld: *const Field, fld_attrs: ?[]const Attribute) FieldLayout {
+        const type_layout = computeLayout(fld.ty, self.comp);
+
+        // The required alignment of the field is the maximum of the required alignment of the
+        // underlying type and the __declspec(align) annotation on the field itself.
+        // See test case 0028.
+        var req_align = type_layout.required_alignment_bits;
+        if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| {
+            req_align = @max(anno * BITS_PER_BYTE, req_align);
+        }
+
+        // The required alignment of a record is the maximum of the required alignments of its
+        // fields except that the required alignment of bitfields is ignored.
+        // See test case 0029.
+        if (fld.isRegularField()) {
+            self.req_align_bits = @max(self.req_align_bits, req_align);
+        }
+
+        // The offset of the field is based on the field alignment of the underlying type.
+        // See test case 0027.
+        var fld_align_bits = type_layout.field_alignment_bits;
+        if (self.max_field_align_bits) |max_align| {
+            fld_align_bits = @min(fld_align_bits, max_align);
+        }
+        // check the requested alignment of the field type.
+        if (fld.ty.requestedAlignment(self.comp)) |type_req_align| {
+            fld_align_bits = @max(fld_align_bits, type_req_align * 8);
+        }
+
+        if (isPacked(fld_attrs)) {
+            // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma
+            // pack(1) had been applied only to this field. See test case 0057.
+            fld_align_bits = BITS_PER_BYTE;
+        }
+        // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma
+        // pack(1) had been applied only to this field. See test case 0057.
+        fld_align_bits = @max(fld_align_bits, req_align);
+        if (fld.isRegularField()) {
+            return self.layoutRegularField(type_layout.size_bits, fld_align_bits);
+        } else {
+            return self.layoutBitField(type_layout.size_bits, fld_align_bits, fld.specifiedBitWidth());
+        }
+    }
+
+    fn layoutBitField(self: *MsvcContext, ty_size_bits: u64, field_align: u32, bit_width: u32) FieldLayout {
+        if (bit_width == 0) {
+            // A zero-sized bit-field that does not follow a non-zero-sized bit-field does not affect
+            // the overall layout of the record. Even in a union where the order would otherwise
+            // not matter. See test case 0035.
+            if (self.ongoing_bitfield) |_| {
+                self.ongoing_bitfield = null;
+            } else {
+                // this field takes 0 space.
+                return .{ .offset_bits = self.size_bits, .size_bits = bit_width };
+            }
+        } else {
+            std.debug.assert(bit_width <= ty_size_bits);
+            // If there is an ongoing bit-field in a struct whose underlying type has the same size and
+            // if there is enough space left to place this bit-field, then this bit-field is placed in
+            // the ongoing bit-field and the overall layout of the struct is not affected by this
+            // bit-field. See test case 0037.
+            if (!self.is_union) {
+                if (self.ongoing_bitfield) |*p| {
+                    if (p.size_bits == ty_size_bits and p.unused_size_bits >= bit_width) {
+                        const offset_bits = self.size_bits - p.unused_size_bits;
+                        p.unused_size_bits -= bit_width;
+                        return .{ .offset_bits = offset_bits, .size_bits = bit_width };
+                    }
+                }
+            }
+            // Otherwise this field is part of a new ongoing bit-field.
+            self.ongoing_bitfield = .{ .size_bits = ty_size_bits, .unused_size_bits = ty_size_bits - bit_width };
+        }
+        const offset_bits = if (!self.is_union) bits: {
+            // This is the one place in the layout of a record where the pointer alignment might
+            // get assigned a smaller value than the field alignment. This can only happen if
+            // the field or the type of the field has a required alignment. Otherwise the value
+            // of field_alignment_bits is already bound by max_field_alignment_bits.
+            // See test case 0038.
+            const p_align = if (self.max_field_align_bits) |max_fld_align|
+                @min(max_fld_align, field_align)
+            else
+                field_align;
+            self.pointer_align_bits = @max(self.pointer_align_bits, p_align);
+            self.field_align_bits = @max(self.field_align_bits, field_align);
+
+            const offset_bits = std.mem.alignForward(u64, self.size_bits, field_align);
+            self.size_bits = if (bit_width == 0) offset_bits else offset_bits + ty_size_bits;
+
+            break :bits offset_bits;
+        } else bits: {
+            // Bit-fields do not affect the alignment of a union. See test case 0041.
+            self.size_bits = @max(self.size_bits, ty_size_bits);
+            break :bits 0;
+        };
+        return .{ .offset_bits = offset_bits, .size_bits = bit_width };
+    }
+
+    fn layoutRegularField(self: *MsvcContext, size_bits: u64, field_align: u32) FieldLayout {
+        self.contains_non_bitfield = true;
+        self.ongoing_bitfield = null;
+        // The alignment of the field affects both the pointer alignment and the field
+        // alignment of the record. See test case 0032.
+        self.pointer_align_bits = @max(self.pointer_align_bits, field_align);
+        self.field_align_bits = @max(self.field_align_bits, field_align);
+        const offset_bits = switch (self.is_union) {
+            true => 0,
+            false => std.mem.alignForward(u64, self.size_bits, field_align),
+        };
+        self.size_bits = @max(self.size_bits, offset_bits + size_bits);
+        return .{ .offset_bits = offset_bits, .size_bits = size_bits };
+    }
+    fn handleZeroSizedRecord(self: *MsvcContext) void {
+        if (self.is_union) {
+            // MSVC does not allow unions without fields.
+            // If all fields in a union have size 0, the size of the union is set to
+            // - its field alignment if it contains at least one non-bitfield
+            // - 4 bytes if it contains only bitfields
+            // See test case 0025.
+            if (self.contains_non_bitfield) {
+                self.size_bits = self.field_align_bits;
+            } else {
+                self.size_bits = 4 * BITS_PER_BYTE;
+            }
+        } else {
+            // If all fields in a struct have size 0, its size is set to its required alignment
+            // but at least to 4 bytes. See test case 0026.
+            self.size_bits = @max(self.req_align_bits, 4 * BITS_PER_BYTE);
+            self.pointer_align_bits = @intCast(@min(self.pointer_align_bits, self.size_bits));
+        }
+    }
+};
+
+pub fn compute(rec: *Type.Record, ty: Type, comp: *const Compilation, pragma_pack: ?u8) void {
+    switch (comp.langopts.emulate) {
+        .gcc, .clang => {
+            var context = SysVContext.init(ty, comp, pragma_pack);
+
+            context.layoutFields(rec);
+
+            context.size_bits = std.mem.alignForward(u64, context.size_bits, context.aligned_bits);
+
+            rec.type_layout = .{
+                .size_bits = context.size_bits,
+                .field_alignment_bits = context.aligned_bits,
+                .pointer_alignment_bits = context.aligned_bits,
+                .required_alignment_bits = BITS_PER_BYTE,
+            };
+        },
+        .msvc => {
+            var context = MsvcContext.init(ty, comp, pragma_pack);
+            for (rec.fields, 0..) |*fld, fld_indx| {
+                var field_attrs: ?[]const Attribute = null;
+                if (rec.field_attributes) |attrs| {
+                    field_attrs = attrs[fld_indx];
+                }
+
+                fld.layout = context.layoutField(fld, field_attrs);
+            }
+            if (context.size_bits == 0) {
+                // As an extension, MSVC allows records that only contain zero-sized bitfields and empty
+                // arrays. Such records would be zero-sized but this case is handled here separately to
+                // ensure that there are no zero-sized records.
+                context.handleZeroSizedRecord();
+            }
+            context.size_bits = std.mem.alignForward(u64, context.size_bits, context.pointer_align_bits);
+            rec.type_layout = .{
+                .size_bits = context.size_bits,
+                .field_alignment_bits = context.field_align_bits,
+                .pointer_alignment_bits = context.pointer_align_bits,
+                .required_alignment_bits = context.req_align_bits,
+            };
+        },
+    }
+}
+
+fn computeLayout(ty: Type, comp: *const Compilation) TypeLayout {
+    if (ty.getRecord()) |rec| {
+        const requested = BITS_PER_BYTE * (ty.requestedAlignment(comp) orelse 0);
+        return .{
+            .size_bits = rec.type_layout.size_bits,
+            .pointer_alignment_bits = @max(requested, rec.type_layout.pointer_alignment_bits),
+            .field_alignment_bits = @max(requested, rec.type_layout.field_alignment_bits),
+            .required_alignment_bits = rec.type_layout.required_alignment_bits,
+        };
+    } else {
+        const type_align = ty.alignof(comp) * BITS_PER_BYTE;
+        return .{
+            .size_bits = ty.bitSizeof(comp) orelse 0,
+            .pointer_alignment_bits = type_align,
+            .field_alignment_bits = type_align,
+            .required_alignment_bits = BITS_PER_BYTE,
+        };
+    }
+}
+
+fn isPacked(attrs: ?[]const Attribute) bool {
+    const a = attrs orelse return false;
+
+    for (a) |attribute| {
+        if (attribute.tag != .@"packed") continue;
+        return true;
+    }
+    return false;
+}
+
+// The effect of #pragma pack(N) depends on the target.
+//
+// x86: By default, there is no maximum field alignment. N={1,2,4} set the maximum field
+//      alignment to that value. All other N activate the default.
+// x64: By default, there is no maximum field alignment. N={1,2,4,8} set the maximum field
+//      alignment to that value. All other N activate the default.
+// arm: By default, the maximum field alignment is 8. N={1,2,4,8,16} set the maximum field
+//      alignment to that value. All other N activate the default.
+// arm64: By default, the maximum field alignment is 8. N={1,2,4,8} set the maximum field
+//        alignment to that value. N=16 disables the maximum field alignment. All other N
+//        activate the default.
+//
+// See test case 0020.
+pub fn msvcPragmaPack(comp: *const Compilation, pack: u32) ?u32 {
+    return switch (pack) {
+        8, 16, 32 => pack,
+        64 => if (comp.target.cpu.arch == .x86) null else pack,
+        128 => if (comp.target.cpu.arch == .thumb) pack else null,
+        else => {
+            return switch (comp.target.cpu.arch) {
+                .thumb, .aarch64 => 64,
+                else => null,
+            };
+        },
+    };
+}
deps/aro/Source.zig
@@ -0,0 +1,125 @@
+const std = @import("std");
+const Source = @This();
+
+pub const Id = enum(u32) {
+    unused = 0,
+    generated = 1,
+    _,
+};
+
+pub const Location = struct {
+    id: Id = .unused,
+    byte_offset: u32 = 0,
+    line: u32 = 0,
+
+    pub fn eql(a: Location, b: Location) bool {
+        return a.id == b.id and a.byte_offset == b.byte_offset and a.line == b.line;
+    }
+};
+
+path: []const u8,
+buf: []const u8,
+id: Id,
+/// each entry represents a byte position within `buf` where a backslash+newline was deleted
+/// from the original raw buffer. The same position can appear multiple times if multiple
+/// consecutive splices happened. Guaranteed to be non-decreasing
+splice_locs: []const u32,
+
+/// Todo: binary search instead of scanning entire `splice_locs`.
+pub fn numSplicesBefore(source: Source, byte_offset: u32) u32 {
+    for (source.splice_locs, 0..) |splice_offset, i| {
+        if (splice_offset > byte_offset) return @intCast(i);
+    }
+    return @intCast(source.splice_locs.len);
+}
+
+/// Returns the actual line number (before newline splicing) of a Location
+/// This corresponds to what the user would actually see in their text editor
+pub fn physicalLine(source: Source, loc: Location) u32 {
+    return loc.line + source.numSplicesBefore(loc.byte_offset);
+}
+
+const LineCol = struct { line: []const u8, line_no: u32, col: u32, width: u32, end_with_splice: bool };
+
+pub fn lineCol(source: Source, loc: Location) LineCol {
+    var start: usize = 0;
+    // find the start of the line which is either a newline or a splice
+    if (std.mem.lastIndexOfScalar(u8, source.buf[0..loc.byte_offset], '\n')) |some| start = some + 1;
+    const splice_index: u32 = for (source.splice_locs, 0..) |splice_offset, i| {
+        if (splice_offset > start) {
+            if (splice_offset < loc.byte_offset) {
+                start = splice_offset;
+                break @as(u32, @intCast(i)) + 1;
+            }
+            break @intCast(i);
+        }
+    } else @intCast(source.splice_locs.len);
+    var i: usize = start;
+    var col: u32 = 1;
+    var width: u32 = 0;
+
+    while (i < loc.byte_offset) : (col += 1) { // TODO this is still incorrect, but better
+        const len = std.unicode.utf8ByteSequenceLength(source.buf[i]) catch unreachable;
+        const cp = std.unicode.utf8Decode(source.buf[i..][0..len]) catch unreachable;
+        width += codepointWidth(cp);
+        i += len;
+    }
+
+    // find the end of the line which is either a newline, EOF or a splice
+    var nl = source.buf.len;
+    var end_with_splice = false;
+    if (std.mem.indexOfScalar(u8, source.buf[start..], '\n')) |some| nl = some + start;
+    if (source.splice_locs.len > splice_index and nl > source.splice_locs[splice_index] and source.splice_locs[splice_index] > start) {
+        end_with_splice = true;
+        nl = source.splice_locs[splice_index];
+    }
+    return .{
+        .line = source.buf[start..nl],
+        .line_no = loc.line + splice_index,
+        .col = col,
+        .width = width,
+        .end_with_splice = end_with_splice,
+    };
+}
+
+fn codepointWidth(cp: u32) u32 {
+    return switch (cp) {
+        0x1100...0x115F,
+        0x2329,
+        0x232A,
+        0x2E80...0x303F,
+        0x3040...0x3247,
+        0x3250...0x4DBF,
+        0x4E00...0xA4C6,
+        0xA960...0xA97C,
+        0xAC00...0xD7A3,
+        0xF900...0xFAFF,
+        0xFE10...0xFE19,
+        0xFE30...0xFE6B,
+        0xFF01...0xFF60,
+        0xFFE0...0xFFE6,
+        0x1B000...0x1B001,
+        0x1F200...0x1F251,
+        0x20000...0x3FFFD,
+        0x1F300...0x1F5FF,
+        0x1F900...0x1F9FF,
+        => 2,
+        else => 1,
+    };
+}
+
+/// Returns the first offset, if any, in buf where an invalid utf8 sequence
+/// is found. Code adapted from std.unicode.utf8ValidateSlice
+pub fn offsetOfInvalidUtf8(self: Source) ?u32 {
+    const buf = self.buf;
+    std.debug.assert(buf.len <= std.math.maxInt(u32));
+    var i: u32 = 0;
+    while (i < buf.len) {
+        if (std.unicode.utf8ByteSequenceLength(buf[i])) |cp_len| {
+            if (i + cp_len > buf.len) return i;
+            if (std.meta.isError(std.unicode.utf8Decode(buf[i .. i + cp_len]))) return i;
+            i += cp_len;
+        } else |_| return i;
+    }
+    return null;
+}
deps/aro/StringInterner.zig
@@ -0,0 +1,78 @@
+const std = @import("std");
+const mem = std.mem;
+
+const StringInterner = @This();
+
+const StringToIdMap = std.StringHashMapUnmanaged(StringId);
+
+pub const StringId = enum(u32) {
+    empty,
+    _,
+};
+
+pub const TypeMapper = struct {
+    const LookupSpeed = enum {
+        fast,
+        slow,
+    };
+
+    data: union(LookupSpeed) {
+        fast: []const []const u8,
+        slow: *const StringToIdMap,
+    },
+
+    pub fn lookup(self: TypeMapper, string_id: StringInterner.StringId) []const u8 {
+        if (string_id == .empty) return "";
+        switch (self.data) {
+            .fast => |arr| return arr[@intFromEnum(string_id)],
+            .slow => |map| {
+                var it = map.iterator();
+                while (it.next()) |entry| {
+                    if (entry.value_ptr.* == string_id) return entry.key_ptr.*;
+                }
+                unreachable;
+            },
+        }
+    }
+
+    pub fn deinit(self: TypeMapper, allocator: mem.Allocator) void {
+        switch (self.data) {
+            .slow => {},
+            .fast => |arr| allocator.free(arr),
+        }
+    }
+};
+
+string_table: StringToIdMap = .{},
+next_id: StringId = @enumFromInt(@intFromEnum(StringId.empty) + 1),
+
+pub fn deinit(self: *StringInterner, allocator: mem.Allocator) void {
+    self.string_table.deinit(allocator);
+}
+
+pub fn intern(self: *StringInterner, allocator: mem.Allocator, str: []const u8) !StringId {
+    if (str.len == 0) return .empty;
+
+    const gop = try self.string_table.getOrPut(allocator, str);
+    if (gop.found_existing) return gop.value_ptr.*;
+
+    defer self.next_id = @enumFromInt(@intFromEnum(self.next_id) + 1);
+    gop.value_ptr.* = self.next_id;
+    return self.next_id;
+}
+
+/// deinit for the returned TypeMapper is a no-op and does not need to be called
+pub fn getSlowTypeMapper(self: *const StringInterner) TypeMapper {
+    return TypeMapper{ .data = .{ .slow = &self.string_table } };
+}
+
+/// Caller must call `deinit` on the returned TypeMapper
+pub fn getFastTypeMapper(self: *const StringInterner, allocator: mem.Allocator) !TypeMapper {
+    var strings = try allocator.alloc([]const u8, @intFromEnum(self.next_id));
+    var it = self.string_table.iterator();
+    strings[0] = "";
+    while (it.next()) |entry| {
+        strings[@intFromEnum(entry.value_ptr.*)] = entry.key_ptr.*;
+    }
+    return TypeMapper{ .data = .{ .fast = strings } };
+}
deps/aro/SymbolStack.zig
@@ -0,0 +1,375 @@
+const std = @import("std");
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const assert = std.debug.assert;
+const Tree = @import("Tree.zig");
+const Token = Tree.Token;
+const TokenIndex = Tree.TokenIndex;
+const NodeIndex = Tree.NodeIndex;
+const Type = @import("Type.zig");
+const Parser = @import("Parser.zig");
+const Value = @import("Value.zig");
+const StringId = @import("StringInterner.zig").StringId;
+
+const SymbolStack = @This();
+
+pub const Symbol = struct {
+    name: StringId,
+    ty: Type,
+    tok: TokenIndex,
+    node: NodeIndex = .none,
+    kind: Kind,
+    val: Value,
+};
+
+pub const Kind = enum {
+    typedef,
+    @"struct",
+    @"union",
+    @"enum",
+    decl,
+    def,
+    enumeration,
+    constexpr,
+};
+
+syms: std.MultiArrayList(Symbol) = .{},
+scopes: std.ArrayListUnmanaged(u32) = .{},
+
+pub fn deinit(s: *SymbolStack, gpa: Allocator) void {
+    s.syms.deinit(gpa);
+    s.scopes.deinit(gpa);
+    s.* = undefined;
+}
+
+pub fn scopeEnd(s: SymbolStack) u32 {
+    if (s.scopes.items.len == 0) return 0;
+    return s.scopes.items[s.scopes.items.len - 1];
+}
+
+pub fn pushScope(s: *SymbolStack, p: *Parser) !void {
+    try s.scopes.append(p.pp.comp.gpa, @intCast(s.syms.len));
+}
+
+pub fn popScope(s: *SymbolStack) void {
+    s.syms.len = s.scopes.pop();
+}
+
+pub fn findTypedef(s: *SymbolStack, p: *Parser, name: StringId, name_tok: TokenIndex, no_type_yet: bool) !?Symbol {
+    const kinds = s.syms.items(.kind);
+    const names = s.syms.items(.name);
+    var i = s.syms.len;
+    while (i > 0) {
+        i -= 1;
+        switch (kinds[i]) {
+            .typedef => if (names[i] == name) return s.syms.get(i),
+            .@"struct" => if (names[i] == name) {
+                if (no_type_yet) return null;
+                try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok));
+                return s.syms.get(i);
+            },
+            .@"union" => if (names[i] == name) {
+                if (no_type_yet) return null;
+                try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok));
+                return s.syms.get(i);
+            },
+            .@"enum" => if (names[i] == name) {
+                if (no_type_yet) return null;
+                try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok));
+                return s.syms.get(i);
+            },
+            .def, .decl, .constexpr => if (names[i] == name) return null,
+            else => {},
+        }
+    }
+    return null;
+}
+
+pub fn findSymbol(s: *SymbolStack, name: StringId) ?Symbol {
+    const kinds = s.syms.items(.kind);
+    const names = s.syms.items(.name);
+    var i = s.syms.len;
+    while (i > 0) {
+        i -= 1;
+        switch (kinds[i]) {
+            .def, .decl, .enumeration, .constexpr => if (names[i] == name) return s.syms.get(i),
+            else => {},
+        }
+    }
+    return null;
+}
+
+pub fn findTag(
+    s: *SymbolStack,
+    p: *Parser,
+    name: StringId,
+    kind: Token.Id,
+    name_tok: TokenIndex,
+    next_tok_id: Token.Id,
+) !?Symbol {
+    const kinds = s.syms.items(.kind);
+    const names = s.syms.items(.name);
+    // `tag Name;` should always result in a new type if in a new scope.
+    const end = if (next_tok_id == .semicolon) s.scopeEnd() else 0;
+    var i = s.syms.len;
+    while (i > end) {
+        i -= 1;
+        switch (kinds[i]) {
+            .@"enum" => if (names[i] == name) {
+                if (kind == .keyword_enum) return s.syms.get(i);
+                break;
+            },
+            .@"struct" => if (names[i] == name) {
+                if (kind == .keyword_struct) return s.syms.get(i);
+                break;
+            },
+            .@"union" => if (names[i] == name) {
+                if (kind == .keyword_union) return s.syms.get(i);
+                break;
+            },
+            else => {},
+        }
+    } else return null;
+
+    if (i < s.scopeEnd()) return null;
+    try p.errStr(.wrong_tag, name_tok, p.tokSlice(name_tok));
+    try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+    return null;
+}
+
+pub fn defineTypedef(
+    s: *SymbolStack,
+    p: *Parser,
+    name: StringId,
+    ty: Type,
+    tok: TokenIndex,
+    node: NodeIndex,
+) !void {
+    const kinds = s.syms.items(.kind);
+    const names = s.syms.items(.name);
+    const end = s.scopeEnd();
+    var i = s.syms.len;
+    while (i > end) {
+        i -= 1;
+        switch (kinds[i]) {
+            .typedef => if (names[i] == name) {
+                const prev_ty = s.syms.items(.ty)[i];
+                if (ty.eql(prev_ty, p.pp.comp, true)) break;
+                try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev_ty));
+                const previous_tok = s.syms.items(.tok)[i];
+                if (previous_tok != 0) try p.errTok(.previous_definition, previous_tok);
+                break;
+            },
+            else => {},
+        }
+    }
+    try s.syms.append(p.pp.comp.gpa, .{
+        .kind = .typedef,
+        .name = name,
+        .tok = tok,
+        .ty = ty,
+        .node = node,
+        .val = .{},
+    });
+}
+
+pub fn defineSymbol(
+    s: *SymbolStack,
+    p: *Parser,
+    name: StringId,
+    ty: Type,
+    tok: TokenIndex,
+    node: NodeIndex,
+    val: Value,
+    constexpr: bool,
+) !void {
+    const kinds = s.syms.items(.kind);
+    const names = s.syms.items(.name);
+    const end = s.scopeEnd();
+    var i = s.syms.len;
+    while (i > end) {
+        i -= 1;
+        switch (kinds[i]) {
+            .enumeration => if (names[i] == name) {
+                try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                break;
+            },
+            .decl => if (names[i] == name) {
+                const prev_ty = s.syms.items(.ty)[i];
+                if (!ty.eql(prev_ty, p.pp.comp, true)) { // TODO adjusted equality check
+                    try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
+                    try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                }
+                break;
+            },
+            .def, .constexpr => if (names[i] == name) {
+                try p.errStr(.redefinition, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                break;
+            },
+            else => {},
+        }
+    }
+    try s.syms.append(p.pp.comp.gpa, .{
+        .kind = if (constexpr) .constexpr else .def,
+        .name = name,
+        .tok = tok,
+        .ty = ty,
+        .node = node,
+        .val = val,
+    });
+}
+
+pub fn declareSymbol(
+    s: *SymbolStack,
+    p: *Parser,
+    name: StringId,
+    ty: Type,
+    tok: TokenIndex,
+    node: NodeIndex,
+) !void {
+    const kinds = s.syms.items(.kind);
+    const names = s.syms.items(.name);
+    const end = s.scopeEnd();
+    var i = s.syms.len;
+    while (i > end) {
+        i -= 1;
+        switch (kinds[i]) {
+            .enumeration => if (names[i] == name) {
+                try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                break;
+            },
+            .decl => if (names[i] == name) {
+                const prev_ty = s.syms.items(.ty)[i];
+                if (!ty.eql(prev_ty, p.pp.comp, true)) { // TODO adjusted equality check
+                    try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
+                    try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                }
+                break;
+            },
+            .def, .constexpr => if (names[i] == name) {
+                const prev_ty = s.syms.items(.ty)[i];
+                if (!ty.eql(prev_ty, p.pp.comp, true)) { // TODO adjusted equality check
+                    try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
+                    try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                    break;
+                }
+                return;
+            },
+            else => {},
+        }
+    }
+    try s.syms.append(p.pp.comp.gpa, .{
+        .kind = .decl,
+        .name = name,
+        .tok = tok,
+        .ty = ty,
+        .node = node,
+        .val = .{},
+    });
+}
+
+pub fn defineParam(s: *SymbolStack, p: *Parser, name: StringId, ty: Type, tok: TokenIndex) !void {
+    const kinds = s.syms.items(.kind);
+    const names = s.syms.items(.name);
+    const end = s.scopeEnd();
+    var i = s.syms.len;
+    while (i > end) {
+        i -= 1;
+        switch (kinds[i]) {
+            .enumeration, .decl, .def, .constexpr => if (names[i] == name) {
+                try p.errStr(.redefinition_of_parameter, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                break;
+            },
+            else => {},
+        }
+    }
+    if (ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
+        try p.errStr(.suggest_pointer_for_invalid_fp16, tok, "parameters");
+    }
+    try s.syms.append(p.pp.comp.gpa, .{
+        .kind = .def,
+        .name = name,
+        .tok = tok,
+        .ty = ty,
+        .val = .{},
+    });
+}
+
+pub fn defineTag(
+    s: *SymbolStack,
+    p: *Parser,
+    name: StringId,
+    kind: Token.Id,
+    tok: TokenIndex,
+) !?Symbol {
+    const kinds = s.syms.items(.kind);
+    const names = s.syms.items(.name);
+    const end = s.scopeEnd();
+    var i = s.syms.len;
+    while (i > end) {
+        i -= 1;
+        switch (kinds[i]) {
+            .@"enum" => if (names[i] == name) {
+                if (kind == .keyword_enum) return s.syms.get(i);
+                try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                return null;
+            },
+            .@"struct" => if (names[i] == name) {
+                if (kind == .keyword_struct) return s.syms.get(i);
+                try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                return null;
+            },
+            .@"union" => if (names[i] == name) {
+                if (kind == .keyword_union) return s.syms.get(i);
+                try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                return null;
+            },
+            else => {},
+        }
+    }
+    return null;
+}
+
+pub fn defineEnumeration(
+    s: *SymbolStack,
+    p: *Parser,
+    name: StringId,
+    ty: Type,
+    tok: TokenIndex,
+    val: Value,
+) !void {
+    const kinds = s.syms.items(.kind);
+    const names = s.syms.items(.name);
+    const end = s.scopeEnd();
+    var i = s.syms.len;
+    while (i > end) {
+        i -= 1;
+        switch (kinds[i]) {
+            .enumeration => if (names[i] == name) {
+                try p.errStr(.redefinition, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                return;
+            },
+            .decl, .def, .constexpr => if (names[i] == name) {
+                try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
+                try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
+                return;
+            },
+            else => {},
+        }
+    }
+    try s.syms.append(p.pp.comp.gpa, .{
+        .kind = .enumeration,
+        .name = name,
+        .tok = tok,
+        .ty = ty,
+        .val = val,
+    });
+}
deps/aro/target.zig
@@ -0,0 +1,810 @@
+const std = @import("std");
+const LangOpts = @import("LangOpts.zig");
+const Type = @import("Type.zig");
+const llvm = @import("zig").codegen.llvm;
+const TargetSet = @import("builtins/Properties.zig").TargetSet;
+
+/// intmax_t for this target
+pub fn intMaxType(target: std.Target) Type {
+    switch (target.cpu.arch) {
+        .aarch64,
+        .aarch64_be,
+        .sparc64,
+        => if (target.os.tag != .openbsd) return .{ .specifier = .long },
+
+        .bpfel,
+        .bpfeb,
+        .loongarch64,
+        .riscv64,
+        .powerpc64,
+        .powerpc64le,
+        .tce,
+        .tcele,
+        .ve,
+        => return .{ .specifier = .long },
+
+        .x86_64 => switch (target.os.tag) {
+            .windows, .openbsd => {},
+            else => switch (target.abi) {
+                .gnux32, .muslx32 => {},
+                else => return .{ .specifier = .long },
+            },
+        },
+
+        else => {},
+    }
+    return .{ .specifier = .long_long };
+}
+
+/// intptr_t for this target
+pub fn intPtrType(target: std.Target) Type {
+    switch (target.os.tag) {
+        .haiku => return .{ .specifier = .long },
+        .nacl => return .{ .specifier = .int },
+        else => {},
+    }
+
+    switch (target.cpu.arch) {
+        .aarch64, .aarch64_be => switch (target.os.tag) {
+            .windows => return .{ .specifier = .long_long },
+            else => {},
+        },
+
+        .msp430,
+        .csky,
+        .loongarch32,
+        .riscv32,
+        .xcore,
+        .hexagon,
+        .tce,
+        .tcele,
+        .m68k,
+        .spir,
+        .spirv32,
+        .arc,
+        .avr,
+        => return .{ .specifier = .int },
+
+        .sparc, .sparcel => switch (target.os.tag) {
+            .netbsd, .openbsd => {},
+            else => return .{ .specifier = .int },
+        },
+
+        .powerpc, .powerpcle => switch (target.os.tag) {
+            .linux, .freebsd, .netbsd => return .{ .specifier = .int },
+            else => {},
+        },
+
+        // 32-bit x86 Darwin, OpenBSD, and RTEMS use long (the default); others use int
+        .x86 => switch (target.os.tag) {
+            .openbsd, .rtems => {},
+            else => if (!target.os.tag.isDarwin()) return .{ .specifier = .int },
+        },
+
+        .x86_64 => switch (target.os.tag) {
+            .windows => return .{ .specifier = .long_long },
+            else => switch (target.abi) {
+                .gnux32, .muslx32 => return .{ .specifier = .int },
+                else => {},
+            },
+        },
+
+        else => {},
+    }
+
+    return .{ .specifier = .long };
+}
+
+/// int16_t for this target
+pub fn int16Type(target: std.Target) Type {
+    return switch (target.cpu.arch) {
+        .avr => .{ .specifier = .int },
+        else => .{ .specifier = .short },
+    };
+}
+
+/// int64_t for this target
+pub fn int64Type(target: std.Target) Type {
+    switch (target.cpu.arch) {
+        .loongarch64,
+        .ve,
+        .riscv64,
+        .powerpc64,
+        .powerpc64le,
+        .bpfel,
+        .bpfeb,
+        => return .{ .specifier = .long },
+
+        .sparc64 => return intMaxType(target),
+
+        .x86, .x86_64 => if (!target.isDarwin()) return intMaxType(target),
+        .aarch64, .aarch64_be => if (!target.isDarwin() and target.os.tag != .openbsd and target.os.tag != .windows) return .{ .specifier = .long },
+        else => {},
+    }
+    return .{ .specifier = .long_long };
+}
+
+/// This function returns 1 if function alignment is not observable or settable.
+pub fn defaultFunctionAlignment(target: std.Target) u8 {
+    return switch (target.cpu.arch) {
+        .arm, .armeb => 4,
+        .aarch64, .aarch64_32, .aarch64_be => 4,
+        .sparc, .sparcel, .sparc64 => 4,
+        .riscv64 => 2,
+        else => 1,
+    };
+}
+
+pub fn isTlsSupported(target: std.Target) bool {
+    if (target.isDarwin()) {
+        var supported = false;
+        switch (target.os.tag) {
+            .macos => supported = !(target.os.isAtLeast(.macos, .{ .major = 10, .minor = 7, .patch = 0 }) orelse false),
+            else => {},
+        }
+        return supported;
+    }
+    return switch (target.cpu.arch) {
+        .tce, .tcele, .bpfel, .bpfeb, .msp430, .nvptx, .nvptx64, .x86, .arm, .armeb, .thumb, .thumbeb => false,
+        else => true,
+    };
+}
+
+pub fn ignoreNonZeroSizedBitfieldTypeAlignment(target: std.Target) bool {
+    switch (target.cpu.arch) {
+        .avr => return true,
+        .arm => {
+            if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
+                switch (target.os.tag) {
+                    .ios => return true,
+                    else => return false,
+                }
+            }
+        },
+        else => return false,
+    }
+    return false;
+}
+
+pub fn ignoreZeroSizedBitfieldTypeAlignment(target: std.Target) bool {
+    switch (target.cpu.arch) {
+        .avr => return true,
+        else => return false,
+    }
+}
+
+pub fn minZeroWidthBitfieldAlignment(target: std.Target) ?u29 {
+    switch (target.cpu.arch) {
+        .avr => return 8,
+        .arm => {
+            if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
+                switch (target.os.tag) {
+                    .ios => return 32,
+                    else => return null,
+                }
+            } else return null;
+        },
+        else => return null,
+    }
+}
+
+pub fn unnamedFieldAffectsAlignment(target: std.Target) bool {
+    switch (target.cpu.arch) {
+        .aarch64 => {
+            if (target.isDarwin() or target.os.tag == .windows) return false;
+            return true;
+        },
+        .armeb => {
+            if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
+                if (std.Target.Abi.default(target.cpu.arch, target.os) == .eabi) return true;
+            }
+        },
+        .arm => return true,
+        .avr => return true,
+        .thumb => {
+            if (target.os.tag == .windows) return false;
+            return true;
+        },
+        else => return false,
+    }
+    return false;
+}
+
+pub fn packAllEnums(target: std.Target) bool {
+    return switch (target.cpu.arch) {
+        .hexagon => true,
+        else => false,
+    };
+}
+
+/// Default alignment (in bytes) for __attribute__((aligned)) when no alignment is specified
+pub fn defaultAlignment(target: std.Target) u29 {
+    switch (target.cpu.arch) {
+        .avr => return 1,
+        .arm => if (target.isAndroid() or target.os.tag == .ios) return 16 else return 8,
+        .sparc => if (std.Target.sparc.featureSetHas(target.cpu.features, .v9)) return 16 else return 8,
+        .mips, .mipsel => switch (target.abi) {
+            .none, .gnuabi64 => return 16,
+            else => return 8,
+        },
+        .s390x, .armeb, .thumbeb, .thumb => return 8,
+        else => return 16,
+    }
+}
+pub fn systemCompiler(target: std.Target) LangOpts.Compiler {
+    // Android is linux but not gcc, so these checks go first
+    // the rest for documentation as fn returns .clang
+    if (target.isDarwin() or
+        target.isAndroid() or
+        target.isBSD() or
+        target.os.tag == .fuchsia or
+        target.os.tag == .solaris or
+        target.os.tag == .haiku or
+        target.cpu.arch == .hexagon)
+    {
+        return .clang;
+    }
+    if (target.os.tag == .uefi) return .msvc;
+    // this is before windows to grab WindowsGnu
+    if (target.abi.isGnu() or
+        target.os.tag == .linux)
+    {
+        return .gcc;
+    }
+    if (target.os.tag == .windows) {
+        return .msvc;
+    }
+    if (target.cpu.arch == .avr) return .gcc;
+    return .clang;
+}
+
+pub fn hasInt128(target: std.Target) bool {
+    if (target.cpu.arch == .wasm32) return true;
+    if (target.cpu.arch == .x86_64) return true;
+    return target.ptrBitWidth() >= 64;
+}
+
+pub fn hasHalfPrecisionFloatABI(target: std.Target) bool {
+    return switch (target.cpu.arch) {
+        .thumb, .thumbeb, .arm, .aarch64 => true,
+        else => false,
+    };
+}
+
+pub const FPSemantics = enum {
+    None,
+    IEEEHalf,
+    BFloat,
+    IEEESingle,
+    IEEEDouble,
+    IEEEQuad,
+    /// Minifloat 5-bit exponent 2-bit mantissa
+    E5M2,
+    /// Minifloat 4-bit exponent 3-bit mantissa
+    E4M3,
+    x87ExtendedDouble,
+    IBMExtendedDouble,
+
+    /// Only intended for generating float.h macros for the preprocessor
+    pub fn forType(ty: std.Target.CType, target: std.Target) FPSemantics {
+        std.debug.assert(ty == .float or ty == .double or ty == .longdouble);
+        return switch (target.c_type_bit_size(ty)) {
+            32 => .IEEESingle,
+            64 => .IEEEDouble,
+            80 => .x87ExtendedDouble,
+            128 => switch (target.cpu.arch) {
+                .powerpc, .powerpcle, .powerpc64, .powerpc64le => .IBMExtendedDouble,
+                else => .IEEEQuad,
+            },
+            else => unreachable,
+        };
+    }
+
+    pub fn halfPrecisionType(target: std.Target) ?FPSemantics {
+        switch (target.cpu.arch) {
+            .aarch64,
+            .aarch64_32,
+            .aarch64_be,
+            .arm,
+            .armeb,
+            .hexagon,
+            .riscv32,
+            .riscv64,
+            .spirv32,
+            .spirv64,
+            => return .IEEEHalf,
+            .x86, .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .sse2)) return .IEEEHalf,
+            else => {},
+        }
+        return null;
+    }
+
+    pub fn chooseValue(self: FPSemantics, comptime T: type, values: [6]T) T {
+        return switch (self) {
+            .IEEEHalf => values[0],
+            .IEEESingle => values[1],
+            .IEEEDouble => values[2],
+            .x87ExtendedDouble => values[3],
+            .IBMExtendedDouble => values[4],
+            .IEEEQuad => values[5],
+            else => unreachable,
+        };
+    }
+};
+
+pub fn isLP64(target: std.Target) bool {
+    return target.c_type_bit_size(.int) == 32 and target.ptrBitWidth() == 64;
+}
+
+pub fn isKnownWindowsMSVCEnvironment(target: std.Target) bool {
+    return target.os.tag == .windows and target.abi == .msvc;
+}
+
+pub fn isWindowsMSVCEnvironment(target: std.Target) bool {
+    return target.os.tag == .windows and (target.abi == .msvc or target.abi == .none);
+}
+
+pub fn isCygwinMinGW(target: std.Target) bool {
+    return target.os.tag == .windows and (target.abi == .gnu or target.abi == .cygnus);
+}
+
+pub fn builtinEnabled(target: std.Target, enabled_for: TargetSet) bool {
+    var copy = enabled_for;
+    var it = copy.iterator();
+    while (it.next()) |val| {
+        switch (val) {
+            .basic => return true,
+            .x86_64 => if (target.cpu.arch == .x86_64) return true,
+            .aarch64 => if (target.cpu.arch == .aarch64) return true,
+            .arm => if (target.cpu.arch == .arm) return true,
+            .ppc => switch (target.cpu.arch) {
+                .powerpc, .powerpc64, .powerpc64le => return true,
+                else => {},
+            },
+            else => {
+                // Todo: handle other target predicates
+            },
+        }
+    }
+    return false;
+}
+
+pub fn defaultFpEvalMethod(target: std.Target) LangOpts.FPEvalMethod {
+    if (target.os.tag == .aix) return .double;
+    switch (target.cpu.arch) {
+        .x86, .x86_64 => {
+            if (target.ptrBitWidth() == 32 and target.os.tag == .netbsd) {
+                if (target.os.version_range.semver.min.order(.{ .major = 6, .minor = 99, .patch = 26 }) != .gt) {
+                    // NETBSD <= 6.99.26 on 32-bit x86 defaults to double
+                    return .double;
+                }
+            }
+            if (std.Target.x86.featureSetHas(target.cpu.features, .sse)) {
+                return .source;
+            }
+            return .extended;
+        },
+        else => {},
+    }
+    return .source;
+}
+
+/// Value of the `-m` flag for `ld` for this target
+pub fn ldEmulationOption(target: std.Target, arm_endianness: ?std.builtin.Endian) ?[]const u8 {
+    return switch (target.cpu.arch) {
+        .x86 => if (target.os.tag == .elfiamcu) "elf_iamcu" else "elf_i386",
+        .arm,
+        .armeb,
+        .thumb,
+        .thumbeb,
+        => switch (arm_endianness orelse target.cpu.arch.endian()) {
+            .Little => "armelf_linux_eabi",
+            .Big => "armelfb_linux_eabi",
+        },
+        .aarch64 => "aarch64linux",
+        .aarch64_be => "aarch64linuxb",
+        .m68k => "m68kelf",
+        .powerpc => if (target.os.tag == .linux) "elf32ppclinux" else "elf32ppc",
+        .powerpcle => if (target.os.tag == .linux) "elf32lppclinux" else "elf32lppc",
+        .powerpc64 => "elf64ppc",
+        .powerpc64le => "elf64lppc",
+        .riscv32 => "elf32lriscv",
+        .riscv64 => "elf64lriscv",
+        .sparc, .sparcel => "elf32_sparc",
+        .sparc64 => "elf64_sparc",
+        .loongarch32 => "elf32loongarch",
+        .loongarch64 => "elf64loongarch",
+        .mips => "elf32btsmip",
+        .mipsel => "elf32ltsmip",
+        .mips64 => if (target.abi == .gnuabin32) "elf32btsmipn32" else "elf64btsmip",
+        .mips64el => if (target.abi == .gnuabin32) "elf32ltsmipn32" else "elf64ltsmip",
+        .x86_64 => if (target.abi == .gnux32 or target.abi == .muslx32) "elf32_x86_64" else "elf_x86_64",
+        .ve => "elf64ve",
+        .csky => "cskyelf_linux",
+        else => null,
+    };
+}
+
+pub fn get32BitArchVariant(target: std.Target) ?std.Target {
+    var copy = target;
+    switch (target.cpu.arch) {
+        .amdgcn,
+        .avr,
+        .msp430,
+        .spu_2,
+        .ve,
+        .bpfel,
+        .bpfeb,
+        .s390x,
+        => return null,
+
+        .arc,
+        .arm,
+        .armeb,
+        .csky,
+        .hexagon,
+        .m68k,
+        .le32,
+        .mips,
+        .mipsel,
+        .powerpc,
+        .powerpcle,
+        .r600,
+        .riscv32,
+        .sparc,
+        .sparcel,
+        .tce,
+        .tcele,
+        .thumb,
+        .thumbeb,
+        .x86,
+        .xcore,
+        .nvptx,
+        .amdil,
+        .hsail,
+        .spir,
+        .kalimba,
+        .shave,
+        .lanai,
+        .wasm32,
+        .renderscript32,
+        .aarch64_32,
+        .spirv32,
+        .loongarch32,
+        .dxil,
+        .xtensa,
+        => {}, // Already 32 bit
+
+        .aarch64 => copy.cpu.arch = .arm,
+        .aarch64_be => copy.cpu.arch = .armeb,
+        .le64 => copy.cpu.arch = .le32,
+        .amdil64 => copy.cpu.arch = .amdil,
+        .nvptx64 => copy.cpu.arch = .nvptx,
+        .wasm64 => copy.cpu.arch = .wasm32,
+        .hsail64 => copy.cpu.arch = .hsail,
+        .spir64 => copy.cpu.arch = .spir,
+        .spirv64 => copy.cpu.arch = .spirv32,
+        .renderscript64 => copy.cpu.arch = .renderscript32,
+        .loongarch64 => copy.cpu.arch = .loongarch32,
+        .mips64 => copy.cpu.arch = .mips,
+        .mips64el => copy.cpu.arch = .mipsel,
+        .powerpc64 => copy.cpu.arch = .powerpc,
+        .powerpc64le => copy.cpu.arch = .powerpcle,
+        .riscv64 => copy.cpu.arch = .riscv32,
+        .sparc64 => copy.cpu.arch = .sparc,
+        .x86_64 => copy.cpu.arch = .x86,
+    }
+    return copy;
+}
+
+pub fn get64BitArchVariant(target: std.Target) ?std.Target {
+    var copy = target;
+    switch (target.cpu.arch) {
+        .arc,
+        .avr,
+        .csky,
+        .dxil,
+        .hexagon,
+        .kalimba,
+        .lanai,
+        .m68k,
+        .msp430,
+        .r600,
+        .shave,
+        .sparcel,
+        .spu_2,
+        .tce,
+        .tcele,
+        .xcore,
+        .xtensa,
+        => return null,
+
+        .aarch64,
+        .aarch64_be,
+        .amdgcn,
+        .bpfeb,
+        .bpfel,
+        .le64,
+        .amdil64,
+        .nvptx64,
+        .wasm64,
+        .hsail64,
+        .spir64,
+        .spirv64,
+        .renderscript64,
+        .loongarch64,
+        .mips64,
+        .mips64el,
+        .powerpc64,
+        .powerpc64le,
+        .riscv64,
+        .s390x,
+        .sparc64,
+        .ve,
+        .x86_64,
+        => {}, // Already 64 bit
+
+        .aarch64_32 => copy.cpu.arch = .aarch64,
+        .amdil => copy.cpu.arch = .amdil64,
+        .arm => copy.cpu.arch = .aarch64,
+        .armeb => copy.cpu.arch = .aarch64_be,
+        .hsail => copy.cpu.arch = .hsail64,
+        .le32 => copy.cpu.arch = .le64,
+        .loongarch32 => copy.cpu.arch = .loongarch64,
+        .mips => copy.cpu.arch = .mips64,
+        .mipsel => copy.cpu.arch = .mips64el,
+        .nvptx => copy.cpu.arch = .nvptx64,
+        .powerpc => copy.cpu.arch = .powerpc64,
+        .powerpcle => copy.cpu.arch = .powerpc64le,
+        .renderscript32 => copy.cpu.arch = .renderscript64,
+        .riscv32 => copy.cpu.arch = .riscv64,
+        .sparc => copy.cpu.arch = .sparc64,
+        .spir => copy.cpu.arch = .spir64,
+        .spirv32 => copy.cpu.arch = .spirv64,
+        .thumb => copy.cpu.arch = .aarch64,
+        .thumbeb => copy.cpu.arch = .aarch64_be,
+        .wasm32 => copy.cpu.arch = .wasm64,
+        .x86 => copy.cpu.arch = .x86_64,
+    }
+    return copy;
+}
+
+/// Adapted from Zig's src/codegen/llvm.zig
+pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
+    // 64 bytes is assumed to be large enough to hold any target triple; increase if necessary
+    std.debug.assert(buf.len >= 64);
+
+    var stream = std.io.fixedBufferStream(buf);
+    const writer = stream.writer();
+
+    const llvm_arch = switch (target.cpu.arch) {
+        .arm => "arm",
+        .armeb => "armeb",
+        .aarch64 => "aarch64",
+        .aarch64_be => "aarch64_be",
+        .aarch64_32 => "aarch64_32",
+        .arc => "arc",
+        .avr => "avr",
+        .bpfel => "bpfel",
+        .bpfeb => "bpfeb",
+        .csky => "csky",
+        .dxil => "dxil",
+        .hexagon => "hexagon",
+        .loongarch32 => "loongarch32",
+        .loongarch64 => "loongarch64",
+        .m68k => "m68k",
+        .mips => "mips",
+        .mipsel => "mipsel",
+        .mips64 => "mips64",
+        .mips64el => "mips64el",
+        .msp430 => "msp430",
+        .powerpc => "powerpc",
+        .powerpcle => "powerpcle",
+        .powerpc64 => "powerpc64",
+        .powerpc64le => "powerpc64le",
+        .r600 => "r600",
+        .amdgcn => "amdgcn",
+        .riscv32 => "riscv32",
+        .riscv64 => "riscv64",
+        .sparc => "sparc",
+        .sparc64 => "sparc64",
+        .sparcel => "sparcel",
+        .s390x => "s390x",
+        .tce => "tce",
+        .tcele => "tcele",
+        .thumb => "thumb",
+        .thumbeb => "thumbeb",
+        .x86 => "i386",
+        .x86_64 => "x86_64",
+        .xcore => "xcore",
+        .xtensa => "xtensa",
+        .nvptx => "nvptx",
+        .nvptx64 => "nvptx64",
+        .le32 => "le32",
+        .le64 => "le64",
+        .amdil => "amdil",
+        .amdil64 => "amdil64",
+        .hsail => "hsail",
+        .hsail64 => "hsail64",
+        .spir => "spir",
+        .spir64 => "spir64",
+        .spirv32 => "spirv32",
+        .spirv64 => "spirv64",
+        .kalimba => "kalimba",
+        .shave => "shave",
+        .lanai => "lanai",
+        .wasm32 => "wasm32",
+        .wasm64 => "wasm64",
+        .renderscript32 => "renderscript32",
+        .renderscript64 => "renderscript64",
+        .ve => "ve",
+        // Note: spu_2 is not supported in LLVM; this is the Zig arch name
+        .spu_2 => "spu_2",
+    };
+    writer.writeAll(llvm_arch) catch unreachable;
+    writer.writeByte('-') catch unreachable;
+
+    const llvm_os = switch (target.os.tag) {
+        .freestanding => "unknown",
+        .ananas => "ananas",
+        .cloudabi => "cloudabi",
+        .dragonfly => "dragonfly",
+        .freebsd => "freebsd",
+        .fuchsia => "fuchsia",
+        .kfreebsd => "kfreebsd",
+        .linux => "linux",
+        .lv2 => "lv2",
+        .netbsd => "netbsd",
+        .openbsd => "openbsd",
+        .solaris => "solaris",
+        .windows => "windows",
+        .zos => "zos",
+        .haiku => "haiku",
+        .minix => "minix",
+        .rtems => "rtems",
+        .nacl => "nacl",
+        .aix => "aix",
+        .cuda => "cuda",
+        .nvcl => "nvcl",
+        .amdhsa => "amdhsa",
+        .ps4 => "ps4",
+        .ps5 => "ps5",
+        .elfiamcu => "elfiamcu",
+        .mesa3d => "mesa3d",
+        .contiki => "contiki",
+        .amdpal => "amdpal",
+        .hermit => "hermit",
+        .hurd => "hurd",
+        .wasi => "wasi",
+        .emscripten => "emscripten",
+        .uefi => "windows",
+        .macos => "macosx",
+        .ios => "ios",
+        .tvos => "tvos",
+        .watchos => "watchos",
+        .driverkit => "driverkit",
+        .shadermodel => "shadermodel",
+        .opencl,
+        .glsl450,
+        .vulkan,
+        .plan9,
+        .other,
+        => "unknown",
+    };
+    writer.writeAll(llvm_os) catch unreachable;
+
+    if (target.os.tag.isDarwin()) {
+        const min_version = target.os.version_range.semver.min;
+        writer.print("{d}.{d}.{d}", .{
+            min_version.major,
+            min_version.minor,
+            min_version.patch,
+        }) catch unreachable;
+    }
+    writer.writeByte('-') catch unreachable;
+
+    const llvm_abi = switch (target.abi) {
+        .none => "unknown",
+        .gnu => "gnu",
+        .gnuabin32 => "gnuabin32",
+        .gnuabi64 => "gnuabi64",
+        .gnueabi => "gnueabi",
+        .gnueabihf => "gnueabihf",
+        .gnuf32 => "gnuf32",
+        .gnuf64 => "gnuf64",
+        .gnusf => "gnusf",
+        .gnux32 => "gnux32",
+        .gnuilp32 => "gnuilp32",
+        .code16 => "code16",
+        .eabi => "eabi",
+        .eabihf => "eabihf",
+        .android => "android",
+        .musl => "musl",
+        .musleabi => "musleabi",
+        .musleabihf => "musleabihf",
+        .muslx32 => "muslx32",
+        .msvc => "msvc",
+        .itanium => "itanium",
+        .cygnus => "cygnus",
+        .coreclr => "coreclr",
+        .simulator => "simulator",
+        .macabi => "macabi",
+        .pixel => "pixel",
+        .vertex => "vertex",
+        .geometry => "geometry",
+        .hull => "hull",
+        .domain => "domain",
+        .compute => "compute",
+        .library => "library",
+        .raygeneration => "raygeneration",
+        .intersection => "intersection",
+        .anyhit => "anyhit",
+        .closesthit => "closesthit",
+        .miss => "miss",
+        .callable => "callable",
+        .mesh => "mesh",
+        .amplification => "amplification",
+    };
+    writer.writeAll(llvm_abi) catch unreachable;
+    return stream.getWritten();
+}
+
+test "alignment functions - smoke test" {
+    var target: std.Target = undefined;
+    const x86 = std.Target.Cpu.Arch.x86_64;
+    target.cpu = std.Target.Cpu.baseline(x86);
+    target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
+    target.abi = std.Target.Abi.default(x86, target.os);
+
+    try std.testing.expect(isTlsSupported(target));
+    try std.testing.expect(!ignoreNonZeroSizedBitfieldTypeAlignment(target));
+    try std.testing.expect(minZeroWidthBitfieldAlignment(target) == null);
+    try std.testing.expect(!unnamedFieldAffectsAlignment(target));
+    try std.testing.expect(defaultAlignment(target) == 16);
+    try std.testing.expect(!packAllEnums(target));
+    try std.testing.expect(systemCompiler(target) == .gcc);
+
+    const arm = std.Target.Cpu.Arch.arm;
+    target.cpu = std.Target.Cpu.baseline(arm);
+    target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
+    target.abi = std.Target.Abi.default(arm, target.os);
+
+    try std.testing.expect(!isTlsSupported(target));
+    try std.testing.expect(ignoreNonZeroSizedBitfieldTypeAlignment(target));
+    try std.testing.expectEqual(@as(?u29, 32), minZeroWidthBitfieldAlignment(target));
+    try std.testing.expect(unnamedFieldAffectsAlignment(target));
+    try std.testing.expect(defaultAlignment(target) == 16);
+    try std.testing.expect(!packAllEnums(target));
+    try std.testing.expect(systemCompiler(target) == .clang);
+}
+
+test "target size/align tests" {
+    var comp: @import("Compilation.zig") = undefined;
+
+    const x86 = std.Target.Cpu.Arch.x86;
+    comp.target.cpu.arch = x86;
+    comp.target.cpu.model = &std.Target.x86.cpu.i586;
+    comp.target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
+    comp.target.abi = std.Target.Abi.gnu;
+
+    const tt: Type = .{
+        .specifier = .long_long,
+    };
+
+    try std.testing.expectEqual(@as(u64, 8), tt.sizeof(&comp).?);
+    try std.testing.expectEqual(@as(u64, 4), tt.alignof(&comp));
+
+    const arm = std.Target.Cpu.Arch.arm;
+    comp.target.cpu = std.Target.Cpu.Model.toCpu(&std.Target.arm.cpu.cortex_r4, arm);
+    comp.target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
+    comp.target.abi = std.Target.Abi.none;
+
+    const ct: Type = .{
+        .specifier = .char,
+    };
+
+    try std.testing.expectEqual(true, std.Target.arm.featureSetHas(comp.target.cpu.features, .has_v7));
+    try std.testing.expectEqual(@as(u64, 1), ct.sizeof(&comp).?);
+    try std.testing.expectEqual(@as(u64, 1), ct.alignof(&comp));
+    try std.testing.expectEqual(true, ignoreNonZeroSizedBitfieldTypeAlignment(comp.target));
+}
deps/aro/Tokenizer.zig
@@ -0,0 +1,2140 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const Compilation = @import("Compilation.zig");
+const Source = @import("Source.zig");
+const LangOpts = @import("LangOpts.zig");
+const CharInfo = @import("CharInfo.zig");
+const unicode = @import("unicode.zig");
+
+const Tokenizer = @This();
+
+pub const Token = struct {
+    id: Id,
+    source: Source.Id,
+    start: u32 = 0,
+    end: u32 = 0,
+    line: u32 = 0,
+
+    pub const Id = enum(u8) {
+        invalid,
+        nl,
+        whitespace,
+        eof,
+        /// identifier containing solely basic character set characters
+        identifier,
+        /// identifier with at least one extended character
+        extended_identifier,
+
+        // string literals with prefixes
+        string_literal,
+        string_literal_utf_16,
+        string_literal_utf_8,
+        string_literal_utf_32,
+        string_literal_wide,
+
+        // <foobar> only generated by preprocessor
+        macro_string,
+
+        // char literals with prefixes
+        char_literal,
+        char_literal_utf_8,
+        char_literal_utf_16,
+        char_literal_utf_32,
+        char_literal_wide,
+
+        /// Integer literal tokens generated by preprocessor.
+        one,
+        zero,
+
+        bang,
+        bang_equal,
+        pipe,
+        pipe_pipe,
+        pipe_equal,
+        equal,
+        equal_equal,
+        l_paren,
+        r_paren,
+        l_brace,
+        r_brace,
+        l_bracket,
+        r_bracket,
+        period,
+        ellipsis,
+        caret,
+        caret_equal,
+        plus,
+        plus_plus,
+        plus_equal,
+        minus,
+        minus_minus,
+        minus_equal,
+        asterisk,
+        asterisk_equal,
+        percent,
+        percent_equal,
+        arrow,
+        colon,
+        colon_colon,
+        semicolon,
+        slash,
+        slash_equal,
+        comma,
+        ampersand,
+        ampersand_ampersand,
+        ampersand_equal,
+        question_mark,
+        angle_bracket_left,
+        angle_bracket_left_equal,
+        angle_bracket_angle_bracket_left,
+        angle_bracket_angle_bracket_left_equal,
+        angle_bracket_right,
+        angle_bracket_right_equal,
+        angle_bracket_angle_bracket_right,
+        angle_bracket_angle_bracket_right_equal,
+        tilde,
+        hash,
+        hash_hash,
+
+        /// Special token to speed up preprocessing, `loc.end` will be an index to the param list.
+        macro_param,
+        /// Special token to signal that the argument must be replaced without expansion (e.g. in concatenation)
+        macro_param_no_expand,
+        /// Special token to speed up preprocessing, `loc.end` will be an index to the param list.
+        stringify_param,
+        /// Same as stringify_param, but for var args
+        stringify_va_args,
+        /// Special macro whitespace, always equal to a single space
+        macro_ws,
+        /// Special token for implementing __has_attribute
+        macro_param_has_attribute,
+        /// Special token for implementing __has_warning
+        macro_param_has_warning,
+        /// Special token for implementing __has_feature
+        macro_param_has_feature,
+        /// Special token for implementing __has_extension
+        macro_param_has_extension,
+        /// Special token for implementing __has_builtin
+        macro_param_has_builtin,
+        /// Special token for implementing __has_include
+        macro_param_has_include,
+        /// Special token for implementing __has_include_next
+        macro_param_has_include_next,
+        /// Special token for implementing __is_identifier
+        macro_param_is_identifier,
+        /// Special token for implementing __FILE__
+        macro_file,
+        /// Special token for implementing __LINE__
+        macro_line,
+        /// Special token for implementing __COUNTER__
+        macro_counter,
+        /// Special token for implementing _Pragma
+        macro_param_pragma_operator,
+
+        /// Special identifier for implementing __func__
+        macro_func,
+        /// Special identifier for implementing __FUNCTION__
+        macro_function,
+        /// Special identifier for implementing __PRETTY_FUNCTION__
+        macro_pretty_func,
+
+        keyword_auto,
+        keyword_auto_type,
+        keyword_break,
+        keyword_case,
+        keyword_char,
+        keyword_const,
+        keyword_continue,
+        keyword_default,
+        keyword_do,
+        keyword_double,
+        keyword_else,
+        keyword_enum,
+        keyword_extern,
+        keyword_float,
+        keyword_for,
+        keyword_goto,
+        keyword_if,
+        keyword_int,
+        keyword_long,
+        keyword_register,
+        keyword_return,
+        keyword_short,
+        keyword_signed,
+        keyword_sizeof,
+        keyword_static,
+        keyword_struct,
+        keyword_switch,
+        keyword_typedef,
+        keyword_typeof1,
+        keyword_typeof2,
+        keyword_union,
+        keyword_unsigned,
+        keyword_void,
+        keyword_volatile,
+        keyword_while,
+
+        // ISO C99
+        keyword_bool,
+        keyword_complex,
+        keyword_imaginary,
+        keyword_inline,
+        keyword_restrict,
+
+        // ISO C11
+        keyword_alignas,
+        keyword_alignof,
+        keyword_atomic,
+        keyword_generic,
+        keyword_noreturn,
+        keyword_static_assert,
+        keyword_thread_local,
+
+        // ISO C23
+        keyword_bit_int,
+        keyword_c23_alignas,
+        keyword_c23_alignof,
+        keyword_c23_bool,
+        keyword_c23_static_assert,
+        keyword_c23_thread_local,
+        keyword_constexpr,
+        keyword_true,
+        keyword_false,
+        keyword_nullptr,
+
+        // Preprocessor directives
+        keyword_include,
+        keyword_include_next,
+        keyword_embed,
+        keyword_define,
+        keyword_defined,
+        keyword_undef,
+        keyword_ifdef,
+        keyword_ifndef,
+        keyword_elif,
+        keyword_elifdef,
+        keyword_elifndef,
+        keyword_endif,
+        keyword_error,
+        keyword_warning,
+        keyword_pragma,
+        keyword_line,
+        keyword_va_args,
+
+        // gcc keywords
+        keyword_const1,
+        keyword_const2,
+        keyword_inline1,
+        keyword_inline2,
+        keyword_volatile1,
+        keyword_volatile2,
+        keyword_restrict1,
+        keyword_restrict2,
+        keyword_alignof1,
+        keyword_alignof2,
+        keyword_typeof,
+        keyword_attribute1,
+        keyword_attribute2,
+        keyword_extension,
+        keyword_asm,
+        keyword_asm1,
+        keyword_asm2,
+        keyword_float80,
+        keyword_float128,
+        keyword_int128,
+        keyword_imag1,
+        keyword_imag2,
+        keyword_real1,
+        keyword_real2,
+        keyword_float16,
+
+        // clang keywords
+        keyword_fp16,
+
+        // ms keywords
+        keyword_declspec,
+        keyword_int64,
+        keyword_int64_2,
+        keyword_int32,
+        keyword_int32_2,
+        keyword_int16,
+        keyword_int16_2,
+        keyword_int8,
+        keyword_int8_2,
+        keyword_stdcall,
+        keyword_stdcall2,
+        keyword_thiscall,
+        keyword_thiscall2,
+        keyword_vectorcall,
+        keyword_vectorcall2,
+
+        // builtins that require special parsing
+        builtin_choose_expr,
+        builtin_va_arg,
+        builtin_offsetof,
+        builtin_bitoffsetof,
+        builtin_types_compatible_p,
+
+        /// Generated by #embed directive
+        /// Decimal value with no prefix or suffix
+        embed_byte,
+
+        /// preprocessor number
+        /// An optional period, followed by a digit 0-9, followed by any number of letters
+        /// digits, underscores, periods, and exponents (e+, e-, E+, E-, p+, p-, P+, P-)
+        pp_num,
+
+        /// preprocessor placemarker token
+        /// generated if `##` is used with a zero-token argument
+        /// removed after substitution, so the parser should never see this
+        /// See C99 6.10.3.3.2
+        placemarker,
+
+        /// Return true if token is identifier or keyword.
+        pub fn isMacroIdentifier(id: Id) bool {
+            switch (id) {
+                .keyword_include,
+                .keyword_include_next,
+                .keyword_embed,
+                .keyword_define,
+                .keyword_defined,
+                .keyword_undef,
+                .keyword_ifdef,
+                .keyword_ifndef,
+                .keyword_elif,
+                .keyword_elifdef,
+                .keyword_elifndef,
+                .keyword_endif,
+                .keyword_error,
+                .keyword_warning,
+                .keyword_pragma,
+                .keyword_line,
+                .keyword_va_args,
+                .macro_func,
+                .macro_function,
+                .macro_pretty_func,
+                .keyword_auto,
+                .keyword_auto_type,
+                .keyword_break,
+                .keyword_case,
+                .keyword_char,
+                .keyword_const,
+                .keyword_continue,
+                .keyword_default,
+                .keyword_do,
+                .keyword_double,
+                .keyword_else,
+                .keyword_enum,
+                .keyword_extern,
+                .keyword_float,
+                .keyword_for,
+                .keyword_goto,
+                .keyword_if,
+                .keyword_int,
+                .keyword_long,
+                .keyword_register,
+                .keyword_return,
+                .keyword_short,
+                .keyword_signed,
+                .keyword_sizeof,
+                .keyword_static,
+                .keyword_struct,
+                .keyword_switch,
+                .keyword_typedef,
+                .keyword_union,
+                .keyword_unsigned,
+                .keyword_void,
+                .keyword_volatile,
+                .keyword_while,
+                .keyword_bool,
+                .keyword_complex,
+                .keyword_imaginary,
+                .keyword_inline,
+                .keyword_restrict,
+                .keyword_alignas,
+                .keyword_alignof,
+                .keyword_atomic,
+                .keyword_generic,
+                .keyword_noreturn,
+                .keyword_static_assert,
+                .keyword_thread_local,
+                .identifier,
+                .extended_identifier,
+                .keyword_typeof,
+                .keyword_typeof1,
+                .keyword_typeof2,
+                .keyword_const1,
+                .keyword_const2,
+                .keyword_inline1,
+                .keyword_inline2,
+                .keyword_volatile1,
+                .keyword_volatile2,
+                .keyword_restrict1,
+                .keyword_restrict2,
+                .keyword_alignof1,
+                .keyword_alignof2,
+                .builtin_choose_expr,
+                .builtin_va_arg,
+                .builtin_offsetof,
+                .builtin_bitoffsetof,
+                .builtin_types_compatible_p,
+                .keyword_attribute1,
+                .keyword_attribute2,
+                .keyword_extension,
+                .keyword_asm,
+                .keyword_asm1,
+                .keyword_asm2,
+                .keyword_float80,
+                .keyword_float128,
+                .keyword_int128,
+                .keyword_imag1,
+                .keyword_imag2,
+                .keyword_real1,
+                .keyword_real2,
+                .keyword_float16,
+                .keyword_fp16,
+                .keyword_declspec,
+                .keyword_int64,
+                .keyword_int64_2,
+                .keyword_int32,
+                .keyword_int32_2,
+                .keyword_int16,
+                .keyword_int16_2,
+                .keyword_int8,
+                .keyword_int8_2,
+                .keyword_stdcall,
+                .keyword_stdcall2,
+                .keyword_thiscall,
+                .keyword_thiscall2,
+                .keyword_vectorcall,
+                .keyword_vectorcall2,
+                .keyword_bit_int,
+                .keyword_c23_alignas,
+                .keyword_c23_alignof,
+                .keyword_c23_bool,
+                .keyword_c23_static_assert,
+                .keyword_c23_thread_local,
+                .keyword_constexpr,
+                .keyword_true,
+                .keyword_false,
+                .keyword_nullptr,
+                => return true,
+                else => return false,
+            }
+        }
+
+        /// Turn macro keywords into identifiers.
+        /// `keyword_defined` is special since it should only turn into an identifier if
+        /// we are *not* in an #if or #elif expression
+        pub fn simplifyMacroKeywordExtra(id: *Id, defined_to_identifier: bool) void {
+            switch (id.*) {
+                .keyword_include,
+                .keyword_include_next,
+                .keyword_embed,
+                .keyword_define,
+                .keyword_undef,
+                .keyword_ifdef,
+                .keyword_ifndef,
+                .keyword_elif,
+                .keyword_elifdef,
+                .keyword_elifndef,
+                .keyword_endif,
+                .keyword_error,
+                .keyword_warning,
+                .keyword_pragma,
+                .keyword_line,
+                .keyword_va_args,
+                => id.* = .identifier,
+                .keyword_defined => if (defined_to_identifier) {
+                    id.* = .identifier;
+                },
+                else => {},
+            }
+        }
+
+        pub fn simplifyMacroKeyword(id: *Id) void {
+            simplifyMacroKeywordExtra(id, false);
+        }
+
+        pub fn lexeme(id: Id) ?[]const u8 {
+            return switch (id) {
+                .invalid,
+                .identifier,
+                .extended_identifier,
+                .string_literal,
+                .string_literal_utf_16,
+                .string_literal_utf_8,
+                .string_literal_utf_32,
+                .string_literal_wide,
+                .char_literal,
+                .char_literal_utf_8,
+                .char_literal_utf_16,
+                .char_literal_utf_32,
+                .char_literal_wide,
+                .macro_string,
+                .whitespace,
+                .pp_num,
+                .embed_byte,
+                => null,
+
+                .zero => "0",
+                .one => "1",
+
+                .nl,
+                .eof,
+                .macro_param,
+                .macro_param_no_expand,
+                .stringify_param,
+                .stringify_va_args,
+                .macro_param_has_attribute,
+                .macro_param_has_warning,
+                .macro_param_has_feature,
+                .macro_param_has_extension,
+                .macro_param_has_builtin,
+                .macro_param_has_include,
+                .macro_param_has_include_next,
+                .macro_param_is_identifier,
+                .macro_file,
+                .macro_line,
+                .macro_counter,
+                .macro_param_pragma_operator,
+                .placemarker,
+                => "",
+                .macro_ws => " ",
+
+                .macro_func => "__func__",
+                .macro_function => "__FUNCTION__",
+                .macro_pretty_func => "__PRETTY_FUNCTION__",
+
+                .bang => "!",
+                .bang_equal => "!=",
+                .pipe => "|",
+                .pipe_pipe => "||",
+                .pipe_equal => "|=",
+                .equal => "=",
+                .equal_equal => "==",
+                .l_paren => "(",
+                .r_paren => ")",
+                .l_brace => "{",
+                .r_brace => "}",
+                .l_bracket => "[",
+                .r_bracket => "]",
+                .period => ".",
+                .ellipsis => "...",
+                .caret => "^",
+                .caret_equal => "^=",
+                .plus => "+",
+                .plus_plus => "++",
+                .plus_equal => "+=",
+                .minus => "-",
+                .minus_minus => "--",
+                .minus_equal => "-=",
+                .asterisk => "*",
+                .asterisk_equal => "*=",
+                .percent => "%",
+                .percent_equal => "%=",
+                .arrow => "->",
+                .colon => ":",
+                .colon_colon => "::",
+                .semicolon => ";",
+                .slash => "/",
+                .slash_equal => "/=",
+                .comma => ",",
+                .ampersand => "&",
+                .ampersand_ampersand => "&&",
+                .ampersand_equal => "&=",
+                .question_mark => "?",
+                .angle_bracket_left => "<",
+                .angle_bracket_left_equal => "<=",
+                .angle_bracket_angle_bracket_left => "<<",
+                .angle_bracket_angle_bracket_left_equal => "<<=",
+                .angle_bracket_right => ">",
+                .angle_bracket_right_equal => ">=",
+                .angle_bracket_angle_bracket_right => ">>",
+                .angle_bracket_angle_bracket_right_equal => ">>=",
+                .tilde => "~",
+                .hash => "#",
+                .hash_hash => "##",
+
+                .keyword_auto => "auto",
+                .keyword_auto_type => "__auto_type",
+                .keyword_break => "break",
+                .keyword_case => "case",
+                .keyword_char => "char",
+                .keyword_const => "const",
+                .keyword_continue => "continue",
+                .keyword_default => "default",
+                .keyword_do => "do",
+                .keyword_double => "double",
+                .keyword_else => "else",
+                .keyword_enum => "enum",
+                .keyword_extern => "extern",
+                .keyword_float => "float",
+                .keyword_for => "for",
+                .keyword_goto => "goto",
+                .keyword_if => "if",
+                .keyword_int => "int",
+                .keyword_long => "long",
+                .keyword_register => "register",
+                .keyword_return => "return",
+                .keyword_short => "short",
+                .keyword_signed => "signed",
+                .keyword_sizeof => "sizeof",
+                .keyword_static => "static",
+                .keyword_struct => "struct",
+                .keyword_switch => "switch",
+                .keyword_typedef => "typedef",
+                .keyword_typeof => "typeof",
+                .keyword_union => "union",
+                .keyword_unsigned => "unsigned",
+                .keyword_void => "void",
+                .keyword_volatile => "volatile",
+                .keyword_while => "while",
+                .keyword_bool => "_Bool",
+                .keyword_complex => "_Complex",
+                .keyword_imaginary => "_Imaginary",
+                .keyword_inline => "inline",
+                .keyword_restrict => "restrict",
+                .keyword_alignas => "_Alignas",
+                .keyword_alignof => "_Alignof",
+                .keyword_atomic => "_Atomic",
+                .keyword_generic => "_Generic",
+                .keyword_noreturn => "_Noreturn",
+                .keyword_static_assert => "_Static_assert",
+                .keyword_thread_local => "_Thread_local",
+                .keyword_bit_int => "_BitInt",
+                .keyword_c23_alignas => "alignas",
+                .keyword_c23_alignof => "alignof",
+                .keyword_c23_bool => "bool",
+                .keyword_c23_static_assert => "static_assert",
+                .keyword_c23_thread_local => "thread_local",
+                .keyword_constexpr => "constexpr",
+                .keyword_true => "true",
+                .keyword_false => "false",
+                .keyword_nullptr => "nullptr",
+                .keyword_include => "include",
+                .keyword_include_next => "include_next",
+                .keyword_embed => "embed",
+                .keyword_define => "define",
+                .keyword_defined => "defined",
+                .keyword_undef => "undef",
+                .keyword_ifdef => "ifdef",
+                .keyword_ifndef => "ifndef",
+                .keyword_elif => "elif",
+                .keyword_elifdef => "elifdef",
+                .keyword_elifndef => "elifndef",
+                .keyword_endif => "endif",
+                .keyword_error => "error",
+                .keyword_warning => "warning",
+                .keyword_pragma => "pragma",
+                .keyword_line => "line",
+                .keyword_va_args => "__VA_ARGS__",
+                .keyword_const1 => "__const",
+                .keyword_const2 => "__const__",
+                .keyword_inline1 => "__inline",
+                .keyword_inline2 => "__inline__",
+                .keyword_volatile1 => "__volatile",
+                .keyword_volatile2 => "__volatile__",
+                .keyword_restrict1 => "__restrict",
+                .keyword_restrict2 => "__restrict__",
+                .keyword_alignof1 => "__alignof",
+                .keyword_alignof2 => "__alignof__",
+                .keyword_typeof1 => "__typeof",
+                .keyword_typeof2 => "__typeof__",
+                .builtin_choose_expr => "__builtin_choose_expr",
+                .builtin_va_arg => "__builtin_va_arg",
+                .builtin_offsetof => "__builtin_offsetof",
+                .builtin_bitoffsetof => "__builtin_bitoffsetof",
+                .builtin_types_compatible_p => "__builtin_types_compatible_p",
+                .keyword_attribute1 => "__attribute",
+                .keyword_attribute2 => "__attribute__",
+                .keyword_extension => "__extension__",
+                .keyword_asm => "asm",
+                .keyword_asm1 => "__asm",
+                .keyword_asm2 => "__asm__",
+                .keyword_float80 => "__float80",
+                .keyword_float128 => "__float18",
+                .keyword_int128 => "__int128",
+                .keyword_imag1 => "__imag",
+                .keyword_imag2 => "__imag__",
+                .keyword_real1 => "__real",
+                .keyword_real2 => "__real__",
+                .keyword_float16 => "_Float16",
+                .keyword_fp16 => "__fp16",
+                .keyword_declspec => "__declspec",
+                .keyword_int64 => "__int64",
+                .keyword_int64_2 => "_int64",
+                .keyword_int32 => "__int32",
+                .keyword_int32_2 => "_int32",
+                .keyword_int16 => "__int16",
+                .keyword_int16_2 => "_int16",
+                .keyword_int8 => "__int8",
+                .keyword_int8_2 => "_int8",
+                .keyword_stdcall => "__stdcall",
+                .keyword_stdcall2 => "_stdcall",
+                .keyword_thiscall => "__thiscall",
+                .keyword_thiscall2 => "_thiscall",
+                .keyword_vectorcall => "__vectorcall",
+                .keyword_vectorcall2 => "_vectorcall",
+            };
+        }
+
+        pub fn symbol(id: Id) []const u8 {
+            return switch (id) {
+                .macro_string, .invalid => unreachable,
+                .identifier,
+                .extended_identifier,
+                .macro_func,
+                .macro_function,
+                .macro_pretty_func,
+                .builtin_choose_expr,
+                .builtin_va_arg,
+                .builtin_offsetof,
+                .builtin_bitoffsetof,
+                .builtin_types_compatible_p,
+                => "an identifier",
+                .string_literal,
+                .string_literal_utf_16,
+                .string_literal_utf_8,
+                .string_literal_utf_32,
+                .string_literal_wide,
+                => "a string literal",
+                .char_literal,
+                .char_literal_utf_8,
+                .char_literal_utf_16,
+                .char_literal_utf_32,
+                .char_literal_wide,
+                => "a character literal",
+                .pp_num, .embed_byte => "A number",
+                else => id.lexeme().?,
+            };
+        }
+
+        /// tokens that can start an expression parsed by Preprocessor.expr
+        /// Note that eof, r_paren, and string literals cannot actually start a
+        /// preprocessor expression, but we include them here so that a nicer
+        /// error message can be generated by the parser.
+        pub fn validPreprocessorExprStart(id: Id) bool {
+            return switch (id) {
+                .eof,
+                .r_paren,
+                .string_literal,
+                .string_literal_utf_16,
+                .string_literal_utf_8,
+                .string_literal_utf_32,
+                .string_literal_wide,
+
+                .char_literal,
+                .char_literal_utf_8,
+                .char_literal_utf_16,
+                .char_literal_utf_32,
+                .char_literal_wide,
+                .l_paren,
+                .plus,
+                .minus,
+                .tilde,
+                .bang,
+                .identifier,
+                .extended_identifier,
+                .keyword_defined,
+                .one,
+                .zero,
+                .pp_num,
+                .keyword_true,
+                .keyword_false,
+                => true,
+                else => false,
+            };
+        }
+
+        pub fn allowsDigraphs(id: Id, comp: *const Compilation) bool {
+            return switch (id) {
+                .l_bracket,
+                .r_bracket,
+                .l_brace,
+                .r_brace,
+                .hash,
+                .hash_hash,
+                => comp.langopts.hasDigraphs(),
+                else => false,
+            };
+        }
+
+        pub fn canOpenGCCAsmStmt(id: Id) bool {
+            return switch (id) {
+                .keyword_volatile, .keyword_volatile1, .keyword_volatile2, .keyword_inline, .keyword_inline1, .keyword_inline2, .keyword_goto, .l_paren => true,
+                else => false,
+            };
+        }
+
+        pub fn isStringLiteral(id: Id) bool {
+            return switch (id) {
+                .string_literal, .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32, .string_literal_wide => true,
+                else => false,
+            };
+        }
+    };
+
+    /// double underscore and underscore + capital letter identifiers
+    /// belong to the implementation namespace, so we always convert them
+    /// to keywords.
+    pub fn getTokenId(comp: *const Compilation, str: []const u8) Token.Id {
+        const kw = all_kws.get(str) orelse return .identifier;
+        const standard = comp.langopts.standard;
+        return switch (kw) {
+            .keyword_inline => if (standard.isGNU() or standard.atLeast(.c99)) kw else .identifier,
+            .keyword_restrict => if (standard.atLeast(.c99)) kw else .identifier,
+            .keyword_typeof => if (standard.isGNU() or standard.atLeast(.c2x)) kw else .identifier,
+            .keyword_asm => if (standard.isGNU()) kw else .identifier,
+            .keyword_declspec => if (comp.langopts.declspec_attrs) kw else .identifier,
+
+            .keyword_c23_alignas,
+            .keyword_c23_alignof,
+            .keyword_c23_bool,
+            .keyword_c23_static_assert,
+            .keyword_c23_thread_local,
+            .keyword_constexpr,
+            .keyword_true,
+            .keyword_false,
+            .keyword_nullptr,
+            .keyword_elifdef,
+            .keyword_elifndef,
+            => if (standard.atLeast(.c2x)) kw else .identifier,
+
+            .keyword_int64,
+            .keyword_int64_2,
+            .keyword_int32,
+            .keyword_int32_2,
+            .keyword_int16,
+            .keyword_int16_2,
+            .keyword_int8,
+            .keyword_int8_2,
+            .keyword_stdcall2,
+            .keyword_thiscall2,
+            .keyword_vectorcall2,
+            => if (comp.langopts.ms_extensions) kw else .identifier,
+            else => kw,
+        };
+    }
+
+    /// Check if codepoint may appear in specified context
+    /// does not check basic character set chars because the tokenizer handles them separately to keep the common
+    /// case on the fast path
+    pub fn mayAppearInIdent(comp: *const Compilation, codepoint: u21, where: enum { start, inside }) bool {
+        if (codepoint == '$') return comp.langopts.dollars_in_identifiers;
+        if (codepoint <= 0x7F) return false;
+        return switch (where) {
+            .start => if (comp.langopts.standard.atLeast(.c11))
+                CharInfo.isC11IdChar(codepoint) and !CharInfo.isC11DisallowedInitialIdChar(codepoint)
+            else
+                CharInfo.isC99IdChar(codepoint) and !CharInfo.isC99DisallowedInitialIDChar(codepoint),
+            .inside => if (comp.langopts.standard.atLeast(.c11))
+                CharInfo.isC11IdChar(codepoint)
+            else
+                CharInfo.isC99IdChar(codepoint),
+        };
+    }
+
+    const all_kws = std.ComptimeStringMap(Id, .{
+        .{ "auto", auto: {
+            @setEvalBranchQuota(3000);
+            break :auto .keyword_auto;
+        } },
+        .{ "break", .keyword_break },
+        .{ "case", .keyword_case },
+        .{ "char", .keyword_char },
+        .{ "const", .keyword_const },
+        .{ "continue", .keyword_continue },
+        .{ "default", .keyword_default },
+        .{ "do", .keyword_do },
+        .{ "double", .keyword_double },
+        .{ "else", .keyword_else },
+        .{ "enum", .keyword_enum },
+        .{ "extern", .keyword_extern },
+        .{ "float", .keyword_float },
+        .{ "for", .keyword_for },
+        .{ "goto", .keyword_goto },
+        .{ "if", .keyword_if },
+        .{ "int", .keyword_int },
+        .{ "long", .keyword_long },
+        .{ "register", .keyword_register },
+        .{ "return", .keyword_return },
+        .{ "short", .keyword_short },
+        .{ "signed", .keyword_signed },
+        .{ "sizeof", .keyword_sizeof },
+        .{ "static", .keyword_static },
+        .{ "struct", .keyword_struct },
+        .{ "switch", .keyword_switch },
+        .{ "typedef", .keyword_typedef },
+        .{ "union", .keyword_union },
+        .{ "unsigned", .keyword_unsigned },
+        .{ "void", .keyword_void },
+        .{ "volatile", .keyword_volatile },
+        .{ "while", .keyword_while },
+        .{ "__typeof__", .keyword_typeof2 },
+        .{ "__typeof", .keyword_typeof1 },
+
+        // ISO C99
+        .{ "_Bool", .keyword_bool },
+        .{ "_Complex", .keyword_complex },
+        .{ "_Imaginary", .keyword_imaginary },
+        .{ "inline", .keyword_inline },
+        .{ "restrict", .keyword_restrict },
+
+        // ISO C11
+        .{ "_Alignas", .keyword_alignas },
+        .{ "_Alignof", .keyword_alignof },
+        .{ "_Atomic", .keyword_atomic },
+        .{ "_Generic", .keyword_generic },
+        .{ "_Noreturn", .keyword_noreturn },
+        .{ "_Static_assert", .keyword_static_assert },
+        .{ "_Thread_local", .keyword_thread_local },
+
+        // ISO C23
+        .{ "_BitInt", .keyword_bit_int },
+        .{ "alignas", .keyword_c23_alignas },
+        .{ "alignof", .keyword_c23_alignof },
+        .{ "bool", .keyword_c23_bool },
+        .{ "static_assert", .keyword_c23_static_assert },
+        .{ "thread_local", .keyword_c23_thread_local },
+        .{ "constexpr", .keyword_constexpr },
+        .{ "true", .keyword_true },
+        .{ "false", .keyword_false },
+        .{ "nullptr", .keyword_nullptr },
+
+        // Preprocessor directives
+        .{ "include", .keyword_include },
+        .{ "include_next", .keyword_include_next },
+        .{ "embed", .keyword_embed },
+        .{ "define", .keyword_define },
+        .{ "defined", .keyword_defined },
+        .{ "undef", .keyword_undef },
+        .{ "ifdef", .keyword_ifdef },
+        .{ "ifndef", .keyword_ifndef },
+        .{ "elif", .keyword_elif },
+        .{ "elifdef", .keyword_elifdef },
+        .{ "elifndef", .keyword_elifndef },
+        .{ "endif", .keyword_endif },
+        .{ "error", .keyword_error },
+        .{ "warning", .keyword_warning },
+        .{ "pragma", .keyword_pragma },
+        .{ "line", .keyword_line },
+        .{ "__VA_ARGS__", .keyword_va_args },
+        .{ "__func__", .macro_func },
+        .{ "__FUNCTION__", .macro_function },
+        .{ "__PRETTY_FUNCTION__", .macro_pretty_func },
+
+        // gcc keywords
+        .{ "__auto_type", .keyword_auto_type },
+        .{ "__const", .keyword_const1 },
+        .{ "__const__", .keyword_const2 },
+        .{ "__inline", .keyword_inline1 },
+        .{ "__inline__", .keyword_inline2 },
+        .{ "__volatile", .keyword_volatile1 },
+        .{ "__volatile__", .keyword_volatile2 },
+        .{ "__restrict", .keyword_restrict1 },
+        .{ "__restrict__", .keyword_restrict2 },
+        .{ "__alignof", .keyword_alignof1 },
+        .{ "__alignof__", .keyword_alignof2 },
+        .{ "typeof", .keyword_typeof },
+        .{ "__attribute", .keyword_attribute1 },
+        .{ "__attribute__", .keyword_attribute2 },
+        .{ "__extension__", .keyword_extension },
+        .{ "asm", .keyword_asm },
+        .{ "__asm", .keyword_asm1 },
+        .{ "__asm__", .keyword_asm2 },
+        .{ "__float80", .keyword_float80 },
+        .{ "__float128", .keyword_float128 },
+        .{ "__int128", .keyword_int128 },
+        .{ "__imag", .keyword_imag1 },
+        .{ "__imag__", .keyword_imag2 },
+        .{ "__real", .keyword_real1 },
+        .{ "__real__", .keyword_real2 },
+        .{ "_Float16", .keyword_float16 },
+
+        // clang keywords
+        .{ "__fp16", .keyword_fp16 },
+
+        // ms keywords
+        .{ "__declspec", .keyword_declspec },
+        .{ "__int64", .keyword_int64 },
+        .{ "_int64", .keyword_int64_2 },
+        .{ "__int32", .keyword_int32 },
+        .{ "_int32", .keyword_int32_2 },
+        .{ "__int16", .keyword_int16 },
+        .{ "_int16", .keyword_int16_2 },
+        .{ "__int8", .keyword_int8 },
+        .{ "_int8", .keyword_int8_2 },
+        .{ "__stdcall", .keyword_stdcall },
+        .{ "_stdcall", .keyword_stdcall2 },
+        .{ "__thiscall", .keyword_thiscall },
+        .{ "_thiscall", .keyword_thiscall2 },
+        .{ "__vectorcall", .keyword_vectorcall },
+        .{ "_vectorcall", .keyword_vectorcall2 },
+
+        // builtins that require special parsing
+        .{ "__builtin_choose_expr", .builtin_choose_expr },
+        .{ "__builtin_va_arg", .builtin_va_arg },
+        .{ "__builtin_offsetof", .builtin_offsetof },
+        .{ "__builtin_bitoffsetof", .builtin_bitoffsetof },
+        .{ "__builtin_types_compatible_p", .builtin_types_compatible_p },
+    });
+};
+
+buf: []const u8,
+index: u32 = 0,
+source: Source.Id,
+comp: *const Compilation,
+line: u32 = 1,
+
+pub fn next(self: *Tokenizer) Token {
+    var state: enum {
+        start,
+        whitespace,
+        u,
+        u8,
+        U,
+        L,
+        string_literal,
+        char_literal_start,
+        char_literal,
+        escape_sequence,
+        octal_escape,
+        hex_escape,
+        unicode_escape,
+        identifier,
+        extended_identifier,
+        equal,
+        bang,
+        pipe,
+        colon,
+        percent,
+        asterisk,
+        plus,
+        angle_bracket_left,
+        angle_bracket_angle_bracket_left,
+        angle_bracket_right,
+        angle_bracket_angle_bracket_right,
+        caret,
+        period,
+        period2,
+        minus,
+        slash,
+        ampersand,
+        hash,
+        hash_digraph,
+        hash_hash_digraph_partial,
+        line_comment,
+        multi_line_comment,
+        multi_line_comment_asterisk,
+        multi_line_comment_done,
+        pp_num,
+        pp_num_exponent,
+        pp_num_digit_separator,
+    } = .start;
+
+    var start = self.index;
+    var id: Token.Id = .eof;
+
+    var return_state = state;
+    var counter: u32 = 0;
+    var codepoint_len: u3 = undefined;
+    while (self.index < self.buf.len) : (self.index += codepoint_len) {
+        // Source files get checked for valid utf-8 before being tokenized so it is safe to use
+        // these versions.
+        codepoint_len = unicode.utf8ByteSequenceLength_unsafe(self.buf[self.index]);
+        const c: u21 = switch (codepoint_len) {
+            1 => @as(u21, self.buf[self.index]),
+            2 => unicode.utf8Decode2_unsafe(self.buf[self.index..]),
+            3 => unicode.utf8Decode3_unsafe(self.buf[self.index..]),
+            4 => unicode.utf8Decode4_unsafe(self.buf[self.index..]),
+            else => unreachable,
+        };
+        switch (state) {
+            .start => switch (c) {
+                '\n' => {
+                    id = .nl;
+                    self.index += 1;
+                    self.line += 1;
+                    break;
+                },
+                '"' => {
+                    id = .string_literal;
+                    state = .string_literal;
+                },
+                '\'' => {
+                    id = .char_literal;
+                    state = .char_literal_start;
+                },
+                'u' => state = .u,
+                'U' => state = .U,
+                'L' => state = .L,
+                'a'...'t', 'v'...'z', 'A'...'K', 'M'...'T', 'V'...'Z', '_' => state = .identifier,
+                '=' => state = .equal,
+                '!' => state = .bang,
+                '|' => state = .pipe,
+                '(' => {
+                    id = .l_paren;
+                    self.index += 1;
+                    break;
+                },
+                ')' => {
+                    id = .r_paren;
+                    self.index += 1;
+                    break;
+                },
+                '[' => {
+                    id = .l_bracket;
+                    self.index += 1;
+                    break;
+                },
+                ']' => {
+                    id = .r_bracket;
+                    self.index += 1;
+                    break;
+                },
+                ';' => {
+                    id = .semicolon;
+                    self.index += 1;
+                    break;
+                },
+                ',' => {
+                    id = .comma;
+                    self.index += 1;
+                    break;
+                },
+                '?' => {
+                    id = .question_mark;
+                    self.index += 1;
+                    break;
+                },
+                ':' => state = .colon,
+                '%' => state = .percent,
+                '*' => state = .asterisk,
+                '+' => state = .plus,
+                '<' => state = .angle_bracket_left,
+                '>' => state = .angle_bracket_right,
+                '^' => state = .caret,
+                '{' => {
+                    id = .l_brace;
+                    self.index += 1;
+                    break;
+                },
+                '}' => {
+                    id = .r_brace;
+                    self.index += 1;
+                    break;
+                },
+                '~' => {
+                    id = .tilde;
+                    self.index += 1;
+                    break;
+                },
+                '.' => state = .period,
+                '-' => state = .minus,
+                '/' => state = .slash,
+                '&' => state = .ampersand,
+                '#' => state = .hash,
+                '0'...'9' => state = .pp_num,
+                '\t', '\x0B', '\x0C', ' ' => state = .whitespace,
+                else => if (Token.mayAppearInIdent(self.comp, c, .start)) {
+                    state = .extended_identifier;
+                } else {
+                    id = .invalid;
+                    self.index += codepoint_len;
+                    break;
+                },
+            },
+            .whitespace => switch (c) {
+                '\t', '\x0B', '\x0C', ' ' => {},
+                else => {
+                    id = .whitespace;
+                    break;
+                },
+            },
+            .u => switch (c) {
+                '8' => {
+                    state = .u8;
+                },
+                '\'' => {
+                    id = .char_literal_utf_16;
+                    state = .char_literal_start;
+                },
+                '\"' => {
+                    id = .string_literal_utf_16;
+                    state = .string_literal;
+                },
+                else => {
+                    codepoint_len = 0;
+                    state = .identifier;
+                },
+            },
+            .u8 => switch (c) {
+                '\"' => {
+                    id = .string_literal_utf_8;
+                    state = .string_literal;
+                },
+                '\'' => {
+                    id = .char_literal_utf_8;
+                    state = .char_literal_start;
+                },
+                else => {
+                    codepoint_len = 0;
+                    state = .identifier;
+                },
+            },
+            .U => switch (c) {
+                '\'' => {
+                    id = .char_literal_utf_32;
+                    state = .char_literal_start;
+                },
+                '\"' => {
+                    id = .string_literal_utf_32;
+                    state = .string_literal;
+                },
+                else => {
+                    codepoint_len = 0;
+                    state = .identifier;
+                },
+            },
+            .L => switch (c) {
+                '\'' => {
+                    id = .char_literal_wide;
+                    state = .char_literal_start;
+                },
+                '\"' => {
+                    id = .string_literal_wide;
+                    state = .string_literal;
+                },
+                else => {
+                    codepoint_len = 0;
+                    state = .identifier;
+                },
+            },
+            .string_literal => switch (c) {
+                '\\' => {
+                    return_state = .string_literal;
+                    state = .escape_sequence;
+                },
+                '"' => {
+                    self.index += 1;
+                    break;
+                },
+                '\n' => {
+                    id = .invalid;
+                    break;
+                },
+                '\r' => unreachable,
+                else => {},
+            },
+            .char_literal_start => switch (c) {
+                '\\' => {
+                    return_state = .char_literal;
+                    state = .escape_sequence;
+                },
+
+                '\'', '\n' => {
+                    id = .invalid;
+                    break;
+                },
+                else => {
+                    state = .char_literal;
+                },
+            },
+            .char_literal => switch (c) {
+                '\\' => {
+                    return_state = .char_literal;
+                    state = .escape_sequence;
+                },
+                '\'' => {
+                    self.index += 1;
+                    break;
+                },
+                '\n' => {
+                    id = .invalid;
+                    break;
+                },
+                else => {},
+            },
+            .escape_sequence => switch (c) {
+                '\'', '"', '?', '\\', 'a', 'b', 'e', 'f', 'n', 'r', 't', 'v' => {
+                    state = return_state;
+                },
+                '\n' => {
+                    state = return_state;
+                    self.line += 1;
+                },
+                '0'...'7' => {
+                    counter = 1;
+                    state = .octal_escape;
+                },
+                'x' => state = .hex_escape,
+                'u' => {
+                    counter = 4;
+                    state = .unicode_escape;
+                },
+                'U' => {
+                    counter = 8;
+                    state = .unicode_escape;
+                },
+                else => {
+                    id = .invalid;
+                    break;
+                },
+            },
+            .octal_escape => switch (c) {
+                '0'...'7' => {
+                    counter += 1;
+                    if (counter == 3) state = return_state;
+                },
+                else => {
+                    codepoint_len = 0;
+                    state = return_state;
+                },
+            },
+            .hex_escape => switch (c) {
+                '0'...'9', 'a'...'f', 'A'...'F' => {},
+                else => {
+                    codepoint_len = 0;
+                    state = return_state;
+                },
+            },
+            .unicode_escape => switch (c) {
+                '0'...'9', 'a'...'f', 'A'...'F' => {
+                    counter -= 1;
+                    if (counter == 0) state = return_state;
+                },
+                else => {
+                    id = .invalid;
+                    break;
+                },
+            },
+            .identifier, .extended_identifier => switch (c) {
+                'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
+                else => {
+                    if (!Token.mayAppearInIdent(self.comp, c, .inside)) {
+                        id = if (state == .identifier) Token.getTokenId(self.comp, self.buf[start..self.index]) else .extended_identifier;
+                        break;
+                    }
+                    state = .extended_identifier;
+                },
+            },
+            .equal => switch (c) {
+                '=' => {
+                    id = .equal_equal;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .equal;
+                    break;
+                },
+            },
+            .bang => switch (c) {
+                '=' => {
+                    id = .bang_equal;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .bang;
+                    break;
+                },
+            },
+            .pipe => switch (c) {
+                '=' => {
+                    id = .pipe_equal;
+                    self.index += 1;
+                    break;
+                },
+                '|' => {
+                    id = .pipe_pipe;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .pipe;
+                    break;
+                },
+            },
+            .colon => switch (c) {
+                '>' => {
+                    if (self.comp.langopts.hasDigraphs()) {
+                        id = .r_bracket;
+                        self.index += 1;
+                    } else {
+                        id = .colon;
+                    }
+                    break;
+                },
+                ':' => {
+                    if (self.comp.langopts.standard.atLeast(.c2x)) {
+                        id = .colon_colon;
+                        self.index += 1;
+                        break;
+                    } else {
+                        id = .colon;
+                        break;
+                    }
+                },
+                else => {
+                    id = .colon;
+                    break;
+                },
+            },
+            .percent => switch (c) {
+                '=' => {
+                    id = .percent_equal;
+                    self.index += 1;
+                    break;
+                },
+                '>' => {
+                    if (self.comp.langopts.hasDigraphs()) {
+                        id = .r_brace;
+                        self.index += 1;
+                    } else {
+                        id = .percent;
+                    }
+                    break;
+                },
+                ':' => {
+                    if (self.comp.langopts.hasDigraphs()) {
+                        state = .hash_digraph;
+                    } else {
+                        id = .percent;
+                        break;
+                    }
+                },
+                else => {
+                    id = .percent;
+                    break;
+                },
+            },
+            .asterisk => switch (c) {
+                '=' => {
+                    id = .asterisk_equal;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .asterisk;
+                    break;
+                },
+            },
+            .plus => switch (c) {
+                '=' => {
+                    id = .plus_equal;
+                    self.index += 1;
+                    break;
+                },
+                '+' => {
+                    id = .plus_plus;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .plus;
+                    break;
+                },
+            },
+            .angle_bracket_left => switch (c) {
+                '<' => state = .angle_bracket_angle_bracket_left,
+                '=' => {
+                    id = .angle_bracket_left_equal;
+                    self.index += 1;
+                    break;
+                },
+                ':' => {
+                    if (self.comp.langopts.hasDigraphs()) {
+                        id = .l_bracket;
+                        self.index += 1;
+                    } else {
+                        id = .angle_bracket_left;
+                    }
+                    break;
+                },
+                '%' => {
+                    if (self.comp.langopts.hasDigraphs()) {
+                        id = .l_brace;
+                        self.index += 1;
+                    } else {
+                        id = .angle_bracket_left;
+                    }
+                    break;
+                },
+                else => {
+                    id = .angle_bracket_left;
+                    break;
+                },
+            },
+            .angle_bracket_angle_bracket_left => switch (c) {
+                '=' => {
+                    id = .angle_bracket_angle_bracket_left_equal;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .angle_bracket_angle_bracket_left;
+                    break;
+                },
+            },
+            .angle_bracket_right => switch (c) {
+                '>' => state = .angle_bracket_angle_bracket_right,
+                '=' => {
+                    id = .angle_bracket_right_equal;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .angle_bracket_right;
+                    break;
+                },
+            },
+            .angle_bracket_angle_bracket_right => switch (c) {
+                '=' => {
+                    id = .angle_bracket_angle_bracket_right_equal;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .angle_bracket_angle_bracket_right;
+                    break;
+                },
+            },
+            .caret => switch (c) {
+                '=' => {
+                    id = .caret_equal;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .caret;
+                    break;
+                },
+            },
+            .period => switch (c) {
+                '.' => state = .period2,
+                '0'...'9' => state = .pp_num,
+                else => {
+                    id = .period;
+                    break;
+                },
+            },
+            .period2 => switch (c) {
+                '.' => {
+                    id = .ellipsis;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .period;
+                    self.index -= 1;
+                    break;
+                },
+            },
+            .minus => switch (c) {
+                '>' => {
+                    id = .arrow;
+                    self.index += 1;
+                    break;
+                },
+                '=' => {
+                    id = .minus_equal;
+                    self.index += 1;
+                    break;
+                },
+                '-' => {
+                    id = .minus_minus;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .minus;
+                    break;
+                },
+            },
+            .ampersand => switch (c) {
+                '&' => {
+                    id = .ampersand_ampersand;
+                    self.index += 1;
+                    break;
+                },
+                '=' => {
+                    id = .ampersand_equal;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .ampersand;
+                    break;
+                },
+            },
+            .hash => switch (c) {
+                '#' => {
+                    id = .hash_hash;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .hash;
+                    break;
+                },
+            },
+            .hash_digraph => switch (c) {
+                '%' => state = .hash_hash_digraph_partial,
+                else => {
+                    id = .hash;
+                    break;
+                },
+            },
+            .hash_hash_digraph_partial => switch (c) {
+                ':' => {
+                    id = .hash_hash;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .hash;
+                    self.index -= 1; // re-tokenize the percent
+                    break;
+                },
+            },
+            .slash => switch (c) {
+                '/' => state = .line_comment,
+                '*' => state = .multi_line_comment,
+                '=' => {
+                    id = .slash_equal;
+                    self.index += 1;
+                    break;
+                },
+                else => {
+                    id = .slash;
+                    break;
+                },
+            },
+            .line_comment => switch (c) {
+                '\n' => {
+                    self.index -= 1;
+                    state = .start;
+                },
+                else => {},
+            },
+            .multi_line_comment => switch (c) {
+                '*' => state = .multi_line_comment_asterisk,
+                '\n' => self.line += 1,
+                else => {},
+            },
+            .multi_line_comment_asterisk => switch (c) {
+                '/' => state = .multi_line_comment_done,
+                '\n' => {
+                    self.line += 1;
+                    state = .multi_line_comment;
+                },
+                '*' => {},
+                else => state = .multi_line_comment,
+            },
+            .multi_line_comment_done => switch (c) {
+                '\n' => {
+                    start = self.index;
+                    id = .nl;
+                    self.index += 1;
+                    self.line += 1;
+                    break;
+                },
+                '\r' => unreachable,
+                '\t', '\x0B', '\x0C', ' ' => {
+                    start = self.index;
+                    state = .whitespace;
+                },
+                else => {
+                    id = .whitespace;
+                    break;
+                },
+            },
+            .pp_num => switch (c) {
+                'a'...'d',
+                'A'...'D',
+                'f'...'o',
+                'F'...'O',
+                'q'...'z',
+                'Q'...'Z',
+                '0'...'9',
+                '_',
+                '.',
+                => {},
+                'e', 'E', 'p', 'P' => state = .pp_num_exponent,
+                '\'' => if (self.comp.langopts.standard.atLeast(.c2x)) {
+                    state = .pp_num_digit_separator;
+                } else {
+                    id = .pp_num;
+                    break;
+                },
+                else => {
+                    id = .pp_num;
+                    break;
+                },
+            },
+            .pp_num_digit_separator => switch (c) {
+                'a'...'d',
+                'A'...'D',
+                'f'...'o',
+                'F'...'O',
+                'q'...'z',
+                'Q'...'Z',
+                '0'...'9',
+                '_',
+                => state = .pp_num,
+                else => {
+                    self.index -= 1;
+                    id = .pp_num;
+                    break;
+                },
+            },
+            .pp_num_exponent => switch (c) {
+                'a'...'z',
+                'A'...'Z',
+                '0'...'9',
+                '_',
+                '.',
+                '+',
+                '-',
+                => state = .pp_num,
+                else => {
+                    id = .pp_num;
+                    break;
+                },
+            },
+        }
+    } else if (self.index == self.buf.len) {
+        switch (state) {
+            .start, .line_comment => {},
+            .u, .u8, .U, .L, .identifier => id = Token.getTokenId(self.comp, self.buf[start..self.index]),
+            .extended_identifier => id = .extended_identifier,
+            .period2,
+            .string_literal,
+            .char_literal_start,
+            .char_literal,
+            .escape_sequence,
+            .octal_escape,
+            .hex_escape,
+            .unicode_escape,
+            .multi_line_comment,
+            .multi_line_comment_asterisk,
+            => id = .invalid,
+
+            .whitespace => id = .whitespace,
+            .multi_line_comment_done => id = .whitespace,
+
+            .equal => id = .equal,
+            .bang => id = .bang,
+            .minus => id = .minus,
+            .slash => id = .slash,
+            .ampersand => id = .ampersand,
+            .hash => id = .hash,
+            .period => id = .period,
+            .pipe => id = .pipe,
+            .angle_bracket_angle_bracket_right => id = .angle_bracket_angle_bracket_right,
+            .angle_bracket_right => id = .angle_bracket_right,
+            .angle_bracket_angle_bracket_left => id = .angle_bracket_angle_bracket_left,
+            .angle_bracket_left => id = .angle_bracket_left,
+            .plus => id = .plus,
+            .colon => id = .colon,
+            .percent => id = .percent,
+            .caret => id = .caret,
+            .asterisk => id = .asterisk,
+            .hash_digraph => id = .hash,
+            .hash_hash_digraph_partial => {
+                id = .hash;
+                self.index -= 1; // re-tokenize the percent
+            },
+            .pp_num, .pp_num_exponent, .pp_num_digit_separator => id = .pp_num,
+        }
+    }
+
+    return .{
+        .id = id,
+        .start = start,
+        .end = self.index,
+        .line = self.line,
+        .source = self.source,
+    };
+}
+
+pub fn nextNoWS(self: *Tokenizer) Token {
+    var tok = self.next();
+    while (tok.id == .whitespace) tok = self.next();
+    return tok;
+}
+
+test "operators" {
+    try expectTokens(
+        \\ ! != | || |= = ==
+        \\ ( ) { } [ ] . .. ...
+        \\ ^ ^= + ++ += - -- -=
+        \\ * *= % %= -> : ; / /=
+        \\ , & && &= ? < <= <<
+        \\  <<= > >= >> >>= ~ # ##
+        \\
+    , &.{
+        .bang,
+        .bang_equal,
+        .pipe,
+        .pipe_pipe,
+        .pipe_equal,
+        .equal,
+        .equal_equal,
+        .nl,
+        .l_paren,
+        .r_paren,
+        .l_brace,
+        .r_brace,
+        .l_bracket,
+        .r_bracket,
+        .period,
+        .period,
+        .period,
+        .ellipsis,
+        .nl,
+        .caret,
+        .caret_equal,
+        .plus,
+        .plus_plus,
+        .plus_equal,
+        .minus,
+        .minus_minus,
+        .minus_equal,
+        .nl,
+        .asterisk,
+        .asterisk_equal,
+        .percent,
+        .percent_equal,
+        .arrow,
+        .colon,
+        .semicolon,
+        .slash,
+        .slash_equal,
+        .nl,
+        .comma,
+        .ampersand,
+        .ampersand_ampersand,
+        .ampersand_equal,
+        .question_mark,
+        .angle_bracket_left,
+        .angle_bracket_left_equal,
+        .angle_bracket_angle_bracket_left,
+        .nl,
+        .angle_bracket_angle_bracket_left_equal,
+        .angle_bracket_right,
+        .angle_bracket_right_equal,
+        .angle_bracket_angle_bracket_right,
+        .angle_bracket_angle_bracket_right_equal,
+        .tilde,
+        .hash,
+        .hash_hash,
+        .nl,
+    });
+}
+
+test "keywords" {
+    try expectTokens(
+        \\auto __auto_type break case char const continue default do
+        \\double else enum extern float for goto if int 
+        \\long register return short signed sizeof static 
+        \\struct switch typedef union unsigned void volatile 
+        \\while _Bool _Complex _Imaginary inline restrict _Alignas 
+        \\_Alignof _Atomic _Generic _Noreturn _Static_assert _Thread_local 
+        \\__attribute __attribute__
+        \\
+    , &.{
+        .keyword_auto,
+        .keyword_auto_type,
+        .keyword_break,
+        .keyword_case,
+        .keyword_char,
+        .keyword_const,
+        .keyword_continue,
+        .keyword_default,
+        .keyword_do,
+        .nl,
+        .keyword_double,
+        .keyword_else,
+        .keyword_enum,
+        .keyword_extern,
+        .keyword_float,
+        .keyword_for,
+        .keyword_goto,
+        .keyword_if,
+        .keyword_int,
+        .nl,
+        .keyword_long,
+        .keyword_register,
+        .keyword_return,
+        .keyword_short,
+        .keyword_signed,
+        .keyword_sizeof,
+        .keyword_static,
+        .nl,
+        .keyword_struct,
+        .keyword_switch,
+        .keyword_typedef,
+        .keyword_union,
+        .keyword_unsigned,
+        .keyword_void,
+        .keyword_volatile,
+        .nl,
+        .keyword_while,
+        .keyword_bool,
+        .keyword_complex,
+        .keyword_imaginary,
+        .keyword_inline,
+        .keyword_restrict,
+        .keyword_alignas,
+        .nl,
+        .keyword_alignof,
+        .keyword_atomic,
+        .keyword_generic,
+        .keyword_noreturn,
+        .keyword_static_assert,
+        .keyword_thread_local,
+        .nl,
+        .keyword_attribute1,
+        .keyword_attribute2,
+        .nl,
+    });
+}
+
+test "preprocessor keywords" {
+    try expectTokens(
+        \\#include
+        \\#include_next
+        \\#embed
+        \\#define
+        \\#ifdef
+        \\#ifndef
+        \\#error
+        \\#pragma
+        \\
+    , &.{
+        .hash,
+        .keyword_include,
+        .nl,
+        .hash,
+        .keyword_include_next,
+        .nl,
+        .hash,
+        .keyword_embed,
+        .nl,
+        .hash,
+        .keyword_define,
+        .nl,
+        .hash,
+        .keyword_ifdef,
+        .nl,
+        .hash,
+        .keyword_ifndef,
+        .nl,
+        .hash,
+        .keyword_error,
+        .nl,
+        .hash,
+        .keyword_pragma,
+        .nl,
+    });
+}
+
+test "line continuation" {
+    try expectTokens(
+        \\#define foo \
+        \\  bar
+        \\"foo\
+        \\ bar"
+        \\#define "foo"
+        \\ "bar"
+        \\#define "foo" \
+        \\ "bar"
+    , &.{
+        .hash,
+        .keyword_define,
+        .identifier,
+        .identifier,
+        .nl,
+        .string_literal,
+        .nl,
+        .hash,
+        .keyword_define,
+        .string_literal,
+        .nl,
+        .string_literal,
+        .nl,
+        .hash,
+        .keyword_define,
+        .string_literal,
+        .string_literal,
+    });
+}
+
+test "string prefix" {
+    try expectTokens(
+        \\"foo"
+        \\u"foo"
+        \\u8"foo"
+        \\U"foo"
+        \\L"foo"
+        \\'foo'
+        \\u8'A'
+        \\u'foo'
+        \\U'foo'
+        \\L'foo'
+        \\
+    , &.{
+        .string_literal,
+        .nl,
+        .string_literal_utf_16,
+        .nl,
+        .string_literal_utf_8,
+        .nl,
+        .string_literal_utf_32,
+        .nl,
+        .string_literal_wide,
+        .nl,
+        .char_literal,
+        .nl,
+        .char_literal_utf_8,
+        .nl,
+        .char_literal_utf_16,
+        .nl,
+        .char_literal_utf_32,
+        .nl,
+        .char_literal_wide,
+        .nl,
+    });
+}
+
+test "num suffixes" {
+    try expectTokens(
+        \\ 1.0f 1.0L 1.0 .0 1. 0x1p0f 0X1p0
+        \\ 0l 0lu 0ll 0llu 0
+        \\ 1u 1ul 1ull 1
+        \\ 1.0i 1.0I
+        \\ 1.0if 1.0If 1.0fi 1.0fI
+        \\ 1.0il 1.0Il 1.0li 1.0lI
+        \\
+    , &.{
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .nl,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .nl,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .nl,
+        .pp_num,
+        .pp_num,
+        .nl,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .nl,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .pp_num,
+        .nl,
+    });
+}
+
+test "comments" {
+    try expectTokens(
+        \\//foo
+        \\#foo
+    , &.{
+        .nl,
+        .hash,
+        .identifier,
+    });
+}
+
+test "extended identifiers" {
+    try expectTokens("๐“ช๐“ป๐“ธ๐“ฌ๐“ฌ", &.{.extended_identifier});
+    try expectTokens("u๐“ช๐“ป๐“ธ๐“ฌ๐“ฌ", &.{.extended_identifier});
+    try expectTokens("u8๐“ช๐“ป๐“ธ๐“ฌ๐“ฌ", &.{.extended_identifier});
+    try expectTokens("U๐“ช๐“ป๐“ธ๐“ฌ๐“ฌ", &.{.extended_identifier});
+    try expectTokens("L๐“ช๐“ป๐“ธ๐“ฌ๐“ฌ", &.{.extended_identifier});
+    try expectTokens("1โ„ข", &.{ .pp_num, .extended_identifier });
+    try expectTokens("1.โ„ข", &.{ .pp_num, .extended_identifier });
+    try expectTokens("..โ„ข", &.{ .period, .period, .extended_identifier });
+    try expectTokens("0โ„ข", &.{ .pp_num, .extended_identifier });
+    try expectTokens("0b\u{E0000}", &.{ .pp_num, .extended_identifier });
+    try expectTokens("0b0\u{E0000}", &.{ .pp_num, .extended_identifier });
+    try expectTokens("01\u{E0000}", &.{ .pp_num, .extended_identifier });
+    try expectTokens("010\u{E0000}", &.{ .pp_num, .extended_identifier });
+    try expectTokens("0x\u{E0000}", &.{ .pp_num, .extended_identifier });
+    try expectTokens("0x0\u{E0000}", &.{ .pp_num, .extended_identifier });
+    try expectTokens("\"\\0\u{E0000}\"", &.{.string_literal});
+    try expectTokens("\"\\x\u{E0000}\"", &.{.string_literal});
+    try expectTokens("\"\\u\u{E0000}\"", &.{ .invalid, .extended_identifier, .invalid });
+    try expectTokens("1e\u{E0000}", &.{ .pp_num, .extended_identifier });
+    try expectTokens("1e1\u{E0000}", &.{ .pp_num, .extended_identifier });
+}
+
+test "digraphs" {
+    try expectTokens("%:<::><%%>%:%:", &.{ .hash, .l_bracket, .r_bracket, .l_brace, .r_brace, .hash_hash });
+    try expectTokens("\"%:<::><%%>%:%:\"", &.{.string_literal});
+    try expectTokens("%:%42 %:%", &.{ .hash, .percent, .pp_num, .hash, .percent });
+}
+
+test "C23 keywords" {
+    try expectTokensExtra("true false alignas alignof bool static_assert thread_local nullptr", &.{
+        .keyword_true,
+        .keyword_false,
+        .keyword_c23_alignas,
+        .keyword_c23_alignof,
+        .keyword_c23_bool,
+        .keyword_c23_static_assert,
+        .keyword_c23_thread_local,
+        .keyword_nullptr,
+    }, .c2x);
+}
+
+fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, standard: ?LangOpts.Standard) !void {
+    var comp = Compilation.init(std.testing.allocator);
+    defer comp.deinit();
+    if (standard) |provided| {
+        comp.langopts.standard = provided;
+    }
+    const source = try comp.addSourceFromBuffer("path", contents);
+    var tokenizer = Tokenizer{
+        .buf = source.buf,
+        .source = source.id,
+        .comp = &comp,
+    };
+    var i: usize = 0;
+    while (i < expected_tokens.len) {
+        const token = tokenizer.next();
+        if (token.id == .whitespace) continue;
+        const expected_token_id = expected_tokens[i];
+        i += 1;
+        if (!std.meta.eql(token.id, expected_token_id)) {
+            std.debug.print("expected {s}, found {s}\n", .{ @tagName(expected_token_id), @tagName(token.id) });
+            return error.TokensDoNotEqual;
+        }
+    }
+    const last_token = tokenizer.next();
+    try std.testing.expect(last_token.id == .eof);
+}
+
+fn expectTokens(contents: []const u8, expected_tokens: []const Token.Id) !void {
+    return expectTokensExtra(contents, expected_tokens, null);
+}
deps/aro/Toolchain.zig
@@ -0,0 +1,493 @@
+const std = @import("std");
+const Driver = @import("Driver.zig");
+const Compilation = @import("Compilation.zig");
+const util = @import("util.zig");
+const mem = std.mem;
+const system_defaults = @import("system_defaults");
+const target_util = @import("target.zig");
+const Linux = @import("toolchains/Linux.zig");
+const Multilib = @import("Driver/Multilib.zig");
+const Filesystem = @import("Driver/Filesystem.zig").Filesystem;
+
+const Toolchain = @This();
+
+pub const PathList = std.ArrayListUnmanaged([]const u8);
+
+pub const RuntimeLibKind = enum {
+    compiler_rt,
+    libgcc,
+};
+
+pub const FileKind = enum {
+    object,
+    static,
+    shared,
+};
+
+pub const LibGCCKind = enum {
+    unspecified,
+    static,
+    shared,
+};
+
+pub const UnwindLibKind = enum {
+    none,
+    compiler_rt,
+    libgcc,
+};
+
+const Inner = union(enum) {
+    uninitialized,
+    linux: Linux,
+    unknown: void,
+
+    fn deinit(self: *Inner, allocator: mem.Allocator) void {
+        switch (self.*) {
+            .linux => |*linux| linux.deinit(allocator),
+            .uninitialized, .unknown => {},
+        }
+    }
+};
+
+filesystem: Filesystem = .{ .real = {} },
+driver: *Driver,
+arena: mem.Allocator,
+
+/// The list of toolchain specific path prefixes to search for libraries.
+library_paths: PathList = .{},
+
+/// The list of toolchain specific path prefixes to search for files.
+file_paths: PathList = .{},
+
+/// The list of toolchain specific path prefixes to search for programs.
+program_paths: PathList = .{},
+
+selected_multilib: Multilib = .{},
+
+inner: Inner = .{ .uninitialized = {} },
+
+pub fn getTarget(tc: *const Toolchain) std.Target {
+    return tc.driver.comp.target;
+}
+
+fn getDefaultLinker(tc: *const Toolchain) []const u8 {
+    return switch (tc.inner) {
+        .uninitialized => unreachable,
+        .linux => |linux| linux.getDefaultLinker(tc.getTarget()),
+        .unknown => "ld",
+    };
+}
+
+/// Call this after driver has finished parsing command line arguments to find the toolchain
+pub fn discover(tc: *Toolchain) !void {
+    if (tc.inner != .uninitialized) return;
+
+    const target = tc.getTarget();
+    tc.inner = switch (target.os.tag) {
+        .elfiamcu,
+        .linux,
+        => if (target.cpu.arch == .hexagon)
+            .{ .unknown = {} } // TODO
+        else if (target.cpu.arch.isMIPS())
+            .{ .unknown = {} } // TODO
+        else if (target.cpu.arch.isPPC())
+            .{ .unknown = {} } // TODO
+        else if (target.cpu.arch == .ve)
+            .{ .unknown = {} } // TODO
+        else
+            .{ .linux = .{} },
+        else => .{ .unknown = {} }, // TODO
+    };
+    return switch (tc.inner) {
+        .uninitialized => unreachable,
+        .linux => |*linux| linux.discover(tc),
+        .unknown => {},
+    };
+}
+
+pub fn deinit(tc: *Toolchain) void {
+    const gpa = tc.driver.comp.gpa;
+    tc.inner.deinit(gpa);
+
+    tc.library_paths.deinit(gpa);
+    tc.file_paths.deinit(gpa);
+    tc.program_paths.deinit(gpa);
+}
+
+/// Write linker path to `buf` and return a slice of it
+pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 {
+    // --ld-path= takes precedence over -fuse-ld= and specifies the executable
+    // name. -B, COMPILER_PATH and PATH are consulted if the value does not
+    // contain a path component separator.
+    // -fuse-ld=lld can be used with --ld-path= to indicate that the binary
+    // that --ld-path= points to is lld.
+    const use_linker = tc.driver.use_linker orelse system_defaults.linker;
+
+    if (tc.driver.linker_path) |ld_path| {
+        var path = ld_path;
+        if (path.len > 0) {
+            if (std.fs.path.dirname(path) == null) {
+                path = tc.getProgramPath(path, buf);
+            }
+            if (tc.filesystem.canExecute(path)) {
+                return path;
+            }
+        }
+        return tc.driver.fatal(
+            "invalid linker name in argument '--ld-path={s}'",
+            .{path},
+        );
+    }
+
+    // If we're passed -fuse-ld= with no argument, or with the argument ld,
+    // then use whatever the default system linker is.
+    if (use_linker.len == 0 or mem.eql(u8, use_linker, "ld")) {
+        const default = tc.getDefaultLinker();
+        if (std.fs.path.isAbsolute(default)) return default;
+        return tc.getProgramPath(default, buf);
+    }
+
+    // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
+    // for the linker flavor is brittle. In addition, prepending "ld." or "ld64."
+    // to a relative path is surprising. This is more complex due to priorities
+    // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead.
+    if (mem.indexOfScalar(u8, use_linker, '/') != null) {
+        try tc.driver.comp.diag.add(.{ .tag = .fuse_ld_path }, &.{});
+    }
+
+    if (std.fs.path.isAbsolute(use_linker)) {
+        if (tc.filesystem.canExecute(use_linker)) {
+            return use_linker;
+        }
+    } else {
+        var linker_name = try std.ArrayList(u8).initCapacity(tc.driver.comp.gpa, 5 + use_linker.len); // "ld64." ++ use_linker
+        defer linker_name.deinit();
+        if (tc.getTarget().isDarwin()) {
+            linker_name.appendSliceAssumeCapacity("ld64.");
+        } else {
+            linker_name.appendSliceAssumeCapacity("ld.");
+        }
+        linker_name.appendSliceAssumeCapacity(use_linker);
+        const linker_path = tc.getProgramPath(linker_name.items, buf);
+        if (tc.filesystem.canExecute(linker_path)) {
+            return linker_path;
+        }
+    }
+
+    if (tc.driver.use_linker) |linker| {
+        return tc.driver.fatal(
+            "invalid linker name in argument '-fuse-ld={s}'",
+            .{linker},
+        );
+    }
+    const default_linker = tc.getDefaultLinker();
+    return tc.getProgramPath(default_linker, buf);
+}
+
+const TargetSpecificToolName = std.BoundedArray(u8, 64);
+
+/// If an explicit target is provided, also check the prefixed tool-specific name
+/// TODO: this isn't exactly right since our target names don't necessarily match up
+/// with GCC's.
+/// For example the Zig target `arm-freestanding-eabi` would need the `arm-none-eabi` tools
+fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, target_specific: *TargetSpecificToolName) std.BoundedArray([]const u8, 2) {
+    var possible_names: std.BoundedArray([]const u8, 2) = .{};
+    if (raw_triple) |triple| {
+        const w = target_specific.writer();
+        if (w.print("{s}-{s}", .{ triple, name })) {
+            possible_names.appendAssumeCapacity(target_specific.constSlice());
+        } else |_| {}
+    }
+    possible_names.appendAssumeCapacity(name);
+
+    return possible_names;
+}
+
+/// Add toolchain `file_paths` to argv as `-L` arguments
+pub fn addFilePathLibArgs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
+    try argv.ensureUnusedCapacity(tc.file_paths.items.len);
+
+    var bytes_needed: usize = 0;
+    for (tc.file_paths.items) |path| {
+        bytes_needed += path.len + 2; // +2 for `-L`
+    }
+    var bytes = try tc.arena.alloc(u8, bytes_needed);
+    var index: usize = 0;
+    for (tc.file_paths.items) |path| {
+        @memcpy(bytes[index..][0..2], "-L");
+        @memcpy(bytes[index + 2 ..][0..path.len], path);
+        argv.appendAssumeCapacity(bytes[index..][0 .. path.len + 2]);
+        index += path.len + 2;
+    }
+}
+
+/// Search for an executable called `name` or `{triple}-{name} in program_paths and the $PATH environment variable
+/// If not found there, just use `name`
+/// Writes the result to `buf` and returns a slice of it
+fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8 {
+    var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+    var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+
+    var tool_specific_name: TargetSpecificToolName = .{};
+    const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_name);
+
+    for (possible_names.constSlice()) |tool_name| {
+        for (tc.program_paths.items) |program_path| {
+            defer fib.reset();
+
+            const candidate = std.fs.path.join(fib.allocator(), &.{ program_path, tool_name }) catch continue;
+
+            if (tc.filesystem.canExecute(candidate) and candidate.len <= buf.len) {
+                @memcpy(buf[0..candidate.len], candidate);
+                return buf[0..candidate.len];
+            }
+        }
+        return tc.filesystem.findProgramByName(tc.driver.comp.gpa, name, tc.driver.comp.environment.path, buf) orelse continue;
+    }
+    @memcpy(buf[0..name.len], name);
+    return buf[0..name.len];
+}
+
+pub fn getSysroot(tc: *const Toolchain) []const u8 {
+    return tc.driver.sysroot orelse system_defaults.sysroot;
+}
+
+/// Search for `name` in a variety of places
+/// TODO: cache results based on `name` so we're not repeatedly allocating the same strings?
+pub fn getFilePath(tc: *const Toolchain, name: []const u8) ![]const u8 {
+    var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+    var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+    const allocator = fib.allocator();
+
+    const sysroot = tc.getSysroot();
+
+    // todo check resource dir
+    // todo check compiler RT path
+    const aro_dir = std.fs.path.dirname(tc.driver.aro_name) orelse "";
+    const candidate = try std.fs.path.join(allocator, &.{ aro_dir, "..", name });
+    if (tc.filesystem.exists(candidate)) {
+        return tc.arena.dupe(u8, candidate);
+    }
+
+    if (tc.searchPaths(&fib, sysroot, tc.library_paths.items, name)) |path| {
+        return tc.arena.dupe(u8, path);
+    }
+
+    if (tc.searchPaths(&fib, sysroot, tc.file_paths.items, name)) |path| {
+        return try tc.arena.dupe(u8, path);
+    }
+
+    return name;
+}
+
+/// Search a list of `path_prefixes` for the existence `name`
+/// Assumes that `fba` is a fixed-buffer allocator, so does not free joined path candidates
+fn searchPaths(tc: *const Toolchain, fib: *std.heap.FixedBufferAllocator, sysroot: []const u8, path_prefixes: []const []const u8, name: []const u8) ?[]const u8 {
+    for (path_prefixes) |path| {
+        fib.reset();
+        if (path.len == 0) continue;
+
+        const candidate = if (path[0] == '=')
+            std.fs.path.join(fib.allocator(), &.{ sysroot, path[1..], name }) catch continue
+        else
+            std.fs.path.join(fib.allocator(), &.{ path, name }) catch continue;
+
+        if (tc.filesystem.exists(candidate)) {
+            return candidate;
+        }
+    }
+    return null;
+}
+
+const PathKind = enum {
+    library,
+    file,
+    program,
+};
+
+/// Join `components` into a path. If the path exists, dupe it into the toolchain arena and
+/// add it to the specified path list.
+pub fn addPathIfExists(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void {
+    var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+    var fib = std.heap.FixedBufferAllocator.init(&path_buf);
+
+    const candidate = try std.fs.path.join(fib.allocator(), components);
+
+    if (tc.filesystem.exists(candidate)) {
+        const duped = try tc.arena.dupe(u8, candidate);
+        const dest = switch (dest_kind) {
+            .library => &tc.library_paths,
+            .file => &tc.file_paths,
+            .program => &tc.program_paths,
+        };
+        try dest.append(tc.driver.comp.gpa, duped);
+    }
+}
+
+/// Join `components` using the toolchain arena and add the resulting path to `dest_kind`. Does not check
+/// whether the path actually exists
+pub fn addPathFromComponents(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void {
+    const full_path = try std.fs.path.join(tc.arena, components);
+    const dest = switch (dest_kind) {
+        .library => &tc.library_paths,
+        .file => &tc.file_paths,
+        .program => &tc.program_paths,
+    };
+    try dest.append(tc.driver.comp.gpa, full_path);
+}
+
+/// Add linker args to `argv`. Does not add path to linker executable as first item; that must be handled separately
+/// Items added to `argv` will be string literals or owned by `tc.arena` so they must not be individually freed
+pub fn buildLinkerArgs(tc: *Toolchain, argv: *std.ArrayList([]const u8)) !void {
+    return switch (tc.inner) {
+        .uninitialized => unreachable,
+        .linux => |*linux| linux.buildLinkerArgs(tc, argv),
+        .unknown => @panic("This toolchain does not support linking yet"),
+    };
+}
+
+fn getDefaultRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
+    if (tc.getTarget().isAndroid()) {
+        return .compiler_rt;
+    }
+    return .libgcc;
+}
+
+pub fn getRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
+    const libname = tc.driver.rtlib orelse system_defaults.rtlib;
+    if (mem.eql(u8, libname, "compiler-rt"))
+        return .compiler_rt
+    else if (mem.eql(u8, libname, "libgcc"))
+        return .libgcc
+    else
+        return tc.getDefaultRuntimeLibKind();
+}
+
+/// TODO
+pub fn getCompilerRt(tc: *const Toolchain, component: []const u8, file_kind: FileKind) ![]const u8 {
+    _ = file_kind;
+    _ = component;
+    _ = tc;
+    return "";
+}
+
+fn getLibGCCKind(tc: *const Toolchain) LibGCCKind {
+    const target = tc.getTarget();
+    if (tc.driver.static_libgcc or tc.driver.static or tc.driver.static_pie or target.isAndroid()) {
+        return .static;
+    }
+    if (tc.driver.shared_libgcc) {
+        return .shared;
+    }
+    return .unspecified;
+}
+
+fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind {
+    const libname = tc.driver.unwindlib orelse system_defaults.unwindlib;
+    if (libname.len == 0 or mem.eql(u8, libname, "platform")) {
+        switch (tc.getRuntimeLibKind()) {
+            .compiler_rt => {
+                const target = tc.getTarget();
+                if (target.isAndroid() or target.os.tag == .aix) {
+                    return .compiler_rt;
+                } else {
+                    return .none;
+                }
+            },
+            .libgcc => return .libgcc,
+        }
+    } else if (mem.eql(u8, libname, "none")) {
+        return .none;
+    } else if (mem.eql(u8, libname, "libgcc")) {
+        return .libgcc;
+    } else if (mem.eql(u8, libname, "libunwind")) {
+        if (tc.getRuntimeLibKind() == .libgcc) {
+            try tc.driver.comp.diag.add(.{ .tag = .incompatible_unwindlib }, &.{});
+        }
+        return .compiler_rt;
+    } else {
+        unreachable;
+    }
+}
+
+fn getAsNeededOption(is_solaris: bool, needed: bool) []const u8 {
+    if (is_solaris) {
+        return if (needed) "-zignore" else "-zrecord";
+    } else {
+        return if (needed) "--as-needed" else "--no-as-needed";
+    }
+}
+
+fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
+    const unw = try tc.getUnwindLibKind();
+    const target = tc.getTarget();
+    if ((target.isAndroid() and unw == .libgcc) or
+        target.os.tag == .elfiamcu or
+        target.ofmt == .wasm or
+        target_util.isWindowsMSVCEnvironment(target) or
+        unw == .none) return;
+
+    const lgk = tc.getLibGCCKind();
+    const as_needed = lgk == .unspecified and !target.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix;
+    if (as_needed) {
+        try argv.append(getAsNeededOption(target.os.tag == .solaris, true));
+    }
+    switch (unw) {
+        .none => return,
+        .libgcc => if (lgk == .static) try argv.append("-lgcc_eh") else try argv.append("-lgcc_s"),
+        .compiler_rt => if (target.os.tag == .aix) {
+            if (lgk != .static) {
+                try argv.append("-lunwind");
+            }
+        } else if (lgk == .static) {
+            try argv.append("-l:libunwind.a");
+        } else if (lgk == .shared) {
+            if (target_util.isCygwinMinGW(target)) {
+                try argv.append("-l:libunwind.dll.a");
+            } else {
+                try argv.append("-l:libunwind.so");
+            }
+        } else {
+            try argv.append("-lunwind");
+        },
+    }
+
+    if (as_needed) {
+        try argv.append(getAsNeededOption(target.os.tag == .solaris, false));
+    }
+}
+
+fn addLibGCC(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
+    const libgcc_kind = tc.getLibGCCKind();
+    if (libgcc_kind == .static or libgcc_kind == .unspecified) {
+        try argv.append("-lgcc");
+    }
+    try tc.addUnwindLibrary(argv);
+    if (libgcc_kind == .shared) {
+        try argv.append("-lgcc");
+    }
+}
+
+pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
+    const target = tc.getTarget();
+    const rlt = tc.getRuntimeLibKind();
+    switch (rlt) {
+        .compiler_rt => {
+            // TODO
+        },
+        .libgcc => {
+            if (target_util.isKnownWindowsMSVCEnvironment(target)) {
+                const rtlib_str = tc.driver.rtlib orelse system_defaults.rtlib;
+                if (!mem.eql(u8, rtlib_str, "platform")) {
+                    try tc.driver.comp.diag.add(.{ .tag = .unsupported_rtlib_gcc, .extra = .{ .str = "MSVC" } }, &.{});
+                }
+            } else {
+                try tc.addLibGCC(argv);
+            }
+        },
+    }
+
+    if (target.isAndroid() and !tc.driver.static and !tc.driver.static_pie) {
+        try argv.append("-ldl");
+    }
+}
deps/aro/Tree.zig
@@ -0,0 +1,1312 @@
+const std = @import("std");
+const Type = @import("Type.zig");
+const Tokenizer = @import("Tokenizer.zig");
+const Compilation = @import("Compilation.zig");
+const Source = @import("Source.zig");
+const Attribute = @import("Attribute.zig");
+const Value = @import("Value.zig");
+const StringInterner = @import("StringInterner.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+
+const Tree = @This();
+
+pub const Token = struct {
+    id: Id,
+    flags: packed struct {
+        expansion_disabled: bool = false,
+        is_macro_arg: bool = false,
+    } = .{},
+    /// This location contains the actual token slice which might be generated.
+    /// If it is generated then there is guaranteed to be at least one
+    /// expansion location.
+    loc: Source.Location,
+    expansion_locs: ?[*]Source.Location = null,
+
+    pub fn expansionSlice(tok: Token) []const Source.Location {
+        const locs = tok.expansion_locs orelse return &[0]Source.Location{};
+        var i: usize = 0;
+        while (locs[i].id != .unused) : (i += 1) {}
+        return locs[0..i];
+    }
+
+    pub fn addExpansionLocation(tok: *Token, gpa: std.mem.Allocator, new: []const Source.Location) !void {
+        if (new.len == 0 or tok.id == .whitespace) return;
+        var list = std.ArrayList(Source.Location).init(gpa);
+        defer {
+            @memset(list.items.ptr[list.items.len..list.capacity], .{});
+            // Add a sentinel to indicate the end of the list since
+            // the ArrayList's capacity isn't guaranteed to be exactly
+            // what we ask for.
+            if (list.capacity > 0) {
+                list.items.ptr[list.capacity - 1].byte_offset = 1;
+            }
+            tok.expansion_locs = list.items.ptr;
+        }
+
+        if (tok.expansion_locs) |locs| {
+            var i: usize = 0;
+            while (locs[i].id != .unused) : (i += 1) {}
+            list.items = locs[0..i];
+            while (locs[i].byte_offset != 1) : (i += 1) {}
+            list.capacity = i + 1;
+        }
+
+        const min_len = @max(list.items.len + new.len + 1, 4);
+        const wanted_len = std.math.ceilPowerOfTwo(usize, min_len) catch
+            return error.OutOfMemory;
+        try list.ensureTotalCapacity(wanted_len);
+
+        for (new) |new_loc| {
+            if (new_loc.id == .generated) continue;
+            list.appendAssumeCapacity(new_loc);
+        }
+    }
+
+    pub fn free(expansion_locs: ?[*]Source.Location, gpa: std.mem.Allocator) void {
+        const locs = expansion_locs orelse return;
+        var i: usize = 0;
+        while (locs[i].id != .unused) : (i += 1) {}
+        while (locs[i].byte_offset != 1) : (i += 1) {}
+        gpa.free(locs[0 .. i + 1]);
+    }
+
+    pub fn dupe(tok: Token, gpa: std.mem.Allocator) !Token {
+        var copy = tok;
+        copy.expansion_locs = null;
+        try copy.addExpansionLocation(gpa, tok.expansionSlice());
+        return copy;
+    }
+
+    pub const List = std.MultiArrayList(Token);
+    pub const Id = Tokenizer.Token.Id;
+};
+
+pub const TokenIndex = u32;
+pub const NodeIndex = enum(u32) { none, _ };
+pub const ValueMap = std.AutoHashMap(NodeIndex, Value);
+
+comp: *Compilation,
+arena: std.heap.ArenaAllocator,
+generated: []const u8,
+tokens: Token.List.Slice,
+nodes: Node.List.Slice,
+data: []const NodeIndex,
+root_decls: []const NodeIndex,
+strings: []const u8,
+value_map: ValueMap,
+
+pub fn deinit(tree: *Tree) void {
+    tree.comp.gpa.free(tree.root_decls);
+    tree.comp.gpa.free(tree.data);
+    tree.comp.gpa.free(tree.strings);
+    tree.nodes.deinit(tree.comp.gpa);
+    tree.arena.deinit();
+    tree.value_map.deinit();
+}
+
+pub const GNUAssemblyQualifiers = struct {
+    @"volatile": bool = false,
+    @"inline": bool = false,
+    goto: bool = false,
+};
+
+pub const Node = struct {
+    tag: Tag,
+    ty: Type = .{ .specifier = .void },
+    data: Data,
+
+    pub const Range = struct { start: u32, end: u32 };
+
+    pub const Data = union {
+        decl: struct {
+            name: TokenIndex,
+            node: NodeIndex = .none,
+        },
+        decl_ref: TokenIndex,
+        range: Range,
+        if3: struct {
+            cond: NodeIndex,
+            body: u32,
+        },
+        un: NodeIndex,
+        bin: struct {
+            lhs: NodeIndex,
+            rhs: NodeIndex,
+        },
+        member: struct {
+            lhs: NodeIndex,
+            index: u32,
+        },
+        union_init: struct {
+            field_index: u32,
+            node: NodeIndex,
+        },
+        cast: struct {
+            operand: NodeIndex,
+            kind: CastKind,
+        },
+        int: u64,
+        return_zero: bool,
+
+        pub fn forDecl(data: Data, tree: Tree) struct {
+            decls: []const NodeIndex,
+            cond: NodeIndex,
+            incr: NodeIndex,
+            body: NodeIndex,
+        } {
+            const items = tree.data[data.range.start..data.range.end];
+            const decls = items[0 .. items.len - 3];
+
+            return .{
+                .decls = decls,
+                .cond = items[items.len - 3],
+                .incr = items[items.len - 2],
+                .body = items[items.len - 1],
+            };
+        }
+
+        pub fn forStmt(data: Data, tree: Tree) struct {
+            init: NodeIndex,
+            cond: NodeIndex,
+            incr: NodeIndex,
+            body: NodeIndex,
+        } {
+            const items = tree.data[data.if3.body..];
+
+            return .{
+                .init = items[0],
+                .cond = items[1],
+                .incr = items[2],
+                .body = data.if3.cond,
+            };
+        }
+    };
+
+    pub const List = std.MultiArrayList(Node);
+};
+
+pub const CastKind = enum(u8) {
+    /// Does nothing except possibly add qualifiers
+    no_op,
+    /// Interpret one bit pattern as another. Used for operands which have the same
+    /// size and unrelated types, e.g. casting one pointer type to another
+    bitcast,
+    /// Convert T[] to T *
+    array_to_pointer,
+    /// Converts an lvalue to an rvalue
+    lval_to_rval,
+    /// Convert a function type to a pointer to a function
+    function_to_pointer,
+    /// Convert a pointer type to a _Bool
+    pointer_to_bool,
+    /// Convert a pointer type to an integer type
+    pointer_to_int,
+    /// Convert _Bool to an integer type
+    bool_to_int,
+    /// Convert _Bool to a floating type
+    bool_to_float,
+    /// Convert a _Bool to a pointer; will cause a  warning
+    bool_to_pointer,
+    /// Convert an integer type to _Bool
+    int_to_bool,
+    /// Convert an integer to a floating type
+    int_to_float,
+    /// Convert a complex integer to a complex floating type
+    complex_int_to_complex_float,
+    /// Convert an integer type to a pointer type
+    int_to_pointer,
+    /// Convert a floating type to a _Bool
+    float_to_bool,
+    /// Convert a floating type to an integer
+    float_to_int,
+    /// Convert a complex floating type to a complex integer
+    complex_float_to_complex_int,
+    /// Convert one integer type to another
+    int_cast,
+    /// Convert one complex integer type to another
+    complex_int_cast,
+    /// Convert real part of complex integer to a integer
+    complex_int_to_real,
+    /// Create a complex integer type using operand as the real part
+    real_to_complex_int,
+    /// Convert one floating type to another
+    float_cast,
+    /// Convert one complex floating type to another
+    complex_float_cast,
+    /// Convert real part of complex float to a float
+    complex_float_to_real,
+    /// Create a complex floating type using operand as the real part
+    real_to_complex_float,
+    /// Convert type to void
+    to_void,
+    /// Convert a literal 0 to a null pointer
+    null_to_pointer,
+    /// GNU cast-to-union extension
+    union_cast,
+    /// Create vector where each value is same as the input scalar.
+    vector_splat,
+};
+
+pub const Tag = enum(u8) {
+    /// Must appear at index 0. Also used as the tag for __builtin_types_compatible_p arguments, since the arguments are types
+    /// Reaching it is always the result of a bug.
+    invalid,
+
+    // ====== Decl ======
+
+    // _Static_assert
+    static_assert,
+
+    // function prototype
+    fn_proto,
+    static_fn_proto,
+    inline_fn_proto,
+    inline_static_fn_proto,
+
+    // function definition
+    fn_def,
+    static_fn_def,
+    inline_fn_def,
+    inline_static_fn_def,
+
+    // variable declaration
+    @"var",
+    extern_var,
+    static_var,
+    // same as static_var, used for __func__, __FUNCTION__ and __PRETTY_FUNCTION__
+    implicit_static_var,
+    threadlocal_var,
+    threadlocal_extern_var,
+    threadlocal_static_var,
+
+    /// __asm__("...") at file scope
+    file_scope_asm,
+
+    // typedef declaration
+    typedef,
+
+    // container declarations
+    /// { lhs; rhs; }
+    struct_decl_two,
+    /// { lhs; rhs; }
+    union_decl_two,
+    /// { lhs, rhs, }
+    enum_decl_two,
+    /// { range }
+    struct_decl,
+    /// { range }
+    union_decl,
+    /// { range }
+    enum_decl,
+    /// struct decl_ref;
+    struct_forward_decl,
+    /// union decl_ref;
+    union_forward_decl,
+    /// enum decl_ref;
+    enum_forward_decl,
+
+    /// name = node
+    enum_field_decl,
+    /// ty name : node
+    /// name == 0 means unnamed
+    record_field_decl,
+    /// Used when a record has an unnamed record as a field
+    indirect_record_field_decl,
+
+    // ====== Stmt ======
+
+    labeled_stmt,
+    /// { first; second; } first and second may be null
+    compound_stmt_two,
+    /// { data }
+    compound_stmt,
+    /// if (first) data[second] else data[second+1];
+    if_then_else_stmt,
+    /// if (first) second; second may be null
+    if_then_stmt,
+    /// switch (first) second
+    switch_stmt,
+    /// case first: second
+    case_stmt,
+    /// case data[body]...data[body+1]: cond
+    case_range_stmt,
+    /// default: first
+    default_stmt,
+    /// while (first) second
+    while_stmt,
+    /// do second while(first);
+    do_while_stmt,
+    /// for (data[..]; data[len-3]; data[len-2]) data[len-1]
+    for_decl_stmt,
+    /// for (;;;) first
+    forever_stmt,
+    /// for (data[first]; data[first+1]; data[first+2]) second
+    for_stmt,
+    /// goto first;
+    goto_stmt,
+    /// goto *un;
+    computed_goto_stmt,
+    // continue; first and second unused
+    continue_stmt,
+    // break; first and second unused
+    break_stmt,
+    // null statement (just a semicolon); first and second unused
+    null_stmt,
+    /// return first; first may be null
+    return_stmt,
+    /// Assembly statement of the form __asm__("string literal")
+    gnu_asm_simple,
+
+    // ====== Expr ======
+
+    /// lhs , rhs
+    comma_expr,
+    /// lhs ? data[0] : data[1]
+    binary_cond_expr,
+    /// Used as the base for casts of the lhs in `binary_cond_expr`.
+    cond_dummy_expr,
+    /// lhs ? data[0] : data[1]
+    cond_expr,
+    /// lhs = rhs
+    assign_expr,
+    /// lhs *= rhs
+    mul_assign_expr,
+    /// lhs /= rhs
+    div_assign_expr,
+    /// lhs %= rhs
+    mod_assign_expr,
+    /// lhs += rhs
+    add_assign_expr,
+    /// lhs -= rhs
+    sub_assign_expr,
+    /// lhs <<= rhs
+    shl_assign_expr,
+    /// lhs >>= rhs
+    shr_assign_expr,
+    /// lhs &= rhs
+    bit_and_assign_expr,
+    /// lhs ^= rhs
+    bit_xor_assign_expr,
+    /// lhs |= rhs
+    bit_or_assign_expr,
+    /// lhs || rhs
+    bool_or_expr,
+    /// lhs && rhs
+    bool_and_expr,
+    /// lhs | rhs
+    bit_or_expr,
+    /// lhs ^ rhs
+    bit_xor_expr,
+    /// lhs & rhs
+    bit_and_expr,
+    /// lhs == rhs
+    equal_expr,
+    /// lhs != rhs
+    not_equal_expr,
+    /// lhs < rhs
+    less_than_expr,
+    /// lhs <= rhs
+    less_than_equal_expr,
+    /// lhs > rhs
+    greater_than_expr,
+    /// lhs >= rhs
+    greater_than_equal_expr,
+    /// lhs << rhs
+    shl_expr,
+    /// lhs >> rhs
+    shr_expr,
+    /// lhs + rhs
+    add_expr,
+    /// lhs - rhs
+    sub_expr,
+    /// lhs * rhs
+    mul_expr,
+    /// lhs / rhs
+    div_expr,
+    /// lhs % rhs
+    mod_expr,
+    /// Explicit: (type) cast
+    explicit_cast,
+    /// Implicit: cast
+    implicit_cast,
+    /// &un
+    addr_of_expr,
+    /// &&decl_ref
+    addr_of_label,
+    /// *un
+    deref_expr,
+    /// +un
+    plus_expr,
+    /// -un
+    negate_expr,
+    /// ~un
+    bit_not_expr,
+    /// !un
+    bool_not_expr,
+    /// ++un
+    pre_inc_expr,
+    /// --un
+    pre_dec_expr,
+    /// __imag un
+    imag_expr,
+    /// __real un
+    real_expr,
+    /// lhs[rhs]  lhs is pointer/array type, rhs is integer type
+    array_access_expr,
+    /// first(second) second may be 0
+    call_expr_one,
+    /// data[0](data[1..])
+    call_expr,
+    /// decl
+    builtin_call_expr_one,
+    builtin_call_expr,
+    /// lhs.member
+    member_access_expr,
+    /// lhs->member
+    member_access_ptr_expr,
+    /// un++
+    post_inc_expr,
+    /// un--
+    post_dec_expr,
+    /// (un)
+    paren_expr,
+    /// decl_ref
+    decl_ref_expr,
+    /// decl_ref
+    enumeration_ref,
+    /// C23 bool literal `true` / `false`
+    bool_literal,
+    /// C23 nullptr literal
+    nullptr_literal,
+    /// integer literal, always unsigned
+    int_literal,
+    /// Same as int_literal, but originates from a char literal
+    char_literal,
+    /// _Float16 literal
+    float16_literal,
+    /// f32 literal
+    float_literal,
+    /// f64 literal
+    double_literal,
+    /// wraps a float or double literal: un
+    imaginary_literal,
+    /// tree.str[index..][0..len]
+    string_literal_expr,
+    /// sizeof(un?)
+    sizeof_expr,
+    /// _Alignof(un?)
+    alignof_expr,
+    /// _Generic(controlling lhs, chosen rhs)
+    generic_expr_one,
+    /// _Generic(controlling range[0], chosen range[1], rest range[2..])
+    generic_expr,
+    /// ty: un
+    generic_association_expr,
+    // default: un
+    generic_default_expr,
+    /// __builtin_choose_expr(lhs, data[0], data[1])
+    builtin_choose_expr,
+    /// __builtin_types_compatible_p(lhs, rhs)
+    builtin_types_compatible_p,
+    /// decl - special builtins require custom parsing
+    special_builtin_call_one,
+    /// ({ un })
+    stmt_expr,
+
+    // ====== Initializer expressions ======
+
+    /// { lhs, rhs }
+    array_init_expr_two,
+    /// { range }
+    array_init_expr,
+    /// { lhs, rhs }
+    struct_init_expr_two,
+    /// { range }
+    struct_init_expr,
+    /// { union_init }
+    union_init_expr,
+    /// (ty){ un }
+    compound_literal_expr,
+
+    /// Inserted at the end of a function body if no return stmt is found.
+    /// ty is the functions return type
+    /// data is return_zero which is true if the function is called "main" and ty is compatible with int
+    implicit_return,
+
+    /// Inserted in array_init_expr to represent unspecified elements.
+    /// data.int contains the amount of elements.
+    array_filler_expr,
+    /// Inserted in record and scalar initializers for unspecified elements.
+    default_init_expr,
+
+    pub fn isImplicit(tag: Tag) bool {
+        return switch (tag) {
+            .implicit_cast,
+            .implicit_return,
+            .array_filler_expr,
+            .default_init_expr,
+            .implicit_static_var,
+            .cond_dummy_expr,
+            => true,
+            else => false,
+        };
+    }
+};
+
+pub fn isBitfield(nodes: Node.List.Slice, node: NodeIndex) bool {
+    return bitfieldWidth(nodes, node, false) != null;
+}
+
+/// Returns null if node is not a bitfield. If inspect_lval is true, this function will
+/// recurse into implicit lval_to_rval casts (useful for arithmetic conversions)
+pub fn bitfieldWidth(nodes: Node.List.Slice, node: NodeIndex, inspect_lval: bool) ?u32 {
+    if (node == .none) return null;
+    switch (nodes.items(.tag)[@intFromEnum(node)]) {
+        .member_access_expr, .member_access_ptr_expr => {
+            const member = nodes.items(.data)[@intFromEnum(node)].member;
+            var ty = nodes.items(.ty)[@intFromEnum(member.lhs)];
+            if (ty.isPtr()) ty = ty.elemType();
+            const record_ty = ty.get(.@"struct") orelse ty.get(.@"union") orelse return null;
+            const field = record_ty.data.record.fields[member.index];
+            return field.bit_width;
+        },
+        .implicit_cast => {
+            if (!inspect_lval) return null;
+
+            const data = nodes.items(.data)[@intFromEnum(node)];
+            return switch (data.cast.kind) {
+                .lval_to_rval => bitfieldWidth(nodes, data.cast.operand, false),
+                else => null,
+            };
+        },
+        else => return null,
+    }
+}
+
+pub fn isLval(nodes: Node.List.Slice, extra: []const NodeIndex, value_map: ValueMap, node: NodeIndex) bool {
+    var is_const: bool = undefined;
+    return isLvalExtra(nodes, extra, value_map, node, &is_const);
+}
+
+pub fn isLvalExtra(nodes: Node.List.Slice, extra: []const NodeIndex, value_map: ValueMap, node: NodeIndex, is_const: *bool) bool {
+    is_const.* = false;
+    switch (nodes.items(.tag)[@intFromEnum(node)]) {
+        .compound_literal_expr => {
+            is_const.* = nodes.items(.ty)[@intFromEnum(node)].isConst();
+            return true;
+        },
+        .string_literal_expr => return true,
+        .member_access_ptr_expr => {
+            const lhs_expr = nodes.items(.data)[@intFromEnum(node)].member.lhs;
+            const ptr_ty = nodes.items(.ty)[@intFromEnum(lhs_expr)];
+            if (ptr_ty.isPtr()) is_const.* = ptr_ty.elemType().isConst();
+            return true;
+        },
+        .array_access_expr => {
+            const lhs_expr = nodes.items(.data)[@intFromEnum(node)].bin.lhs;
+            if (lhs_expr != .none) {
+                const array_ty = nodes.items(.ty)[@intFromEnum(lhs_expr)];
+                if (array_ty.isPtr() or array_ty.isArray()) is_const.* = array_ty.elemType().isConst();
+            }
+            return true;
+        },
+        .decl_ref_expr => {
+            const decl_ty = nodes.items(.ty)[@intFromEnum(node)];
+            is_const.* = decl_ty.isConst();
+            return true;
+        },
+        .deref_expr => {
+            const data = nodes.items(.data)[@intFromEnum(node)];
+            const operand_ty = nodes.items(.ty)[@intFromEnum(data.un)];
+            if (operand_ty.isFunc()) return false;
+            if (operand_ty.isPtr() or operand_ty.isArray()) is_const.* = operand_ty.elemType().isConst();
+            return true;
+        },
+        .member_access_expr => {
+            const data = nodes.items(.data)[@intFromEnum(node)];
+            return isLvalExtra(nodes, extra, value_map, data.member.lhs, is_const);
+        },
+        .paren_expr => {
+            const data = nodes.items(.data)[@intFromEnum(node)];
+            return isLvalExtra(nodes, extra, value_map, data.un, is_const);
+        },
+        .builtin_choose_expr => {
+            const data = nodes.items(.data)[@intFromEnum(node)];
+
+            if (value_map.get(data.if3.cond)) |val| {
+                const offset = @intFromBool(val.isZero());
+                return isLvalExtra(nodes, extra, value_map, extra[data.if3.body + offset], is_const);
+            }
+            return false;
+        },
+        else => return false,
+    }
+}
+
+pub fn dumpStr(retained_strings: []const u8, range: Value.ByteRange, tag: Tag, writer: anytype) !void {
+    switch (tag) {
+        .string_literal_expr => {
+            const lit_range = range.trim(1); // remove null-terminator
+            const str = lit_range.slice(retained_strings);
+            try writer.print("\"{}\"", .{std.zig.fmtEscapes(str)});
+        },
+        else => unreachable,
+    }
+}
+
+pub fn tokSlice(tree: Tree, tok_i: TokenIndex) []const u8 {
+    if (tree.tokens.items(.id)[tok_i].lexeme()) |some| return some;
+    const loc = tree.tokens.items(.loc)[tok_i];
+    var tmp_tokenizer = Tokenizer{
+        .buf = tree.comp.getSource(loc.id).buf,
+        .comp = tree.comp,
+        .index = loc.byte_offset,
+        .source = .generated,
+    };
+    const tok = tmp_tokenizer.next();
+    return tmp_tokenizer.buf[tok.start..tok.end];
+}
+
+pub fn dump(tree: Tree, color: bool, writer: anytype) @TypeOf(writer).Error!void {
+    const mapper = tree.comp.string_interner.getFastTypeMapper(tree.comp.gpa) catch tree.comp.string_interner.getSlowTypeMapper();
+    defer mapper.deinit(tree.comp.gpa);
+
+    for (tree.root_decls) |i| {
+        try tree.dumpNode(i, 0, mapper, color, writer);
+        try writer.writeByte('\n');
+    }
+}
+
+fn dumpFieldAttributes(attributes: []const Attribute, level: u32, strings: []const u8, writer: anytype) !void {
+    for (attributes) |attr| {
+        try writer.writeByteNTimes(' ', level);
+        try writer.print("field attr: {s}", .{@tagName(attr.tag)});
+        try dumpAttribute(attr, strings, writer);
+    }
+}
+
+fn dumpAttribute(attr: Attribute, strings: []const u8, writer: anytype) !void {
+    switch (attr.tag) {
+        inline else => |tag| {
+            const args = @field(attr.args, @tagName(tag));
+            if (@TypeOf(args) == void) {
+                try writer.writeByte('\n');
+                return;
+            }
+            try writer.writeByte(' ');
+            inline for (@typeInfo(@TypeOf(args)).Struct.fields, 0..) |f, i| {
+                if (comptime std.mem.eql(u8, f.name, "__name_tok")) continue;
+                if (i != 0) {
+                    try writer.writeAll(", ");
+                }
+                try writer.writeAll(f.name);
+                try writer.writeAll(": ");
+                switch (f.type) {
+                    Value.ByteRange => try writer.print("\"{s}\"", .{@field(args, f.name).slice(strings)}),
+                    ?Value.ByteRange => try writer.print("\"{?s}\"", .{if (@field(args, f.name)) |range| range.slice(strings) else null}),
+                    else => switch (@typeInfo(f.type)) {
+                        .Enum => try writer.writeAll(@tagName(@field(args, f.name))),
+                        else => try writer.print("{any}", .{@field(args, f.name)}),
+                    },
+                }
+            }
+            try writer.writeByte('\n');
+            return;
+        },
+    }
+}
+
+fn dumpNode(tree: Tree, node: NodeIndex, level: u32, mapper: StringInterner.TypeMapper, color: bool, w: anytype) @TypeOf(w).Error!void {
+    const delta = 2;
+    const half = delta / 2;
+    const util = @import("util.zig");
+    const TYPE = util.Color.purple;
+    const TAG = util.Color.cyan;
+    const IMPLICIT = util.Color.blue;
+    const NAME = util.Color.red;
+    const LITERAL = util.Color.green;
+    const ATTRIBUTE = util.Color.yellow;
+    std.debug.assert(node != .none);
+
+    const tag = tree.nodes.items(.tag)[@intFromEnum(node)];
+    const data = tree.nodes.items(.data)[@intFromEnum(node)];
+    const ty = tree.nodes.items(.ty)[@intFromEnum(node)];
+    try w.writeByteNTimes(' ', level);
+
+    if (color) util.setColor(if (tag.isImplicit()) IMPLICIT else TAG, w);
+    try w.print("{s}: ", .{@tagName(tag)});
+    if (tag == .implicit_cast or tag == .explicit_cast) {
+        if (color) util.setColor(.white, w);
+        try w.print("({s}) ", .{@tagName(data.cast.kind)});
+    }
+    if (color) util.setColor(TYPE, w);
+    try w.writeByte('\'');
+    try ty.dump(mapper, tree.comp.langopts, w);
+    try w.writeByte('\'');
+
+    if (isLval(tree.nodes, tree.data, tree.value_map, node)) {
+        if (color) util.setColor(ATTRIBUTE, w);
+        try w.writeAll(" lvalue");
+    }
+    if (isBitfield(tree.nodes, node)) {
+        if (color) util.setColor(ATTRIBUTE, w);
+        try w.writeAll(" bitfield");
+    }
+    if (tree.value_map.get(node)) |val| {
+        if (color) util.setColor(LITERAL, w);
+        try w.writeAll(" (value: ");
+        try val.dump(ty, tree.comp, tree.strings, w);
+        try w.writeByte(')');
+    }
+    if (tag == .implicit_return and data.return_zero) {
+        if (color) util.setColor(IMPLICIT, w);
+        try w.writeAll(" (value: 0)");
+        if (color) util.setColor(.reset, w);
+    }
+
+    try w.writeAll("\n");
+    if (color) util.setColor(.reset, w);
+
+    if (ty.specifier == .attributed) {
+        if (color) util.setColor(ATTRIBUTE, w);
+        for (ty.data.attributed.attributes) |attr| {
+            try w.writeByteNTimes(' ', level + half);
+            try w.print("attr: {s}", .{@tagName(attr.tag)});
+            try dumpAttribute(attr, tree.strings, w);
+        }
+        if (color) util.setColor(.reset, w);
+    }
+
+    switch (tag) {
+        .invalid => unreachable,
+        .file_scope_asm => {
+            try w.writeByteNTimes(' ', level + 1);
+            try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+        },
+        .gnu_asm_simple => {
+            try w.writeByteNTimes(' ', level);
+            try tree.dumpNode(data.un, level, mapper, color, w);
+        },
+        .static_assert => {
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("condition:\n");
+            try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+            if (data.bin.rhs != .none) {
+                try w.writeByteNTimes(' ', level + 1);
+                try w.writeAll("diagnostic:\n");
+                try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+            }
+        },
+        .fn_proto,
+        .static_fn_proto,
+        .inline_fn_proto,
+        .inline_static_fn_proto,
+        => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+            if (color) util.setColor(.reset, w);
+        },
+        .fn_def,
+        .static_fn_def,
+        .inline_fn_def,
+        .inline_static_fn_def,
+        => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+            if (color) util.setColor(.reset, w);
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("body:\n");
+            try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+        },
+        .typedef,
+        .@"var",
+        .extern_var,
+        .static_var,
+        .implicit_static_var,
+        .threadlocal_var,
+        .threadlocal_extern_var,
+        .threadlocal_static_var,
+        => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+            if (color) util.setColor(.reset, w);
+            if (data.decl.node != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("init:\n");
+                try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+            }
+        },
+        .enum_field_decl => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+            if (color) util.setColor(.reset, w);
+            if (data.decl.node != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("value:\n");
+                try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+            }
+        },
+        .record_field_decl => {
+            if (data.decl.name != 0) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("name: ");
+                if (color) util.setColor(NAME, w);
+                try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+                if (color) util.setColor(.reset, w);
+            }
+            if (data.decl.node != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("bits:\n");
+                try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+            }
+        },
+        .indirect_record_field_decl => {},
+        .compound_stmt,
+        .array_init_expr,
+        .struct_init_expr,
+        .enum_decl,
+        .struct_decl,
+        .union_decl,
+        => {
+            const maybe_field_attributes = if (ty.getRecord()) |record| record.field_attributes else null;
+            for (tree.data[data.range.start..data.range.end], 0..) |stmt, i| {
+                if (i != 0) try w.writeByte('\n');
+                try tree.dumpNode(stmt, level + delta, mapper, color, w);
+                if (maybe_field_attributes) |field_attributes| {
+                    if (field_attributes[i].len == 0) continue;
+
+                    if (color) util.setColor(ATTRIBUTE, w);
+                    try dumpFieldAttributes(field_attributes[i], level + delta + half, tree.strings, w);
+                    if (color) util.setColor(.reset, w);
+                }
+            }
+        },
+        .compound_stmt_two,
+        .array_init_expr_two,
+        .struct_init_expr_two,
+        .enum_decl_two,
+        .struct_decl_two,
+        .union_decl_two,
+        => {
+            var attr_array = [2][]const Attribute{ &.{}, &.{} };
+            const empty: [][]const Attribute = &attr_array;
+            const field_attributes = if (ty.getRecord()) |record| (record.field_attributes orelse empty.ptr) else empty.ptr;
+            if (data.bin.lhs != .none) {
+                try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+                if (field_attributes[0].len > 0) {
+                    if (color) util.setColor(ATTRIBUTE, w);
+                    try dumpFieldAttributes(field_attributes[0], level + delta + half, tree.strings, w);
+                    if (color) util.setColor(.reset, w);
+                }
+            }
+            if (data.bin.rhs != .none) {
+                try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+                if (field_attributes[1].len > 0) {
+                    if (color) util.setColor(ATTRIBUTE, w);
+                    try dumpFieldAttributes(field_attributes[1], level + delta + half, tree.strings, w);
+                    if (color) util.setColor(.reset, w);
+                }
+            }
+        },
+        .union_init_expr => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("field index: ");
+            if (color) util.setColor(LITERAL, w);
+            try w.print("{d}\n", .{data.union_init.field_index});
+            if (color) util.setColor(.reset, w);
+            if (data.union_init.node != .none) {
+                try tree.dumpNode(data.union_init.node, level + delta, mapper, color, w);
+            }
+        },
+        .compound_literal_expr => {
+            try tree.dumpNode(data.un, level + half, mapper, color, w);
+        },
+        .labeled_stmt => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("label: ");
+            if (color) util.setColor(LITERAL, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+            if (color) util.setColor(.reset, w);
+            if (data.decl.node != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("stmt:\n");
+                try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+            }
+        },
+        .case_stmt => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("value:\n");
+            try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+            if (data.bin.rhs != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("stmt:\n");
+                try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+            }
+        },
+        .case_range_stmt => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("range start:\n");
+            try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, color, w);
+
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("range end:\n");
+            try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, color, w);
+
+            if (data.if3.cond != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("stmt:\n");
+                try tree.dumpNode(data.if3.cond, level + delta, mapper, color, w);
+            }
+        },
+        .default_stmt => {
+            if (data.un != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("stmt:\n");
+                try tree.dumpNode(data.un, level + delta, mapper, color, w);
+            }
+        },
+        .binary_cond_expr, .cond_expr, .if_then_else_stmt, .builtin_choose_expr => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("cond:\n");
+            try tree.dumpNode(data.if3.cond, level + delta, mapper, color, w);
+
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("then:\n");
+            try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, color, w);
+
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("else:\n");
+            try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, color, w);
+        },
+        .builtin_types_compatible_p => {
+            std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.lhs)] == .invalid);
+            std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.rhs)] == .invalid);
+
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("lhs: ");
+
+            const lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.lhs)];
+            if (color) util.setColor(TYPE, w);
+            try lhs_ty.dump(mapper, tree.comp.langopts, w);
+            if (color) util.setColor(.reset, w);
+            try w.writeByte('\n');
+
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("rhs: ");
+
+            const rhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.rhs)];
+            if (color) util.setColor(TYPE, w);
+            try rhs_ty.dump(mapper, tree.comp.langopts, w);
+            if (color) util.setColor(.reset, w);
+            try w.writeByte('\n');
+        },
+        .if_then_stmt => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("cond:\n");
+            try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+
+            if (data.bin.rhs != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("then:\n");
+                try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+            }
+        },
+        .switch_stmt, .while_stmt, .do_while_stmt => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("cond:\n");
+            try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+
+            if (data.bin.rhs != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("body:\n");
+                try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+            }
+        },
+        .for_decl_stmt => {
+            const for_decl = data.forDecl(tree);
+
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("decl:\n");
+            for (for_decl.decls) |decl| {
+                try tree.dumpNode(decl, level + delta, mapper, color, w);
+                try w.writeByte('\n');
+            }
+            if (for_decl.cond != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("cond:\n");
+                try tree.dumpNode(for_decl.cond, level + delta, mapper, color, w);
+            }
+            if (for_decl.incr != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("incr:\n");
+                try tree.dumpNode(for_decl.incr, level + delta, mapper, color, w);
+            }
+            if (for_decl.body != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("body:\n");
+                try tree.dumpNode(for_decl.body, level + delta, mapper, color, w);
+            }
+        },
+        .forever_stmt => {
+            if (data.un != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("body:\n");
+                try tree.dumpNode(data.un, level + delta, mapper, color, w);
+            }
+        },
+        .for_stmt => {
+            const for_stmt = data.forStmt(tree);
+
+            if (for_stmt.init != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("init:\n");
+                try tree.dumpNode(for_stmt.init, level + delta, mapper, color, w);
+            }
+            if (for_stmt.cond != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("cond:\n");
+                try tree.dumpNode(for_stmt.cond, level + delta, mapper, color, w);
+            }
+            if (for_stmt.incr != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("incr:\n");
+                try tree.dumpNode(for_stmt.incr, level + delta, mapper, color, w);
+            }
+            if (for_stmt.body != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("body:\n");
+                try tree.dumpNode(for_stmt.body, level + delta, mapper, color, w);
+            }
+        },
+        .goto_stmt, .addr_of_label => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("label: ");
+            if (color) util.setColor(LITERAL, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
+            if (color) util.setColor(.reset, w);
+        },
+        .continue_stmt, .break_stmt, .implicit_return, .null_stmt => {},
+        .return_stmt => {
+            if (data.un != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("expr:\n");
+                try tree.dumpNode(data.un, level + delta, mapper, color, w);
+            }
+        },
+        .call_expr => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("lhs:\n");
+            try tree.dumpNode(tree.data[data.range.start], level + delta, mapper, color, w);
+
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("args:\n");
+            for (tree.data[data.range.start + 1 .. data.range.end]) |arg| try tree.dumpNode(arg, level + delta, mapper, color, w);
+        },
+        .call_expr_one => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("lhs:\n");
+            try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+            if (data.bin.rhs != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("arg:\n");
+                try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+            }
+        },
+        .builtin_call_expr => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{tree.tokSlice(@intFromEnum(tree.data[data.range.start]))});
+            if (color) util.setColor(.reset, w);
+
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("args:\n");
+            for (tree.data[data.range.start + 1 .. data.range.end]) |arg| try tree.dumpNode(arg, level + delta, mapper, color, w);
+        },
+        .builtin_call_expr_one => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+            if (color) util.setColor(.reset, w);
+            if (data.decl.node != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("arg:\n");
+                try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+            }
+        },
+        .special_builtin_call_one => {
+            try w.writeByteNTimes(' ', level + half);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
+            if (color) util.setColor(.reset, w);
+            if (data.decl.node != .none) {
+                try w.writeByteNTimes(' ', level + half);
+                try w.writeAll("arg:\n");
+                try tree.dumpNode(data.decl.node, level + delta, mapper, color, w);
+            }
+        },
+        .comma_expr,
+        .assign_expr,
+        .mul_assign_expr,
+        .div_assign_expr,
+        .mod_assign_expr,
+        .add_assign_expr,
+        .sub_assign_expr,
+        .shl_assign_expr,
+        .shr_assign_expr,
+        .bit_and_assign_expr,
+        .bit_xor_assign_expr,
+        .bit_or_assign_expr,
+        .bool_or_expr,
+        .bool_and_expr,
+        .bit_or_expr,
+        .bit_xor_expr,
+        .bit_and_expr,
+        .equal_expr,
+        .not_equal_expr,
+        .less_than_expr,
+        .less_than_equal_expr,
+        .greater_than_expr,
+        .greater_than_equal_expr,
+        .shl_expr,
+        .shr_expr,
+        .add_expr,
+        .sub_expr,
+        .mul_expr,
+        .div_expr,
+        .mod_expr,
+        => {
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("lhs:\n");
+            try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("rhs:\n");
+            try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+        },
+        .explicit_cast, .implicit_cast => try tree.dumpNode(data.cast.operand, level + delta, mapper, color, w),
+        .addr_of_expr,
+        .computed_goto_stmt,
+        .deref_expr,
+        .plus_expr,
+        .negate_expr,
+        .bit_not_expr,
+        .bool_not_expr,
+        .pre_inc_expr,
+        .pre_dec_expr,
+        .imag_expr,
+        .real_expr,
+        .post_inc_expr,
+        .post_dec_expr,
+        .paren_expr,
+        => {
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("operand:\n");
+            try tree.dumpNode(data.un, level + delta, mapper, color, w);
+        },
+        .decl_ref_expr => {
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
+            if (color) util.setColor(.reset, w);
+        },
+        .enumeration_ref => {
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
+            if (color) util.setColor(.reset, w);
+        },
+        .bool_literal,
+        .nullptr_literal,
+        .int_literal,
+        .char_literal,
+        .float16_literal,
+        .float_literal,
+        .double_literal,
+        .string_literal_expr,
+        => {},
+        .member_access_expr, .member_access_ptr_expr => {
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("lhs:\n");
+            try tree.dumpNode(data.member.lhs, level + delta, mapper, color, w);
+
+            var lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.member.lhs)];
+            if (lhs_ty.isPtr()) lhs_ty = lhs_ty.elemType();
+            lhs_ty = lhs_ty.canonicalize(.standard);
+
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("name: ");
+            if (color) util.setColor(NAME, w);
+            try w.print("{s}\n", .{mapper.lookup(lhs_ty.data.record.fields[data.member.index].name)});
+            if (color) util.setColor(.reset, w);
+        },
+        .array_access_expr => {
+            if (data.bin.lhs != .none) {
+                try w.writeByteNTimes(' ', level + 1);
+                try w.writeAll("lhs:\n");
+                try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+            }
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("index:\n");
+            try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+        },
+        .sizeof_expr, .alignof_expr => {
+            if (data.un != .none) {
+                try w.writeByteNTimes(' ', level + 1);
+                try w.writeAll("expr:\n");
+                try tree.dumpNode(data.un, level + delta, mapper, color, w);
+            }
+        },
+        .generic_expr_one => {
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("controlling:\n");
+            try tree.dumpNode(data.bin.lhs, level + delta, mapper, color, w);
+            try w.writeByteNTimes(' ', level + 1);
+            if (data.bin.rhs != .none) {
+                try w.writeAll("chosen:\n");
+                try tree.dumpNode(data.bin.rhs, level + delta, mapper, color, w);
+            }
+        },
+        .generic_expr => {
+            const nodes = tree.data[data.range.start..data.range.end];
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("controlling:\n");
+            try tree.dumpNode(nodes[0], level + delta, mapper, color, w);
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("chosen:\n");
+            try tree.dumpNode(nodes[1], level + delta, mapper, color, w);
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("rest:\n");
+            for (nodes[2..]) |expr| {
+                try tree.dumpNode(expr, level + delta, mapper, color, w);
+            }
+        },
+        .generic_association_expr, .generic_default_expr, .stmt_expr, .imaginary_literal => {
+            try tree.dumpNode(data.un, level + delta, mapper, color, w);
+        },
+        .array_filler_expr => {
+            try w.writeByteNTimes(' ', level + 1);
+            try w.writeAll("count: ");
+            if (color) util.setColor(LITERAL, w);
+            try w.print("{d}\n", .{data.int});
+            if (color) util.setColor(.reset, w);
+        },
+        .struct_forward_decl,
+        .union_forward_decl,
+        .enum_forward_decl,
+        .default_init_expr,
+        .cond_dummy_expr,
+        => {},
+    }
+}
deps/aro/Type.zig
@@ -0,0 +1,2692 @@
+const std = @import("std");
+const Tree = @import("Tree.zig");
+const TokenIndex = Tree.TokenIndex;
+const NodeIndex = Tree.NodeIndex;
+const Parser = @import("Parser.zig");
+const Compilation = @import("Compilation.zig");
+const Attribute = @import("Attribute.zig");
+const StringInterner = @import("StringInterner.zig");
+const StringId = StringInterner.StringId;
+const target_util = @import("target.zig");
+const LangOpts = @import("LangOpts.zig");
+const BuiltinFunction = @import("builtins/BuiltinFunction.zig");
+
+const Type = @This();
+
+pub const Qualifiers = packed struct {
+    @"const": bool = false,
+    atomic: bool = false,
+    @"volatile": bool = false,
+    restrict: bool = false,
+
+    // for function parameters only, stored here since it fits in the padding
+    register: bool = false,
+
+    pub fn any(quals: Qualifiers) bool {
+        return quals.@"const" or quals.restrict or quals.@"volatile" or quals.atomic;
+    }
+
+    pub fn dump(quals: Qualifiers, w: anytype) !void {
+        if (quals.@"const") try w.writeAll("const ");
+        if (quals.atomic) try w.writeAll("_Atomic ");
+        if (quals.@"volatile") try w.writeAll("volatile ");
+        if (quals.restrict) try w.writeAll("restrict ");
+        if (quals.register) try w.writeAll("register ");
+    }
+
+    /// Merge the const/volatile qualifiers, used by type resolution
+    /// of the conditional operator
+    pub fn mergeCV(a: Qualifiers, b: Qualifiers) Qualifiers {
+        return .{
+            .@"const" = a.@"const" or b.@"const",
+            .@"volatile" = a.@"volatile" or b.@"volatile",
+        };
+    }
+
+    /// Merge all qualifiers, used by typeof()
+    fn mergeAll(a: Qualifiers, b: Qualifiers) Qualifiers {
+        return .{
+            .@"const" = a.@"const" or b.@"const",
+            .atomic = a.atomic or b.atomic,
+            .@"volatile" = a.@"volatile" or b.@"volatile",
+            .restrict = a.restrict or b.restrict,
+            .register = a.register or b.register,
+        };
+    }
+
+    /// Checks if a has all the qualifiers of b
+    pub fn hasQuals(a: Qualifiers, b: Qualifiers) bool {
+        if (b.@"const" and !a.@"const") return false;
+        if (b.@"volatile" and !a.@"volatile") return false;
+        if (b.atomic and !a.atomic) return false;
+        return true;
+    }
+
+    /// register is a storage class and not actually a qualifier
+    /// so it is not preserved by typeof()
+    pub fn inheritFromTypeof(quals: Qualifiers) Qualifiers {
+        var res = quals;
+        res.register = false;
+        return res;
+    }
+
+    pub const Builder = struct {
+        @"const": ?TokenIndex = null,
+        atomic: ?TokenIndex = null,
+        @"volatile": ?TokenIndex = null,
+        restrict: ?TokenIndex = null,
+
+        pub fn finish(b: Qualifiers.Builder, p: *Parser, ty: *Type) !void {
+            if (ty.specifier != .pointer and b.restrict != null) {
+                try p.errStr(.restrict_non_pointer, b.restrict.?, try p.typeStr(ty.*));
+            }
+            if (b.atomic) |some| {
+                if (ty.isArray()) try p.errStr(.atomic_array, some, try p.typeStr(ty.*));
+                if (ty.isFunc()) try p.errStr(.atomic_func, some, try p.typeStr(ty.*));
+                if (ty.hasIncompleteSize()) try p.errStr(.atomic_incomplete, some, try p.typeStr(ty.*));
+            }
+
+            if (b.@"const" != null) ty.qual.@"const" = true;
+            if (b.atomic != null) ty.qual.atomic = true;
+            if (b.@"volatile" != null) ty.qual.@"volatile" = true;
+            if (b.restrict != null) ty.qual.restrict = true;
+        }
+    };
+};
+
+// TODO improve memory usage
+pub const Func = struct {
+    return_type: Type,
+    params: []Param,
+
+    pub const Param = struct {
+        ty: Type,
+        name: StringId,
+        name_tok: TokenIndex,
+    };
+};
+
+pub const Array = struct {
+    len: u64,
+    elem: Type,
+};
+
+pub const Expr = struct {
+    node: NodeIndex,
+    ty: Type,
+};
+
+pub const Attributed = struct {
+    attributes: []Attribute,
+    base: Type,
+
+    pub fn create(allocator: std.mem.Allocator, base: Type, existing_attributes: []const Attribute, attributes: []const Attribute) !*Attributed {
+        var attributed_type = try allocator.create(Attributed);
+        errdefer allocator.destroy(attributed_type);
+
+        var all_attrs = try allocator.alloc(Attribute, existing_attributes.len + attributes.len);
+        std.mem.copy(Attribute, all_attrs, existing_attributes);
+        std.mem.copy(Attribute, all_attrs[existing_attributes.len..], attributes);
+
+        attributed_type.* = .{
+            .attributes = all_attrs,
+            .base = base,
+        };
+        return attributed_type;
+    }
+};
+
+// TODO improve memory usage
+pub const Enum = struct {
+    fields: []Field,
+    tag_ty: Type,
+    name: StringId,
+    fixed: bool,
+
+    pub const Field = struct {
+        ty: Type,
+        name: StringId,
+        name_tok: TokenIndex,
+        node: NodeIndex,
+    };
+
+    pub fn isIncomplete(e: Enum) bool {
+        return e.fields.len == std.math.maxInt(usize);
+    }
+
+    pub fn create(allocator: std.mem.Allocator, name: StringId, fixed_ty: ?Type) !*Enum {
+        var e = try allocator.create(Enum);
+        e.name = name;
+        e.fields.len = std.math.maxInt(usize);
+        if (fixed_ty) |some| e.tag_ty = some;
+        e.fixed = fixed_ty != null;
+        return e;
+    }
+};
+
+// might not need all 4 of these when finished,
+// but currently it helps having all 4 when diff-ing
+// the rust code.
+pub const TypeLayout = struct {
+    /// The size of the type in bits.
+    ///
+    /// This is the value returned by `sizeof` and C and `std::mem::size_of` in Rust
+    /// (but in bits instead of bytes). This is a multiple of `pointer_alignment_bits`.
+    size_bits: u64,
+    /// The alignment of the type, in bits, when used as a field in a record.
+    ///
+    /// This is usually the value returned by `_Alignof` in C, but there are some edge
+    /// cases in GCC where `_Alignof` returns a smaller value.
+    field_alignment_bits: u32,
+    /// The alignment, in bits, of valid pointers to this type.
+    ///
+    /// This is the value returned by `std::mem::align_of` in Rust
+    /// (but in bits instead of bytes). `size_bits` is a multiple of this value.
+    pointer_alignment_bits: u32,
+    /// The required alignment of the type in bits.
+    ///
+    /// This value is only used by MSVC targets. It is 8 on all other
+    /// targets. On MSVC targets, this value restricts the effects of `#pragma pack` except
+    /// in some cases involving bit-fields.
+    required_alignment_bits: u32,
+};
+
+pub const FieldLayout = struct {
+    /// `offset_bits` and `size_bits` should both be INVALID if and only if the field
+    /// is an unnamed bitfield. There is no way to reference an unnamed bitfield in C, so
+    /// there should be no way to observe these values. If it is used, this value will
+    /// maximize the chance that a safety-checked overflow will occur.
+    const INVALID = std.math.maxInt(u64);
+
+    /// The offset of the field, in bits, from the start of the struct.
+    offset_bits: u64 = INVALID,
+    /// The size, in bits, of the field.
+    ///
+    /// For bit-fields, this is the width of the field.
+    size_bits: u64 = INVALID,
+
+    pub fn isUnnamed(self: FieldLayout) bool {
+        return self.offset_bits == INVALID and self.size_bits == INVALID;
+    }
+};
+
+// TODO improve memory usage
+pub const Record = struct {
+    fields: []Field,
+    type_layout: TypeLayout,
+    /// If this is null, none of the fields have attributes
+    /// Otherwise, it's a pointer to N items (where N == number of fields)
+    /// and the item at index i is the attributes for the field at index i
+    field_attributes: ?[*][]const Attribute,
+    name: StringId,
+
+    pub const Field = struct {
+        ty: Type,
+        name: StringId,
+        /// zero for anonymous fields
+        name_tok: TokenIndex = 0,
+        bit_width: ?u32 = null,
+        layout: FieldLayout = .{
+            .offset_bits = 0,
+            .size_bits = 0,
+        },
+
+        pub fn isNamed(f: *const Field) bool {
+            return f.name_tok != 0;
+        }
+
+        pub fn isAnonymousRecord(f: Field) bool {
+            return !f.isNamed() and f.ty.isRecord();
+        }
+
+        /// false for bitfields
+        pub fn isRegularField(f: *const Field) bool {
+            return f.bit_width == null;
+        }
+
+        /// bit width as specified in the C source. Asserts that `f` is a bitfield.
+        pub fn specifiedBitWidth(f: *const Field) u32 {
+            return f.bit_width.?;
+        }
+    };
+
+    pub fn isIncomplete(r: Record) bool {
+        return r.fields.len == std.math.maxInt(usize);
+    }
+
+    pub fn create(allocator: std.mem.Allocator, name: StringId) !*Record {
+        var r = try allocator.create(Record);
+        r.name = name;
+        r.fields.len = std.math.maxInt(usize);
+        r.field_attributes = null;
+        r.type_layout = .{
+            .size_bits = 8,
+            .field_alignment_bits = 8,
+            .pointer_alignment_bits = 8,
+            .required_alignment_bits = 8,
+        };
+        return r;
+    }
+
+    pub fn hasFieldOfType(self: *const Record, ty: Type, comp: *const Compilation) bool {
+        if (self.isIncomplete()) return false;
+        for (self.fields) |f| {
+            if (ty.eql(f.ty, comp, false)) return true;
+        }
+        return false;
+    }
+};
+
+pub const Specifier = enum {
+    /// A NaN-like poison value
+    invalid,
+
+    /// GNU auto type
+    /// This is a placeholder specifier - it must be replaced by the actual type specifier (determined by the initializer)
+    auto_type,
+
+    void,
+    bool,
+
+    // integers
+    char,
+    schar,
+    uchar,
+    short,
+    ushort,
+    int,
+    uint,
+    long,
+    ulong,
+    long_long,
+    ulong_long,
+    int128,
+    uint128,
+    complex_char,
+    complex_schar,
+    complex_uchar,
+    complex_short,
+    complex_ushort,
+    complex_int,
+    complex_uint,
+    complex_long,
+    complex_ulong,
+    complex_long_long,
+    complex_ulong_long,
+    complex_int128,
+    complex_uint128,
+
+    // data.int
+    bit_int,
+    complex_bit_int,
+
+    // floating point numbers
+    fp16,
+    float16,
+    float,
+    double,
+    long_double,
+    float80,
+    float128,
+    complex_float,
+    complex_double,
+    complex_long_double,
+    complex_float80,
+    complex_float128,
+
+    // data.sub_type
+    pointer,
+    unspecified_variable_len_array,
+    decayed_unspecified_variable_len_array,
+    // data.func
+    /// int foo(int bar, char baz) and int (void)
+    func,
+    /// int foo(int bar, char baz, ...)
+    var_args_func,
+    /// int foo(bar, baz) and int foo()
+    /// is also var args, but we can give warnings about incorrect amounts of parameters
+    old_style_func,
+
+    // data.array
+    array,
+    decayed_array,
+    static_array,
+    decayed_static_array,
+    incomplete_array,
+    decayed_incomplete_array,
+    vector,
+    // data.expr
+    variable_len_array,
+    decayed_variable_len_array,
+
+    // data.record
+    @"struct",
+    @"union",
+
+    // data.enum
+    @"enum",
+
+    /// typeof(type-name)
+    typeof_type,
+    /// decayed array created with typeof(type-name)
+    decayed_typeof_type,
+
+    /// typeof(expression)
+    typeof_expr,
+    /// decayed array created with typeof(expression)
+    decayed_typeof_expr,
+
+    /// data.attributed
+    attributed,
+
+    /// C23 nullptr_t
+    nullptr_t,
+};
+
+/// All fields of Type except data may be mutated
+data: union {
+    sub_type: *Type,
+    func: *Func,
+    array: *Array,
+    expr: *Expr,
+    @"enum": *Enum,
+    record: *Record,
+    attributed: *Attributed,
+    none: void,
+    int: struct {
+        bits: u8,
+        signedness: std.builtin.Signedness,
+    },
+} = .{ .none = {} },
+specifier: Specifier,
+qual: Qualifiers = .{},
+
+pub const int = Type{ .specifier = .int };
+pub const invalid = Type{ .specifier = .invalid };
+
+/// Determine if type matches the given specifier, recursing into typeof
+/// types if necessary.
+pub fn is(ty: Type, specifier: Specifier) bool {
+    std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr);
+    return ty.get(specifier) != null;
+}
+
+pub fn withAttributes(self: Type, allocator: std.mem.Allocator, attributes: []const Attribute) !Type {
+    if (attributes.len == 0) return self;
+    const attributed_type = try Type.Attributed.create(allocator, self, self.getAttributes(), attributes);
+    return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type } };
+}
+
+pub fn isCallable(ty: Type) ?Type {
+    return switch (ty.specifier) {
+        .func, .var_args_func, .old_style_func => ty,
+        .pointer => if (ty.data.sub_type.isFunc()) ty.data.sub_type.* else null,
+        .typeof_type => ty.data.sub_type.isCallable(),
+        .typeof_expr => ty.data.expr.ty.isCallable(),
+        .attributed => ty.data.attributed.base.isCallable(),
+        else => null,
+    };
+}
+
+pub fn isFunc(ty: Type) bool {
+    return switch (ty.specifier) {
+        .func, .var_args_func, .old_style_func => true,
+        .typeof_type => ty.data.sub_type.isFunc(),
+        .typeof_expr => ty.data.expr.ty.isFunc(),
+        .attributed => ty.data.attributed.base.isFunc(),
+        else => false,
+    };
+}
+
+pub fn isArray(ty: Type) bool {
+    return switch (ty.specifier) {
+        .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => true,
+        .typeof_type => ty.data.sub_type.isArray(),
+        .typeof_expr => ty.data.expr.ty.isArray(),
+        .attributed => ty.data.attributed.base.isArray(),
+        else => false,
+    };
+}
+
+pub fn isScalar(ty: Type) bool {
+    return ty.isInt() or ty.isScalarNonInt();
+}
+
+/// To avoid calling isInt() twice for allowable loop/if controlling expressions
+pub fn isScalarNonInt(ty: Type) bool {
+    return ty.isFloat() or ty.isPtr() or ty.is(.nullptr_t);
+}
+
+pub fn isDecayed(ty: Type) bool {
+    const decayed = switch (ty.specifier) {
+        .decayed_array,
+        .decayed_static_array,
+        .decayed_incomplete_array,
+        .decayed_variable_len_array,
+        .decayed_unspecified_variable_len_array,
+        .decayed_typeof_type,
+        .decayed_typeof_expr,
+        => true,
+        else => false,
+    };
+    std.debug.assert(decayed or !std.mem.startsWith(u8, @tagName(ty.specifier), "decayed"));
+    return decayed;
+}
+
+pub fn isPtr(ty: Type) bool {
+    return switch (ty.specifier) {
+        .pointer,
+        .decayed_array,
+        .decayed_static_array,
+        .decayed_incomplete_array,
+        .decayed_variable_len_array,
+        .decayed_unspecified_variable_len_array,
+        .decayed_typeof_type,
+        .decayed_typeof_expr,
+        => true,
+        .typeof_type => ty.data.sub_type.isPtr(),
+        .typeof_expr => ty.data.expr.ty.isPtr(),
+        .attributed => ty.data.attributed.base.isPtr(),
+        else => false,
+    };
+}
+
+pub fn isInt(ty: Type) bool {
+    return switch (ty.specifier) {
+        // zig fmt: off
+        .@"enum", .bool, .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong,
+        .long_long, .ulong_long, .int128, .uint128, .complex_char, .complex_schar, .complex_uchar,
+        .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
+        .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
+        .bit_int, .complex_bit_int => true,
+        // zig fmt: on
+        .typeof_type => ty.data.sub_type.isInt(),
+        .typeof_expr => ty.data.expr.ty.isInt(),
+        .attributed => ty.data.attributed.base.isInt(),
+        else => false,
+    };
+}
+
+pub fn isFloat(ty: Type) bool {
+    return switch (ty.specifier) {
+        // zig fmt: off
+        .float, .double, .long_double, .complex_float, .complex_double, .complex_long_double,
+        .fp16, .float16, .float80, .float128, .complex_float80, .complex_float128 => true,
+        // zig fmt: on
+        .typeof_type => ty.data.sub_type.isFloat(),
+        .typeof_expr => ty.data.expr.ty.isFloat(),
+        .attributed => ty.data.attributed.base.isFloat(),
+        else => false,
+    };
+}
+
+pub fn isReal(ty: Type) bool {
+    return switch (ty.specifier) {
+        // zig fmt: off
+        .complex_float, .complex_double, .complex_long_double, .complex_float80,
+        .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
+        .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
+        .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
+        .complex_bit_int => false,
+        // zig fmt: on
+        .typeof_type => ty.data.sub_type.isReal(),
+        .typeof_expr => ty.data.expr.ty.isReal(),
+        .attributed => ty.data.attributed.base.isReal(),
+        else => true,
+    };
+}
+
+pub fn isComplex(ty: Type) bool {
+    return switch (ty.specifier) {
+        // zig fmt: off
+        .complex_float, .complex_double, .complex_long_double, .complex_float80,
+        .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
+        .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
+        .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
+        .complex_bit_int => true,
+        // zig fmt: on
+        .typeof_type => ty.data.sub_type.isComplex(),
+        .typeof_expr => ty.data.expr.ty.isComplex(),
+        .attributed => ty.data.attributed.base.isComplex(),
+        else => false,
+    };
+}
+
+pub fn isVoidStar(ty: Type) bool {
+    return switch (ty.specifier) {
+        .pointer => ty.data.sub_type.specifier == .void,
+        .typeof_type => ty.data.sub_type.isVoidStar(),
+        .typeof_expr => ty.data.expr.ty.isVoidStar(),
+        .attributed => ty.data.attributed.base.isVoidStar(),
+        else => false,
+    };
+}
+
+pub fn isTypeof(ty: Type) bool {
+    return switch (ty.specifier) {
+        .typeof_type, .typeof_expr, .decayed_typeof_type, .decayed_typeof_expr => true,
+        else => false,
+    };
+}
+
+pub fn isConst(ty: Type) bool {
+    return switch (ty.specifier) {
+        .typeof_type, .decayed_typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(),
+        .typeof_expr, .decayed_typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(),
+        .attributed => ty.data.attributed.base.isConst(),
+        else => ty.qual.@"const",
+    };
+}
+
+pub fn isUnsignedInt(ty: Type, comp: *const Compilation) bool {
+    return switch (ty.specifier) {
+        // zig fmt: off
+        .char, .complex_char => return comp.getCharSignedness() == .unsigned,
+        .uchar, .ushort, .uint, .ulong, .ulong_long, .bool, .complex_uchar, .complex_ushort,
+        .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128 => true,
+        // zig fmt: on
+        .bit_int, .complex_bit_int => return ty.data.int.signedness == .unsigned,
+        .typeof_type => ty.data.sub_type.isUnsignedInt(comp),
+        .typeof_expr => ty.data.expr.ty.isUnsignedInt(comp),
+        .attributed => ty.data.attributed.base.isUnsignedInt(comp),
+        else => false,
+    };
+}
+
+pub fn isEnumOrRecord(ty: Type) bool {
+    return switch (ty.specifier) {
+        .@"enum", .@"struct", .@"union" => true,
+        .typeof_type => ty.data.sub_type.isEnumOrRecord(),
+        .typeof_expr => ty.data.expr.ty.isEnumOrRecord(),
+        .attributed => ty.data.attributed.base.isEnumOrRecord(),
+        else => false,
+    };
+}
+
+pub fn isRecord(ty: Type) bool {
+    return switch (ty.specifier) {
+        .@"struct", .@"union" => true,
+        .typeof_type => ty.data.sub_type.isRecord(),
+        .typeof_expr => ty.data.expr.ty.isRecord(),
+        .attributed => ty.data.attributed.base.isRecord(),
+        else => false,
+    };
+}
+
+pub fn isAnonymousRecord(ty: Type, comp: *const Compilation) bool {
+    return switch (ty.specifier) {
+        // anonymous records can be recognized by their names which are in
+        // the format "(anonymous TAG at path:line:col)".
+        .@"struct", .@"union" => {
+            const mapper = comp.string_interner.getSlowTypeMapper();
+            return mapper.lookup(ty.data.record.name)[0] == '(';
+        },
+        .typeof_type => ty.data.sub_type.isAnonymousRecord(comp),
+        .typeof_expr => ty.data.expr.ty.isAnonymousRecord(comp),
+        .attributed => ty.data.attributed.base.isAnonymousRecord(comp),
+        else => false,
+    };
+}
+
+pub fn elemType(ty: Type) Type {
+    return switch (ty.specifier) {
+        .pointer, .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => ty.data.sub_type.*,
+        .array, .static_array, .incomplete_array, .decayed_array, .decayed_static_array, .decayed_incomplete_array, .vector => ty.data.array.elem,
+        .variable_len_array, .decayed_variable_len_array => ty.data.expr.ty,
+        .typeof_type, .decayed_typeof_type, .typeof_expr, .decayed_typeof_expr => {
+            const unwrapped = ty.canonicalize(.preserve_quals);
+            var elem = unwrapped.elemType();
+            elem.qual = elem.qual.mergeAll(unwrapped.qual);
+            return elem;
+        },
+        .attributed => ty.data.attributed.base,
+        .invalid => Type.invalid,
+        // zig fmt: off
+        .complex_float, .complex_double, .complex_long_double, .complex_float80,
+        .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
+        .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
+        .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
+        .complex_bit_int => ty.makeReal(),
+        // zig fmt: on
+        else => unreachable,
+    };
+}
+
+pub fn returnType(ty: Type) Type {
+    return switch (ty.specifier) {
+        .func, .var_args_func, .old_style_func => ty.data.func.return_type,
+        .typeof_type, .decayed_typeof_type => ty.data.sub_type.returnType(),
+        .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.returnType(),
+        .attributed => ty.data.attributed.base.returnType(),
+        .invalid => Type.invalid,
+        else => unreachable,
+    };
+}
+
+pub fn params(ty: Type) []Func.Param {
+    return switch (ty.specifier) {
+        .func, .var_args_func, .old_style_func => ty.data.func.params,
+        .typeof_type, .decayed_typeof_type => ty.data.sub_type.params(),
+        .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.params(),
+        .attributed => ty.data.attributed.base.params(),
+        .invalid => &.{},
+        else => unreachable,
+    };
+}
+
+pub fn arrayLen(ty: Type) ?u64 {
+    return switch (ty.specifier) {
+        .array, .static_array, .decayed_array, .decayed_static_array => ty.data.array.len,
+        .typeof_type, .decayed_typeof_type => ty.data.sub_type.arrayLen(),
+        .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.arrayLen(),
+        .attributed => ty.data.attributed.base.arrayLen(),
+        else => null,
+    };
+}
+
+/// Complex numbers are scalars but they can be initialized with a 2-element initList
+pub fn expectedInitListSize(ty: Type) ?u64 {
+    return if (ty.isComplex()) 2 else ty.arrayLen();
+}
+
+pub fn anyQual(ty: Type) bool {
+    return switch (ty.specifier) {
+        .typeof_type => ty.qual.any() or ty.data.sub_type.anyQual(),
+        .typeof_expr => ty.qual.any() or ty.data.expr.ty.anyQual(),
+        else => ty.qual.any(),
+    };
+}
+
+pub fn getAttributes(ty: Type) []const Attribute {
+    return switch (ty.specifier) {
+        .attributed => ty.data.attributed.attributes,
+        .typeof_type, .decayed_typeof_type => ty.data.sub_type.getAttributes(),
+        .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getAttributes(),
+        else => &.{},
+    };
+}
+
+pub fn getRecord(ty: Type) ?*const Type.Record {
+    return switch (ty.specifier) {
+        .attributed => ty.data.attributed.base.getRecord(),
+        .typeof_type, .decayed_typeof_type => ty.data.sub_type.getRecord(),
+        .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getRecord(),
+        .@"struct", .@"union" => ty.data.record,
+        else => null,
+    };
+}
+
+fn compareIntegerRanks(a: Type, b: Type, comp: *const Compilation) std.math.Order {
+    std.debug.assert(a.isInt() and b.isInt());
+    if (a.eql(b, comp, false)) return .eq;
+
+    const a_unsigned = a.isUnsignedInt(comp);
+    const b_unsigned = b.isUnsignedInt(comp);
+
+    const a_rank = a.integerRank(comp);
+    const b_rank = b.integerRank(comp);
+    if (a_unsigned == b_unsigned) {
+        return std.math.order(a_rank, b_rank);
+    }
+    if (a_unsigned) {
+        if (a_rank >= b_rank) return .gt;
+        return .lt;
+    }
+    std.debug.assert(b_unsigned);
+    if (b_rank >= a_rank) return .lt;
+    return .gt;
+}
+
+fn realIntegerConversion(a: Type, b: Type, comp: *const Compilation) Type {
+    std.debug.assert(a.isReal() and b.isReal());
+    const type_order = a.compareIntegerRanks(b, comp);
+    const a_signed = !a.isUnsignedInt(comp);
+    const b_signed = !b.isUnsignedInt(comp);
+    if (a_signed == b_signed) {
+        // If both have the same sign, use higher-rank type.
+        return switch (type_order) {
+            .lt => b,
+            .eq, .gt => a,
+        };
+    } else if (type_order != if (a_signed) std.math.Order.gt else std.math.Order.lt) {
+        // Only one is signed; and the unsigned type has rank >= the signed type
+        // Use the unsigned type
+        return if (b_signed) a else b;
+    } else if (a.bitSizeof(comp).? != b.bitSizeof(comp).?) {
+        // Signed type is higher rank and sizes are not equal
+        // Use the signed type
+        return if (a_signed) a else b;
+    } else {
+        // Signed type is higher rank but same size as unsigned type
+        // e.g. `long` and `unsigned` on x86-linux-gnu
+        // Use unsigned version of the signed type
+        return if (a_signed) a.makeIntegerUnsigned() else b.makeIntegerUnsigned();
+    }
+}
+
+pub fn makeIntegerUnsigned(ty: Type) Type {
+    // TODO discards attributed/typeof
+    var base = ty.canonicalize(.standard);
+    switch (base.specifier) {
+        // zig fmt: off
+        .uchar, .ushort, .uint, .ulong, .ulong_long, .uint128,
+        .complex_uchar, .complex_ushort, .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128,
+        => return ty,
+        // zig fmt: on
+
+        .char, .complex_char => {
+            base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 2);
+            return base;
+        },
+
+        // zig fmt: off
+        .schar, .short, .int, .long, .long_long, .int128,
+        .complex_schar, .complex_short, .complex_int, .complex_long, .complex_long_long, .complex_int128 => {
+            base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 1);
+            return base;
+        },
+        // zig fmt: on
+
+        .bit_int, .complex_bit_int => {
+            base.data.int.signedness = .unsigned;
+            return base;
+        },
+        else => unreachable,
+    }
+}
+
+/// Find the common type of a and b for binary operations
+pub fn integerConversion(a: Type, b: Type, comp: *const Compilation) Type {
+    const a_real = a.isReal();
+    const b_real = b.isReal();
+    const target_ty = a.makeReal().realIntegerConversion(b.makeReal(), comp);
+    return if (a_real and b_real) target_ty else target_ty.makeComplex();
+}
+
+pub fn integerPromotion(ty: Type, comp: *Compilation) Type {
+    var specifier = ty.specifier;
+    switch (specifier) {
+        .@"enum" => {
+            if (ty.hasIncompleteSize()) return .{ .specifier = .int };
+            specifier = ty.data.@"enum".tag_ty.specifier;
+        },
+        .bit_int, .complex_bit_int => return .{ .specifier = specifier, .data = ty.data },
+        else => {},
+    }
+    return switch (specifier) {
+        else => .{
+            .specifier = switch (specifier) {
+                // zig fmt: off
+                .bool, .char, .schar, .uchar, .short => .int,
+                .ushort => if (ty.sizeof(comp).? == sizeof(.{ .specifier = .int }, comp)) Specifier.uint else .int,
+                .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128, .complex_char,
+                .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
+                .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
+                .complex_int128, .complex_uint128 => specifier,
+                // zig fmt: on
+                .typeof_type => return ty.data.sub_type.integerPromotion(comp),
+                .typeof_expr => return ty.data.expr.ty.integerPromotion(comp),
+                .attributed => return ty.data.attributed.base.integerPromotion(comp),
+                .invalid => .invalid,
+                else => unreachable, // _BitInt, or not an integer type
+            },
+        },
+    };
+}
+
+/// Promote a bitfield. If `int` can hold all the values of the underlying field,
+/// promote to int. Otherwise, promote to unsigned int
+/// Returns null if no promotion is necessary
+pub fn bitfieldPromotion(ty: Type, comp: *Compilation, width: u32) ?Type {
+    const type_size_bits = ty.bitSizeof(comp).?;
+
+    // Note: GCC and clang will promote `long: 3` to int even though the C standard does not allow this
+    if (width < type_size_bits) {
+        return int;
+    }
+
+    if (width == type_size_bits) {
+        return if (ty.isUnsignedInt(comp)) .{ .specifier = .uint } else int;
+    }
+
+    return null;
+}
+
+pub fn hasIncompleteSize(ty: Type) bool {
+    return switch (ty.specifier) {
+        .void, .incomplete_array, .invalid => true,
+        .@"enum" => ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed,
+        .@"struct", .@"union" => ty.data.record.isIncomplete(),
+        .array, .static_array => ty.data.array.elem.hasIncompleteSize(),
+        .typeof_type => ty.data.sub_type.hasIncompleteSize(),
+        .typeof_expr => ty.data.expr.ty.hasIncompleteSize(),
+        .attributed => ty.data.attributed.base.hasIncompleteSize(),
+        else => false,
+    };
+}
+
+pub fn hasUnboundVLA(ty: Type) bool {
+    var cur = ty;
+    while (true) {
+        switch (cur.specifier) {
+            .unspecified_variable_len_array,
+            .decayed_unspecified_variable_len_array,
+            => return true,
+            .array,
+            .static_array,
+            .incomplete_array,
+            .variable_len_array,
+            .decayed_array,
+            .decayed_static_array,
+            .decayed_incomplete_array,
+            .decayed_variable_len_array,
+            => cur = cur.elemType(),
+            .typeof_type, .decayed_typeof_type => cur = cur.data.sub_type.*,
+            .typeof_expr, .decayed_typeof_expr => cur = cur.data.expr.ty,
+            .attributed => cur = cur.data.attributed.base,
+            else => return false,
+        }
+    }
+}
+
+pub fn hasField(ty: Type, name: StringId) bool {
+    switch (ty.specifier) {
+        .@"struct" => {
+            std.debug.assert(!ty.data.record.isIncomplete());
+            for (ty.data.record.fields) |f| {
+                if (f.isAnonymousRecord() and f.ty.hasField(name)) return true;
+                if (name == f.name) return true;
+            }
+        },
+        .@"union" => {
+            std.debug.assert(!ty.data.record.isIncomplete());
+            for (ty.data.record.fields) |f| {
+                if (f.isAnonymousRecord() and f.ty.hasField(name)) return true;
+                if (name == f.name) return true;
+            }
+        },
+        .typeof_type => return ty.data.sub_type.hasField(name),
+        .typeof_expr => return ty.data.expr.ty.hasField(name),
+        .attributed => return ty.data.attributed.base.hasField(name),
+        .invalid => return false,
+        else => unreachable,
+    }
+    return false;
+}
+
+pub fn minInt(ty: Type, comp: *const Compilation) i64 {
+    std.debug.assert(ty.isInt());
+    if (ty.isUnsignedInt(comp)) return 0;
+    return switch (ty.sizeof(comp).?) {
+        1 => std.math.minInt(i8),
+        2 => std.math.minInt(i16),
+        4 => std.math.minInt(i32),
+        8 => std.math.minInt(i64),
+        else => unreachable,
+    };
+}
+
+pub fn maxInt(ty: Type, comp: *const Compilation) u64 {
+    std.debug.assert(ty.isInt());
+    return switch (ty.sizeof(comp).?) {
+        1 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u8)) else std.math.maxInt(i8),
+        2 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u16)) else std.math.maxInt(i16),
+        4 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u32)) else std.math.maxInt(i32),
+        8 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u64)) else std.math.maxInt(i64),
+        else => unreachable,
+    };
+}
+
+const TypeSizeOrder = enum {
+    lt,
+    gt,
+    eq,
+    indeterminate,
+};
+
+pub fn sizeCompare(a: Type, b: Type, comp: *Compilation) TypeSizeOrder {
+    const a_size = a.sizeof(comp) orelse return .indeterminate;
+    const b_size = b.sizeof(comp) orelse return .indeterminate;
+    return switch (std.math.order(a_size, b_size)) {
+        .lt => .lt,
+        .gt => .gt,
+        .eq => .eq,
+    };
+}
+
+/// Size of type as reported by sizeof
+pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
+    return switch (ty.specifier) {
+        .auto_type => unreachable,
+        .variable_len_array, .unspecified_variable_len_array => return null,
+        .incomplete_array => return if (comp.langopts.emulate == .msvc) @as(?u64, 0) else null,
+        .func, .var_args_func, .old_style_func, .void, .bool => 1,
+        .char, .schar, .uchar => 1,
+        .short => comp.target.c_type_byte_size(.short),
+        .ushort => comp.target.c_type_byte_size(.ushort),
+        .int => comp.target.c_type_byte_size(.int),
+        .uint => comp.target.c_type_byte_size(.uint),
+        .long => comp.target.c_type_byte_size(.long),
+        .ulong => comp.target.c_type_byte_size(.ulong),
+        .long_long => comp.target.c_type_byte_size(.longlong),
+        .ulong_long => comp.target.c_type_byte_size(.ulonglong),
+        .long_double => comp.target.c_type_byte_size(.longdouble),
+        .int128, .uint128 => 16,
+        .fp16, .float16 => 2,
+        .float => comp.target.c_type_byte_size(.float),
+        .double => comp.target.c_type_byte_size(.double),
+        .float80 => 16,
+        .float128 => 16,
+        .bit_int => {
+            return std.mem.alignForward(u64, (ty.data.int.bits + 7) / 8, ty.alignof(comp));
+        },
+        // zig fmt: off
+        .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
+        .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
+        .complex_int128, .complex_uint128, .complex_float, .complex_double,
+        .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
+        => return 2 * ty.makeReal().sizeof(comp).?,
+        // zig fmt: on
+        .pointer,
+        .decayed_array,
+        .decayed_static_array,
+        .decayed_incomplete_array,
+        .decayed_variable_len_array,
+        .decayed_unspecified_variable_len_array,
+        .decayed_typeof_type,
+        .decayed_typeof_expr,
+        .static_array,
+        .nullptr_t,
+        => comp.target.ptrBitWidth() / 8,
+        .array, .vector => {
+            const size = ty.data.array.elem.sizeof(comp) orelse return null;
+            const arr_size = size * ty.data.array.len;
+            if (comp.langopts.emulate == .msvc) {
+                // msvc ignores array type alignment.
+                // Since the size might not be a multiple of the field
+                // alignment, the address of the second element might not be properly aligned
+                // for the field alignment. A flexible array has size 0. See test case 0018.
+                return arr_size;
+            } else {
+                return std.mem.alignForward(u64, arr_size, ty.alignof(comp));
+            }
+        },
+        .@"struct", .@"union" => if (ty.data.record.isIncomplete()) null else @as(u64, ty.data.record.type_layout.size_bits / 8),
+        .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) null else ty.data.@"enum".tag_ty.sizeof(comp),
+        .typeof_type => ty.data.sub_type.sizeof(comp),
+        .typeof_expr => ty.data.expr.ty.sizeof(comp),
+        .attributed => ty.data.attributed.base.sizeof(comp),
+        .invalid => return null,
+    };
+}
+
+pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 {
+    return switch (ty.specifier) {
+        .bool => if (comp.langopts.emulate == .msvc) @as(u64, 8) else 1,
+        .typeof_type, .decayed_typeof_type => ty.data.sub_type.bitSizeof(comp),
+        .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.bitSizeof(comp),
+        .attributed => ty.data.attributed.base.bitSizeof(comp),
+        .bit_int => return ty.data.int.bits,
+        .long_double => comp.target.c_type_bit_size(.longdouble),
+        .float80 => return 80,
+        else => 8 * (ty.sizeof(comp) orelse return null),
+    };
+}
+
+pub fn alignable(ty: Type) bool {
+    return ty.isArray() or !ty.hasIncompleteSize() or ty.is(.void);
+}
+
+/// Get the alignment of a type
+pub fn alignof(ty: Type, comp: *const Compilation) u29 {
+    // don't return the attribute for records
+    // layout has already accounted for requested alignment
+    if (ty.requestedAlignment(comp)) |requested| {
+        // gcc does not respect alignment on enums
+        if (ty.get(.@"enum")) |ty_enum| {
+            if (comp.langopts.emulate == .gcc) {
+                return ty_enum.alignof(comp);
+            }
+        } else if (ty.getRecord()) |rec| {
+            if (ty.hasIncompleteSize()) return 0;
+            const computed: u29 = @intCast(@divExact(rec.type_layout.field_alignment_bits, 8));
+            return @max(requested, computed);
+        } else if (comp.langopts.emulate == .msvc) {
+            const type_align = ty.data.attributed.base.alignof(comp);
+            return @max(requested, type_align);
+        }
+        return requested;
+    }
+
+    return switch (ty.specifier) {
+        .invalid => unreachable,
+        .auto_type => unreachable,
+
+        .variable_len_array,
+        .incomplete_array,
+        .unspecified_variable_len_array,
+        .array,
+        .vector,
+        => ty.elemType().alignof(comp),
+        .func, .var_args_func, .old_style_func => target_util.defaultFunctionAlignment(comp.target),
+        .char, .schar, .uchar, .void, .bool => 1,
+
+        // zig fmt: off
+        .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
+        .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
+        .complex_int128, .complex_uint128, .complex_float, .complex_double,
+        .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
+        => return ty.makeReal().alignof(comp),
+        // zig fmt: on
+
+        .short => comp.target.c_type_alignment(.short),
+        .ushort => comp.target.c_type_alignment(.ushort),
+        .int => comp.target.c_type_alignment(.int),
+        .uint => comp.target.c_type_alignment(.uint),
+
+        .long => comp.target.c_type_alignment(.long),
+        .ulong => comp.target.c_type_alignment(.ulong),
+        .long_long => comp.target.c_type_alignment(.longlong),
+        .ulong_long => comp.target.c_type_alignment(.ulonglong),
+
+        .bit_int => @min(
+            std.math.ceilPowerOfTwoPromote(u16, (ty.data.int.bits + 7) / 8),
+            comp.target.maxIntAlignment(),
+        ),
+
+        .float => comp.target.c_type_alignment(.float),
+        .double => comp.target.c_type_alignment(.double),
+        .long_double => comp.target.c_type_alignment(.longdouble),
+
+        .int128, .uint128 => if (comp.target.cpu.arch == .s390x and comp.target.os.tag == .linux and comp.target.isGnu()) 8 else 16,
+        .fp16, .float16 => 2,
+
+        .float80, .float128 => 16,
+        .pointer,
+        .decayed_array,
+        .decayed_static_array,
+        .decayed_incomplete_array,
+        .decayed_variable_len_array,
+        .decayed_unspecified_variable_len_array,
+        .static_array,
+        .nullptr_t,
+        => switch (comp.target.cpu.arch) {
+            .avr => 1,
+            else => comp.target.ptrBitWidth() / 8,
+        },
+        .@"struct", .@"union" => if (ty.data.record.isIncomplete()) 0 else @intCast(ty.data.record.type_layout.field_alignment_bits / 8),
+        .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) 0 else ty.data.@"enum".tag_ty.alignof(comp),
+        .typeof_type, .decayed_typeof_type => ty.data.sub_type.alignof(comp),
+        .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.alignof(comp),
+        .attributed => ty.data.attributed.base.alignof(comp),
+    };
+}
+
+/// Canonicalize a possibly-typeof() type. If the type is not a typeof() type, simply
+/// return it. Otherwise, determine the actual qualified type.
+/// The `qual_handling` parameter can be used to return the full set of qualifiers
+/// added by typeof() operations, which is useful when determining the elemType of
+/// arrays and pointers.
+pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) Type {
+    var cur = ty;
+    if (cur.specifier == .attributed) cur = cur.data.attributed.base;
+    if (!cur.isTypeof()) return cur;
+
+    var qual = cur.qual;
+    while (true) {
+        switch (cur.specifier) {
+            .typeof_type => cur = cur.data.sub_type.*,
+            .typeof_expr => cur = cur.data.expr.ty,
+            .decayed_typeof_type => {
+                cur = cur.data.sub_type.*;
+                cur.decayArray();
+            },
+            .decayed_typeof_expr => {
+                cur = cur.data.expr.ty;
+                cur.decayArray();
+            },
+            else => break,
+        }
+        qual = qual.mergeAll(cur.qual);
+    }
+    if ((cur.isArray() or cur.isPtr()) and qual_handling == .standard) {
+        cur.qual = .{};
+    } else {
+        cur.qual = qual;
+    }
+    return cur;
+}
+
+pub fn get(ty: *const Type, specifier: Specifier) ?*const Type {
+    std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr);
+    return switch (ty.specifier) {
+        .typeof_type => ty.data.sub_type.get(specifier),
+        .typeof_expr => ty.data.expr.ty.get(specifier),
+        .attributed => ty.data.attributed.base.get(specifier),
+        else => if (ty.specifier == specifier) ty else null,
+    };
+}
+
+pub fn requestedAlignment(ty: Type, comp: *const Compilation) ?u29 {
+    return switch (ty.specifier) {
+        .typeof_type, .decayed_typeof_type => ty.data.sub_type.requestedAlignment(comp),
+        .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.requestedAlignment(comp),
+        .attributed => annotationAlignment(comp, ty.data.attributed.attributes),
+        else => null,
+    };
+}
+
+pub fn enumIsPacked(ty: Type, comp: *const Compilation) bool {
+    std.debug.assert(ty.is(.@"enum"));
+    return comp.langopts.short_enums or target_util.packAllEnums(comp.target) or ty.hasAttribute(.@"packed");
+}
+
+pub fn annotationAlignment(comp: *const Compilation, attrs: ?[]const Attribute) ?u29 {
+    const a = attrs orelse return null;
+
+    var max_requested: ?u29 = null;
+    for (a) |attribute| {
+        if (attribute.tag != .aligned) continue;
+        const requested = if (attribute.args.aligned.alignment) |alignment| alignment.requested else target_util.defaultAlignment(comp.target);
+        if (max_requested == null or max_requested.? < requested) {
+            max_requested = requested;
+        }
+    }
+    return max_requested;
+}
+
+/// Checks type compatibility for __builtin_types_compatible_p
+/// Returns true if the unqualified version of `a_param` and `b_param` are the same
+/// Ignores top-level qualifiers (e.g. `int` and `const int` are compatible) but `int *` and `const int *` are not
+/// Two types that are typedefed are considered compatible if their underlying types are compatible.
+/// An enum type is not considered to be compatible with another enum type even if both are compatible with the same integer type;
+/// `A[]` and `A[N]` for a type `A` and integer `N` are compatible
+pub fn compatible(a_param: Type, b_param: Type, comp: *const Compilation) bool {
+    var a_unqual = a_param.canonicalize(.standard);
+    a_unqual.qual.@"const" = false;
+    a_unqual.qual.@"volatile" = false;
+    var b_unqual = b_param.canonicalize(.standard);
+    b_unqual.qual.@"const" = false;
+    b_unqual.qual.@"volatile" = false;
+
+    if (a_unqual.eql(b_unqual, comp, true)) return true;
+    if (!a_unqual.isArray() or !b_unqual.isArray()) return false;
+
+    if (a_unqual.arrayLen() == null or b_unqual.arrayLen() == null) {
+        // incomplete arrays are compatible with arrays of the same element type
+        // GCC and clang ignore cv-qualifiers on arrays
+        return a_unqual.elemType().compatible(b_unqual.elemType(), comp);
+    }
+    return false;
+}
+
+pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifiers: bool) bool {
+    const a = a_param.canonicalize(.standard);
+    const b = b_param.canonicalize(.standard);
+
+    if (a.specifier == .invalid or b.specifier == .invalid) return false;
+    if (a.alignof(comp) != b.alignof(comp)) return false;
+    if (a.isPtr()) {
+        if (!b.isPtr()) return false;
+    } else if (a.isFunc()) {
+        if (!b.isFunc()) return false;
+    } else if (a.isArray()) {
+        if (!b.isArray()) return false;
+    } else if (a.specifier != b.specifier) return false;
+
+    if (a.qual.atomic != b.qual.atomic) return false;
+    if (check_qualifiers) {
+        if (a.qual.@"const" != b.qual.@"const") return false;
+        if (a.qual.@"volatile" != b.qual.@"volatile") return false;
+    }
+
+    switch (a.specifier) {
+        .pointer,
+        .decayed_array,
+        .decayed_static_array,
+        .decayed_incomplete_array,
+        .decayed_variable_len_array,
+        .decayed_unspecified_variable_len_array,
+        => if (!a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers)) return false,
+
+        .func,
+        .var_args_func,
+        .old_style_func,
+        => {
+            // TODO validate this
+            if (a.data.func.params.len != b.data.func.params.len) return false;
+            // return type cannot have qualifiers
+            if (!a.returnType().eql(b.returnType(), comp, false)) return false;
+            for (a.data.func.params, b.data.func.params) |param, b_qual| {
+                var a_unqual = param.ty;
+                a_unqual.qual.@"const" = false;
+                a_unqual.qual.@"volatile" = false;
+                var b_unqual = b_qual.ty;
+                b_unqual.qual.@"const" = false;
+                b_unqual.qual.@"volatile" = false;
+                if (!a_unqual.eql(b_unqual, comp, check_qualifiers)) return false;
+            }
+        },
+
+        .array,
+        .static_array,
+        .incomplete_array,
+        .vector,
+        => {
+            if (!std.meta.eql(a.arrayLen(), b.arrayLen())) return false;
+            if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false;
+        },
+        .variable_len_array => if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false,
+
+        .@"struct", .@"union" => if (a.data.record != b.data.record) return false,
+        .@"enum" => if (a.data.@"enum" != b.data.@"enum") return false,
+        .bit_int, .complex_bit_int => return a.data.int.bits == b.data.int.bits and a.data.int.signedness == b.data.int.signedness,
+
+        else => {},
+    }
+    return true;
+}
+
+/// Decays an array to a pointer
+pub fn decayArray(ty: *Type) void {
+    // the decayed array type is the current specifier +1
+    ty.specifier = @enumFromInt(@intFromEnum(ty.specifier) + 1);
+}
+
+pub fn originalTypeOfDecayedArray(ty: Type) Type {
+    std.debug.assert(ty.isDecayed());
+    var copy = ty;
+    copy.specifier = @enumFromInt(@intFromEnum(ty.specifier) - 1);
+    return copy;
+}
+
+/// Rank for floating point conversions, ignoring domain (complex vs real)
+/// Asserts that ty is a floating point type
+pub fn floatRank(ty: Type) usize {
+    const real = ty.makeReal();
+    return switch (real.specifier) {
+        // TODO: bfloat16 => 0
+        .float16 => 1,
+        .fp16 => 2,
+        .float => 3,
+        .double => 4,
+        .long_double => 5,
+        .float128 => 6,
+        // TODO: ibm128 => 7
+        else => unreachable,
+    };
+}
+
+/// Rank for integer conversions, ignoring domain (complex vs real)
+/// Asserts that ty is an integer type
+pub fn integerRank(ty: Type, comp: *const Compilation) usize {
+    const real = ty.makeReal();
+    return @intCast(switch (real.specifier) {
+        .bit_int => @as(u64, real.data.int.bits) << 3,
+
+        .bool => 1 + (ty.bitSizeof(comp).? << 3),
+        .char, .schar, .uchar => 2 + (ty.bitSizeof(comp).? << 3),
+        .short, .ushort => 3 + (ty.bitSizeof(comp).? << 3),
+        .int, .uint => 4 + (ty.bitSizeof(comp).? << 3),
+        .long, .ulong => 5 + (ty.bitSizeof(comp).? << 3),
+        .long_long, .ulong_long => 6 + (ty.bitSizeof(comp).? << 3),
+        .int128, .uint128 => 7 + (ty.bitSizeof(comp).? << 3),
+
+        else => unreachable,
+    });
+}
+
+/// Returns true if `a` and `b` are integer types that differ only in sign
+pub fn sameRankDifferentSign(a: Type, b: Type, comp: *const Compilation) bool {
+    if (!a.isInt() or !b.isInt()) return false;
+    if (a.integerRank(comp) != b.integerRank(comp)) return false;
+    return a.isUnsignedInt(comp) != b.isUnsignedInt(comp);
+}
+
+pub fn makeReal(ty: Type) Type {
+    // TODO discards attributed/typeof
+    var base = ty.canonicalize(.standard);
+    switch (base.specifier) {
+        .complex_float, .complex_double, .complex_long_double, .complex_float80, .complex_float128 => {
+            base.specifier = @enumFromInt(@intFromEnum(base.specifier) - 5);
+            return base;
+        },
+        .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128 => {
+            base.specifier = @enumFromInt(@intFromEnum(base.specifier) - 13);
+            return base;
+        },
+        .complex_bit_int => {
+            base.specifier = .bit_int;
+            return base;
+        },
+        else => return ty,
+    }
+}
+
+pub fn makeComplex(ty: Type) Type {
+    // TODO discards attributed/typeof
+    var base = ty.canonicalize(.standard);
+    switch (base.specifier) {
+        .float, .double, .long_double, .float80, .float128 => {
+            base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 5);
+            return base;
+        },
+        .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128 => {
+            base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 13);
+            return base;
+        },
+        .bit_int => {
+            base.specifier = .complex_bit_int;
+            return base;
+        },
+        else => return ty,
+    }
+}
+
+/// Combines types recursively in the order they were parsed, uses `.void` specifier as a sentinel value.
+pub fn combine(inner: *Type, outer: Type) Parser.Error!void {
+    switch (inner.specifier) {
+        .pointer => return inner.data.sub_type.combine(outer),
+        .unspecified_variable_len_array => {
+            try inner.data.sub_type.combine(outer);
+        },
+        .variable_len_array => {
+            try inner.data.expr.ty.combine(outer);
+        },
+        .array, .static_array, .incomplete_array => {
+            try inner.data.array.elem.combine(outer);
+        },
+        .func, .var_args_func, .old_style_func => {
+            try inner.data.func.return_type.combine(outer);
+        },
+        .decayed_array,
+        .decayed_static_array,
+        .decayed_incomplete_array,
+        .decayed_variable_len_array,
+        .decayed_unspecified_variable_len_array,
+        .decayed_typeof_type,
+        .decayed_typeof_expr,
+        => unreachable, // type should not be able to decay before being combined
+        .void => inner.* = outer,
+        else => unreachable,
+    }
+}
+
+pub fn validateCombinedType(ty: Type, p: *Parser, source_tok: TokenIndex) Parser.Error!void {
+    switch (ty.specifier) {
+        .pointer => return ty.data.sub_type.validateCombinedType(p, source_tok),
+        .unspecified_variable_len_array,
+        .variable_len_array,
+        .array,
+        .static_array,
+        .incomplete_array,
+        => {
+            const elem_ty = ty.elemType();
+            if (elem_ty.hasIncompleteSize()) {
+                try p.errStr(.array_incomplete_elem, source_tok, try p.typeStr(elem_ty));
+                return error.ParsingFailed;
+            }
+            if (elem_ty.isFunc()) {
+                try p.errTok(.array_func_elem, source_tok);
+                return error.ParsingFailed;
+            }
+            if (elem_ty.specifier == .static_array and elem_ty.isArray()) {
+                try p.errTok(.static_non_outermost_array, source_tok);
+            }
+            if (elem_ty.anyQual() and elem_ty.isArray()) {
+                try p.errTok(.qualifier_non_outermost_array, source_tok);
+            }
+        },
+        .func, .var_args_func, .old_style_func => {
+            const ret_ty = &ty.data.func.return_type;
+            if (ret_ty.isArray()) try p.errTok(.func_cannot_return_array, source_tok);
+            if (ret_ty.isFunc()) try p.errTok(.func_cannot_return_func, source_tok);
+            if (ret_ty.qual.@"const") {
+                try p.errStr(.qual_on_ret_type, source_tok, "const");
+                ret_ty.qual.@"const" = false;
+            }
+            if (ret_ty.qual.@"volatile") {
+                try p.errStr(.qual_on_ret_type, source_tok, "volatile");
+                ret_ty.qual.@"volatile" = false;
+            }
+            if (ret_ty.qual.atomic) {
+                try p.errStr(.qual_on_ret_type, source_tok, "atomic");
+                ret_ty.qual.atomic = false;
+            }
+            if (ret_ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
+                try p.errStr(.suggest_pointer_for_invalid_fp16, source_tok, "function return value");
+            }
+        },
+        .typeof_type, .decayed_typeof_type => return ty.data.sub_type.validateCombinedType(p, source_tok),
+        .typeof_expr, .decayed_typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok),
+        .attributed => return ty.data.attributed.base.validateCombinedType(p, source_tok),
+        else => {},
+    }
+}
+
+/// An unfinished Type
+pub const Builder = struct {
+    complex_tok: ?TokenIndex = null,
+    bit_int_tok: ?TokenIndex = null,
+    auto_type_tok: ?TokenIndex = null,
+    typedef: ?struct {
+        tok: TokenIndex,
+        ty: Type,
+    } = null,
+    specifier: Builder.Specifier = .none,
+    qual: Qualifiers.Builder = .{},
+    typeof: ?Type = null,
+    /// When true an error is returned instead of adding a diagnostic message.
+    /// Used for trying to combine typedef types.
+    error_on_invalid: bool = false,
+
+    pub const Specifier = union(enum) {
+        none,
+        void,
+        /// GNU __auto_type extension
+        auto_type,
+        nullptr_t,
+        bool,
+        char,
+        schar,
+        uchar,
+        complex_char,
+        complex_schar,
+        complex_uchar,
+
+        unsigned,
+        signed,
+        short,
+        sshort,
+        ushort,
+        short_int,
+        sshort_int,
+        ushort_int,
+        int,
+        sint,
+        uint,
+        long,
+        slong,
+        ulong,
+        long_int,
+        slong_int,
+        ulong_int,
+        long_long,
+        slong_long,
+        ulong_long,
+        long_long_int,
+        slong_long_int,
+        ulong_long_int,
+        int128,
+        sint128,
+        uint128,
+        complex_unsigned,
+        complex_signed,
+        complex_short,
+        complex_sshort,
+        complex_ushort,
+        complex_short_int,
+        complex_sshort_int,
+        complex_ushort_int,
+        complex_int,
+        complex_sint,
+        complex_uint,
+        complex_long,
+        complex_slong,
+        complex_ulong,
+        complex_long_int,
+        complex_slong_int,
+        complex_ulong_int,
+        complex_long_long,
+        complex_slong_long,
+        complex_ulong_long,
+        complex_long_long_int,
+        complex_slong_long_int,
+        complex_ulong_long_int,
+        complex_int128,
+        complex_sint128,
+        complex_uint128,
+        bit_int: i16,
+        sbit_int: i16,
+        ubit_int: i16,
+        complex_bit_int: i16,
+        complex_sbit_int: i16,
+        complex_ubit_int: i16,
+
+        fp16,
+        float16,
+        float,
+        double,
+        long_double,
+        float80,
+        float128,
+        complex,
+        complex_float,
+        complex_double,
+        complex_long_double,
+        complex_float80,
+        complex_float128,
+
+        pointer: *Type,
+        unspecified_variable_len_array: *Type,
+        decayed_unspecified_variable_len_array: *Type,
+        func: *Func,
+        var_args_func: *Func,
+        old_style_func: *Func,
+        array: *Array,
+        decayed_array: *Array,
+        static_array: *Array,
+        decayed_static_array: *Array,
+        incomplete_array: *Array,
+        decayed_incomplete_array: *Array,
+        vector: *Array,
+        variable_len_array: *Expr,
+        decayed_variable_len_array: *Expr,
+        @"struct": *Record,
+        @"union": *Record,
+        @"enum": *Enum,
+        typeof_type: *Type,
+        decayed_typeof_type: *Type,
+        typeof_expr: *Expr,
+        decayed_typeof_expr: *Expr,
+
+        attributed: *Attributed,
+
+        pub fn str(spec: Builder.Specifier, langopts: LangOpts) ?[]const u8 {
+            return switch (spec) {
+                .none => unreachable,
+                .void => "void",
+                .auto_type => "__auto_type",
+                .nullptr_t => "nullptr_t",
+                .bool => if (langopts.standard.atLeast(.c2x)) "bool" else "_Bool",
+                .char => "char",
+                .schar => "signed char",
+                .uchar => "unsigned char",
+                .unsigned => "unsigned",
+                .signed => "signed",
+                .short => "short",
+                .ushort => "unsigned short",
+                .sshort => "signed short",
+                .short_int => "short int",
+                .sshort_int => "signed short int",
+                .ushort_int => "unsigned short int",
+                .int => "int",
+                .sint => "signed int",
+                .uint => "unsigned int",
+                .long => "long",
+                .slong => "signed long",
+                .ulong => "unsigned long",
+                .long_int => "long int",
+                .slong_int => "signed long int",
+                .ulong_int => "unsigned long int",
+                .long_long => "long long",
+                .slong_long => "signed long long",
+                .ulong_long => "unsigned long long",
+                .long_long_int => "long long int",
+                .slong_long_int => "signed long long int",
+                .ulong_long_int => "unsigned long long int",
+                .int128 => "__int128",
+                .sint128 => "signed __int128",
+                .uint128 => "unsigned __int128",
+                .bit_int => "_BitInt",
+                .sbit_int => "signed _BitInt",
+                .ubit_int => "unsigned _BitInt",
+                .complex_char => "_Complex char",
+                .complex_schar => "_Complex signed char",
+                .complex_uchar => "_Complex unsigned char",
+                .complex_unsigned => "_Complex unsigned",
+                .complex_signed => "_Complex signed",
+                .complex_short => "_Complex short",
+                .complex_ushort => "_Complex unsigned short",
+                .complex_sshort => "_Complex signed short",
+                .complex_short_int => "_Complex short int",
+                .complex_sshort_int => "_Complex signed short int",
+                .complex_ushort_int => "_Complex unsigned short int",
+                .complex_int => "_Complex int",
+                .complex_sint => "_Complex signed int",
+                .complex_uint => "_Complex unsigned int",
+                .complex_long => "_Complex long",
+                .complex_slong => "_Complex signed long",
+                .complex_ulong => "_Complex unsigned long",
+                .complex_long_int => "_Complex long int",
+                .complex_slong_int => "_Complex signed long int",
+                .complex_ulong_int => "_Complex unsigned long int",
+                .complex_long_long => "_Complex long long",
+                .complex_slong_long => "_Complex signed long long",
+                .complex_ulong_long => "_Complex unsigned long long",
+                .complex_long_long_int => "_Complex long long int",
+                .complex_slong_long_int => "_Complex signed long long int",
+                .complex_ulong_long_int => "_Complex unsigned long long int",
+                .complex_int128 => "_Complex __int128",
+                .complex_sint128 => "_Complex signed __int128",
+                .complex_uint128 => "_Complex unsigned __int128",
+                .complex_bit_int => "_Complex _BitInt",
+                .complex_sbit_int => "_Complex signed _BitInt",
+                .complex_ubit_int => "_Complex unsigned _BitInt",
+
+                .fp16 => "__fp16",
+                .float16 => "_Float16",
+                .float => "float",
+                .double => "double",
+                .long_double => "long double",
+                .float80 => "__float80",
+                .float128 => "__float128",
+                .complex => "_Complex",
+                .complex_float => "_Complex float",
+                .complex_double => "_Complex double",
+                .complex_long_double => "_Complex long double",
+                .complex_float80 => "_Complex __float80",
+                .complex_float128 => "_Complex __float128",
+
+                .attributed => |attributed| Builder.fromType(attributed.base).str(langopts),
+
+                else => null,
+            };
+        }
+    };
+
+    pub fn finish(b: Builder, p: *Parser) Parser.Error!Type {
+        var ty: Type = .{ .specifier = undefined };
+        if (b.typedef) |typedef| {
+            ty = typedef.ty;
+            if (ty.isArray()) {
+                var elem = ty.elemType();
+                try b.qual.finish(p, &elem);
+                // TODO this really should be easier
+                switch (ty.specifier) {
+                    .array, .static_array, .incomplete_array => {
+                        var old = ty.data.array;
+                        ty.data.array = try p.arena.create(Array);
+                        ty.data.array.* = .{
+                            .len = old.len,
+                            .elem = elem,
+                        };
+                    },
+                    .variable_len_array, .unspecified_variable_len_array => {
+                        var old = ty.data.expr;
+                        ty.data.expr = try p.arena.create(Expr);
+                        ty.data.expr.* = .{
+                            .node = old.node,
+                            .ty = elem,
+                        };
+                    },
+                    .typeof_type => {}, // TODO handle
+                    .typeof_expr => {}, // TODO handle
+                    .attributed => {}, // TODO handle
+                    else => unreachable,
+                }
+
+                return ty;
+            }
+            try b.qual.finish(p, &ty);
+            return ty;
+        }
+        switch (b.specifier) {
+            .none => {
+                if (b.typeof) |typeof| {
+                    ty = typeof;
+                } else {
+                    ty.specifier = .int;
+                    try p.err(.missing_type_specifier);
+                }
+            },
+            .void => ty.specifier = .void,
+            .auto_type => ty.specifier = .auto_type,
+            .nullptr_t => unreachable, // nullptr_t can only be accessed via typeof(nullptr)
+            .bool => ty.specifier = .bool,
+            .char => ty.specifier = .char,
+            .schar => ty.specifier = .schar,
+            .uchar => ty.specifier = .uchar,
+            .complex_char => ty.specifier = .complex_char,
+            .complex_schar => ty.specifier = .complex_schar,
+            .complex_uchar => ty.specifier = .complex_uchar,
+
+            .unsigned => ty.specifier = .uint,
+            .signed => ty.specifier = .int,
+            .short_int, .sshort_int, .short, .sshort => ty.specifier = .short,
+            .ushort, .ushort_int => ty.specifier = .ushort,
+            .int, .sint => ty.specifier = .int,
+            .uint => ty.specifier = .uint,
+            .long, .slong, .long_int, .slong_int => ty.specifier = .long,
+            .ulong, .ulong_int => ty.specifier = .ulong,
+            .long_long, .slong_long, .long_long_int, .slong_long_int => ty.specifier = .long_long,
+            .ulong_long, .ulong_long_int => ty.specifier = .ulong_long,
+            .int128, .sint128 => ty.specifier = .int128,
+            .uint128 => ty.specifier = .uint128,
+            .complex_unsigned => ty.specifier = .complex_uint,
+            .complex_signed => ty.specifier = .complex_int,
+            .complex_short_int, .complex_sshort_int, .complex_short, .complex_sshort => ty.specifier = .complex_short,
+            .complex_ushort, .complex_ushort_int => ty.specifier = .complex_ushort,
+            .complex_int, .complex_sint => ty.specifier = .complex_int,
+            .complex_uint => ty.specifier = .complex_uint,
+            .complex_long, .complex_slong, .complex_long_int, .complex_slong_int => ty.specifier = .complex_long,
+            .complex_ulong, .complex_ulong_int => ty.specifier = .complex_ulong,
+            .complex_long_long, .complex_slong_long, .complex_long_long_int, .complex_slong_long_int => ty.specifier = .complex_long_long,
+            .complex_ulong_long, .complex_ulong_long_int => ty.specifier = .complex_ulong_long,
+            .complex_int128, .complex_sint128 => ty.specifier = .complex_int128,
+            .complex_uint128 => ty.specifier = .complex_uint128,
+            .bit_int, .sbit_int, .ubit_int, .complex_bit_int, .complex_ubit_int, .complex_sbit_int => |bits| {
+                const unsigned = b.specifier == .ubit_int or b.specifier == .complex_ubit_int;
+                if (unsigned) {
+                    if (bits < 1) {
+                        try p.errStr(.unsigned_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
+                        return error.ParsingFailed;
+                    }
+                } else {
+                    if (bits < 2) {
+                        try p.errStr(.signed_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
+                        return error.ParsingFailed;
+                    }
+                }
+                if (bits > Compilation.bit_int_max_bits) {
+                    try p.errStr(.bit_int_too_big, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
+                    return error.ParsingFailed;
+                }
+                ty.specifier = if (b.complex_tok != null) .complex_bit_int else .bit_int;
+                ty.data = .{ .int = .{
+                    .signedness = if (unsigned) .unsigned else .signed,
+                    .bits = @intCast(bits),
+                } };
+            },
+
+            .fp16 => ty.specifier = .fp16,
+            .float16 => ty.specifier = .float16,
+            .float => ty.specifier = .float,
+            .double => ty.specifier = .double,
+            .long_double => ty.specifier = .long_double,
+            .float80 => ty.specifier = .float80,
+            .float128 => ty.specifier = .float128,
+            .complex_float => ty.specifier = .complex_float,
+            .complex_double => ty.specifier = .complex_double,
+            .complex_long_double => ty.specifier = .complex_long_double,
+            .complex_float80 => ty.specifier = .complex_float80,
+            .complex_float128 => ty.specifier = .complex_float128,
+            .complex => {
+                try p.errTok(.plain_complex, p.tok_i - 1);
+                ty.specifier = .complex_double;
+            },
+
+            .pointer => |data| {
+                ty.specifier = .pointer;
+                ty.data = .{ .sub_type = data };
+            },
+            .unspecified_variable_len_array => |data| {
+                ty.specifier = .unspecified_variable_len_array;
+                ty.data = .{ .sub_type = data };
+            },
+            .decayed_unspecified_variable_len_array => |data| {
+                ty.specifier = .decayed_unspecified_variable_len_array;
+                ty.data = .{ .sub_type = data };
+            },
+            .func => |data| {
+                ty.specifier = .func;
+                ty.data = .{ .func = data };
+            },
+            .var_args_func => |data| {
+                ty.specifier = .var_args_func;
+                ty.data = .{ .func = data };
+            },
+            .old_style_func => |data| {
+                ty.specifier = .old_style_func;
+                ty.data = .{ .func = data };
+            },
+            .array => |data| {
+                ty.specifier = .array;
+                ty.data = .{ .array = data };
+            },
+            .decayed_array => |data| {
+                ty.specifier = .decayed_array;
+                ty.data = .{ .array = data };
+            },
+            .static_array => |data| {
+                ty.specifier = .static_array;
+                ty.data = .{ .array = data };
+            },
+            .decayed_static_array => |data| {
+                ty.specifier = .decayed_static_array;
+                ty.data = .{ .array = data };
+            },
+            .incomplete_array => |data| {
+                ty.specifier = .incomplete_array;
+                ty.data = .{ .array = data };
+            },
+            .decayed_incomplete_array => |data| {
+                ty.specifier = .decayed_incomplete_array;
+                ty.data = .{ .array = data };
+            },
+            .vector => |data| {
+                ty.specifier = .vector;
+                ty.data = .{ .array = data };
+            },
+            .variable_len_array => |data| {
+                ty.specifier = .variable_len_array;
+                ty.data = .{ .expr = data };
+            },
+            .decayed_variable_len_array => |data| {
+                ty.specifier = .decayed_variable_len_array;
+                ty.data = .{ .expr = data };
+            },
+            .@"struct" => |data| {
+                ty.specifier = .@"struct";
+                ty.data = .{ .record = data };
+            },
+            .@"union" => |data| {
+                ty.specifier = .@"union";
+                ty.data = .{ .record = data };
+            },
+            .@"enum" => |data| {
+                ty.specifier = .@"enum";
+                ty.data = .{ .@"enum" = data };
+            },
+            .typeof_type => |data| {
+                ty.specifier = .typeof_type;
+                ty.data = .{ .sub_type = data };
+            },
+            .decayed_typeof_type => |data| {
+                ty.specifier = .decayed_typeof_type;
+                ty.data = .{ .sub_type = data };
+            },
+            .typeof_expr => |data| {
+                ty.specifier = .typeof_expr;
+                ty.data = .{ .expr = data };
+            },
+            .decayed_typeof_expr => |data| {
+                ty.specifier = .decayed_typeof_expr;
+                ty.data = .{ .expr = data };
+            },
+            .attributed => |data| {
+                ty.specifier = .attributed;
+                ty.data = .{ .attributed = data };
+            },
+        }
+        if (!ty.isReal() and ty.isInt()) {
+            if (b.complex_tok) |tok| try p.errTok(.complex_int, tok);
+        }
+        try b.qual.finish(p, &ty);
+        return ty;
+    }
+
+    fn cannotCombine(b: Builder, p: *Parser, source_tok: TokenIndex) !void {
+        if (b.error_on_invalid) return error.CannotCombine;
+        const ty_str = b.specifier.str(p.comp.langopts) orelse try p.typeStr(try b.finish(p));
+        try p.errExtra(.cannot_combine_spec, source_tok, .{ .str = ty_str });
+        if (b.typedef) |some| try p.errStr(.spec_from_typedef, some.tok, try p.typeStr(some.ty));
+    }
+
+    fn duplicateSpec(b: *Builder, p: *Parser, source_tok: TokenIndex, spec: []const u8) !void {
+        if (b.error_on_invalid) return error.CannotCombine;
+        if (p.comp.langopts.emulate != .clang) return b.cannotCombine(p, source_tok);
+        try p.errStr(.duplicate_decl_spec, p.tok_i, spec);
+    }
+
+    pub fn combineFromTypeof(b: *Builder, p: *Parser, new: Type, source_tok: TokenIndex) Compilation.Error!void {
+        if (b.typeof != null) return p.errStr(.cannot_combine_spec, source_tok, "typeof");
+        if (b.specifier != .none) return p.errStr(.invalid_typeof, source_tok, @tagName(b.specifier));
+        const inner = switch (new.specifier) {
+            .typeof_type => new.data.sub_type.*,
+            .typeof_expr => new.data.expr.ty,
+            .nullptr_t => new, // typeof(nullptr) is special-cased to be an unwrapped typeof-expr
+            else => unreachable,
+        };
+
+        b.typeof = switch (inner.specifier) {
+            .attributed => inner.data.attributed.base,
+            else => new,
+        };
+    }
+
+    /// Try to combine type from typedef, returns true if successful.
+    pub fn combineTypedef(b: *Builder, p: *Parser, typedef_ty: Type, name_tok: TokenIndex) bool {
+        b.error_on_invalid = true;
+        defer b.error_on_invalid = false;
+
+        const new_spec = fromType(typedef_ty);
+        b.combineExtra(p, new_spec, 0) catch |err| switch (err) {
+            error.FatalError => unreachable, // we do not add any diagnostics
+            error.OutOfMemory => unreachable, // we do not add any diagnostics
+            error.ParsingFailed => unreachable, // we do not add any diagnostics
+            error.CannotCombine => return false,
+        };
+        b.typedef = .{ .tok = name_tok, .ty = typedef_ty };
+        return true;
+    }
+
+    pub fn combine(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void {
+        b.combineExtra(p, new, source_tok) catch |err| switch (err) {
+            error.CannotCombine => unreachable,
+            else => |e| return e,
+        };
+    }
+
+    fn combineExtra(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void {
+        if (b.typeof != null) {
+            if (b.error_on_invalid) return error.CannotCombine;
+            try p.errStr(.invalid_typeof, source_tok, @tagName(new));
+        }
+
+        switch (new) {
+            .complex => b.complex_tok = source_tok,
+            .bit_int => b.bit_int_tok = source_tok,
+            .auto_type => b.auto_type_tok = source_tok,
+            else => {},
+        }
+
+        if (new == .int128 and !target_util.hasInt128(p.comp.target)) {
+            try p.errStr(.type_not_supported_on_target, source_tok, "__int128");
+        }
+
+        switch (new) {
+            else => switch (b.specifier) {
+                .none => b.specifier = new,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .signed => b.specifier = switch (b.specifier) {
+                .none => .signed,
+                .char => .schar,
+                .short => .sshort,
+                .short_int => .sshort_int,
+                .int => .sint,
+                .long => .slong,
+                .long_int => .slong_int,
+                .long_long => .slong_long,
+                .long_long_int => .slong_long_int,
+                .int128 => .sint128,
+                .bit_int => |bits| .{ .sbit_int = bits },
+                .complex => .complex_signed,
+                .complex_char => .complex_schar,
+                .complex_short => .complex_sshort,
+                .complex_short_int => .complex_sshort_int,
+                .complex_int => .complex_sint,
+                .complex_long => .complex_slong,
+                .complex_long_int => .complex_slong_int,
+                .complex_long_long => .complex_slong_long,
+                .complex_long_long_int => .complex_slong_long_int,
+                .complex_int128 => .complex_sint128,
+                .complex_bit_int => |bits| .{ .complex_sbit_int = bits },
+                .signed,
+                .sshort,
+                .sshort_int,
+                .sint,
+                .slong,
+                .slong_int,
+                .slong_long,
+                .slong_long_int,
+                .sint128,
+                .sbit_int,
+                .complex_schar,
+                .complex_signed,
+                .complex_sshort,
+                .complex_sshort_int,
+                .complex_sint,
+                .complex_slong,
+                .complex_slong_int,
+                .complex_slong_long,
+                .complex_slong_long_int,
+                .complex_sint128,
+                .complex_sbit_int,
+                => return b.duplicateSpec(p, source_tok, "signed"),
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .unsigned => b.specifier = switch (b.specifier) {
+                .none => .unsigned,
+                .char => .uchar,
+                .short => .ushort,
+                .short_int => .ushort_int,
+                .int => .uint,
+                .long => .ulong,
+                .long_int => .ulong_int,
+                .long_long => .ulong_long,
+                .long_long_int => .ulong_long_int,
+                .int128 => .uint128,
+                .bit_int => |bits| .{ .ubit_int = bits },
+                .complex => .complex_unsigned,
+                .complex_char => .complex_uchar,
+                .complex_short => .complex_ushort,
+                .complex_short_int => .complex_ushort_int,
+                .complex_int => .complex_uint,
+                .complex_long => .complex_ulong,
+                .complex_long_int => .complex_ulong_int,
+                .complex_long_long => .complex_ulong_long,
+                .complex_long_long_int => .complex_ulong_long_int,
+                .complex_int128 => .complex_uint128,
+                .complex_bit_int => |bits| .{ .complex_ubit_int = bits },
+                .unsigned,
+                .ushort,
+                .ushort_int,
+                .uint,
+                .ulong,
+                .ulong_int,
+                .ulong_long,
+                .ulong_long_int,
+                .uint128,
+                .ubit_int,
+                .complex_uchar,
+                .complex_unsigned,
+                .complex_ushort,
+                .complex_ushort_int,
+                .complex_uint,
+                .complex_ulong,
+                .complex_ulong_int,
+                .complex_ulong_long,
+                .complex_ulong_long_int,
+                .complex_uint128,
+                .complex_ubit_int,
+                => return b.duplicateSpec(p, source_tok, "unsigned"),
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .char => b.specifier = switch (b.specifier) {
+                .none => .char,
+                .unsigned => .uchar,
+                .signed => .schar,
+                .complex => .complex_char,
+                .complex_signed => .complex_schar,
+                .complex_unsigned => .complex_uchar,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .short => b.specifier = switch (b.specifier) {
+                .none => .short,
+                .unsigned => .ushort,
+                .signed => .sshort,
+                .int => .short_int,
+                .sint => .sshort_int,
+                .uint => .ushort_int,
+                .complex => .complex_short,
+                .complex_signed => .complex_sshort,
+                .complex_unsigned => .complex_ushort,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .int => b.specifier = switch (b.specifier) {
+                .none => .int,
+                .signed => .sint,
+                .unsigned => .uint,
+                .short => .short_int,
+                .sshort => .sshort_int,
+                .ushort => .ushort_int,
+                .long => .long_int,
+                .slong => .slong_int,
+                .ulong => .ulong_int,
+                .long_long => .long_long_int,
+                .slong_long => .slong_long_int,
+                .ulong_long => .ulong_long_int,
+                .complex => .complex_int,
+                .complex_signed => .complex_sint,
+                .complex_unsigned => .complex_uint,
+                .complex_short => .complex_short_int,
+                .complex_sshort => .complex_sshort_int,
+                .complex_ushort => .complex_ushort_int,
+                .complex_long => .complex_long_int,
+                .complex_slong => .complex_slong_int,
+                .complex_ulong => .complex_ulong_int,
+                .complex_long_long => .complex_long_long_int,
+                .complex_slong_long => .complex_slong_long_int,
+                .complex_ulong_long => .complex_ulong_long_int,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .long => b.specifier = switch (b.specifier) {
+                .none => .long,
+                .long => .long_long,
+                .unsigned => .ulong,
+                .signed => .long,
+                .int => .long_int,
+                .sint => .slong_int,
+                .ulong => .ulong_long,
+                .complex => .complex_long,
+                .complex_signed => .complex_slong,
+                .complex_unsigned => .complex_ulong,
+                .complex_long => .complex_long_long,
+                .complex_slong => .complex_slong_long,
+                .complex_ulong => .complex_ulong_long,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .int128 => b.specifier = switch (b.specifier) {
+                .none => .int128,
+                .unsigned => .uint128,
+                .signed => .sint128,
+                .complex => .complex_int128,
+                .complex_signed => .complex_sint128,
+                .complex_unsigned => .complex_uint128,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .bit_int => b.specifier = switch (b.specifier) {
+                .none => .{ .bit_int = new.bit_int },
+                .unsigned => .{ .ubit_int = new.bit_int },
+                .signed => .{ .sbit_int = new.bit_int },
+                .complex => .{ .complex_bit_int = new.bit_int },
+                .complex_signed => .{ .complex_sbit_int = new.bit_int },
+                .complex_unsigned => .{ .complex_ubit_int = new.bit_int },
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .auto_type => b.specifier = switch (b.specifier) {
+                .none => .auto_type,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .fp16 => b.specifier = switch (b.specifier) {
+                .none => .fp16,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .float16 => b.specifier = switch (b.specifier) {
+                .none => .float16,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .float => b.specifier = switch (b.specifier) {
+                .none => .float,
+                .complex => .complex_float,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .double => b.specifier = switch (b.specifier) {
+                .none => .double,
+                .long => .long_double,
+                .complex_long => .complex_long_double,
+                .complex => .complex_double,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .float80 => b.specifier = switch (b.specifier) {
+                .none => .float80,
+                .complex => .complex_float80,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .float128 => b.specifier = switch (b.specifier) {
+                .none => .float128,
+                .complex => .complex_float128,
+                else => return b.cannotCombine(p, source_tok),
+            },
+            .complex => b.specifier = switch (b.specifier) {
+                .none => .complex,
+                .float => .complex_float,
+                .double => .complex_double,
+                .long_double => .complex_long_double,
+                .float80 => .complex_float80,
+                .float128 => .complex_float128,
+                .char => .complex_char,
+                .schar => .complex_schar,
+                .uchar => .complex_uchar,
+                .unsigned => .complex_unsigned,
+                .signed => .complex_signed,
+                .short => .complex_short,
+                .sshort => .complex_sshort,
+                .ushort => .complex_ushort,
+                .short_int => .complex_short_int,
+                .sshort_int => .complex_sshort_int,
+                .ushort_int => .complex_ushort_int,
+                .int => .complex_int,
+                .sint => .complex_sint,
+                .uint => .complex_uint,
+                .long => .complex_long,
+                .slong => .complex_slong,
+                .ulong => .complex_ulong,
+                .long_int => .complex_long_int,
+                .slong_int => .complex_slong_int,
+                .ulong_int => .complex_ulong_int,
+                .long_long => .complex_long_long,
+                .slong_long => .complex_slong_long,
+                .ulong_long => .complex_ulong_long,
+                .long_long_int => .complex_long_long_int,
+                .slong_long_int => .complex_slong_long_int,
+                .ulong_long_int => .complex_ulong_long_int,
+                .int128 => .complex_int128,
+                .sint128 => .complex_sint128,
+                .uint128 => .complex_uint128,
+                .bit_int => |bits| .{ .complex_bit_int = bits },
+                .sbit_int => |bits| .{ .complex_sbit_int = bits },
+                .ubit_int => |bits| .{ .complex_ubit_int = bits },
+                .complex,
+                .complex_float,
+                .complex_double,
+                .complex_long_double,
+                .complex_float80,
+                .complex_float128,
+                .complex_char,
+                .complex_schar,
+                .complex_uchar,
+                .complex_unsigned,
+                .complex_signed,
+                .complex_short,
+                .complex_sshort,
+                .complex_ushort,
+                .complex_short_int,
+                .complex_sshort_int,
+                .complex_ushort_int,
+                .complex_int,
+                .complex_sint,
+                .complex_uint,
+                .complex_long,
+                .complex_slong,
+                .complex_ulong,
+                .complex_long_int,
+                .complex_slong_int,
+                .complex_ulong_int,
+                .complex_long_long,
+                .complex_slong_long,
+                .complex_ulong_long,
+                .complex_long_long_int,
+                .complex_slong_long_int,
+                .complex_ulong_long_int,
+                .complex_int128,
+                .complex_sint128,
+                .complex_uint128,
+                .complex_bit_int,
+                .complex_sbit_int,
+                .complex_ubit_int,
+                => return b.duplicateSpec(p, source_tok, "_Complex"),
+                else => return b.cannotCombine(p, source_tok),
+            },
+        }
+    }
+
+    pub fn fromType(ty: Type) Builder.Specifier {
+        return switch (ty.specifier) {
+            .void => .void,
+            .auto_type => .auto_type,
+            .nullptr_t => .nullptr_t,
+            .bool => .bool,
+            .char => .char,
+            .schar => .schar,
+            .uchar => .uchar,
+            .short => .short,
+            .ushort => .ushort,
+            .int => .int,
+            .uint => .uint,
+            .long => .long,
+            .ulong => .ulong,
+            .long_long => .long_long,
+            .ulong_long => .ulong_long,
+            .int128 => .int128,
+            .uint128 => .uint128,
+            .bit_int => if (ty.data.int.signedness == .unsigned) {
+                return .{ .ubit_int = ty.data.int.bits };
+            } else {
+                return .{ .bit_int = ty.data.int.bits };
+            },
+            .complex_char => .complex_char,
+            .complex_schar => .complex_schar,
+            .complex_uchar => .complex_uchar,
+            .complex_short => .complex_short,
+            .complex_ushort => .complex_ushort,
+            .complex_int => .complex_int,
+            .complex_uint => .complex_uint,
+            .complex_long => .complex_long,
+            .complex_ulong => .complex_ulong,
+            .complex_long_long => .complex_long_long,
+            .complex_ulong_long => .complex_ulong_long,
+            .complex_int128 => .complex_int128,
+            .complex_uint128 => .complex_uint128,
+            .complex_bit_int => if (ty.data.int.signedness == .unsigned) {
+                return .{ .complex_ubit_int = ty.data.int.bits };
+            } else {
+                return .{ .complex_bit_int = ty.data.int.bits };
+            },
+            .fp16 => .fp16,
+            .float16 => .float16,
+            .float => .float,
+            .double => .double,
+            .float80 => .float80,
+            .float128 => .float128,
+            .long_double => .long_double,
+            .complex_float => .complex_float,
+            .complex_double => .complex_double,
+            .complex_long_double => .complex_long_double,
+            .complex_float80 => .complex_float80,
+            .complex_float128 => .complex_float128,
+
+            .pointer => .{ .pointer = ty.data.sub_type },
+            .unspecified_variable_len_array => .{ .unspecified_variable_len_array = ty.data.sub_type },
+            .decayed_unspecified_variable_len_array => .{ .decayed_unspecified_variable_len_array = ty.data.sub_type },
+            .func => .{ .func = ty.data.func },
+            .var_args_func => .{ .var_args_func = ty.data.func },
+            .old_style_func => .{ .old_style_func = ty.data.func },
+            .array => .{ .array = ty.data.array },
+            .decayed_array => .{ .decayed_array = ty.data.array },
+            .static_array => .{ .static_array = ty.data.array },
+            .decayed_static_array => .{ .decayed_static_array = ty.data.array },
+            .incomplete_array => .{ .incomplete_array = ty.data.array },
+            .decayed_incomplete_array => .{ .decayed_incomplete_array = ty.data.array },
+            .vector => .{ .vector = ty.data.array },
+            .variable_len_array => .{ .variable_len_array = ty.data.expr },
+            .decayed_variable_len_array => .{ .decayed_variable_len_array = ty.data.expr },
+            .@"struct" => .{ .@"struct" = ty.data.record },
+            .@"union" => .{ .@"union" = ty.data.record },
+            .@"enum" => .{ .@"enum" = ty.data.@"enum" },
+
+            .typeof_type => .{ .typeof_type = ty.data.sub_type },
+            .decayed_typeof_type => .{ .decayed_typeof_type = ty.data.sub_type },
+            .typeof_expr => .{ .typeof_expr = ty.data.expr },
+            .decayed_typeof_expr => .{ .decayed_typeof_expr = ty.data.expr },
+
+            .attributed => .{ .attributed = ty.data.attributed },
+            else => unreachable,
+        };
+    }
+};
+
+pub fn getAttribute(ty: Type, comptime tag: Attribute.Tag) ?Attribute.ArgumentsForTag(tag) {
+    switch (ty.specifier) {
+        .typeof_type => return ty.data.sub_type.getAttribute(tag),
+        .typeof_expr => return ty.data.expr.ty.getAttribute(tag),
+        .attributed => {
+            for (ty.data.attributed.attributes) |attribute| {
+                if (attribute.tag == tag) return @field(attribute.args, @tagName(tag));
+            }
+            return null;
+        },
+        else => return null,
+    }
+}
+
+pub fn hasAttribute(ty: Type, tag: Attribute.Tag) bool {
+    for (ty.getAttributes()) |attr| {
+        if (attr.tag == tag) return true;
+    }
+    return false;
+}
+
+/// printf format modifier
+pub fn formatModifier(ty: Type) []const u8 {
+    return switch (ty.specifier) {
+        .schar, .uchar => "hh",
+        .short, .ushort => "h",
+        .int, .uint => "",
+        .long, .ulong => "l",
+        .long_long, .ulong_long => "ll",
+        else => unreachable,
+    };
+}
+
+/// Suffix for integer values of this type
+pub fn intValueSuffix(ty: Type, comp: *const Compilation) []const u8 {
+    return switch (ty.specifier) {
+        .schar, .short, .int => "",
+        .long => "L",
+        .long_long => "LL",
+        .uchar, .char => {
+            if (ty.specifier == .char and comp.getCharSignedness() == .signed) return "";
+            // Only 8-bit char supported currently;
+            // TODO: handle platforms with 16-bit int + 16-bit char
+            std.debug.assert(ty.sizeof(comp).? == 1);
+            return "";
+        },
+        .ushort => {
+            if (ty.sizeof(comp).? < int.sizeof(comp).?) {
+                return "";
+            }
+            return "U";
+        },
+        .uint => "U",
+        .ulong => "UL",
+        .ulong_long => "ULL",
+        else => unreachable, // not integer
+    };
+}
+
+/// Print type in C style
+pub fn print(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+    _ = try ty.printPrologue(mapper, langopts, w);
+    try ty.printEpilogue(mapper, langopts, w);
+}
+
+pub fn printNamed(ty: Type, name: []const u8, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+    const simple = try ty.printPrologue(mapper, langopts, w);
+    if (simple) try w.writeByte(' ');
+    try w.writeAll(name);
+    try ty.printEpilogue(mapper, langopts, w);
+}
+
+const StringGetter = fn (TokenIndex) []const u8;
+
+/// return true if `ty` is simple
+fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!bool {
+    if (ty.qual.atomic) {
+        var non_atomic_ty = ty;
+        non_atomic_ty.qual.atomic = false;
+        try w.writeAll("_Atomic(");
+        try non_atomic_ty.print(mapper, langopts, w);
+        try w.writeAll(")");
+        return true;
+    }
+    switch (ty.specifier) {
+        .pointer,
+        .decayed_array,
+        .decayed_static_array,
+        .decayed_incomplete_array,
+        .decayed_variable_len_array,
+        .decayed_unspecified_variable_len_array,
+        .decayed_typeof_type,
+        .decayed_typeof_expr,
+        => {
+            const elem_ty = ty.elemType();
+            const simple = try elem_ty.printPrologue(mapper, langopts, w);
+            if (simple) try w.writeByte(' ');
+            if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte('(');
+            try w.writeByte('*');
+            try ty.qual.dump(w);
+            return false;
+        },
+        .func, .var_args_func, .old_style_func => {
+            const ret_ty = ty.data.func.return_type;
+            const simple = try ret_ty.printPrologue(mapper, langopts, w);
+            if (simple) try w.writeByte(' ');
+            return false;
+        },
+        .array, .static_array, .incomplete_array, .unspecified_variable_len_array, .variable_len_array => {
+            const elem_ty = ty.elemType();
+            const simple = try elem_ty.printPrologue(mapper, langopts, w);
+            if (simple) try w.writeByte(' ');
+            return false;
+        },
+        .typeof_type, .typeof_expr => {
+            const actual = ty.canonicalize(.standard);
+            return actual.printPrologue(mapper, langopts, w);
+        },
+        .attributed => {
+            const actual = ty.canonicalize(.standard);
+            return actual.printPrologue(mapper, langopts, w);
+        },
+        else => {},
+    }
+    try ty.qual.dump(w);
+
+    switch (ty.specifier) {
+        .@"enum" => if (ty.data.@"enum".fixed) {
+            try w.print("enum {s}: ", .{mapper.lookup(ty.data.@"enum".name)});
+            try ty.data.@"enum".tag_ty.dump(mapper, langopts, w);
+        } else {
+            try w.print("enum {s}", .{mapper.lookup(ty.data.@"enum".name)});
+        },
+        .@"struct" => try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)}),
+        .@"union" => try w.print("union {s}", .{mapper.lookup(ty.data.record.name)}),
+        .vector => {
+            const len = ty.data.array.len;
+            const elem_ty = ty.data.array.elem;
+            try w.print("__attribute__((__vector_size__({d} * sizeof(", .{len});
+            _ = try elem_ty.printPrologue(mapper, langopts, w);
+            try w.writeAll(")))) ");
+            _ = try elem_ty.printPrologue(mapper, langopts, w);
+            try w.print(" (vector of {d} '", .{len});
+            _ = try elem_ty.printPrologue(mapper, langopts, w);
+            try w.writeAll("' values)");
+        },
+        else => try w.writeAll(Builder.fromType(ty).str(langopts).?),
+    }
+    return true;
+}
+
+fn printEpilogue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+    if (ty.qual.atomic) return;
+    switch (ty.specifier) {
+        .pointer,
+        .decayed_array,
+        .decayed_static_array,
+        .decayed_incomplete_array,
+        .decayed_variable_len_array,
+        .decayed_unspecified_variable_len_array,
+        .decayed_typeof_type,
+        .decayed_typeof_expr,
+        => {
+            const elem_ty = ty.elemType();
+            if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte(')');
+            try elem_ty.printEpilogue(mapper, langopts, w);
+        },
+        .func, .var_args_func, .old_style_func => {
+            try w.writeByte('(');
+            for (ty.data.func.params, 0..) |param, i| {
+                if (i != 0) try w.writeAll(", ");
+                _ = try param.ty.printPrologue(mapper, langopts, w);
+                try param.ty.printEpilogue(mapper, langopts, w);
+            }
+            if (ty.specifier != .func) {
+                if (ty.data.func.params.len != 0) try w.writeAll(", ");
+                try w.writeAll("...");
+            } else if (ty.data.func.params.len == 0) {
+                try w.writeAll("void");
+            }
+            try w.writeByte(')');
+            try ty.data.func.return_type.printEpilogue(mapper, langopts, w);
+        },
+        .array, .static_array => {
+            try w.writeByte('[');
+            if (ty.specifier == .static_array) try w.writeAll("static ");
+            try ty.qual.dump(w);
+            try w.print("{d}]", .{ty.data.array.len});
+            try ty.data.array.elem.printEpilogue(mapper, langopts, w);
+        },
+        .incomplete_array => {
+            try w.writeByte('[');
+            try ty.qual.dump(w);
+            try w.writeByte(']');
+            try ty.data.array.elem.printEpilogue(mapper, langopts, w);
+        },
+        .unspecified_variable_len_array => {
+            try w.writeByte('[');
+            try ty.qual.dump(w);
+            try w.writeAll("*]");
+            try ty.data.sub_type.printEpilogue(mapper, langopts, w);
+        },
+        .variable_len_array => {
+            try w.writeByte('[');
+            try ty.qual.dump(w);
+            try w.writeAll("<expr>]");
+            try ty.data.expr.ty.printEpilogue(mapper, langopts, w);
+        },
+        .typeof_type, .typeof_expr => {
+            const actual = ty.canonicalize(.standard);
+            try actual.printEpilogue(mapper, langopts, w);
+        },
+        .attributed => {
+            const actual = ty.canonicalize(.standard);
+            try actual.printEpilogue(mapper, langopts, w);
+        },
+        else => {},
+    }
+}
+
+/// Useful for debugging, too noisy to be enabled by default.
+const dump_detailed_containers = false;
+
+// Print as Zig types since those are actually readable
+pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+    try ty.qual.dump(w);
+    switch (ty.specifier) {
+        .invalid => try w.writeAll("invalid"),
+        .pointer => {
+            try w.writeAll("*");
+            try ty.data.sub_type.dump(mapper, langopts, w);
+        },
+        .func, .var_args_func, .old_style_func => {
+            try w.writeAll("fn (");
+            for (ty.data.func.params, 0..) |param, i| {
+                if (i != 0) try w.writeAll(", ");
+                if (param.name != .empty) try w.print("{s}: ", .{mapper.lookup(param.name)});
+                try param.ty.dump(mapper, langopts, w);
+            }
+            if (ty.specifier != .func) {
+                if (ty.data.func.params.len != 0) try w.writeAll(", ");
+                try w.writeAll("...");
+            }
+            try w.writeAll(") ");
+            try ty.data.func.return_type.dump(mapper, langopts, w);
+        },
+        .array, .static_array, .decayed_array, .decayed_static_array => {
+            if (ty.specifier == .decayed_array or ty.specifier == .decayed_static_array) try w.writeByte('d');
+            try w.writeByte('[');
+            if (ty.specifier == .static_array or ty.specifier == .decayed_static_array) try w.writeAll("static ");
+            try w.print("{d}]", .{ty.data.array.len});
+            try ty.data.array.elem.dump(mapper, langopts, w);
+        },
+        .vector => {
+            try w.print("vector({d}, ", .{ty.data.array.len});
+            try ty.data.array.elem.dump(mapper, langopts, w);
+            try w.writeAll(")");
+        },
+        .incomplete_array, .decayed_incomplete_array => {
+            if (ty.specifier == .decayed_incomplete_array) try w.writeByte('d');
+            try w.writeAll("[]");
+            try ty.data.array.elem.dump(mapper, langopts, w);
+        },
+        .@"enum" => {
+            const enum_ty = ty.data.@"enum";
+            if (enum_ty.isIncomplete() and !enum_ty.fixed) {
+                try w.print("enum {s}", .{mapper.lookup(enum_ty.name)});
+            } else {
+                try w.print("enum {s}: ", .{mapper.lookup(enum_ty.name)});
+                try enum_ty.tag_ty.dump(mapper, langopts, w);
+            }
+            if (dump_detailed_containers) try dumpEnum(enum_ty, mapper, w);
+        },
+        .@"struct" => {
+            try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)});
+            if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);
+        },
+        .@"union" => {
+            try w.print("union {s}", .{mapper.lookup(ty.data.record.name)});
+            if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);
+        },
+        .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => {
+            if (ty.specifier == .decayed_unspecified_variable_len_array) try w.writeByte('d');
+            try w.writeAll("[*]");
+            try ty.data.sub_type.dump(mapper, langopts, w);
+        },
+        .variable_len_array, .decayed_variable_len_array => {
+            if (ty.specifier == .decayed_variable_len_array) try w.writeByte('d');
+            try w.writeAll("[<expr>]");
+            try ty.data.expr.ty.dump(mapper, langopts, w);
+        },
+        .typeof_type, .decayed_typeof_type => {
+            try w.writeAll("typeof(");
+            try ty.data.sub_type.dump(mapper, langopts, w);
+            try w.writeAll(")");
+        },
+        .typeof_expr, .decayed_typeof_expr => {
+            try w.writeAll("typeof(<expr>: ");
+            try ty.data.expr.ty.dump(mapper, langopts, w);
+            try w.writeAll(")");
+        },
+        .attributed => {
+            try w.writeAll("attributed(");
+            try ty.data.attributed.base.dump(mapper, langopts, w);
+            try w.writeAll(")");
+        },
+        else => {
+            try w.writeAll(Builder.fromType(ty).str(langopts).?);
+            if (ty.specifier == .bit_int or ty.specifier == .complex_bit_int) {
+                try w.print("({d})", .{ty.data.int.bits});
+            }
+        },
+    }
+}
+
+fn dumpEnum(@"enum": *Enum, mapper: StringInterner.TypeMapper, w: anytype) @TypeOf(w).Error!void {
+    try w.writeAll(" {");
+    for (@"enum".fields) |field| {
+        try w.print(" {s} = {d},", .{ mapper.lookup(field.name), field.value });
+    }
+    try w.writeAll(" }");
+}
+
+fn dumpRecord(record: *Record, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
+    try w.writeAll(" {");
+    for (record.fields) |field| {
+        try w.writeByte(' ');
+        try field.ty.dump(mapper, langopts, w);
+        try w.print(" {s}: {d};", .{ mapper.lookup(field.name), field.bit_width });
+    }
+    try w.writeAll(" }");
+}
deps/aro/unicode.zig
@@ -0,0 +1,41 @@
+//! Copied from https://github.com/ziglang/zig/blob/6f0807f50f4e946bb850e746beaa5d6556cf7750/lib/std/unicode.zig
+//! with all safety checks removed. These functions must only be called with known-good buffers that have already
+//! been validated as being legitimate UTF8-encoded data, otherwise undefined behavior will occur.
+
+pub fn utf8ByteSequenceLength_unsafe(first_byte: u8) u3 {
+    return switch (first_byte) {
+        0b0000_0000...0b0111_1111 => 1,
+        0b1100_0000...0b1101_1111 => 2,
+        0b1110_0000...0b1110_1111 => 3,
+        0b1111_0000...0b1111_0111 => 4,
+        else => unreachable,
+    };
+}
+
+pub fn utf8Decode2_unsafe(bytes: []const u8) u21 {
+    var value: u21 = bytes[0] & 0b00011111;
+    value <<= 6;
+    return value | (bytes[1] & 0b00111111);
+}
+
+pub fn utf8Decode3_unsafe(bytes: []const u8) u21 {
+    var value: u21 = bytes[0] & 0b00001111;
+
+    value <<= 6;
+    value |= bytes[1] & 0b00111111;
+
+    value <<= 6;
+    return value | (bytes[2] & 0b00111111);
+}
+
+pub fn utf8Decode4_unsafe(bytes: []const u8) u21 {
+    var value: u21 = bytes[0] & 0b00000111;
+    value <<= 6;
+    value |= bytes[1] & 0b00111111;
+
+    value <<= 6;
+    value |= bytes[2] & 0b00111111;
+
+    value <<= 6;
+    return value | (bytes[3] & 0b00111111);
+}
deps/aro/util.zig
@@ -0,0 +1,83 @@
+const std = @import("std");
+const mem = std.mem;
+const builtin = @import("builtin");
+const is_windows = builtin.os.tag == .windows;
+
+pub const Color = enum {
+    reset,
+    red,
+    green,
+    blue,
+    cyan,
+    purple,
+    yellow,
+    white,
+};
+
+pub fn fileSupportsColor(file: std.fs.File) bool {
+    return file.supportsAnsiEscapeCodes() or (is_windows and file.isTty());
+}
+
+pub fn setColor(color: Color, w: anytype) void {
+    if (is_windows) {
+        const stderr_file = std.io.getStdErr();
+        if (!stderr_file.isTty()) return;
+        const windows = std.os.windows;
+        const S = struct {
+            var attrs: windows.WORD = undefined;
+            var init_attrs = false;
+        };
+        if (!S.init_attrs) {
+            S.init_attrs = true;
+            var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
+            _ = windows.kernel32.GetConsoleScreenBufferInfo(stderr_file.handle, &info);
+            S.attrs = info.wAttributes;
+            _ = windows.kernel32.SetConsoleOutputCP(65001);
+        }
+
+        // need to flush bufferedWriter
+        const T = if (@typeInfo(@TypeOf(w.context)) == .Pointer) @TypeOf(w.context.*) else @TypeOf(w.context);
+        if (T != void and @hasDecl(T, "flush")) w.context.flush() catch {};
+
+        switch (color) {
+            .reset => _ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs) catch {},
+            .red => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY) catch {},
+            .green => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {},
+            .blue => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {},
+            .cyan => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {},
+            .purple => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {},
+            .yellow => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {},
+            .white => _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {},
+        }
+    } else switch (color) {
+        .reset => w.writeAll("\x1b[0m") catch {},
+        .red => w.writeAll("\x1b[31;1m") catch {},
+        .green => w.writeAll("\x1b[32;1m") catch {},
+        .blue => w.writeAll("\x1b[34;1m") catch {},
+        .cyan => w.writeAll("\x1b[36;1m") catch {},
+        .purple => w.writeAll("\x1b[35;1m") catch {},
+        .yellow => w.writeAll("\x1b[93;1m") catch {},
+        .white => w.writeAll("\x1b[0m\x1b[1m") catch {},
+    }
+}
+
+pub fn errorDescription(err: anyerror) []const u8 {
+    return switch (err) {
+        error.OutOfMemory => "ran out of memory",
+        error.FileNotFound => "file not found",
+        error.IsDir => "is a directory",
+        error.NotDir => "is not a directory",
+        error.NotOpenForReading => "file is not open for reading",
+        error.NotOpenForWriting => "file is not open for writing",
+        error.InvalidUtf8 => "input is not valid UTF-8",
+        error.FileBusy => "file is busy",
+        error.NameTooLong => "file name is too long",
+        error.AccessDenied => "access denied",
+        error.FileTooBig => "file is too big",
+        error.ProcessFdQuotaExceeded, error.SystemFdQuotaExceeded => "ran out of file descriptors",
+        error.SystemResources => "ran out of system resources",
+        error.FatalError => "a fatal error occurred",
+        error.Unexpected => "an unexpected error occurred",
+        else => @errorName(err),
+    };
+}
deps/aro/Value.zig
@@ -0,0 +1,601 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const Compilation = @import("Compilation.zig");
+const Type = @import("Type.zig");
+
+const Value = @This();
+
+pub const ByteRange = struct {
+    start: u32,
+    end: u32,
+
+    pub fn len(self: ByteRange) u32 {
+        return self.end - self.start;
+    }
+
+    pub fn trim(self: ByteRange, amount: u32) ByteRange {
+        std.debug.assert(self.start <= self.end - amount);
+        return .{ .start = self.start, .end = self.end - amount };
+    }
+
+    pub fn slice(self: ByteRange, all_bytes: []const u8) []const u8 {
+        return all_bytes[self.start..self.end];
+    }
+};
+
+tag: Tag = .unavailable,
+data: union {
+    none: void,
+    int: u64,
+    float: f64,
+    bytes: ByteRange,
+} = .{ .none = {} },
+
+const Tag = enum {
+    unavailable,
+    nullptr_t,
+    /// int is used to store integer, boolean and pointer values
+    int,
+    float,
+    bytes,
+};
+
+pub fn zero(v: Value) Value {
+    return switch (v.tag) {
+        .int => int(0),
+        .float => float(0),
+        else => unreachable,
+    };
+}
+
+pub fn one(v: Value) Value {
+    return switch (v.tag) {
+        .int => int(1),
+        .float => float(1),
+        else => unreachable,
+    };
+}
+
+pub fn int(v: anytype) Value {
+    if (@TypeOf(v) == comptime_int or @typeInfo(@TypeOf(v)).Int.signedness == .unsigned)
+        return .{ .tag = .int, .data = .{ .int = v } }
+    else
+        return .{ .tag = .int, .data = .{ .int = @bitCast(@as(i64, v)) } };
+}
+
+pub fn float(v: anytype) Value {
+    return .{ .tag = .float, .data = .{ .float = v } };
+}
+
+pub fn bytes(start: u32, end: u32) Value {
+    return .{ .tag = .bytes, .data = .{ .bytes = .{ .start = start, .end = end } } };
+}
+
+pub fn signExtend(v: Value, old_ty: Type, comp: *Compilation) i64 {
+    const size = old_ty.sizeof(comp).?;
+    return switch (size) {
+        1 => v.getInt(i8),
+        2 => v.getInt(i16),
+        4 => v.getInt(i32),
+        8 => v.getInt(i64),
+        else => unreachable,
+    };
+}
+
+/// Number of bits needed to hold `v` which is of type `ty`.
+/// Asserts that `v` is not negative
+pub fn minUnsignedBits(v: Value, ty: Type, comp: *const Compilation) usize {
+    assert(v.compare(.gte, Value.int(0), ty, comp));
+    return switch (ty.sizeof(comp).?) {
+        1 => 8 - @clz(v.getInt(u8)),
+        2 => 16 - @clz(v.getInt(u16)),
+        4 => 32 - @clz(v.getInt(u32)),
+        8 => 64 - @clz(v.getInt(u64)),
+        else => unreachable,
+    };
+}
+
+test "minUnsignedBits" {
+    const Test = struct {
+        fn checkIntBits(comp: *const Compilation, specifier: Type.Specifier, v: u64, expected: usize) !void {
+            const val = Value.int(v);
+            try std.testing.expectEqual(expected, val.minUnsignedBits(.{ .specifier = specifier }, comp));
+        }
+    };
+
+    var comp = Compilation.init(std.testing.allocator);
+    defer comp.deinit();
+    comp.target = (try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-linux-gnu" })).toTarget();
+
+    try Test.checkIntBits(&comp, .int, 0, 0);
+    try Test.checkIntBits(&comp, .int, 1, 1);
+    try Test.checkIntBits(&comp, .int, 2, 2);
+    try Test.checkIntBits(&comp, .int, std.math.maxInt(i8), 7);
+    try Test.checkIntBits(&comp, .int, std.math.maxInt(u8), 8);
+    try Test.checkIntBits(&comp, .int, std.math.maxInt(i16), 15);
+    try Test.checkIntBits(&comp, .int, std.math.maxInt(u16), 16);
+    try Test.checkIntBits(&comp, .int, std.math.maxInt(i32), 31);
+    try Test.checkIntBits(&comp, .uint, std.math.maxInt(u32), 32);
+    try Test.checkIntBits(&comp, .long, std.math.maxInt(i64), 63);
+    try Test.checkIntBits(&comp, .ulong, std.math.maxInt(u64), 64);
+    try Test.checkIntBits(&comp, .long_long, std.math.maxInt(i64), 63);
+    try Test.checkIntBits(&comp, .ulong_long, std.math.maxInt(u64), 64);
+}
+
+/// Minimum number of bits needed to represent `v` in 2's complement notation
+/// Asserts that `v` is negative.
+pub fn minSignedBits(v: Value, ty: Type, comp: *const Compilation) usize {
+    assert(v.compare(.lt, Value.int(0), ty, comp));
+    return switch (ty.sizeof(comp).?) {
+        1 => 8 - @clz(~v.getInt(u8)) + 1,
+        2 => 16 - @clz(~v.getInt(u16)) + 1,
+        4 => 32 - @clz(~v.getInt(u32)) + 1,
+        8 => 64 - @clz(~v.getInt(u64)) + 1,
+        else => unreachable,
+    };
+}
+
+test "minSignedBits" {
+    const Test = struct {
+        fn checkIntBits(comp: *const Compilation, specifier: Type.Specifier, v: i64, expected: usize) !void {
+            const val = Value.int(v);
+            try std.testing.expectEqual(expected, val.minSignedBits(.{ .specifier = specifier }, comp));
+        }
+    };
+
+    var comp = Compilation.init(std.testing.allocator);
+    defer comp.deinit();
+    comp.target = (try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-linux-gnu" })).toTarget();
+
+    for ([_]Type.Specifier{ .int, .long, .long_long }) |specifier| {
+        try Test.checkIntBits(&comp, specifier, -1, 1);
+        try Test.checkIntBits(&comp, specifier, -2, 2);
+        try Test.checkIntBits(&comp, specifier, -10, 5);
+        try Test.checkIntBits(&comp, specifier, -101, 8);
+
+        try Test.checkIntBits(&comp, specifier, std.math.minInt(i8), 8);
+        try Test.checkIntBits(&comp, specifier, std.math.minInt(i16), 16);
+        try Test.checkIntBits(&comp, specifier, std.math.minInt(i32), 32);
+    }
+
+    try Test.checkIntBits(&comp, .long, std.math.minInt(i64), 64);
+    try Test.checkIntBits(&comp, .long_long, std.math.minInt(i64), 64);
+}
+
+pub const FloatToIntChangeKind = enum {
+    /// value did not change
+    none,
+    /// floating point number too small or large for destination integer type
+    out_of_range,
+    /// tried to convert a NaN or Infinity
+    overflow,
+    /// fractional value was converted to zero
+    nonzero_to_zero,
+    /// fractional part truncated
+    value_changed,
+};
+
+fn floatToIntExtra(comptime FloatTy: type, int_ty_signedness: std.builtin.Signedness, int_ty_size: u16, v: *Value) FloatToIntChangeKind {
+    const float_val = v.getFloat(FloatTy);
+    const was_zero = float_val == 0;
+    const had_fraction = std.math.modf(float_val).fpart != 0;
+
+    switch (int_ty_signedness) {
+        inline else => |signedness| switch (int_ty_size) {
+            inline 1, 2, 4, 8 => |bytecount| {
+                const IntTy = std.meta.Int(signedness, bytecount * 8);
+
+                const intVal = std.math.lossyCast(IntTy, float_val);
+                v.* = int(intVal);
+                if (!was_zero and v.isZero()) return .nonzero_to_zero;
+                if (float_val <= std.math.minInt(IntTy) or float_val >= std.math.maxInt(IntTy)) return .out_of_range;
+                if (had_fraction) return .value_changed;
+                return .none;
+            },
+            else => unreachable,
+        },
+    }
+}
+
+/// Converts the stored value from a float to an integer.
+/// `.unavailable` value remains unchanged.
+pub fn floatToInt(v: *Value, old_ty: Type, new_ty: Type, comp: *Compilation) FloatToIntChangeKind {
+    assert(old_ty.isFloat());
+    if (v.tag == .unavailable) return .none;
+    if (new_ty.is(.bool)) {
+        const was_zero = v.isZero();
+        const was_one = v.getFloat(f64) == 1.0;
+        v.toBool();
+        if (was_zero or was_one) return .none;
+        return .value_changed;
+    } else if (new_ty.isUnsignedInt(comp) and v.data.float < 0) {
+        v.* = int(0);
+        return .out_of_range;
+    } else if (!std.math.isFinite(v.data.float)) {
+        v.tag = .unavailable;
+        return .overflow;
+    }
+    const old_size = old_ty.sizeof(comp).?;
+    const new_size: u16 = @intCast(new_ty.sizeof(comp).?);
+    if (new_ty.isUnsignedInt(comp)) switch (old_size) {
+        1 => unreachable, // promoted to int
+        2 => unreachable, // promoted to int
+        4 => return floatToIntExtra(f32, .unsigned, new_size, v),
+        8 => return floatToIntExtra(f64, .unsigned, new_size, v),
+        else => unreachable,
+    } else switch (old_size) {
+        1 => unreachable, // promoted to int
+        2 => unreachable, // promoted to int
+        4 => return floatToIntExtra(f32, .signed, new_size, v),
+        8 => return floatToIntExtra(f64, .signed, new_size, v),
+        else => unreachable,
+    }
+}
+
+/// Converts the stored value from an integer to a float.
+/// `.unavailable` value remains unchanged.
+pub fn intToFloat(v: *Value, old_ty: Type, new_ty: Type, comp: *Compilation) void {
+    assert(old_ty.isInt());
+    if (v.tag == .unavailable) return;
+    if (!new_ty.isReal() or new_ty.sizeof(comp).? > 8) {
+        v.tag = .unavailable;
+    } else if (old_ty.isUnsignedInt(comp)) {
+        v.* = float(@as(f64, @floatFromInt(v.data.int)));
+    } else {
+        v.* = float(@as(f64, @floatFromInt(@as(i64, @bitCast(v.data.int)))));
+    }
+}
+
+/// Truncates or extends bits based on type.
+/// old_ty is only used for size.
+pub fn intCast(v: *Value, old_ty: Type, new_ty: Type, comp: *Compilation) void {
+    // assert(old_ty.isInt() and new_ty.isInt());
+    if (v.tag == .unavailable) return;
+    if (new_ty.is(.bool)) return v.toBool();
+    if (!old_ty.isUnsignedInt(comp)) {
+        const size = new_ty.sizeof(comp).?;
+        switch (size) {
+            1 => v.* = int(@as(u8, @truncate(@as(u64, @bitCast(v.signExtend(old_ty, comp)))))),
+            2 => v.* = int(@as(u16, @truncate(@as(u64, @bitCast(v.signExtend(old_ty, comp)))))),
+            4 => v.* = int(@as(u32, @truncate(@as(u64, @bitCast(v.signExtend(old_ty, comp)))))),
+            8 => return,
+            else => unreachable,
+        }
+    }
+}
+
+/// Converts the stored value from an integer to a float.
+/// `.unavailable` value remains unchanged.
+pub fn floatCast(v: *Value, old_ty: Type, new_ty: Type, comp: *Compilation) void {
+    assert(old_ty.isFloat() and new_ty.isFloat());
+    if (v.tag == .unavailable) return;
+    const size = new_ty.sizeof(comp).?;
+    if (!new_ty.isReal() or size > 8) {
+        v.tag = .unavailable;
+    } else if (size == 32) {
+        v.* = float(@as(f32, @floatCast(v.data.float)));
+    }
+}
+
+/// Truncates data.int to one bit
+pub fn toBool(v: *Value) void {
+    if (v.tag == .unavailable) return;
+    const res = v.getBool();
+    v.* = int(@intFromBool(res));
+}
+
+pub fn isZero(v: Value) bool {
+    return switch (v.tag) {
+        .unavailable => false,
+        .nullptr_t => false,
+        .int => v.data.int == 0,
+        .float => v.data.float == 0,
+        .bytes => false,
+    };
+}
+
+pub fn getBool(v: Value) bool {
+    return switch (v.tag) {
+        .unavailable => unreachable,
+        .nullptr_t => false,
+        .int => v.data.int != 0,
+        .float => v.data.float != 0,
+        .bytes => true,
+    };
+}
+
+pub fn getInt(v: Value, comptime T: type) T {
+    if (T == u64) return v.data.int;
+    return if (@typeInfo(T).Int.signedness == .unsigned)
+        @truncate(v.data.int)
+    else
+        @truncate(@as(i64, @bitCast(v.data.int)));
+}
+
+pub fn getFloat(v: Value, comptime T: type) T {
+    if (T == f64) return v.data.float;
+    return @floatCast(v.data.float);
+}
+
+const bin_overflow = struct {
+    inline fn addInt(comptime T: type, out: *Value, a: Value, b: Value) bool {
+        const a_val = a.getInt(T);
+        const b_val = b.getInt(T);
+        const sum, const overflowed = @addWithOverflow(a_val, b_val);
+        out.* = int(sum);
+        return overflowed != 0;
+    }
+    inline fn addFloat(comptime T: type, aa: Value, bb: Value) Value {
+        const a_val = aa.getFloat(T);
+        const b_val = bb.getFloat(T);
+        return float(a_val + b_val);
+    }
+
+    inline fn subInt(comptime T: type, out: *Value, a: Value, b: Value) bool {
+        const a_val = a.getInt(T);
+        const b_val = b.getInt(T);
+        const difference, const overflowed = @subWithOverflow(a_val, b_val);
+        out.* = int(difference);
+        return overflowed != 0;
+    }
+    inline fn subFloat(comptime T: type, aa: Value, bb: Value) Value {
+        const a_val = aa.getFloat(T);
+        const b_val = bb.getFloat(T);
+        return float(a_val - b_val);
+    }
+
+    inline fn mulInt(comptime T: type, out: *Value, a: Value, b: Value) bool {
+        const a_val = a.getInt(T);
+        const b_val = b.getInt(T);
+        const product, const overflowed = @mulWithOverflow(a_val, b_val);
+        out.* = int(product);
+        return overflowed != 0;
+    }
+    inline fn mulFloat(comptime T: type, aa: Value, bb: Value) Value {
+        const a_val = aa.getFloat(T);
+        const b_val = bb.getFloat(T);
+        return float(a_val * b_val);
+    }
+
+    const FT = fn (*Value, Value, Value, Type, *Compilation) bool;
+    fn getOp(comptime intFunc: anytype, comptime floatFunc: anytype) FT {
+        return struct {
+            fn op(res: *Value, a: Value, b: Value, ty: Type, comp: *Compilation) bool {
+                const size = ty.sizeof(comp).?;
+                if (@TypeOf(floatFunc) != @TypeOf(null) and ty.isFloat()) {
+                    res.* = switch (size) {
+                        4 => floatFunc(f32, a, b),
+                        8 => floatFunc(f64, a, b),
+                        else => unreachable,
+                    };
+                    return false;
+                }
+
+                if (ty.isUnsignedInt(comp)) switch (size) {
+                    1 => return intFunc(u8, res, a, b),
+                    2 => return intFunc(u16, res, a, b),
+                    4 => return intFunc(u32, res, a, b),
+                    8 => return intFunc(u64, res, a, b),
+                    else => unreachable,
+                } else switch (size) {
+                    1 => return intFunc(u8, res, a, b),
+                    2 => return intFunc(u16, res, a, b),
+                    4 => return intFunc(i32, res, a, b),
+                    8 => return intFunc(i64, res, a, b),
+                    else => unreachable,
+                }
+            }
+        }.op;
+    }
+};
+
+pub const add = bin_overflow.getOp(bin_overflow.addInt, bin_overflow.addFloat);
+pub const sub = bin_overflow.getOp(bin_overflow.subInt, bin_overflow.subFloat);
+pub const mul = bin_overflow.getOp(bin_overflow.mulInt, bin_overflow.mulFloat);
+
+const bin_ops = struct {
+    inline fn divInt(comptime T: type, aa: Value, bb: Value) Value {
+        const a_val = aa.getInt(T);
+        const b_val = bb.getInt(T);
+        return int(@divTrunc(a_val, b_val));
+    }
+    inline fn divFloat(comptime T: type, aa: Value, bb: Value) Value {
+        const a_val = aa.getFloat(T);
+        const b_val = bb.getFloat(T);
+        return float(a_val / b_val);
+    }
+
+    inline fn remInt(comptime T: type, a: Value, b: Value) Value {
+        const a_val = a.getInt(T);
+        const b_val = b.getInt(T);
+
+        if (@typeInfo(T).Int.signedness == .signed) {
+            if (a_val == std.math.minInt(T) and b_val == -1) {
+                return Value{ .tag = .unavailable, .data = .{ .none = {} } };
+            } else {
+                if (b_val > 0) return int(@rem(a_val, b_val));
+                return int(a_val - @divTrunc(a_val, b_val) * b_val);
+            }
+        } else {
+            return int(a_val % b_val);
+        }
+    }
+
+    inline fn orInt(comptime T: type, a: Value, b: Value) Value {
+        const a_val = a.getInt(T);
+        const b_val = b.getInt(T);
+        return int(a_val | b_val);
+    }
+    inline fn xorInt(comptime T: type, a: Value, b: Value) Value {
+        const a_val = a.getInt(T);
+        const b_val = b.getInt(T);
+        return int(a_val ^ b_val);
+    }
+    inline fn andInt(comptime T: type, a: Value, b: Value) Value {
+        const a_val = a.getInt(T);
+        const b_val = b.getInt(T);
+        return int(a_val & b_val);
+    }
+
+    inline fn shl(comptime T: type, a: Value, b: Value) Value {
+        const ShiftT = std.math.Log2Int(T);
+        const info = @typeInfo(T).Int;
+        const UT = std.meta.Int(.unsigned, info.bits);
+        const b_val = b.getInt(T);
+
+        if (b_val > std.math.maxInt(ShiftT)) {
+            return if (info.signedness == .unsigned)
+                int(@as(UT, std.math.maxInt(UT)))
+            else
+                int(@as(T, std.math.minInt(T)));
+        }
+        const amt: ShiftT = @truncate(@as(UT, @bitCast(b_val)));
+        const a_val = a.getInt(T);
+        return int(a_val << amt);
+    }
+    inline fn shr(comptime T: type, a: Value, b: Value) Value {
+        const ShiftT = std.math.Log2Int(T);
+        const UT = std.meta.Int(.unsigned, @typeInfo(T).Int.bits);
+
+        const b_val = b.getInt(T);
+        if (b_val > std.math.maxInt(ShiftT)) return Value.int(0);
+
+        const amt: ShiftT = @truncate(@as(UT, @intCast(b_val)));
+        const a_val = a.getInt(T);
+        return int(a_val >> amt);
+    }
+
+    const FT = fn (Value, Value, Type, *Compilation) Value;
+    fn getOp(comptime intFunc: anytype, comptime floatFunc: anytype) FT {
+        return struct {
+            fn op(a: Value, b: Value, ty: Type, comp: *Compilation) Value {
+                const size = ty.sizeof(comp).?;
+                if (@TypeOf(floatFunc) != @TypeOf(null) and ty.isFloat()) {
+                    switch (size) {
+                        4 => return floatFunc(f32, a, b),
+                        8 => return floatFunc(f64, a, b),
+                        else => unreachable,
+                    }
+                }
+
+                if (ty.isUnsignedInt(comp)) switch (size) {
+                    1 => unreachable, // promoted to int
+                    2 => unreachable, // promoted to int
+                    4 => return intFunc(u32, a, b),
+                    8 => return intFunc(u64, a, b),
+                    else => unreachable,
+                } else switch (size) {
+                    1 => unreachable, // promoted to int
+                    2 => unreachable, // promoted to int
+                    4 => return intFunc(i32, a, b),
+                    8 => return intFunc(i64, a, b),
+                    else => unreachable,
+                }
+            }
+        }.op;
+    }
+};
+
+/// caller guarantees rhs != 0
+pub const div = bin_ops.getOp(bin_ops.divInt, bin_ops.divFloat);
+/// caller guarantees rhs != 0
+/// caller guarantees lhs != std.math.minInt(T) OR rhs != -1
+pub const rem = bin_ops.getOp(bin_ops.remInt, null);
+
+pub const bitOr = bin_ops.getOp(bin_ops.orInt, null);
+pub const bitXor = bin_ops.getOp(bin_ops.xorInt, null);
+pub const bitAnd = bin_ops.getOp(bin_ops.andInt, null);
+
+pub const shl = bin_ops.getOp(bin_ops.shl, null);
+pub const shr = bin_ops.getOp(bin_ops.shr, null);
+
+pub fn bitNot(v: Value, ty: Type, comp: *Compilation) Value {
+    const size = ty.sizeof(comp).?;
+    var out: Value = undefined;
+    if (ty.isUnsignedInt(comp)) switch (size) {
+        1 => unreachable, // promoted to int
+        2 => unreachable, // promoted to int
+        4 => out = int(~v.getInt(u32)),
+        8 => out = int(~v.getInt(u64)),
+        else => unreachable,
+    } else switch (size) {
+        1 => unreachable, // promoted to int
+        2 => unreachable, // promoted to int
+        4 => out = int(~v.getInt(i32)),
+        8 => out = int(~v.getInt(i64)),
+        else => unreachable,
+    }
+    return out;
+}
+
+pub fn compare(a: Value, op: std.math.CompareOperator, b: Value, ty: Type, comp: *const Compilation) bool {
+    assert(a.tag == b.tag);
+    if (a.tag == .nullptr_t) {
+        return switch (op) {
+            .eq => true,
+            .neq => false,
+            else => unreachable,
+        };
+    }
+    const S = struct {
+        inline fn doICompare(comptime T: type, aa: Value, opp: std.math.CompareOperator, bb: Value) bool {
+            const a_val = aa.getInt(T);
+            const b_val = bb.getInt(T);
+            return std.math.compare(a_val, opp, b_val);
+        }
+        inline fn doFCompare(comptime T: type, aa: Value, opp: std.math.CompareOperator, bb: Value) bool {
+            const a_val = aa.getFloat(T);
+            const b_val = bb.getFloat(T);
+            return std.math.compare(a_val, opp, b_val);
+        }
+    };
+    const size = ty.sizeof(comp).?;
+    switch (a.tag) {
+        .unavailable => return true,
+        .int => if (ty.isUnsignedInt(comp)) switch (size) {
+            1 => return S.doICompare(u8, a, op, b),
+            2 => return S.doICompare(u16, a, op, b),
+            4 => return S.doICompare(u32, a, op, b),
+            8 => return S.doICompare(u64, a, op, b),
+            else => unreachable,
+        } else switch (size) {
+            1 => return S.doICompare(i8, a, op, b),
+            2 => return S.doICompare(i16, a, op, b),
+            4 => return S.doICompare(i32, a, op, b),
+            8 => return S.doICompare(i64, a, op, b),
+            else => unreachable,
+        },
+        .float => switch (size) {
+            4 => return S.doFCompare(f32, a, op, b),
+            8 => return S.doFCompare(f64, a, op, b),
+            else => unreachable,
+        },
+        else => @panic("TODO"),
+    }
+    return false;
+}
+
+pub fn hash(v: Value) u64 {
+    switch (v.tag) {
+        .unavailable => unreachable,
+        .int => return std.hash.Wyhash.hash(0, std.mem.asBytes(&v.data.int)),
+        else => @panic("TODO"),
+    }
+}
+
+pub fn dump(v: Value, ty: Type, comp: *Compilation, strings: []const u8, w: anytype) !void {
+    switch (v.tag) {
+        .unavailable => try w.writeAll("unavailable"),
+        .int => if (ty.is(.bool) and comp.langopts.standard.atLeast(.c2x)) {
+            try w.print("{s}", .{if (v.isZero()) "false" else "true"});
+        } else if (ty.isUnsignedInt(comp)) {
+            try w.print("{d}", .{v.data.int});
+        } else {
+            try w.print("{d}", .{v.signExtend(ty, comp)});
+        },
+        .bytes => try w.print("\"{s}\"", .{v.data.bytes.slice(strings)}),
+        // std.fmt does @as instead of @floatCast
+        .float => try w.print("{d}", .{@as(f64, @floatCast(v.data.float))}),
+        else => try w.print("({s})", .{@tagName(v.tag)}),
+    }
+}
.gitattributes
@@ -10,3 +10,4 @@ lib/libcxx/** linguist-vendored
 lib/libcxxabi/** linguist-vendored
 lib/libunwind/** linguist-vendored
 lib/tsan/** linguist-vendored
+deps/** linguist-vendored
build.zig
@@ -580,6 +580,9 @@ fn addCompilerStep(
         .optimize = optimize,
     });
     exe.stack_size = stack_size;
+    exe.addAnonymousModule("aro", .{
+        .source_file = .{ .path = "deps/aro/lib.zig" },
+    });
     return exe;
 }
 
CMakeLists.txt
@@ -797,7 +797,8 @@ set(BUILD_ZIG2_ARGS
   -OReleaseSmall
   --name zig2 -femit-bin="${ZIG2_C_SOURCE}"
   --mod "build_options::${ZIG_CONFIG_ZIG_OUT}"
-  --deps build_options
+  --mod "aro::deps/aro/lib.zig"
+  --deps build_options,aro
   -target "${ZIG_HOST_TARGET_TRIPLE}"
 )