authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-21 22:33:00-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-21 23:21:07-07:00
logaecebf38acc8835db21eeea7b53e4ee26ec739a8
tree132a3982487ae7bb1a0210a4ff2b7cd7a2934855
parent0e2b9ac7770df07212d4d1cbfb15c3aaed0bef18

stage2: progress towards ability to compile compiler-rt

* prepare compiler-rt to support being compiled by stage2 - put in a few minor workarounds that will be removed later, such as using `builtin.stage2_arch` rather than `builtin.cpu.arch`. - only try to export a few symbols for now - we'll move more symbols over to the "working in stage2" section as they become functional and gain test coverage. - use `inline fn` at function declarations rather than `@call` with an always_inline modifier at the callsites, to avoid depending on the anonymous array literal syntax language feature (for now). * AIR: replace floatcast instruction with fptrunc and fpext for shortening and widening floating point values, respectively. * Introduce a new ZIR instruction, `export_value`, which implements `@export` for the case when the thing to be exported is a local comptime value that points to a function. - AstGen: fix `@export` not properly reporting ambiguous decl references. * Sema: handle ExportOptions linkage. The value is now available to all backends. - Implement setting global linkage as appropriate in the LLVM backend. I did not yet inspect the LLVM IR, so this still needs to be audited. There is already a pending task to make sure the alias stuff is working as intended, and this is related. - Sema almost handles section, just a tiny bit more code is needed in `resolveExportOptions`. * Sema: implement float widening and shortening for both `@floatCast` and float coercion. - Implement the LLVM backend code for this as well.

21 files changed, 1723 insertions(+), 1547 deletions(-)

