1const builtin = @import("builtin");
2const std = @import("std");
3
4const compiler_rt = @import("../compiler_rt.zig");
5const symbol = compiler_rt.symbol;
6
7comptime {
8 // This is just a conservative stub for now, to make sure that code that
9 // uses function multiversioning will link correctly, albeit with the
10 // slowest variant of a function.
11
12 if (builtin.target.cpu.arch.isAarch64()) _ = aarch64;
13 if (builtin.target.cpu.arch.isLoongarch()) _ = loongarch;
14 if (builtin.target.cpu.arch.isRiscv()) _ = riscv;
15 if (builtin.target.cpu.arch.isX86()) _ = x86;
16}
17
18const aarch64 = struct {
19 comptime {
20 symbol(&__aarch64_cpu_features, "__aarch64_cpu_features");
21 symbol(&__init_cpu_features_resolver, "__init_cpu_features_resolver");
22 }
23
24 var __aarch64_cpu_features: extern struct {
25 features: c_ulonglong,
26 } = .{
27 .features = 0,
28 };
29
30 const __init_cpu_features_resolver = switch (builtin.target.os.tag) {
31 .fuchsia,
32 .driverkit,
33 .ios,
34 .maccatalyst,
35 .macos,
36 .tvos,
37 .visionos,
38 .watchos,
39 => struct {
40 fn __init_cpu_features_resolver() callconv(.c) void {}
41 },
42 else => struct {
43 fn __init_cpu_features_resolver(hwcap: c_ulong, arg: *const extern struct {
44 _size: c_ulong,
45 _hwcap: c_ulong,
46 _hwcap2: c_ulong,
47 _hwcap3: c_ulong,
48 _hwcap4: c_ulong,
49 }) callconv(.c) void {
50 _ = hwcap;
51 _ = arg;
52 }
53 },
54 }.__init_cpu_features_resolver;
55};
56
57const loongarch = struct {
58 comptime {
59 symbol(&__loongarch_feature_bits, "__loongarch_feature_bits");
60 symbol(&__init_loongarch_features_resolver, "__init_loongarch_features_resolver");
61 }
62
63 var __loongarch_feature_bits: extern struct {
64 features: c_ulonglong,
65 } = .{
66 .features = 0,
67 };
68
69 var __riscv_cpu_model: extern struct {
70 mvendorid: c_uint,
71 marchid: c_ulonglong,
72 mimpid: c_ulonglong,
73 } = .{
74 .mvendorid = 0,
75 .marchid = 0,
76 .mimpid = 0,
77 };
78
79 fn __init_loongarch_features_resolver() callconv(.c) void {}
80};
81
82const riscv = struct {
83 comptime {
84 symbol(&__riscv_feature_bits, "__riscv_feature_bits");
85 symbol(&__riscv_cpu_model, "__riscv_cpu_model");
86 symbol(&__init_riscv_feature_bits, "__init_riscv_feature_bits");
87 }
88
89 var __riscv_feature_bits: extern struct {
90 length: c_uint,
91 features: [2]c_ulonglong,
92 } = .{
93 .length = 2,
94 .features = @splat(0),
95 };
96
97 var __riscv_cpu_model: extern struct {
98 mvendorid: c_uint,
99 marchid: c_ulonglong,
100 mimpid: c_ulonglong,
101 } = .{
102 .mvendorid = 0,
103 .marchid = 0,
104 .mimpid = 0,
105 };
106
107 fn __init_riscv_feature_bits(args: ?*anyopaque) callconv(.c) void {
108 _ = args;
109 }
110};
111
112const x86 = struct {
113 comptime {
114 symbol(&__cpu_model, "__cpu_model");
115 symbol(&__cpu_features2, "__cpu_features2");
116 symbol(&__cpu_indicator_init, "__cpu_indicator_init");
117 }
118
119 var __cpu_model: extern struct {
120 __cpu_vendor: c_uint,
121 __cpu_type: c_uint,
122 __cpu_subtype: c_uint,
123 __cpu_features: [1]c_uint,
124 } = .{
125 .__cpu_vendor = 0,
126 .__cpu_type = 0,
127 .__cpu_subtype = 0,
128 .__cpu_features = @splat(0),
129 };
130
131 var __cpu_features2: [4]c_uint = @splat(0);
132
133 fn __cpu_indicator_init() callconv(.c) c_int {
134 return 0;
135 }
136};