lib/std/special/compiler_rt.zig+591-573
...@@ -1,171 +1,24 @@...@@ -1,171 +1,24 @@
1const std = @import("std");1const std = @import("std");
2const builtin = std.builtin;2const builtin = @import("builtin");
3const is_test = builtin.is_test;3const is_test = builtin.is_test;
4const os_tag = std.Target.current.os.tag;4const os_tag = std.Target.current.os.tag;
5const arch = std.Target.current.cpu.arch;5const arch = builtin.stage2_arch;
6const abi = std.Target.current.abi;6const abi = std.Target.current.abi;
77
8const is_gnu = abi.isGnu();8const is_gnu = abi.isGnu();
9const is_mingw = os_tag == .windows and is_gnu;9const is_mingw = os_tag == .windows and is_gnu;
1010
11comptime {11const linkage = if (is_test)
12 const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak;12 std.builtin.GlobalLinkage.Internal
13 const strong_linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;13else
1414 std.builtin.GlobalLinkage.Weak;
15 switch (arch) {
16 .i386,
17 .x86_64,
18 => {
19 const zig_probe_stack = @import("compiler_rt/stack_probe.zig").zig_probe_stack;
20 @export(zig_probe_stack, .{
21 .name = "__zig_probe_stack",
22 .linkage = linkage,
23 });
24 },
25
26 else => {},
27 }
2815
29 // __clear_cache manages its own logic about whether to be exported or not.16const strong_linkage = if (is_test)
30 _ = @import("compiler_rt/clear_cache.zig").clear_cache;17 std.builtin.GlobalLinkage.Internal
3118else
32 const __lesf2 = @import("compiler_rt/compareXf2.zig").__lesf2;19 std.builtin.GlobalLinkage.Strong;
33 @export(__lesf2, .{ .name = "__lesf2", .linkage = linkage });
34 const __ledf2 = @import("compiler_rt/compareXf2.zig").__ledf2;
35 @export(__ledf2, .{ .name = "__ledf2", .linkage = linkage });
36 const __letf2 = @import("compiler_rt/compareXf2.zig").__letf2;
37 @export(__letf2, .{ .name = "__letf2", .linkage = linkage });
38
39 const __gesf2 = @import("compiler_rt/compareXf2.zig").__gesf2;
40 @export(__gesf2, .{ .name = "__gesf2", .linkage = linkage });
41 const __gedf2 = @import("compiler_rt/compareXf2.zig").__gedf2;
42 @export(__gedf2, .{ .name = "__gedf2", .linkage = linkage });
43 const __getf2 = @import("compiler_rt/compareXf2.zig").__getf2;
44 @export(__getf2, .{ .name = "__getf2", .linkage = linkage });
45
46 if (!is_test) {
47 @export(__lesf2, .{ .name = "__cmpsf2", .linkage = linkage });
48 @export(__ledf2, .{ .name = "__cmpdf2", .linkage = linkage });
49 @export(__letf2, .{ .name = "__cmptf2", .linkage = linkage });
50
51 const __eqsf2 = @import("compiler_rt/compareXf2.zig").__eqsf2;
52 @export(__eqsf2, .{ .name = "__eqsf2", .linkage = linkage });
53 const __eqdf2 = @import("compiler_rt/compareXf2.zig").__eqdf2;
54 @export(__eqdf2, .{ .name = "__eqdf2", .linkage = linkage });
55 @export(__letf2, .{ .name = "__eqtf2", .linkage = linkage });
56
57 const __ltsf2 = @import("compiler_rt/compareXf2.zig").__ltsf2;
58 @export(__ltsf2, .{ .name = "__ltsf2", .linkage = linkage });
59 const __ltdf2 = @import("compiler_rt/compareXf2.zig").__ltdf2;
60 @export(__ltdf2, .{ .name = "__ltdf2", .linkage = linkage });
61 @export(__letf2, .{ .name = "__lttf2", .linkage = linkage });
62
63 const __nesf2 = @import("compiler_rt/compareXf2.zig").__nesf2;
64 @export(__nesf2, .{ .name = "__nesf2", .linkage = linkage });
65 const __nedf2 = @import("compiler_rt/compareXf2.zig").__nedf2;
66 @export(__nedf2, .{ .name = "__nedf2", .linkage = linkage });
67 @export(__letf2, .{ .name = "__netf2", .linkage = linkage });
68
69 const __gtsf2 = @import("compiler_rt/compareXf2.zig").__gtsf2;
70 @export(__gtsf2, .{ .name = "__gtsf2", .linkage = linkage });
71 const __gtdf2 = @import("compiler_rt/compareXf2.zig").__gtdf2;
72 @export(__gtdf2, .{ .name = "__gtdf2", .linkage = linkage });
73 @export(__getf2, .{ .name = "__gttf2", .linkage = linkage });
74
75 const __extendhfsf2 = @import("compiler_rt/extendXfYf2.zig").__extendhfsf2;
76 @export(__extendhfsf2, .{ .name = "__gnu_h2f_ieee", .linkage = linkage });
77 const __truncsfhf2 = @import("compiler_rt/truncXfYf2.zig").__truncsfhf2;
78 @export(__truncsfhf2, .{ .name = "__gnu_f2h_ieee", .linkage = linkage });
79 }
80
81 const __unordsf2 = @import("compiler_rt/compareXf2.zig").__unordsf2;
82 @export(__unordsf2, .{ .name = "__unordsf2", .linkage = linkage });
83 const __unorddf2 = @import("compiler_rt/compareXf2.zig").__unorddf2;
84 @export(__unorddf2, .{ .name = "__unorddf2", .linkage = linkage });
85 const __unordtf2 = @import("compiler_rt/compareXf2.zig").__unordtf2;
86 @export(__unordtf2, .{ .name = "__unordtf2", .linkage = linkage });
87
88 const __addsf3 = @import("compiler_rt/addXf3.zig").__addsf3;
89 @export(__addsf3, .{ .name = "__addsf3", .linkage = linkage });
90 const __adddf3 = @import("compiler_rt/addXf3.zig").__adddf3;
91 @export(__adddf3, .{ .name = "__adddf3", .linkage = linkage });
92 const __addtf3 = @import("compiler_rt/addXf3.zig").__addtf3;
93 @export(__addtf3, .{ .name = "__addtf3", .linkage = linkage });
94 const __subsf3 = @import("compiler_rt/addXf3.zig").__subsf3;
95 @export(__subsf3, .{ .name = "__subsf3", .linkage = linkage });
96 const __subdf3 = @import("compiler_rt/addXf3.zig").__subdf3;
97 @export(__subdf3, .{ .name = "__subdf3", .linkage = linkage });
98 const __subtf3 = @import("compiler_rt/addXf3.zig").__subtf3;
99 @export(__subtf3, .{ .name = "__subtf3", .linkage = linkage });
100
101 const __mulsf3 = @import("compiler_rt/mulXf3.zig").__mulsf3;
102 @export(__mulsf3, .{ .name = "__mulsf3", .linkage = linkage });
103 const __muldf3 = @import("compiler_rt/mulXf3.zig").__muldf3;
104 @export(__muldf3, .{ .name = "__muldf3", .linkage = linkage });
105 const __multf3 = @import("compiler_rt/mulXf3.zig").__multf3;
106 @export(__multf3, .{ .name = "__multf3", .linkage = linkage });
107
108 const __divsf3 = @import("compiler_rt/divsf3.zig").__divsf3;
109 @export(__divsf3, .{ .name = "__divsf3", .linkage = linkage });
110 const __divdf3 = @import("compiler_rt/divdf3.zig").__divdf3;
111 @export(__divdf3, .{ .name = "__divdf3", .linkage = linkage });
112 const __divtf3 = @import("compiler_rt/divtf3.zig").__divtf3;
113 @export(__divtf3, .{ .name = "__divtf3", .linkage = linkage });
114
115 const __ashldi3 = @import("compiler_rt/shift.zig").__ashldi3;
116 @export(__ashldi3, .{ .name = "__ashldi3", .linkage = linkage });
117 const __ashlti3 = @import("compiler_rt/shift.zig").__ashlti3;
118 @export(__ashlti3, .{ .name = "__ashlti3", .linkage = linkage });
119 const __ashrdi3 = @import("compiler_rt/shift.zig").__ashrdi3;
120 @export(__ashrdi3, .{ .name = "__ashrdi3", .linkage = linkage });
121 const __ashrti3 = @import("compiler_rt/shift.zig").__ashrti3;
122 @export(__ashrti3, .{ .name = "__ashrti3", .linkage = linkage });
123 const __lshrdi3 = @import("compiler_rt/shift.zig").__lshrdi3;
124 @export(__lshrdi3, .{ .name = "__lshrdi3", .linkage = linkage });
125 const __lshrti3 = @import("compiler_rt/shift.zig").__lshrti3;
126 @export(__lshrti3, .{ .name = "__lshrti3", .linkage = linkage });
127
128 const __floatsidf = @import("compiler_rt/floatsiXf.zig").__floatsidf;
129 @export(__floatsidf, .{ .name = "__floatsidf", .linkage = linkage });
130 const __floatsisf = @import("compiler_rt/floatsiXf.zig").__floatsisf;
131 @export(__floatsisf, .{ .name = "__floatsisf", .linkage = linkage });
132 const __floatdidf = @import("compiler_rt/floatdidf.zig").__floatdidf;
133 @export(__floatdidf, .{ .name = "__floatdidf", .linkage = linkage });
134 const __floatsitf = @import("compiler_rt/floatsiXf.zig").__floatsitf;
135 @export(__floatsitf, .{ .name = "__floatsitf", .linkage = linkage });
136
137 const __floatunsisf = @import("compiler_rt/floatunsisf.zig").__floatunsisf;
138 @export(__floatunsisf, .{ .name = "__floatunsisf", .linkage = linkage });
139 const __floatundisf = @import("compiler_rt/floatundisf.zig").__floatundisf;
140 @export(__floatundisf, .{ .name = "__floatundisf", .linkage = linkage });
141 const __floatunsidf = @import("compiler_rt/floatunsidf.zig").__floatunsidf;
142 @export(__floatunsidf, .{ .name = "__floatunsidf", .linkage = linkage });
143 const __floatundidf = @import("compiler_rt/floatundidf.zig").__floatundidf;
144 @export(__floatundidf, .{ .name = "__floatundidf", .linkage = linkage });
145
146 const __floatditf = @import("compiler_rt/floatditf.zig").__floatditf;
147 @export(__floatditf, .{ .name = "__floatditf", .linkage = linkage });
148 const __floattitf = @import("compiler_rt/floattitf.zig").__floattitf;
149 @export(__floattitf, .{ .name = "__floattitf", .linkage = linkage });
150 const __floattidf = @import("compiler_rt/floattidf.zig").__floattidf;
151 @export(__floattidf, .{ .name = "__floattidf", .linkage = linkage });
152 const __floattisf = @import("compiler_rt/floatXisf.zig").__floattisf;
153 @export(__floattisf, .{ .name = "__floattisf", .linkage = linkage });
154 const __floatdisf = @import("compiler_rt/floatXisf.zig").__floatdisf;
155 @export(__floatdisf, .{ .name = "__floatdisf", .linkage = linkage });
156
157 const __floatunditf = @import("compiler_rt/floatunditf.zig").__floatunditf;
158 @export(__floatunditf, .{ .name = "__floatunditf", .linkage = linkage });
159 const __floatunsitf = @import("compiler_rt/floatunsitf.zig").__floatunsitf;
160 @export(__floatunsitf, .{ .name = "__floatunsitf", .linkage = linkage });
161
162 const __floatuntitf = @import("compiler_rt/floatuntitf.zig").__floatuntitf;
163 @export(__floatuntitf, .{ .name = "__floatuntitf", .linkage = linkage });
164 const __floatuntidf = @import("compiler_rt/floatuntidf.zig").__floatuntidf;
165 @export(__floatuntidf, .{ .name = "__floatuntidf", .linkage = linkage });
166 const __floatuntisf = @import("compiler_rt/floatuntisf.zig").__floatuntisf;
167 @export(__floatuntisf, .{ .name = "__floatuntisf", .linkage = linkage });
16820
21comptime {
169 const __extenddftf2 = @import("compiler_rt/extendXfYf2.zig").__extenddftf2;22 const __extenddftf2 = @import("compiler_rt/extendXfYf2.zig").__extenddftf2;
170 @export(__extenddftf2, .{ .name = "__extenddftf2", .linkage = linkage });23 @export(__extenddftf2, .{ .name = "__extenddftf2", .linkage = linkage });
171 const __extendsftf2 = @import("compiler_rt/extendXfYf2.zig").__extendsftf2;24 const __extendsftf2 = @import("compiler_rt/extendXfYf2.zig").__extendsftf2;
...@@ -175,446 +28,611 @@ comptime {...@@ -175,446 +28,611 @@ comptime {
175 const __extendhftf2 = @import("compiler_rt/extendXfYf2.zig").__extendhftf2;28 const __extendhftf2 = @import("compiler_rt/extendXfYf2.zig").__extendhftf2;
176 @export(__extendhftf2, .{ .name = "__extendhftf2", .linkage = linkage });29 @export(__extendhftf2, .{ .name = "__extendhftf2", .linkage = linkage });
17730
178 const __truncsfhf2 = @import("compiler_rt/truncXfYf2.zig").__truncsfhf2;31 if (!builtin.zig_is_stage2) {
179 @export(__truncsfhf2, .{ .name = "__truncsfhf2", .linkage = linkage });32 switch (arch) {
180 const __truncdfhf2 = @import("compiler_rt/truncXfYf2.zig").__truncdfhf2;33 .i386,
181 @export(__truncdfhf2, .{ .name = "__truncdfhf2", .linkage = linkage });34 .x86_64,
182 const __trunctfhf2 = @import("compiler_rt/truncXfYf2.zig").__trunctfhf2;35 => {
183 @export(__trunctfhf2, .{ .name = "__trunctfhf2", .linkage = linkage });36 const zig_probe_stack = @import("compiler_rt/stack_probe.zig").zig_probe_stack;
184 const __trunctfdf2 = @import("compiler_rt/truncXfYf2.zig").__trunctfdf2;37 @export(zig_probe_stack, .{
185 @export(__trunctfdf2, .{ .name = "__trunctfdf2", .linkage = linkage });38 .name = "__zig_probe_stack",
186 const __trunctfsf2 = @import("compiler_rt/truncXfYf2.zig").__trunctfsf2;39 .linkage = linkage,
187 @export(__trunctfsf2, .{ .name = "__trunctfsf2", .linkage = linkage });40 });
18841 },
189 const __truncdfsf2 = @import("compiler_rt/truncXfYf2.zig").__truncdfsf2;
190 @export(__truncdfsf2, .{ .name = "__truncdfsf2", .linkage = linkage });
191
192 const __extendsfdf2 = @import("compiler_rt/extendXfYf2.zig").__extendsfdf2;
193 @export(__extendsfdf2, .{ .name = "__extendsfdf2", .linkage = linkage });
194
195 const __fixunssfsi = @import("compiler_rt/fixunssfsi.zig").__fixunssfsi;
196 @export(__fixunssfsi, .{ .name = "__fixunssfsi", .linkage = linkage });
197 const __fixunssfdi = @import("compiler_rt/fixunssfdi.zig").__fixunssfdi;
198 @export(__fixunssfdi, .{ .name = "__fixunssfdi", .linkage = linkage });
199 const __fixunssfti = @import("compiler_rt/fixunssfti.zig").__fixunssfti;
200 @export(__fixunssfti, .{ .name = "__fixunssfti", .linkage = linkage });
201
202 const __fixunsdfsi = @import("compiler_rt/fixunsdfsi.zig").__fixunsdfsi;
203 @export(__fixunsdfsi, .{ .name = "__fixunsdfsi", .linkage = linkage });
204 const __fixunsdfdi = @import("compiler_rt/fixunsdfdi.zig").__fixunsdfdi;
205 @export(__fixunsdfdi, .{ .name = "__fixunsdfdi", .linkage = linkage });
206 const __fixunsdfti = @import("compiler_rt/fixunsdfti.zig").__fixunsdfti;
207 @export(__fixunsdfti, .{ .name = "__fixunsdfti", .linkage = linkage });
208
209 const __fixunstfsi = @import("compiler_rt/fixunstfsi.zig").__fixunstfsi;
210 @export(__fixunstfsi, .{ .name = "__fixunstfsi", .linkage = linkage });
211 const __fixunstfdi = @import("compiler_rt/fixunstfdi.zig").__fixunstfdi;
212 @export(__fixunstfdi, .{ .name = "__fixunstfdi", .linkage = linkage });
213 const __fixunstfti = @import("compiler_rt/fixunstfti.zig").__fixunstfti;
214 @export(__fixunstfti, .{ .name = "__fixunstfti", .linkage = linkage });
215
216 const __fixdfdi = @import("compiler_rt/fixdfdi.zig").__fixdfdi;
217 @export(__fixdfdi, .{ .name = "__fixdfdi", .linkage = linkage });
218 const __fixdfsi = @import("compiler_rt/fixdfsi.zig").__fixdfsi;
219 @export(__fixdfsi, .{ .name = "__fixdfsi", .linkage = linkage });
220 const __fixdfti = @import("compiler_rt/fixdfti.zig").__fixdfti;
221 @export(__fixdfti, .{ .name = "__fixdfti", .linkage = linkage });
222 const __fixsfdi = @import("compiler_rt/fixsfdi.zig").__fixsfdi;
223 @export(__fixsfdi, .{ .name = "__fixsfdi", .linkage = linkage });
224 const __fixsfsi = @import("compiler_rt/fixsfsi.zig").__fixsfsi;
225 @export(__fixsfsi, .{ .name = "__fixsfsi", .linkage = linkage });
226 const __fixsfti = @import("compiler_rt/fixsfti.zig").__fixsfti;
227 @export(__fixsfti, .{ .name = "__fixsfti", .linkage = linkage });
228 const __fixtfdi = @import("compiler_rt/fixtfdi.zig").__fixtfdi;
229 @export(__fixtfdi, .{ .name = "__fixtfdi", .linkage = linkage });
230 const __fixtfsi = @import("compiler_rt/fixtfsi.zig").__fixtfsi;
231 @export(__fixtfsi, .{ .name = "__fixtfsi", .linkage = linkage });
232 const __fixtfti = @import("compiler_rt/fixtfti.zig").__fixtfti;
233 @export(__fixtfti, .{ .name = "__fixtfti", .linkage = linkage });
234
235 const __udivmoddi4 = @import("compiler_rt/int.zig").__udivmoddi4;
236 @export(__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });
237 const __popcountdi2 = @import("compiler_rt/popcountdi2.zig").__popcountdi2;
238 @export(__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });
239
240 const __mulsi3 = @import("compiler_rt/int.zig").__mulsi3;
241 @export(__mulsi3, .{ .name = "__mulsi3", .linkage = linkage });
242 const __muldi3 = @import("compiler_rt/muldi3.zig").__muldi3;
243 @export(__muldi3, .{ .name = "__muldi3", .linkage = linkage });
244 const __divmoddi4 = @import("compiler_rt/int.zig").__divmoddi4;
245 @export(__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });
246 const __divsi3 = @import("compiler_rt/int.zig").__divsi3;
247 @export(__divsi3, .{ .name = "__divsi3", .linkage = linkage });
248 const __divdi3 = @import("compiler_rt/int.zig").__divdi3;
249 @export(__divdi3, .{ .name = "__divdi3", .linkage = linkage });
250 const __udivsi3 = @import("compiler_rt/int.zig").__udivsi3;
251 @export(__udivsi3, .{ .name = "__udivsi3", .linkage = linkage });
252 const __udivdi3 = @import("compiler_rt/int.zig").__udivdi3;
253 @export(__udivdi3, .{ .name = "__udivdi3", .linkage = linkage });
254 const __modsi3 = @import("compiler_rt/int.zig").__modsi3;
255 @export(__modsi3, .{ .name = "__modsi3", .linkage = linkage });
256 const __moddi3 = @import("compiler_rt/int.zig").__moddi3;
257 @export(__moddi3, .{ .name = "__moddi3", .linkage = linkage });
258 const __umodsi3 = @import("compiler_rt/int.zig").__umodsi3;
259 @export(__umodsi3, .{ .name = "__umodsi3", .linkage = linkage });
260 const __umoddi3 = @import("compiler_rt/int.zig").__umoddi3;
261 @export(__umoddi3, .{ .name = "__umoddi3", .linkage = linkage });
262 const __divmodsi4 = @import("compiler_rt/int.zig").__divmodsi4;
263 @export(__divmodsi4, .{ .name = "__divmodsi4", .linkage = linkage });
264 const __udivmodsi4 = @import("compiler_rt/int.zig").__udivmodsi4;
265 @export(__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = linkage });
266
267 const __negsf2 = @import("compiler_rt/negXf2.zig").__negsf2;
268 @export(__negsf2, .{ .name = "__negsf2", .linkage = linkage });
269 const __negdf2 = @import("compiler_rt/negXf2.zig").__negdf2;
270 @export(__negdf2, .{ .name = "__negdf2", .linkage = linkage });
271
272 const __clzsi2 = @import("compiler_rt/count0bits.zig").__clzsi2;
273 @export(__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });
274 const __clzdi2 = @import("compiler_rt/count0bits.zig").__clzdi2;
275 @export(__clzdi2, .{ .name = "__clzdi2", .linkage = linkage });
276 const __clzti2 = @import("compiler_rt/count0bits.zig").__clzti2;
277 @export(__clzti2, .{ .name = "__clzti2", .linkage = linkage });
278
279 if (builtin.link_libc and os_tag == .openbsd) {
280 const __emutls_get_address = @import("compiler_rt/emutls.zig").__emutls_get_address;
281 @export(__emutls_get_address, .{ .name = "__emutls_get_address", .linkage = linkage });
282 }
28342
284 if ((arch.isARM() or arch.isThumb()) and !is_test) {43 else => {},
285 const __aeabi_unwind_cpp_pr0 = @import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr0;
286 @export(__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = linkage });
287 const __aeabi_unwind_cpp_pr1 = @import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr1;
288 @export(__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = linkage });
289 const __aeabi_unwind_cpp_pr2 = @import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr2;
290 @export(__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = linkage });
291
292 @export(__muldi3, .{ .name = "__aeabi_lmul", .linkage = linkage });
293
294 const __aeabi_ldivmod = @import("compiler_rt/arm.zig").__aeabi_ldivmod;
295 @export(__aeabi_ldivmod, .{ .name = "__aeabi_ldivmod", .linkage = linkage });
296 const __aeabi_uldivmod = @import("compiler_rt/arm.zig").__aeabi_uldivmod;
297 @export(__aeabi_uldivmod, .{ .name = "__aeabi_uldivmod", .linkage = linkage });
298
299 @export(__divsi3, .{ .name = "__aeabi_idiv", .linkage = linkage });
300 const __aeabi_idivmod = @import("compiler_rt/arm.zig").__aeabi_idivmod;
301 @export(__aeabi_idivmod, .{ .name = "__aeabi_idivmod", .linkage = linkage });
302 @export(__udivsi3, .{ .name = "__aeabi_uidiv", .linkage = linkage });
303 const __aeabi_uidivmod = @import("compiler_rt/arm.zig").__aeabi_uidivmod;
304 @export(__aeabi_uidivmod, .{ .name = "__aeabi_uidivmod", .linkage = linkage });
305
306 const __aeabi_memcpy = @import("compiler_rt/arm.zig").__aeabi_memcpy;
307 @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = linkage });
308 @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy4", .linkage = linkage });
309 @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy8", .linkage = linkage });
310
311 const __aeabi_memmove = @import("compiler_rt/arm.zig").__aeabi_memmove;
312 @export(__aeabi_memmove, .{ .name = "__aeabi_memmove", .linkage = linkage });
313 @export(__aeabi_memmove, .{ .name = "__aeabi_memmove4", .linkage = linkage });
314 @export(__aeabi_memmove, .{ .name = "__aeabi_memmove8", .linkage = linkage });
315
316 const __aeabi_memset = @import("compiler_rt/arm.zig").__aeabi_memset;
317 @export(__aeabi_memset, .{ .name = "__aeabi_memset", .linkage = linkage });
318 @export(__aeabi_memset, .{ .name = "__aeabi_memset4", .linkage = linkage });
319 @export(__aeabi_memset, .{ .name = "__aeabi_memset8", .linkage = linkage });
320
321 const __aeabi_memclr = @import("compiler_rt/arm.zig").__aeabi_memclr;
322 @export(__aeabi_memclr, .{ .name = "__aeabi_memclr", .linkage = linkage });
323 @export(__aeabi_memclr, .{ .name = "__aeabi_memclr4", .linkage = linkage });
324 @export(__aeabi_memclr, .{ .name = "__aeabi_memclr8", .linkage = linkage });
325
326 if (os_tag == .linux) {
327 const __aeabi_read_tp = @import("compiler_rt/arm.zig").__aeabi_read_tp;
328 @export(__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = linkage });
329 }44 }
33045
331 const __aeabi_f2d = @import("compiler_rt/extendXfYf2.zig").__aeabi_f2d;46 // __clear_cache manages its own logic about whether to be exported or not.
332 @export(__aeabi_f2d, .{ .name = "__aeabi_f2d", .linkage = linkage });47 _ = @import("compiler_rt/clear_cache.zig").clear_cache;
333 const __aeabi_i2d = @import("compiler_rt/floatsiXf.zig").__aeabi_i2d;48
334 @export(__aeabi_i2d, .{ .name = "__aeabi_i2d", .linkage = linkage });49 const __lesf2 = @import("compiler_rt/compareXf2.zig").__lesf2;
335 const __aeabi_l2d = @import("compiler_rt/floatdidf.zig").__aeabi_l2d;50 @export(__lesf2, .{ .name = "__lesf2", .linkage = linkage });
336 @export(__aeabi_l2d, .{ .name = "__aeabi_l2d", .linkage = linkage });51 const __ledf2 = @import("compiler_rt/compareXf2.zig").__ledf2;
337 const __aeabi_l2f = @import("compiler_rt/floatXisf.zig").__aeabi_l2f;52 @export(__ledf2, .{ .name = "__ledf2", .linkage = linkage });
338 @export(__aeabi_l2f, .{ .name = "__aeabi_l2f", .linkage = linkage });53 const __letf2 = @import("compiler_rt/compareXf2.zig").__letf2;
339 const __aeabi_ui2d = @import("compiler_rt/floatunsidf.zig").__aeabi_ui2d;54 @export(__letf2, .{ .name = "__letf2", .linkage = linkage });
340 @export(__aeabi_ui2d, .{ .name = "__aeabi_ui2d", .linkage = linkage });55
341 const __aeabi_ul2d = @import("compiler_rt/floatundidf.zig").__aeabi_ul2d;56 const __gesf2 = @import("compiler_rt/compareXf2.zig").__gesf2;
342 @export(__aeabi_ul2d, .{ .name = "__aeabi_ul2d", .linkage = linkage });57 @export(__gesf2, .{ .name = "__gesf2", .linkage = linkage });
343 const __aeabi_ui2f = @import("compiler_rt/floatunsisf.zig").__aeabi_ui2f;58 const __gedf2 = @import("compiler_rt/compareXf2.zig").__gedf2;
344 @export(__aeabi_ui2f, .{ .name = "__aeabi_ui2f", .linkage = linkage });59 @export(__gedf2, .{ .name = "__gedf2", .linkage = linkage });
345 const __aeabi_ul2f = @import("compiler_rt/floatundisf.zig").__aeabi_ul2f;60 const __getf2 = @import("compiler_rt/compareXf2.zig").__getf2;
346 @export(__aeabi_ul2f, .{ .name = "__aeabi_ul2f", .linkage = linkage });61 @export(__getf2, .{ .name = "__getf2", .linkage = linkage });
34762
348 const __aeabi_fneg = @import("compiler_rt/negXf2.zig").__aeabi_fneg;63 if (!is_test) {
349 @export(__aeabi_fneg, .{ .name = "__aeabi_fneg", .linkage = linkage });64 @export(__lesf2, .{ .name = "__cmpsf2", .linkage = linkage });
350 const __aeabi_dneg = @import("compiler_rt/negXf2.zig").__aeabi_dneg;65 @export(__ledf2, .{ .name = "__cmpdf2", .linkage = linkage });
351 @export(__aeabi_dneg, .{ .name = "__aeabi_dneg", .linkage = linkage });66 @export(__letf2, .{ .name = "__cmptf2", .linkage = linkage });
35267
353 const __aeabi_fmul = @import("compiler_rt/mulXf3.zig").__aeabi_fmul;68 const __eqsf2 = @import("compiler_rt/compareXf2.zig").__eqsf2;
354 @export(__aeabi_fmul, .{ .name = "__aeabi_fmul", .linkage = linkage });69 @export(__eqsf2, .{ .name = "__eqsf2", .linkage = linkage });
355 const __aeabi_dmul = @import("compiler_rt/mulXf3.zig").__aeabi_dmul;70 const __eqdf2 = @import("compiler_rt/compareXf2.zig").__eqdf2;
356 @export(__aeabi_dmul, .{ .name = "__aeabi_dmul", .linkage = linkage });71 @export(__eqdf2, .{ .name = "__eqdf2", .linkage = linkage });
35772 @export(__letf2, .{ .name = "__eqtf2", .linkage = linkage });
358 const __aeabi_d2h = @import("compiler_rt/truncXfYf2.zig").__aeabi_d2h;73
359 @export(__aeabi_d2h, .{ .name = "__aeabi_d2h", .linkage = linkage });74 const __ltsf2 = @import("compiler_rt/compareXf2.zig").__ltsf2;
36075 @export(__ltsf2, .{ .name = "__ltsf2", .linkage = linkage });
361 const __aeabi_f2ulz = @import("compiler_rt/fixunssfdi.zig").__aeabi_f2ulz;76 const __ltdf2 = @import("compiler_rt/compareXf2.zig").__ltdf2;
362 @export(__aeabi_f2ulz, .{ .name = "__aeabi_f2ulz", .linkage = linkage });77 @export(__ltdf2, .{ .name = "__ltdf2", .linkage = linkage });
363 const __aeabi_d2ulz = @import("compiler_rt/fixunsdfdi.zig").__aeabi_d2ulz;78 @export(__letf2, .{ .name = "__lttf2", .linkage = linkage });
364 @export(__aeabi_d2ulz, .{ .name = "__aeabi_d2ulz", .linkage = linkage });79
36580 const __nesf2 = @import("compiler_rt/compareXf2.zig").__nesf2;
366 const __aeabi_f2lz = @import("compiler_rt/fixsfdi.zig").__aeabi_f2lz;81 @export(__nesf2, .{ .name = "__nesf2", .linkage = linkage });
367 @export(__aeabi_f2lz, .{ .name = "__aeabi_f2lz", .linkage = linkage });82 const __nedf2 = @import("compiler_rt/compareXf2.zig").__nedf2;
368 const __aeabi_d2lz = @import("compiler_rt/fixdfdi.zig").__aeabi_d2lz;83 @export(__nedf2, .{ .name = "__nedf2", .linkage = linkage });
369 @export(__aeabi_d2lz, .{ .name = "__aeabi_d2lz", .linkage = linkage });84 @export(__letf2, .{ .name = "__netf2", .linkage = linkage });
37085
371 const __aeabi_d2uiz = @import("compiler_rt/fixunsdfsi.zig").__aeabi_d2uiz;86 const __gtsf2 = @import("compiler_rt/compareXf2.zig").__gtsf2;
372 @export(__aeabi_d2uiz, .{ .name = "__aeabi_d2uiz", .linkage = linkage });87 @export(__gtsf2, .{ .name = "__gtsf2", .linkage = linkage });
37388 const __gtdf2 = @import("compiler_rt/compareXf2.zig").__gtdf2;
374 const __aeabi_h2f = @import("compiler_rt/extendXfYf2.zig").__aeabi_h2f;89 @export(__gtdf2, .{ .name = "__gtdf2", .linkage = linkage });
375 @export(__aeabi_h2f, .{ .name = "__aeabi_h2f", .linkage = linkage });90 @export(__getf2, .{ .name = "__gttf2", .linkage = linkage });
376 const __aeabi_f2h = @import("compiler_rt/truncXfYf2.zig").__aeabi_f2h;91
377 @export(__aeabi_f2h, .{ .name = "__aeabi_f2h", .linkage = linkage });92 @export(@import("compiler_rt/extendXfYf2.zig").__extendhfsf2, .{
37893 .name = "__gnu_h2f_ieee",
379 const __aeabi_i2f = @import("compiler_rt/floatsiXf.zig").__aeabi_i2f;94 .linkage = linkage,
380 @export(__aeabi_i2f, .{ .name = "__aeabi_i2f", .linkage = linkage });95 });
381 const __aeabi_d2f = @import("compiler_rt/truncXfYf2.zig").__aeabi_d2f;96 @export(@import("compiler_rt/truncXfYf2.zig").__truncsfhf2, .{
382 @export(__aeabi_d2f, .{ .name = "__aeabi_d2f", .linkage = linkage });97 .name = "__gnu_f2h_ieee",
38398 .linkage = linkage,
384 const __aeabi_fadd = @import("compiler_rt/addXf3.zig").__aeabi_fadd;99 });
385 @export(__aeabi_fadd, .{ .name = "__aeabi_fadd", .linkage = linkage });100 }
386 const __aeabi_dadd = @import("compiler_rt/addXf3.zig").__aeabi_dadd;
387 @export(__aeabi_dadd, .{ .name = "__aeabi_dadd", .linkage = linkage });
388 const __aeabi_fsub = @import("compiler_rt/addXf3.zig").__aeabi_fsub;
389 @export(__aeabi_fsub, .{ .name = "__aeabi_fsub", .linkage = linkage });
390 const __aeabi_dsub = @import("compiler_rt/addXf3.zig").__aeabi_dsub;
391 @export(__aeabi_dsub, .{ .name = "__aeabi_dsub", .linkage = linkage });
392
393 const __aeabi_f2uiz = @import("compiler_rt/fixunssfsi.zig").__aeabi_f2uiz;
394 @export(__aeabi_f2uiz, .{ .name = "__aeabi_f2uiz", .linkage = linkage });
395
396 const __aeabi_f2iz = @import("compiler_rt/fixsfsi.zig").__aeabi_f2iz;
397 @export(__aeabi_f2iz, .{ .name = "__aeabi_f2iz", .linkage = linkage });
398 const __aeabi_d2iz = @import("compiler_rt/fixdfsi.zig").__aeabi_d2iz;
399 @export(__aeabi_d2iz, .{ .name = "__aeabi_d2iz", .linkage = linkage });
400
401 const __aeabi_fdiv = @import("compiler_rt/divsf3.zig").__aeabi_fdiv;
402 @export(__aeabi_fdiv, .{ .name = "__aeabi_fdiv", .linkage = linkage });
403 const __aeabi_ddiv = @import("compiler_rt/divdf3.zig").__aeabi_ddiv;
404 @export(__aeabi_ddiv, .{ .name = "__aeabi_ddiv", .linkage = linkage });
405
406 const __aeabi_llsl = @import("compiler_rt/shift.zig").__aeabi_llsl;
407 @export(__aeabi_llsl, .{ .name = "__aeabi_llsl", .linkage = linkage });
408 const __aeabi_lasr = @import("compiler_rt/shift.zig").__aeabi_lasr;
409 @export(__aeabi_lasr, .{ .name = "__aeabi_lasr", .linkage = linkage });
410 const __aeabi_llsr = @import("compiler_rt/shift.zig").__aeabi_llsr;
411 @export(__aeabi_llsr, .{ .name = "__aeabi_llsr", .linkage = linkage });
412
413 const __aeabi_fcmpeq = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpeq;
414 @export(__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = linkage });
415 const __aeabi_fcmplt = @import("compiler_rt/compareXf2.zig").__aeabi_fcmplt;
416 @export(__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = linkage });
417 const __aeabi_fcmple = @import("compiler_rt/compareXf2.zig").__aeabi_fcmple;
418 @export(__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = linkage });
419 const __aeabi_fcmpge = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpge;
420 @export(__aeabi_fcmpge, .{ .name = "__aeabi_fcmpge", .linkage = linkage });
421 const __aeabi_fcmpgt = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpgt;
422 @export(__aeabi_fcmpgt, .{ .name = "__aeabi_fcmpgt", .linkage = linkage });
423 const __aeabi_fcmpun = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpun;
424 @export(__aeabi_fcmpun, .{ .name = "__aeabi_fcmpun", .linkage = linkage });
425
426 const __aeabi_dcmpeq = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpeq;
427 @export(__aeabi_dcmpeq, .{ .name = "__aeabi_dcmpeq", .linkage = linkage });
428 const __aeabi_dcmplt = @import("compiler_rt/compareXf2.zig").__aeabi_dcmplt;
429 @export(__aeabi_dcmplt, .{ .name = "__aeabi_dcmplt", .linkage = linkage });
430 const __aeabi_dcmple = @import("compiler_rt/compareXf2.zig").__aeabi_dcmple;
431 @export(__aeabi_dcmple, .{ .name = "__aeabi_dcmple", .linkage = linkage });
432 const __aeabi_dcmpge = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpge;
433 @export(__aeabi_dcmpge, .{ .name = "__aeabi_dcmpge", .linkage = linkage });
434 const __aeabi_dcmpgt = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpgt;
435 @export(__aeabi_dcmpgt, .{ .name = "__aeabi_dcmpgt", .linkage = linkage });
436 const __aeabi_dcmpun = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpun;
437 @export(__aeabi_dcmpun, .{ .name = "__aeabi_dcmpun", .linkage = linkage });
438 }
439101
440 if (arch == .i386 and abi == .msvc) {102 const __unordsf2 = @import("compiler_rt/compareXf2.zig").__unordsf2;
441 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins103 @export(__unordsf2, .{ .name = "__unordsf2", .linkage = linkage });
442 const _alldiv = @import("compiler_rt/aulldiv.zig")._alldiv;104 const __unorddf2 = @import("compiler_rt/compareXf2.zig").__unorddf2;
443 @export(_alldiv, .{ .name = "\x01__alldiv", .linkage = strong_linkage });105 @export(__unorddf2, .{ .name = "__unorddf2", .linkage = linkage });
444 const _aulldiv = @import("compiler_rt/aulldiv.zig")._aulldiv;106 const __unordtf2 = @import("compiler_rt/compareXf2.zig").__unordtf2;
445 @export(_aulldiv, .{ .name = "\x01__aulldiv", .linkage = strong_linkage });107 @export(__unordtf2, .{ .name = "__unordtf2", .linkage = linkage });
446 const _allrem = @import("compiler_rt/aullrem.zig")._allrem;108
447 @export(_allrem, .{ .name = "\x01__allrem", .linkage = strong_linkage });109 const __addsf3 = @import("compiler_rt/addXf3.zig").__addsf3;
448 const _aullrem = @import("compiler_rt/aullrem.zig")._aullrem;110 @export(__addsf3, .{ .name = "__addsf3", .linkage = linkage });
449 @export(_aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage });111 const __adddf3 = @import("compiler_rt/addXf3.zig").__adddf3;
450 }112 @export(__adddf3, .{ .name = "__adddf3", .linkage = linkage });
113 const __addtf3 = @import("compiler_rt/addXf3.zig").__addtf3;
114 @export(__addtf3, .{ .name = "__addtf3", .linkage = linkage });
115 const __subsf3 = @import("compiler_rt/addXf3.zig").__subsf3;
116 @export(__subsf3, .{ .name = "__subsf3", .linkage = linkage });
117 const __subdf3 = @import("compiler_rt/addXf3.zig").__subdf3;
118 @export(__subdf3, .{ .name = "__subdf3", .linkage = linkage });
119 const __subtf3 = @import("compiler_rt/addXf3.zig").__subtf3;
120 @export(__subtf3, .{ .name = "__subtf3", .linkage = linkage });
121
122 const __mulsf3 = @import("compiler_rt/mulXf3.zig").__mulsf3;
123 @export(__mulsf3, .{ .name = "__mulsf3", .linkage = linkage });
124 const __muldf3 = @import("compiler_rt/mulXf3.zig").__muldf3;
125 @export(__muldf3, .{ .name = "__muldf3", .linkage = linkage });
126 const __multf3 = @import("compiler_rt/mulXf3.zig").__multf3;
127 @export(__multf3, .{ .name = "__multf3", .linkage = linkage });
128
129 const __divsf3 = @import("compiler_rt/divsf3.zig").__divsf3;
130 @export(__divsf3, .{ .name = "__divsf3", .linkage = linkage });
131 const __divdf3 = @import("compiler_rt/divdf3.zig").__divdf3;
132 @export(__divdf3, .{ .name = "__divdf3", .linkage = linkage });
133 const __divtf3 = @import("compiler_rt/divtf3.zig").__divtf3;
134 @export(__divtf3, .{ .name = "__divtf3", .linkage = linkage });
135
136 const __ashldi3 = @import("compiler_rt/shift.zig").__ashldi3;
137 @export(__ashldi3, .{ .name = "__ashldi3", .linkage = linkage });
138 const __ashlti3 = @import("compiler_rt/shift.zig").__ashlti3;
139 @export(__ashlti3, .{ .name = "__ashlti3", .linkage = linkage });
140 const __ashrdi3 = @import("compiler_rt/shift.zig").__ashrdi3;
141 @export(__ashrdi3, .{ .name = "__ashrdi3", .linkage = linkage });
142 const __ashrti3 = @import("compiler_rt/shift.zig").__ashrti3;
143 @export(__ashrti3, .{ .name = "__ashrti3", .linkage = linkage });
144 const __lshrdi3 = @import("compiler_rt/shift.zig").__lshrdi3;
145 @export(__lshrdi3, .{ .name = "__lshrdi3", .linkage = linkage });
146 const __lshrti3 = @import("compiler_rt/shift.zig").__lshrti3;
147 @export(__lshrti3, .{ .name = "__lshrti3", .linkage = linkage });
148
149 const __floatsidf = @import("compiler_rt/floatsiXf.zig").__floatsidf;
150 @export(__floatsidf, .{ .name = "__floatsidf", .linkage = linkage });
151 const __floatsisf = @import("compiler_rt/floatsiXf.zig").__floatsisf;
152 @export(__floatsisf, .{ .name = "__floatsisf", .linkage = linkage });
153 const __floatdidf = @import("compiler_rt/floatdidf.zig").__floatdidf;
154 @export(__floatdidf, .{ .name = "__floatdidf", .linkage = linkage });
155 const __floatsitf = @import("compiler_rt/floatsiXf.zig").__floatsitf;
156 @export(__floatsitf, .{ .name = "__floatsitf", .linkage = linkage });
157
158 const __floatunsisf = @import("compiler_rt/floatunsisf.zig").__floatunsisf;
159 @export(__floatunsisf, .{ .name = "__floatunsisf", .linkage = linkage });
160 const __floatundisf = @import("compiler_rt/floatundisf.zig").__floatundisf;
161 @export(__floatundisf, .{ .name = "__floatundisf", .linkage = linkage });
162 const __floatunsidf = @import("compiler_rt/floatunsidf.zig").__floatunsidf;
163 @export(__floatunsidf, .{ .name = "__floatunsidf", .linkage = linkage });
164 const __floatundidf = @import("compiler_rt/floatundidf.zig").__floatundidf;
165 @export(__floatundidf, .{ .name = "__floatundidf", .linkage = linkage });
166
167 const __floatditf = @import("compiler_rt/floatditf.zig").__floatditf;
168 @export(__floatditf, .{ .name = "__floatditf", .linkage = linkage });
169 const __floattitf = @import("compiler_rt/floattitf.zig").__floattitf;
170 @export(__floattitf, .{ .name = "__floattitf", .linkage = linkage });
171 const __floattidf = @import("compiler_rt/floattidf.zig").__floattidf;
172 @export(__floattidf, .{ .name = "__floattidf", .linkage = linkage });
173 const __floattisf = @import("compiler_rt/floatXisf.zig").__floattisf;
174 @export(__floattisf, .{ .name = "__floattisf", .linkage = linkage });
175 const __floatdisf = @import("compiler_rt/floatXisf.zig").__floatdisf;
176 @export(__floatdisf, .{ .name = "__floatdisf", .linkage = linkage });
177
178 const __floatunditf = @import("compiler_rt/floatunditf.zig").__floatunditf;
179 @export(__floatunditf, .{ .name = "__floatunditf", .linkage = linkage });
180 const __floatunsitf = @import("compiler_rt/floatunsitf.zig").__floatunsitf;
181 @export(__floatunsitf, .{ .name = "__floatunsitf", .linkage = linkage });
182
183 const __floatuntitf = @import("compiler_rt/floatuntitf.zig").__floatuntitf;
184 @export(__floatuntitf, .{ .name = "__floatuntitf", .linkage = linkage });
185 const __floatuntidf = @import("compiler_rt/floatuntidf.zig").__floatuntidf;
186 @export(__floatuntidf, .{ .name = "__floatuntidf", .linkage = linkage });
187 const __floatuntisf = @import("compiler_rt/floatuntisf.zig").__floatuntisf;
188 @export(__floatuntisf, .{ .name = "__floatuntisf", .linkage = linkage });
451189
452 if (arch.isSPARC()) {190 const __truncsfhf2 = @import("compiler_rt/truncXfYf2.zig").__truncsfhf2;
453 // SPARC systems use a different naming scheme191 @export(__truncsfhf2, .{ .name = "__truncsfhf2", .linkage = linkage });
454 const _Qp_add = @import("compiler_rt/sparc.zig")._Qp_add;192 const __truncdfhf2 = @import("compiler_rt/truncXfYf2.zig").__truncdfhf2;
455 @export(_Qp_add, .{ .name = "_Qp_add", .linkage = linkage });193 @export(__truncdfhf2, .{ .name = "__truncdfhf2", .linkage = linkage });
456 const _Qp_div = @import("compiler_rt/sparc.zig")._Qp_div;194 const __trunctfhf2 = @import("compiler_rt/truncXfYf2.zig").__trunctfhf2;
457 @export(_Qp_div, .{ .name = "_Qp_div", .linkage = linkage });195 @export(__trunctfhf2, .{ .name = "__trunctfhf2", .linkage = linkage });
458 const _Qp_mul = @import("compiler_rt/sparc.zig")._Qp_mul;196 const __trunctfdf2 = @import("compiler_rt/truncXfYf2.zig").__trunctfdf2;
459 @export(_Qp_mul, .{ .name = "_Qp_mul", .linkage = linkage });197 @export(__trunctfdf2, .{ .name = "__trunctfdf2", .linkage = linkage });
460 const _Qp_sub = @import("compiler_rt/sparc.zig")._Qp_sub;198 const __trunctfsf2 = @import("compiler_rt/truncXfYf2.zig").__trunctfsf2;
461 @export(_Qp_sub, .{ .name = "_Qp_sub", .linkage = linkage });199 @export(__trunctfsf2, .{ .name = "__trunctfsf2", .linkage = linkage });
462200
463 const _Qp_cmp = @import("compiler_rt/sparc.zig")._Qp_cmp;201 const __truncdfsf2 = @import("compiler_rt/truncXfYf2.zig").__truncdfsf2;
464 @export(_Qp_cmp, .{ .name = "_Qp_cmp", .linkage = linkage });202 @export(__truncdfsf2, .{ .name = "__truncdfsf2", .linkage = linkage });
465 const _Qp_feq = @import("compiler_rt/sparc.zig")._Qp_feq;203
466 @export(_Qp_feq, .{ .name = "_Qp_feq", .linkage = linkage });204 const __extendsfdf2 = @import("compiler_rt/extendXfYf2.zig").__extendsfdf2;
467 const _Qp_fne = @import("compiler_rt/sparc.zig")._Qp_fne;205 @export(__extendsfdf2, .{ .name = "__extendsfdf2", .linkage = linkage });
468 @export(_Qp_fne, .{ .name = "_Qp_fne", .linkage = linkage });206
469 const _Qp_flt = @import("compiler_rt/sparc.zig")._Qp_flt;207 const __fixunssfsi = @import("compiler_rt/fixunssfsi.zig").__fixunssfsi;
470 @export(_Qp_flt, .{ .name = "_Qp_flt", .linkage = linkage });208 @export(__fixunssfsi, .{ .name = "__fixunssfsi", .linkage = linkage });
471 const _Qp_fle = @import("compiler_rt/sparc.zig")._Qp_fle;209 const __fixunssfdi = @import("compiler_rt/fixunssfdi.zig").__fixunssfdi;
472 @export(_Qp_fle, .{ .name = "_Qp_fle", .linkage = linkage });210 @export(__fixunssfdi, .{ .name = "__fixunssfdi", .linkage = linkage });
473 const _Qp_fgt = @import("compiler_rt/sparc.zig")._Qp_fgt;211 const __fixunssfti = @import("compiler_rt/fixunssfti.zig").__fixunssfti;
474 @export(_Qp_fgt, .{ .name = "_Qp_fgt", .linkage = linkage });212 @export(__fixunssfti, .{ .name = "__fixunssfti", .linkage = linkage });
475 const _Qp_fge = @import("compiler_rt/sparc.zig")._Qp_fge;213
476 @export(_Qp_fge, .{ .name = "_Qp_fge", .linkage = linkage });214 const __fixunsdfsi = @import("compiler_rt/fixunsdfsi.zig").__fixunsdfsi;
477215 @export(__fixunsdfsi, .{ .name = "__fixunsdfsi", .linkage = linkage });
478 const _Qp_itoq = @import("compiler_rt/sparc.zig")._Qp_itoq;216 const __fixunsdfdi = @import("compiler_rt/fixunsdfdi.zig").__fixunsdfdi;
479 @export(_Qp_itoq, .{ .name = "_Qp_itoq", .linkage = linkage });217 @export(__fixunsdfdi, .{ .name = "__fixunsdfdi", .linkage = linkage });
480 const _Qp_uitoq = @import("compiler_rt/sparc.zig")._Qp_uitoq;218 const __fixunsdfti = @import("compiler_rt/fixunsdfti.zig").__fixunsdfti;
481 @export(_Qp_uitoq, .{ .name = "_Qp_uitoq", .linkage = linkage });219 @export(__fixunsdfti, .{ .name = "__fixunsdfti", .linkage = linkage });
482 const _Qp_xtoq = @import("compiler_rt/sparc.zig")._Qp_xtoq;220
483 @export(_Qp_xtoq, .{ .name = "_Qp_xtoq", .linkage = linkage });221 const __fixunstfsi = @import("compiler_rt/fixunstfsi.zig").__fixunstfsi;
484 const _Qp_uxtoq = @import("compiler_rt/sparc.zig")._Qp_uxtoq;222 @export(__fixunstfsi, .{ .name = "__fixunstfsi", .linkage = linkage });
485 @export(_Qp_uxtoq, .{ .name = "_Qp_uxtoq", .linkage = linkage });223 const __fixunstfdi = @import("compiler_rt/fixunstfdi.zig").__fixunstfdi;
486 const _Qp_stoq = @import("compiler_rt/sparc.zig")._Qp_stoq;224 @export(__fixunstfdi, .{ .name = "__fixunstfdi", .linkage = linkage });
487 @export(_Qp_stoq, .{ .name = "_Qp_stoq", .linkage = linkage });225 const __fixunstfti = @import("compiler_rt/fixunstfti.zig").__fixunstfti;
488 const _Qp_dtoq = @import("compiler_rt/sparc.zig")._Qp_dtoq;226 @export(__fixunstfti, .{ .name = "__fixunstfti", .linkage = linkage });
489 @export(_Qp_dtoq, .{ .name = "_Qp_dtoq", .linkage = linkage });227
490 const _Qp_qtoi = @import("compiler_rt/sparc.zig")._Qp_qtoi;228 const __fixdfdi = @import("compiler_rt/fixdfdi.zig").__fixdfdi;
491 @export(_Qp_qtoi, .{ .name = "_Qp_qtoi", .linkage = linkage });229 @export(__fixdfdi, .{ .name = "__fixdfdi", .linkage = linkage });
492 const _Qp_qtoui = @import("compiler_rt/sparc.zig")._Qp_qtoui;230 const __fixdfsi = @import("compiler_rt/fixdfsi.zig").__fixdfsi;
493 @export(_Qp_qtoui, .{ .name = "_Qp_qtoui", .linkage = linkage });231 @export(__fixdfsi, .{ .name = "__fixdfsi", .linkage = linkage });
494 const _Qp_qtox = @import("compiler_rt/sparc.zig")._Qp_qtox;232 const __fixdfti = @import("compiler_rt/fixdfti.zig").__fixdfti;
495 @export(_Qp_qtox, .{ .name = "_Qp_qtox", .linkage = linkage });233 @export(__fixdfti, .{ .name = "__fixdfti", .linkage = linkage });
496 const _Qp_qtoux = @import("compiler_rt/sparc.zig")._Qp_qtoux;234 const __fixsfdi = @import("compiler_rt/fixsfdi.zig").__fixsfdi;
497 @export(_Qp_qtoux, .{ .name = "_Qp_qtoux", .linkage = linkage });235 @export(__fixsfdi, .{ .name = "__fixsfdi", .linkage = linkage });
498 const _Qp_qtos = @import("compiler_rt/sparc.zig")._Qp_qtos;236 const __fixsfsi = @import("compiler_rt/fixsfsi.zig").__fixsfsi;
499 @export(_Qp_qtos, .{ .name = "_Qp_qtos", .linkage = linkage });237 @export(__fixsfsi, .{ .name = "__fixsfsi", .linkage = linkage });
500 const _Qp_qtod = @import("compiler_rt/sparc.zig")._Qp_qtod;238 const __fixsfti = @import("compiler_rt/fixsfti.zig").__fixsfti;
501 @export(_Qp_qtod, .{ .name = "_Qp_qtod", .linkage = linkage });239 @export(__fixsfti, .{ .name = "__fixsfti", .linkage = linkage });
502 }240 const __fixtfdi = @import("compiler_rt/fixtfdi.zig").__fixtfdi;
241 @export(__fixtfdi, .{ .name = "__fixtfdi", .linkage = linkage });
242 const __fixtfsi = @import("compiler_rt/fixtfsi.zig").__fixtfsi;
243 @export(__fixtfsi, .{ .name = "__fixtfsi", .linkage = linkage });
244 const __fixtfti = @import("compiler_rt/fixtfti.zig").__fixtfti;
245 @export(__fixtfti, .{ .name = "__fixtfti", .linkage = linkage });
246
247 const __udivmoddi4 = @import("compiler_rt/int.zig").__udivmoddi4;
248 @export(__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });
249 const __popcountdi2 = @import("compiler_rt/popcountdi2.zig").__popcountdi2;
250 @export(__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });
251
252 const __mulsi3 = @import("compiler_rt/int.zig").__mulsi3;
253 @export(__mulsi3, .{ .name = "__mulsi3", .linkage = linkage });
254 const __muldi3 = @import("compiler_rt/muldi3.zig").__muldi3;
255 @export(__muldi3, .{ .name = "__muldi3", .linkage = linkage });
256 const __divmoddi4 = @import("compiler_rt/int.zig").__divmoddi4;
257 @export(__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });
258 const __divsi3 = @import("compiler_rt/int.zig").__divsi3;
259 @export(__divsi3, .{ .name = "__divsi3", .linkage = linkage });
260 const __divdi3 = @import("compiler_rt/int.zig").__divdi3;
261 @export(__divdi3, .{ .name = "__divdi3", .linkage = linkage });
262 const __udivsi3 = @import("compiler_rt/int.zig").__udivsi3;
263 @export(__udivsi3, .{ .name = "__udivsi3", .linkage = linkage });
264 const __udivdi3 = @import("compiler_rt/int.zig").__udivdi3;
265 @export(__udivdi3, .{ .name = "__udivdi3", .linkage = linkage });
266 const __modsi3 = @import("compiler_rt/int.zig").__modsi3;
267 @export(__modsi3, .{ .name = "__modsi3", .linkage = linkage });
268 const __moddi3 = @import("compiler_rt/int.zig").__moddi3;
269 @export(__moddi3, .{ .name = "__moddi3", .linkage = linkage });
270 const __umodsi3 = @import("compiler_rt/int.zig").__umodsi3;
271 @export(__umodsi3, .{ .name = "__umodsi3", .linkage = linkage });
272 const __umoddi3 = @import("compiler_rt/int.zig").__umoddi3;
273 @export(__umoddi3, .{ .name = "__umoddi3", .linkage = linkage });
274 const __divmodsi4 = @import("compiler_rt/int.zig").__divmodsi4;
275 @export(__divmodsi4, .{ .name = "__divmodsi4", .linkage = linkage });
276 const __udivmodsi4 = @import("compiler_rt/int.zig").__udivmodsi4;
277 @export(__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = linkage });
278
279 const __negsf2 = @import("compiler_rt/negXf2.zig").__negsf2;
280 @export(__negsf2, .{ .name = "__negsf2", .linkage = linkage });
281 const __negdf2 = @import("compiler_rt/negXf2.zig").__negdf2;
282 @export(__negdf2, .{ .name = "__negdf2", .linkage = linkage });
283
284 const __clzsi2 = @import("compiler_rt/count0bits.zig").__clzsi2;
285 @export(__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });
286 const __clzdi2 = @import("compiler_rt/count0bits.zig").__clzdi2;
287 @export(__clzdi2, .{ .name = "__clzdi2", .linkage = linkage });
288 const __clzti2 = @import("compiler_rt/count0bits.zig").__clzti2;
289 @export(__clzti2, .{ .name = "__clzti2", .linkage = linkage });
290
291 if (builtin.link_libc and os_tag == .openbsd) {
292 const __emutls_get_address = @import("compiler_rt/emutls.zig").__emutls_get_address;
293 @export(__emutls_get_address, .{ .name = "__emutls_get_address", .linkage = linkage });
294 }
503295
504 if ((arch == .powerpc or arch.isPPC64()) and !is_test) {296 if ((arch.isARM() or arch.isThumb()) and !is_test) {
505 @export(__addtf3, .{ .name = "__addkf3", .linkage = linkage });297 const __aeabi_unwind_cpp_pr0 = @import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr0;
506 @export(__subtf3, .{ .name = "__subkf3", .linkage = linkage });298 @export(__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = linkage });
507 @export(__multf3, .{ .name = "__mulkf3", .linkage = linkage });299 const __aeabi_unwind_cpp_pr1 = @import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr1;
508 @export(__divtf3, .{ .name = "__divkf3", .linkage = linkage });300 @export(__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = linkage });
509 @export(__extendsftf2, .{ .name = "__extendsfkf2", .linkage = linkage });301 const __aeabi_unwind_cpp_pr2 = @import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr2;
510 @export(__extenddftf2, .{ .name = "__extenddfkf2", .linkage = linkage });302 @export(__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = linkage });
511 @export(__trunctfsf2, .{ .name = "__trunckfsf2", .linkage = linkage });303
512 @export(__trunctfdf2, .{ .name = "__trunckfdf2", .linkage = linkage });304 @export(__muldi3, .{ .name = "__aeabi_lmul", .linkage = linkage });
513 @export(__fixtfdi, .{ .name = "__fixkfdi", .linkage = linkage });305
514 @export(__fixtfsi, .{ .name = "__fixkfsi", .linkage = linkage });306 const __aeabi_ldivmod = @import("compiler_rt/arm.zig").__aeabi_ldivmod;
515 @export(__fixunstfsi, .{ .name = "__fixunskfsi", .linkage = linkage });307 @export(__aeabi_ldivmod, .{ .name = "__aeabi_ldivmod", .linkage = linkage });
516 @export(__fixunstfdi, .{ .name = "__fixunskfdi", .linkage = linkage });308 const __aeabi_uldivmod = @import("compiler_rt/arm.zig").__aeabi_uldivmod;
517 @export(__floatsitf, .{ .name = "__floatsikf", .linkage = linkage });309 @export(__aeabi_uldivmod, .{ .name = "__aeabi_uldivmod", .linkage = linkage });
518 @export(__floatditf, .{ .name = "__floatdikf", .linkage = linkage });310
519 @export(__floatunditf, .{ .name = "__floatundikf", .linkage = linkage });311 @export(__divsi3, .{ .name = "__aeabi_idiv", .linkage = linkage });
520 @export(__floatunsitf, .{ .name = "__floatunsikf", .linkage = linkage });312 const __aeabi_idivmod = @import("compiler_rt/arm.zig").__aeabi_idivmod;
521313 @export(__aeabi_idivmod, .{ .name = "__aeabi_idivmod", .linkage = linkage });
522 @export(__letf2, .{ .name = "__eqkf2", .linkage = linkage });314 @export(__udivsi3, .{ .name = "__aeabi_uidiv", .linkage = linkage });
523 @export(__letf2, .{ .name = "__nekf2", .linkage = linkage });315 const __aeabi_uidivmod = @import("compiler_rt/arm.zig").__aeabi_uidivmod;
524 @export(__getf2, .{ .name = "__gekf2", .linkage = linkage });316 @export(__aeabi_uidivmod, .{ .name = "__aeabi_uidivmod", .linkage = linkage });
525 @export(__letf2, .{ .name = "__ltkf2", .linkage = linkage });317
526 @export(__letf2, .{ .name = "__lekf2", .linkage = linkage });318 const __aeabi_memcpy = @import("compiler_rt/arm.zig").__aeabi_memcpy;
527 @export(__getf2, .{ .name = "__gtkf2", .linkage = linkage });319 @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = linkage });
528 @export(__unordtf2, .{ .name = "__unordkf2", .linkage = linkage });320 @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy4", .linkage = linkage });
529 }321 @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy8", .linkage = linkage });
322
323 const __aeabi_memmove = @import("compiler_rt/arm.zig").__aeabi_memmove;
324 @export(__aeabi_memmove, .{ .name = "__aeabi_memmove", .linkage = linkage });
325 @export(__aeabi_memmove, .{ .name = "__aeabi_memmove4", .linkage = linkage });
326 @export(__aeabi_memmove, .{ .name = "__aeabi_memmove8", .linkage = linkage });
327
328 const __aeabi_memset = @import("compiler_rt/arm.zig").__aeabi_memset;
329 @export(__aeabi_memset, .{ .name = "__aeabi_memset", .linkage = linkage });
330 @export(__aeabi_memset, .{ .name = "__aeabi_memset4", .linkage = linkage });
331 @export(__aeabi_memset, .{ .name = "__aeabi_memset8", .linkage = linkage });
332
333 const __aeabi_memclr = @import("compiler_rt/arm.zig").__aeabi_memclr;
334 @export(__aeabi_memclr, .{ .name = "__aeabi_memclr", .linkage = linkage });
335 @export(__aeabi_memclr, .{ .name = "__aeabi_memclr4", .linkage = linkage });
336 @export(__aeabi_memclr, .{ .name = "__aeabi_memclr8", .linkage = linkage });
337
338 if (os_tag == .linux) {
339 const __aeabi_read_tp = @import("compiler_rt/arm.zig").__aeabi_read_tp;
340 @export(__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = linkage });
341 }
342
343 const __aeabi_f2d = @import("compiler_rt/extendXfYf2.zig").__aeabi_f2d;
344 @export(__aeabi_f2d, .{ .name = "__aeabi_f2d", .linkage = linkage });
345 const __aeabi_i2d = @import("compiler_rt/floatsiXf.zig").__aeabi_i2d;
346 @export(__aeabi_i2d, .{ .name = "__aeabi_i2d", .linkage = linkage });
347 const __aeabi_l2d = @import("compiler_rt/floatdidf.zig").__aeabi_l2d;
348 @export(__aeabi_l2d, .{ .name = "__aeabi_l2d", .linkage = linkage });
349 const __aeabi_l2f = @import("compiler_rt/floatXisf.zig").__aeabi_l2f;
350 @export(__aeabi_l2f, .{ .name = "__aeabi_l2f", .linkage = linkage });
351 const __aeabi_ui2d = @import("compiler_rt/floatunsidf.zig").__aeabi_ui2d;
352 @export(__aeabi_ui2d, .{ .name = "__aeabi_ui2d", .linkage = linkage });
353 const __aeabi_ul2d = @import("compiler_rt/floatundidf.zig").__aeabi_ul2d;
354 @export(__aeabi_ul2d, .{ .name = "__aeabi_ul2d", .linkage = linkage });
355 const __aeabi_ui2f = @import("compiler_rt/floatunsisf.zig").__aeabi_ui2f;
356 @export(__aeabi_ui2f, .{ .name = "__aeabi_ui2f", .linkage = linkage });
357 const __aeabi_ul2f = @import("compiler_rt/floatundisf.zig").__aeabi_ul2f;
358 @export(__aeabi_ul2f, .{ .name = "__aeabi_ul2f", .linkage = linkage });
359
360 const __aeabi_fneg = @import("compiler_rt/negXf2.zig").__aeabi_fneg;
361 @export(__aeabi_fneg, .{ .name = "__aeabi_fneg", .linkage = linkage });
362 const __aeabi_dneg = @import("compiler_rt/negXf2.zig").__aeabi_dneg;
363 @export(__aeabi_dneg, .{ .name = "__aeabi_dneg", .linkage = linkage });
364
365 const __aeabi_fmul = @import("compiler_rt/mulXf3.zig").__aeabi_fmul;
366 @export(__aeabi_fmul, .{ .name = "__aeabi_fmul", .linkage = linkage });
367 const __aeabi_dmul = @import("compiler_rt/mulXf3.zig").__aeabi_dmul;
368 @export(__aeabi_dmul, .{ .name = "__aeabi_dmul", .linkage = linkage });
369
370 const __aeabi_d2h = @import("compiler_rt/truncXfYf2.zig").__aeabi_d2h;
371 @export(__aeabi_d2h, .{ .name = "__aeabi_d2h", .linkage = linkage });
372
373 const __aeabi_f2ulz = @import("compiler_rt/fixunssfdi.zig").__aeabi_f2ulz;
374 @export(__aeabi_f2ulz, .{ .name = "__aeabi_f2ulz", .linkage = linkage });
375 const __aeabi_d2ulz = @import("compiler_rt/fixunsdfdi.zig").__aeabi_d2ulz;
376 @export(__aeabi_d2ulz, .{ .name = "__aeabi_d2ulz", .linkage = linkage });
377
378 const __aeabi_f2lz = @import("compiler_rt/fixsfdi.zig").__aeabi_f2lz;
379 @export(__aeabi_f2lz, .{ .name = "__aeabi_f2lz", .linkage = linkage });
380 const __aeabi_d2lz = @import("compiler_rt/fixdfdi.zig").__aeabi_d2lz;
381 @export(__aeabi_d2lz, .{ .name = "__aeabi_d2lz", .linkage = linkage });
382
383 const __aeabi_d2uiz = @import("compiler_rt/fixunsdfsi.zig").__aeabi_d2uiz;
384 @export(__aeabi_d2uiz, .{ .name = "__aeabi_d2uiz", .linkage = linkage });
385
386 const __aeabi_h2f = @import("compiler_rt/extendXfYf2.zig").__aeabi_h2f;
387 @export(__aeabi_h2f, .{ .name = "__aeabi_h2f", .linkage = linkage });
388 const __aeabi_f2h = @import("compiler_rt/truncXfYf2.zig").__aeabi_f2h;
389 @export(__aeabi_f2h, .{ .name = "__aeabi_f2h", .linkage = linkage });
390
391 const __aeabi_i2f = @import("compiler_rt/floatsiXf.zig").__aeabi_i2f;
392 @export(__aeabi_i2f, .{ .name = "__aeabi_i2f", .linkage = linkage });
393 const __aeabi_d2f = @import("compiler_rt/truncXfYf2.zig").__aeabi_d2f;
394 @export(__aeabi_d2f, .{ .name = "__aeabi_d2f", .linkage = linkage });
395
396 const __aeabi_fadd = @import("compiler_rt/addXf3.zig").__aeabi_fadd;
397 @export(__aeabi_fadd, .{ .name = "__aeabi_fadd", .linkage = linkage });
398 const __aeabi_dadd = @import("compiler_rt/addXf3.zig").__aeabi_dadd;
399 @export(__aeabi_dadd, .{ .name = "__aeabi_dadd", .linkage = linkage });
400 const __aeabi_fsub = @import("compiler_rt/addXf3.zig").__aeabi_fsub;
401 @export(__aeabi_fsub, .{ .name = "__aeabi_fsub", .linkage = linkage });
402 const __aeabi_dsub = @import("compiler_rt/addXf3.zig").__aeabi_dsub;
403 @export(__aeabi_dsub, .{ .name = "__aeabi_dsub", .linkage = linkage });
404
405 const __aeabi_f2uiz = @import("compiler_rt/fixunssfsi.zig").__aeabi_f2uiz;
406 @export(__aeabi_f2uiz, .{ .name = "__aeabi_f2uiz", .linkage = linkage });
407
408 const __aeabi_f2iz = @import("compiler_rt/fixsfsi.zig").__aeabi_f2iz;
409 @export(__aeabi_f2iz, .{ .name = "__aeabi_f2iz", .linkage = linkage });
410 const __aeabi_d2iz = @import("compiler_rt/fixdfsi.zig").__aeabi_d2iz;
411 @export(__aeabi_d2iz, .{ .name = "__aeabi_d2iz", .linkage = linkage });
412
413 const __aeabi_fdiv = @import("compiler_rt/divsf3.zig").__aeabi_fdiv;
414 @export(__aeabi_fdiv, .{ .name = "__aeabi_fdiv", .linkage = linkage });
415 const __aeabi_ddiv = @import("compiler_rt/divdf3.zig").__aeabi_ddiv;
416 @export(__aeabi_ddiv, .{ .name = "__aeabi_ddiv", .linkage = linkage });
417
418 const __aeabi_llsl = @import("compiler_rt/shift.zig").__aeabi_llsl;
419 @export(__aeabi_llsl, .{ .name = "__aeabi_llsl", .linkage = linkage });
420 const __aeabi_lasr = @import("compiler_rt/shift.zig").__aeabi_lasr;
421 @export(__aeabi_lasr, .{ .name = "__aeabi_lasr", .linkage = linkage });
422 const __aeabi_llsr = @import("compiler_rt/shift.zig").__aeabi_llsr;
423 @export(__aeabi_llsr, .{ .name = "__aeabi_llsr", .linkage = linkage });
424
425 const __aeabi_fcmpeq = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpeq;
426 @export(__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = linkage });
427 const __aeabi_fcmplt = @import("compiler_rt/compareXf2.zig").__aeabi_fcmplt;
428 @export(__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = linkage });
429 const __aeabi_fcmple = @import("compiler_rt/compareXf2.zig").__aeabi_fcmple;
430 @export(__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = linkage });
431 const __aeabi_fcmpge = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpge;
432 @export(__aeabi_fcmpge, .{ .name = "__aeabi_fcmpge", .linkage = linkage });
433 const __aeabi_fcmpgt = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpgt;
434 @export(__aeabi_fcmpgt, .{ .name = "__aeabi_fcmpgt", .linkage = linkage });
435 const __aeabi_fcmpun = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpun;
436 @export(__aeabi_fcmpun, .{ .name = "__aeabi_fcmpun", .linkage = linkage });
437
438 const __aeabi_dcmpeq = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpeq;
439 @export(__aeabi_dcmpeq, .{ .name = "__aeabi_dcmpeq", .linkage = linkage });
440 const __aeabi_dcmplt = @import("compiler_rt/compareXf2.zig").__aeabi_dcmplt;
441 @export(__aeabi_dcmplt, .{ .name = "__aeabi_dcmplt", .linkage = linkage });
442 const __aeabi_dcmple = @import("compiler_rt/compareXf2.zig").__aeabi_dcmple;
443 @export(__aeabi_dcmple, .{ .name = "__aeabi_dcmple", .linkage = linkage });
444 const __aeabi_dcmpge = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpge;
445 @export(__aeabi_dcmpge, .{ .name = "__aeabi_dcmpge", .linkage = linkage });
446 const __aeabi_dcmpgt = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpgt;
447 @export(__aeabi_dcmpgt, .{ .name = "__aeabi_dcmpgt", .linkage = linkage });
448 const __aeabi_dcmpun = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpun;
449 @export(__aeabi_dcmpun, .{ .name = "__aeabi_dcmpun", .linkage = linkage });
450 }
530451
531 if (builtin.os.tag == .windows) {452 if (arch == .i386 and abi == .msvc) {
532 // Default stack-probe functions emitted by LLVM453 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins
533 if (is_mingw) {454 const _alldiv = @import("compiler_rt/aulldiv.zig")._alldiv;
534 const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;455 @export(_alldiv, .{ .name = "\x01__alldiv", .linkage = strong_linkage });
535 @export(_chkstk, .{ .name = "_alloca", .linkage = strong_linkage });456 const _aulldiv = @import("compiler_rt/aulldiv.zig")._aulldiv;
536 const ___chkstk_ms = @import("compiler_rt/stack_probe.zig").___chkstk_ms;457 @export(_aulldiv, .{ .name = "\x01__aulldiv", .linkage = strong_linkage });
537 @export(___chkstk_ms, .{ .name = "___chkstk_ms", .linkage = strong_linkage });458 const _allrem = @import("compiler_rt/aullrem.zig")._allrem;
538 } else if (!builtin.link_libc) {459 @export(_allrem, .{ .name = "\x01__allrem", .linkage = strong_linkage });
539 // This symbols are otherwise exported by MSVCRT.lib460 const _aullrem = @import("compiler_rt/aullrem.zig")._aullrem;
540 const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;461 @export(_aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage });
541 @export(_chkstk, .{ .name = "_chkstk", .linkage = strong_linkage });
542 const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
543 @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
544 }462 }
545463
546 switch (arch) {464 if (arch.isSPARC()) {
547 .i386 => {465 // SPARC systems use a different naming scheme
548 const __divti3 = @import("compiler_rt/divti3.zig").__divti3;466 const _Qp_add = @import("compiler_rt/sparc.zig")._Qp_add;
549 @export(__divti3, .{ .name = "__divti3", .linkage = linkage });467 @export(_Qp_add, .{ .name = "_Qp_add", .linkage = linkage });
468 const _Qp_div = @import("compiler_rt/sparc.zig")._Qp_div;
469 @export(_Qp_div, .{ .name = "_Qp_div", .linkage = linkage });
470 const _Qp_mul = @import("compiler_rt/sparc.zig")._Qp_mul;
471 @export(_Qp_mul, .{ .name = "_Qp_mul", .linkage = linkage });
472 const _Qp_sub = @import("compiler_rt/sparc.zig")._Qp_sub;
473 @export(_Qp_sub, .{ .name = "_Qp_sub", .linkage = linkage });
474
475 const _Qp_cmp = @import("compiler_rt/sparc.zig")._Qp_cmp;
476 @export(_Qp_cmp, .{ .name = "_Qp_cmp", .linkage = linkage });
477 const _Qp_feq = @import("compiler_rt/sparc.zig")._Qp_feq;
478 @export(_Qp_feq, .{ .name = "_Qp_feq", .linkage = linkage });
479 const _Qp_fne = @import("compiler_rt/sparc.zig")._Qp_fne;
480 @export(_Qp_fne, .{ .name = "_Qp_fne", .linkage = linkage });
481 const _Qp_flt = @import("compiler_rt/sparc.zig")._Qp_flt;
482 @export(_Qp_flt, .{ .name = "_Qp_flt", .linkage = linkage });
483 const _Qp_fle = @import("compiler_rt/sparc.zig")._Qp_fle;
484 @export(_Qp_fle, .{ .name = "_Qp_fle", .linkage = linkage });
485 const _Qp_fgt = @import("compiler_rt/sparc.zig")._Qp_fgt;
486 @export(_Qp_fgt, .{ .name = "_Qp_fgt", .linkage = linkage });
487 const _Qp_fge = @import("compiler_rt/sparc.zig")._Qp_fge;
488 @export(_Qp_fge, .{ .name = "_Qp_fge", .linkage = linkage });
489
490 const _Qp_itoq = @import("compiler_rt/sparc.zig")._Qp_itoq;
491 @export(_Qp_itoq, .{ .name = "_Qp_itoq", .linkage = linkage });
492 const _Qp_uitoq = @import("compiler_rt/sparc.zig")._Qp_uitoq;
493 @export(_Qp_uitoq, .{ .name = "_Qp_uitoq", .linkage = linkage });
494 const _Qp_xtoq = @import("compiler_rt/sparc.zig")._Qp_xtoq;
495 @export(_Qp_xtoq, .{ .name = "_Qp_xtoq", .linkage = linkage });
496 const _Qp_uxtoq = @import("compiler_rt/sparc.zig")._Qp_uxtoq;
497 @export(_Qp_uxtoq, .{ .name = "_Qp_uxtoq", .linkage = linkage });
498 const _Qp_stoq = @import("compiler_rt/sparc.zig")._Qp_stoq;
499 @export(_Qp_stoq, .{ .name = "_Qp_stoq", .linkage = linkage });
500 const _Qp_dtoq = @import("compiler_rt/sparc.zig")._Qp_dtoq;
501 @export(_Qp_dtoq, .{ .name = "_Qp_dtoq", .linkage = linkage });
502 const _Qp_qtoi = @import("compiler_rt/sparc.zig")._Qp_qtoi;
503 @export(_Qp_qtoi, .{ .name = "_Qp_qtoi", .linkage = linkage });
504 const _Qp_qtoui = @import("compiler_rt/sparc.zig")._Qp_qtoui;
505 @export(_Qp_qtoui, .{ .name = "_Qp_qtoui", .linkage = linkage });
506 const _Qp_qtox = @import("compiler_rt/sparc.zig")._Qp_qtox;
507 @export(_Qp_qtox, .{ .name = "_Qp_qtox", .linkage = linkage });
508 const _Qp_qtoux = @import("compiler_rt/sparc.zig")._Qp_qtoux;
509 @export(_Qp_qtoux, .{ .name = "_Qp_qtoux", .linkage = linkage });
510 const _Qp_qtos = @import("compiler_rt/sparc.zig")._Qp_qtos;
511 @export(_Qp_qtos, .{ .name = "_Qp_qtos", .linkage = linkage });
512 const _Qp_qtod = @import("compiler_rt/sparc.zig")._Qp_qtod;
513 @export(_Qp_qtod, .{ .name = "_Qp_qtod", .linkage = linkage });
514 }
515
516 if ((arch == .powerpc or arch.isPPC64()) and !is_test) {
517 @export(__addtf3, .{ .name = "__addkf3", .linkage = linkage });
518 @export(__subtf3, .{ .name = "__subkf3", .linkage = linkage });
519 @export(__multf3, .{ .name = "__mulkf3", .linkage = linkage });
520 @export(__divtf3, .{ .name = "__divkf3", .linkage = linkage });
521 @export(__extendsftf2, .{ .name = "__extendsfkf2", .linkage = linkage });
522 @export(__extenddftf2, .{ .name = "__extenddfkf2", .linkage = linkage });
523 @export(__trunctfsf2, .{ .name = "__trunckfsf2", .linkage = linkage });
524 @export(__trunctfdf2, .{ .name = "__trunckfdf2", .linkage = linkage });
525 @export(__fixtfdi, .{ .name = "__fixkfdi", .linkage = linkage });
526 @export(__fixtfsi, .{ .name = "__fixkfsi", .linkage = linkage });
527 @export(__fixunstfsi, .{ .name = "__fixunskfsi", .linkage = linkage });
528 @export(__fixunstfdi, .{ .name = "__fixunskfdi", .linkage = linkage });
529 @export(__floatsitf, .{ .name = "__floatsikf", .linkage = linkage });
530 @export(__floatditf, .{ .name = "__floatdikf", .linkage = linkage });
531 @export(__floatunditf, .{ .name = "__floatundikf", .linkage = linkage });
532 @export(__floatunsitf, .{ .name = "__floatunsikf", .linkage = linkage });
533
534 @export(__letf2, .{ .name = "__eqkf2", .linkage = linkage });
535 @export(__letf2, .{ .name = "__nekf2", .linkage = linkage });
536 @export(__getf2, .{ .name = "__gekf2", .linkage = linkage });
537 @export(__letf2, .{ .name = "__ltkf2", .linkage = linkage });
538 @export(__letf2, .{ .name = "__lekf2", .linkage = linkage });
539 @export(__getf2, .{ .name = "__gtkf2", .linkage = linkage });
540 @export(__unordtf2, .{ .name = "__unordkf2", .linkage = linkage });
541 }
542
543 if (builtin.os.tag == .windows) {
544 // Default stack-probe functions emitted by LLVM
545 if (is_mingw) {
546 const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;
547 @export(_chkstk, .{ .name = "_alloca", .linkage = strong_linkage });
548 const ___chkstk_ms = @import("compiler_rt/stack_probe.zig").___chkstk_ms;
549 @export(___chkstk_ms, .{ .name = "___chkstk_ms", .linkage = strong_linkage });
550 } else if (!builtin.link_libc) {
551 // This symbols are otherwise exported by MSVCRT.lib
552 const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;
553 @export(_chkstk, .{ .name = "_chkstk", .linkage = strong_linkage });
554 const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
555 @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
556 }
557
558 switch (arch) {
559 .i386 => {
560 const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
561 @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
562 const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
563 @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
564 const __multi3 = @import("compiler_rt/multi3.zig").__multi3;
565 @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
566 const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
567 @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
568 const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
569 @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
570 const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
571 @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
572 },
573 .x86_64 => {
574 // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
575 // that LLVM expects compiler-rt to have.
576 const __divti3_windows_x86_64 = @import("compiler_rt/divti3.zig").__divti3_windows_x86_64;
577 @export(__divti3_windows_x86_64, .{ .name = "__divti3", .linkage = linkage });
578 const __modti3_windows_x86_64 = @import("compiler_rt/modti3.zig").__modti3_windows_x86_64;
579 @export(__modti3_windows_x86_64, .{ .name = "__modti3", .linkage = linkage });
580 const __multi3_windows_x86_64 = @import("compiler_rt/multi3.zig").__multi3_windows_x86_64;
581 @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = linkage });
582 const __udivti3_windows_x86_64 = @import("compiler_rt/udivti3.zig").__udivti3_windows_x86_64;
583 @export(__udivti3_windows_x86_64, .{ .name = "__udivti3", .linkage = linkage });
584 const __udivmodti4_windows_x86_64 = @import("compiler_rt/udivmodti4.zig").__udivmodti4_windows_x86_64;
585 @export(__udivmodti4_windows_x86_64, .{ .name = "__udivmodti4", .linkage = linkage });
586 const __umodti3_windows_x86_64 = @import("compiler_rt/umodti3.zig").__umodti3_windows_x86_64;
587 @export(__umodti3_windows_x86_64, .{ .name = "__umodti3", .linkage = linkage });
588 },
589 else => {},
590 }
591 if (arch.isAARCH64()) {
592 const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
593 @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
594 const __divti3_windows = @import("compiler_rt/divti3.zig").__divti3;
595 @export(__divti3_windows, .{ .name = "__divti3", .linkage = linkage });
550 const __modti3 = @import("compiler_rt/modti3.zig").__modti3;596 const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
551 @export(__modti3, .{ .name = "__modti3", .linkage = linkage });597 @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
552 const __multi3 = @import("compiler_rt/multi3.zig").__multi3;598 const __udivti3_windows = @import("compiler_rt/udivti3.zig").__udivti3;
553 @export(__multi3, .{ .name = "__multi3", .linkage = linkage });599 @export(__udivti3_windows, .{ .name = "__udivti3", .linkage = linkage });
554 const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
555 @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
556 const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
557 @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
558 const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;600 const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
559 @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });601 @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
560 },602 }
561 .x86_64 => {603 } else {
562 // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI604 const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
563 // that LLVM expects compiler-rt to have.605 @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
564 const __divti3_windows_x86_64 = @import("compiler_rt/divti3.zig").__divti3_windows_x86_64;
565 @export(__divti3_windows_x86_64, .{ .name = "__divti3", .linkage = linkage });
566 const __modti3_windows_x86_64 = @import("compiler_rt/modti3.zig").__modti3_windows_x86_64;
567 @export(__modti3_windows_x86_64, .{ .name = "__modti3", .linkage = linkage });
568 const __multi3_windows_x86_64 = @import("compiler_rt/multi3.zig").__multi3_windows_x86_64;
569 @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = linkage });
570 const __udivti3_windows_x86_64 = @import("compiler_rt/udivti3.zig").__udivti3_windows_x86_64;
571 @export(__udivti3_windows_x86_64, .{ .name = "__udivti3", .linkage = linkage });
572 const __udivmodti4_windows_x86_64 = @import("compiler_rt/udivmodti4.zig").__udivmodti4_windows_x86_64;
573 @export(__udivmodti4_windows_x86_64, .{ .name = "__udivmodti4", .linkage = linkage });
574 const __umodti3_windows_x86_64 = @import("compiler_rt/umodti3.zig").__umodti3_windows_x86_64;
575 @export(__umodti3_windows_x86_64, .{ .name = "__umodti3", .linkage = linkage });
576 },
577 else => {},
578 }
579 if (arch.isAARCH64()) {
580 const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
581 @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
582 const __divti3_windows = @import("compiler_rt/divti3.zig").__divti3;
583 @export(__divti3_windows, .{ .name = "__divti3", .linkage = linkage });
584 const __modti3 = @import("compiler_rt/modti3.zig").__modti3;606 const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
585 @export(__modti3, .{ .name = "__modti3", .linkage = linkage });607 @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
586 const __udivti3_windows = @import("compiler_rt/udivti3.zig").__udivti3;608 const __multi3 = @import("compiler_rt/multi3.zig").__multi3;
587 @export(__udivti3_windows, .{ .name = "__udivti3", .linkage = linkage });609 @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
610 const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
611 @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
612 const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
613 @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
588 const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;614 const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
589 @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });615 @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
590 }616 }
591 } else {617 const __muloti4 = @import("compiler_rt/muloti4.zig").__muloti4;
592 const __divti3 = @import("compiler_rt/divti3.zig").__divti3;618 @export(__muloti4, .{ .name = "__muloti4", .linkage = linkage });
593 @export(__divti3, .{ .name = "__divti3", .linkage = linkage });619 const __mulodi4 = @import("compiler_rt/mulodi4.zig").__mulodi4;
594 const __modti3 = @import("compiler_rt/modti3.zig").__modti3;620 @export(__mulodi4, .{ .name = "__mulodi4", .linkage = linkage });
595 @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
596 const __multi3 = @import("compiler_rt/multi3.zig").__multi3;
597 @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
598 const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
599 @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
600 const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
601 @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
602 const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
603 @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
604 }
605 const __muloti4 = @import("compiler_rt/muloti4.zig").__muloti4;
606 @export(__muloti4, .{ .name = "__muloti4", .linkage = linkage });
607 const __mulodi4 = @import("compiler_rt/mulodi4.zig").__mulodi4;
608 @export(__mulodi4, .{ .name = "__mulodi4", .linkage = linkage });
609621
610 _ = @import("compiler_rt/atomics.zig");622 _ = @import("compiler_rt/atomics.zig");
623 }
611}624}
612625
613// Avoid dragging in the runtime safety mechanisms into this .o file,626// Avoid dragging in the runtime safety mechanisms into this .o file,
614// unless we're trying to test this file.627// unless we're trying to test this file.
615pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {628pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
616 _ = error_return_trace;629 _ = error_return_trace;
617 @setCold(true);630 @setCold(true);
631 if (builtin.zig_is_stage2) {
632 while (true) {
633 @breakpoint();
634 }
635 }
618 if (is_test) {636 if (is_test) {
619 std.debug.panic("{s}", .{msg});637 std.debug.panic("{s}", .{msg});
620 } else {638 } else {
lib/std/special/compiler_rt/extendXfYf2.zig+6-6
...@@ -3,23 +3,23 @@ const builtin = @import("builtin");...@@ -3,23 +3,23 @@ const builtin = @import("builtin");
3const is_test = builtin.is_test;3const is_test = builtin.is_test;
44
5pub fn __extendsfdf2(a: f32) callconv(.C) f64 {5pub fn __extendsfdf2(a: f32) callconv(.C) f64 {
6 return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f64, f32, @bitCast(u32, a) });6 return extendXfYf2(f64, f32, @bitCast(u32, a));
7}7}
88
9pub fn __extenddftf2(a: f64) callconv(.C) f128 {9pub fn __extenddftf2(a: f64) callconv(.C) f128 {
10 return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f128, f64, @bitCast(u64, a) });10 return extendXfYf2(f128, f64, @bitCast(u64, a));
11}11}
1212
13pub fn __extendsftf2(a: f32) callconv(.C) f128 {13pub fn __extendsftf2(a: f32) callconv(.C) f128 {
14 return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f128, f32, @bitCast(u32, a) });14 return extendXfYf2(f128, f32, @bitCast(u32, a));
15}15}
1616
17pub fn __extendhfsf2(a: u16) callconv(.C) f32 {17pub fn __extendhfsf2(a: u16) callconv(.C) f32 {
18 return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f32, f16, a });18 return extendXfYf2(f32, f16, a);
19}19}
2020
21pub fn __extendhftf2(a: u16) callconv(.C) f128 {21pub fn __extendhftf2(a: u16) callconv(.C) f128 {
22 return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f128, f16, a });22 return extendXfYf2(f128, f16, a);
23}23}
2424
25pub fn __aeabi_h2f(arg: u16) callconv(.AAPCS) f32 {25pub fn __aeabi_h2f(arg: u16) callconv(.AAPCS) f32 {
...@@ -34,7 +34,7 @@ pub fn __aeabi_f2d(arg: f32) callconv(.AAPCS) f64 {...@@ -34,7 +34,7 @@ pub fn __aeabi_f2d(arg: f32) callconv(.AAPCS) f64 {
3434
35const CHAR_BIT = 8;35const CHAR_BIT = 8;
3636
37fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits)) dst_t {37inline fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits)) dst_t {
38 @setRuntimeSafety(builtin.is_test);38 @setRuntimeSafety(builtin.is_test);
3939
40 const src_rep_t = std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits);40 const src_rep_t = std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits);
src/Air.zig+7-3
...@@ -227,9 +227,12 @@ pub const Inst = struct {...@@ -227,9 +227,12 @@ pub const Inst = struct {
227 /// Indicates the program counter will never get to this instruction.227 /// Indicates the program counter will never get to this instruction.
228 /// Result type is always noreturn; no instructions in a block follow this one.228 /// Result type is always noreturn; no instructions in a block follow this one.
229 unreach,229 unreach,
230 /// Convert from one float type to another.230 /// Convert from a float type to a smaller one.
231 /// Uses the `ty_op` field.231 /// Uses the `ty_op` field.
232 floatcast,232 fptrunc,
233 /// Convert from a float type to a wider one.
234 /// Uses the `ty_op` field.
235 fpext,
233 /// Returns an integer with a different type than the operand. The new type may have236 /// Returns an integer with a different type than the operand. The new type may have
234 /// fewer, the same, or more bits than the operand type. However, the instruction237 /// fewer, the same, or more bits than the operand type. However, the instruction
235 /// guarantees that the same integer value fits in both types.238 /// guarantees that the same integer value fits in both types.
...@@ -586,7 +589,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -586,7 +589,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
586 .not,589 .not,
587 .bitcast,590 .bitcast,
588 .load,591 .load,
589 .floatcast,592 .fpext,
593 .fptrunc,
590 .intcast,594 .intcast,
591 .trunc,595 .trunc,
592 .optional_payload,596 .optional_payload,
src/AstGen.zig+49-25
...@@ -2166,6 +2166,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner...@@ -2166,6 +2166,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
2166 .ensure_result_used,2166 .ensure_result_used,
2167 .ensure_result_non_error,2167 .ensure_result_non_error,
2168 .@"export",2168 .@"export",
2169 .export_value,
2169 .set_eval_branch_quota,2170 .set_eval_branch_quota,
2170 .ensure_err_payload_void,2171 .ensure_err_payload_void,
2171 .atomic_store,2172 .atomic_store,
...@@ -7095,32 +7096,55 @@ fn builtinCall(...@@ -7095,32 +7096,55 @@ fn builtinCall(
7095 .identifier => {7096 .identifier => {
7096 const ident_token = main_tokens[params[0]];7097 const ident_token = main_tokens[params[0]];
7097 decl_name = try astgen.identAsString(ident_token);7098 decl_name = try astgen.identAsString(ident_token);
7098 {7099
7099 var s = scope;7100 var s = scope;
7100 while (true) switch (s.tag) {7101 var found_already: ?Ast.Node.Index = null; // we have found a decl with the same name already
7101 .local_val => {7102 while (true) switch (s.tag) {
7102 const local_val = s.cast(Scope.LocalVal).?;7103 .local_val => {
7103 if (local_val.name == decl_name) {7104 const local_val = s.cast(Scope.LocalVal).?;
7104 local_val.used = true;7105 if (local_val.name == decl_name) {
7105 break;7106 local_val.used = true;
7106 }7107 _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{
7107 s = local_val.parent;7108 .operand = local_val.inst,
7108 },7109 .options = try comptimeExpr(gz, scope, .{ .coerced_ty = .export_options_type }, params[1]),
7109 .local_ptr => {7110 });
7110 const local_ptr = s.cast(Scope.LocalPtr).?;7111 return rvalue(gz, rl, .void_value, node);
7111 if (local_ptr.name == decl_name) {7112 }
7112 if (!local_ptr.maybe_comptime)7113 s = local_val.parent;
7113 return astgen.failNode(params[0], "unable to export runtime-known value", .{});7114 },
7114 local_ptr.used = true;7115 .local_ptr => {
7115 break;7116 const local_ptr = s.cast(Scope.LocalPtr).?;
7117 if (local_ptr.name == decl_name) {
7118 if (!local_ptr.maybe_comptime)
7119 return astgen.failNode(params[0], "unable to export runtime-known value", .{});
7120 local_ptr.used = true;
7121 const loaded = try gz.addUnNode(.load, local_ptr.ptr, node);
7122 _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{
7123 .operand = loaded,
7124 .options = try comptimeExpr(gz, scope, .{ .coerced_ty = .export_options_type }, params[1]),
7125 });
7126 return rvalue(gz, rl, .void_value, node);
7127 }
7128 s = local_ptr.parent;
7129 },
7130 .gen_zir => s = s.cast(GenZir).?.parent,
7131 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
7132 .namespace => {
7133 const ns = s.cast(Scope.Namespace).?;
7134 if (ns.decls.get(decl_name)) |i| {
7135 if (found_already) |f| {
7136 return astgen.failNodeNotes(node, "ambiguous reference", .{}, &.{
7137 try astgen.errNoteNode(f, "declared here", .{}),
7138 try astgen.errNoteNode(i, "also declared here", .{}),
7139 });
7116 }7140 }
7117 s = local_ptr.parent;7141 // We found a match but must continue looking for ambiguous references to decls.
7118 },7142 found_already = i;
7119 .gen_zir => s = s.cast(GenZir).?.parent,7143 }
7120 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,7144 s = ns.parent;
7121 .namespace, .top => break,7145 },
7122 };7146 .top => break,
7123 }7147 };
7124 },7148 },
7125 .field_access => {7149 .field_access => {
7126 const namespace_node = node_datas[params[0]].lhs;7150 const namespace_node = node_datas[params[0]].lhs;
src/Liveness.zig+2-1
...@@ -274,7 +274,8 @@ fn analyzeInst(...@@ -274,7 +274,8 @@ fn analyzeInst(
274 .not,274 .not,
275 .bitcast,275 .bitcast,
276 .load,276 .load,
277 .floatcast,277 .fpext,
278 .fptrunc,
278 .intcast,279 .intcast,
279 .trunc,280 .trunc,
280 .optional_payload,281 .optional_payload,
src/Module.zig+27-15
...@@ -2389,6 +2389,7 @@ pub fn deinit(mod: *Module) void {...@@ -2389,6 +2389,7 @@ pub fn deinit(mod: *Module) void {
2389fn freeExportList(gpa: *Allocator, export_list: []*Export) void {2389fn freeExportList(gpa: *Allocator, export_list: []*Export) void {
2390 for (export_list) |exp| {2390 for (export_list) |exp| {
2391 gpa.free(exp.options.name);2391 gpa.free(exp.options.name);
2392 if (exp.options.section) |s| gpa.free(s);
2392 gpa.destroy(exp);2393 gpa.destroy(exp);
2393 }2394 }
2394 gpa.free(export_list);2395 gpa.free(export_list);
...@@ -3317,7 +3318,8 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3317,7 +3318,8 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3317 return mod.fail(&block_scope.base, export_src, "export of inline function", .{});3318 return mod.fail(&block_scope.base, export_src, "export of inline function", .{});
3318 }3319 }
3319 // The scope needs to have the decl in it.3320 // The scope needs to have the decl in it.
3320 try mod.analyzeExport(&block_scope.base, export_src, mem.spanZ(decl.name), decl);3321 const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
3322 try mod.analyzeExport(&block_scope.base, export_src, options, decl);
3321 }3323 }
3322 return type_changed or is_inline != prev_is_inline;3324 return type_changed or is_inline != prev_is_inline;
3323 }3325 }
...@@ -3376,7 +3378,8 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3376,7 +3378,8 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3376 if (decl.is_exported) {3378 if (decl.is_exported) {
3377 const export_src = src; // TODO point to the export token3379 const export_src = src; // TODO point to the export token
3378 // The scope needs to have the decl in it.3380 // The scope needs to have the decl in it.
3379 try mod.analyzeExport(&block_scope.base, export_src, mem.spanZ(decl.name), decl);3381 const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
3382 try mod.analyzeExport(&block_scope.base, export_src, options, decl);
3380 }3383 }
33813384
3382 return type_changed;3385 return type_changed;
...@@ -4119,7 +4122,7 @@ pub fn analyzeExport(...@@ -4119,7 +4122,7 @@ pub fn analyzeExport(
4119 mod: *Module,4122 mod: *Module,
4120 scope: *Scope,4123 scope: *Scope,
4121 src: LazySrcLoc,4124 src: LazySrcLoc,
4122 borrowed_symbol_name: []const u8,4125 borrowed_options: std.builtin.ExportOptions,
4123 exported_decl: *Decl,4126 exported_decl: *Decl,
4124) !void {4127) !void {
4125 try mod.ensureDeclAnalyzed(exported_decl);4128 try mod.ensureDeclAnalyzed(exported_decl);
...@@ -4128,23 +4131,32 @@ pub fn analyzeExport(...@@ -4128,23 +4131,32 @@ pub fn analyzeExport(
4128 else => return mod.fail(scope, src, "unable to export type '{}'", .{exported_decl.ty}),4131 else => return mod.fail(scope, src, "unable to export type '{}'", .{exported_decl.ty}),
4129 }4132 }
41304133
4131 try mod.decl_exports.ensureUnusedCapacity(mod.gpa, 1);4134 const gpa = mod.gpa;
4132 try mod.export_owners.ensureUnusedCapacity(mod.gpa, 1);4135
4136 try mod.decl_exports.ensureUnusedCapacity(gpa, 1);
4137 try mod.export_owners.ensureUnusedCapacity(gpa, 1);
41334138
4134 const new_export = try mod.gpa.create(Export);4139 const new_export = try gpa.create(Export);
4135 errdefer mod.gpa.destroy(new_export);4140 errdefer gpa.destroy(new_export);
41364141
4137 const symbol_name = try mod.gpa.dupe(u8, borrowed_symbol_name);4142 const symbol_name = try gpa.dupe(u8, borrowed_options.name);
4138 errdefer mod.gpa.free(symbol_name);4143 errdefer gpa.free(symbol_name);
4144
4145 const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null;
4146 errdefer if (section) |s| gpa.free(s);
41394147
4140 const owner_decl = scope.ownerDecl().?;4148 const owner_decl = scope.ownerDecl().?;
41414149
4142 log.debug("exporting Decl '{s}' as symbol '{s}' from Decl '{s}'", .{4150 log.debug("exporting Decl '{s}' as symbol '{s}' from Decl '{s}'", .{
4143 exported_decl.name, borrowed_symbol_name, owner_decl.name,4151 exported_decl.name, symbol_name, owner_decl.name,
4144 });4152 });
41454153
4146 new_export.* = .{4154 new_export.* = .{
4147 .options = .{ .name = symbol_name },4155 .options = .{
4156 .name = symbol_name,
4157 .linkage = borrowed_options.linkage,
4158 .section = section,
4159 },
4148 .src = src,4160 .src = src,
4149 .link = switch (mod.comp.bin_file.tag) {4161 .link = switch (mod.comp.bin_file.tag) {
4150 .coff => .{ .coff = {} },4162 .coff => .{ .coff = {} },
...@@ -4165,18 +4177,18 @@ pub fn analyzeExport(...@@ -4165,18 +4177,18 @@ pub fn analyzeExport(
4165 if (!eo_gop.found_existing) {4177 if (!eo_gop.found_existing) {
4166 eo_gop.value_ptr.* = &[0]*Export{};4178 eo_gop.value_ptr.* = &[0]*Export{};
4167 }4179 }
4168 eo_gop.value_ptr.* = try mod.gpa.realloc(eo_gop.value_ptr.*, eo_gop.value_ptr.len + 1);4180 eo_gop.value_ptr.* = try gpa.realloc(eo_gop.value_ptr.*, eo_gop.value_ptr.len + 1);
4169 eo_gop.value_ptr.*[eo_gop.value_ptr.len - 1] = new_export;4181 eo_gop.value_ptr.*[eo_gop.value_ptr.len - 1] = new_export;
4170 errdefer eo_gop.value_ptr.* = mod.gpa.shrink(eo_gop.value_ptr.*, eo_gop.value_ptr.len - 1);4182 errdefer eo_gop.value_ptr.* = gpa.shrink(eo_gop.value_ptr.*, eo_gop.value_ptr.len - 1);
41714183
4172 // Add to exported_decl table.4184 // Add to exported_decl table.
4173 const de_gop = mod.decl_exports.getOrPutAssumeCapacity(exported_decl);4185 const de_gop = mod.decl_exports.getOrPutAssumeCapacity(exported_decl);
4174 if (!de_gop.found_existing) {4186 if (!de_gop.found_existing) {
4175 de_gop.value_ptr.* = &[0]*Export{};4187 de_gop.value_ptr.* = &[0]*Export{};
4176 }4188 }
4177 de_gop.value_ptr.* = try mod.gpa.realloc(de_gop.value_ptr.*, de_gop.value_ptr.len + 1);4189 de_gop.value_ptr.* = try gpa.realloc(de_gop.value_ptr.*, de_gop.value_ptr.len + 1);
4178 de_gop.value_ptr.*[de_gop.value_ptr.len - 1] = new_export;4190 de_gop.value_ptr.*[de_gop.value_ptr.len - 1] = new_export;
4179 errdefer de_gop.value_ptr.* = mod.gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1);4191 errdefer de_gop.value_ptr.* = gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1);
4180}4192}
41814193
4182/// Takes ownership of `name` even if it returns an error.4194/// Takes ownership of `name` even if it returns an error.
src/Sema.zig+97-39
...@@ -458,6 +458,11 @@ pub fn analyzeBody(...@@ -458,6 +458,11 @@ pub fn analyzeBody(
458 i += 1;458 i += 1;
459 continue;459 continue;
460 },460 },
461 .export_value => {
462 try sema.zirExportValue(block, inst);
463 i += 1;
464 continue;
465 },
461 .set_align_stack => {466 .set_align_stack => {
462 try sema.zirSetAlignStack(block, inst);467 try sema.zirSetAlignStack(block, inst);
463 i += 1;468 i += 1;
...@@ -2392,30 +2397,33 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro...@@ -2392,30 +2397,33 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
2392 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;2397 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2393 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;2398 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
2394 const src = inst_data.src();2399 const src = inst_data.src();
2395 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };2400 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
2396 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };2401 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
2397 const decl_name = sema.code.nullTerminatedString(extra.decl_name);2402 const decl_name = sema.code.nullTerminatedString(extra.decl_name);
2398 if (extra.namespace != .none) {2403 if (extra.namespace != .none) {
2399 return sema.mod.fail(&block.base, src, "TODO: implement exporting with field access", .{});2404 return sema.mod.fail(&block.base, src, "TODO: implement exporting with field access", .{});
2400 }2405 }
2401 const decl = try sema.lookupIdentifier(block, lhs_src, decl_name);2406 const decl = try sema.lookupIdentifier(block, operand_src, decl_name);
2402 const options = try sema.resolveInstConst(block, rhs_src, extra.options);2407 const options = try sema.resolveExportOptions(block, options_src, extra.options);
2403 const struct_obj = options.ty.castTag(.@"struct").?.data;2408 try sema.mod.analyzeExport(&block.base, src, options, decl);
2404 const fields = options.val.castTag(.@"struct").?.data[0..struct_obj.fields.count()];2409}
2405 const name_index = struct_obj.fields.getIndex("name").?;
2406 const linkage_index = struct_obj.fields.getIndex("linkage").?;
2407 const section_index = struct_obj.fields.getIndex("section").?;
2408 const export_name = try fields[name_index].toAllocatedBytes(sema.arena);
2409 const linkage = fields[linkage_index].toEnum(std.builtin.GlobalLinkage);
24102410
2411 if (linkage != .Strong) {2411fn zirExportValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {
2412 return sema.mod.fail(&block.base, src, "TODO: implement exporting with non-strong linkage", .{});2412 const tracy = trace(@src());
2413 }2413 defer tracy.end();
2414 if (!fields[section_index].isNull()) {
2415 return sema.mod.fail(&block.base, src, "TODO: implement exporting with linksection", .{});
2416 }
24172414
2418 try sema.mod.analyzeExport(&block.base, src, export_name, decl);2415 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2416 const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;
2417 const src = inst_data.src();
2418 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
2419 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
2420 const operand = try sema.resolveInstConst(block, operand_src, extra.operand);
2421 const options = try sema.resolveExportOptions(block, options_src, extra.options);
2422 const decl = switch (operand.val.tag()) {
2423 .function => operand.val.castTag(.function).?.data.owner_decl,
2424 else => return sema.mod.fail(&block.base, operand_src, "TODO implement exporting arbitrary Value objects", .{}), // TODO put this Value into an anonymous Decl and then export it.
2425 };
2426 try sema.mod.analyzeExport(&block.base, src, options, decl);
2419}2427}
24202428
2421fn zirSetAlignStack(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {2429fn zirSetAlignStack(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {
...@@ -4516,11 +4524,18 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE...@@ -4516,11 +4524,18 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
45164524
4517 if (try sema.isComptimeKnown(block, operand_src, operand)) {4525 if (try sema.isComptimeKnown(block, operand_src, operand)) {
4518 return sema.coerce(block, dest_type, operand, operand_src);4526 return sema.coerce(block, dest_type, operand, operand_src);
4519 } else if (dest_is_comptime_float) {4527 }
4528 if (dest_is_comptime_float) {
4520 return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_float'", .{});4529 return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_float'", .{});
4521 }4530 }
45224531 const target = sema.mod.getTarget();
4523 return sema.mod.fail(&block.base, src, "TODO implement analyze widen or shorten float", .{});4532 const src_bits = operand_ty.floatBits(target);
4533 const dst_bits = dest_type.floatBits(target);
4534 if (dst_bits >= src_bits) {
4535 return sema.coerce(block, dest_type, operand, operand_src);
4536 }
4537 try sema.requireRuntimeBlock(block, operand_src);
4538 return block.addTyOp(.fptrunc, dest_type, operand);
4524}4539}
45254540
4526fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4541fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -7936,6 +7951,31 @@ fn checkAtomicOperandType(...@@ -7936,6 +7951,31 @@ fn checkAtomicOperandType(
7936 }7951 }
7937}7952}
79387953
7954fn resolveExportOptions(
7955 sema: *Sema,
7956 block: *Scope.Block,
7957 src: LazySrcLoc,
7958 zir_ref: Zir.Inst.Ref,
7959) CompileError!std.builtin.ExportOptions {
7960 const export_options_ty = try sema.getBuiltinType(block, src, "ExportOptions");
7961 const air_ref = sema.resolveInst(zir_ref);
7962 const coerced = try sema.coerce(block, export_options_ty, air_ref, src);
7963 const val = try sema.resolveConstValue(block, src, coerced);
7964 const fields = val.castTag(.@"struct").?.data;
7965 const struct_obj = export_options_ty.castTag(.@"struct").?.data;
7966 const name_index = struct_obj.fields.getIndex("name").?;
7967 const linkage_index = struct_obj.fields.getIndex("linkage").?;
7968 const section_index = struct_obj.fields.getIndex("section").?;
7969 if (!fields[section_index].isNull()) {
7970 return sema.mod.fail(&block.base, src, "TODO: implement exporting with linksection", .{});
7971 }
7972 return std.builtin.ExportOptions{
7973 .name = try fields[name_index].toAllocatedBytes(sema.arena),
7974 .linkage = fields[linkage_index].toEnum(std.builtin.GlobalLinkage),
7975 .section = null, // TODO
7976 };
7977}
7978
7939fn resolveAtomicOrder(7979fn resolveAtomicOrder(
7940 sema: *Sema,7980 sema: *Sema,
7941 block: *Scope.Block,7981 block: *Scope.Block,
...@@ -9581,7 +9621,7 @@ fn coerce(...@@ -9581,7 +9621,7 @@ fn coerce(
9581 const dst_bits = dest_type.floatBits(target);9621 const dst_bits = dest_type.floatBits(target);
9582 if (dst_bits >= src_bits) {9622 if (dst_bits >= src_bits) {
9583 try sema.requireRuntimeBlock(block, inst_src);9623 try sema.requireRuntimeBlock(block, inst_src);
9584 return block.addTyOp(.floatcast, dest_type, inst);9624 return block.addTyOp(.fpext, dest_type, inst);
9585 }9625 }
9586 }9626 }
9587 },9627 },
...@@ -9729,35 +9769,53 @@ fn coerceNum(...@@ -9729,35 +9769,53 @@ fn coerceNum(
9729 const target = sema.mod.getTarget();9769 const target = sema.mod.getTarget();
97309770
9731 switch (dst_zig_tag) {9771 switch (dst_zig_tag) {
9732 .ComptimeInt, .Int => {9772 .ComptimeInt, .Int => switch (src_zig_tag) {
9733 if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {9773 .Float, .ComptimeFloat => {
9734 if (val.floatHasFraction()) {9774 if (val.floatHasFraction()) {
9735 return sema.mod.fail(&block.base, inst_src, "fractional component prevents float value {} from being casted to type '{}'", .{ val, inst_ty });9775 return sema.mod.fail(&block.base, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val, dest_type });
9736 }9776 }
9737 return sema.mod.fail(&block.base, inst_src, "TODO float to int", .{});9777 return sema.mod.fail(&block.base, inst_src, "TODO float to int", .{});
9738 } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {9778 },
9779 .Int, .ComptimeInt => {
9739 if (!val.intFitsInType(dest_type, target)) {9780 if (!val.intFitsInType(dest_type, target)) {
9740 return sema.mod.fail(&block.base, inst_src, "type {} cannot represent integer value {}", .{ dest_type, val });9781 return sema.mod.fail(&block.base, inst_src, "type {} cannot represent integer value {}", .{ dest_type, val });
9741 }9782 }
9742 return try sema.addConstant(dest_type, val);9783 return try sema.addConstant(dest_type, val);
9743 }9784 },
9785 else => {},
9744 },9786 },
9745 .ComptimeFloat, .Float => {9787 .ComptimeFloat, .Float => switch (src_zig_tag) {
9746 if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {9788 .ComptimeFloat => {
9747 const res = val.floatCast(sema.arena, dest_type) catch |err| switch (err) {9789 const result_val = try val.floatCast(sema.arena, dest_type);
9748 error.Overflow => return sema.mod.fail(9790 return try sema.addConstant(dest_type, result_val);
9791 },
9792 .Float => {
9793 const result_val = try val.floatCast(sema.arena, dest_type);
9794 if (!val.eql(result_val, dest_type)) {
9795 return sema.mod.fail(
9749 &block.base,9796 &block.base,
9750 inst_src,9797 inst_src,
9751 "cast of value {} to type '{}' loses information",9798 "type {} cannot represent float value {}",
9752 .{ val, dest_type },9799 .{ dest_type, val },
9753 ),9800 );
9754 error.OutOfMemory => return error.OutOfMemory,9801 }
9755 };9802 return try sema.addConstant(dest_type, result_val);
9756 return try sema.addConstant(dest_type, res);9803 },
9757 } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {9804 .Int, .ComptimeInt => {
9758 const result_val = try val.intToFloat(sema.arena, dest_type, target);9805 const result_val = try val.intToFloat(sema.arena, dest_type, target);
9806 // TODO implement this compile error
9807 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);
9808 //if (!int_again_val.eql(val, inst_ty)) {
9809 // return sema.mod.fail(
9810 // &block.base,
9811 // inst_src,
9812 // "type {} cannot represent integer value {}",
9813 // .{ dest_type, val },
9814 // );
9815 //}
9759 return try sema.addConstant(dest_type, result_val);9816 return try sema.addConstant(dest_type, result_val);
9760 }9817 },
9818 else => {},
9761 },9819 },
9762 else => {},9820 else => {},
9763 }9821 }
src/Zir.zig+13-1
...@@ -319,9 +319,13 @@ pub const Inst = struct {...@@ -319,9 +319,13 @@ pub const Inst = struct {
319 /// `error.Foo` syntax. Uses the `str_tok` field of the Data union.319 /// `error.Foo` syntax. Uses the `str_tok` field of the Data union.
320 error_value,320 error_value,
321 /// Implements the `@export` builtin function, based on either an identifier to a Decl,321 /// Implements the `@export` builtin function, based on either an identifier to a Decl,
322 /// or field access of a Decl.322 /// or field access of a Decl. The thing being exported is the Decl.
323 /// Uses the `pl_node` union field. Payload is `Export`.323 /// Uses the `pl_node` union field. Payload is `Export`.
324 @"export",324 @"export",
325 /// Implements the `@export` builtin function, based on a comptime-known value.
326 /// The thing being exported is the comptime-known value which is the operand.
327 /// Uses the `pl_node` union field. Payload is `ExportValue`.
328 export_value,
325 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer329 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer
326 /// to the named field. The field name is stored in string_bytes. Used by a.b syntax.330 /// to the named field. The field name is stored in string_bytes. Used by a.b syntax.
327 /// Uses `pl_node` field. The AST node is the a.b syntax. Payload is Field.331 /// Uses `pl_node` field. The AST node is the a.b syntax. Payload is Field.
...@@ -1010,6 +1014,7 @@ pub const Inst = struct {...@@ -1010,6 +1014,7 @@ pub const Inst = struct {
1010 .ensure_result_used,1014 .ensure_result_used,
1011 .ensure_result_non_error,1015 .ensure_result_non_error,
1012 .@"export",1016 .@"export",
1017 .export_value,
1013 .field_ptr,1018 .field_ptr,
1014 .field_val,1019 .field_val,
1015 .field_ptr_named,1020 .field_ptr_named,
...@@ -1273,6 +1278,7 @@ pub const Inst = struct {...@@ -1273,6 +1278,7 @@ pub const Inst = struct {
1273 .error_union_type = .pl_node,1278 .error_union_type = .pl_node,
1274 .error_value = .str_tok,1279 .error_value = .str_tok,
1275 .@"export" = .pl_node,1280 .@"export" = .pl_node,
1281 .export_value = .pl_node,
1276 .field_ptr = .pl_node,1282 .field_ptr = .pl_node,
1277 .field_val = .pl_node,1283 .field_val = .pl_node,
1278 .field_ptr_named = .pl_node,1284 .field_ptr_named = .pl_node,
...@@ -2843,6 +2849,12 @@ pub const Inst = struct {...@@ -2843,6 +2849,12 @@ pub const Inst = struct {
2843 options: Ref,2849 options: Ref,
2844 };2850 };
28452851
2852 pub const ExportValue = struct {
2853 /// The comptime value to export.
2854 operand: Ref,
2855 options: Ref,
2856 };
2857
2846 /// Trailing: `CompileErrors.Item` for each `items_len`.2858 /// Trailing: `CompileErrors.Item` for each `items_len`.
2847 pub const CompileErrors = struct {2859 pub const CompileErrors = struct {
2848 items_len: u32,2860 items_len: u32,
src/codegen.zig+12-3
...@@ -859,7 +859,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -859,7 +859,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
859 .call => try self.airCall(inst),859 .call => try self.airCall(inst),
860 .cond_br => try self.airCondBr(inst),860 .cond_br => try self.airCondBr(inst),
861 .dbg_stmt => try self.airDbgStmt(inst),861 .dbg_stmt => try self.airDbgStmt(inst),
862 .floatcast => try self.airFloatCast(inst),862 .fptrunc => try self.airFptrunc(inst),
863 .fpext => try self.airFpext(inst),
863 .intcast => try self.airIntCast(inst),864 .intcast => try self.airIntCast(inst),
864 .trunc => try self.airTrunc(inst),865 .trunc => try self.airTrunc(inst),
865 .bool_to_int => try self.airBoolToInt(inst),866 .bool_to_int => try self.airBoolToInt(inst),
...@@ -1172,10 +1173,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1172,10 +1173,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1172 return self.finishAir(inst, .{ .ptr_stack_offset = stack_offset }, .{ .none, .none, .none });1173 return self.finishAir(inst, .{ .ptr_stack_offset = stack_offset }, .{ .none, .none, .none });
1173 }1174 }
11741175
1175 fn airFloatCast(self: *Self, inst: Air.Inst.Index) !void {1176 fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
1176 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1177 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1177 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {1178 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {
1178 else => return self.fail("TODO implement floatCast for {}", .{self.target.cpu.arch}),1179 else => return self.fail("TODO implement airFptrunc for {}", .{self.target.cpu.arch}),
1180 };
1181 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1182 }
1183
1184 fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
1185 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1186 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {
1187 else => return self.fail("TODO implement airFpext for {}", .{self.target.cpu.arch}),
1179 };1188 };
1180 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1189 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1181 }1190 }
src/codegen/c.zig+6-4
...@@ -954,7 +954,12 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -954,7 +954,12 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
954 .atomic_rmw => try airAtomicRmw(f, inst),954 .atomic_rmw => try airAtomicRmw(f, inst),
955 .atomic_load => try airAtomicLoad(f, inst),955 .atomic_load => try airAtomicLoad(f, inst),
956956
957 .int_to_float, .float_to_int => try airSimpleCast(f, inst),957 .int_to_float,
958 .float_to_int,
959 .fptrunc,
960 .fpext,
961 .ptrtoint,
962 => try airSimpleCast(f, inst),
958963
959 .atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.Unordered)),964 .atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.Unordered)),
960 .atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.Monotonic)),965 .atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.Monotonic)),
...@@ -982,9 +987,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -982,9 +987,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
982 .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),987 .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),
983 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),988 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),
984 .wrap_errunion_err => try airWrapErrUnionErr(f, inst),989 .wrap_errunion_err => try airWrapErrUnionErr(f, inst),
985
986 .ptrtoint => return f.fail("TODO: C backend: implement codegen for ptrtoint", .{}),
987 .floatcast => return f.fail("TODO: C backend: implement codegen for floatcast", .{}),
988 // zig fmt: on990 // zig fmt: on
989 };991 };
990 switch (result_value) {992 switch (result_value) {
src/codegen/llvm.zig+31-5
...@@ -472,7 +472,18 @@ pub const Object = struct {...@@ -472,7 +472,18 @@ pub const Object = struct {
472 alias.setAliasee(llvm_fn);472 alias.setAliasee(llvm_fn);
473 } else {473 } else {
474 const alias = self.llvm_module.addAlias(llvm_fn.typeOf(), llvm_fn, exp_name_z);474 const alias = self.llvm_module.addAlias(llvm_fn.typeOf(), llvm_fn, exp_name_z);
475 _ = alias;475 switch (exp.options.linkage) {
476 .Internal => alias.setLinkage(.Internal),
477 .Strong => alias.setLinkage(.External),
478 .Weak => {
479 if (is_extern) {
480 alias.setLinkage(.ExternalWeak);
481 } else {
482 alias.setLinkage(.WeakODR);
483 }
484 },
485 .LinkOnce => alias.setLinkage(.LinkOnceODR),
486 }
476 }487 }
477 }488 }
478 }489 }
...@@ -1137,7 +1148,8 @@ pub const FuncGen = struct {...@@ -1137,7 +1148,8 @@ pub const FuncGen = struct {
1137 .cond_br => try self.airCondBr(inst),1148 .cond_br => try self.airCondBr(inst),
1138 .intcast => try self.airIntCast(inst),1149 .intcast => try self.airIntCast(inst),
1139 .trunc => try self.airTrunc(inst),1150 .trunc => try self.airTrunc(inst),
1140 .floatcast => try self.airFloatCast(inst),1151 .fptrunc => try self.airFptrunc(inst),
1152 .fpext => try self.airFpext(inst),
1141 .ptrtoint => try self.airPtrToInt(inst),1153 .ptrtoint => try self.airPtrToInt(inst),
1142 .load => try self.airLoad(inst),1154 .load => try self.airLoad(inst),
1143 .loop => try self.airLoop(inst),1155 .loop => try self.airLoop(inst),
...@@ -2060,12 +2072,26 @@ pub const FuncGen = struct {...@@ -2060,12 +2072,26 @@ pub const FuncGen = struct {
2060 return self.builder.buildTrunc(operand, dest_llvm_ty, "");2072 return self.builder.buildTrunc(operand, dest_llvm_ty, "");
2061 }2073 }
20622074
2063 fn airFloatCast(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {2075 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
2064 if (self.liveness.isUnused(inst))2076 if (self.liveness.isUnused(inst))
2065 return null;2077 return null;
20662078
2067 // TODO split floatcast AIR into float_widen and float_shorten2079 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2068 return self.todo("implement 'airFloatCast'", .{});2080 const operand = try self.resolveInst(ty_op.operand);
2081 const dest_llvm_ty = try self.dg.llvmType(self.air.typeOfIndex(inst));
2082
2083 return self.builder.buildFPTrunc(operand, dest_llvm_ty, "");
2084 }
2085
2086 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
2087 if (self.liveness.isUnused(inst))
2088 return null;
2089
2090 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2091 const operand = try self.resolveInst(ty_op.operand);
2092 const dest_llvm_ty = try self.dg.llvmType(self.air.typeOfIndex(inst));
2093
2094 return self.builder.buildFPExt(operand, dest_llvm_ty, "");
2069 }2095 }
20702096
2071 fn airPtrToInt(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {2097 fn airPtrToInt(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
src/codegen/llvm/bindings.zig+16
...@@ -601,6 +601,22 @@ pub const Builder = opaque {...@@ -601,6 +601,22 @@ pub const Builder = opaque {
601 DestTy: *const Type,601 DestTy: *const Type,
602 Name: [*:0]const u8,602 Name: [*:0]const u8,
603 ) *const Value;603 ) *const Value;
604
605 pub const buildFPTrunc = LLVMBuildFPTrunc;
606 extern fn LLVMBuildFPTrunc(
607 *const Builder,
608 Val: *const Value,
609 DestTy: *const Type,
610 Name: [*:0]const u8,
611 ) *const Value;
612
613 pub const buildFPExt = LLVMBuildFPExt;
614 extern fn LLVMBuildFPExt(
615 *const Builder,
616 Val: *const Value,
617 DestTy: *const Type,
618 Name: [*:0]const u8,
619 ) *const Value;
604};620};
605621
606pub const IntPredicate = enum(c_uint) {622pub const IntPredicate = enum(c_uint) {
src/print_air.zig+2-1
...@@ -156,7 +156,8 @@ const Writer = struct {...@@ -156,7 +156,8 @@ const Writer = struct {
156 .not,156 .not,
157 .bitcast,157 .bitcast,
158 .load,158 .load,
159 .floatcast,159 .fptrunc,
160 .fpext,
160 .intcast,161 .intcast,
161 .trunc,162 .trunc,
162 .optional_payload,163 .optional_payload,
src/print_zir.zig+12
...@@ -285,6 +285,7 @@ const Writer = struct {...@@ -285,6 +285,7 @@ const Writer = struct {
285 => try self.writePlNodeBin(stream, inst),285 => try self.writePlNodeBin(stream, inst),
286286
287 .@"export" => try self.writePlNodeExport(stream, inst),287 .@"export" => try self.writePlNodeExport(stream, inst),
288 .export_value => try self.writePlNodeExportValue(stream, inst),
288289
289 .call,290 .call,
290 .call_chkused,291 .call_chkused,
...@@ -611,6 +612,17 @@ const Writer = struct {...@@ -611,6 +612,17 @@ const Writer = struct {
611 try self.writeSrc(stream, inst_data.src());612 try self.writeSrc(stream, inst_data.src());
612 }613 }
613614
615 fn writePlNodeExportValue(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
616 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
617 const extra = self.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;
618
619 try self.writeInstRef(stream, extra.operand);
620 try stream.writeAll(", ");
621 try self.writeInstRef(stream, extra.options);
622 try stream.writeAll(") ");
623 try self.writeSrc(stream, inst_data.src());
624 }
625
614 fn writeStructInit(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {626 fn writeStructInit(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
615 const inst_data = self.code.instructions.items(.data)[inst].pl_node;627 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
616 const extra = self.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);628 const extra = self.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);
src/stage1/codegen.cpp+1
...@@ -9325,6 +9325,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -9325,6 +9325,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
9325 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));9325 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
9326 buf_appendf(contents, "pub const abi = std.Target.Abi.%s;\n", cur_abi);9326 buf_appendf(contents, "pub const abi = std.Target.Abi.%s;\n", cur_abi);
9327 buf_appendf(contents, "pub const cpu = std.Target.Cpu.baseline(.%s);\n", cur_arch);9327 buf_appendf(contents, "pub const cpu = std.Target.Cpu.baseline(.%s);\n", cur_arch);
9328 buf_appendf(contents, "pub const stage2_arch: std.Target.Cpu.Arch = .%s;\n", cur_arch);
9328 buf_appendf(contents, "pub const os = std.Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os);9329 buf_appendf(contents, "pub const os = std.Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os);
9329 buf_appendf(contents,9330 buf_appendf(contents,
9330 "pub const target = std.Target{\n"9331 "pub const target = std.Target{\n"
src/value.zig+7-22
...@@ -1041,30 +1041,15 @@ pub const Value = extern union {...@@ -1041,30 +1041,15 @@ pub const Value = extern union {
1041 }1041 }
1042 }1042 }
10431043
1044 /// Converts an integer or a float to a float.1044 /// Converts an integer or a float to a float. May result in a loss of information.
1045 /// Returns `error.Overflow` if the value does not fit in the new type.1045 /// Caller can find out by equality checking the result against the operand.
1046 pub fn floatCast(self: Value, allocator: *Allocator, dest_ty: Type) !Value {1046 pub fn floatCast(self: Value, arena: *Allocator, dest_ty: Type) !Value {
1047 switch (dest_ty.tag()) {1047 switch (dest_ty.tag()) {
1048 .f16 => {1048 .f16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)),
1049 const res = try Value.Tag.float_16.create(allocator, self.toFloat(f16));1049 .f32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)),
1050 if (!self.eql(res, dest_ty))1050 .f64 => return Value.Tag.float_64.create(arena, self.toFloat(f64)),
1051 return error.Overflow;
1052 return res;
1053 },
1054 .f32 => {
1055 const res = try Value.Tag.float_32.create(allocator, self.toFloat(f32));
1056 if (!self.eql(res, dest_ty))
1057 return error.Overflow;
1058 return res;
1059 },
1060 .f64 => {
1061 const res = try Value.Tag.float_64.create(allocator, self.toFloat(f64));
1062 if (!self.eql(res, dest_ty))
1063 return error.Overflow;
1064 return res;
1065 },
1066 .f128, .comptime_float, .c_longdouble => {1051 .f128, .comptime_float, .c_longdouble => {
1067 return Value.Tag.float_128.create(allocator, self.toFloat(f128));1052 return Value.Tag.float_128.create(arena, self.toFloat(f128));
1068 },1053 },
1069 else => unreachable,1054 else => unreachable,
1070 }1055 }
test/behavior.zig+2-2
...@@ -13,6 +13,7 @@ test {...@@ -13,6 +13,7 @@ test {
13 _ = @import("behavior/atomics.zig");13 _ = @import("behavior/atomics.zig");
14 _ = @import("behavior/sizeof_and_typeof.zig");14 _ = @import("behavior/sizeof_and_typeof.zig");
15 _ = @import("behavior/translate_c_macros.zig");15 _ = @import("behavior/translate_c_macros.zig");
16 _ = @import("behavior/union.zig");
16 _ = @import("behavior/widening.zig");17 _ = @import("behavior/widening.zig");
1718
18 if (builtin.zig_is_stage2) {19 if (builtin.zig_is_stage2) {
...@@ -149,7 +150,7 @@ test {...@@ -149,7 +150,7 @@ test {
149 _ = @import("behavior/typename.zig");150 _ = @import("behavior/typename.zig");
150 _ = @import("behavior/undefined.zig");151 _ = @import("behavior/undefined.zig");
151 _ = @import("behavior/underscore.zig");152 _ = @import("behavior/underscore.zig");
152 _ = @import("behavior/union.zig");153 _ = @import("behavior/union_stage1.zig");
153 _ = @import("behavior/usingnamespace_stage1.zig");154 _ = @import("behavior/usingnamespace_stage1.zig");
154 _ = @import("behavior/var_args.zig");155 _ = @import("behavior/var_args.zig");
155 _ = @import("behavior/vector.zig");156 _ = @import("behavior/vector.zig");
...@@ -158,7 +159,6 @@ test {...@@ -158,7 +159,6 @@ test {
158 _ = @import("behavior/wasm.zig");159 _ = @import("behavior/wasm.zig");
159 }160 }
160 _ = @import("behavior/while.zig");161 _ = @import("behavior/while.zig");
161 _ = @import("behavior/widening_stage1.zig");
162 _ = @import("behavior/src.zig");162 _ = @import("behavior/src.zig");
163 _ = @import("behavior/translate_c_macros_stage1.zig");163 _ = @import("behavior/translate_c_macros_stage1.zig");
164 }164 }
test/behavior/union.zig-813
...@@ -2,816 +2,3 @@ const std = @import("std");...@@ -2,816 +2,3 @@ const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;3const expectEqual = std.testing.expectEqual;
4const Tag = std.meta.Tag;4const Tag = std.meta.Tag;
5
6const Value = union(enum) {
7 Int: u64,
8 Array: [9]u8,
9};
10
11const Agg = struct {
12 val1: Value,
13 val2: Value,
14};
15
16const v1 = Value{ .Int = 1234 };
17const v2 = Value{ .Array = [_]u8{3} ** 9 };
18
19const err = @as(anyerror!Agg, Agg{
20 .val1 = v1,
21 .val2 = v2,
22});
23
24const array = [_]Value{
25 v1,
26 v2,
27 v1,
28 v2,
29};
30
31test "unions embedded in aggregate types" {
32 switch (array[1]) {
33 Value.Array => |arr| try expect(arr[4] == 3),
34 else => unreachable,
35 }
36 switch ((err catch unreachable).val1) {
37 Value.Int => |x| try expect(x == 1234),
38 else => unreachable,
39 }
40}
41
42const Foo = union {
43 float: f64,
44 int: i32,
45};
46
47test "basic unions" {
48 var foo = Foo{ .int = 1 };
49 try expect(foo.int == 1);
50 foo = Foo{ .float = 12.34 };
51 try expect(foo.float == 12.34);
52}
53
54test "comptime union field access" {
55 comptime {
56 var foo = Foo{ .int = 0 };
57 try expect(foo.int == 0);
58
59 foo = Foo{ .float = 42.42 };
60 try expect(foo.float == 42.42);
61 }
62}
63
64test "init union with runtime value" {
65 var foo: Foo = undefined;
66
67 setFloat(&foo, 12.34);
68 try expect(foo.float == 12.34);
69
70 setInt(&foo, 42);
71 try expect(foo.int == 42);
72}
73
74fn setFloat(foo: *Foo, x: f64) void {
75 foo.* = Foo{ .float = x };
76}
77
78fn setInt(foo: *Foo, x: i32) void {
79 foo.* = Foo{ .int = x };
80}
81
82const FooExtern = extern union {
83 float: f64,
84 int: i32,
85};
86
87test "basic extern unions" {
88 var foo = FooExtern{ .int = 1 };
89 try expect(foo.int == 1);
90 foo.float = 12.34;
91 try expect(foo.float == 12.34);
92}
93
94const Letter = enum {
95 A,
96 B,
97 C,
98};
99const Payload = union(Letter) {
100 A: i32,
101 B: f64,
102 C: bool,
103};
104
105test "union with specified enum tag" {
106 try doTest();
107 comptime try doTest();
108}
109
110fn doTest() error{TestUnexpectedResult}!void {
111 try expect((try bar(Payload{ .A = 1234 })) == -10);
112}
113
114fn bar(value: Payload) error{TestUnexpectedResult}!i32 {
115 try expect(@as(Letter, value) == Letter.A);
116 return switch (value) {
117 Payload.A => |x| return x - 1244,
118 Payload.B => |x| if (x == 12.34) @as(i32, 20) else 21,
119 Payload.C => |x| if (x) @as(i32, 30) else 31,
120 };
121}
122
123const MultipleChoice = union(enum(u32)) {
124 A = 20,
125 B = 40,
126 C = 60,
127 D = 1000,
128};
129test "simple union(enum(u32))" {
130 var x = MultipleChoice.C;
131 try expect(x == MultipleChoice.C);
132 try expect(@enumToInt(@as(Tag(MultipleChoice), x)) == 60);
133}
134
135const MultipleChoice2 = union(enum(u32)) {
136 Unspecified1: i32,
137 A: f32 = 20,
138 Unspecified2: void,
139 B: bool = 40,
140 Unspecified3: i32,
141 C: i8 = 60,
142 Unspecified4: void,
143 D: void = 1000,
144 Unspecified5: i32,
145};
146
147test "union(enum(u32)) with specified and unspecified tag values" {
148 comptime try expect(Tag(Tag(MultipleChoice2)) == u32);
149 try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
150 comptime try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
151}
152
153fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) !void {
154 try expect(@enumToInt(@as(Tag(MultipleChoice2), x)) == 60);
155 try expect(1123 == switch (x) {
156 MultipleChoice2.A => 1,
157 MultipleChoice2.B => 2,
158 MultipleChoice2.C => |v| @as(i32, 1000) + v,
159 MultipleChoice2.D => 4,
160 MultipleChoice2.Unspecified1 => 5,
161 MultipleChoice2.Unspecified2 => 6,
162 MultipleChoice2.Unspecified3 => 7,
163 MultipleChoice2.Unspecified4 => 8,
164 MultipleChoice2.Unspecified5 => 9,
165 });
166}
167
168const ExternPtrOrInt = extern union {
169 ptr: *u8,
170 int: u64,
171};
172test "extern union size" {
173 comptime try expect(@sizeOf(ExternPtrOrInt) == 8);
174}
175
176const PackedPtrOrInt = packed union {
177 ptr: *u8,
178 int: u64,
179};
180test "extern union size" {
181 comptime try expect(@sizeOf(PackedPtrOrInt) == 8);
182}
183
184const ZeroBits = union {
185 OnlyField: void,
186};
187test "union with only 1 field which is void should be zero bits" {
188 comptime try expect(@sizeOf(ZeroBits) == 0);
189}
190
191const TheTag = enum {
192 A,
193 B,
194 C,
195};
196const TheUnion = union(TheTag) {
197 A: i32,
198 B: i32,
199 C: i32,
200};
201test "union field access gives the enum values" {
202 try expect(TheUnion.A == TheTag.A);
203 try expect(TheUnion.B == TheTag.B);
204 try expect(TheUnion.C == TheTag.C);
205}
206
207test "cast union to tag type of union" {
208 try testCastUnionToTag(TheUnion{ .B = 1234 });
209 comptime try testCastUnionToTag(TheUnion{ .B = 1234 });
210}
211
212fn testCastUnionToTag(x: TheUnion) !void {
213 try expect(@as(TheTag, x) == TheTag.B);
214}
215
216test "cast tag type of union to union" {
217 var x: Value2 = Letter2.B;
218 try expect(@as(Letter2, x) == Letter2.B);
219}
220const Letter2 = enum {
221 A,
222 B,
223 C,
224};
225const Value2 = union(Letter2) {
226 A: i32,
227 B,
228 C,
229};
230
231test "implicit cast union to its tag type" {
232 var x: Value2 = Letter2.B;
233 try expect(x == Letter2.B);
234 try giveMeLetterB(x);
235}
236fn giveMeLetterB(x: Letter2) !void {
237 try expect(x == Value2.B);
238}
239
240pub const PackThis = union(enum) {
241 Invalid: bool,
242 StringLiteral: u2,
243};
244
245test "constant packed union" {
246 try testConstPackedUnion(&[_]PackThis{PackThis{ .StringLiteral = 1 }});
247}
248
249fn testConstPackedUnion(expected_tokens: []const PackThis) !void {
250 try expect(expected_tokens[0].StringLiteral == 1);
251}
252
253test "switch on union with only 1 field" {
254 var r: PartialInst = undefined;
255 r = PartialInst.Compiled;
256 switch (r) {
257 PartialInst.Compiled => {
258 var z: PartialInstWithPayload = undefined;
259 z = PartialInstWithPayload{ .Compiled = 1234 };
260 switch (z) {
261 PartialInstWithPayload.Compiled => |x| {
262 try expect(x == 1234);
263 return;
264 },
265 }
266 },
267 }
268 unreachable;
269}
270
271const PartialInst = union(enum) {
272 Compiled,
273};
274
275const PartialInstWithPayload = union(enum) {
276 Compiled: i32,
277};
278
279test "access a member of tagged union with conflicting enum tag name" {
280 const Bar = union(enum) {
281 A: A,
282 B: B,
283
284 const A = u8;
285 const B = void;
286 };
287
288 comptime try expect(Bar.A == u8);
289}
290
291test "tagged union initialization with runtime void" {
292 try expect(testTaggedUnionInit({}));
293}
294
295const TaggedUnionWithAVoid = union(enum) {
296 A,
297 B: i32,
298};
299
300fn testTaggedUnionInit(x: anytype) bool {
301 const y = TaggedUnionWithAVoid{ .A = x };
302 return @as(Tag(TaggedUnionWithAVoid), y) == TaggedUnionWithAVoid.A;
303}
304
305pub const UnionEnumNoPayloads = union(enum) {
306 A,
307 B,
308};
309
310test "tagged union with no payloads" {
311 const a = UnionEnumNoPayloads{ .B = {} };
312 switch (a) {
313 Tag(UnionEnumNoPayloads).A => @panic("wrong"),
314 Tag(UnionEnumNoPayloads).B => {},
315 }
316}
317
318test "union with only 1 field casted to its enum type" {
319 const Literal = union(enum) {
320 Number: f64,
321 Bool: bool,
322 };
323
324 const Expr = union(enum) {
325 Literal: Literal,
326 };
327
328 var e = Expr{ .Literal = Literal{ .Bool = true } };
329 const ExprTag = Tag(Expr);
330 comptime try expect(Tag(ExprTag) == u0);
331 var t = @as(ExprTag, e);
332 try expect(t == Expr.Literal);
333}
334
335test "union with only 1 field casted to its enum type which has enum value specified" {
336 const Literal = union(enum) {
337 Number: f64,
338 Bool: bool,
339 };
340
341 const ExprTag = enum(comptime_int) {
342 Literal = 33,
343 };
344
345 const Expr = union(ExprTag) {
346 Literal: Literal,
347 };
348
349 var e = Expr{ .Literal = Literal{ .Bool = true } };
350 comptime try expect(Tag(ExprTag) == comptime_int);
351 var t = @as(ExprTag, e);
352 try expect(t == Expr.Literal);
353 try expect(@enumToInt(t) == 33);
354 comptime try expect(@enumToInt(t) == 33);
355}
356
357test "@enumToInt works on unions" {
358 const Bar = union(enum) {
359 A: bool,
360 B: u8,
361 C,
362 };
363
364 const a = Bar{ .A = true };
365 var b = Bar{ .B = undefined };
366 var c = Bar.C;
367 try expect(@enumToInt(a) == 0);
368 try expect(@enumToInt(b) == 1);
369 try expect(@enumToInt(c) == 2);
370}
371
372const Attribute = union(enum) {
373 A: bool,
374 B: u8,
375};
376
377fn setAttribute(attr: Attribute) void {
378 _ = attr;
379}
380
381fn Setter(attr: Attribute) type {
382 return struct {
383 fn set() void {
384 setAttribute(attr);
385 }
386 };
387}
388
389test "comptime union field value equality" {
390 const a0 = Setter(Attribute{ .A = false });
391 const a1 = Setter(Attribute{ .A = true });
392 const a2 = Setter(Attribute{ .A = false });
393
394 const b0 = Setter(Attribute{ .B = 5 });
395 const b1 = Setter(Attribute{ .B = 9 });
396 const b2 = Setter(Attribute{ .B = 5 });
397
398 try expect(a0 == a0);
399 try expect(a1 == a1);
400 try expect(a0 == a2);
401
402 try expect(b0 == b0);
403 try expect(b1 == b1);
404 try expect(b0 == b2);
405
406 try expect(a0 != b0);
407 try expect(a0 != a1);
408 try expect(b0 != b1);
409}
410
411test "return union init with void payload" {
412 const S = struct {
413 fn entry() !void {
414 try expect(func().state == State.one);
415 }
416 const Outer = union(enum) {
417 state: State,
418 };
419 const State = union(enum) {
420 one: void,
421 two: u32,
422 };
423 fn func() Outer {
424 return Outer{ .state = State{ .one = {} } };
425 }
426 };
427 try S.entry();
428 comptime try S.entry();
429}
430
431test "@unionInit can modify a union type" {
432 const UnionInitEnum = union(enum) {
433 Boolean: bool,
434 Byte: u8,
435 };
436
437 var value: UnionInitEnum = undefined;
438
439 value = @unionInit(UnionInitEnum, "Boolean", true);
440 try expect(value.Boolean == true);
441 value.Boolean = false;
442 try expect(value.Boolean == false);
443
444 value = @unionInit(UnionInitEnum, "Byte", 2);
445 try expect(value.Byte == 2);
446 value.Byte = 3;
447 try expect(value.Byte == 3);
448}
449
450test "@unionInit can modify a pointer value" {
451 const UnionInitEnum = union(enum) {
452 Boolean: bool,
453 Byte: u8,
454 };
455
456 var value: UnionInitEnum = undefined;
457 var value_ptr = &value;
458
459 value_ptr.* = @unionInit(UnionInitEnum, "Boolean", true);
460 try expect(value.Boolean == true);
461
462 value_ptr.* = @unionInit(UnionInitEnum, "Byte", 2);
463 try expect(value.Byte == 2);
464}
465
466test "union no tag with struct member" {
467 const Struct = struct {};
468 const Union = union {
469 s: Struct,
470 pub fn foo(self: *@This()) void {
471 _ = self;
472 }
473 };
474 var u = Union{ .s = Struct{} };
475 u.foo();
476}
477
478fn testComparison() !void {
479 var x = Payload{ .A = 42 };
480 try expect(x == .A);
481 try expect(x != .B);
482 try expect(x != .C);
483 try expect((x == .B) == false);
484 try expect((x == .C) == false);
485 try expect((x != .A) == false);
486}
487
488test "comparison between union and enum literal" {
489 try testComparison();
490 comptime try testComparison();
491}
492
493test "packed union generates correctly aligned LLVM type" {
494 const U = packed union {
495 f1: fn () error{TestUnexpectedResult}!void,
496 f2: u32,
497 };
498 var foo = [_]U{
499 U{ .f1 = doTest },
500 U{ .f2 = 0 },
501 };
502 try foo[0].f1();
503}
504
505test "union with one member defaults to u0 tag type" {
506 const U0 = union(enum) {
507 X: u32,
508 };
509 comptime try expect(Tag(Tag(U0)) == u0);
510}
511
512test "union with comptime_int tag" {
513 const Union = union(enum(comptime_int)) {
514 X: u32,
515 Y: u16,
516 Z: u8,
517 };
518 comptime try expect(Tag(Tag(Union)) == comptime_int);
519}
520
521test "extern union doesn't trigger field check at comptime" {
522 const U = extern union {
523 x: u32,
524 y: u8,
525 };
526
527 const x = U{ .x = 0x55AAAA55 };
528 comptime try expect(x.y == 0x55);
529}
530
531const Foo1 = union(enum) {
532 f: struct {
533 x: usize,
534 },
535};
536var glbl: Foo1 = undefined;
537
538test "global union with single field is correctly initialized" {
539 glbl = Foo1{
540 .f = @typeInfo(Foo1).Union.fields[0].field_type{ .x = 123 },
541 };
542 try expect(glbl.f.x == 123);
543}
544
545pub const FooUnion = union(enum) {
546 U0: usize,
547 U1: u8,
548};
549
550var glbl_array: [2]FooUnion = undefined;
551
552test "initialize global array of union" {
553 glbl_array[1] = FooUnion{ .U1 = 2 };
554 glbl_array[0] = FooUnion{ .U0 = 1 };
555 try expect(glbl_array[0].U0 == 1);
556 try expect(glbl_array[1].U1 == 2);
557}
558
559test "anonymous union literal syntax" {
560 const S = struct {
561 const Number = union {
562 int: i32,
563 float: f64,
564 };
565
566 fn doTheTest() !void {
567 var i: Number = .{ .int = 42 };
568 var f = makeNumber();
569 try expect(i.int == 42);
570 try expect(f.float == 12.34);
571 }
572
573 fn makeNumber() Number {
574 return .{ .float = 12.34 };
575 }
576 };
577 try S.doTheTest();
578 comptime try S.doTheTest();
579}
580
581test "update the tag value for zero-sized unions" {
582 const S = union(enum) {
583 U0: void,
584 U1: void,
585 };
586 var x = S{ .U0 = {} };
587 try expect(x == .U0);
588 x = S{ .U1 = {} };
589 try expect(x == .U1);
590}
591
592test "function call result coerces from tagged union to the tag" {
593 const S = struct {
594 const Arch = union(enum) {
595 One,
596 Two: usize,
597 };
598
599 const ArchTag = Tag(Arch);
600
601 fn doTheTest() !void {
602 var x: ArchTag = getArch1();
603 try expect(x == .One);
604
605 var y: ArchTag = getArch2();
606 try expect(y == .Two);
607 }
608
609 pub fn getArch1() Arch {
610 return .One;
611 }
612
613 pub fn getArch2() Arch {
614 return .{ .Two = 99 };
615 }
616 };
617 try S.doTheTest();
618 comptime try S.doTheTest();
619}
620
621test "0-sized extern union definition" {
622 const U = extern union {
623 a: void,
624 const f = 1;
625 };
626
627 try expect(U.f == 1);
628}
629
630test "union initializer generates padding only if needed" {
631 const U = union(enum) {
632 A: u24,
633 };
634
635 var v = U{ .A = 532 };
636 try expect(v.A == 532);
637}
638
639test "runtime tag name with single field" {
640 const U = union(enum) {
641 A: i32,
642 };
643
644 var v = U{ .A = 42 };
645 try expect(std.mem.eql(u8, @tagName(v), "A"));
646}
647
648test "cast from anonymous struct to union" {
649 const S = struct {
650 const U = union(enum) {
651 A: u32,
652 B: []const u8,
653 C: void,
654 };
655 fn doTheTest() !void {
656 var y: u32 = 42;
657 const t0 = .{ .A = 123 };
658 const t1 = .{ .B = "foo" };
659 const t2 = .{ .C = {} };
660 const t3 = .{ .A = y };
661 const x0: U = t0;
662 var x1: U = t1;
663 const x2: U = t2;
664 var x3: U = t3;
665 try expect(x0.A == 123);
666 try expect(std.mem.eql(u8, x1.B, "foo"));
667 try expect(x2 == .C);
668 try expect(x3.A == y);
669 }
670 };
671 try S.doTheTest();
672 comptime try S.doTheTest();
673}
674
675test "cast from pointer to anonymous struct to pointer to union" {
676 const S = struct {
677 const U = union(enum) {
678 A: u32,
679 B: []const u8,
680 C: void,
681 };
682 fn doTheTest() !void {
683 var y: u32 = 42;
684 const t0 = &.{ .A = 123 };
685 const t1 = &.{ .B = "foo" };
686 const t2 = &.{ .C = {} };
687 const t3 = &.{ .A = y };
688 const x0: *const U = t0;
689 var x1: *const U = t1;
690 const x2: *const U = t2;
691 var x3: *const U = t3;
692 try expect(x0.A == 123);
693 try expect(std.mem.eql(u8, x1.B, "foo"));
694 try expect(x2.* == .C);
695 try expect(x3.A == y);
696 }
697 };
698 try S.doTheTest();
699 comptime try S.doTheTest();
700}
701
702test "method call on an empty union" {
703 const S = struct {
704 const MyUnion = union(MyUnionTag) {
705 pub const MyUnionTag = enum { X1, X2 };
706 X1: [0]u8,
707 X2: [0]u8,
708
709 pub fn useIt(self: *@This()) bool {
710 _ = self;
711 return true;
712 }
713 };
714
715 fn doTheTest() !void {
716 var u = MyUnion{ .X1 = [0]u8{} };
717 try expect(u.useIt());
718 }
719 };
720 try S.doTheTest();
721 comptime try S.doTheTest();
722}
723
724test "switching on non exhaustive union" {
725 const S = struct {
726 const E = enum(u8) {
727 a,
728 b,
729 _,
730 };
731 const U = union(E) {
732 a: i32,
733 b: u32,
734 };
735 fn doTheTest() !void {
736 var a = U{ .a = 2 };
737 switch (a) {
738 .a => |val| try expect(val == 2),
739 .b => unreachable,
740 }
741 }
742 };
743 try S.doTheTest();
744 comptime try S.doTheTest();
745}
746
747test "containers with single-field enums" {
748 const S = struct {
749 const A = union(enum) { f1 };
750 const B = union(enum) { f1: void };
751 const C = struct { a: A };
752 const D = struct { a: B };
753
754 fn doTheTest() !void {
755 var array1 = [1]A{A{ .f1 = {} }};
756 var array2 = [1]B{B{ .f1 = {} }};
757 try expect(array1[0] == .f1);
758 try expect(array2[0] == .f1);
759
760 var struct1 = C{ .a = A{ .f1 = {} } };
761 var struct2 = D{ .a = B{ .f1 = {} } };
762 try expect(struct1.a == .f1);
763 try expect(struct2.a == .f1);
764 }
765 };
766
767 try S.doTheTest();
768 comptime try S.doTheTest();
769}
770
771test "@unionInit on union w/ tag but no fields" {
772 const S = struct {
773 const Type = enum(u8) { no_op = 105 };
774
775 const Data = union(Type) {
776 no_op: void,
777
778 pub fn decode(buf: []const u8) Data {
779 _ = buf;
780 return @unionInit(Data, "no_op", {});
781 }
782 };
783
784 comptime {
785 std.debug.assert(@sizeOf(Data) != 0);
786 }
787
788 fn doTheTest() !void {
789 var data: Data = .{ .no_op = .{} };
790 _ = data;
791 var o = Data.decode(&[_]u8{});
792 try expectEqual(Type.no_op, o);
793 }
794 };
795
796 try S.doTheTest();
797 comptime try S.doTheTest();
798}
799
800test "union enum type gets a separate scope" {
801 const S = struct {
802 const U = union(enum) {
803 a: u8,
804 const foo = 1;
805 };
806
807 fn doTheTest() !void {
808 try expect(!@hasDecl(Tag(U), "foo"));
809 }
810 };
811
812 try S.doTheTest();
813}
814test "anytype union field: issue #9233" {
815 const Baz = union(enum) { bar: anytype };
816 _ = Baz;
817}
test/behavior/union_stage1.zig created+799
...@@ -0,0 +1,799 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4const Tag = std.meta.Tag;
5
6const Value = union(enum) {
7 Int: u64,
8 Array: [9]u8,
9};
10
11const Agg = struct {
12 val1: Value,
13 val2: Value,
14};
15
16const v1 = Value{ .Int = 1234 };
17const v2 = Value{ .Array = [_]u8{3} ** 9 };
18
19const err = @as(anyerror!Agg, Agg{
20 .val1 = v1,
21 .val2 = v2,
22});
23
24const array = [_]Value{ v1, v2, v1, v2 };
25
26test "unions embedded in aggregate types" {
27 switch (array[1]) {
28 Value.Array => |arr| try expect(arr[4] == 3),
29 else => unreachable,
30 }
31 switch ((err catch unreachable).val1) {
32 Value.Int => |x| try expect(x == 1234),
33 else => unreachable,
34 }
35}
36
37const Foo = union {
38 float: f64,
39 int: i32,
40};
41
42test "basic unions" {
43 var foo = Foo{ .int = 1 };
44 try expect(foo.int == 1);
45 foo = Foo{ .float = 12.34 };
46 try expect(foo.float == 12.34);
47}
48
49test "comptime union field access" {
50 comptime {
51 var foo = Foo{ .int = 0 };
52 try expect(foo.int == 0);
53
54 foo = Foo{ .float = 42.42 };
55 try expect(foo.float == 42.42);
56 }
57}
58
59test "init union with runtime value" {
60 var foo: Foo = undefined;
61
62 setFloat(&foo, 12.34);
63 try expect(foo.float == 12.34);
64
65 setInt(&foo, 42);
66 try expect(foo.int == 42);
67}
68
69fn setFloat(foo: *Foo, x: f64) void {
70 foo.* = Foo{ .float = x };
71}
72
73fn setInt(foo: *Foo, x: i32) void {
74 foo.* = Foo{ .int = x };
75}
76
77const FooExtern = extern union {
78 float: f64,
79 int: i32,
80};
81
82test "basic extern unions" {
83 var foo = FooExtern{ .int = 1 };
84 try expect(foo.int == 1);
85 foo.float = 12.34;
86 try expect(foo.float == 12.34);
87}
88
89const Letter = enum { A, B, C };
90const Payload = union(Letter) {
91 A: i32,
92 B: f64,
93 C: bool,
94};
95
96test "union with specified enum tag" {
97 try doTest();
98 comptime try doTest();
99}
100
101fn doTest() error{TestUnexpectedResult}!void {
102 try expect((try bar(Payload{ .A = 1234 })) == -10);
103}
104
105fn bar(value: Payload) error{TestUnexpectedResult}!i32 {
106 try expect(@as(Letter, value) == Letter.A);
107 return switch (value) {
108 Payload.A => |x| return x - 1244,
109 Payload.B => |x| if (x == 12.34) @as(i32, 20) else 21,
110 Payload.C => |x| if (x) @as(i32, 30) else 31,
111 };
112}
113
114const MultipleChoice = union(enum(u32)) {
115 A = 20,
116 B = 40,
117 C = 60,
118 D = 1000,
119};
120test "simple union(enum(u32))" {
121 var x = MultipleChoice.C;
122 try expect(x == MultipleChoice.C);
123 try expect(@enumToInt(@as(Tag(MultipleChoice), x)) == 60);
124}
125
126const MultipleChoice2 = union(enum(u32)) {
127 Unspecified1: i32,
128 A: f32 = 20,
129 Unspecified2: void,
130 B: bool = 40,
131 Unspecified3: i32,
132 C: i8 = 60,
133 Unspecified4: void,
134 D: void = 1000,
135 Unspecified5: i32,
136};
137
138test "union(enum(u32)) with specified and unspecified tag values" {
139 comptime try expect(Tag(Tag(MultipleChoice2)) == u32);
140 try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
141 comptime try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
142}
143
144fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) !void {
145 try expect(@enumToInt(@as(Tag(MultipleChoice2), x)) == 60);
146 try expect(1123 == switch (x) {
147 MultipleChoice2.A => 1,
148 MultipleChoice2.B => 2,
149 MultipleChoice2.C => |v| @as(i32, 1000) + v,
150 MultipleChoice2.D => 4,
151 MultipleChoice2.Unspecified1 => 5,
152 MultipleChoice2.Unspecified2 => 6,
153 MultipleChoice2.Unspecified3 => 7,
154 MultipleChoice2.Unspecified4 => 8,
155 MultipleChoice2.Unspecified5 => 9,
156 });
157}
158
159const ExternPtrOrInt = extern union {
160 ptr: *u8,
161 int: u64,
162};
163test "extern union size" {
164 comptime try expect(@sizeOf(ExternPtrOrInt) == 8);
165}
166
167const PackedPtrOrInt = packed union {
168 ptr: *u8,
169 int: u64,
170};
171test "extern union size" {
172 comptime try expect(@sizeOf(PackedPtrOrInt) == 8);
173}
174
175const ZeroBits = union {
176 OnlyField: void,
177};
178test "union with only 1 field which is void should be zero bits" {
179 comptime try expect(@sizeOf(ZeroBits) == 0);
180}
181
182const TheTag = enum { A, B, C };
183const TheUnion = union(TheTag) {
184 A: i32,
185 B: i32,
186 C: i32,
187};
188test "union field access gives the enum values" {
189 try expect(TheUnion.A == TheTag.A);
190 try expect(TheUnion.B == TheTag.B);
191 try expect(TheUnion.C == TheTag.C);
192}
193
194test "cast union to tag type of union" {
195 try testCastUnionToTag(TheUnion{ .B = 1234 });
196 comptime try testCastUnionToTag(TheUnion{ .B = 1234 });
197}
198
199fn testCastUnionToTag(x: TheUnion) !void {
200 try expect(@as(TheTag, x) == TheTag.B);
201}
202
203test "cast tag type of union to union" {
204 var x: Value2 = Letter2.B;
205 try expect(@as(Letter2, x) == Letter2.B);
206}
207const Letter2 = enum { A, B, C };
208const Value2 = union(Letter2) {
209 A: i32,
210 B,
211 C,
212};
213
214test "implicit cast union to its tag type" {
215 var x: Value2 = Letter2.B;
216 try expect(x == Letter2.B);
217 try giveMeLetterB(x);
218}
219fn giveMeLetterB(x: Letter2) !void {
220 try expect(x == Value2.B);
221}
222
223// TODO it looks like this test intended to test packed unions, but this is not a packed
224// union. go through git history and find out what happened.
225pub const PackThis = union(enum) {
226 Invalid: bool,
227 StringLiteral: u2,
228};
229
230test "constant packed union" {
231 try testConstPackedUnion(&[_]PackThis{PackThis{ .StringLiteral = 1 }});
232}
233
234fn testConstPackedUnion(expected_tokens: []const PackThis) !void {
235 try expect(expected_tokens[0].StringLiteral == 1);
236}
237
238test "switch on union with only 1 field" {
239 var r: PartialInst = undefined;
240 r = PartialInst.Compiled;
241 switch (r) {
242 PartialInst.Compiled => {
243 var z: PartialInstWithPayload = undefined;
244 z = PartialInstWithPayload{ .Compiled = 1234 };
245 switch (z) {
246 PartialInstWithPayload.Compiled => |x| {
247 try expect(x == 1234);
248 return;
249 },
250 }
251 },
252 }
253 unreachable;
254}
255
256const PartialInst = union(enum) {
257 Compiled,
258};
259
260const PartialInstWithPayload = union(enum) {
261 Compiled: i32,
262};
263
264test "access a member of tagged union with conflicting enum tag name" {
265 const Bar = union(enum) {
266 A: A,
267 B: B,
268
269 const A = u8;
270 const B = void;
271 };
272
273 comptime try expect(Bar.A == u8);
274}
275
276test "tagged union initialization with runtime void" {
277 try expect(testTaggedUnionInit({}));
278}
279
280const TaggedUnionWithAVoid = union(enum) {
281 A,
282 B: i32,
283};
284
285fn testTaggedUnionInit(x: anytype) bool {
286 const y = TaggedUnionWithAVoid{ .A = x };
287 return @as(Tag(TaggedUnionWithAVoid), y) == TaggedUnionWithAVoid.A;
288}
289
290pub const UnionEnumNoPayloads = union(enum) { A, B };
291
292test "tagged union with no payloads" {
293 const a = UnionEnumNoPayloads{ .B = {} };
294 switch (a) {
295 Tag(UnionEnumNoPayloads).A => @panic("wrong"),
296 Tag(UnionEnumNoPayloads).B => {},
297 }
298}
299
300test "union with only 1 field casted to its enum type" {
301 const Literal = union(enum) {
302 Number: f64,
303 Bool: bool,
304 };
305
306 const Expr = union(enum) {
307 Literal: Literal,
308 };
309
310 var e = Expr{ .Literal = Literal{ .Bool = true } };
311 const ExprTag = Tag(Expr);
312 comptime try expect(Tag(ExprTag) == u0);
313 var t = @as(ExprTag, e);
314 try expect(t == Expr.Literal);
315}
316
317test "union with only 1 field casted to its enum type which has enum value specified" {
318 const Literal = union(enum) {
319 Number: f64,
320 Bool: bool,
321 };
322
323 const ExprTag = enum(comptime_int) {
324 Literal = 33,
325 };
326
327 const Expr = union(ExprTag) {
328 Literal: Literal,
329 };
330
331 var e = Expr{ .Literal = Literal{ .Bool = true } };
332 comptime try expect(Tag(ExprTag) == comptime_int);
333 var t = @as(ExprTag, e);
334 try expect(t == Expr.Literal);
335 try expect(@enumToInt(t) == 33);
336 comptime try expect(@enumToInt(t) == 33);
337}
338
339test "@enumToInt works on unions" {
340 const Bar = union(enum) {
341 A: bool,
342 B: u8,
343 C,
344 };
345
346 const a = Bar{ .A = true };
347 var b = Bar{ .B = undefined };
348 var c = Bar.C;
349 try expect(@enumToInt(a) == 0);
350 try expect(@enumToInt(b) == 1);
351 try expect(@enumToInt(c) == 2);
352}
353
354const Attribute = union(enum) {
355 A: bool,
356 B: u8,
357};
358
359fn setAttribute(attr: Attribute) void {
360 _ = attr;
361}
362
363fn Setter(attr: Attribute) type {
364 return struct {
365 fn set() void {
366 setAttribute(attr);
367 }
368 };
369}
370
371test "comptime union field value equality" {
372 const a0 = Setter(Attribute{ .A = false });
373 const a1 = Setter(Attribute{ .A = true });
374 const a2 = Setter(Attribute{ .A = false });
375
376 const b0 = Setter(Attribute{ .B = 5 });
377 const b1 = Setter(Attribute{ .B = 9 });
378 const b2 = Setter(Attribute{ .B = 5 });
379
380 try expect(a0 == a0);
381 try expect(a1 == a1);
382 try expect(a0 == a2);
383
384 try expect(b0 == b0);
385 try expect(b1 == b1);
386 try expect(b0 == b2);
387
388 try expect(a0 != b0);
389 try expect(a0 != a1);
390 try expect(b0 != b1);
391}
392
393test "return union init with void payload" {
394 const S = struct {
395 fn entry() !void {
396 try expect(func().state == State.one);
397 }
398 const Outer = union(enum) {
399 state: State,
400 };
401 const State = union(enum) {
402 one: void,
403 two: u32,
404 };
405 fn func() Outer {
406 return Outer{ .state = State{ .one = {} } };
407 }
408 };
409 try S.entry();
410 comptime try S.entry();
411}
412
413test "@unionInit can modify a union type" {
414 const UnionInitEnum = union(enum) {
415 Boolean: bool,
416 Byte: u8,
417 };
418
419 var value: UnionInitEnum = undefined;
420
421 value = @unionInit(UnionInitEnum, "Boolean", true);
422 try expect(value.Boolean == true);
423 value.Boolean = false;
424 try expect(value.Boolean == false);
425
426 value = @unionInit(UnionInitEnum, "Byte", 2);
427 try expect(value.Byte == 2);
428 value.Byte = 3;
429 try expect(value.Byte == 3);
430}
431
432test "@unionInit can modify a pointer value" {
433 const UnionInitEnum = union(enum) {
434 Boolean: bool,
435 Byte: u8,
436 };
437
438 var value: UnionInitEnum = undefined;
439 var value_ptr = &value;
440
441 value_ptr.* = @unionInit(UnionInitEnum, "Boolean", true);
442 try expect(value.Boolean == true);
443
444 value_ptr.* = @unionInit(UnionInitEnum, "Byte", 2);
445 try expect(value.Byte == 2);
446}
447
448test "union no tag with struct member" {
449 const Struct = struct {};
450 const Union = union {
451 s: Struct,
452 pub fn foo(self: *@This()) void {
453 _ = self;
454 }
455 };
456 var u = Union{ .s = Struct{} };
457 u.foo();
458}
459
460fn testComparison() !void {
461 var x = Payload{ .A = 42 };
462 try expect(x == .A);
463 try expect(x != .B);
464 try expect(x != .C);
465 try expect((x == .B) == false);
466 try expect((x == .C) == false);
467 try expect((x != .A) == false);
468}
469
470test "comparison between union and enum literal" {
471 try testComparison();
472 comptime try testComparison();
473}
474
475test "packed union generates correctly aligned LLVM type" {
476 const U = packed union {
477 f1: fn () error{TestUnexpectedResult}!void,
478 f2: u32,
479 };
480 var foo = [_]U{
481 U{ .f1 = doTest },
482 U{ .f2 = 0 },
483 };
484 try foo[0].f1();
485}
486
487test "union with one member defaults to u0 tag type" {
488 const U0 = union(enum) {
489 X: u32,
490 };
491 comptime try expect(Tag(Tag(U0)) == u0);
492}
493
494test "union with comptime_int tag" {
495 const Union = union(enum(comptime_int)) {
496 X: u32,
497 Y: u16,
498 Z: u8,
499 };
500 comptime try expect(Tag(Tag(Union)) == comptime_int);
501}
502
503test "extern union doesn't trigger field check at comptime" {
504 const U = extern union {
505 x: u32,
506 y: u8,
507 };
508
509 const x = U{ .x = 0x55AAAA55 };
510 comptime try expect(x.y == 0x55);
511}
512
513const Foo1 = union(enum) {
514 f: struct {
515 x: usize,
516 },
517};
518var glbl: Foo1 = undefined;
519
520test "global union with single field is correctly initialized" {
521 glbl = Foo1{
522 .f = @typeInfo(Foo1).Union.fields[0].field_type{ .x = 123 },
523 };
524 try expect(glbl.f.x == 123);
525}
526
527pub const FooUnion = union(enum) {
528 U0: usize,
529 U1: u8,
530};
531
532var glbl_array: [2]FooUnion = undefined;
533
534test "initialize global array of union" {
535 glbl_array[1] = FooUnion{ .U1 = 2 };
536 glbl_array[0] = FooUnion{ .U0 = 1 };
537 try expect(glbl_array[0].U0 == 1);
538 try expect(glbl_array[1].U1 == 2);
539}
540
541test "anonymous union literal syntax" {
542 const S = struct {
543 const Number = union {
544 int: i32,
545 float: f64,
546 };
547
548 fn doTheTest() !void {
549 var i: Number = .{ .int = 42 };
550 var f = makeNumber();
551 try expect(i.int == 42);
552 try expect(f.float == 12.34);
553 }
554
555 fn makeNumber() Number {
556 return .{ .float = 12.34 };
557 }
558 };
559 try S.doTheTest();
560 comptime try S.doTheTest();
561}
562
563test "update the tag value for zero-sized unions" {
564 const S = union(enum) {
565 U0: void,
566 U1: void,
567 };
568 var x = S{ .U0 = {} };
569 try expect(x == .U0);
570 x = S{ .U1 = {} };
571 try expect(x == .U1);
572}
573
574test "function call result coerces from tagged union to the tag" {
575 const S = struct {
576 const Arch = union(enum) {
577 One,
578 Two: usize,
579 };
580
581 const ArchTag = Tag(Arch);
582
583 fn doTheTest() !void {
584 var x: ArchTag = getArch1();
585 try expect(x == .One);
586
587 var y: ArchTag = getArch2();
588 try expect(y == .Two);
589 }
590
591 pub fn getArch1() Arch {
592 return .One;
593 }
594
595 pub fn getArch2() Arch {
596 return .{ .Two = 99 };
597 }
598 };
599 try S.doTheTest();
600 comptime try S.doTheTest();
601}
602
603test "0-sized extern union definition" {
604 const U = extern union {
605 a: void,
606 const f = 1;
607 };
608
609 try expect(U.f == 1);
610}
611
612test "union initializer generates padding only if needed" {
613 const U = union(enum) {
614 A: u24,
615 };
616
617 var v = U{ .A = 532 };
618 try expect(v.A == 532);
619}
620
621test "runtime tag name with single field" {
622 const U = union(enum) {
623 A: i32,
624 };
625
626 var v = U{ .A = 42 };
627 try expect(std.mem.eql(u8, @tagName(v), "A"));
628}
629
630test "cast from anonymous struct to union" {
631 const S = struct {
632 const U = union(enum) {
633 A: u32,
634 B: []const u8,
635 C: void,
636 };
637 fn doTheTest() !void {
638 var y: u32 = 42;
639 const t0 = .{ .A = 123 };
640 const t1 = .{ .B = "foo" };
641 const t2 = .{ .C = {} };
642 const t3 = .{ .A = y };
643 const x0: U = t0;
644 var x1: U = t1;
645 const x2: U = t2;
646 var x3: U = t3;
647 try expect(x0.A == 123);
648 try expect(std.mem.eql(u8, x1.B, "foo"));
649 try expect(x2 == .C);
650 try expect(x3.A == y);
651 }
652 };
653 try S.doTheTest();
654 comptime try S.doTheTest();
655}
656
657test "cast from pointer to anonymous struct to pointer to union" {
658 const S = struct {
659 const U = union(enum) {
660 A: u32,
661 B: []const u8,
662 C: void,
663 };
664 fn doTheTest() !void {
665 var y: u32 = 42;
666 const t0 = &.{ .A = 123 };
667 const t1 = &.{ .B = "foo" };
668 const t2 = &.{ .C = {} };
669 const t3 = &.{ .A = y };
670 const x0: *const U = t0;
671 var x1: *const U = t1;
672 const x2: *const U = t2;
673 var x3: *const U = t3;
674 try expect(x0.A == 123);
675 try expect(std.mem.eql(u8, x1.B, "foo"));
676 try expect(x2.* == .C);
677 try expect(x3.A == y);
678 }
679 };
680 try S.doTheTest();
681 comptime try S.doTheTest();
682}
683
684test "method call on an empty union" {
685 const S = struct {
686 const MyUnion = union(MyUnionTag) {
687 pub const MyUnionTag = enum { X1, X2 };
688 X1: [0]u8,
689 X2: [0]u8,
690
691 pub fn useIt(self: *@This()) bool {
692 _ = self;
693 return true;
694 }
695 };
696
697 fn doTheTest() !void {
698 var u = MyUnion{ .X1 = [0]u8{} };
699 try expect(u.useIt());
700 }
701 };
702 try S.doTheTest();
703 comptime try S.doTheTest();
704}
705
706test "switching on non exhaustive union" {
707 const S = struct {
708 const E = enum(u8) {
709 a,
710 b,
711 _,
712 };
713 const U = union(E) {
714 a: i32,
715 b: u32,
716 };
717 fn doTheTest() !void {
718 var a = U{ .a = 2 };
719 switch (a) {
720 .a => |val| try expect(val == 2),
721 .b => unreachable,
722 }
723 }
724 };
725 try S.doTheTest();
726 comptime try S.doTheTest();
727}
728
729test "containers with single-field enums" {
730 const S = struct {
731 const A = union(enum) { f1 };
732 const B = union(enum) { f1: void };
733 const C = struct { a: A };
734 const D = struct { a: B };
735
736 fn doTheTest() !void {
737 var array1 = [1]A{A{ .f1 = {} }};
738 var array2 = [1]B{B{ .f1 = {} }};
739 try expect(array1[0] == .f1);
740 try expect(array2[0] == .f1);
741
742 var struct1 = C{ .a = A{ .f1 = {} } };
743 var struct2 = D{ .a = B{ .f1 = {} } };
744 try expect(struct1.a == .f1);
745 try expect(struct2.a == .f1);
746 }
747 };
748
749 try S.doTheTest();
750 comptime try S.doTheTest();
751}
752
753test "@unionInit on union w/ tag but no fields" {
754 const S = struct {
755 const Type = enum(u8) { no_op = 105 };
756
757 const Data = union(Type) {
758 no_op: void,
759
760 pub fn decode(buf: []const u8) Data {
761 _ = buf;
762 return @unionInit(Data, "no_op", {});
763 }
764 };
765
766 comptime {
767 std.debug.assert(@sizeOf(Data) != 0);
768 }
769
770 fn doTheTest() !void {
771 var data: Data = .{ .no_op = .{} };
772 _ = data;
773 var o = Data.decode(&[_]u8{});
774 try expectEqual(Type.no_op, o);
775 }
776 };
777
778 try S.doTheTest();
779 comptime try S.doTheTest();
780}
781
782test "union enum type gets a separate scope" {
783 const S = struct {
784 const U = union(enum) {
785 a: u8,
786 const foo = 1;
787 };
788
789 fn doTheTest() !void {
790 try expect(!@hasDecl(Tag(U), "foo"));
791 }
792 };
793
794 try S.doTheTest();
795}
796test "anytype union field: issue #9233" {
797 const Baz = union(enum) { bar: anytype };
798 _ = Baz;
799}
test/behavior/widening.zig+43
...@@ -17,3 +17,46 @@ test "implicit unsigned integer to signed integer" {...@@ -17,3 +17,46 @@ test "implicit unsigned integer to signed integer" {
17 var b: i16 = a;17 var b: i16 = a;
18 try expect(b == 250);18 try expect(b == 250);
19}19}
20
21test "float widening" {
22 if (@import("builtin").zig_is_stage2) {
23 // This test is passing but it depends on compiler-rt symbols, which
24 // cannot yet be built with stage2 due to
25 // "TODO implement equality comparison between a union's tag value and an enum literal"
26 return error.SkipZigTest;
27 }
28 var a: f16 = 12.34;
29 var b: f32 = a;
30 var c: f64 = b;
31 var d: f128 = c;
32 try expect(a == b);
33 try expect(b == c);
34 try expect(c == d);
35}
36
37test "float widening f16 to f128" {
38 if (@import("builtin").zig_is_stage2) {
39 // This test is passing but it depends on compiler-rt symbols, which
40 // cannot yet be built with stage2 due to
41 // "TODO implement equality comparison between a union's tag value and an enum literal"
42 return error.SkipZigTest;
43 }
44 // TODO https://github.com/ziglang/zig/issues/3282
45 if (@import("builtin").stage2_arch == .aarch64) return error.SkipZigTest;
46 if (@import("builtin").stage2_arch == .powerpc64le) return error.SkipZigTest;
47
48 var x: f16 = 12.34;
49 var y: f128 = x;
50 try expect(x == y);
51}
52
53test "cast small unsigned to larger signed" {
54 try expect(castSmallUnsignedToLargerSigned1(200) == @as(i16, 200));
55 try expect(castSmallUnsignedToLargerSigned2(9999) == @as(i64, 9999));
56}
57fn castSmallUnsignedToLargerSigned1(x: u8) i16 {
58 return x;
59}
60fn castSmallUnsignedToLargerSigned2(x: u16) i64 {
61 return x;
62}
test/behavior/widening_stage1.zig deleted-34
...@@ -1,34 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const mem = std.mem;
4
5test "float widening" {
6 var a: f16 = 12.34;
7 var b: f32 = a;
8 var c: f64 = b;
9 var d: f128 = c;
10 try expect(a == b);
11 try expect(b == c);
12 try expect(c == d);
13}
14
15test "float widening f16 to f128" {
16 // TODO https://github.com/ziglang/zig/issues/3282
17 if (@import("builtin").stage2_arch == .aarch64) return error.SkipZigTest;
18 if (@import("builtin").stage2_arch == .powerpc64le) return error.SkipZigTest;
19
20 var x: f16 = 12.34;
21 var y: f128 = x;
22 try expect(x == y);
23}
24
25test "cast small unsigned to larger signed" {
26 try expect(castSmallUnsignedToLargerSigned1(200) == @as(i16, 200));
27 try expect(castSmallUnsignedToLargerSigned2(9999) == @as(i64, 9999));
28}
29fn castSmallUnsignedToLargerSigned1(x: u8) i16 {
30 return x;
31}
32fn castSmallUnsignedToLargerSigned2(x: u16) i64 {
33 return x;
34}