authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-07-27 15:51:03-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-07-27 15:51:03-04:00
logb52057f05218d13901fe576bf2d472b657e58e6f
tree80203b7f809f94c3a1a49f6e9404331d8947f78b
parentd01609af2aaf5a3c9ddd2ddf75a5d211e0e94b07
parent47396c903cb118df9e5562f383026b0f460d38f6

Merge pull request 'compiler_rt: change `f80` abi so it can become compatible with cbe' (#35932) from jacobly/s390x-abi into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35932

320 files changed, 19181 insertions(+), 13424 deletions(-)

CMakeLists.txt+2
...@@ -358,6 +358,8 @@ set(ZIG_STAGE2_SOURCES...@@ -358,6 +358,8 @@ set(ZIG_STAGE2_SOURCES
358 src/codegen/c/type/render_defs.zig358 src/codegen/c/type/render_defs.zig
359 src/codegen/llvm.zig359 src/codegen/llvm.zig
360 src/codegen/llvm/bindings.zig360 src/codegen/llvm/bindings.zig
361 src/codegen/loongarch/abi.zig
362 src/codegen/s390x/abi.zig
361 src/crash_report.zig363 src/crash_report.zig
362 src/dev.zig364 src/dev.zig
363 src/libs/freebsd.zig365 src/libs/freebsd.zig
lib/compiler/aro/aro/Target.zig+3-3
...@@ -1559,15 +1559,15 @@ pub fn ptrBitWidth(target: *const Target) u16 {...@@ -1559,15 +1559,15 @@ pub fn ptrBitWidth(target: *const Target) u16 {
1559}1559}
15601560
1561pub fn cCharSignedness(target: *const Target) std.builtin.Signedness {1561pub fn cCharSignedness(target: *const Target) std.builtin.Signedness {
1562 return target.toZigTarget().cCharSignedness();1562 return target.toZigTarget().cCharSignedness().?;
1563}1563}
15641564
1565pub fn cTypeBitSize(target: *const Target, c_type: std.Target.CType) u16 {1565pub fn cTypeBitSize(target: *const Target, c_type: std.Target.CType) u16 {
1566 return target.toZigTarget().cTypeBitSize(c_type);1566 return target.toZigTarget().cTypeBitSize(c_type).?;
1567}1567}
15681568
1569pub fn cTypeAlignment(target: *const Target, c_type: std.Target.CType) u16 {1569pub fn cTypeAlignment(target: *const Target, c_type: std.Target.CType) u16 {
1570 return target.toZigTarget().cTypeAlignment(c_type);1570 return target.toZigTarget().cTypeAlignment(c_type).?;
1571}1571}
15721572
1573pub fn standardDynamicLinkerPath(target: *const Target) std.Target.DynamicLinker {1573pub fn standardDynamicLinkerPath(target: *const Target) std.Target.DynamicLinker {
lib/compiler/reduce.zig+1-1
...@@ -400,7 +400,7 @@ fn parse(gpa: Allocator, io: Io, file_path: []const u8) !Ast {...@@ -400,7 +400,7 @@ fn parse(gpa: Allocator, io: Io, file_path: []const u8) !Ast {
400 file_path,400 file_path,
401 gpa,401 gpa,
402 .limited(std.math.maxInt(u32)),402 .limited(std.math.maxInt(u32)),
403 .fromByteUnits(1),403 .@"1",
404 0,404 0,
405 ) catch |err| {405 ) catch |err| {
406 fatal("unable to open '{s}': {s}", .{ file_path, @errorName(err) });406 fatal("unable to open '{s}': {s}", .{ file_path, @errorName(err) });
lib/compiler/resinator/parse.zig+1-1
...@@ -1277,7 +1277,7 @@ pub const Parser = struct {...@@ -1277,7 +1277,7 @@ pub const Parser = struct {
1277 },1277 },
1278 else => unreachable,1278 else => unreachable,
1279 }1279 }
1280 @compileError("unreachable");1280 comptime unreachable;
1281 }1281 }
12821282
1283 pub const OptionalParamParser = struct {1283 pub const OptionalParamParser = struct {
lib/compiler/test_runner.zig+11-11
...@@ -91,24 +91,23 @@ fn mainServer(init: std.process.Init.Minimal) !void {...@@ -91,24 +91,23 @@ fn mainServer(init: std.process.Init.Minimal) !void {
91 return std.process.exit(0);91 return std.process.exit(0);
92 },92 },
93 .query_test_metadata => {93 .query_test_metadata => {
94 testing.allocator_instance = .init(std.heap.page_allocator, .{});94 var sa: std.heap.SafeAllocator = .init(std.heap.page_allocator, .{});
95 defer if (testing.allocator_instance.deinit() != 0) {95 defer if (sa.deinit() != 0) @panic("internal test runner memory leak");
96 @panic("internal test runner memory leak");96 const gpa = sa.allocator();
97 };
9897
99 var string_bytes: std.ArrayList(u8) = .empty;98 var string_bytes: std.ArrayList(u8) = .empty;
100 defer string_bytes.deinit(testing.allocator);99 defer string_bytes.deinit(gpa);
101 try string_bytes.append(testing.allocator, 0); // Reserve 0 for null.100 try string_bytes.append(gpa, 0); // Reserve 0 for null.
102101
103 const test_fns = builtin.test_functions;102 const test_fns = builtin.test_functions;
104 const names = try testing.allocator.alloc(u32, test_fns.len);103 const names = try gpa.alloc(u32, test_fns.len);
105 defer testing.allocator.free(names);104 defer gpa.free(names);
106 const expected_panic_msgs = try testing.allocator.alloc(u32, test_fns.len);105 const expected_panic_msgs = try gpa.alloc(u32, test_fns.len);
107 defer testing.allocator.free(expected_panic_msgs);106 defer gpa.free(expected_panic_msgs);
108107
109 for (test_fns, names, expected_panic_msgs) |test_fn, *name, *expected_panic_msg| {108 for (test_fns, names, expected_panic_msgs) |test_fn, *name, *expected_panic_msg| {
110 name.* = @intCast(string_bytes.items.len);109 name.* = @intCast(string_bytes.items.len);
111 try string_bytes.ensureUnusedCapacity(testing.allocator, test_fn.name.len + 1);110 try string_bytes.ensureUnusedCapacity(gpa, test_fn.name.len + 1);
112 string_bytes.appendSliceAssumeCapacity(test_fn.name);111 string_bytes.appendSliceAssumeCapacity(test_fn.name);
113 string_bytes.appendAssumeCapacity(0);112 string_bytes.appendAssumeCapacity(0);
114 expected_panic_msg.* = 0;113 expected_panic_msg.* = 0;
...@@ -377,6 +376,7 @@ pub fn mainSimple() anyerror!void {...@@ -377,6 +376,7 @@ pub fn mainSimple() anyerror!void {
377 else => false,376 else => false,
378 };377 };
379378
379 testing.allocator_instance = .init(std.heap.page_allocator, .{});
380 testing.io_instance = .init(testing.allocator, .{});380 testing.io_instance = .init(testing.allocator, .{});
381381
382 var passed: u64 = 0;382 var passed: u64 = 0;
lib/compiler_rt.zig+120-168
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const compiler_rt = @This();
2const ofmt_c = builtin.object_format == .c;3const ofmt_c = builtin.object_format == .c;
3const native_endian = builtin.cpu.arch.endian();4const native_endian = builtin.cpu.arch.endian();
45
...@@ -84,144 +85,17 @@ comptime {...@@ -84,144 +85,17 @@ comptime {
84 // Float routines85 // Float routines
85 // conversion86 // conversion
86 _ = @import("compiler_rt/extendf.zig");87 _ = @import("compiler_rt/extendf.zig");
87 _ = @import("compiler_rt/extendhfsf2.zig");
88 _ = @import("compiler_rt/extendhfdf2.zig");
89 _ = @import("compiler_rt/extendhftf2.zig");
90 _ = @import("compiler_rt/extendhfxf2.zig");
91 _ = @import("compiler_rt/extendsfdf2.zig");
92 _ = @import("compiler_rt/extendsftf2.zig");
93 _ = @import("compiler_rt/extendsfxf2.zig");
94 _ = @import("compiler_rt/extenddftf2.zig");
95 _ = @import("compiler_rt/extenddfxf2.zig");
96 _ = @import("compiler_rt/extendxftf2.zig");
97
98 _ = @import("compiler_rt/truncf.zig");88 _ = @import("compiler_rt/truncf.zig");
99 _ = @import("compiler_rt/truncsfhf2.zig");
100 _ = @import("compiler_rt/truncdfhf2.zig");
101 _ = @import("compiler_rt/truncdfsf2.zig");
102 _ = @import("compiler_rt/truncxfhf2.zig");
103 _ = @import("compiler_rt/truncxfsf2.zig");
104 _ = @import("compiler_rt/truncxfdf2.zig");
105 _ = @import("compiler_rt/trunctfhf2.zig");
106 _ = @import("compiler_rt/trunctfsf2.zig");
107 _ = @import("compiler_rt/trunctfdf2.zig");
108 _ = @import("compiler_rt/trunctfxf2.zig");
109
110 _ = @import("compiler_rt/int_from_float.zig");89 _ = @import("compiler_rt/int_from_float.zig");
111 _ = @import("compiler_rt/fixhfei.zig");
112 _ = @import("compiler_rt/fixsfsi.zig");
113 _ = @import("compiler_rt/fixsfdi.zig");
114 _ = @import("compiler_rt/fixsfti.zig");
115 _ = @import("compiler_rt/fixsfei.zig");
116 _ = @import("compiler_rt/fixdfsi.zig");
117 _ = @import("compiler_rt/fixdfdi.zig");
118 _ = @import("compiler_rt/fixdfti.zig");
119 _ = @import("compiler_rt/fixdfei.zig");
120 _ = @import("compiler_rt/fixtfsi.zig");
121 _ = @import("compiler_rt/fixtfdi.zig");
122 _ = @import("compiler_rt/fixtfti.zig");
123 _ = @import("compiler_rt/fixtfei.zig");
124 _ = @import("compiler_rt/fixxfsi.zig");
125 _ = @import("compiler_rt/fixxfdi.zig");
126 _ = @import("compiler_rt/fixxfei.zig");
127
128 _ = @import("compiler_rt/fixunshfsi.zig");
129 _ = @import("compiler_rt/fixunshfdi.zig");
130 _ = @import("compiler_rt/fixunshfti.zig");
131 _ = @import("compiler_rt/fixunshfei.zig");
132 _ = @import("compiler_rt/fixunssfsi.zig");
133 _ = @import("compiler_rt/fixunssfdi.zig");
134 _ = @import("compiler_rt/fixunssfti.zig");
135 _ = @import("compiler_rt/fixunssfei.zig");
136 _ = @import("compiler_rt/fixunsdfsi.zig");
137 _ = @import("compiler_rt/fixunsdfdi.zig");
138 _ = @import("compiler_rt/fixunsdfti.zig");
139 _ = @import("compiler_rt/fixunsdfei.zig");
140 _ = @import("compiler_rt/fixunstfsi.zig");
141 _ = @import("compiler_rt/fixunstfdi.zig");
142 _ = @import("compiler_rt/fixunstfti.zig");
143 _ = @import("compiler_rt/fixunstfei.zig");
144 _ = @import("compiler_rt/fixunsxfsi.zig");
145 _ = @import("compiler_rt/fixunsxfdi.zig");
146 _ = @import("compiler_rt/fixunsxfti.zig");
147 _ = @import("compiler_rt/fixunsxfei.zig");
148
149 _ = @import("compiler_rt/float_from_int.zig");90 _ = @import("compiler_rt/float_from_int.zig");
150 _ = @import("compiler_rt/floatsihf.zig");
151 _ = @import("compiler_rt/floatsisf.zig");
152 _ = @import("compiler_rt/floatsidf.zig");
153 _ = @import("compiler_rt/floatsitf.zig");
154 _ = @import("compiler_rt/floatsixf.zig");
155 _ = @import("compiler_rt/floatdihf.zig");
156 _ = @import("compiler_rt/floatdisf.zig");
157 _ = @import("compiler_rt/floatdidf.zig");
158 _ = @import("compiler_rt/floatditf.zig");
159 _ = @import("compiler_rt/floatdixf.zig");
160 _ = @import("compiler_rt/floattihf.zig");
161 _ = @import("compiler_rt/floattisf.zig");
162 _ = @import("compiler_rt/floattidf.zig");
163 _ = @import("compiler_rt/floattitf.zig");
164 _ = @import("compiler_rt/floattixf.zig");
165 _ = @import("compiler_rt/floateihf.zig");
166 _ = @import("compiler_rt/floateisf.zig");
167 _ = @import("compiler_rt/floateidf.zig");
168 _ = @import("compiler_rt/floateitf.zig");
169 _ = @import("compiler_rt/floateixf.zig");
170 _ = @import("compiler_rt/floatunsihf.zig");
171 _ = @import("compiler_rt/floatunsisf.zig");
172 _ = @import("compiler_rt/floatunsidf.zig");
173 _ = @import("compiler_rt/floatunsitf.zig");
174 _ = @import("compiler_rt/floatunsixf.zig");
175 _ = @import("compiler_rt/floatundihf.zig");
176 _ = @import("compiler_rt/floatundisf.zig");
177 _ = @import("compiler_rt/floatundidf.zig");
178 _ = @import("compiler_rt/floatunditf.zig");
179 _ = @import("compiler_rt/floatundixf.zig");
180 _ = @import("compiler_rt/floatuntihf.zig");
181 _ = @import("compiler_rt/floatuntisf.zig");
182 _ = @import("compiler_rt/floatuntidf.zig");
183 _ = @import("compiler_rt/floatuntitf.zig");
184 _ = @import("compiler_rt/floatuntixf.zig");
185 _ = @import("compiler_rt/floatuneihf.zig");
186 _ = @import("compiler_rt/floatuneisf.zig");
187 _ = @import("compiler_rt/floatuneidf.zig");
188 _ = @import("compiler_rt/floatuneitf.zig");
189 _ = @import("compiler_rt/floatuneixf.zig");
19091
191 // comparison92 // comparison
192 _ = @import("compiler_rt/comparef.zig");93 _ = @import("compiler_rt/comparef.zig");
193 _ = @import("compiler_rt/cmpdf2.zig");
194 _ = @import("compiler_rt/cmptf2.zig");
195 _ = @import("compiler_rt/cmpxf2.zig");
196 _ = @import("compiler_rt/unorddf2.zig");
197 _ = @import("compiler_rt/gehf2.zig");
198 _ = @import("compiler_rt/gesf2.zig");
199 _ = @import("compiler_rt/gedf2.zig");
200 _ = @import("compiler_rt/gexf2.zig");
201 _ = @import("compiler_rt/getf2.zig");
20294
203 // arithmetic95 // arithmetic
204 _ = @import("compiler_rt/addf3.zig");96 _ = @import("compiler_rt/addf3.zig");
205 _ = @import("compiler_rt/addhf3.zig");
206 _ = @import("compiler_rt/addsf3.zig");
207 _ = @import("compiler_rt/adddf3.zig");
208 _ = @import("compiler_rt/addtf3.zig");
209 _ = @import("compiler_rt/addxf3.zig");
210
211 _ = @import("compiler_rt/subhf3.zig");
212 _ = @import("compiler_rt/subsf3.zig");
213 _ = @import("compiler_rt/subdf3.zig");
214 _ = @import("compiler_rt/subtf3.zig");
215 _ = @import("compiler_rt/subxf3.zig");
216
217 _ = @import("compiler_rt/mulf3.zig");97 _ = @import("compiler_rt/mulf3.zig");
218 _ = @import("compiler_rt/mulhf3.zig");
219 _ = @import("compiler_rt/mulsf3.zig");
220 _ = @import("compiler_rt/muldf3.zig");
221 _ = @import("compiler_rt/multf3.zig");
222 _ = @import("compiler_rt/mulxf3.zig");
22398
224 _ = @import("compiler_rt/divhf3.zig");
225 _ = @import("compiler_rt/divsf3.zig");99 _ = @import("compiler_rt/divsf3.zig");
226 _ = @import("compiler_rt/divdf3.zig");100 _ = @import("compiler_rt/divdf3.zig");
227 _ = @import("compiler_rt/divxf3.zig");101 _ = @import("compiler_rt/divxf3.zig");
...@@ -235,25 +109,17 @@ comptime {...@@ -235,25 +109,17 @@ comptime {
235 symbol(&__negsf2, "__negsf2");109 symbol(&__negsf2, "__negsf2");
236 symbol(&__negdf2, "__negdf2");110 symbol(&__negdf2, "__negdf2");
237 }111 }
238 if (want_ppc_abi) symbol(&__negtf2, "__negkf2");112 if (want_ppc_abi) {
239 symbol(&__negtf2, "__negtf2");113 symbol(&__negtf2, "__negkf2");
114 } else {
115 symbol(&__negtf2, "__negtf2");
116 }
240 symbol(&__negxf2, "__negxf2");117 symbol(&__negxf2, "__negxf2");
241118
242 // other119 // other
243 _ = @import("compiler_rt/powiXf2.zig");120 _ = @import("compiler_rt/powiXf2.zig");
244 _ = @import("compiler_rt/mulc3.zig");121 _ = @import("compiler_rt/mulc3.zig");
245 _ = @import("compiler_rt/mulhc3.zig");
246 _ = @import("compiler_rt/mulsc3.zig");
247 _ = @import("compiler_rt/muldc3.zig");
248 _ = @import("compiler_rt/mulxc3.zig");
249 _ = @import("compiler_rt/multc3.zig");
250
251 _ = @import("compiler_rt/divc3.zig");122 _ = @import("compiler_rt/divc3.zig");
252 _ = @import("compiler_rt/divhc3.zig");
253 _ = @import("compiler_rt/divsc3.zig");
254 _ = @import("compiler_rt/divdc3.zig");
255 _ = @import("compiler_rt/divxc3.zig");
256 _ = @import("compiler_rt/divtc3.zig");
257123
258 // Math routines. Alphabetically sorted.124 // Math routines. Alphabetically sorted.
259 _ = @import("compiler_rt/cos.zig");125 _ = @import("compiler_rt/cos.zig");
...@@ -279,7 +145,7 @@ comptime {...@@ -279,7 +145,7 @@ comptime {
279 _ = @import("compiler_rt/divmodei4.zig");145 _ = @import("compiler_rt/divmodei4.zig");
280 _ = @import("compiler_rt/udivmodei4.zig");146 _ = @import("compiler_rt/udivmodei4.zig");
281147
282 _ = @import("compiler_rt/limb64.zig");148 if (builtin.cpu.arch.isWasm()) _ = @import("compiler_rt/limb64.zig");
283149
284 // extra150 // extra
285 _ = @import("compiler_rt/os_version_check.zig");151 _ = @import("compiler_rt/os_version_check.zig");
...@@ -290,7 +156,7 @@ comptime {...@@ -290,7 +156,7 @@ comptime {
290 _ = @import("compiler_rt/clear_cache.zig");156 _ = @import("compiler_rt/clear_cache.zig");
291 _ = @import("compiler_rt/hexagon.zig");157 _ = @import("compiler_rt/hexagon.zig");
292158
293 if (@import("builtin").object_format != .c) {159 if (builtin.object_format != .c) {
294 if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig");160 if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig");
295 _ = @import("compiler_rt/stack_probe.zig");161 _ = @import("compiler_rt/stack_probe.zig");
296162
...@@ -366,10 +232,7 @@ pub const want_aeabi = switch (builtin.abi) {...@@ -366,10 +232,7 @@ pub const want_aeabi = switch (builtin.abi) {
366 .gnueabihf,232 .gnueabihf,
367 .android,233 .android,
368 .androideabi,234 .androideabi,
369 => switch (builtin.cpu.arch) {235 => builtin.cpu.arch.isArm(),
370 .arm, .armeb, .thumb, .thumbeb => true,
371 else => false,
372 },
373 else => false,236 else => false,
374};237};
375238
...@@ -443,19 +306,108 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) {...@@ -443,19 +306,108 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) {
443pub const want_sparc64_abi = builtin.cpu.arch == .sparc64;306pub const want_sparc64_abi = builtin.cpu.arch == .sparc64;
444pub const want_sparc32_abi = builtin.cpu.arch == .sparc;307pub const want_sparc32_abi = builtin.cpu.arch == .sparc;
445308
446pub fn F16T(comptime OtherType: type) type {309/// For operations converting between `f16` and another floating point type.
447 return switch (builtin.cpu.arch) {310pub fn f16Conv(comptime OtherType: type) type {
448 .x86, .x86_64 => if (builtin.target.os.tag.isDarwin()) switch (OtherType) {311 switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) {
449 // Starting with LLVM 16, Darwin uses different abi for f16312 .hard => {},
450 // depending on the type of the other return/argument..???313 .soft => return softFloatAbi(f16),
451 f32, f64 => u16,314 }
452 f80, f128 => f16,315 if (builtin.cpu.arch.isX86() and builtin.os.tag.isDarwin()) switch (OtherType) {
453 else => unreachable,316 else => unreachable,
454 } else f16,317 // Starting with LLVM 16, Darwin uses different abi for f16
455 else => f16,318 // depending on the type of the other return/argument..???
319 f32, f64 => return softFloatAbi(f16),
320 f80, f128 => {},
321 };
322 return hardFloatAbi(f16);
323}
324pub const @"f16" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) {
325 .hard => hardFloatAbi(f16),
326 .soft => softFloatAbi(f16),
327};
328pub const @"f32" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 32)) {
329 .hard => hardFloatAbi(f32),
330 .soft => softFloatAbi(f32),
331};
332pub const @"f64" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 64)) {
333 .hard => hardFloatAbi(f64),
334 .soft => softFloatAbi(f64),
335};
336pub const @"f80" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 80)) {
337 .hard => hardFloatAbi(f80),
338 .soft => struct {
339 pub const Abi = extern struct { mantissa: u64, exponent: u16 };
340 const Repr = packed struct { mantissa: u64, exponent: u16 };
341 pub inline fn toAbi(raw: f80) Abi {
342 const repr: Repr = @bitCast(raw);
343 return .{ .mantissa = repr.mantissa, .exponent = repr.exponent };
344 }
345 pub inline fn fromAbi(abi: Abi) f80 {
346 const repr: Repr = .{ .mantissa = abi.mantissa, .exponent = abi.exponent };
347 return @bitCast(repr);
348 }
349 pub const complex = complexAbi(f80, @This());
350 },
351};
352pub const @"f128" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 128)) {
353 .hard => hardFloatAbi(f128),
354 .soft => struct {
355 pub const Abi = switch (builtin.cpu.arch.endian()) {
356 .big => extern struct { hi: u64, lo: u64 },
357 .little => extern struct { lo: u64, hi: u64 },
358 };
359 const Repr = packed struct { lo: u64, hi: u64 };
360 pub inline fn toAbi(raw: f128) Abi {
361 const repr: Repr = @bitCast(raw);
362 return .{ .lo = repr.lo, .hi = repr.hi };
363 }
364 pub inline fn fromAbi(abi: Abi) f128 {
365 const repr: Repr = .{ .lo = abi.lo, .hi = abi.hi };
366 return @bitCast(repr);
367 }
368 pub const complex = complexAbi(f128, @This());
369 },
370};
371fn hardFloatAbi(comptime Float: type) type {
372 return struct {
373 pub const Abi = Float;
374 pub inline fn toAbi(raw: Float) Abi {
375 return raw;
376 }
377 pub inline fn fromAbi(abi: Abi) Float {
378 return abi;
379 }
380 pub const complex = complexAbi(Float, @This());
381 };
382}
383fn softFloatAbi(comptime Float: type) type {
384 return struct {
385 pub const Abi = @Int(.unsigned, @bitSizeOf(Float));
386 pub inline fn toAbi(raw: Float) Abi {
387 return @bitCast(raw);
388 }
389 pub inline fn fromAbi(abi: Abi) Float {
390 return @bitCast(abi);
391 }
392 pub const complex = complexAbi(Float, @This());
393 };
394}
395fn complexAbi(comptime Float: type, comptime float: type) type {
396 return struct {
397 pub const Abi = extern struct { real: float.Abi, imag: float.Abi };
398 pub inline fn toAbi(raw: Complex(Float)) Abi {
399 return .{ .real = float.toAbi(raw.real), .imag = float.toAbi(raw.imag) };
400 }
401 pub inline fn fromAbi(abi: Abi) Complex(Float) {
402 return .{ .real = float.fromAbi(abi.real), .imag = float.fromAbi(abi.imag) };
403 }
456 };404 };
457}405}
458406
407pub fn Complex(comptime Float: type) type {
408 return struct { real: Float, imag: Float };
409}
410
459pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {411pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
460 switch (Z) {412 switch (Z) {
461 u16 => {413 u16 => {
...@@ -588,31 +540,31 @@ pub inline fn fneg(a: anytype) @TypeOf(a) {...@@ -588,31 +540,31 @@ pub inline fn fneg(a: anytype) @TypeOf(a) {
588 return @bitCast(negated);540 return @bitCast(negated);
589}541}
590542
591fn __negxf2(a: f80) callconv(.c) f80 {543fn __neghf2(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
592 return fneg(a);544 return compiler_rt.f16.toAbi(fneg(compiler_rt.f16.fromAbi(a)));
593}545}
594546
595fn __neghf2(a: f16) callconv(.c) f16 {547fn __negsf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
596 return fneg(a);548 return compiler_rt.f32.toAbi(fneg(compiler_rt.f32.fromAbi(a)));
597}549}
598550
599fn __negdf2(a: f64) callconv(.c) f64 {551fn __negdf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
600 return fneg(a);552 return compiler_rt.f64.toAbi(fneg(compiler_rt.f64.fromAbi(a)));
601}553}
602554
603fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 {555fn __negxf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
604 return fneg(a);556 return compiler_rt.f80.toAbi(fneg(compiler_rt.f80.fromAbi(a)));
605}557}
606558
607fn __negtf2(a: f128) callconv(.c) f128 {559fn __negtf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
608 return fneg(a);560 return compiler_rt.f128.toAbi(fneg(compiler_rt.f128.fromAbi(a)));
609}561}
610562
611fn __negsf2(a: f32) callconv(.c) f32 {563fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
612 return fneg(a);564 return fneg(a);
613}565}
614566
615fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 {567fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
616 return fneg(a);568 return fneg(a);
617}569}
618570
lib/compiler_rt/absv.zig+1-2
...@@ -14,8 +14,7 @@ pub inline fn absv(comptime ST: type, a: ST) ST {...@@ -14,8 +14,7 @@ pub inline fn absv(comptime ST: type, a: ST) ST {
14 const sign: ST = a >> N - 1;14 const sign: ST = a >> N - 1;
15 x +%= sign;15 x +%= sign;
16 x ^= sign;16 x ^= sign;
17 if (x < 0)17 if (x < 0) @panic("integer overflow");
18 @panic("compiler_rt absv: overflow");
19 return x;18 return x;
20}19}
2120
lib/compiler_rt/absvdi2.zig+3-2
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const symbol = @import("../compiler_rt.zig").symbol;1const compiler_rt = @import("../compiler_rt.zig");
2const absv = @import("./absv.zig").absv;2const symbol = compiler_rt.symbol;
3const absv = @import("absv.zig").absv;
34
4comptime {5comptime {
5 symbol(&__absvdi2, "__absvdi2");6 symbol(&__absvdi2, "__absvdi2");
lib/compiler_rt/absvsi2.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const compiler_rt = @import("../compiler_rt.zig");1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;2const symbol = compiler_rt.symbol;
3const absv = @import("./absv.zig").absv;3const absv = @import("absv.zig").absv;
44
5comptime {5comptime {
6 symbol(&__absvsi2, "__absvsi2");6 symbol(&__absvsi2, "__absvsi2");
lib/compiler_rt/absvti2.zig+3-2
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const symbol = @import("../compiler_rt.zig").symbol;1const compiler_rt = @import("../compiler_rt.zig");
2const absv = @import("./absv.zig").absv;2const symbol = compiler_rt.symbol;
3const absv = @import("absv.zig").absv;
34
4comptime {5comptime {
5 symbol(&__absvti2, "__absvti2");6 symbol(&__absvti2, "__absvti2");
lib/compiler_rt/adddf3.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const addf3 = @import("./addf3.zig").addf3;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_dadd, "__aeabi_dadd");
8 } else {
9 symbol(&__adddf3, "__adddf3");
10 }
11}
12
13fn __adddf3(a: f64, b: f64) callconv(.c) f64 {
14 return addf3(f64, a, b);
15}
16
17fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
18 return addf3(f64, a, b);
19}
lib/compiler_rt/addf3.zig+132-1
...@@ -1,12 +1,143 @@...@@ -1,12 +1,143 @@
1const std = @import("std");1const std = @import("std");
2const math = std.math;2const math = std.math;
3const compiler_rt = @import("../compiler_rt.zig");3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
4const normalize = compiler_rt.normalize;5const normalize = compiler_rt.normalize;
56
7comptime {
8 symbol(&__addhf3, "__addhf3");
9 if (compiler_rt.want_aeabi) {
10 symbol(&__aeabi_fadd, "__aeabi_fadd");
11 symbol(&__aeabi_dadd, "__aeabi_dadd");
12 } else {
13 symbol(&__addsf3, "__addsf3");
14 symbol(&__adddf3, "__adddf3");
15 }
16 symbol(&__addxf3, "__addxf3");
17 if (compiler_rt.want_ppc_abi) {
18 symbol(&__addtf3, "__addkf3");
19 } else if (compiler_rt.want_sparc64_abi) {
20 symbol(&_Qp_add, "_Qp_add");
21 } else if (compiler_rt.want_sparc32_abi) {
22 symbol(&__addtf3, "_Q_add");
23 } else {
24 symbol(&__addtf3, "__addtf3");
25 }
26}
27
28fn __addhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
29 return compiler_rt.f16.toAbi(add_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
30}
31pub fn add_f16(a: f16, b: f16) f16 {
32 return addf3(f16, a, b);
33}
34
35fn __addsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
36 return compiler_rt.f32.toAbi(add_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)));
37}
38fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
39 return add_f32(a, b);
40}
41pub fn add_f32(a: f32, b: f32) f32 {
42 return addf3(f32, a, b);
43}
44
45fn __adddf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
46 return compiler_rt.f64.toAbi(add_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)));
47}
48fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
49 return add_f64(a, b);
50}
51pub fn add_f64(a: f64, b: f64) f64 {
52 return addf3(f64, a, b);
53}
54
55fn __addxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
56 return compiler_rt.f80.toAbi(add_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)));
57}
58pub fn add_f80(a: f80, b: f80) f80 {
59 return addf3(f80, a, b);
60}
61
62fn __addtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
63 return compiler_rt.f128.toAbi(add_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)));
64}
65fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void {
66 c.* = add_f128(a.*, b.*);
67}
68pub fn add_f128(a: f128, b: f128) f128 {
69 return addf3(f128, a, b);
70}
71
72comptime {
73 symbol(&__subhf3, "__subhf3");
74 if (compiler_rt.want_aeabi) {
75 symbol(&__aeabi_fsub, "__aeabi_fsub");
76 symbol(&__aeabi_dsub, "__aeabi_dsub");
77 } else {
78 symbol(&__subsf3, "__subsf3");
79 symbol(&__subdf3, "__subdf3");
80 }
81 symbol(&__subxf3, "__subxf3");
82 if (compiler_rt.want_ppc_abi) {
83 symbol(&__subtf3, "__subkf3");
84 } else if (compiler_rt.want_sparc64_abi) {
85 symbol(&_Qp_sub, "_Qp_sub");
86 } else if (compiler_rt.want_sparc32_abi) {
87 symbol(&__subtf3, "_Q_sub");
88 } else {
89 symbol(&__subtf3, "__subtf3");
90 }
91}
92
93fn __subhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
94 return compiler_rt.f16.toAbi(sub_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
95}
96pub fn sub_f16(a: f16, b: f16) f16 {
97 return add_f16(a, compiler_rt.fneg(b));
98}
99
100fn __subsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
101 return compiler_rt.f32.toAbi(sub_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)));
102}
103fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
104 return sub_f32(a, b);
105}
106pub fn sub_f32(a: f32, b: f32) f32 {
107 return add_f32(a, compiler_rt.fneg(b));
108}
109
110fn __subdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
111 return compiler_rt.f64.toAbi(sub_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)));
112}
113fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
114 return sub_f64(a, b);
115}
116pub fn sub_f64(a: f64, b: f64) f64 {
117 return add_f64(a, compiler_rt.fneg(b));
118}
119
120fn __subxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
121 return compiler_rt.f80.toAbi(sub_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)));
122}
123pub fn sub_f80(a: f80, b: f80) f80 {
124 return add_f80(a, compiler_rt.fneg(b));
125}
126
127fn __subtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
128 return compiler_rt.f128.toAbi(sub_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)));
129}
130fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {
131 c.* = sub_f128(a.*, b.*);
132}
133pub fn sub_f128(a: f128, b: f128) f128 {
134 return add_f128(a, compiler_rt.fneg(b));
135}
136
6/// Ported from:137/// Ported from:
7///138///
8/// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc139/// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc
9pub inline fn addf3(comptime T: type, a: T, b: T) T {140inline fn addf3(comptime T: type, a: T, b: T) T {
10 const bits = @typeInfo(T).float.bits;141 const bits = @typeInfo(T).float.bits;
11 const Z = @Int(.unsigned, bits);142 const Z = @Int(.unsigned, bits);
12143
lib/compiler_rt/addf3_test.zig+7-6
...@@ -8,12 +8,13 @@ const builtin = @import("builtin");...@@ -8,12 +8,13 @@ const builtin = @import("builtin");
8const math = std.math;8const math = std.math;
9const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);9const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);
1010
11const __addtf3 = @import("addtf3.zig").__addtf3;11const impl = @import("addf3.zig");
12const __addxf3 = @import("addxf3.zig").__addxf3;12const add_f128 = impl.add_f128;
13const __subtf3 = @import("subtf3.zig").__subtf3;13const add_f80 = impl.add_f80;
14const sub_f128 = impl.sub_f128;
1415
15fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {16fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
16 const x = __addtf3(a, b);17 const x = add_f128(a, b);
1718
18 const rep: u128 = @bitCast(x);19 const rep: u128 = @bitCast(x);
19 const hi: u64 = @intCast(rep >> 64);20 const hi: u64 = @intCast(rep >> 64);
...@@ -52,7 +53,7 @@ test "addtf3" {...@@ -52,7 +53,7 @@ test "addtf3" {
52}53}
5354
54fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {55fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
55 const x = __subtf3(a, b);56 const x = sub_f128(a, b);
5657
57 const rep: u128 = @bitCast(x);58 const rep: u128 = @bitCast(x);
58 const hi: u64 = @intCast(rep >> 64);59 const hi: u64 = @intCast(rep >> 64);
...@@ -91,7 +92,7 @@ test "subtf3" {...@@ -91,7 +92,7 @@ test "subtf3" {
91const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));92const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));
9293
93fn test__addxf3(a: f80, b: f80, expected: u80) !void {94fn test__addxf3(a: f80, b: f80, expected: u80) !void {
94 const x = __addxf3(a, b);95 const x = add_f80(a, b);
95 const rep: u80 = @bitCast(x);96 const rep: u80 = @bitCast(x);
9697
97 if (rep == expected)98 if (rep == expected)
lib/compiler_rt/addhf3.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 symbol(&__addhf3, "__addhf3");
7}
8
9fn __addhf3(a: f16, b: f16) callconv(.c) f16 {
10 return addf3(f16, a, b);
11}
lib/compiler_rt/addsf3.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const addf3 = @import("./addf3.zig").addf3;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_fadd, "__aeabi_fadd");
8 } else {
9 symbol(&__addsf3, "__addsf3");
10 }
11}
12
13fn __addsf3(a: f32, b: f32) callconv(.c) f32 {
14 return addf3(f32, a, b);
15}
16
17fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
18 return addf3(f32, a, b);
19}
lib/compiler_rt/addtf3.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__addtf3, "__addkf3");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_add, "_Qp_add");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__addtf3, "_Q_add");
12 }
13 symbol(&__addtf3, "__addtf3");
14}
15
16pub fn __addtf3(a: f128, b: f128) callconv(.c) f128 {
17 return addf3(f128, a, b);
18}
19
20fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void {
21 c.* = addf3(f128, a.*, b.*);
22}
lib/compiler_rt/addvdi3.zig+3-2
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const symbol = @import("../compiler_rt.zig").symbol;1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
2const testing = @import("std").testing;3const testing = @import("std").testing;
34
4comptime {5comptime {
...@@ -9,7 +10,7 @@ pub fn __addvdi3(a: i64, b: i64) callconv(.c) i64 {...@@ -9,7 +10,7 @@ pub fn __addvdi3(a: i64, b: i64) callconv(.c) i64 {
9 const sum = a +% b;10 const sum = a +% b;
10 // Overflow occurred iff both operands have the same sign, and the sign of the sum does11 // Overflow occurred iff both operands have the same sign, and the sign of the sum does
11 // not match it. In other words, iff the sum sign is not the sign of either operand.12 // not match it. In other words, iff the sum sign is not the sign of either operand.
12 if (((sum ^ a) & (sum ^ b)) < 0) @panic("compiler-rt: integer overflow");13 if (((sum ^ a) & (sum ^ b)) < 0) @panic("integer overflow");
13 return sum;14 return sum;
14}15}
1516
lib/compiler_rt/addvsi3.zig+1-1
...@@ -10,7 +10,7 @@ pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 {...@@ -10,7 +10,7 @@ pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 {
10 const sum = a +% b;10 const sum = a +% b;
11 // Overflow occurred iff both operands have the same sign, and the sign of the sum does11 // Overflow occurred iff both operands have the same sign, and the sign of the sum does
12 // not match it. In other words, iff the sum sign is not the sign of either operand.12 // not match it. In other words, iff the sum sign is not the sign of either operand.
13 if (((sum ^ a) & (sum ^ b)) < 0) @panic("compiler-rt: integer overflow");13 if (((sum ^ a) & (sum ^ b)) < 0) @panic("integer overflow");
14 return sum;14 return sum;
15}15}
1616
lib/compiler_rt/addxf3.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 symbol(&__addxf3, "__addxf3");
7}
8
9pub fn __addxf3(a: f80, b: f80) callconv(.c) f80 {
10 return addf3(f80, a, b);
11}
lib/compiler_rt/atomics.zig+1-1
...@@ -5,7 +5,7 @@ const arch = cpu.arch;...@@ -5,7 +5,7 @@ const arch = cpu.arch;
5const std = @import("std");5const std = @import("std");
66
7const compiler_rt = @import("../compiler_rt.zig");7const compiler_rt = @import("../compiler_rt.zig");
8const symbol = @import("../compiler_rt.zig").symbol;8const symbol = compiler_rt.symbol;
99
10// This parameter is true iff the target architecture supports the bare minimum10// This parameter is true iff the target architecture supports the bare minimum
11// to implement the atomic load/store intrinsics.11// to implement the atomic load/store intrinsics.
lib/compiler_rt/aulldiv.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
22
3const compiler_rt = @import("../compiler_rt.zig");3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = @import("../compiler_rt.zig").symbol;4const symbol = compiler_rt.symbol;
55
6comptime {6comptime {
7 if (compiler_rt.want_windows_x86_msvc_abi) {7 if (compiler_rt.want_windows_x86_msvc_abi) {
lib/compiler_rt/cmpdf2.zig deleted-67
...@@ -1,67 +0,0 @@
1///! The quoted behavior definitions are from
2///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
3const compiler_rt = @import("../compiler_rt.zig");
4const comparef = @import("./comparef.zig");
5const symbol = @import("../compiler_rt.zig").symbol;
6
7comptime {
8 if (compiler_rt.want_aeabi) {
9 symbol(&__aeabi_dcmpeq, "__aeabi_dcmpeq");
10 symbol(&__aeabi_dcmplt, "__aeabi_dcmplt");
11 symbol(&__aeabi_dcmple, "__aeabi_dcmple");
12 } else {
13 symbol(&__eqdf2, "__eqdf2");
14 symbol(&__nedf2, "__nedf2");
15 symbol(&__ledf2, "__ledf2");
16 symbol(&__cmpdf2, "__cmpdf2");
17 symbol(&__ltdf2, "__ltdf2");
18 }
19}
20
21/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;
22/// if a is greater than b, they return 1; and if a and b are equal they return 0.
23/// If either argument is NaN they return 1..."
24///
25/// Note that this matches the definition of `__ledf2`, `__eqdf2`, `__nedf2`, `__cmpdf2`,
26/// and `__ltdf2`.
27fn __cmpdf2(a: f64, b: f64) callconv(.c) i32 {
28 return @backingInt(comparef.cmpf2(f64, comparef.LE, a, b));
29}
30
31/// "These functions return a value less than or equal to zero if neither argument is NaN,
32/// and a is less than or equal to b."
33pub fn __ledf2(a: f64, b: f64) callconv(.c) i32 {
34 return __cmpdf2(a, b);
35}
36
37/// "These functions return zero if neither argument is NaN, and a and b are equal."
38/// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined
39/// to have the same return value.
40pub fn __eqdf2(a: f64, b: f64) callconv(.c) i32 {
41 return __cmpdf2(a, b);
42}
43
44/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."
45/// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined
46/// to have the same return value.
47pub fn __nedf2(a: f64, b: f64) callconv(.c) i32 {
48 return __cmpdf2(a, b);
49}
50
51/// "These functions return a value less than zero if neither argument is NaN, and a
52/// is strictly less than b."
53pub fn __ltdf2(a: f64, b: f64) callconv(.c) i32 {
54 return __cmpdf2(a, b);
55}
56
57fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
58 return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Equal);
59}
60
61fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
62 return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Less);
63}
64
65fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
66 return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) != .Greater);
67}
lib/compiler_rt/cmptf2.zig deleted-146
...@@ -1,146 +0,0 @@
1///! The quoted behavior definitions are from
2///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
3const compiler_rt = @import("../compiler_rt.zig");
4const comparef = @import("./comparef.zig");
5const symbol = @import("../compiler_rt.zig").symbol;
6
7comptime {
8 if (compiler_rt.want_ppc_abi) {
9 symbol(&__eqtf2, "__eqkf2");
10 symbol(&__netf2, "__nekf2");
11 symbol(&__lttf2, "__ltkf2");
12 symbol(&__letf2, "__lekf2");
13 } else if (compiler_rt.want_sparc64_abi) {
14 symbol(&_Qp_cmp, "_Qp_cmp");
15 symbol(&_Qp_feq, "_Qp_feq");
16 symbol(&_Qp_fne, "_Qp_fne");
17 symbol(&_Qp_flt, "_Qp_flt");
18 symbol(&_Qp_fle, "_Qp_fle");
19 symbol(&_Qp_fgt, "_Qp_fgt");
20 symbol(&_Qp_fge, "_Qp_fge");
21 } else if (compiler_rt.want_sparc32_abi) {
22 symbol(&_Q_cmp, "_Q_cmp");
23 symbol(&_Q_feq, "_Q_feq");
24 symbol(&_Q_fne, "_Q_fne");
25 symbol(&_Q_flt, "_Q_flt");
26 symbol(&_Q_fle, "_Q_fle");
27 symbol(&_Q_fgt, "_Q_fgt");
28 symbol(&_Q_fge, "_Q_fge");
29 }
30 symbol(&__eqtf2, "__eqtf2");
31 symbol(&__netf2, "__netf2");
32 symbol(&__letf2, "__letf2");
33 symbol(&__cmptf2, "__cmptf2");
34 symbol(&__lttf2, "__lttf2");
35}
36
37/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;
38/// if a is greater than b, they return 1; and if a and b are equal they return 0.
39/// If either argument is NaN they return 1..."
40///
41/// Note that this matches the definition of `__letf2`, `__eqtf2`, `__netf2`, `__cmptf2`,
42/// and `__lttf2`.
43fn __cmptf2(a: f128, b: f128) callconv(.c) i32 {
44 return @backingInt(comparef.cmpf2(f128, comparef.LE, a, b));
45}
46
47/// "These functions return a value less than or equal to zero if neither argument is NaN,
48/// and a is less than or equal to b."
49fn __letf2(a: f128, b: f128) callconv(.c) i32 {
50 return __cmptf2(a, b);
51}
52
53/// "These functions return zero if neither argument is NaN, and a and b are equal."
54/// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined
55/// to have the same return value.
56fn __eqtf2(a: f128, b: f128) callconv(.c) i32 {
57 return __cmptf2(a, b);
58}
59
60/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."
61/// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined
62/// to have the same return value.
63fn __netf2(a: f128, b: f128) callconv(.c) i32 {
64 return __cmptf2(a, b);
65}
66
67/// "These functions return a value less than zero if neither argument is NaN, and a
68/// is strictly less than b."
69fn __lttf2(a: f128, b: f128) callconv(.c) i32 {
70 return __cmptf2(a, b);
71}
72
73const SparcFCMP = enum(i32) {
74 Equal = 0,
75 Less = 1,
76 Greater = 2,
77 Unordered = 3,
78};
79
80fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) i32 {
81 return @backingInt(comparef.cmpf2(f128, SparcFCMP, a.*, b.*));
82}
83
84fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) bool {
85 return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Equal;
86}
87
88fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) bool {
89 return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) != .Equal;
90}
91
92fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) bool {
93 return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Less;
94}
95
96fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) bool {
97 return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Greater;
98}
99
100fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) bool {
101 return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b))))) {
102 .Equal, .Greater => true,
103 .Less, .Unordered => false,
104 };
105}
106
107fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) bool {
108 return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b))))) {
109 .Equal, .Less => true,
110 .Greater, .Unordered => false,
111 };
112}
113
114fn _Q_cmp(a: f128, b: f128) callconv(.c) i32 {
115 return @backingInt(comparef.cmpf2(f128, SparcFCMP, a, b));
116}
117
118fn _Q_feq(a: f128, b: f128) callconv(.c) bool {
119 return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Equal;
120}
121
122fn _Q_fne(a: f128, b: f128) callconv(.c) bool {
123 return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) != .Equal;
124}
125
126fn _Q_flt(a: f128, b: f128) callconv(.c) bool {
127 return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Less;
128}
129
130fn _Q_fgt(a: f128, b: f128) callconv(.c) bool {
131 return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Greater;
132}
133
134fn _Q_fge(a: f128, b: f128) callconv(.c) bool {
135 return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b))))) {
136 .Equal, .Greater => true,
137 .Less, .Unordered => false,
138 };
139}
140
141fn _Q_fle(a: f128, b: f128) callconv(.c) bool {
142 return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b))))) {
143 .Equal, .Less => true,
144 .Greater, .Unordered => false,
145 };
146}
lib/compiler_rt/cmpxf2.zig deleted-49
...@@ -1,49 +0,0 @@
1///! The quoted behavior definitions are from
2///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const comparef = @import("./comparef.zig");
6
7comptime {
8 symbol(&__eqxf2, "__eqxf2");
9 symbol(&__nexf2, "__nexf2");
10 symbol(&__lexf2, "__lexf2");
11 symbol(&__cmpxf2, "__cmpxf2");
12 symbol(&__ltxf2, "__ltxf2");
13}
14
15/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;
16/// if a is greater than b, they return 1; and if a and b are equal they return 0.
17/// If either argument is NaN they return 1..."
18///
19/// Note that this matches the definition of `__lexf2`, `__eqxf2`, `__nexf2`, `__cmpxf2`,
20/// and `__ltxf2`.
21fn __cmpxf2(a: f80, b: f80) callconv(.c) i32 {
22 return @backingInt(comparef.cmp_f80(comparef.LE, a, b));
23}
24
25/// "These functions return a value less than or equal to zero if neither argument is NaN,
26/// and a is less than or equal to b."
27fn __lexf2(a: f80, b: f80) callconv(.c) i32 {
28 return __cmpxf2(a, b);
29}
30
31/// "These functions return zero if neither argument is NaN, and a and b are equal."
32/// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined
33/// to have the same return value.
34fn __eqxf2(a: f80, b: f80) callconv(.c) i32 {
35 return __cmpxf2(a, b);
36}
37
38/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."
39/// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined
40/// to have the same return value.
41fn __nexf2(a: f80, b: f80) callconv(.c) i32 {
42 return __cmpxf2(a, b);
43}
44
45/// "These functions return a value less than zero if neither argument is NaN, and a
46/// is strictly less than b."
47fn __ltxf2(a: f80, b: f80) callconv(.c) i32 {
48 return __cmpxf2(a, b);
49}
lib/compiler_rt/comparedf2_test.zig+17-73
...@@ -5,52 +5,12 @@...@@ -5,52 +5,12 @@
5const std = @import("std");5const std = @import("std");
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
8const __eqdf2 = @import("./cmpdf2.zig").__eqdf2;8const compiler_rt = @import("../compiler_rt.zig");
9const __ledf2 = @import("./cmpdf2.zig").__ledf2;
10const __ltdf2 = @import("./cmpdf2.zig").__ltdf2;
11const __nedf2 = @import("./cmpdf2.zig").__nedf2;
129
13const __gedf2 = @import("./gedf2.zig").__gedf2;10const impl = @import("comparef.zig");
14const __gtdf2 = @import("./gedf2.zig").__gtdf2;11const Order = impl.Order;
1512const cmp_f64 = impl.cmp_f64;
16const __unorddf2 = @import("./unorddf2.zig").__unorddf2;13const unord_f64 = impl.unord_f64;
17
18const TestVector = struct {
19 a: f64,
20 b: f64,
21 eqReference: c_int,
22 geReference: c_int,
23 gtReference: c_int,
24 leReference: c_int,
25 ltReference: c_int,
26 neReference: c_int,
27 unReference: c_int,
28};
29
30fn test__cmpdf2(vector: TestVector) bool {
31 if (__eqdf2(vector.a, vector.b) != vector.eqReference) {
32 return false;
33 }
34 if (__gedf2(vector.a, vector.b) != vector.geReference) {
35 return false;
36 }
37 if (__gtdf2(vector.a, vector.b) != vector.gtReference) {
38 return false;
39 }
40 if (__ledf2(vector.a, vector.b) != vector.leReference) {
41 return false;
42 }
43 if (__ltdf2(vector.a, vector.b) != vector.ltReference) {
44 return false;
45 }
46 if (__nedf2(vector.a, vector.b) != vector.neReference) {
47 return false;
48 }
49 if (__unorddf2(vector.a, vector.b) != vector.unReference) {
50 return false;
51 }
52 return true;
53}
5414
55const arguments = [_]f64{15const arguments = [_]f64{
56 std.math.nan(f64),16 std.math.nan(f64),
...@@ -73,36 +33,20 @@ const arguments = [_]f64{...@@ -73,36 +33,20 @@ const arguments = [_]f64{
73 std.math.inf(f64),33 std.math.inf(f64),
74};34};
7535
76fn generateVector(comptime a: f64, comptime b: f64) TestVector {36test "compare f64" {
77 const leResult = if (a < b) -1 else if (a == b) 0 else 1;
78 const geResult = if (a > b) 1 else if (a == b) 0 else -1;
79 const unResult = if (a != a or b != b) 1 else 0;
80 return TestVector{
81 .a = a,
82 .b = b,
83 .eqReference = leResult,
84 .geReference = geResult,
85 .gtReference = geResult,
86 .leReference = leResult,
87 .ltReference = leResult,
88 .neReference = leResult,
89 .unReference = unResult,
90 };
91}
92
93const test_vectors = init: {
94 @setEvalBranchQuota(10000);
95 var vectors: [arguments.len * arguments.len]TestVector = undefined;
96 for (arguments[0..], 0..) |arg_i, i| {37 for (arguments[0..], 0..) |arg_i, i| {
97 for (arguments[0..], 0..) |arg_j, j| {38 for (arguments[0..], 0..) |arg_j, j| {
98 vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j);39 const expected_unord = i == 0 or j == 0;
40 const expected_order: ?Order = if (expected_unord) null else switch (std.math.order(
41 if (i >= 9) i - 1 else i,
42 if (j >= 9) j - 1 else j,
43 )) {
44 .lt => .lt,
45 .eq => .eq,
46 .gt => .gt,
47 };
48 try std.testing.expect(expected_order == cmp_f64(arg_i, arg_j));
49 try std.testing.expect(expected_unord == unord_f64(arg_i, arg_j));
99 }50 }
100 }51 }
101 break :init vectors;
102};
103
104test "compare f64" {
105 for (test_vectors) |vector| {
106 try std.testing.expect(test__cmpdf2(vector));
107 }
108}52}
lib/compiler_rt/comparef.zig+274-167
...@@ -1,163 +1,309 @@...@@ -1,163 +1,309 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
23
3const compiler_rt = @import("../compiler_rt.zig");4const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;5const symbol = compiler_rt.symbol;
56
6comptime {7const Unordered = if (builtin.cpu.arch == .avr)
7 if (compiler_rt.want_aeabi) {8 i8
8 symbol(&__aeabi_fcmpun, "__aeabi_fcmpun");9else if (builtin.cpu.arch.isAARCH64())
9 } else {10 i32
10 symbol(&__unordsf2, "__unordsf2");11else if (builtin.target.cTypeBitSize(.long).? >= builtin.target.ptrBitWidth())
11 }12 c_long
1213else
13 symbol(&__unordxf2, "__unordxf2");14 c_longlong;
15pub const Order = enum(Unordered) { lt = -1, eq = 0, gt = 1 };
16const SparcOrder = enum(i32) { eq = 0, lt = 1, gt = 2, un = 3 };
1417
15 symbol(&__eqhf2, "__eqhf2");18comptime {
16 symbol(&__nehf2, "__nehf2");
17 symbol(&__lehf2, "__lehf2");
18 symbol(&__cmphf2, "__cmphf2");19 symbol(&__cmphf2, "__cmphf2");
19 symbol(&__lthf2, "__lthf2");20 symbol(&__cmphf2, "__eqhf2");
21 symbol(&__cmphf2, "__nehf2");
22 symbol(&__cmphf2, "__lthf2");
23 symbol(&__cmphf2, "__lehf2");
24 symbol(&__gehf2, "__gthf2");
25 symbol(&__gehf2, "__gehf2");
26 symbol(&__unordhf2, "__unordhf2");
2027
21 if (compiler_rt.want_aeabi) {28 if (compiler_rt.want_aeabi) {
22 symbol(&__aeabi_fcmpeq, "__aeabi_fcmpeq");29 symbol(&__aeabi_fcmpeq, "__aeabi_fcmpeq");
23 symbol(&__aeabi_fcmplt, "__aeabi_fcmplt");30 symbol(&__aeabi_fcmplt, "__aeabi_fcmplt");
24 symbol(&__aeabi_fcmple, "__aeabi_fcmple");31 symbol(&__aeabi_fcmple, "__aeabi_fcmple");
32 symbol(&__aeabi_fcmpgt, "__aeabi_fcmpgt");
33 symbol(&__aeabi_fcmpge, "__aeabi_fcmpge");
34 symbol(&__aeabi_fcmpun, "__aeabi_fcmpun");
35
36 symbol(&__aeabi_dcmpeq, "__aeabi_dcmpeq");
37 symbol(&__aeabi_dcmplt, "__aeabi_dcmplt");
38 symbol(&__aeabi_dcmple, "__aeabi_dcmple");
39 symbol(&__aeabi_dcmpgt, "__aeabi_dcmpgt");
40 symbol(&__aeabi_dcmpge, "__aeabi_dcmpge");
41 symbol(&__aeabi_dcmpun, "__aeabi_dcmpun");
25 } else {42 } else {
26 symbol(&__eqsf2, "__eqsf2");
27 symbol(&__nesf2, "__nesf2");
28 symbol(&__lesf2, "__lesf2");
29 symbol(&__cmpsf2, "__cmpsf2");43 symbol(&__cmpsf2, "__cmpsf2");
30 symbol(&__ltsf2, "__ltsf2");44 symbol(&__cmpsf2, "__eqsf2");
45 symbol(&__cmpsf2, "__nesf2");
46 symbol(&__cmpsf2, "__ltsf2");
47 symbol(&__cmpsf2, "__lesf2");
48 symbol(&__gesf2, "__gtsf2");
49 symbol(&__gesf2, "__gesf2");
50 symbol(&__unordsf2, "__unordsf2");
51
52 symbol(&__cmpdf2, "__cmpdf2");
53 symbol(&__cmpdf2, "__eqdf2");
54 symbol(&__cmpdf2, "__nedf2");
55 symbol(&__cmpdf2, "__ltdf2");
56 symbol(&__cmpdf2, "__ledf2");
57 symbol(&__gedf2, "__gtdf2");
58 symbol(&__gedf2, "__gedf2");
59 symbol(&__unorddf2, "__unorddf2");
31 }60 }
3261
62 symbol(&__cmpxf2, "__cmpxf2");
63 symbol(&__cmpxf2, "__eqxf2");
64 symbol(&__cmpxf2, "__nexf2");
65 symbol(&__cmpxf2, "__ltxf2");
66 symbol(&__cmpxf2, "__lexf2");
67 symbol(&__gexf2, "__gtxf2");
68 symbol(&__gexf2, "__gexf2");
69 symbol(&__unordxf2, "__unordxf2");
70
33 if (compiler_rt.want_ppc_abi) {71 if (compiler_rt.want_ppc_abi) {
72 symbol(&__cmptf2, "__eqkf2");
73 symbol(&__cmptf2, "__nekf2");
74 symbol(&__cmptf2, "__ltkf2");
75 symbol(&__cmptf2, "__lekf2");
76 symbol(&__getf2, "__gtkf2");
77 symbol(&__getf2, "__gekf2");
34 symbol(&__unordtf2, "__unordkf2");78 symbol(&__unordtf2, "__unordkf2");
79 } else if (compiler_rt.want_sparc64_abi) {
80 symbol(&_Qp_cmp, "_Qp_cmp");
81 symbol(&_Qp_feq, "_Qp_feq");
82 symbol(&_Qp_fne, "_Qp_fne");
83 symbol(&_Qp_flt, "_Qp_flt");
84 symbol(&_Qp_fle, "_Qp_fle");
85 symbol(&_Qp_fgt, "_Qp_fgt");
86 symbol(&_Qp_fge, "_Qp_fge");
87 } else if (compiler_rt.want_sparc32_abi) {
88 symbol(&_Q_cmp, "_Q_cmp");
89 symbol(&_Q_feq, "_Q_feq");
90 symbol(&_Q_fne, "_Q_fne");
91 symbol(&_Q_flt, "_Q_flt");
92 symbol(&_Q_fle, "_Q_fle");
93 symbol(&_Q_fgt, "_Q_fgt");
94 symbol(&_Q_fge, "_Q_fge");
95 } else {
96 symbol(&__cmptf2, "__cmptf2");
97 symbol(&__cmptf2, "__eqtf2");
98 symbol(&__cmptf2, "__netf2");
99 symbol(&__cmptf2, "__lttf2");
100 symbol(&__cmptf2, "__letf2");
101 symbol(&__getf2, "__gttf2");
102 symbol(&__getf2, "__getf2");
103 symbol(&__unordtf2, "__unordtf2");
35 }104 }
36 symbol(&__unordtf2, "__unordtf2");
37 symbol(&__unordhf2, "__unordhf2");
38}
39
40pub fn __unordhf2(a: f16, b: f16) callconv(.c) i32 {
41 return unordcmp(f16, a, b);
42}105}
43106
44pub fn __unordtf2(a: f128, b: f128) callconv(.c) i32 {107fn __cmphf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order {
45 return unordcmp(f128, a, b);108 return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .gt;
46}109}
47110fn __gehf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order {
48/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;111 return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .lt;
49/// if a is greater than b, they return 1; and if a and b are equal they return 0.
50/// If either argument is NaN they return 1..."
51///
52/// Note that this matches the definition of `__lesf2`, `__eqsf2`, `__nesf2`, `__cmpsf2`,
53/// and `__ltsf2`.
54fn __cmpsf2(a: f32, b: f32) callconv(.c) i32 {
55 return @backingInt(cmpf2(f32, LE, a, b));
56}112}
57113fn __unordhf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Unordered {
58/// "These functions return a value less than or equal to zero if neither argument is NaN,114 return @intFromBool(unord_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
59/// and a is less than or equal to b."
60pub fn __lesf2(a: f32, b: f32) callconv(.c) i32 {
61 return __cmpsf2(a, b);
62}115}
63116pub fn cmp_f16(a: f16, b: f16) ?Order {
64/// "These functions return zero if neither argument is NaN, and a and b are equal."117 return cmpf2(f16, a, b);
65/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined
66/// to have the same return value.
67pub fn __eqsf2(a: f32, b: f32) callconv(.c) i32 {
68 return __cmpsf2(a, b);
69}118}
70119pub fn unord_f16(a: f16, b: f16) bool {
71/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."120 return unord(f16, a, b);
72/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined
73/// to have the same return value.
74pub fn __nesf2(a: f32, b: f32) callconv(.c) i32 {
75 return __cmpsf2(a, b);
76}121}
77122
78/// "These functions return a value less than zero if neither argument is NaN, and a123fn __cmpsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order {
79/// is strictly less than b."124 return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .gt;
80pub fn __ltsf2(a: f32, b: f32) callconv(.c) i32 {
81 return __cmpsf2(a, b);
82}125}
83
84fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {126fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
85 return @intFromBool(cmpf2(f32, LE, a, b) == .Equal);127 return @intFromBool(cmp_f32(a, b) == .eq);
86}128}
87
88fn __aeabi_fcmplt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {129fn __aeabi_fcmplt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
89 return @intFromBool(cmpf2(f32, LE, a, b) == .Less);130 return @intFromBool(cmp_f32(a, b) == .lt);
90}131}
91
92fn __aeabi_fcmple(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {132fn __aeabi_fcmple(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
93 return @intFromBool(cmpf2(f32, LE, a, b) != .Greater);133 return @intFromBool(cmp_f32(a, b) orelse .gt != .gt);
94}134}
95135fn __gesf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order {
96/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;136 return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .lt;
97/// if a is greater than b, they return 1; and if a and b are equal they return 0.
98/// If either argument is NaN they return 1..."
99///
100/// Note that this matches the definition of `__lehf2`, `__eqhf2`, `__nehf2`, `__cmphf2`,
101/// and `__lthf2`.
102fn __cmphf2(a: f16, b: f16) callconv(.c) i32 {
103 return @backingInt(cmpf2(f16, LE, a, b));
104}137}
105138fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
106/// "These functions return a value less than or equal to zero if neither argument is NaN,139 return @intFromBool(cmp_f32(a, b) orelse .lt != .lt);
107/// and a is less than or equal to b."
108fn __lehf2(a: f16, b: f16) callconv(.c) i32 {
109 return __cmphf2(a, b);
110}140}
111141fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
112/// "These functions return zero if neither argument is NaN, and a and b are equal."142 return @intFromBool(cmp_f32(a, b) == .gt);
113/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined
114/// to have the same return value.
115fn __eqhf2(a: f16, b: f16) callconv(.c) i32 {
116 return __cmphf2(a, b);
117}143}
118144fn __unordsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Unordered {
119/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."145 return @intFromBool(unord_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)));
120/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined
121/// to have the same return value.
122fn __nehf2(a: f16, b: f16) callconv(.c) i32 {
123 return __cmphf2(a, b);
124}146}
125147fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
126/// "These functions return a value less than zero if neither argument is NaN, and a148 return @intFromBool(unord_f32(a, b));
127/// is strictly less than b."
128fn __lthf2(a: f16, b: f16) callconv(.c) i32 {
129 return __cmphf2(a, b);
130}149}
131150pub fn cmp_f32(a: f32, b: f32) ?Order {
132fn __unordxf2(a: f80, b: f80) callconv(.c) i32 {151 return cmpf2(f32, a, b);
133 return unordcmp(f80, a, b);152}
153pub fn unord_f32(a: f32, b: f32) bool {
154 return unord(f32, a, b);
134}155}
135156
136pub fn __unordsf2(a: f32, b: f32) callconv(.c) i32 {157fn __cmpdf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order {
137 return unordcmp(f32, a, b);158 return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .gt;
159}
160fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
161 return @intFromBool(cmp_f64(a, b) == .eq);
162}
163fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
164 return @intFromBool(cmp_f64(a, b) == .lt);
165}
166fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
167 return @intFromBool(cmp_f64(a, b) orelse .gt != .gt);
168}
169fn __gedf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order {
170 return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .lt;
171}
172fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
173 return @intFromBool(cmp_f64(a, b) orelse .lt != .lt);
174}
175fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
176 return @intFromBool(cmp_f64(a, b) == .gt);
177}
178fn __unorddf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Unordered {
179 return @intFromBool(unord_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)));
180}
181fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
182 return @intFromBool(unord_f64(a, b));
183}
184pub fn cmp_f64(a: f64, b: f64) ?Order {
185 return cmpf2(f64, a, b);
186}
187pub fn unord_f64(a: f64, b: f64) bool {
188 return unord(f64, a, b);
138}189}
139190
140fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {191fn __cmpxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order {
141 return unordcmp(f32, a, b);192 return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .gt;
193}
194fn __gexf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order {
195 return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .lt;
142}196}
197fn __unordxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Unordered {
198 return @intFromBool(unord_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)));
199}
200pub fn cmp_f80(a: f80, b: f80) ?Order {
201 const a_rep = std.math.F80.fromFloat(a);
202 const b_rep = std.math.F80.fromFloat(b);
203 const sig_bits = std.math.floatMantissaBits(f80);
204 const int_bit = 0x8000000000000000;
205 const sign_bit = 0x8000;
206 const special_exp = 0x7FFF;
143207
144pub const LE = enum(i32) {208 // If either a or b is NaN, they are unordered.
145 Less = -1,209 if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or
146 Equal = 0,210 (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0))
147 Greater = 1,211 return null;
148212
149 const Unordered: LE = .Greater;213 // If a and b are both zeros, they are equal.
150};214 if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0)
215 return .eq;
151216
152pub const GE = enum(i32) {217 if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) {
153 Less = -1,218 return .eq;
154 Equal = 0,219 } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) {
155 Greater = 1,220 // signs are different
221 if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) {
222 return .lt;
223 } else {
224 return .gt;
225 }
226 } else {
227 const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits);
228 const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits);
229 if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) {
230 return .lt;
231 } else {
232 return .gt;
233 }
234 }
235}
236pub fn unord_f80(a: f80, b: f80) bool {
237 return unord(f80, a, b);
238}
156239
157 const Unordered: GE = .Less;240fn __cmptf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order {
158};241 return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .gt;
242}
243fn __getf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order {
244 return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .lt;
245}
246fn __unordtf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Unordered {
247 return @intFromBool(unord_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)));
248}
249fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) SparcOrder {
250 return switch (cmp_f128(a.*, b.*) orelse return .un) {
251 .lt => .lt,
252 .eq => .eq,
253 .gt => .gt,
254 };
255}
256fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) i32 {
257 return @intFromBool(cmp_f128(a.*, b.*) == .eq);
258}
259fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) i32 {
260 return @intFromBool(cmp_f128(a.*, b.*) != .eq);
261}
262fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) i32 {
263 return @intFromBool(cmp_f128(a.*, b.*) == .lt);
264}
265fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) i32 {
266 return @intFromBool((cmp_f128(a.*, b.*) orelse .gt) != .gt);
267}
268fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) i32 {
269 return @intFromBool(cmp_f128(a.*, b.*) == .gt);
270}
271fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) i32 {
272 return @intFromBool((cmp_f128(a.*, b.*) orelse .lt) != .lt);
273}
274fn _Q_cmp(a: f128, b: f128) callconv(.c) SparcOrder {
275 return switch (cmp_f128(a, b) orelse return .un) {
276 .lt => .lt,
277 .eq => .eq,
278 .gt => .gt,
279 };
280}
281fn _Q_feq(a: f128, b: f128) callconv(.c) i32 {
282 return @intFromBool(cmp_f128(a, b) == .eq);
283}
284fn _Q_fne(a: f128, b: f128) callconv(.c) i32 {
285 return @intFromBool(cmp_f128(a, b) != .eq);
286}
287fn _Q_flt(a: f128, b: f128) callconv(.c) i32 {
288 return @intFromBool(cmp_f128(a, b) == .lt);
289}
290fn _Q_fle(a: f128, b: f128) callconv(.c) i32 {
291 return @intFromBool((cmp_f128(a, b) orelse .gt) != .gt);
292}
293fn _Q_fgt(a: f128, b: f128) callconv(.c) i32 {
294 return @intFromBool(cmp_f128(a, b) == .gt);
295}
296fn _Q_fge(a: f128, b: f128) callconv(.c) i32 {
297 return @intFromBool((cmp_f128(a, b) orelse .lt) != .lt);
298}
299pub fn cmp_f128(a: f128, b: f128) ?Order {
300 return cmpf2(f128, a, b);
301}
302pub fn unord_f128(a: f128, b: f128) bool {
303 return unord(f128, a, b);
304}
159305
160pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT {306inline fn cmpf2(comptime T: type, a: T, b: T) ?Order {
161 const bits = @typeInfo(T).float.bits;307 const bits = @typeInfo(T).float.bits;
162 const srep_t = @Int(.signed, bits);308 const srep_t = @Int(.signed, bits);
163 const rep_t = @Int(.unsigned, bits);309 const rep_t = @Int(.unsigned, bits);
...@@ -175,81 +321,42 @@ pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT {...@@ -175,81 +321,42 @@ pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT {
175 const bAbs = @as(rep_t, @bitCast(bInt)) & absMask;321 const bAbs = @as(rep_t, @bitCast(bInt)) & absMask;
176322
177 // If either a or b is NaN, they are unordered.323 // If either a or b is NaN, they are unordered.
178 if (aAbs > infRep or bAbs > infRep) return RT.Unordered;324 if (aAbs > infRep or bAbs > infRep) return null;
179325
180 // If a and b are both zeros, they are equal.326 // If a and b are both zeros, they are equal.
181 if ((aAbs | bAbs) == 0) return .Equal;327 if ((aAbs | bAbs) == 0) return .eq;
182328
183 // If at least one of a and b is positive, we get the same result comparing329 // If at least one of a and b is positive, we get the same result comparing
184 // a and b as signed integers as we would with a floating-point compare.330 // a and b as signed integers as we would with a floating-point compare.
185 if ((aInt & bInt) >= 0) {331 if ((aInt & bInt) >= 0) {
186 if (aInt < bInt) {332 if (aInt < bInt) {
187 return .Less;333 return .lt;
188 } else if (aInt == bInt) {334 } else if (aInt == bInt) {
189 return .Equal;335 return .eq;
190 } else return .Greater;336 } else return .gt;
191 } else {337 } else {
192 // Otherwise, both are negative, so we need to flip the sense of the338 // Otherwise, both are negative, so we need to flip the sense of the
193 // comparison to get the correct result. (This assumes a twos- or ones-339 // comparison to get the correct result. (This assumes a twos- or ones-
194 // complement integer representation; if integers are represented in a340 // complement integer representation; if integers are represented in a
195 // sign-magnitude representation, then this flip is incorrect).341 // sign-magnitude representation, then this flip is incorrect).
196 if (aInt > bInt) {342 if (aInt > bInt) {
197 return .Less;343 return .lt;
198 } else if (aInt == bInt) {344 } else if (aInt == bInt) {
199 return .Equal;345 return .eq;
200 } else return .Greater;346 } else return .gt;
201 }347 }
202}348}
203349
204pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {350test cmp_f80 {
205 const a_rep = std.math.F80.fromFloat(a);351 try std.testing.expect(cmp_f80(1.0, 1.0) == .eq);
206 const b_rep = std.math.F80.fromFloat(b);352 try std.testing.expect(cmp_f80(0.0, -0.0) == .eq);
207 const sig_bits = std.math.floatMantissaBits(f80);353 try std.testing.expect(cmp_f80(2.0, 4.0) == .lt);
208 const int_bit = 0x8000000000000000;354 try std.testing.expect(cmp_f80(2.0, -4.0) == .gt);
209 const sign_bit = 0x8000;355 try std.testing.expect(cmp_f80(-2.0, -4.0) == .gt);
210 const special_exp = 0x7FFF;356 try std.testing.expect(cmp_f80(-2.0, 4.0) == .lt);
211
212 // If either a or b is NaN, they are unordered.
213 if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or
214 (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0))
215 return RT.Unordered;
216
217 // If a and b are both zeros, they are equal.
218 if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0)
219 return .Equal;
220
221 if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) {
222 return .Equal;
223 } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) {
224 // signs are different
225 if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) {
226 return .Less;
227 } else {
228 return .Greater;
229 }
230 } else {
231 const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits);
232 const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits);
233 if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) {
234 return .Less;
235 } else {
236 return .Greater;
237 }
238 }
239}
240
241test "cmp_f80" {
242 inline for (.{ LE, GE }) |RT| {
243 try std.testing.expect(cmp_f80(RT, 1.0, 1.0) == RT.Equal);
244 try std.testing.expect(cmp_f80(RT, 0.0, -0.0) == RT.Equal);
245 try std.testing.expect(cmp_f80(RT, 2.0, 4.0) == RT.Less);
246 try std.testing.expect(cmp_f80(RT, 2.0, -4.0) == RT.Greater);
247 try std.testing.expect(cmp_f80(RT, -2.0, -4.0) == RT.Greater);
248 try std.testing.expect(cmp_f80(RT, -2.0, 4.0) == RT.Less);
249 }
250}357}
251358
252pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {359inline fn unord(comptime T: type, a: T, b: T) bool {
253 const rep_t = @Int(.unsigned, @typeInfo(T).float.bits);360 const rep_t = @Int(.unsigned, @typeInfo(T).float.bits);
254361
255 const significandBits = std.math.floatMantissaBits(T);362 const significandBits = std.math.floatMantissaBits(T);
...@@ -261,7 +368,7 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {...@@ -261,7 +368,7 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {
261 const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask;368 const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask;
262 const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask;369 const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask;
263370
264 return @intFromBool(aAbs > infRep or bAbs > infRep);371 return aAbs > infRep or bAbs > infRep;
265}372}
266373
267test {374test {
lib/compiler_rt/comparesf2_test.zig+17-73
...@@ -5,52 +5,12 @@...@@ -5,52 +5,12 @@
5const std = @import("std");5const std = @import("std");
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
8const __eqsf2 = @import("./comparef.zig").__eqsf2;8const compiler_rt = @import("../compiler_rt.zig");
9const __lesf2 = @import("./comparef.zig").__lesf2;
10const __ltsf2 = @import("./comparef.zig").__ltsf2;
11const __nesf2 = @import("./comparef.zig").__nesf2;
129
13const __gesf2 = @import("./gesf2.zig").__gesf2;10const impl = @import("comparef.zig");
14const __gtsf2 = @import("./gesf2.zig").__gtsf2;11const Order = impl.Order;
1512const cmp_f32 = impl.cmp_f32;
16const __unordsf2 = @import("./comparef.zig").__unordsf2;13const unord_f32 = impl.unord_f32;
17
18const TestVector = struct {
19 a: f32,
20 b: f32,
21 eqReference: c_int,
22 geReference: c_int,
23 gtReference: c_int,
24 leReference: c_int,
25 ltReference: c_int,
26 neReference: c_int,
27 unReference: c_int,
28};
29
30fn test__cmpsf2(vector: TestVector) bool {
31 if (__eqsf2(vector.a, vector.b) != vector.eqReference) {
32 return false;
33 }
34 if (__gesf2(vector.a, vector.b) != vector.geReference) {
35 return false;
36 }
37 if (__gtsf2(vector.a, vector.b) != vector.gtReference) {
38 return false;
39 }
40 if (__lesf2(vector.a, vector.b) != vector.leReference) {
41 return false;
42 }
43 if (__ltsf2(vector.a, vector.b) != vector.ltReference) {
44 return false;
45 }
46 if (__nesf2(vector.a, vector.b) != vector.neReference) {
47 return false;
48 }
49 if (__unordsf2(vector.a, vector.b) != vector.unReference) {
50 return false;
51 }
52 return true;
53}
5414
55const arguments = [_]f32{15const arguments = [_]f32{
56 std.math.nan(f32),16 std.math.nan(f32),
...@@ -73,36 +33,20 @@ const arguments = [_]f32{...@@ -73,36 +33,20 @@ const arguments = [_]f32{
73 std.math.inf(f32),33 std.math.inf(f32),
74};34};
7535
76fn generateVector(comptime a: f32, comptime b: f32) TestVector {36test "compare f32" {
77 const leResult = if (a < b) -1 else if (a == b) 0 else 1;
78 const geResult = if (a > b) 1 else if (a == b) 0 else -1;
79 const unResult = if (a != a or b != b) 1 else 0;
80 return TestVector{
81 .a = a,
82 .b = b,
83 .eqReference = leResult,
84 .geReference = geResult,
85 .gtReference = geResult,
86 .leReference = leResult,
87 .ltReference = leResult,
88 .neReference = leResult,
89 .unReference = unResult,
90 };
91}
92
93const test_vectors = init: {
94 @setEvalBranchQuota(10000);
95 var vectors: [arguments.len * arguments.len]TestVector = undefined;
96 for (arguments[0..], 0..) |arg_i, i| {37 for (arguments[0..], 0..) |arg_i, i| {
97 for (arguments[0..], 0..) |arg_j, j| {38 for (arguments[0..], 0..) |arg_j, j| {
98 vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j);39 const expected_unord = i == 0 or j == 0;
40 const expected_order: ?Order = if (expected_unord) null else switch (std.math.order(
41 i - @intFromBool(i >= 9),
42 j - @intFromBool(j >= 9),
43 )) {
44 .lt => .lt,
45 .eq => .eq,
46 .gt => .gt,
47 };
48 try std.testing.expect(expected_order == cmp_f32(arg_i, arg_j));
49 try std.testing.expect(expected_unord == unord_f32(arg_i, arg_j));
99 }50 }
100 }51 }
101 break :init vectors;
102};
103
104test "compare f32" {
105 for (test_vectors) |vector| {
106 try std.testing.expect(test__cmpsf2(vector));
107 }
108}52}
lib/compiler_rt/cos.zig+64-51
...@@ -13,31 +13,34 @@ const expect = std.testing.expect;...@@ -13,31 +13,34 @@ const expect = std.testing.expect;
13const expectApproxEqAbs = std.testing.expectApproxEqAbs;13const expectApproxEqAbs = std.testing.expectApproxEqAbs;
1414
15const compiler_rt = @import("../compiler_rt.zig");15const compiler_rt = @import("../compiler_rt.zig");
16const symbol = @import("../compiler_rt.zig").symbol;16const symbol = compiler_rt.symbol;
17const trig = @import("trig.zig");17const trig = @import("trig.zig");
18const rem_pio2 = @import("rem_pio2.zig").rem_pio2;18const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
19const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;19const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
20const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;20const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
2121
22comptime {22comptime {
23 symbol(&cosh, "__cosh");23 symbol(&__cosh, "__cosh");
24 symbol(&cosl, "__cosl");
25 symbol(&cosf, "cosf");24 symbol(&cosf, "cosf");
26 symbol(&cos, "cos");25 symbol(&cos, "cos");
27 symbol(&cosx, "__cosx");26 symbol(&__cosx, "__cosx");
28 if (compiler_rt.want_ppc_abi) {27 symbol(&cosq, "cosf128");
29 symbol(&cosq, "cosf128");
30 }
31 symbol(&cosq, "cosq");
32 symbol(&cosl, "cosl");28 symbol(&cosl, "cosl");
29 symbol(&cosl, "__cosl"); // required by musl
33}30}
3431
35pub fn cosh(a: f16) callconv(.c) f16 {32fn __cosh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
33 return compiler_rt.f16.toAbi(cos_f16(compiler_rt.f16.fromAbi(x)));
34}
35pub fn cos_f16(x: f16) f16 {
36 // TODO: more efficient implementation36 // TODO: more efficient implementation
37 return @floatCast(cosf(a));37 return @floatCast(cos_f32(x));
38}38}
3939
40pub fn cosf(x: f32) callconv(.c) f32 {40fn cosf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
41 return compiler_rt.f32.toAbi(cos_f32(compiler_rt.f32.fromAbi(x)));
42}
43pub fn cos_f32(x: f32) f32 {
41 // Small multiples of pi/2 rounded to double precision.44 // Small multiples of pi/2 rounded to double precision.
42 const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D1845 const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
43 const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D1846 const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
...@@ -94,7 +97,10 @@ pub fn cosf(x: f32) callconv(.c) f32 {...@@ -94,7 +97,10 @@ pub fn cosf(x: f32) callconv(.c) f32 {
94 };97 };
95}98}
9699
97pub fn cos(x: f64) callconv(.c) f64 {100fn cos(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
101 return compiler_rt.f64.toAbi(cos_f64(compiler_rt.f64.fromAbi(x)));
102}
103pub fn cos_f64(x: f64) f64 {
98 var ix = @as(u64, @bitCast(x)) >> 32;104 var ix = @as(u64, @bitCast(x)) >> 32;
99 ix &= 0x7fffffff;105 ix &= 0x7fffffff;
100106
...@@ -123,7 +129,10 @@ pub fn cos(x: f64) callconv(.c) f64 {...@@ -123,7 +129,10 @@ pub fn cos(x: f64) callconv(.c) f64 {
123 };129 };
124}130}
125131
126pub fn cosx(x: f80) callconv(.c) f80 {132fn __cosx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
133 return compiler_rt.f80.toAbi(cos_f80(compiler_rt.f80.fromAbi(x)));
134}
135pub fn cos_f80(x: f80) f80 {
127 const se = ld.signExponent(x) & 0x7fff;136 const se = ld.signExponent(x) & 0x7fff;
128 if (se == 0x7fff) {137 if (se == 0x7fff) {
129 return x - x;138 return x - x;
...@@ -147,7 +156,10 @@ pub fn cosx(x: f80) callconv(.c) f80 {...@@ -147,7 +156,10 @@ pub fn cosx(x: f80) callconv(.c) f80 {
147 };156 };
148}157}
149158
150pub fn cosq(x: f128) callconv(.c) f128 {159fn cosq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
160 return compiler_rt.f128.toAbi(cos_f128(compiler_rt.f128.fromAbi(x)));
161}
162pub fn cos_f128(x: f128) f128 {
151 const se = ld.signExponent(x) & 0x7fff;163 const se = ld.signExponent(x) & 0x7fff;
152 if (se == 0x7fff) {164 if (se == 0x7fff) {
153 return x - x;165 return x - x;
...@@ -173,20 +185,21 @@ pub fn cosq(x: f128) callconv(.c) f128 {...@@ -173,20 +185,21 @@ pub fn cosq(x: f128) callconv(.c) f128 {
173185
174pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble {186pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble {
175 switch (@typeInfo(c_longdouble).float.bits) {187 switch (@typeInfo(c_longdouble).float.bits) {
176 64 => return cos(x),188 64 => return cos_f64(x),
177 80 => return cosx(x),189 80 => return cos_f80(x),
178 128 => return cosq(x),190 128 => return cos_f128(x),
179 else => @compileError("unreachable"),191 else => comptime unreachable,
180 }192 }
181}193}
182194
183fn testCosSpecial(comptime T: type) !void {195fn testCosSpecial(comptime T: type) !void {
184 const f = switch (T) {196 const f = switch (T) {
185 f32 => cosf,197 f16 => cos_f16,
186 f64 => cos,198 f32 => cos_f32,
187 f80 => cosx,199 f64 => cos_f64,
188 f128 => cosq,200 f80 => cos_f80,
189 else => @compileError("unimplemented"),201 f128 => cos_f128,
202 else => comptime unreachable,
190 };203 };
191204
192 try expect(f(0.0) == 1.0);205 try expect(f(0.0) == 1.0);
...@@ -198,13 +211,13 @@ fn testCosSpecial(comptime T: type) !void {...@@ -198,13 +211,13 @@ fn testCosSpecial(comptime T: type) !void {
198211
199test "cos32.normal" {212test "cos32.normal" {
200 const epsilon = math.floatEps(f32);213 const epsilon = math.floatEps(f32);
201 try expectApproxEqAbs(@as(f32, 1.0), cosf(0.0), epsilon);214 try expectApproxEqAbs(@as(f32, 1.0), cos_f32(0.0), epsilon);
202 try expectApproxEqAbs(@as(f32, 0.9800666), cosf(0.2), epsilon);215 try expectApproxEqAbs(@as(f32, 0.9800666), cos_f32(0.2), epsilon);
203 try expectApproxEqAbs(@as(f32, 0.6276231), cosf(0.8923), epsilon);216 try expectApproxEqAbs(@as(f32, 0.6276231), cos_f32(0.8923), epsilon);
204 try expectApproxEqAbs(@as(f32, 0.0707372), cosf(1.5), epsilon);217 try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(1.5), epsilon);
205 try expectApproxEqAbs(@as(f32, 0.0707372), cosf(-1.5), epsilon);218 try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(-1.5), epsilon);
206 try expectApproxEqAbs(@as(f32, 0.96913195), cosf(37.45), epsilon);219 try expectApproxEqAbs(@as(f32, 0.96913195), cos_f32(37.45), epsilon);
207 try expectApproxEqAbs(@as(f32, 0.40079966), cosf(89.123), epsilon);220 try expectApproxEqAbs(@as(f32, 0.40079966), cos_f32(89.123), epsilon);
208}221}
209222
210test "cos32.special" {223test "cos32.special" {
...@@ -213,13 +226,13 @@ test "cos32.special" {...@@ -213,13 +226,13 @@ test "cos32.special" {
213226
214test "cos64.normal" {227test "cos64.normal" {
215 const epsilon = math.floatEps(f64);228 const epsilon = math.floatEps(f64);
216 try expectApproxEqAbs(@as(f64, 1.0), cos(0.0), epsilon);229 try expectApproxEqAbs(@as(f64, 1.0), cos_f64(0.0), epsilon);
217 try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos(0.2), epsilon);230 try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos_f64(0.2), epsilon);
218 try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos(0.8923), epsilon);231 try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos_f64(0.8923), epsilon);
219 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(1.5), epsilon);232 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(1.5), epsilon);
220 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(-1.5), epsilon);233 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(-1.5), epsilon);
221 try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos(37.45), epsilon);234 try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos_f64(37.45), epsilon);
222 try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos(89.123), epsilon);235 try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos_f64(89.123), epsilon);
223}236}
224237
225test "cos64.special" {238test "cos64.special" {
...@@ -228,13 +241,13 @@ test "cos64.special" {...@@ -228,13 +241,13 @@ test "cos64.special" {
228241
229test "cos80.normal" {242test "cos80.normal" {
230 const epsilon = math.floatEps(f80);243 const epsilon = math.floatEps(f80);
231 try expectApproxEqAbs(@as(f80, 1.0), cosx(0.0), epsilon);244 try expectApproxEqAbs(@as(f80, 1.0), cos_f80(0.0), epsilon);
232 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cosx(0.2), epsilon);245 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cos_f80(0.2), epsilon);
233 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cosx(0.8923), epsilon);246 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cos_f80(0.8923), epsilon);
234 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(1.5), epsilon);247 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(1.5), epsilon);
235 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(-1.5), epsilon);248 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(-1.5), epsilon);
236 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cosx(37.45), epsilon);249 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cos_f80(37.45), epsilon);
237 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cosx(89.123), epsilon);250 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cos_f80(89.123), epsilon);
238}251}
239252
240test "cos80.special" {253test "cos80.special" {
...@@ -243,13 +256,13 @@ test "cos80.special" {...@@ -243,13 +256,13 @@ test "cos80.special" {
243256
244test "cos128.normal" {257test "cos128.normal" {
245 const epsilon = math.floatEps(f128);258 const epsilon = math.floatEps(f128);
246 try expectApproxEqAbs(@as(f128, 1.0), cosq(0.0), epsilon);259 try expectApproxEqAbs(@as(f128, 1.0), cos_f128(0.0), epsilon);
247 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cosq(0.2), epsilon);260 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cos_f128(0.2), epsilon);
248 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cosq(0.8923), epsilon);261 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cos_f128(0.8923), epsilon);
249 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(1.5), epsilon);262 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(1.5), epsilon);
250 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(-1.5), epsilon);263 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(-1.5), epsilon);
251 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cosq(37.45), epsilon);264 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cos_f128(37.45), epsilon);
252 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cosq(89.123), epsilon);265 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cos_f128(89.123), epsilon);
253}266}
254267
255test "cos128.special" {268test "cos128.special" {
lib/compiler_rt/count0bits.zig+2-1
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const std = @import("std");2const std = @import("std");
3const symbol = @import("../compiler_rt.zig").symbol;3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
45
5comptime {6comptime {
6 symbol(&__clzsi2, "__clzsi2");7 symbol(&__clzsi2, "__clzsi2");
lib/compiler_rt/divc3.zig+78-5
...@@ -7,12 +7,81 @@ const maxInt = std.math.maxInt;...@@ -7,12 +7,81 @@ const maxInt = std.math.maxInt;
7const minInt = std.math.minInt;7const minInt = std.math.minInt;
8const isFinite = std.math.isFinite;8const isFinite = std.math.isFinite;
9const copysign = std.math.copysign;9const copysign = std.math.copysign;
10const Complex = @import("mulc3.zig").Complex;10
11const compiler_rt = @import("../compiler_rt.zig");
12const symbol = compiler_rt.symbol;
13const Complex = compiler_rt.Complex;
14
15comptime {
16 if (@import("builtin").zig_backend != .stage2_c) {
17 symbol(&__divhc3, "__divhc3");
18 symbol(&__divsc3, "__divsc3");
19 symbol(&__divdc3, "__divdc3");
20 symbol(&__divxc3, "__divxc3");
21 if (compiler_rt.want_ppc_abi) {
22 symbol(&__divtc3, "__divkc3");
23 } else {
24 symbol(&__divtc3, "__divtc3");
25 }
26 }
27}
28
29fn __divhc3(lhs_real: compiler_rt.f16.Abi, lhs_imag: compiler_rt.f16.Abi, rhs_real: compiler_rt.f16.Abi, rhs_imag: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.complex.Abi {
30 return compiler_rt.f16.complex.toAbi(div_cf16(
31 compiler_rt.f16.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
32 compiler_rt.f16.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
33 ));
34}
35pub fn div_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) {
36 return divc3(f16, a, b);
37}
38
39fn __divsc3(lhs_real: compiler_rt.f32.Abi, lhs_imag: compiler_rt.f32.Abi, rhs_real: compiler_rt.f32.Abi, rhs_imag: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.complex.Abi {
40 return compiler_rt.f32.complex.toAbi(div_cf32(
41 compiler_rt.f32.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
42 compiler_rt.f32.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
43 ));
44}
45pub fn div_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) {
46 return divc3(f32, a, b);
47}
48
49fn __divdc3(lhs_real: compiler_rt.f64.Abi, lhs_imag: compiler_rt.f64.Abi, rhs_real: compiler_rt.f64.Abi, rhs_imag: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.complex.Abi {
50 return compiler_rt.f64.complex.toAbi(div_cf64(
51 compiler_rt.f64.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
52 compiler_rt.f64.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
53 ));
54}
55pub fn div_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) {
56 return divc3(f64, a, b);
57}
58
59fn __divxc3(lhs_real: compiler_rt.f80.Abi, lhs_imag: compiler_rt.f80.Abi, rhs_real: compiler_rt.f80.Abi, rhs_imag: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.complex.Abi {
60 return compiler_rt.f80.complex.toAbi(div_cf80(
61 compiler_rt.f80.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
62 compiler_rt.f80.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
63 ));
64}
65pub fn div_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) {
66 return divc3(f80, a, b);
67}
68
69fn __divtc3(lhs_real: compiler_rt.f128.Abi, lhs_imag: compiler_rt.f128.Abi, rhs_real: compiler_rt.f128.Abi, rhs_imag: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.complex.Abi {
70 return compiler_rt.f128.complex.toAbi(div_cf128(
71 compiler_rt.f128.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
72 compiler_rt.f128.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
73 ));
74}
75pub fn div_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) {
76 return divc3(f128, a, b);
77}
1178
12/// Implementation based on Annex G of C17 Standard (N2176)79/// Implementation based on Annex G of C17 Standard (N2176)
13pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) {80inline fn divc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) {
14 var c = c_in;81 const a = lhs.real;
15 var d = d_in;82 const b = lhs.imag;
83 var c = rhs.real;
84 var d = rhs.imag;
1685
17 // logbw used to prevent under/over-flow86 // logbw used to prevent under/over-flow
18 const logbw = ilogb(@max(@abs(c), @abs(d)));87 const logbw = ilogb(@max(@abs(c), @abs(d)));
...@@ -23,7 +92,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) {...@@ -23,7 +92,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) {
23 break :b logbw;92 break :b logbw;
24 } else 0;93 } else 0;
25 const denom = c * c + d * d;94 const denom = c * c + d * d;
26 const result = Complex(T){95 const result: Complex(T) = .{
27 .real = scalbn((a * c + b * d) / denom, -ilogbw),96 .real = scalbn((a * c + b * d) / denom, -ilogbw),
28 .imag = scalbn((b * c - a * d) / denom, -ilogbw),97 .imag = scalbn((b * c - a * d) / denom, -ilogbw),
29 };98 };
...@@ -58,3 +127,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) {...@@ -58,3 +127,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) {
58127
59 return result;128 return result;
60}129}
130
131test {
132 _ = @import("divc3_test.zig");
133}
lib/compiler_rt/divc3_test.zig+28-51
...@@ -2,76 +2,53 @@ const std = @import("std");...@@ -2,76 +2,53 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5const Complex = @import("./mulc3.zig").Complex;5const Complex = @import("../compiler_rt.zig").Complex;
6const __divhc3 = @import("./divhc3.zig").__divhc3;6
7const __divsc3 = @import("./divsc3.zig").__divsc3;7const impl = @import("divc3.zig");
8const __divdc3 = @import("./divdc3.zig").__divdc3;8const div_cf16 = impl.div_cf16;
9const __divxc3 = @import("./divxc3.zig").__divxc3;9const div_cf32 = impl.div_cf32;
10const __divtc3 = @import("./divtc3.zig").__divtc3;10const div_cf64 = impl.div_cf64;
11const div_cf80 = impl.div_cf80;
12const div_cf128 = impl.div_cf128;
1113
12test "divc3" {14test "divc3" {
13 try testDiv(f16, __divhc3);15 try testDiv(f16, div_cf16);
14 try testDiv(f32, __divsc3);16 try testDiv(f32, div_cf32);
15 try testDiv(f64, __divdc3);17 try testDiv(f64, div_cf64);
16 try testDiv(f80, __divxc3);18 try testDiv(f80, div_cf80);
17 try testDiv(f128, __divtc3);19 try testDiv(f128, div_cf128);
18}20}
1921
20fn testDiv(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void {22fn testDiv(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void {
21 {23 {
22 const a: T = 1.0;24 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 });
23 const b: T = 0.0;
24 const c: T = -1.0;
25 const d: T = 0.0;
26
27 const result = f(a, b, c, d);
28 try expect(result.real == -1.0);25 try expect(result.real == -1.0);
29 try expect(result.imag == 0.0);26 try expect(math.isNegativeZero(result.imag));
30 }27 }
31 {28 {
32 const a: T = 1.0;29 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 });
33 const b: T = 0.0;
34 const c: T = -4.0;
35 const d: T = 0.0;
36
37 const result = f(a, b, c, d);
38 try expect(result.real == -0.25);30 try expect(result.real == -0.25);
39 try expect(result.imag == 0.0);31 try expect(math.isNegativeZero(result.imag));
40 }32 }
41 {33 {
42 // if the first operand is an infinity and the second operand is a finite number, then the34 // if the first operand is an infinity and the second operand is a finite number, then the
43 // result of the / operator is an infinity;35 // resultult of the / operator is an infinity;
44 const a: T = -math.inf(T);36 const result = f(.{ .real = -math.inf(T), .imag = 0.0 }, .{ .real = -4.0, .imag = 1.0 });
45 const b: T = 0.0;37 try expect(math.isPositiveInf(result.real));
46 const c: T = -4.0;38 try expect(math.isPositiveInf(result.imag));
47 const d: T = 1.0;
48
49 const result = f(a, b, c, d);
50 try expect(result.real == math.inf(T));
51 try expect(result.imag == math.inf(T));
52 }39 }
53 {40 {
54 // if the first operand is a finite number and the second operand is an infinity, then the41 // if the first operand is a finite number and the second operand is an infinity, then the
55 // result of the / operator is a zero;42 // result of the / operator is a zero;
56 const a: T = 17.2;43 const result = f(.{ .real = 17.2, .imag = 0.0 }, .{ .real = -math.inf(T), .imag = 0.0 });
57 const b: T = 0.0;44 try expect(math.isNegativeZero(result.real));
58 const c: T = -math.inf(T);45 try expect(math.isNegativeZero(result.imag));
59 const d: T = 0.0;
60
61 const result = f(a, b, c, d);
62 try expect(result.real == -0.0);
63 try expect(result.imag == 0.0);
64 }46 }
65 {47 {
66 // if the first operand is a nonzero finite number or an infinity and the second operand is48 // if the first operand is a nonzero finite number or an infinity and the second operand is
67 // a zero, then the result of the / operator is an infinity49 // a zero, then the result of the / operator is an infinity
68 const a: T = 1.1;50 const result = f(.{ .real = 1.1, .imag = 0.1 }, .{ .real = 0.0, .imag = 0.0 });
69 const b: T = 0.1;51 try expect(math.isPositiveInf(result.real));
70 const c: T = 0.0;52 try expect(math.isPositiveInf(result.imag));
71 const d: T = 0.0;
72
73 const result = f(a, b, c, d);
74 try expect(result.real == math.inf(T));
75 try expect(result.imag == math.inf(T));
76 }53 }
77}54}
lib/compiler_rt/divdc3.zig deleted-13
...@@ -1,13 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const divc3 = @import("./divc3.zig");
3const Complex = @import("./mulc3.zig").Complex;
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__divdc3, "__divdc3");
8 }
9}
10
11pub fn __divdc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) Complex(f64) {
12 return divc3.divc3(f64, a, b, c, d);
13}
lib/compiler_rt/divdf3.zig+4-4
...@@ -17,15 +17,15 @@ comptime {...@@ -17,15 +17,15 @@ comptime {
17 }17 }
18}18}
1919
20pub fn __divdf3(a: f64, b: f64) callconv(.c) f64 {20fn __divdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
21 return div(a, b);21 return compiler_rt.f64.toAbi(div_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)));
22}22}
2323
24fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {24fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
25 return div(a, b);25 return div_f64(a, b);
26}26}
2727
28inline fn div(a: f64, b: f64) f64 {28pub fn div_f64(a: f64, b: f64) f64 {
29 const Z = @Int(.unsigned, 64);29 const Z = @Int(.unsigned, 64);
30 const SignedZ = @Int(.signed, 64);30 const SignedZ = @Int(.signed, 64);
3131
lib/compiler_rt/divdf3_test.zig+2-2
...@@ -6,7 +6,7 @@ const std = @import("std");...@@ -6,7 +6,7 @@ const std = @import("std");
6const math = std.math;6const math = std.math;
7const testing = std.testing;7const testing = std.testing;
88
9const __divdf3 = @import("divdf3.zig").__divdf3;9const div_f64 = @import("divdf3.zig").div_f64;
1010
11const nanRep: u64 = @as(u64, @bitCast(math.nan(f64)));11const nanRep: u64 = @as(u64, @bitCast(math.nan(f64)));
12const infRep: u64 = @as(u64, @bitCast(math.inf(f64)));12const infRep: u64 = @as(u64, @bitCast(math.inf(f64)));
...@@ -30,7 +30,7 @@ fn compareResultD(result: f64, expected: u64) bool {...@@ -30,7 +30,7 @@ fn compareResultD(result: f64, expected: u64) bool {
30}30}
3131
32fn test__divdf3(a: f64, b: f64, expected: u64) !void {32fn test__divdf3(a: f64, b: f64, expected: u64) !void {
33 const x = __divdf3(a, b);33 const x = div_f64(a, b);
34 const ret = compareResultD(x, expected);34 const ret = compareResultD(x, expected);
35 try testing.expect(ret == true);35 try testing.expect(ret == true);
36}36}
lib/compiler_rt/divhc3.zig deleted-14
...@@ -1,14 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const divc3 = @import("./divc3.zig");
4const Complex = @import("./mulc3.zig").Complex;
5
6comptime {
7 if (@import("builtin").zig_backend != .stage2_c) {
8 symbol(&__divhc3, "__divhc3");
9 }
10}
11
12pub fn __divhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) Complex(f16) {
13 return divc3.divc3(f16, a, b, c, d);
14}
lib/compiler_rt/divhf3.zig deleted-11
...@@ -1,11 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const divsf3 = @import("./divsf3.zig");
3
4comptime {
5 symbol(&__divhf3, "__divhf3");
6}
7
8pub fn __divhf3(a: f16, b: f16) callconv(.c) f16 {
9 // TODO: more efficient implementation
10 return @floatCast(divsf3.__divsf3(a, b));
11}
lib/compiler_rt/divmodei4.zig+1-1
...@@ -5,7 +5,7 @@ const std = @import("std");...@@ -5,7 +5,7 @@ const std = @import("std");
55
6const compiler_rt = @import("../compiler_rt.zig");6const compiler_rt = @import("../compiler_rt.zig");
7const udivmod = @import("udivmodei4.zig").divmod;7const udivmod = @import("udivmodei4.zig").divmod;
8const symbol = @import("../compiler_rt.zig").symbol;8const symbol = compiler_rt.symbol;
99
10comptime {10comptime {
11 symbol(&__divei4, "__divei4");11 symbol(&__divei4, "__divei4");
lib/compiler_rt/divsc3.zig deleted-13
...@@ -1,13 +0,0 @@
1const divc3 = @import("./divc3.zig");
2const Complex = @import("./mulc3.zig").Complex;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__divsc3, "__divsc3");
8 }
9}
10
11pub fn __divsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) Complex(f32) {
12 return divc3.divc3(f32, a, b, c, d);
13}
lib/compiler_rt/divsf3.zig+13-4
...@@ -9,6 +9,7 @@ const symbol = compiler_rt.symbol;...@@ -9,6 +9,7 @@ const symbol = compiler_rt.symbol;
9const normalize = compiler_rt.normalize;9const normalize = compiler_rt.normalize;
1010
11comptime {11comptime {
12 symbol(&__divhf3, "__divhf3");
12 if (compiler_rt.want_aeabi) {13 if (compiler_rt.want_aeabi) {
13 symbol(&__aeabi_fdiv, "__aeabi_fdiv");14 symbol(&__aeabi_fdiv, "__aeabi_fdiv");
14 } else {15 } else {
...@@ -16,15 +17,23 @@ comptime {...@@ -16,15 +17,23 @@ comptime {
16 }17 }
17}18}
1819
19pub fn __divsf3(a: f32, b: f32) callconv(.c) f32 {20fn __divhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
20 return div(a, b);21 return compiler_rt.f16.toAbi(div_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
22}
23pub fn div_f16(a: f16, b: f16) f16 {
24 // TODO: more efficient implementation
25 return @floatCast(div_f32(a, b));
26}
27
28fn __divsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
29 return compiler_rt.f32.toAbi(div_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)));
21}30}
2231
23fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {32fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
24 return div(a, b);33 return div_f32(a, b);
25}34}
2635
27inline fn div(a: f32, b: f32) f32 {36pub fn div_f32(a: f32, b: f32) f32 {
28 const Z = @Int(.unsigned, 32);37 const Z = @Int(.unsigned, 32);
2938
30 const significandBits = std.math.floatMantissaBits(f32);39 const significandBits = std.math.floatMantissaBits(f32);
lib/compiler_rt/divsf3_test.zig+2-2
...@@ -6,7 +6,7 @@ const std = @import("std");...@@ -6,7 +6,7 @@ const std = @import("std");
6const math = std.math;6const math = std.math;
7const testing = std.testing;7const testing = std.testing;
88
9const __divsf3 = @import("divsf3.zig").__divsf3;9const div_f32 = @import("divsf3.zig").div_f32;
1010
11const nanRep: u32 = @as(u32, @bitCast(math.nan(f32)));11const nanRep: u32 = @as(u32, @bitCast(math.nan(f32)));
12const infRep: u32 = @as(u32, @bitCast(math.inf(f32)));12const infRep: u32 = @as(u32, @bitCast(math.inf(f32)));
...@@ -30,7 +30,7 @@ fn compareResultF(result: f32, expected: u32) bool {...@@ -30,7 +30,7 @@ fn compareResultF(result: f32, expected: u32) bool {
30}30}
3131
32fn test__divsf3(a: f32, b: f32, expected: u32) !void {32fn test__divsf3(a: f32, b: f32, expected: u32) !void {
33 const x = __divsf3(a, b);33 const x = div_f32(a, b);
34 const ret = compareResultF(x, expected);34 const ret = compareResultF(x, expected);
35 try testing.expect(ret == true);35 try testing.expect(ret == true);
36}36}
lib/compiler_rt/divtc3.zig deleted-16
...@@ -1,16 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const divc3 = @import("./divc3.zig");
3const Complex = @import("./mulc3.zig").Complex;
4const symbol = @import("../compiler_rt.zig").symbol;
5
6comptime {
7 if (@import("builtin").zig_backend != .stage2_c) {
8 if (compiler_rt.want_ppc_abi)
9 symbol(&__divtc3, "__divkc3");
10 symbol(&__divtc3, "__divtc3");
11 }
12}
13
14pub fn __divtc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) Complex(f128) {
15 return divc3.divc3(f128, a, b, c, d);
16}
lib/compiler_rt/divtf3.zig+6-5
...@@ -13,19 +13,20 @@ comptime {...@@ -13,19 +13,20 @@ comptime {
13 symbol(&_Qp_div, "_Qp_div");13 symbol(&_Qp_div, "_Qp_div");
14 } else if (compiler_rt.want_sparc32_abi) {14 } else if (compiler_rt.want_sparc32_abi) {
15 symbol(&__divtf3, "_Q_div");15 symbol(&__divtf3, "_Q_div");
16 } else {
17 symbol(&__divtf3, "__divtf3");
16 }18 }
17 symbol(&__divtf3, "__divtf3");
18}19}
1920
20pub fn __divtf3(a: f128, b: f128) callconv(.c) f128 {21fn __divtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
21 return div(a, b);22 return compiler_rt.f128.toAbi(div_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)));
22}23}
2324
24fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {25fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {
25 c.* = div(a.*, b.*);26 c.* = div_f128(a.*, b.*);
26}27}
2728
28inline fn div(a: f128, b: f128) f128 {29pub fn div_f128(a: f128, b: f128) f128 {
29 const Z = @Int(.unsigned, 128);30 const Z = @Int(.unsigned, 128);
3031
31 const significandBits = std.math.floatMantissaBits(f128);32 const significandBits = std.math.floatMantissaBits(f128);
lib/compiler_rt/divtf3_test.zig+2-2
...@@ -2,7 +2,7 @@ const std = @import("std");...@@ -2,7 +2,7 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const testing = std.testing;3const testing = std.testing;
44
5const __divtf3 = @import("divtf3.zig").__divtf3;5const div_f128 = @import("divtf3.zig").div_f128;
66
7fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {7fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
8 const rep: u128 = @bitCast(result);8 const rep: u128 = @bitCast(result);
...@@ -24,7 +24,7 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {...@@ -24,7 +24,7 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
24}24}
2525
26fn test__divtf3(a: f128, b: f128, expectedHi: u64, expectedLo: u64) !void {26fn test__divtf3(a: f128, b: f128, expectedHi: u64, expectedLo: u64) !void {
27 const x = __divtf3(a, b);27 const x = div_f128(a, b);
28 const ret = compareResultLD(x, expectedHi, expectedLo);28 const ret = compareResultLD(x, expectedHi, expectedLo);
29 try testing.expect(ret == true);29 try testing.expect(ret == true);
30}30}
lib/compiler_rt/divxc3.zig deleted-13
...@@ -1,13 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const divc3 = @import("./divc3.zig");
3const Complex = @import("./mulc3.zig").Complex;
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__divxc3, "__divxc3");
8 }
9}
10
11pub fn __divxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) Complex(f80) {
12 return divc3.divc3(f80, a, b, c, d);
13}
lib/compiler_rt/divxf3.zig+4-1
...@@ -11,7 +11,10 @@ comptime {...@@ -11,7 +11,10 @@ comptime {
11 symbol(&__divxf3, "__divxf3");11 symbol(&__divxf3, "__divxf3");
12}12}
1313
14pub fn __divxf3(a: f80, b: f80) callconv(.c) f80 {14fn __divxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
15 return compiler_rt.f80.toAbi(div_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)));
16}
17pub fn div_f80(a: f80, b: f80) f80 {
15 const T = f80;18 const T = f80;
16 const Z = @Int(.unsigned, @bitSizeOf(T));19 const Z = @Int(.unsigned, @bitSizeOf(T));
1720
lib/compiler_rt/divxf3_test.zig+3-3
...@@ -2,7 +2,7 @@ const std = @import("std");...@@ -2,7 +2,7 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const testing = std.testing;3const testing = std.testing;
44
5const __divxf3 = @import("divxf3.zig").__divxf3;5const div_f80 = @import("divxf3.zig").div_f80;
66
7const nanRep: u80 = @as(u80, @bitCast(math.nan(f80)));7const nanRep: u80 = @as(u80, @bitCast(math.nan(f80)));
8const infRep: u80 = @as(u80, @bitCast(math.inf(f80)));8const infRep: u80 = @as(u80, @bitCast(math.inf(f80)));
...@@ -19,14 +19,14 @@ fn compareResult(result: f80, expected: u80) bool {...@@ -19,14 +19,14 @@ fn compareResult(result: f80, expected: u80) bool {
19}19}
2020
21fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void {21fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void {
22 const x = __divxf3(a, b);22 const x = div_f80(a, b);
23 const ret = compareResult(x, expected);23 const ret = compareResult(x, expected);
24 try testing.expect(ret == true);24 try testing.expect(ret == true);
25}25}
2626
27fn test__divxf3(a: f80, b: f80) !void {27fn test__divxf3(a: f80, b: f80) !void {
28 const integerBit = 1 << math.floatFractionalBits(f80);28 const integerBit = 1 << math.floatFractionalBits(f80);
29 const x = __divxf3(a, b);29 const x = div_f80(a, b);
3030
31 // Next float (assuming normal, non-zero result)31 // Next float (assuming normal, non-zero result)
32 const x_plus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) + 1) | integerBit);32 const x_plus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) + 1) | integerBit);
lib/compiler_rt/exp.zig+105-94
...@@ -14,26 +14,29 @@ const expect = std.testing.expect;...@@ -14,26 +14,29 @@ const expect = std.testing.expect;
14const expectEqual = std.testing.expectEqual;14const expectEqual = std.testing.expectEqual;
1515
16const compiler_rt = @import("../compiler_rt.zig");16const compiler_rt = @import("../compiler_rt.zig");
17const symbol = @import("../compiler_rt.zig").symbol;17const symbol = compiler_rt.symbol;
1818
19comptime {19comptime {
20 symbol(&__exph, "__exph");20 symbol(&__exph, "__exph");
21 symbol(&expf, "expf");21 symbol(&expf, "expf");
22 symbol(&exp, "exp");22 symbol(&exp, "exp");
23 symbol(&__expx, "__expx");23 symbol(&__expx, "__expx");
24 if (compiler_rt.want_ppc_abi) {24 symbol(&expq, "expf128");
25 symbol(&expq, "expf128");
26 }
27 symbol(&expq, "expq");
28 symbol(&expl, "expl");25 symbol(&expl, "expl");
29}26}
3027
31pub fn __exph(a: f16) callconv(.c) f16 {28fn __exph(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
29 return compiler_rt.f16.toAbi(exp_f16(compiler_rt.f16.fromAbi(x)));
30}
31pub fn exp_f16(x: f16) f16 {
32 // TODO: more efficient implementation32 // TODO: more efficient implementation
33 return @floatCast(expf(a));33 return @floatCast(exp_f32(x));
34}34}
3535
36pub fn expf(x_: f32) callconv(.c) f32 {36fn expf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
37 return compiler_rt.f32.toAbi(exp_f32(compiler_rt.f32.fromAbi(x)));
38}
39pub fn exp_f32(x_: f32) f32 {
37 const half = [_]f32{ 0.5, -0.5 };40 const half = [_]f32{ 0.5, -0.5 };
38 const ln2hi = 6.9314575195e-1;41 const ln2hi = 6.9314575195e-1;
39 const ln2lo = 1.4286067653e-6;42 const ln2lo = 1.4286067653e-6;
...@@ -108,7 +111,10 @@ pub fn expf(x_: f32) callconv(.c) f32 {...@@ -108,7 +111,10 @@ pub fn expf(x_: f32) callconv(.c) f32 {
108 }111 }
109}112}
110113
111pub fn exp(x_: f64) callconv(.c) f64 {114fn exp(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
115 return compiler_rt.f64.toAbi(exp_f64(compiler_rt.f64.fromAbi(x)));
116}
117pub fn exp_f64(x_: f64) f64 {
112 const half = [_]f64{ 0.5, -0.5 };118 const half = [_]f64{ 0.5, -0.5 };
113 const ln2hi: f64 = 6.93147180369123816490e-01;119 const ln2hi: f64 = 6.93147180369123816490e-01;
114 const ln2lo: f64 = 1.90821492927058770002e-10;120 const ln2lo: f64 = 1.90821492927058770002e-10;
...@@ -189,116 +195,121 @@ pub fn exp(x_: f64) callconv(.c) f64 {...@@ -189,116 +195,121 @@ pub fn exp(x_: f64) callconv(.c) f64 {
189 }195 }
190}196}
191197
192pub fn __expx(a: f80) callconv(.c) f80 {198fn __expx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
199 return compiler_rt.f80.toAbi(exp_f80(compiler_rt.f80.fromAbi(x)));
200}
201pub fn exp_f80(x: f80) f80 {
193 // TODO: more efficient implementation202 // TODO: more efficient implementation
194 return @floatCast(expq(a));203 return @floatCast(exp_f128(x));
195}204}
196205
197const expq = @import("exp_f128.zig").exp;206fn expq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
207 return compiler_rt.f128.toAbi(exp_f128(compiler_rt.f128.fromAbi(x)));
208}
209pub const exp_f128 = @import("exp_f128.zig").exp;
198210
199pub fn expl(x: c_longdouble) callconv(.c) c_longdouble {211pub fn expl(x: c_longdouble) callconv(.c) c_longdouble {
200 switch (@typeInfo(c_longdouble).float.bits) {212 switch (@typeInfo(c_longdouble).float.bits) {
201 64 => return exp(x),213 64 => return exp_f64(x),
202 80 => return __expx(x),214 80 => return exp_f80(x),
203 128 => return expq(x),215 128 => return exp_f128(x),
204 else => @compileError("unreachable"),216 else => comptime unreachable,
205 }217 }
206}218}
207219
208test "expf() special" {220test "expf() special" {
209 try expectEqual(expf(0.0), 1.0);221 try expectEqual(exp_f32(0.0), 1.0);
210 try expectEqual(expf(-0.0), 1.0);222 try expectEqual(exp_f32(-0.0), 1.0);
211 try expectEqual(expf(1.0), math.e);223 try expectEqual(exp_f32(1.0), math.e);
212 try expectEqual(expf(math.ln2), 2.0);224 try expectEqual(exp_f32(math.ln2), 2.0);
213 try expectEqual(expf(math.inf(f32)), math.inf(f32));225 try expectEqual(exp_f32(math.inf(f32)), math.inf(f32));
214 try expect(math.isPositiveZero(expf(-math.inf(f32))));226 try expect(math.isPositiveZero(exp_f32(-math.inf(f32))));
215 try expect(math.isNan(expf(math.nan(f32))));227 try expect(math.isNan(exp_f32(math.nan(f32))));
216 try expect(math.isNan(expf(math.snan(f32))));228 try expect(math.isNan(exp_f32(math.snan(f32))));
217}229}
218230
219test "expf() sanity" {231test "expf() sanity" {
220 try expectEqual(expf(-0x1.0223a0p+3), 0x1.490320p-12);232 try expectEqual(exp_f32(-0x1.0223a0p+3), 0x1.490320p-12);
221 try expectEqual(expf(0x1.161868p+2), 0x1.34712ap+6);233 try expectEqual(exp_f32(0x1.161868p+2), 0x1.34712ap+6);
222 try expectEqual(expf(-0x1.0c34b4p+3), 0x1.e06b1ap-13);234 try expectEqual(exp_f32(-0x1.0c34b4p+3), 0x1.e06b1ap-13);
223 try expectEqual(expf(-0x1.a206f0p+2), 0x1.7dd484p-10);235 try expectEqual(exp_f32(-0x1.a206f0p+2), 0x1.7dd484p-10);
224 try expectEqual(expf(0x1.288bbcp+3), 0x1.4abc80p+13);236 try expectEqual(exp_f32(0x1.288bbcp+3), 0x1.4abc80p+13);
225 try expectEqual(expf(0x1.52efd0p-1), 0x1.f04a9cp+0);237 try expectEqual(exp_f32(0x1.52efd0p-1), 0x1.f04a9cp+0);
226 try expectEqual(expf(-0x1.a05cc8p-2), 0x1.54f1e0p-1);238 try expectEqual(exp_f32(-0x1.a05cc8p-2), 0x1.54f1e0p-1);
227 try expectEqual(expf(0x1.1f9efap-1), 0x1.c0f628p+0);239 try expectEqual(exp_f32(0x1.1f9efap-1), 0x1.c0f628p+0);
228 try expectEqual(expf(0x1.8c5db0p-1), 0x1.1599b2p+1);240 try expectEqual(exp_f32(0x1.8c5db0p-1), 0x1.1599b2p+1);
229 try expectEqual(expf(-0x1.5b86eap-1), 0x1.03b572p-1);241 try expectEqual(exp_f32(-0x1.5b86eap-1), 0x1.03b572p-1);
230 try expectEqual(expf(-0x1.57f25cp+2), 0x1.2fbea2p-8);242 try expectEqual(exp_f32(-0x1.57f25cp+2), 0x1.2fbea2p-8);
231 try expectEqual(expf(0x1.c7d310p+3), 0x1.76eefp+20);243 try expectEqual(exp_f32(0x1.c7d310p+3), 0x1.76eefp+20);
232 try expectEqual(expf(0x1.19be70p+4), 0x1.52d3dep+25);244 try expectEqual(exp_f32(0x1.19be70p+4), 0x1.52d3dep+25);
233 try expectEqual(expf(-0x1.ab6d70p+3), 0x1.a88adep-20);245 try expectEqual(exp_f32(-0x1.ab6d70p+3), 0x1.a88adep-20);
234 try expectEqual(expf(-0x1.5ac18ep+2), 0x1.22b328p-8);246 try expectEqual(exp_f32(-0x1.5ac18ep+2), 0x1.22b328p-8);
235 try expectEqual(expf(-0x1.925982p-1), 0x1.d2acc0p-2);247 try expectEqual(exp_f32(-0x1.925982p-1), 0x1.d2acc0p-2);
236 try expectEqual(expf(0x1.7221cep+3), 0x1.9c2ceap+16);248 try expectEqual(exp_f32(0x1.7221cep+3), 0x1.9c2ceap+16);
237 try expectEqual(expf(0x1.11a0d4p+4), 0x1.980ee6p+24);249 try expectEqual(exp_f32(0x1.11a0d4p+4), 0x1.980ee6p+24);
238 try expectEqual(expf(-0x1.ae41a2p+1), 0x1.1c28d0p-5);250 try expectEqual(exp_f32(-0x1.ae41a2p+1), 0x1.1c28d0p-5);
239 try expectEqual(expf(-0x1.329154p+4), 0x1.47ef94p-28);251 try expectEqual(exp_f32(-0x1.329154p+4), 0x1.47ef94p-28);
240}252}
241253
242test "expf() boundary" {254test "expf() boundary" {
243 try expectEqual(expf(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite255 try expectEqual(exp_f32(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite
244 try expectEqual(expf(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf256 try expectEqual(exp_f32(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf
245 try expectEqual(expf(0x1.fffffep+127), math.inf(f32)); // Max input value257 try expectEqual(exp_f32(0x1.fffffep+127), math.inf(f32)); // Max input value
246 try expectEqual(expf(0x1p-149), 1.0); // Min positive input value258 try expectEqual(exp_f32(0x1p-149), 1.0); // Min positive input value
247 try expectEqual(expf(-0x1p-149), 1.0); // Min negative input value259 try expectEqual(exp_f32(-0x1p-149), 1.0); // Min negative input value
248 try expectEqual(expf(0x1p-126), 1.0); // First positive subnormal input260 try expectEqual(exp_f32(0x1p-126), 1.0); // First positive subnormal input
249 try expectEqual(expf(-0x1p-126), 1.0); // First negative subnormal input261 try expectEqual(exp_f32(-0x1p-126), 1.0); // First negative subnormal input
250 try expectEqual(expf(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero262 try expectEqual(exp_f32(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero
251 try expectEqual(expf(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero263 try expectEqual(exp_f32(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero
252 try expectEqual(expf(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal264 try expectEqual(exp_f32(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal
253 try expectEqual(expf(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal265 try expectEqual(exp_f32(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal
254
255}266}
256267
257test "exp() special" {268test "exp() special" {
258 try expectEqual(exp(0.0), 1.0);269 try expectEqual(exp_f64(0.0), 1.0);
259 try expectEqual(exp(-0.0), 1.0);270 try expectEqual(exp_f64(-0.0), 1.0);
260 // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC271 // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC
261 // try expectEqual(exp(1.0), math.e);272 // try expectEqual(exp(1.0), math.e);
262 try expectEqual(exp(math.ln2), 2.0);273 try expectEqual(exp_f64(math.ln2), 2.0);
263 try expectEqual(exp(math.inf(f64)), math.inf(f64));274 try expectEqual(exp_f64(math.inf(f64)), math.inf(f64));
264 try expect(math.isPositiveZero(exp(-math.inf(f64))));275 try expect(math.isPositiveZero(exp_f64(-math.inf(f64))));
265 try expect(math.isNan(exp(math.nan(f64))));276 try expect(math.isNan(exp_f64(math.nan(f64))));
266 try expect(math.isNan(exp(math.snan(f64))));277 try expect(math.isNan(exp_f64(math.snan(f64))));
267}278}
268279
269test "exp() sanity" {280test "exp() sanity" {
270 try expectEqual(exp(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12);281 try expectEqual(exp_f64(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12);
271 try expectEqual(exp(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6);282 try expectEqual(exp_f64(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6);
272 try expectEqual(exp(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13);283 try expectEqual(exp_f64(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13);
273 try expectEqual(exp(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10);284 try expectEqual(exp_f64(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10);
274 try expectEqual(exp(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13);285 try expectEqual(exp_f64(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13);
275 try expectEqual(exp(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0);286 try expectEqual(exp_f64(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0);
276 try expectEqual(exp(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1);287 try expectEqual(exp_f64(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1);
277 try expectEqual(exp(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0);288 try expectEqual(exp_f64(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0);
278 try expectEqual(exp(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1);289 try expectEqual(exp_f64(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1);
279 try expectEqual(exp(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1);290 try expectEqual(exp_f64(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1);
280 try expectEqual(exp(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8);291 try expectEqual(exp_f64(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8);
281 try expectEqual(exp(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20);292 try expectEqual(exp_f64(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20);
282 try expectEqual(exp(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25);293 try expectEqual(exp_f64(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25);
283 try expectEqual(exp(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20);294 try expectEqual(exp_f64(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20);
284 try expectEqual(exp(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8);295 try expectEqual(exp_f64(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8);
285 try expectEqual(exp(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2);296 try expectEqual(exp_f64(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2);
286 try expectEqual(exp(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16);297 try expectEqual(exp_f64(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16);
287 try expectEqual(exp(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24);298 try expectEqual(exp_f64(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24);
288 try expectEqual(exp(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5);299 try expectEqual(exp_f64(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5);
289 try expectEqual(exp(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28);300 try expectEqual(exp_f64(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28);
290}301}
291302
292test "exp() boundary" {303test "exp() boundary" {
293 try expectEqual(exp(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite304 try expectEqual(exp_f64(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite
294 try expectEqual(exp(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf305 try expectEqual(exp_f64(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf
295 try expectEqual(exp(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value306 try expectEqual(exp_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
296 try expectEqual(exp(0x1p-1074), 1.0); // Min positive input value307 try expectEqual(exp_f64(0x1p-1074), 1.0); // Min positive input value
297 try expectEqual(exp(-0x1p-1074), 1.0); // Min negative input value308 try expectEqual(exp_f64(-0x1p-1074), 1.0); // Min negative input value
298 try expectEqual(exp(0x1p-1022), 1.0); // First positive subnormal input309 try expectEqual(exp_f64(0x1p-1022), 1.0); // First positive subnormal input
299 try expectEqual(exp(-0x1p-1022), 1.0); // First negative subnormal input310 try expectEqual(exp_f64(-0x1p-1022), 1.0); // First negative subnormal input
300 try expectEqual(exp(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero311 try expectEqual(exp_f64(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero
301 try expectEqual(exp(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero312 try expectEqual(exp_f64(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero
302 try expectEqual(exp(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal313 try expectEqual(exp_f64(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal
303 try expectEqual(exp(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal314 try expectEqual(exp_f64(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal
304}315}
lib/compiler_rt/exp2.zig+85-73
...@@ -19,19 +19,22 @@ comptime {...@@ -19,19 +19,22 @@ comptime {
19 symbol(&exp2f, "exp2f");19 symbol(&exp2f, "exp2f");
20 symbol(&exp2, "exp2");20 symbol(&exp2, "exp2");
21 symbol(&__exp2x, "__exp2x");21 symbol(&__exp2x, "__exp2x");
22 if (compiler_rt.want_ppc_abi) {22 symbol(&exp2q, "exp2f128");
23 symbol(&exp2q, "exp2f128");
24 }
25 symbol(&exp2q, "exp2q");
26 symbol(&exp2l, "exp2l");23 symbol(&exp2l, "exp2l");
27}24}
2825
29pub fn __exp2h(x: f16) callconv(.c) f16 {26fn __exp2h(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
27 return compiler_rt.f16.toAbi(exp2_f16(compiler_rt.f16.fromAbi(x)));
28}
29pub fn exp2_f16(x: f16) f16 {
30 // TODO: more efficient implementation30 // TODO: more efficient implementation
31 return @floatCast(exp2f(x));31 return @floatCast(exp2_f32(x));
32}32}
3333
34pub fn exp2f(x: f32) callconv(.c) f32 {34fn exp2f(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
35 return compiler_rt.f32.toAbi(exp2_f32(compiler_rt.f32.fromAbi(x)));
36}
37pub fn exp2_f32(x: f32) f32 {
35 const tblsiz: u32 = @intCast(exp2ft.len);38 const tblsiz: u32 = @intCast(exp2ft.len);
36 const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz));39 const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz));
37 const P1: f32 = 0x1.62e430p-1;40 const P1: f32 = 0x1.62e430p-1;
...@@ -88,7 +91,10 @@ pub fn exp2f(x: f32) callconv(.c) f32 {...@@ -88,7 +91,10 @@ pub fn exp2f(x: f32) callconv(.c) f32 {
88 return @floatCast(r * uk);91 return @floatCast(r * uk);
89}92}
9093
91pub fn exp2(x: f64) callconv(.c) f64 {94fn exp2(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
95 return compiler_rt.f64.toAbi(exp2_f64(compiler_rt.f64.fromAbi(x)));
96}
97pub fn exp2_f64(x: f64) f64 {
92 const tblsiz: u32 = @intCast(exp2dt.len / 2);98 const tblsiz: u32 = @intCast(exp2dt.len / 2);
93 const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz));99 const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz));
94 const P1: f64 = 0x1.62e42fefa39efp-1;100 const P1: f64 = 0x1.62e42fefa39efp-1;
...@@ -156,19 +162,25 @@ pub fn exp2(x: f64) callconv(.c) f64 {...@@ -156,19 +162,25 @@ pub fn exp2(x: f64) callconv(.c) f64 {
156 return math.scalbn(r, ik);162 return math.scalbn(r, ik);
157}163}
158164
159pub fn __exp2x(x: f80) callconv(.c) f80 {165fn __exp2x(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
166 return compiler_rt.f80.toAbi(exp2_f80(compiler_rt.f80.fromAbi(x)));
167}
168pub fn exp2_f80(x: f80) f80 {
160 // TODO: more efficient implementation169 // TODO: more efficient implementation
161 return @floatCast(exp2q(x));170 return @floatCast(exp2_f128(x));
162}171}
163172
164pub const exp2q = @import("exp_f128.zig").exp2;173fn exp2q(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
174 return compiler_rt.f128.toAbi(exp2_f128(compiler_rt.f128.fromAbi(x)));
175}
176pub const exp2_f128 = @import("exp_f128.zig").exp2;
165177
166pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble {178pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble {
167 switch (@typeInfo(c_longdouble).float.bits) {179 switch (@typeInfo(c_longdouble).float.bits) {
168 64 => return exp2(x),180 64 => return exp2_f64(x),
169 80 => return __exp2x(x),181 80 => return exp2_f80(x),
170 128 => return exp2q(x),182 128 => return exp2_f128(x),
171 else => @compileError("unreachable"),183 else => comptime unreachable,
172 }184 }
173}185}
174186
...@@ -452,77 +464,77 @@ const exp2dt = [_]f64{...@@ -452,77 +464,77 @@ const exp2dt = [_]f64{
452};464};
453465
454test "exp2f() special" {466test "exp2f() special" {
455 try expectEqual(exp2f(0.0), 1.0);467 try expectEqual(exp2_f32(0.0), 1.0);
456 try expectEqual(exp2f(-0.0), 1.0);468 try expectEqual(exp2_f32(-0.0), 1.0);
457 try expectEqual(exp2f(1.0), 2.0);469 try expectEqual(exp2_f32(1.0), 2.0);
458 try expectEqual(exp2f(-1.0), 0.5);470 try expectEqual(exp2_f32(-1.0), 0.5);
459 try expectEqual(exp2f(math.inf(f32)), math.inf(f32));471 try expectEqual(exp2_f32(math.inf(f32)), math.inf(f32));
460 try expect(math.isPositiveZero(exp2f(-math.inf(f32))));472 try expect(math.isPositiveZero(exp2_f32(-math.inf(f32))));
461 try expect(math.isNan(exp2f(math.nan(f32))));473 try expect(math.isNan(exp2_f32(math.nan(f32))));
462 try expect(math.isNan(exp2f(math.snan(f32))));474 try expect(math.isNan(exp2_f32(math.snan(f32))));
463}475}
464476
465test "exp2f() sanity" {477test "exp2f() sanity" {
466 try expectEqual(exp2f(-0x1.0223a0p+3), 0x1.e8d134p-9);478 try expectEqual(exp2_f32(-0x1.0223a0p+3), 0x1.e8d134p-9);
467 try expectEqual(exp2f(0x1.161868p+2), 0x1.453672p+4);479 try expectEqual(exp2_f32(0x1.161868p+2), 0x1.453672p+4);
468 try expectEqual(exp2f(-0x1.0c34b4p+3), 0x1.890ca0p-9);480 try expectEqual(exp2_f32(-0x1.0c34b4p+3), 0x1.890ca0p-9);
469 try expectEqual(exp2f(-0x1.a206f0p+2), 0x1.622d4ep-7);481 try expectEqual(exp2_f32(-0x1.a206f0p+2), 0x1.622d4ep-7);
470 try expectEqual(exp2f(0x1.288bbcp+3), 0x1.340ecep+9);482 try expectEqual(exp2_f32(0x1.288bbcp+3), 0x1.340ecep+9);
471 try expectEqual(exp2f(0x1.52efd0p-1), 0x1.950eeep+0);483 try expectEqual(exp2_f32(0x1.52efd0p-1), 0x1.950eeep+0);
472 try expectEqual(exp2f(-0x1.a05cc8p-2), 0x1.824056p-1);484 try expectEqual(exp2_f32(-0x1.a05cc8p-2), 0x1.824056p-1);
473 try expectEqual(exp2f(0x1.1f9efap-1), 0x1.79dfa2p+0);485 try expectEqual(exp2_f32(0x1.1f9efap-1), 0x1.79dfa2p+0);
474 try expectEqual(exp2f(0x1.8c5db0p-1), 0x1.b5ceacp+0);486 try expectEqual(exp2_f32(0x1.8c5db0p-1), 0x1.b5ceacp+0);
475 try expectEqual(exp2f(-0x1.5b86eap-1), 0x1.3fd8bap-1);487 try expectEqual(exp2_f32(-0x1.5b86eap-1), 0x1.3fd8bap-1);
476}488}
477489
478test "exp2f() boundary" {490test "exp2f() boundary" {
479 try expectEqual(exp2f(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite491 try expectEqual(exp2_f32(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite
480 try expectEqual(exp2f(0x1p+7), math.inf(f32)); // The first value that gives infinite result492 try expectEqual(exp2_f32(0x1p+7), math.inf(f32)); // The first value that gives infinite result
481 try expectEqual(exp2f(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero493 try expectEqual(exp2_f32(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero
482 try expectEqual(exp2f(-0x1.2cp+7), 0); // The first value at which the result flushes to zero494 try expectEqual(exp2_f32(-0x1.2cp+7), 0); // The first value at which the result flushes to zero
483 try expectEqual(exp2f(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal495 try expectEqual(exp2_f32(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal
484 try expectEqual(exp2f(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal496 try expectEqual(exp2_f32(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal
485 try expectEqual(exp2f(0x1.fffffep+127), math.inf(f32)); // Max input value497 try expectEqual(exp2_f32(0x1.fffffep+127), math.inf(f32)); // Max input value
486 try expectEqual(exp2f(0x1p-149), 1); // Min positive input value498 try expectEqual(exp2_f32(0x1p-149), 1); // Min positive input value
487 try expectEqual(exp2f(-0x1p-149), 1); // Min negative input value499 try expectEqual(exp2_f32(-0x1p-149), 1); // Min negative input value
488 try expectEqual(exp2f(0x1p-126), 1); // First positive subnormal input500 try expectEqual(exp2_f32(0x1p-126), 1); // First positive subnormal input
489 try expectEqual(exp2f(-0x1p-126), 1); // First negative subnormal input501 try expectEqual(exp2_f32(-0x1p-126), 1); // First negative subnormal input
490}502}
491503
492test "exp2() special" {504test "exp2() special" {
493 try expectEqual(exp2(0.0), 1.0);505 try expectEqual(exp2_f64(0.0), 1.0);
494 try expectEqual(exp2(-0.0), 1.0);506 try expectEqual(exp2_f64(-0.0), 1.0);
495 try expectEqual(exp2(1.0), 2.0);507 try expectEqual(exp2_f64(1.0), 2.0);
496 try expectEqual(exp2(-1.0), 0.5);508 try expectEqual(exp2_f64(-1.0), 0.5);
497 try expectEqual(exp2(math.inf(f64)), math.inf(f64));509 try expectEqual(exp2_f64(math.inf(f64)), math.inf(f64));
498 try expect(math.isPositiveZero(exp2(-math.inf(f64))));510 try expect(math.isPositiveZero(exp2_f64(-math.inf(f64))));
499 try expect(math.isNan(exp2(math.nan(f64))));511 try expect(math.isNan(exp2_f64(math.nan(f64))));
500 try expect(math.isNan(exp2(math.snan(f64))));512 try expect(math.isNan(exp2_f64(math.snan(f64))));
501}513}
502514
503test "exp2() sanity" {515test "exp2() sanity" {
504 try expectEqual(exp2(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9);516 try expectEqual(exp2_f64(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9);
505 try expectEqual(exp2(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4);517 try expectEqual(exp2_f64(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4);
506 try expectEqual(exp2(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9);518 try expectEqual(exp2_f64(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9);
507 try expectEqual(exp2(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7);519 try expectEqual(exp2_f64(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7);
508 try expectEqual(exp2(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9);520 try expectEqual(exp2_f64(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9);
509 try expectEqual(exp2(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0);521 try expectEqual(exp2_f64(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0);
510 try expectEqual(exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1);522 try expectEqual(exp2_f64(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1);
511 try expectEqual(exp2(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0);523 try expectEqual(exp2_f64(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0);
512 try expectEqual(exp2(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0);524 try expectEqual(exp2_f64(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0);
513 try expectEqual(exp2(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1);525 try expectEqual(exp2_f64(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1);
514}526}
515527
516test "exp2() boundary" {528test "exp2() boundary" {
517 try expectEqual(exp2(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite529 try expectEqual(exp2_f64(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite
518 try expectEqual(exp2(0x1p+10), math.inf(f64)); // The first value that gives infinite result530 try expectEqual(exp2_f64(0x1p+10), math.inf(f64)); // The first value that gives infinite result
519 try expectEqual(exp2(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero531 try expectEqual(exp2_f64(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero
520 try expectEqual(exp2(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero532 try expectEqual(exp2_f64(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero
521 try expectEqual(exp2(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal533 try expectEqual(exp2_f64(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal
522 try expectEqual(exp2(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal534 try expectEqual(exp2_f64(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal
523 try expectEqual(exp2(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value535 try expectEqual(exp2_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
524 try expectEqual(exp2(0x1p-1074), 1); // Min positive input value536 try expectEqual(exp2_f64(0x1p-1074), 1); // Min positive input value
525 try expectEqual(exp2(-0x1p-1074), 1); // Min negative input value537 try expectEqual(exp2_f64(-0x1p-1074), 1); // Min negative input value
526 try expectEqual(exp2(0x1p-1022), 1); // First positive subnormal input538 try expectEqual(exp2_f64(0x1p-1022), 1); // First positive subnormal input
527 try expectEqual(exp2(-0x1p-1022), 1); // First negative subnormal input539 try expectEqual(exp2_f64(-0x1p-1022), 1); // First negative subnormal input
528}540}
lib/compiler_rt/exp_f128.zig+2-2
...@@ -26,7 +26,7 @@ const exp_f128 = @This();...@@ -26,7 +26,7 @@ const exp_f128 = @This();
26const std = @import("std");26const std = @import("std");
27const math = std.math;27const math = std.math;
2828
29pub fn exp(x: f128) callconv(.c) f128 {29pub fn exp(x: f128) f128 {
30 if (!math.isFinite(x)) {30 if (!math.isFinite(x)) {
31 if (math.isNan(x)) {31 if (math.isNan(x)) {
32 if (math.isSignalNan(x)) math.raiseInvalid();32 if (math.isSignalNan(x)) math.raiseInvalid();
...@@ -91,7 +91,7 @@ fn expPoly(r_hi: f128, r_lo: f128) f128 {...@@ -91,7 +91,7 @@ fn expPoly(r_hi: f128, r_lo: f128) f128 {
91}91}
9292
93/// Computes 2^x93/// Computes 2^x
94pub fn exp2(x: f128) callconv(.c) f128 {94pub fn exp2(x: f128) f128 {
95 if (!math.isFinite(x)) {95 if (!math.isFinite(x)) {
96 if (math.isNan(x)) {96 if (math.isNan(x)) {
97 if (math.isSignalNan(x)) math.raiseInvalid();97 if (math.isSignalNan(x)) math.raiseInvalid();
lib/compiler_rt/extenddftf2.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const extendf = @import("./extendf.zig").extendf;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__extenddftf2, "__extenddfkf2");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_dtoq, "_Qp_dtoq");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__extenddftf2, "_Q_dtoq");
12 }
13 symbol(&__extenddftf2, "__extenddftf2");
14}
15
16pub fn __extenddftf2(a: f64) callconv(.c) f128 {
17 return extendf(f128, f64, @as(u64, @bitCast(a)));
18}
19
20fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void {
21 c.* = extendf(f128, f64, @as(u64, @bitCast(a)));
22}
lib/compiler_rt/extenddfxf2.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extend_f80 = @import("./extendf.zig").extend_f80;
4
5comptime {
6 symbol(&__extenddfxf2, "__extenddfxf2");
7}
8
9pub fn __extenddfxf2(a: f64) callconv(.c) f80 {
10 return extend_f80(f64, @as(u64, @bitCast(a)));
11}
lib/compiler_rt/extendf.zig+174-7
...@@ -1,10 +1,175 @@...@@ -1,10 +1,175 @@
1const std = @import("std");1const std = @import("std");
22
3pub inline fn extendf(3const compiler_rt = @import("../compiler_rt.zig");
4 comptime dst_t: type,4const symbol = compiler_rt.symbol;
5 comptime src_t: type,5
6 a: @Int(.unsigned, @typeInfo(src_t).float.bits),6comptime {
7) dst_t {7 if (compiler_rt.want_aeabi) {
8 if (compiler_rt.gnu_f16_abi) {
9 symbol(&__aeabi_h2f, "__gnu_h2f_ieee");
10 } else {
11 symbol(&__aeabi_h2f, "__aeabi_h2f");
12 }
13 } else if (compiler_rt.gnu_f16_abi) {
14 symbol(&__extendhfsf2, "__gnu_h2f_ieee");
15 }
16 symbol(&__extendhfsf2, "__extendhfsf2");
17 symbol(&__extendhfdf2, "__extendhfdf2");
18 symbol(&__extendhfxf2, "__extendhfxf2");
19 if (compiler_rt.want_ppc_abi) {
20 symbol(&__extendhftf2, "__extendhfkf2");
21 } else {
22 symbol(&__extendhftf2, "__extendhftf2");
23 }
24
25 if (compiler_rt.want_aeabi) {
26 symbol(&__aeabi_f2d, "__aeabi_f2d");
27 } else {
28 symbol(&__extendsfdf2, "__extendsfdf2");
29 }
30 symbol(&__extendsfxf2, "__extendsfxf2");
31 if (compiler_rt.want_ppc_abi) {
32 symbol(&__extendsftf2, "__extendsfkf2");
33 } else if (compiler_rt.want_sparc64_abi) {
34 symbol(&_Qp_stoq, "_Qp_stoq");
35 } else if (compiler_rt.want_sparc32_abi) {
36 symbol(&__extendsftf2, "_Q_stoq");
37 } else {
38 symbol(&__extendsftf2, "__extendsftf2");
39 }
40
41 symbol(&__extenddfxf2, "__extenddfxf2");
42 if (compiler_rt.want_ppc_abi) {
43 symbol(&__extenddftf2, "__extenddfkf2");
44 } else if (compiler_rt.want_sparc64_abi) {
45 symbol(&_Qp_dtoq, "_Qp_dtoq");
46 } else if (compiler_rt.want_sparc32_abi) {
47 symbol(&__extenddftf2, "_Q_dtoq");
48 } else {
49 symbol(&__extenddftf2, "__extenddftf2");
50 }
51
52 if (compiler_rt.want_ppc_abi) {
53 symbol(&__extendxftf2, "__extendxfkf2");
54 } else {
55 symbol(&__extendxftf2, "__extendxftf2");
56 }
57}
58
59fn __extendhfsf2(a: compiler_rt.f16Conv(f32).Abi) callconv(.c) compiler_rt.f32.Abi {
60 return compiler_rt.f32.toAbi(f32_floatCast_f16(compiler_rt.f16Conv(f32).fromAbi(a)));
61}
62fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) u32 {
63 return @bitCast(f32_floatCast_f16(@bitCast(a)));
64}
65pub fn f32_floatCast_f16(a: f16) f32 {
66 return extendf(f32, f16, a);
67}
68
69fn __extendhfdf2(a: compiler_rt.f16Conv(f64).Abi) callconv(.c) compiler_rt.f64.Abi {
70 return compiler_rt.f64.toAbi(f64_floatCast_f16(compiler_rt.f16Conv(f64).fromAbi(a)));
71}
72pub fn f64_floatCast_f16(a: f16) f64 {
73 return extendf(f64, f16, a);
74}
75
76fn __extendhfxf2(a: compiler_rt.f16Conv(f80).Abi) callconv(.c) compiler_rt.f80.Abi {
77 return compiler_rt.f80.toAbi(f80_floatCast_f16(compiler_rt.f16Conv(f80).fromAbi(a)));
78}
79pub fn f80_floatCast_f16(a: f16) f80 {
80 return extend_f80(f16, a);
81}
82
83fn __extendhftf2(a: compiler_rt.f16Conv(f128).Abi) callconv(.c) compiler_rt.f128.Abi {
84 return compiler_rt.f128.toAbi(f128_floatCast_f16(compiler_rt.f16Conv(f128).fromAbi(a)));
85}
86pub fn f128_floatCast_f16(a: f16) f128 {
87 return extendf(f128, f16, a);
88}
89
90fn __extendsfdf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f64.Abi {
91 return compiler_rt.f64.toAbi(f64_floatCast_f32(compiler_rt.f32.fromAbi(a)));
92}
93fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 {
94 return f64_floatCast_f32(a);
95}
96pub fn f64_floatCast_f32(a: f32) f64 {
97 return extendf(f64, f32, a);
98}
99
100fn __extendsfxf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f80.Abi {
101 return compiler_rt.f80.toAbi(f80_floatCast_f32(compiler_rt.f32.fromAbi(a)));
102}
103pub fn f80_floatCast_f32(a: f32) f80 {
104 return extend_f80(f32, a);
105}
106
107pub fn __extendsftf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f128.Abi {
108 return compiler_rt.f128.toAbi(f128_floatCast_f32(compiler_rt.f32.fromAbi(a)));
109}
110fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void {
111 c.* = f128_floatCast_f32(a);
112}
113pub fn f128_floatCast_f32(a: f32) f128 {
114 return extendf(f128, f32, a);
115}
116
117fn __extenddfxf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f80.Abi {
118 return compiler_rt.f80.toAbi(f80_floatCast_f64(compiler_rt.f64.fromAbi(a)));
119}
120pub fn f80_floatCast_f64(a: f64) f80 {
121 return extend_f80(f64, a);
122}
123
124fn __extenddftf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f128.Abi {
125 return compiler_rt.f128.toAbi(f128_floatCast_f64(compiler_rt.f64.fromAbi(a)));
126}
127fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void {
128 c.* = f128_floatCast_f64(a);
129}
130pub fn f128_floatCast_f64(a: f64) f128 {
131 return extendf(f128, f64, a);
132}
133
134fn __extendxftf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f128.Abi {
135 return compiler_rt.f128.toAbi(f128_floatCast_f80(compiler_rt.f80.fromAbi(a)));
136}
137pub fn f128_floatCast_f80(a: f80) f128 {
138 const src_int_bit: u64 = 0x8000000000000000;
139 const src_sig_mask = ~src_int_bit;
140 const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit
141 const dst_sig_bits = std.math.floatMantissaBits(f128);
142
143 const dst_bits = @bitSizeOf(f128);
144
145 // Break a into a sign and representation of the absolute value
146 var a_rep: std.math.F80 = .fromFloat(a);
147 const sign = a_rep.exp & 0x8000;
148 a_rep.exp &= 0x7FFF;
149 var abs_result: u128 = undefined;
150
151 if (a_rep.exp == 0 and a_rep.fraction == 0) {
152 // zero
153 abs_result = 0;
154 } else if (a_rep.exp == 0x7FFF) {
155 // a is nan or infinite
156 abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits);
157 abs_result |= @as(u128, a_rep.exp) << dst_sig_bits;
158 } else if (a_rep.fraction & src_int_bit != 0) {
159 // a is a normal value
160 abs_result = @as(u128, a_rep.fraction & src_sig_mask) << (dst_sig_bits - src_sig_bits);
161 abs_result |= @as(u128, a_rep.exp) << dst_sig_bits;
162 } else {
163 // a is denormal
164 abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits);
165 }
166
167 // Apply the signbit to (dst_t)abs(a).
168 const result: u128 = abs_result | @as(u128, sign) << (dst_bits - 16);
169 return @bitCast(result);
170}
171
172inline fn extendf(comptime dst_t: type, comptime src_t: type, f: src_t) dst_t {
8 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);173 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);
9 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);174 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);
10 const srcSigBits = std.math.floatMantissaBits(src_t);175 const srcSigBits = std.math.floatMantissaBits(src_t);
...@@ -31,6 +196,7 @@ pub inline fn extendf(...@@ -31,6 +196,7 @@ pub inline fn extendf(
31196
32 const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits;197 const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits;
33198
199 const a: src_rep_t = @bitCast(f);
34 // Break a into a sign and representation of the absolute value200 // Break a into a sign and representation of the absolute value
35 const aRep: src_rep_t = @bitCast(a);201 const aRep: src_rep_t = @bitCast(a);
36 const aAbs: src_rep_t = aRep & srcAbsMask;202 const aAbs: src_rep_t = aRep & srcAbsMask;
...@@ -66,11 +232,11 @@ pub inline fn extendf(...@@ -66,11 +232,11 @@ pub inline fn extendf(
66 }232 }
67233
68 // Apply the signbit to (dst_t)abs(a).234 // Apply the signbit to (dst_t)abs(a).
69 const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits);235 const result: dst_rep_t = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits);
70 return @bitCast(result);236 return @bitCast(result);
71}237}
72238
73pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_t).float.bits)) f80 {239inline fn extend_f80(comptime src_t: type, f: src_t) f80 {
74 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);240 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);
75 const src_sig_bits = std.math.floatMantissaBits(src_t);241 const src_sig_bits = std.math.floatMantissaBits(src_t);
76 const dst_int_bit = 0x8000000000000000;242 const dst_int_bit = 0x8000000000000000;
...@@ -92,6 +258,7 @@ pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_...@@ -92,6 +258,7 @@ pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_
92258
93 var dst: std.math.F80 = undefined;259 var dst: std.math.F80 = undefined;
94260
261 const a: src_rep_t = @bitCast(f);
95 // Break a into a sign and representation of the absolute value262 // Break a into a sign and representation of the absolute value
96 const a_abs = a & src_abs_mask;263 const a_abs = a & src_abs_mask;
97 const sign: u16 = if (a & src_sign_mask != 0) 0x8000 else 0;264 const sign: u16 = if (a & src_sign_mask != 0) 0x8000 else 0;
lib/compiler_rt/extendf_test.zig+94-95
...@@ -1,31 +1,37 @@...@@ -1,31 +1,37 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2
3const std = @import("std");2const std = @import("std");
4const math = std.math;3const testing = std.testing;
4
5const impl = @import("extendf.zig");
6
7const f32_floatCast_f16 = impl.f32_floatCast_f16;
8const f64_floatCast_f16 = impl.f64_floatCast_f16;
9const f80_floatCast_f16 = impl.f80_floatCast_f16;
10const f128_floatCast_f16 = impl.f128_floatCast_f16;
11
12const f64_floatCast_f32 = impl.f64_floatCast_f32;
13const f80_floatCast_f32 = impl.f80_floatCast_f32;
14const f128_floatCast_f32 = impl.f128_floatCast_f32;
515
6const __extendhfsf2 = @import("extendhfsf2.zig").__extendhfsf2;16const f80_floatCast_f64 = impl.f80_floatCast_f64;
7const __extendhftf2 = @import("extendhftf2.zig").__extendhftf2;17const f128_floatCast_f64 = impl.f128_floatCast_f64;
8const __extendsftf2 = @import("extendsftf2.zig").__extendsftf2;
9const __extenddftf2 = @import("extenddftf2.zig").__extenddftf2;
10const __extenddfxf2 = @import("extenddfxf2.zig").__extenddfxf2;
11const F16T = @import("../compiler_rt.zig").F16T;
1218
13fn test__extenddfxf2(a: f64, expected: u80) !void {19const f128_floatCast_f80 = impl.f128_floatCast_f80;
14 const x = __extenddfxf2(a);20
21fn test_f80_floatCast_f64(a: f64, expected: u80) !void {
22 const x = f80_floatCast_f64(a);
1523
16 const rep: u80 = @bitCast(x);24 const rep: u80 = @bitCast(x);
17 if (rep == expected)25 if (rep == expected)
18 return;26 return;
19
20 // test other possible NaN representation(signal NaN)27 // test other possible NaN representation(signal NaN)
21 if (math.isNan(@as(f80, @bitCast(expected))) and math.isNan(x))28 if (std.math.isNan(@as(f80, @bitCast(expected))) and std.math.isNan(x))
22 return;29 return;
2330 return error.TestFailure;
24 @panic("__extenddfxf2 test failure");
25}31}
2632
27fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {33fn test_f128_floatCast_f64(a: f64, expected_hi: u64, expected_lo: u64) !void {
28 const x = __extenddftf2(a);34 const x = f128_floatCast_f64(a);
2935
30 const rep: u128 = @bitCast(x);36 const rep: u128 = @bitCast(x);
31 const hi: u64 = @intCast(rep >> 64);37 const hi: u64 = @intCast(rep >> 64);
...@@ -33,7 +39,6 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {...@@ -33,7 +39,6 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {
3339
34 if (hi == expected_hi and lo == expected_lo)40 if (hi == expected_hi and lo == expected_lo)
35 return;41 return;
36
37 // test other possible NaN representation(signal NaN)42 // test other possible NaN representation(signal NaN)
38 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {43 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
39 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and44 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
...@@ -42,12 +47,11 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {...@@ -42,12 +47,11 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {
42 return;47 return;
43 }48 }
44 }49 }
4550 return error.TestFailure;
46 @panic("__extenddftf2 test failure");
47}51}
4852
49fn test__extendhfsf2(a: u16, expected: u32) !void {53fn test_f32_floatCast_f16(a: u16, expected: u32) !void {
50 const x = __extendhfsf2(@as(F16T(f32), @bitCast(a)));54 const x = f32_floatCast_f16(@bitCast(a));
51 const rep: u32 = @bitCast(x);55 const rep: u32 = @bitCast(x);
5256
53 if (rep == expected) {57 if (rep == expected) {
...@@ -58,12 +62,11 @@ fn test__extendhfsf2(a: u16, expected: u32) !void {...@@ -58,12 +62,11 @@ fn test__extendhfsf2(a: u16, expected: u32) !void {
58 return;62 return;
59 }63 }
60 }64 }
61
62 return error.TestFailure;65 return error.TestFailure;
63}66}
6467
65fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {68fn test_f128_floatCast_f32(a: f32, expected_hi: u64, expected_lo: u64) !void {
66 const x = __extendsftf2(a);69 const x = f128_floatCast_f32(a);
6770
68 const rep: u128 = @bitCast(x);71 const rep: u128 = @bitCast(x);
69 const hi: u64 = @intCast(rep >> 64);72 const hi: u64 = @intCast(rep >> 64);
...@@ -71,7 +74,6 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {...@@ -71,7 +74,6 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {
7174
72 if (hi == expected_hi and lo == expected_lo)75 if (hi == expected_hi and lo == expected_lo)
73 return;76 return;
74
75 // test other possible NaN representation(signal NaN)77 // test other possible NaN representation(signal NaN)
76 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {78 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
77 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and79 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
...@@ -80,111 +82,108 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {...@@ -80,111 +82,108 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {
80 return;82 return;
81 }83 }
82 }84 }
83
84 return error.TestFailure;85 return error.TestFailure;
85}86}
8687
87test "extenddfxf2" {88test f80_floatCast_f64 {
88 // qNaN89 // qNaN
89 try test__extenddfxf2(makeQNaN64(), 0x7fffc000000000000000);90 try test_f80_floatCast_f64(makeQNaN64(), 0x7fffc000000000000000);
9091
91 // NaN92 // NaN
92 try test__extenddfxf2(makeNaN64(0x7100000000000), 0x7fffe080000000000000);93 try test_f80_floatCast_f64(makeNaN64(0x7100000000000), 0x7fffe080000000000000);
93 // This is bad?94 // This is bad?
9495
95 // inf96 // inf
96 try test__extenddfxf2(makeInf64(), 0x7fff8000000000000000);97 try test_f80_floatCast_f64(makeInf64(), 0x7fff8000000000000000);
9798
98 // zero99 // zero
99 try test__extenddfxf2(0.0, 0x0);100 try test_f80_floatCast_f64(0.0, 0x0);
100101
101 try test__extenddfxf2(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000);102 try test_f80_floatCast_f64(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000);
102103
103 try test__extenddfxf2(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000);104 try test_f80_floatCast_f64(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000);
104105
105 try test__extenddfxf2(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000);106 try test_f80_floatCast_f64(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000);
106107
107 try test__extenddfxf2(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000);108 try test_f80_floatCast_f64(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000);
108109
109 // subnormal110 // subnormal
110 try test__extenddfxf2(0x1.8000000000001p-1022, 0x3c01c000000000000800);111 try test_f80_floatCast_f64(0x1.8000000000001p-1022, 0x3c01c000000000000800);
111 try test__extenddfxf2(0x1.8000000000002p-1023, 0x3c00c000000000001000);112 try test_f80_floatCast_f64(0x1.8000000000002p-1023, 0x3c00c000000000001000);
112}113}
113114
114test "extenddftf2" {115test f128_floatCast_f64 {
115 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
116
117 // qNaN116 // qNaN
118 try test__extenddftf2(makeQNaN64(), 0x7fff800000000000, 0x0);117 try test_f128_floatCast_f64(makeQNaN64(), 0x7fff800000000000, 0x0);
119118
120 // NaN119 // NaN
121 try test__extenddftf2(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0);120 try test_f128_floatCast_f64(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0);
122121
123 // inf122 // inf
124 try test__extenddftf2(makeInf64(), 0x7fff000000000000, 0x0);123 try test_f128_floatCast_f64(makeInf64(), 0x7fff000000000000, 0x0);
125124
126 // zero125 // zero
127 try test__extenddftf2(0.0, 0x0, 0x0);126 try test_f128_floatCast_f64(0.0, 0x0, 0x0);
128127
129 try test__extenddftf2(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000);128 try test_f128_floatCast_f64(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000);
130129
131 try test__extenddftf2(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000);130 try test_f128_floatCast_f64(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000);
132131
133 try test__extenddftf2(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000);132 try test_f128_floatCast_f64(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000);
134133
135 try test__extenddftf2(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000);134 try test_f128_floatCast_f64(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000);
136135
137 // subnormal136 // subnormal
138 try test__extenddftf2(0x1.8p-1022, 0x3c01800000000000, 0x0);137 try test_f128_floatCast_f64(0x1.8p-1022, 0x3c01800000000000, 0x0);
139 try test__extenddftf2(0x1.8p-1023, 0x3c00800000000000, 0x0);138 try test_f128_floatCast_f64(0x1.8p-1023, 0x3c00800000000000, 0x0);
140}139}
141140
142test "extendhfsf2" {141test f32_floatCast_f16 {
143 try test__extendhfsf2(0x7e00, 0x7fc00000); // qNaN142 try test_f32_floatCast_f16(0x7e00, 0x7fc00000); // qNaN
144 try test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN143 try test_f32_floatCast_f16(0x7f00, 0x7fe00000); // sNaN
145 // On x86 the NaN becomes quiet because the return is pushed on the x87144 // On x86 the NaN becomes quiet because the return is pushed on the x87
146 // stack due to ABI requirements145 // stack due to ABI requirements
147 if (builtin.target.cpu.arch != .x86 and builtin.target.os.tag == .windows)146 if (builtin.target.cpu.arch != .x86 and builtin.target.os.tag == .windows)
148 try test__extendhfsf2(0x7c01, 0x7f802000); // sNaN147 try test_f32_floatCast_f16(0x7c01, 0x7f802000); // sNaN
149148
150 try test__extendhfsf2(0, 0); // 0149 try test_f32_floatCast_f16(0, 0); // 0
151 try test__extendhfsf2(0x8000, 0x80000000); // -0150 try test_f32_floatCast_f16(0x8000, 0x80000000); // -0
152151
153 try test__extendhfsf2(0x7c00, 0x7f800000); // inf152 try test_f32_floatCast_f16(0x7c00, 0x7f800000); // inf
154 try test__extendhfsf2(0xfc00, 0xff800000); // -inf153 try test_f32_floatCast_f16(0xfc00, 0xff800000); // -inf
155154
156 try test__extendhfsf2(0x0001, 0x33800000); // denormal (min), 2**-24155 try test_f32_floatCast_f16(0x0001, 0x33800000); // denormal (min), 2**-24
157 try test__extendhfsf2(0x8001, 0xb3800000); // denormal (min), -2**-24156 try test_f32_floatCast_f16(0x8001, 0xb3800000); // denormal (min), -2**-24
158157
159 try test__extendhfsf2(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24158 try test_f32_floatCast_f16(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24
160 try test__extendhfsf2(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24159 try test_f32_floatCast_f16(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24
161160
162 try test__extendhfsf2(0x0400, 0x38800000); // normal (min), 2**-14161 try test_f32_floatCast_f16(0x0400, 0x38800000); // normal (min), 2**-14
163 try test__extendhfsf2(0x8400, 0xb8800000); // normal (min), -2**-14162 try test_f32_floatCast_f16(0x8400, 0xb8800000); // normal (min), -2**-14
164163
165 try test__extendhfsf2(0x7bff, 0x477fe000); // normal (max), 65504164 try test_f32_floatCast_f16(0x7bff, 0x477fe000); // normal (max), 65504
166 try test__extendhfsf2(0xfbff, 0xc77fe000); // normal (max), -65504165 try test_f32_floatCast_f16(0xfbff, 0xc77fe000); // normal (max), -65504
167166
168 try test__extendhfsf2(0x3c01, 0x3f802000); // normal, 1 + 2**-10167 try test_f32_floatCast_f16(0x3c01, 0x3f802000); // normal, 1 + 2**-10
169 try test__extendhfsf2(0xbc01, 0xbf802000); // normal, -1 - 2**-10168 try test_f32_floatCast_f16(0xbc01, 0xbf802000); // normal, -1 - 2**-10
170169
171 try test__extendhfsf2(0x3555, 0x3eaaa000); // normal, approx. 1/3170 try test_f32_floatCast_f16(0x3555, 0x3eaaa000); // normal, approx. 1/3
172 try test__extendhfsf2(0xb555, 0xbeaaa000); // normal, approx. -1/3171 try test_f32_floatCast_f16(0xb555, 0xbeaaa000); // normal, approx. -1/3
173}172}
174173
175test "extendsftf2" {174test f128_floatCast_f32 {
176 // qNaN175 // qNaN
177 try test__extendsftf2(makeQNaN32(), 0x7fff800000000000, 0x0);176 try test_f128_floatCast_f32(makeQNaN32(), 0x7fff800000000000, 0x0);
178 // NaN177 // NaN
179 try test__extendsftf2(makeNaN32(0x410000), 0x7fff820000000000, 0x0);178 try test_f128_floatCast_f32(makeNaN32(0x410000), 0x7fff820000000000, 0x0);
180 // inf179 // inf
181 try test__extendsftf2(makeInf32(), 0x7fff000000000000, 0x0);180 try test_f128_floatCast_f32(makeInf32(), 0x7fff000000000000, 0x0);
182 // zero181 // zero
183 try test__extendsftf2(0.0, 0x0, 0x0);182 try test_f128_floatCast_f32(0.0, 0x0, 0x0);
184 try test__extendsftf2(0x1.23456p+5, 0x4004234560000000, 0x0);183 try test_f128_floatCast_f32(0x1.23456p+5, 0x4004234560000000, 0x0);
185 try test__extendsftf2(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0);184 try test_f128_floatCast_f32(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0);
186 try test__extendsftf2(0x1.23456p+45, 0x402c234560000000, 0x0);185 try test_f128_floatCast_f32(0x1.23456p+45, 0x402c234560000000, 0x0);
187 try test__extendsftf2(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0);186 try test_f128_floatCast_f32(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0);
188}187}
189188
190fn makeQNaN64() f64 {189fn makeQNaN64() f64 {
...@@ -211,8 +210,8 @@ fn makeInf32() f32 {...@@ -211,8 +210,8 @@ fn makeInf32() f32 {
211 return @bitCast(@as(u32, 0x7f800000));210 return @bitCast(@as(u32, 0x7f800000));
212}211}
213212
214fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void {213fn test_f128_floatCast_f16(a: u16, expected_hi: u64, expected_lo: u64) !void {
215 const x = __extendhftf2(@as(F16T(f128), @bitCast(a)));214 const x = f128_floatCast_f16(@bitCast(a));
216215
217 const rep: u128 = @bitCast(x);216 const rep: u128 = @bitCast(x);
218 const hi: u64 = @intCast(rep >> 64);217 const hi: u64 = @intCast(rep >> 64);
...@@ -233,26 +232,26 @@ fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void {...@@ -233,26 +232,26 @@ fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void {
233 return error.TestFailure;232 return error.TestFailure;
234}233}
235234
236test "extendhftf2" {235test f128_floatCast_f16 {
237 // qNaN236 // qNaN
238 try test__extendhftf2(0x7e00, 0x7fff800000000000, 0x0);237 try test_f128_floatCast_f16(0x7e00, 0x7fff800000000000, 0x0);
239 // NaN238 // NaN
240 try test__extendhftf2(0x7d00, 0x7fff400000000000, 0x0);239 try test_f128_floatCast_f16(0x7d00, 0x7fff400000000000, 0x0);
241 // inf240 // inf
242 try test__extendhftf2(0x7c00, 0x7fff000000000000, 0x0);241 try test_f128_floatCast_f16(0x7c00, 0x7fff000000000000, 0x0);
243 try test__extendhftf2(0xfc00, 0xffff000000000000, 0x0);242 try test_f128_floatCast_f16(0xfc00, 0xffff000000000000, 0x0);
244 // zero243 // zero
245 try test__extendhftf2(0x0000, 0x0000000000000000, 0x0);244 try test_f128_floatCast_f16(0x0000, 0x0000000000000000, 0x0);
246 try test__extendhftf2(0x8000, 0x8000000000000000, 0x0);245 try test_f128_floatCast_f16(0x8000, 0x8000000000000000, 0x0);
247 // denormal246 // denormal
248 try test__extendhftf2(0x0010, 0x3feb000000000000, 0x0);247 try test_f128_floatCast_f16(0x0010, 0x3feb000000000000, 0x0);
249 try test__extendhftf2(0x0001, 0x3fe7000000000000, 0x0);248 try test_f128_floatCast_f16(0x0001, 0x3fe7000000000000, 0x0);
250 try test__extendhftf2(0x8001, 0xbfe7000000000000, 0x0);249 try test_f128_floatCast_f16(0x8001, 0xbfe7000000000000, 0x0);
251250
252 // pi251 // pi
253 try test__extendhftf2(0x4248, 0x4000920000000000, 0x0);252 try test_f128_floatCast_f16(0x4248, 0x4000920000000000, 0x0);
254 try test__extendhftf2(0xc248, 0xc000920000000000, 0x0);253 try test_f128_floatCast_f16(0xc248, 0xc000920000000000, 0x0);
255254
256 try test__extendhftf2(0x508c, 0x4004230000000000, 0x0);255 try test_f128_floatCast_f16(0x508c, 0x4004230000000000, 0x0);
257 try test__extendhftf2(0x1bb7, 0x3ff6edc000000000, 0x0);256 try test_f128_floatCast_f16(0x1bb7, 0x3ff6edc000000000, 0x0);
258}257}
lib/compiler_rt/extendhfdf2.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const extendf = @import("./extendf.zig").extendf;
4
5comptime {
6 symbol(&__extendhfdf2, "__extendhfdf2");
7}
8
9pub fn __extendhfdf2(a: compiler_rt.F16T(f64)) callconv(.c) f64 {
10 return extendf(f64, f16, @as(u16, @bitCast(a)));
11}
lib/compiler_rt/extendhfsf2.zig deleted-24
...@@ -1,24 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const extendf = @import("./extendf.zig").extendf;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.gnu_f16_abi) {
7 symbol(&__gnu_h2f_ieee, "__gnu_h2f_ieee");
8 } else if (compiler_rt.want_aeabi) {
9 symbol(&__aeabi_h2f, "__aeabi_h2f");
10 }
11 symbol(&__extendhfsf2, "__extendhfsf2");
12}
13
14pub fn __extendhfsf2(a: compiler_rt.F16T(f32)) callconv(.c) f32 {
15 return extendf(f32, f16, @as(u16, @bitCast(a)));
16}
17
18fn __gnu_h2f_ieee(a: compiler_rt.F16T(f32)) callconv(.c) f32 {
19 return extendf(f32, f16, @as(u16, @bitCast(a)));
20}
21
22fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) f32 {
23 return extendf(f32, f16, @as(u16, @bitCast(a)));
24}
lib/compiler_rt/extendhftf2.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extendf = @import("./extendf.zig").extendf;
4
5comptime {
6 symbol(&__extendhftf2, "__extendhftf2");
7}
8
9pub fn __extendhftf2(a: compiler_rt.F16T(f128)) callconv(.c) f128 {
10 return extendf(f128, f16, @as(u16, @bitCast(a)));
11}
lib/compiler_rt/extendhfxf2.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extend_f80 = @import("./extendf.zig").extend_f80;
4
5comptime {
6 symbol(&__extendhfxf2, "__extendhfxf2");
7}
8
9fn __extendhfxf2(a: compiler_rt.F16T(f80)) callconv(.c) f80 {
10 return extend_f80(f16, @as(u16, @bitCast(a)));
11}
lib/compiler_rt/extendsfdf2.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extendf = @import("./extendf.zig").extendf;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_f2d, "__aeabi_f2d");
8 } else {
9 symbol(&__extendsfdf2, "__extendsfdf2");
10 }
11}
12
13fn __extendsfdf2(a: f32) callconv(.c) f64 {
14 return extendf(f64, f32, @as(u32, @bitCast(a)));
15}
16
17fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 {
18 return extendf(f64, f32, @as(u32, @bitCast(a)));
19}
lib/compiler_rt/extendsftf2.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extendf = @import("./extendf.zig").extendf;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__extendsftf2, "__extendsfkf2");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_stoq, "_Qp_stoq");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__extendsftf2, "_Q_stoq");
12 }
13 symbol(&__extendsftf2, "__extendsftf2");
14}
15
16pub fn __extendsftf2(a: f32) callconv(.c) f128 {
17 return extendf(f128, f32, @as(u32, @bitCast(a)));
18}
19
20fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void {
21 c.* = extendf(f128, f32, @as(u32, @bitCast(a)));
22}
lib/compiler_rt/extendsfxf2.zig deleted-10
...@@ -1,10 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const extend_f80 = @import("./extendf.zig").extend_f80;
3
4comptime {
5 symbol(&__extendsfxf2, "__extendsfxf2");
6}
7
8fn __extendsfxf2(a: f32) callconv(.c) f80 {
9 return extend_f80(f32, @as(u32, @bitCast(a)));
10}
lib/compiler_rt/extendxftf2.zig deleted-42
...@@ -1,42 +0,0 @@
1const std = @import("std");
2
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__extendxftf2, "__extendxftf2");
7}
8
9fn __extendxftf2(a: f80) callconv(.c) f128 {
10 const src_int_bit: u64 = 0x8000000000000000;
11 const src_sig_mask = ~src_int_bit;
12 const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit
13 const dst_sig_bits = std.math.floatMantissaBits(f128);
14
15 const dst_bits = @bitSizeOf(f128);
16
17 // Break a into a sign and representation of the absolute value
18 var a_rep = std.math.F80.fromFloat(a);
19 const sign = a_rep.exp & 0x8000;
20 a_rep.exp &= 0x7FFF;
21 var abs_result: u128 = undefined;
22
23 if (a_rep.exp == 0 and a_rep.fraction == 0) {
24 // zero
25 abs_result = 0;
26 } else if (a_rep.exp == 0x7FFF) {
27 // a is nan or infinite
28 abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits);
29 abs_result |= @as(u128, a_rep.exp) << dst_sig_bits;
30 } else if (a_rep.fraction & src_int_bit != 0) {
31 // a is a normal value
32 abs_result = @as(u128, a_rep.fraction & src_sig_mask) << (dst_sig_bits - src_sig_bits);
33 abs_result |= @as(u128, a_rep.exp) << dst_sig_bits;
34 } else {
35 // a is denormal
36 abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits);
37 }
38
39 // Apply the signbit to (dst_t)abs(a).
40 const result: u128 align(@alignOf(f128)) = abs_result | @as(u128, sign) << (dst_bits - 16);
41 return @bitCast(result);
42}
lib/compiler_rt/fabs.zig+25-13
...@@ -9,39 +9,51 @@ comptime {...@@ -9,39 +9,51 @@ comptime {
9 symbol(&fabsf, "fabsf");9 symbol(&fabsf, "fabsf");
10 symbol(&fabs, "fabs");10 symbol(&fabs, "fabs");
11 symbol(&__fabsx, "__fabsx");11 symbol(&__fabsx, "__fabsx");
12 if (compiler_rt.want_ppc_abi) {12 symbol(&fabsq, "fabsf128");
13 symbol(&fabsq, "fabsf128");
14 }
15 symbol(&fabsq, "fabsq");
16 symbol(&fabsl, "fabsl");13 symbol(&fabsl, "fabsl");
17}14}
1815
19pub fn __fabsh(a: f16) callconv(.c) f16 {16fn __fabsh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
17 return compiler_rt.f16.toAbi(fabs_f16(compiler_rt.f16.fromAbi(a)));
18}
19pub fn fabs_f16(a: f16) f16 {
20 return generic_fabs(a);20 return generic_fabs(a);
21}21}
2222
23pub fn fabsf(a: f32) callconv(.c) f32 {23fn fabsf(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
24 return compiler_rt.f32.toAbi(fabs_f32(compiler_rt.f32.fromAbi(a)));
25}
26pub fn fabs_f32(a: f32) f32 {
24 return generic_fabs(a);27 return generic_fabs(a);
25}28}
2629
27pub fn fabs(a: f64) callconv(.c) f64 {30fn fabs(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
31 return compiler_rt.f64.toAbi(fabs_f64(compiler_rt.f64.fromAbi(a)));
32}
33pub fn fabs_f64(a: f64) f64 {
28 return generic_fabs(a);34 return generic_fabs(a);
29}35}
3036
31pub fn __fabsx(a: f80) callconv(.c) f80 {37fn __fabsx(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
38 return compiler_rt.f80.toAbi(fabs_f80(compiler_rt.f80.fromAbi(a)));
39}
40pub fn fabs_f80(a: f80) f80 {
32 return generic_fabs(a);41 return generic_fabs(a);
33}42}
3443
35pub fn fabsq(a: f128) callconv(.c) f128 {44fn fabsq(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
45 return compiler_rt.f128.toAbi(fabs_f128(compiler_rt.f128.fromAbi(a)));
46}
47pub fn fabs_f128(a: f128) f128 {
36 return generic_fabs(a);48 return generic_fabs(a);
37}49}
3850
39pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble {51pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble {
40 switch (@typeInfo(c_longdouble).float.bits) {52 switch (@typeInfo(c_longdouble).float.bits) {
41 64 => return fabs(x),53 64 => return fabs_f64(x),
42 80 => return __fabsx(x),54 80 => return fabs_f80(x),
43 128 => return fabsq(x),55 128 => return fabs_f128(x),
44 else => @compileError("unreachable"),56 else => comptime unreachable,
45 }57 }
46}58}
4759
lib/compiler_rt/fixdfdi.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
7 if (compiler_rt.want_aeabi) {
8 symbol(&__aeabi_d2lz, "__aeabi_d2lz");
9 } else {
10 if (compiler_rt.want_windows_arm_abi) {
11 symbol(&__fixdfdi, "__dtoi64");
12 }
13 symbol(&__fixdfdi, "__fixdfdi");
14 }
15}
16
17pub fn __fixdfdi(a: f64) callconv(.c) i64 {
18 return intFromFloat(i64, a);
19}
20
21fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 {
22 return intFromFloat(i64, a);
23}
lib/compiler_rt/fixdfei.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixdfei, "__fixdfei");
9}
10
11pub fn __fixdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a);
14}
lib/compiler_rt/fixdfsi.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_d2iz, "__aeabi_d2iz");
8 } else {
9 symbol(&__fixdfsi, "__fixdfsi");
10 }
11}
12
13pub fn __fixdfsi(a: f64) callconv(.c) i32 {
14 return intFromFloat(i32, a);
15}
16
17fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
18 return intFromFloat(i32, a);
19}
lib/compiler_rt/fixdfti.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__fixdfti, "__fixdfti");
7}
8
9pub fn __fixdfti(a: f64) callconv(.c) i128 {
10 return intFromFloat(i128, a);
11}
lib/compiler_rt/fixhfei.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixhfei, "__fixhfei");
9}
10
11pub fn __fixhfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a);
14}
lib/compiler_rt/fixint_test.zig deleted-149
...@@ -1,149 +0,0 @@
1const std = @import("std");
2const math = std.math;
3const testing = std.testing;
4
5const fixint = @import("fixint.zig").fixint;
6
7fn test__fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t, expected: fixint_t) !void {
8 const x = fixint(fp_t, fixint_t, a);
9 try testing.expect(x == expected);
10}
11
12test "fixint.i1" {
13 try test__fixint(f32, i1, -math.inf(f32), -1);
14 try test__fixint(f32, i1, -math.floatMax(f32), -1);
15 try test__fixint(f32, i1, -2.0, -1);
16 try test__fixint(f32, i1, -1.1, -1);
17 try test__fixint(f32, i1, -1.0, -1);
18 try test__fixint(f32, i1, -0.9, 0);
19 try test__fixint(f32, i1, -0.1, 0);
20 try test__fixint(f32, i1, -math.floatMin(f32), 0);
21 try test__fixint(f32, i1, -0.0, 0);
22 try test__fixint(f32, i1, 0.0, 0);
23 try test__fixint(f32, i1, math.floatMin(f32), 0);
24 try test__fixint(f32, i1, 0.1, 0);
25 try test__fixint(f32, i1, 0.9, 0);
26 try test__fixint(f32, i1, 1.0, 0);
27 try test__fixint(f32, i1, 2.0, 0);
28 try test__fixint(f32, i1, math.floatMax(f32), 0);
29 try test__fixint(f32, i1, math.inf(f32), 0);
30}
31
32test "fixint.i2" {
33 try test__fixint(f32, i2, -math.inf(f32), -2);
34 try test__fixint(f32, i2, -math.floatMax(f32), -2);
35 try test__fixint(f32, i2, -2.0, -2);
36 try test__fixint(f32, i2, -1.9, -1);
37 try test__fixint(f32, i2, -1.1, -1);
38 try test__fixint(f32, i2, -1.0, -1);
39 try test__fixint(f32, i2, -0.9, 0);
40 try test__fixint(f32, i2, -0.1, 0);
41 try test__fixint(f32, i2, -math.floatMin(f32), 0);
42 try test__fixint(f32, i2, -0.0, 0);
43 try test__fixint(f32, i2, 0.0, 0);
44 try test__fixint(f32, i2, math.floatMin(f32), 0);
45 try test__fixint(f32, i2, 0.1, 0);
46 try test__fixint(f32, i2, 0.9, 0);
47 try test__fixint(f32, i2, 1.0, 1);
48 try test__fixint(f32, i2, 2.0, 1);
49 try test__fixint(f32, i2, math.floatMax(f32), 1);
50 try test__fixint(f32, i2, math.inf(f32), 1);
51}
52
53test "fixint.i3" {
54 try test__fixint(f32, i3, -math.inf(f32), -4);
55 try test__fixint(f32, i3, -math.floatMax(f32), -4);
56 try test__fixint(f32, i3, -4.0, -4);
57 try test__fixint(f32, i3, -3.0, -3);
58 try test__fixint(f32, i3, -2.0, -2);
59 try test__fixint(f32, i3, -1.9, -1);
60 try test__fixint(f32, i3, -1.1, -1);
61 try test__fixint(f32, i3, -1.0, -1);
62 try test__fixint(f32, i3, -0.9, 0);
63 try test__fixint(f32, i3, -0.1, 0);
64 try test__fixint(f32, i3, -math.floatMin(f32), 0);
65 try test__fixint(f32, i3, -0.0, 0);
66 try test__fixint(f32, i3, 0.0, 0);
67 try test__fixint(f32, i3, math.floatMin(f32), 0);
68 try test__fixint(f32, i3, 0.1, 0);
69 try test__fixint(f32, i3, 0.9, 0);
70 try test__fixint(f32, i3, 1.0, 1);
71 try test__fixint(f32, i3, 2.0, 2);
72 try test__fixint(f32, i3, 3.0, 3);
73 try test__fixint(f32, i3, 4.0, 3);
74 try test__fixint(f32, i3, math.floatMax(f32), 3);
75 try test__fixint(f32, i3, math.inf(f32), 3);
76}
77
78test "fixint.i32" {
79 try test__fixint(f64, i32, -math.inf(f64), math.minInt(i32));
80 try test__fixint(f64, i32, -math.floatMax(f64), math.minInt(i32));
81 try test__fixint(f64, i32, @as(f64, math.minInt(i32)), math.minInt(i32));
82 try test__fixint(f64, i32, @as(f64, math.minInt(i32)) + 1, math.minInt(i32) + 1);
83 try test__fixint(f64, i32, -2.0, -2);
84 try test__fixint(f64, i32, -1.9, -1);
85 try test__fixint(f64, i32, -1.1, -1);
86 try test__fixint(f64, i32, -1.0, -1);
87 try test__fixint(f64, i32, -0.9, 0);
88 try test__fixint(f64, i32, -0.1, 0);
89 try test__fixint(f64, i32, -@as(f64, math.floatMin(f32)), 0);
90 try test__fixint(f64, i32, -0.0, 0);
91 try test__fixint(f64, i32, 0.0, 0);
92 try test__fixint(f64, i32, @as(f64, math.floatMin(f32)), 0);
93 try test__fixint(f64, i32, 0.1, 0);
94 try test__fixint(f64, i32, 0.9, 0);
95 try test__fixint(f64, i32, 1.0, 1);
96 try test__fixint(f64, i32, @as(f64, math.maxInt(i32)) - 1, math.maxInt(i32) - 1);
97 try test__fixint(f64, i32, @as(f64, math.maxInt(i32)), math.maxInt(i32));
98 try test__fixint(f64, i32, math.floatMax(f64), math.maxInt(i32));
99 try test__fixint(f64, i32, math.inf(f64), math.maxInt(i32));
100}
101
102test "fixint.i64" {
103 try test__fixint(f64, i64, -math.inf(f64), math.minInt(i64));
104 try test__fixint(f64, i64, -math.floatMax(f64), math.minInt(i64));
105 try test__fixint(f64, i64, @as(f64, math.minInt(i64)), math.minInt(i64));
106 try test__fixint(f64, i64, @as(f64, math.minInt(i64)) + 1, math.minInt(i64));
107 try test__fixint(f64, i64, @as(f64, math.minInt(i64) / 2), math.minInt(i64) / 2);
108 try test__fixint(f64, i64, -2.0, -2);
109 try test__fixint(f64, i64, -1.9, -1);
110 try test__fixint(f64, i64, -1.1, -1);
111 try test__fixint(f64, i64, -1.0, -1);
112 try test__fixint(f64, i64, -0.9, 0);
113 try test__fixint(f64, i64, -0.1, 0);
114 try test__fixint(f64, i64, -@as(f64, math.floatMin(f32)), 0);
115 try test__fixint(f64, i64, -0.0, 0);
116 try test__fixint(f64, i64, 0.0, 0);
117 try test__fixint(f64, i64, @as(f64, math.floatMin(f32)), 0);
118 try test__fixint(f64, i64, 0.1, 0);
119 try test__fixint(f64, i64, 0.9, 0);
120 try test__fixint(f64, i64, 1.0, 1);
121 try test__fixint(f64, i64, @as(f64, math.maxInt(i64)) - 1, math.maxInt(i64));
122 try test__fixint(f64, i64, @as(f64, math.maxInt(i64)), math.maxInt(i64));
123 try test__fixint(f64, i64, math.floatMax(f64), math.maxInt(i64));
124 try test__fixint(f64, i64, math.inf(f64), math.maxInt(i64));
125}
126
127test "fixint.i128" {
128 try test__fixint(f64, i128, -math.inf(f64), math.minInt(i128));
129 try test__fixint(f64, i128, -math.floatMax(f64), math.minInt(i128));
130 try test__fixint(f64, i128, @as(f64, math.minInt(i128)), math.minInt(i128));
131 try test__fixint(f64, i128, @as(f64, math.minInt(i128)) + 1, math.minInt(i128));
132 try test__fixint(f64, i128, -2.0, -2);
133 try test__fixint(f64, i128, -1.9, -1);
134 try test__fixint(f64, i128, -1.1, -1);
135 try test__fixint(f64, i128, -1.0, -1);
136 try test__fixint(f64, i128, -0.9, 0);
137 try test__fixint(f64, i128, -0.1, 0);
138 try test__fixint(f64, i128, -@as(f64, math.floatMin(f32)), 0);
139 try test__fixint(f64, i128, -0.0, 0);
140 try test__fixint(f64, i128, 0.0, 0);
141 try test__fixint(f64, i128, @as(f64, math.floatMin(f32)), 0);
142 try test__fixint(f64, i128, 0.1, 0);
143 try test__fixint(f64, i128, 0.9, 0);
144 try test__fixint(f64, i128, 1.0, 1);
145 try test__fixint(f64, i128, @as(f64, math.maxInt(i128)) - 1, math.maxInt(i128));
146 try test__fixint(f64, i128, @as(f64, math.maxInt(i128)), math.maxInt(i128));
147 try test__fixint(f64, i128, math.floatMax(f64), math.maxInt(i128));
148 try test__fixint(f64, i128, math.inf(f64), math.maxInt(i128));
149}
lib/compiler_rt/fixsfdi.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4const symbol = @import("../compiler_rt.zig").symbol;
5
6comptime {
7 if (compiler_rt.want_aeabi) {
8 symbol(&__aeabi_f2lz, "__aeabi_f2lz");
9 } else {
10 if (compiler_rt.want_windows_arm_abi) {
11 symbol(&__fixsfdi, "__stoi64");
12 }
13 symbol(&__fixsfdi, "__fixsfdi");
14 }
15}
16
17pub fn __fixsfdi(a: f32) callconv(.c) i64 {
18 return intFromFloat(i64, a);
19}
20
21fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 {
22 return intFromFloat(i64, a);
23}
lib/compiler_rt/fixsfei.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixsfei, "__fixsfei");
9}
10
11pub fn __fixsfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a);
14}
lib/compiler_rt/fixsfsi.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_f2iz, "__aeabi_f2iz");
8 } else {
9 symbol(&__fixsfsi, "__fixsfsi");
10 }
11}
12
13pub fn __fixsfsi(a: f32) callconv(.c) i32 {
14 return intFromFloat(i32, a);
15}
16
17fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
18 return intFromFloat(i32, a);
19}
lib/compiler_rt/fixsfti.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
7 symbol(&__fixsfti, "__fixsfti");
8}
9
10pub fn __fixsfti(a: f32) callconv(.c) i128 {
11 return intFromFloat(i128, a);
12}
lib/compiler_rt/fixtfdi.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__fixtfdi, "__fixkfdi");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_qtox, "_Qp_qtox");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__fixtfdi, "_Q_qtoll");
12 }
13 symbol(&__fixtfdi, "__fixtfdi");
14}
15
16pub fn __fixtfdi(a: f128) callconv(.c) i64 {
17 return intFromFloat(i64, a);
18}
19
20fn _Qp_qtox(a: *const f128) callconv(.c) i64 {
21 return intFromFloat(i64, a.*);
22}
lib/compiler_rt/fixtfei.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixtfei, "__fixtfei");
9}
10
11pub fn __fixtfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a);
14}
lib/compiler_rt/fixtfsi.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__fixtfsi, "__fixkfsi");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_qtoi, "_Qp_qtoi");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__fixtfsi, "_Q_qtoi");
12 }
13 symbol(&__fixtfsi, "__fixtfsi");
14}
15
16pub fn __fixtfsi(a: f128) callconv(.c) i32 {
17 return intFromFloat(i32, a);
18}
19
20fn _Qp_qtoi(a: *const f128) callconv(.c) i32 {
21 return intFromFloat(i32, a.*);
22}
lib/compiler_rt/fixtfti.zig deleted-13
...@@ -1,13 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_ppc_abi)
7 symbol(&__fixtfti, "__fixkfti");
8 symbol(&__fixtfti, "__fixtfti");
9}
10
11pub fn __fixtfti(a: f128) callconv(.c) i128 {
12 return intFromFloat(i128, a);
13}
lib/compiler_rt/fixunsdfdi.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
7 if (compiler_rt.want_aeabi) {
8 symbol(&__aeabi_d2ulz, "__aeabi_d2ulz");
9 } else {
10 if (compiler_rt.want_windows_arm_abi) {
11 symbol(&__fixunsdfdi, "__dtou64");
12 }
13 symbol(&__fixunsdfdi, "__fixunsdfdi");
14 }
15}
16
17pub fn __fixunsdfdi(a: f64) callconv(.c) u64 {
18 return intFromFloat(u64, a);
19}
20
21fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 {
22 return intFromFloat(u64, a);
23}
lib/compiler_rt/fixunsdfei.zig deleted-15
...@@ -1,15 +0,0 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
7
8comptime {
9 symbol(&__fixunsdfei, "__fixunsdfei");
10}
11
12pub fn __fixunsdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void {
13 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
14 return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a);
15}
lib/compiler_rt/fixunsdfsi.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_d2uiz, "__aeabi_d2uiz");
8 } else {
9 symbol(&__fixunsdfsi, "__fixunsdfsi");
10 }
11}
12
13pub fn __fixunsdfsi(a: f64) callconv(.c) u32 {
14 return intFromFloat(u32, a);
15}
16
17fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 {
18 return intFromFloat(u32, a);
19}
lib/compiler_rt/fixunsdfti.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 symbol(&__fixunsdfti, "__fixunsdfti");
7}
8
9pub fn __fixunsdfti(a: f64) callconv(.c) u128 {
10 return intFromFloat(u128, a);
11}
lib/compiler_rt/fixunshfdi.zig deleted-10
...@@ -1,10 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3
4comptime {
5 symbol(&__fixunshfdi, "__fixunshfdi");
6}
7
8fn __fixunshfdi(a: f16) callconv(.c) u64 {
9 return intFromFloat(u64, a);
10}
lib/compiler_rt/fixunshfei.zig deleted-15
...@@ -1,15 +0,0 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
7
8comptime {
9 symbol(&__fixunshfei, "__fixunshfei");
10}
11
12pub fn __fixunshfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void {
13 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
14 return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a);
15}
lib/compiler_rt/fixunshfsi.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 symbol(&__fixunshfsi, "__fixunshfsi");
7}
8
9fn __fixunshfsi(a: f16) callconv(.c) u32 {
10 return intFromFloat(u32, a);
11}
lib/compiler_rt/fixunshfti.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__fixunshfti, "__fixunshfti");
7}
8
9pub fn __fixunshfti(a: f16) callconv(.c) u128 {
10 return intFromFloat(u128, a);
11}
lib/compiler_rt/fixunssfdi.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
7 if (compiler_rt.want_aeabi) {
8 symbol(&__aeabi_f2ulz, "__aeabi_f2ulz");
9 } else {
10 if (compiler_rt.want_windows_arm_abi) {
11 symbol(&__fixunssfdi, "__stou64");
12 }
13 symbol(&__fixunssfdi, "__fixunssfdi");
14 }
15}
16
17pub fn __fixunssfdi(a: f32) callconv(.c) u64 {
18 return intFromFloat(u64, a);
19}
20
21fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 {
22 return intFromFloat(u64, a);
23}
lib/compiler_rt/fixunssfei.zig deleted-15
...@@ -1,15 +0,0 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
7
8comptime {
9 symbol(&__fixunssfei, "__fixunssfei");
10}
11
12pub fn __fixunssfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void {
13 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
14 return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a);
15}
lib/compiler_rt/fixunssfsi.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_f2uiz, "__aeabi_f2uiz");
8 } else {
9 symbol(&__fixunssfsi, "__fixunssfsi");
10 }
11}
12
13pub fn __fixunssfsi(a: f32) callconv(.c) u32 {
14 return intFromFloat(u32, a);
15}
16
17fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 {
18 return intFromFloat(u32, a);
19}
lib/compiler_rt/fixunssfti.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4const symbol = @import("../compiler_rt.zig").symbol;
5
6comptime {
7 symbol(&__fixunssfti, "__fixunssfti");
8}
9
10pub fn __fixunssfti(a: f32) callconv(.c) u128 {
11 return intFromFloat(u128, a);
12}
lib/compiler_rt/fixunstfdi.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__fixunstfdi, "__fixunskfdi");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_qtoux, "_Qp_qtoux");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__fixunstfdi, "_Q_qtoull");
12 }
13 symbol(&__fixunstfdi, "__fixunstfdi");
14}
15
16pub fn __fixunstfdi(a: f128) callconv(.c) u64 {
17 return intFromFloat(u64, a);
18}
19
20fn _Qp_qtoux(a: *const f128) callconv(.c) u64 {
21 return intFromFloat(u64, a.*);
22}
lib/compiler_rt/fixunstfei.zig deleted-15
...@@ -1,15 +0,0 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
7
8comptime {
9 symbol(&__fixunstfei, "__fixunstfei");
10}
11
12pub fn __fixunstfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void {
13 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
14 return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a);
15}
lib/compiler_rt/fixunstfsi.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__fixunstfsi, "__fixunskfsi");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_qtoui, "_Qp_qtoui");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__fixunstfsi, "_Q_qtou");
12 }
13 symbol(&__fixunstfsi, "__fixunstfsi");
14}
15
16pub fn __fixunstfsi(a: f128) callconv(.c) u32 {
17 return intFromFloat(u32, a);
18}
19
20fn _Qp_qtoui(a: *const f128) callconv(.c) u32 {
21 return intFromFloat(u32, a.*);
22}
lib/compiler_rt/fixunstfti.zig deleted-14
...@@ -1,14 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
7 if (compiler_rt.want_ppc_abi)
8 symbol(&__fixunstfti, "__fixunskfti");
9 symbol(&__fixunstfti, "__fixunstfti");
10}
11
12pub fn __fixunstfti(a: f128) callconv(.c) u128 {
13 return intFromFloat(u128, a);
14}
lib/compiler_rt/fixunsxfdi.zig deleted-10
...@@ -1,10 +0,0 @@
1const intFromFloat = @import("./int_from_float.zig").intFromFloat;
2const symbol = @import("../compiler_rt.zig").symbol;
3
4comptime {
5 symbol(&__fixunsxfdi, "__fixunsxfdi");
6}
7
8fn __fixunsxfdi(a: f80) callconv(.c) u64 {
9 return intFromFloat(u64, a);
10}
lib/compiler_rt/fixunsxfei.zig deleted-13
...@@ -1,13 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const symbol = @import("../compiler_rt.zig").symbol;
4const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
5
6comptime {
7 symbol(&__fixunsxfei, "__fixunsxfei");
8}
9
10pub fn __fixunsxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void {
11 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
12 return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a);
13}
lib/compiler_rt/fixunsxfsi.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 symbol(&__fixunsxfsi, "__fixunsxfsi");
7}
8
9fn __fixunsxfsi(a: f80) callconv(.c) u32 {
10 return intFromFloat(u32, a);
11}
lib/compiler_rt/fixunsxfti.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
7 symbol(&__fixunsxfti, "__fixunsxfti");
8}
9
10pub fn __fixunsxfti(a: f80) callconv(.c) u128 {
11 return intFromFloat(u128, a);
12}
lib/compiler_rt/fixxfdi.zig deleted-10
...@@ -1,10 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3
4comptime {
5 symbol(&__fixxfdi, "__fixxfdi");
6}
7
8fn __fixxfdi(a: f80) callconv(.c) i64 {
9 return intFromFloat(i64, a);
10}
lib/compiler_rt/fixxfei.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixxfei, "__fixxfei");
9}
10
11pub fn __fixxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a);
14}
lib/compiler_rt/fixxfsi.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 symbol(&__fixxfsi, "__fixxfsi");
7}
8
9fn __fixxfsi(a: f80) callconv(.c) i32 {
10 return intFromFloat(i32, a);
11}
lib/compiler_rt/float_from_int.zig+472-4
...@@ -1,7 +1,475 @@...@@ -1,7 +1,475 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const math = std.math;3const math = std.math;
34
4pub fn floatFromInt(comptime T: type, x: anytype) T {5const compiler_rt = @import("../compiler_rt.zig");
6const symbol = compiler_rt.symbol;
7
8comptime {
9 symbol(&__floatsihf, "__floatsihf");
10 symbol(&__floatdihf, "__floatdihf");
11 symbol(&__floattihf, "__floattihf");
12 symbol(&__floateihf, "__floateihf");
13
14 if (compiler_rt.want_aeabi) {
15 symbol(&__aeabi_i2f, "__aeabi_i2f");
16 symbol(&__aeabi_l2f, "__aeabi_l2f");
17 } else {
18 symbol(&__floatsisf, "__floatsisf");
19 symbol(&__floatdisf, "__floatdisf");
20 if (compiler_rt.want_windows_arm_abi) symbol(&__floatdisf, "__i64tos");
21 }
22 symbol(&__floattisf, "__floattisf");
23 symbol(&__floateisf, "__floateisf");
24
25 if (compiler_rt.want_aeabi) {
26 symbol(&__aeabi_i2d, "__aeabi_i2d");
27 symbol(&__aeabi_l2d, "__aeabi_l2d");
28 } else {
29 symbol(&__floatsidf, "__floatsidf");
30 symbol(&__floatdidf, "__floatdidf");
31 if (compiler_rt.want_windows_arm_abi) symbol(&__floatdidf, "__i64tod");
32 }
33 symbol(&__floattidf, "__floattidf");
34 symbol(&__floateidf, "__floateidf");
35
36 symbol(&__floatsixf, "__floatsixf");
37 symbol(&__floatdixf, "__floatdixf");
38 symbol(&__floattixf, "__floattixf");
39 symbol(&__floateixf, "__floateixf");
40
41 if (compiler_rt.want_ppc_abi) {
42 symbol(&__floatsitf, "__floatsikf");
43 symbol(&__floatditf, "__floatdikf");
44 } else if (compiler_rt.want_sparc64_abi) {
45 symbol(&_Qp_itoq, "_Qp_itoq");
46 symbol(&_Qp_xtoq, "_Qp_xtoq");
47 } else if (compiler_rt.want_sparc32_abi) {
48 symbol(&__floatsitf, "_Q_itoq");
49 symbol(&__floatditf, "_Q_lltoq");
50 } else {
51 symbol(&__floatsitf, "__floatsitf");
52 symbol(&__floatditf, "__floatditf");
53 }
54 if (compiler_rt.want_ppc_abi) {
55 symbol(&__floattitf, "__floattikf");
56 symbol(&__floateitf, "__floateikf");
57 } else {
58 if (builtin.cpu.arch == .x86) {
59 symbol(&__floattitf_x86, "__floattitf");
60 } else {
61 symbol(&__floattitf, "__floattitf");
62 }
63 symbol(&__floateitf, "__floateitf");
64 }
65}
66
67fn __floatsihf(a: i32) callconv(.c) compiler_rt.f16.Abi {
68 return compiler_rt.f16.toAbi(f16_floatFromInt_i32(a));
69}
70pub fn f16_floatFromInt_i32(a: i32) f16 {
71 return floatFromInt(f16, a);
72}
73
74fn __floatdihf(a: i64) callconv(.c) compiler_rt.f16.Abi {
75 return compiler_rt.f16.toAbi(f16_floatFromInt_i64(a));
76}
77pub fn f16_floatFromInt_i64(a: i64) f16 {
78 return floatFromInt(f16, a);
79}
80
81fn __floattihf(a: i128) callconv(.c) compiler_rt.f16.Abi {
82 return compiler_rt.f16.toAbi(f16_floatFromInt_i128(a));
83}
84pub fn f16_floatFromInt_i128(a: i128) f16 {
85 return floatFromInt(f16, a);
86}
87
88fn __floateihf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f16.Abi {
89 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
90 return compiler_rt.f16.toAbi(f16_floatFromInt_signed(a[0..byte_size]));
91}
92pub fn f16_floatFromInt_signed(a: []const u8) f16 {
93 return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a)));
94}
95
96fn __floatsisf(a: i32) callconv(.c) compiler_rt.f32.Abi {
97 return compiler_rt.f32.toAbi(f32_floatFromInt_i32(a));
98}
99fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 {
100 return f32_floatFromInt_i32(a);
101}
102pub fn f32_floatFromInt_i32(a: i32) f32 {
103 return floatFromInt(f32, a);
104}
105
106fn __floatdisf(a: i64) callconv(.c) compiler_rt.f32.Abi {
107 return compiler_rt.f32.toAbi(f32_floatFromInt_i64(a));
108}
109fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 {
110 return f32_floatFromInt_i64(a);
111}
112pub fn f32_floatFromInt_i64(a: i64) f32 {
113 return floatFromInt(f32, a);
114}
115
116fn __floattisf(a: i128) callconv(.c) compiler_rt.f32.Abi {
117 return compiler_rt.f32.toAbi(f32_floatFromInt_i128(a));
118}
119pub fn f32_floatFromInt_i128(a: i128) f32 {
120 return floatFromInt(f32, a);
121}
122
123fn __floateisf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f32.Abi {
124 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
125 return compiler_rt.f32.toAbi(f32_floatFromInt_signed(a[0..byte_size]));
126}
127pub fn f32_floatFromInt_signed(a: []const u8) f32 {
128 return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a)));
129}
130
131fn __floatsidf(a: i32) callconv(.c) compiler_rt.f64.Abi {
132 return compiler_rt.f64.toAbi(f64_floatFromInt_i32(a));
133}
134fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 {
135 return f64_floatFromInt_i32(a);
136}
137pub fn f64_floatFromInt_i32(a: i32) f64 {
138 return floatFromInt(f64, a);
139}
140
141fn __floatdidf(a: i64) callconv(.c) compiler_rt.f64.Abi {
142 return compiler_rt.f64.toAbi(f64_floatFromInt_i64(a));
143}
144fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 {
145 return f64_floatFromInt_i64(a);
146}
147pub fn f64_floatFromInt_i64(a: i64) f64 {
148 return floatFromInt(f64, a);
149}
150
151fn __floattidf(a: i128) callconv(.c) compiler_rt.f64.Abi {
152 return compiler_rt.f64.toAbi(f64_floatFromInt_i128(a));
153}
154pub fn f64_floatFromInt_i128(a: i128) f64 {
155 return floatFromInt(f64, a);
156}
157
158fn __floateidf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f64.Abi {
159 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
160 return compiler_rt.f64.toAbi(f64_floatFromInt_signed(a[0..byte_size]));
161}
162pub fn f64_floatFromInt_signed(a: []const u8) f64 {
163 return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a)));
164}
165
166fn __floatsixf(a: i32) callconv(.c) compiler_rt.f80.Abi {
167 return compiler_rt.f80.toAbi(f80_floatFromInt_i32(a));
168}
169pub fn f80_floatFromInt_i32(a: i32) f80 {
170 return floatFromInt(f80, a);
171}
172
173fn __floatdixf(a: i64) callconv(.c) compiler_rt.f80.Abi {
174 return compiler_rt.f80.toAbi(f80_floatFromInt_i64(a));
175}
176pub fn f80_floatFromInt_i64(a: i64) f80 {
177 return floatFromInt(f80, a);
178}
179
180fn __floattixf(a: i128) callconv(.c) compiler_rt.f80.Abi {
181 return compiler_rt.f80.toAbi(f80_floatFromInt_i128(a));
182}
183pub fn f80_floatFromInt_i128(a: i128) f80 {
184 return floatFromInt(f80, a);
185}
186
187fn __floateixf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f80.Abi {
188 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
189 return compiler_rt.f80.toAbi(f80_floatFromInt_signed(a[0..byte_size]));
190}
191pub fn f80_floatFromInt_signed(a: []const u8) f80 {
192 return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a)));
193}
194
195fn __floatsitf(a: i32) callconv(.c) compiler_rt.f128.Abi {
196 return compiler_rt.f128.toAbi(f128_floatFromInt_i32(a));
197}
198fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void {
199 c.* = f128_floatFromInt_i32(a);
200}
201pub fn f128_floatFromInt_i32(a: i32) f128 {
202 return floatFromInt(f128, a);
203}
204
205fn __floatditf(a: i64) callconv(.c) compiler_rt.f128.Abi {
206 return compiler_rt.f128.toAbi(f128_floatFromInt_i64(a));
207}
208fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void {
209 c.* = f128_floatFromInt_i64(a);
210}
211pub fn f128_floatFromInt_i64(a: i64) f128 {
212 return floatFromInt(f128, a);
213}
214
215fn __floattitf(a: i128) callconv(.c) compiler_rt.f128.Abi {
216 return compiler_rt.f128.toAbi(f128_floatFromInt_i128(a));
217}
218fn __floattitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi {
219 return compiler_rt.f128.toAbi(f128_floatFromInt_i128(@bitCast(a)));
220}
221pub fn f128_floatFromInt_i128(a: i128) f128 {
222 return floatFromInt(f128, a);
223}
224
225fn __floateitf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f128.Abi {
226 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
227 return compiler_rt.f128.toAbi(f128_floatFromInt_signed(a[0..byte_size]));
228}
229pub fn f128_floatFromInt_signed(a: []const u8) f128 {
230 return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a)));
231}
232
233comptime {
234 symbol(&__floatunsihf, "__floatunsihf");
235 symbol(&__floatundihf, "__floatundihf");
236 symbol(&__floatuntihf, "__floatuntihf");
237 symbol(&__floatuneihf, "__floatuneihf");
238
239 if (compiler_rt.want_aeabi) {
240 symbol(&__aeabi_ui2f, "__aeabi_ui2f");
241 symbol(&__aeabi_ul2f, "__aeabi_ul2f");
242 } else {
243 symbol(&__floatunsisf, "__floatunsisf");
244 symbol(&__floatundisf, "__floatundisf");
245 if (compiler_rt.want_windows_arm_abi) symbol(&__floatundisf, "__u64tos");
246 }
247 symbol(&__floatuntisf, "__floatuntisf");
248 symbol(&__floatuneisf, "__floatuneisf");
249
250 if (compiler_rt.want_aeabi) {
251 symbol(&__aeabi_ui2d, "__aeabi_ui2d");
252 } else {
253 symbol(&__floatunsidf, "__floatunsidf");
254 }
255 if (compiler_rt.want_aeabi) {
256 symbol(&__aeabi_ul2d, "__aeabi_ul2d");
257 } else {
258 if (compiler_rt.want_windows_arm_abi) {
259 symbol(&__floatundidf, "__u64tod");
260 }
261 symbol(&__floatundidf, "__floatundidf");
262 }
263 symbol(&__floatuntidf, "__floatuntidf");
264 symbol(&__floatuneidf, "__floatuneidf");
265
266 symbol(&__floatunsixf, "__floatunsixf");
267 symbol(&__floatundixf, "__floatundixf");
268 symbol(&__floatuntixf, "__floatuntixf");
269 symbol(&__floatuneixf, "__floatuneixf");
270
271 if (compiler_rt.want_ppc_abi) {
272 symbol(&__floatunsitf, "__floatunsikf");
273 symbol(&__floatunditf, "__floatundikf");
274 } else if (compiler_rt.want_sparc64_abi) {
275 symbol(&_Qp_uitoq, "_Qp_uitoq");
276 symbol(&_Qp_uxtoq, "_Qp_uxtoq");
277 } else if (compiler_rt.want_sparc32_abi) {
278 symbol(&__floatunsitf, "_Q_utoq");
279 symbol(&__floatunditf, "_Q_ulltoq");
280 } else {
281 symbol(&__floatunsitf, "__floatunsitf");
282 symbol(&__floatunditf, "__floatunditf");
283 }
284 if (compiler_rt.want_ppc_abi) {
285 symbol(&__floatuntitf, "__floatuntikf");
286 symbol(&__floatuneitf, "__floatuneikf");
287 } else {
288 if (builtin.cpu.arch == .x86) {
289 symbol(&__floatuntitf_x86, "__floatuntitf");
290 } else if (builtin.cpu.arch == .x86_64 and
291 (builtin.os.tag == .windows or builtin.os.tag == .uefi))
292 {
293 symbol(&__floatuntitf_x86_64_windows, "__floatuntitf");
294 } else {
295 symbol(&__floatuntitf, "__floatuntitf");
296 }
297 symbol(&__floatuneitf, "__floatuneitf");
298 }
299}
300
301fn __floatunsihf(a: u32) callconv(.c) compiler_rt.f16.Abi {
302 return compiler_rt.f16.toAbi(f16_floatFromInt_u32(a));
303}
304pub fn f16_floatFromInt_u32(a: u32) f16 {
305 return floatFromInt(f16, a);
306}
307
308fn __floatundihf(a: u64) callconv(.c) compiler_rt.f16.Abi {
309 return compiler_rt.f16.toAbi(f16_floatFromInt_u64(a));
310}
311pub fn f16_floatFromInt_u64(a: u64) f16 {
312 return floatFromInt(f16, a);
313}
314
315fn __floatuntihf(a: u128) callconv(.c) compiler_rt.f16.Abi {
316 return compiler_rt.f16.toAbi(f16_floatFromInt_u128(a));
317}
318pub fn f16_floatFromInt_u128(a: u128) f16 {
319 return floatFromInt(f16, a);
320}
321
322fn __floatuneihf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f16.Abi {
323 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
324 return compiler_rt.f16.toAbi(f16_floatFromInt_unsigned(a[0..byte_size]));
325}
326pub fn f16_floatFromInt_unsigned(a: []const u8) f16 {
327 return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a)));
328}
329
330fn __floatunsisf(a: u32) callconv(.c) compiler_rt.f32.Abi {
331 return compiler_rt.f32.toAbi(f32_floatFromInt_u32(a));
332}
333fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 {
334 return f32_floatFromInt_u32(a);
335}
336pub fn f32_floatFromInt_u32(a: u32) f32 {
337 return floatFromInt(f32, a);
338}
339
340fn __floatundisf(a: u64) callconv(.c) compiler_rt.f32.Abi {
341 return compiler_rt.f32.toAbi(f32_floatFromInt_u64(a));
342}
343fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 {
344 return f32_floatFromInt_u64(a);
345}
346pub fn f32_floatFromInt_u64(a: u64) f32 {
347 return floatFromInt(f32, a);
348}
349
350fn __floatuntisf(a: u128) callconv(.c) compiler_rt.f32.Abi {
351 return compiler_rt.f32.toAbi(f32_floatFromInt_u128(a));
352}
353pub fn f32_floatFromInt_u128(a: u128) f32 {
354 return floatFromInt(f32, a);
355}
356
357fn __floatuneisf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f32.Abi {
358 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
359 return compiler_rt.f32.toAbi(f32_floatFromInt_unsigned(a[0..byte_size]));
360}
361pub fn f32_floatFromInt_unsigned(a: []const u8) f32 {
362 return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a)));
363}
364
365fn __floatunsidf(a: u32) callconv(.c) compiler_rt.f64.Abi {
366 return compiler_rt.f64.toAbi(f64_floatFromInt_u32(a));
367}
368fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 {
369 return f64_floatFromInt_u32(a);
370}
371pub fn f64_floatFromInt_u32(a: u32) f64 {
372 return floatFromInt(f64, a);
373}
374
375fn __floatundidf(a: u64) callconv(.c) compiler_rt.f64.Abi {
376 return compiler_rt.f64.toAbi(f64_floatFromInt_u64(a));
377}
378fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 {
379 return f64_floatFromInt_u64(a);
380}
381pub fn f64_floatFromInt_u64(a: u64) f64 {
382 return floatFromInt(f64, a);
383}
384
385fn __floatuntidf(a: u128) callconv(.c) compiler_rt.f64.Abi {
386 return compiler_rt.f64.toAbi(f64_floatFromInt_u128(a));
387}
388pub fn f64_floatFromInt_u128(a: u128) f64 {
389 return floatFromInt(f64, a);
390}
391
392fn __floatuneidf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f64.Abi {
393 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
394 return compiler_rt.f64.toAbi(f64_floatFromInt_unsigned(a[0..byte_size]));
395}
396pub fn f64_floatFromInt_unsigned(a: []const u8) f64 {
397 return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a)));
398}
399
400fn __floatunsixf(a: u32) callconv(.c) compiler_rt.f80.Abi {
401 return compiler_rt.f80.toAbi(f80_floatFromInt_u32(a));
402}
403pub fn f80_floatFromInt_u32(a: u32) f80 {
404 return floatFromInt(f80, a);
405}
406
407fn __floatundixf(a: u64) callconv(.c) compiler_rt.f80.Abi {
408 return compiler_rt.f80.toAbi(f80_floatFromInt_u64(a));
409}
410pub fn f80_floatFromInt_u64(a: u64) f80 {
411 return floatFromInt(f80, a);
412}
413
414fn __floatuntixf(a: u128) callconv(.c) compiler_rt.f80.Abi {
415 return compiler_rt.f80.toAbi(f80_floatFromInt_u128(a));
416}
417pub fn f80_floatFromInt_u128(a: u128) f80 {
418 return floatFromInt(f80, a);
419}
420
421fn __floatuneixf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f80.Abi {
422 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
423 return compiler_rt.f80.toAbi(f80_floatFromInt_unsigned(a[0..byte_size]));
424}
425pub fn f80_floatFromInt_unsigned(a: []const u8) f80 {
426 return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a)));
427}
428
429fn __floatunsitf(a: u32) callconv(.c) compiler_rt.f128.Abi {
430 return compiler_rt.f128.toAbi(f128_floatFromInt_u32(a));
431}
432fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void {
433 c.* = f128_floatFromInt_u32(a);
434}
435pub fn f128_floatFromInt_u32(a: u32) f128 {
436 return floatFromInt(f128, a);
437}
438
439fn __floatunditf(a: u64) callconv(.c) compiler_rt.f128.Abi {
440 return compiler_rt.f128.toAbi(f128_floatFromInt_u64(a));
441}
442fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void {
443 c.* = f128_floatFromInt_u64(a);
444}
445pub fn f128_floatFromInt_u64(a: u64) f128 {
446 return floatFromInt(f128, a);
447}
448
449fn __floatuntitf(a: u128) callconv(.c) compiler_rt.f128.Abi {
450 return compiler_rt.f128.toAbi(f128_floatFromInt_u128(a));
451}
452fn __floatuntitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi {
453 return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast(a)));
454}
455fn __floatuntitf_x86_64_windows(a_lo: u64, a_hi: u64) callconv(.c) compiler_rt.f128.Abi {
456 return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast(
457 packed struct { lo: u64, hi: u64 }{ .lo = a_lo, .hi = a_hi },
458 )));
459}
460pub fn f128_floatFromInt_u128(a: u128) f128 {
461 return floatFromInt(f128, a);
462}
463
464fn __floatuneitf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f128.Abi {
465 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
466 return compiler_rt.f128.toAbi(f128_floatFromInt_unsigned(a[0..byte_size]));
467}
468pub fn f128_floatFromInt_unsigned(a: []const u8) f128 {
469 return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a)));
470}
471
472inline fn floatFromInt(comptime T: type, x: anytype) T {
5 if (x == 0) return 0;473 if (x == 0) return 0;
6474
7 // Various constants whose values follow from the type parameters.475 // Various constants whose values follow from the type parameters.
...@@ -53,7 +521,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {...@@ -53,7 +521,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {
53 return @bitCast(sign_bit | result);521 return @bitCast(sign_bit | result);
54}522}
55523
56const endian = @import("builtin").cpu.arch.endian();524const endian = builtin.cpu.arch.endian();
57inline fn limb(limbs: []const u32, index: usize) u32 {525inline fn limb(limbs: []const u32, index: usize) u32 {
58 return switch (endian) {526 return switch (endian) {
59 .little => limbs[index],527 .little => limbs[index],
...@@ -61,11 +529,11 @@ inline fn limb(limbs: []const u32, index: usize) u32 {...@@ -61,11 +529,11 @@ inline fn limb(limbs: []const u32, index: usize) u32 {
61 };529 };
62}530}
63531
64pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin.Signedness, x: []const u32) T {532inline fn floatFromBigInt(comptime T: type, comptime signedness: std.lang.Signedness, x: []const u32) T {
65 switch (x.len) {533 switch (x.len) {
66 0 => return 0,534 0 => return 0,
67 inline 1...4 => |limbs_len| {535 inline 1...4 => |limbs_len| {
68 const low_to_high: [limbs_len]u32 = switch (@import("builtin").cpu.arch.endian()) {536 const low_to_high: [limbs_len]u32 = switch (endian) {
69 .little => x[0..limbs_len].*,537 .little => x[0..limbs_len].*,
70 .big => switch (limbs_len) {538 .big => switch (limbs_len) {
71 1 => .{x[0]},539 1 => .{x[0]},
lib/compiler_rt/float_from_int_test.zig+757-733
...@@ -2,571 +2,593 @@ const std = @import("std");...@@ -2,571 +2,593 @@ const std = @import("std");
2const testing = std.testing;2const testing = std.testing;
3const math = std.math;3const math = std.math;
44
5const __floatunsihf = @import("floatunsihf.zig").__floatunsihf;5const impl = @import("float_from_int.zig");
66
7// Conversion to f327const f16_floatFromInt_i32 = impl.f16_floatFromInt_i32;
8const __floatsisf = @import("floatsisf.zig").__floatsisf;8const f16_floatFromInt_u32 = impl.f16_floatFromInt_u32;
9const __floatunsisf = @import("floatunsisf.zig").__floatunsisf;9const f16_floatFromInt_i64 = impl.f16_floatFromInt_i64;
10const __floatdisf = @import("floatdisf.zig").__floatdisf;10const f16_floatFromInt_u64 = impl.f16_floatFromInt_u64;
11const __floatundisf = @import("floatundisf.zig").__floatundisf;11const f16_floatFromInt_i128 = impl.f16_floatFromInt_i128;
12const __floattisf = @import("floattisf.zig").__floattisf;12const f16_floatFromInt_u128 = impl.f16_floatFromInt_u128;
13const __floatuntisf = @import("floatuntisf.zig").__floatuntisf;13const f16_floatFromInt_signed = impl.f16_floatFromInt_signed;
14const __floateisf = @import("floateisf.zig").__floateisf;14const f16_floatFromInt_unsigned = impl.f16_floatFromInt_unsigned;
15const __floatuneisf = @import("floatuneisf.zig").__floatuneisf;15
1616const f32_floatFromInt_i32 = impl.f32_floatFromInt_i32;
17// Conversion to f6417const f32_floatFromInt_u32 = impl.f32_floatFromInt_u32;
18const __floatsidf = @import("floatsidf.zig").__floatsidf;18const f32_floatFromInt_i64 = impl.f32_floatFromInt_i64;
19const __floatunsidf = @import("floatunsidf.zig").__floatunsidf;19const f32_floatFromInt_u64 = impl.f32_floatFromInt_u64;
20const __floatdidf = @import("floatdidf.zig").__floatdidf;20const f32_floatFromInt_i128 = impl.f32_floatFromInt_i128;
21const __floatundidf = @import("floatundidf.zig").__floatundidf;21const f32_floatFromInt_u128 = impl.f32_floatFromInt_u128;
22const __floattidf = @import("floattidf.zig").__floattidf;22const f32_floatFromInt_signed = impl.f32_floatFromInt_signed;
23const __floatuntidf = @import("floatuntidf.zig").__floatuntidf;23const f32_floatFromInt_unsigned = impl.f32_floatFromInt_unsigned;
2424
25// Conversion to f12825const f64_floatFromInt_i32 = impl.f64_floatFromInt_i32;
26const __floatsitf = @import("floatsitf.zig").__floatsitf;26const f64_floatFromInt_u32 = impl.f64_floatFromInt_u32;
27const __floatunsitf = @import("floatunsitf.zig").__floatunsitf;27const f64_floatFromInt_i64 = impl.f64_floatFromInt_i64;
28const __floatditf = @import("floatditf.zig").__floatditf;28const f64_floatFromInt_u64 = impl.f64_floatFromInt_u64;
29const __floatunditf = @import("floatunditf.zig").__floatunditf;29const f64_floatFromInt_i128 = impl.f64_floatFromInt_i128;
30const __floattitf = @import("floattitf.zig").__floattitf;30const f64_floatFromInt_u128 = impl.f64_floatFromInt_u128;
31const __floatuntitf = @import("floatuntitf.zig").__floatuntitf;31const f64_floatFromInt_signed = impl.f64_floatFromInt_signed;
3232const f64_floatFromInt_unsigned = impl.f64_floatFromInt_unsigned;
33fn test__floatsisf(a: i32, expected: u32) !void {33
34 const r = __floatsisf(a);34const f80_floatFromInt_i32 = impl.f80_floatFromInt_i32;
35const f80_floatFromInt_u32 = impl.f80_floatFromInt_u32;
36const f80_floatFromInt_i64 = impl.f80_floatFromInt_i64;
37const f80_floatFromInt_u64 = impl.f80_floatFromInt_u64;
38const f80_floatFromInt_i128 = impl.f80_floatFromInt_i128;
39const f80_floatFromInt_u128 = impl.f80_floatFromInt_u128;
40const f80_floatFromInt_signed = impl.f80_floatFromInt_signed;
41const f80_floatFromInt_unsigned = impl.f80_floatFromInt_unsigned;
42
43const f128_floatFromInt_i32 = impl.f128_floatFromInt_i32;
44const f128_floatFromInt_u32 = impl.f128_floatFromInt_u32;
45const f128_floatFromInt_i64 = impl.f128_floatFromInt_i64;
46const f128_floatFromInt_u64 = impl.f128_floatFromInt_u64;
47const f128_floatFromInt_i128 = impl.f128_floatFromInt_i128;
48const f128_floatFromInt_u128 = impl.f128_floatFromInt_u128;
49const f128_floatFromInt_signed = impl.f128_floatFromInt_signed;
50const f128_floatFromInt_unsigned = impl.f128_floatFromInt_unsigned;
51
52fn test_f32_floatFromInt_i32(a: i32, expected: u32) !void {
53 const r = f32_floatFromInt_i32(a);
35 try std.testing.expect(@as(u32, @bitCast(r)) == expected);54 try std.testing.expect(@as(u32, @bitCast(r)) == expected);
36}55}
3756
38fn test_one_floatunsisf(a: u32, expected: u32) !void {57fn test_f32_floatFromInt_u32(a: u32, expected: u32) !void {
39 const r = __floatunsisf(a);58 const r = f32_floatFromInt_u32(a);
40 try std.testing.expect(@as(u32, @bitCast(r)) == expected);59 try std.testing.expect(@as(u32, @bitCast(r)) == expected);
41}60}
4261
43test "floatsisf" {62test f32_floatFromInt_i32 {
44 try test__floatsisf(0, 0x00000000);63 try test_f32_floatFromInt_i32(0, 0x00000000);
45 try test__floatsisf(1, 0x3f800000);64 try test_f32_floatFromInt_i32(1, 0x3f800000);
46 try test__floatsisf(-1, 0xbf800000);65 try test_f32_floatFromInt_i32(-1, 0xbf800000);
47 try test__floatsisf(0x7FFFFFFF, 0x4f000000);66 try test_f32_floatFromInt_i32(0x7FFFFFFF, 0x4f000000);
48 try test__floatsisf(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000);67 try test_f32_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000);
68
69 try testing.expect(f32_floatFromInt_i32(math.minInt(i32)) == math.minInt(i32));
49}70}
5071
51test "floatunsisf" {72test f32_floatFromInt_u32 {
52 // Test the produced bit pattern73 // Test the produced bit pattern
53 try test_one_floatunsisf(0, 0);74 try test_f32_floatFromInt_u32(0, 0);
54 try test_one_floatunsisf(1, 0x3f800000);75 try test_f32_floatFromInt_u32(1, 0x3f800000);
55 try test_one_floatunsisf(0x7FFFFFFF, 0x4f000000);76 try test_f32_floatFromInt_u32(0x7FFFFFFF, 0x4f000000);
56 try test_one_floatunsisf(0x80000000, 0x4f000000);77 try test_f32_floatFromInt_u32(0x80000000, 0x4f000000);
57 try test_one_floatunsisf(0xFFFFFFFF, 0x4f800000);78 try test_f32_floatFromInt_u32(0xFFFFFFFF, 0x4f800000);
79
80 try testing.expect(f32_floatFromInt_u32(0) == 0.0);
81 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24)) == math.maxInt(u24));
82 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact
83 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even
84 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact
85 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even
86 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact
87 try testing.expect(f32_floatFromInt_u32(math.maxInt(u32)) == math.maxInt(u32) + 1);
88}
89
90fn test_f32_floatFromInt_i64(a: i64, expected: f32) !void {
91 const x = f32_floatFromInt_i64(a);
92 try testing.expect(x == expected);
58}93}
5994
60fn test__floatdisf(a: i64, expected: f32) !void {95fn test_f32_floatFromInt_u64(a: u64, expected: f32) !void {
61 const x = __floatdisf(a);96 const x = f32_floatFromInt_u64(a);
62 try testing.expect(x == expected);97 try testing.expect(x == expected);
63}98}
6499
65fn test__floatundisf(a: u64, expected: f32) !void {100test f32_floatFromInt_i64 {
66 try std.testing.expectEqual(expected, __floatundisf(a));101 try test_f32_floatFromInt_i64(0, 0.0);
67}102 try test_f32_floatFromInt_i64(1, 1.0);
68103 try test_f32_floatFromInt_i64(2, 2.0);
69test "floatdisf" {104 try test_f32_floatFromInt_i64(-1, -1.0);
70 try test__floatdisf(0, 0.0);105 try test_f32_floatFromInt_i64(-2, -2.0);
71 try test__floatdisf(1, 1.0);106 try test_f32_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
72 try test__floatdisf(2, 2.0);107 try test_f32_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
73 try test__floatdisf(-1, -1.0);108 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);
74 try test__floatdisf(-2, -2.0);109 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);
75 try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);110 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63);
76 try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);111 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63);
77 try test__floatdisf(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);112 try test_f32_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
78 try test__floatdisf(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);113 try test_f32_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBAp+50);
79 try test__floatdisf(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63);114 try test_f32_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBAp+50);
80 try test__floatdisf(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63);115 try test_f32_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
81 try test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);116 try test_f32_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBCp+50);
82 try test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);117 try test_f32_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBAp+50);
83 try test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);118 try test_f32_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCBAp+50);
84 try test__floatdisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);119 try test_f32_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCBAp+50);
85 try test__floatdisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);120 try test_f32_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
86 try test__floatdisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);121 try test_f32_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCBAp+50);
87 try test__floatdisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);122 try test_f32_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB8p+50);
88 try test__floatdisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);123}
89 try test__floatdisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);124
90 try test__floatdisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);125test f32_floatFromInt_u64 {
91 try test__floatdisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);126 try test_f32_floatFromInt_u64(0, 0.0);
92}127 try test_f32_floatFromInt_u64(1, 1.0);
93128 try test_f32_floatFromInt_u64(2, 2.0);
94test "floatundisf" {129 try test_f32_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
95 try test__floatundisf(0, 0.0);130 try test_f32_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
96 try test__floatundisf(1, 1.0);131 try test_f32_floatFromInt_u64(0x8000008000000000, 0x1p+63);
97 try test__floatundisf(2, 2.0);132 try test_f32_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63);
98 try test__floatundisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);133 try test_f32_floatFromInt_u64(0x8000000000000000, 0x1p+63);
99 try test__floatundisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);134 try test_f32_floatFromInt_u64(0x8000000000000001, 0x1p+63);
100 try test__floatundisf(0x8000008000000000, 0x1p+63);135 try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFE, 0x1p+64);
101 try test__floatundisf(0x8000010000000000, 0x1.000002p+63);136 try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFF, 0x1p+64);
102 try test__floatundisf(0x8000000000000000, 0x1p+63);137 try test_f32_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
103 try test__floatundisf(0x8000000000000001, 0x1p+63);138 try test_f32_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBAp+50);
104 try test__floatundisf(0xFFFFFFFFFFFFFFFE, 0x1p+64);139 try test_f32_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBAp+50);
105 try test__floatundisf(0xFFFFFFFFFFFFFFFF, 0x1p+64);140 try test_f32_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
106 try test__floatundisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);141 try test_f32_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBCp+50);
107 try test__floatundisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);142 try test_f32_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBAp+50);
108 try test__floatundisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);143 try test_f32_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCBAp+50);
109 try test__floatundisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);144 try test_f32_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCBAp+50);
110 try test__floatundisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);145 try test_f32_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
111 try test__floatundisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);146 try test_f32_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCBAp+50);
112 try test__floatundisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);147 try test_f32_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB8p+50);
113 try test__floatundisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);148}
114 try test__floatundisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);149
115 try test__floatundisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);150fn test_f32_floatFromInt_i128(a: i128, expected: f32) !void {
116 try test__floatundisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);151 const x = f32_floatFromInt_i128(a);
117}
118
119fn test__floattisf(a: i128, expected: f32) !void {
120 const x = __floattisf(a);
121 try testing.expect(x == expected);152 try testing.expect(x == expected);
122}153}
123154
124fn test__floatuntisf(a: u128, expected: f32) !void {155fn test_f32_floatFromInt_u128(a: u128, expected: f32) !void {
125 const x = __floatuntisf(a);156 const x = f32_floatFromInt_u128(a);
126 try testing.expect(x == expected);157 try testing.expect(x == expected);
127}158}
128159
129test "floattisf" {160test f32_floatFromInt_i128 {
130 try test__floattisf(0, 0.0);161 try test_f32_floatFromInt_i128(0, 0.0);
131162
132 try test__floattisf(1, 1.0);163 try test_f32_floatFromInt_i128(1, 1.0);
133 try test__floattisf(2, 2.0);164 try test_f32_floatFromInt_i128(2, 2.0);
134 try test__floattisf(-1, -1.0);165 try test_f32_floatFromInt_i128(-1, -1.0);
135 try test__floattisf(-2, -2.0);166 try test_f32_floatFromInt_i128(-2, -2.0);
136167
137 try test__floattisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);168 try test_f32_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
138 try test__floattisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);169 try test_f32_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
139170
140 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62);171 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62);
141 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62);172 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62);
142173
143 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63);174 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63);
144 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63);175 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63);
145176
146 try test__floattisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);177 try test_f32_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
147178
148 try test__floattisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);179 try test_f32_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBAp+50);
149 try test__floattisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);180 try test_f32_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBAp+50);
150 try test__floattisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);181 try test_f32_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
151 try test__floattisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);182 try test_f32_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBCp+50);
152 try test__floattisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);183 try test_f32_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBAp+50);
153184
154 try test__floattisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);185 try test_f32_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCBAp+50);
155 try test__floattisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);186 try test_f32_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCBAp+50);
156 try test__floattisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);187 try test_f32_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
157 try test__floattisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);188 try test_f32_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCBAp+50);
158 try test__floattisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);189 try test_f32_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB8p+50);
159190
160 try test__floattisf(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114);191 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114);
161192
162 try test__floattisf(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114);193 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114);
163 try test__floattisf(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114);194 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114);
164 try test__floattisf(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114);195 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114);
165 try test__floattisf(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114);196 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114);
166 try test__floattisf(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114);197 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114);
167198
168 try test__floattisf(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114);199 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114);
169 try test__floattisf(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114);200 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114);
170 try test__floattisf(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114);201 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114);
171 try test__floattisf(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114);202 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114);
172 try test__floattisf(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114);203 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114);
173}204}
174205
175test "floatuntisf" {206test f32_floatFromInt_u128 {
176 try test__floatuntisf(0, 0.0);207 try test_f32_floatFromInt_u128(0, 0.0);
177208
178 try test__floatuntisf(1, 1.0);209 try test_f32_floatFromInt_u128(1, 1.0);
179 try test__floatuntisf(2, 2.0);210 try test_f32_floatFromInt_u128(2, 2.0);
180 try test__floatuntisf(20, 20.0);211 try test_f32_floatFromInt_u128(20, 20.0);
181212
182 try test__floatuntisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);213 try test_f32_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
183 try test__floatuntisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);214 try test_f32_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
184215
185 try test__floatuntisf(make_uti(0x8000008000000000, 0), 0x1.000001p+127);216 try test_f32_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127);
186 try test__floatuntisf(make_uti(0x8000000000000800, 0), 0x1.0p+127);217 try test_f32_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0p+127);
187 try test__floatuntisf(make_uti(0x8000010000000000, 0), 0x1.000002p+127);218 try test_f32_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127);
188219
189 try test__floatuntisf(make_uti(0x8000000000000000, 0), 0x1.000000p+127);220 try test_f32_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127);
190221
191 try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);222 try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
192223
193 try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);224 try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
194 try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBACp+50);225 try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
195226
196 try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBBp+50);227 try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
197228
198 try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCB98p+50);229 try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
199 try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);230 try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
200 try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB9p+50);231 try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
201232
202 try test__floatuntisf(0xFFFFFFFFFFFFFFFE, 0x1p+64);233 try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0x1p+64);
203 try test__floatuntisf(0xFFFFFFFFFFFFFFFF, 0x1p+64);234 try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0x1p+64);
204235
205 try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);236 try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
206237
207 try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);238 try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBAp+50);
208 try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);239 try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBAp+50);
209 try test__floatuntisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);240 try test_f32_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
210 try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);241 try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBCp+50);
211 try test__floatuntisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);242 try test_f32_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBAp+50);
212243
213 try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);244 try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCBAp+50);
214 try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);245 try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCBAp+50);
215 try test__floatuntisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);246 try test_f32_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
216 try test__floatuntisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);247 try test_f32_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCBAp+50);
217 try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);248 try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB8p+50);
218249
219 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76);250 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76);
220 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76);251 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76);
221 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76);252 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76);
222 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76);253 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76);
223 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76);254 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76);
224 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76);255 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76);
225 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76);256 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76);
226 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76);257 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76);
227 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76);258 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76);
228 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76);259 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76);
229 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76);260 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76);
230 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76);261 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76);
231262
232 // Test overflow to infinity263 // Test overflow to infinity
233 try test__floatuntisf(math.maxInt(u128), @bitCast(math.inf(f32)));264 try test_f32_floatFromInt_u128(math.maxInt(u128), @bitCast(math.inf(f32)));
234}265}
235266
236fn test_floateisf(expected: u32, comptime T: type, a: T) !void {267fn test_f32_floatFromInt(expected: u32, comptime T: type, a: T) !void {
237 const int = @typeInfo(T).int;268 const int = @typeInfo(T).int;
238 const r = switch (int.signedness) {269 const r = switch (int.signedness) {
239 .signed => __floateisf,270 .signed => f32_floatFromInt_signed,
240 .unsigned => __floatuneisf,271 .unsigned => f32_floatFromInt_unsigned,
241 }(@ptrCast(&a), int.bits);272 }(@ptrCast(&a));
242 try testing.expect(expected == @as(u32, @bitCast(r)));273 try testing.expect(expected == @as(u32, @bitCast(r)));
243}274}
244275
245test "floateisf" {276test f32_floatFromInt_signed {
246 try test_floateisf(0xFF000000, i256, -1 << 127);277 try test_f32_floatFromInt(0xFF000000, i256, -1 << 127);
247 try test_floateisf(0xFF000000, i256, -math.maxInt(u127));278 try test_f32_floatFromInt(0xFF000000, i256, -math.maxInt(u127));
248 try test_floateisf(0xDF012347, i256, -0x8123468100000000);279 try test_f32_floatFromInt(0xDF012347, i256, -0x8123468100000000);
249 try test_floateisf(0xDF012347, i256, -0x8123468000000001);280 try test_f32_floatFromInt(0xDF012347, i256, -0x8123468000000001);
250 try test_floateisf(0xDF012346, i256, -0x8123468000000000);281 try test_f32_floatFromInt(0xDF012346, i256, -0x8123468000000000);
251 try test_floateisf(0xDF012346, i256, -0x8123458100000000);282 try test_f32_floatFromInt(0xDF012346, i256, -0x8123458100000000);
252 try test_floateisf(0xDF012346, i256, -0x8123458000000001);283 try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000001);
253 try test_floateisf(0xDF012346, i256, -0x8123458000000000);284 try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000000);
254 try test_floateisf(0xDF012345, i256, -0x8123456789ABCDEF);285 try test_f32_floatFromInt(0xDF012345, i256, -0x8123456789ABCDEF);
255 try test_floateisf(0xBF800000, i256, -1);286 try test_f32_floatFromInt(0xBF800000, i256, -1);
256 try test_floateisf(0x00000000, i256, 0);287 try test_f32_floatFromInt(0x00000000, i256, 0);
257 try test_floateisf(0x5F012345, i256, 0x8123456789ABCDEF);288 try test_f32_floatFromInt(0x5F012345, i256, 0x8123456789ABCDEF);
258 try test_floateisf(0x5F012346, i256, 0x8123458000000000);289 try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000000);
259 try test_floateisf(0x5F012346, i256, 0x8123458000000001);290 try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000001);
260 try test_floateisf(0x5F012346, i256, 0x8123458100000000);291 try test_f32_floatFromInt(0x5F012346, i256, 0x8123458100000000);
261 try test_floateisf(0x5F012346, i256, 0x8123468000000000);292 try test_f32_floatFromInt(0x5F012346, i256, 0x8123468000000000);
262 try test_floateisf(0x5F012347, i256, 0x8123468000000001);293 try test_f32_floatFromInt(0x5F012347, i256, 0x8123468000000001);
263 try test_floateisf(0x5F012347, i256, 0x8123468100000000);294 try test_f32_floatFromInt(0x5F012347, i256, 0x8123468100000000);
264 try test_floateisf(0x7F000000, i256, math.maxInt(u127));295 try test_f32_floatFromInt(0x7F000000, i256, math.maxInt(u127));
265 try test_floateisf(0x7F000000, i256, 1 << 127);296 try test_f32_floatFromInt(0x7F000000, i256, 1 << 127);
266}297}
267298
268test "floatuneisf" {299test f32_floatFromInt_unsigned {
269 try test_floateisf(0x00000000, u256, 0);300 try test_f32_floatFromInt(0x00000000, u256, 0);
270 try test_floateisf(0x5F012345, u256, 0x8123456789ABCDEF);301 try test_f32_floatFromInt(0x5F012345, u256, 0x8123456789ABCDEF);
271 try test_floateisf(0x5F012346, u256, 0x8123458000000000);302 try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000000);
272 try test_floateisf(0x5F012346, u256, 0x8123458000000001);303 try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000001);
273 try test_floateisf(0x5F012346, u256, 0x8123458080000000);304 try test_f32_floatFromInt(0x5F012346, u256, 0x8123458080000000);
274 try test_floateisf(0x5F012346, u256, 0x8123468000000000);305 try test_f32_floatFromInt(0x5F012346, u256, 0x8123468000000000);
275 try test_floateisf(0x5F012347, u256, 0x8123468000000001);306 try test_f32_floatFromInt(0x5F012347, u256, 0x8123468000000001);
276 try test_floateisf(0x5F012347, u256, 0x8123468080000000);307 try test_f32_floatFromInt(0x5F012347, u256, 0x8123468080000000);
277 try test_floateisf(0x7F000000, u256, math.maxInt(u127));308 try test_f32_floatFromInt(0x7F000000, u256, math.maxInt(u127));
278 try test_floateisf(0x7F000000, u256, 1 << 127);309 try test_f32_floatFromInt(0x7F000000, u256, 1 << 127);
279 try test_floateisf(0x7F800000, u256, math.maxInt(u256));310 try test_f32_floatFromInt(0x7F800000, u256, math.maxInt(u256));
280}311}
281312
282fn test_one_floatsidf(a: i32, expected: u64) !void {313fn test_f64_floatFromInt_i32(a: i32, expected: u64) !void {
283 const r = __floatsidf(a);314 const r = f64_floatFromInt_i32(a);
284 try std.testing.expect(@as(u64, @bitCast(r)) == expected);315 try std.testing.expect(@as(u64, @bitCast(r)) == expected);
285}316}
286317
287fn test_one_floatunsidf(a: u32, expected: u64) !void {318fn test_f64_floatFromInt_u32(a: u32, expected: u64) !void {
288 const r = __floatunsidf(a);319 const r = f64_floatFromInt_u32(a);
289 try std.testing.expect(@as(u64, @bitCast(r)) == expected);320 try std.testing.expect(@as(u64, @bitCast(r)) == expected);
290}321}
291322
292test "floatsidf" {323test f64_floatFromInt_i32 {
293 try test_one_floatsidf(0, 0x0000000000000000);324 try test_f64_floatFromInt_i32(0, 0x0000000000000000);
294 try test_one_floatsidf(1, 0x3ff0000000000000);325 try test_f64_floatFromInt_i32(1, 0x3ff0000000000000);
295 try test_one_floatsidf(-1, 0xbff0000000000000);326 try test_f64_floatFromInt_i32(-1, 0xbff0000000000000);
296 try test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000);327 try test_f64_floatFromInt_i32(0x7FFFFFFF, 0x41dfffffffc00000);
297 try test_one_floatsidf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000);328 try test_f64_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000);
298}329}
299330
300test "floatunsidf" {331test f64_floatFromInt_u32 {
301 try test_one_floatunsidf(0, 0x0000000000000000);332 try test_f64_floatFromInt_u32(0, 0x0000000000000000);
302 try test_one_floatunsidf(1, 0x3ff0000000000000);333 try test_f64_floatFromInt_u32(1, 0x3ff0000000000000);
303 try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000);334 try test_f64_floatFromInt_u32(0x7FFFFFFF, 0x41dfffffffc00000);
304 try test_one_floatunsidf(@intCast(0x80000000), 0x41e0000000000000);335 try test_f64_floatFromInt_u32(@intCast(0x80000000), 0x41e0000000000000);
305 try test_one_floatunsidf(@intCast(0xFFFFFFFF), 0x41efffffffe00000);336 try test_f64_floatFromInt_u32(@intCast(0xFFFFFFFF), 0x41efffffffe00000);
306}337}
307338
308fn test__floatdidf(a: i64, expected: f64) !void {339fn test_f64_floatFromInt_i64(a: i64, expected: f64) !void {
309 const r = __floatdidf(a);340 const r = f64_floatFromInt_i64(a);
310 try testing.expect(r == expected);341 try testing.expect(r == expected);
311}342}
312343
313fn test__floatundidf(a: u64, expected: f64) !void {344fn test_f64_floatFromInt_u64(a: u64, expected: f64) !void {
314 const r = __floatundidf(a);345 const r = f64_floatFromInt_u64(a);
315 try testing.expect(r == expected);346 try testing.expect(r == expected);
316}347}
317348
318test "floatdidf" {349test f64_floatFromInt_i64 {
319 try test__floatdidf(0, 0.0);350 try test_f64_floatFromInt_i64(0, 0.0);
320 try test__floatdidf(1, 1.0);351 try test_f64_floatFromInt_i64(1, 1.0);
321 try test__floatdidf(2, 2.0);352 try test_f64_floatFromInt_i64(2, 2.0);
322 try test__floatdidf(20, 20.0);353 try test_f64_floatFromInt_i64(20, 20.0);
323 try test__floatdidf(-1, -1.0);354 try test_f64_floatFromInt_i64(-1, -1.0);
324 try test__floatdidf(-2, -2.0);355 try test_f64_floatFromInt_i64(-2, -2.0);
325 try test__floatdidf(-20, -20.0);356 try test_f64_floatFromInt_i64(-20, -20.0);
326 try test__floatdidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);357 try test_f64_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
327 try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);358 try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
328 try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);359 try test_f64_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
329 try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);360 try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
330 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62);361 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62);
331 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62);362 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62);
332 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62);363 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62);
333 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62);364 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62);
334 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63);365 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63);
335 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001366 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001
336 try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);367 try test_f64_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
337 try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);368 try test_f64_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
338 try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);369 try test_f64_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBACp+50);
339 try test__floatdidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);370 try test_f64_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
340 try test__floatdidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);371 try test_f64_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBBp+50);
341 try test__floatdidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);372 try test_f64_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
342 try test__floatdidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);373 try test_f64_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCB98p+50);
343 try test__floatdidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);374 try test_f64_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
344 try test__floatdidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);375 try test_f64_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
345 try test__floatdidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);376 try test_f64_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
346 try test__floatdidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);377 try test_f64_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB9p+50);
347 try test__floatdidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);378 try test_f64_floatFromInt_i64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
348 try test__floatdidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);379 try test_f64_floatFromInt_i64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
349 try test__floatdidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);380 try test_f64_floatFromInt_i64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
350 try test__floatdidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);381 try test_f64_floatFromInt_i64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
351 try test__floatdidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);382 try test_f64_floatFromInt_i64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
352 try test__floatdidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);383 try test_f64_floatFromInt_i64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
353 try test__floatdidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);384 try test_f64_floatFromInt_i64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
354 try test__floatdidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);385 try test_f64_floatFromInt_i64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
355 try test__floatdidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);386 try test_f64_floatFromInt_i64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
356 try test__floatdidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);387 try test_f64_floatFromInt_i64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
357 try test__floatdidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);388 try test_f64_floatFromInt_i64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
358 try test__floatdidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);389 try test_f64_floatFromInt_i64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
359 try test__floatdidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);390 try test_f64_floatFromInt_i64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
360 try test__floatdidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);391 try test_f64_floatFromInt_i64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
361 try test__floatdidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);392 try test_f64_floatFromInt_i64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
362}393}
363394
364test "floatundidf" {395test f64_floatFromInt_u64 {
365 try test__floatundidf(0, 0.0);396 try test_f64_floatFromInt_u64(0, 0.0);
366 try test__floatundidf(1, 1.0);397 try test_f64_floatFromInt_u64(1, 1.0);
367 try test__floatundidf(2, 2.0);398 try test_f64_floatFromInt_u64(2, 2.0);
368 try test__floatundidf(20, 20.0);399 try test_f64_floatFromInt_u64(20, 20.0);
369 try test__floatundidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);400 try test_f64_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
370 try test__floatundidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);401 try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
371 try test__floatundidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);402 try test_f64_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
372 try test__floatundidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);403 try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
373 try test__floatundidf(0x8000008000000000, 0x1.000001p+63);404 try test_f64_floatFromInt_u64(0x8000008000000000, 0x1.000001p+63);
374 try test__floatundidf(0x8000000000000800, 0x1.0000000000001p+63);405 try test_f64_floatFromInt_u64(0x8000000000000800, 0x1.0000000000001p+63);
375 try test__floatundidf(0x8000010000000000, 0x1.000002p+63);406 try test_f64_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63);
376 try test__floatundidf(0x8000000000001000, 0x1.0000000000002p+63);407 try test_f64_floatFromInt_u64(0x8000000000001000, 0x1.0000000000002p+63);
377 try test__floatundidf(0x8000000000000000, 0x1p+63);408 try test_f64_floatFromInt_u64(0x8000000000000000, 0x1p+63);
378 try test__floatundidf(0x8000000000000001, 0x1p+63);409 try test_f64_floatFromInt_u64(0x8000000000000001, 0x1p+63);
379 try test__floatundidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);410 try test_f64_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
380 try test__floatundidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);411 try test_f64_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
381 try test__floatundidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);412 try test_f64_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBACp+50);
382 try test__floatundidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);413 try test_f64_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
383 try test__floatundidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);414 try test_f64_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBBp+50);
384 try test__floatundidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);415 try test_f64_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
385 try test__floatundidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);416 try test_f64_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCB98p+50);
386 try test__floatundidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);417 try test_f64_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
387 try test__floatundidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);418 try test_f64_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
388 try test__floatundidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);419 try test_f64_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
389 try test__floatundidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);420 try test_f64_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB9p+50);
390 try test__floatundidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);421 try test_f64_floatFromInt_u64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
391 try test__floatundidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);422 try test_f64_floatFromInt_u64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
392 try test__floatundidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);423 try test_f64_floatFromInt_u64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
393 try test__floatundidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);424 try test_f64_floatFromInt_u64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
394 try test__floatundidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);425 try test_f64_floatFromInt_u64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
395 try test__floatundidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);426 try test_f64_floatFromInt_u64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
396 try test__floatundidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);427 try test_f64_floatFromInt_u64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
397 try test__floatundidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);428 try test_f64_floatFromInt_u64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
398 try test__floatundidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);429 try test_f64_floatFromInt_u64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
399 try test__floatundidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);430 try test_f64_floatFromInt_u64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
400 try test__floatundidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);431 try test_f64_floatFromInt_u64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
401 try test__floatundidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);432 try test_f64_floatFromInt_u64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
402 try test__floatundidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);433 try test_f64_floatFromInt_u64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
403 try test__floatundidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);434 try test_f64_floatFromInt_u64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
404 try test__floatundidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);435 try test_f64_floatFromInt_u64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
405}436}
406437
407fn test__floattidf(a: i128, expected: f64) !void {438fn test_f64_floatFromInt_i128(a: i128, expected: f64) !void {
408 const x = __floattidf(a);439 const x = f64_floatFromInt_i128(a);
409 try testing.expect(x == expected);440 try testing.expect(x == expected);
410}441}
411442
412fn test__floatuntidf(a: u128, expected: f64) !void {443fn test_f64_floatFromInt_u128(a: u128, expected: f64) !void {
413 const x = __floatuntidf(a);444 const x = f64_floatFromInt_u128(a);
414 try testing.expect(x == expected);445 try testing.expect(x == expected);
415}446}
416447
417test "floattidf" {448test f64_floatFromInt_i128 {
418 try test__floattidf(0, 0.0);449 try test_f64_floatFromInt_i128(0, 0.0);
419450
420 try test__floattidf(1, 1.0);451 try test_f64_floatFromInt_i128(1, 1.0);
421 try test__floattidf(2, 2.0);452 try test_f64_floatFromInt_i128(2, 2.0);
422 try test__floattidf(20, 20.0);453 try test_f64_floatFromInt_i128(20, 20.0);
423 try test__floattidf(-1, -1.0);454 try test_f64_floatFromInt_i128(-1, -1.0);
424 try test__floattidf(-2, -2.0);455 try test_f64_floatFromInt_i128(-2, -2.0);
425 try test__floattidf(-20, -20.0);456 try test_f64_floatFromInt_i128(-20, -20.0);
426457
427 try test__floattidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);458 try test_f64_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
428 try test__floattidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);459 try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
429 try test__floattidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);460 try test_f64_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
430 try test__floattidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);461 try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
431462
432 try test__floattidf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);463 try test_f64_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);
433 try test__floattidf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);464 try test_f64_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);
434 try test__floattidf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);465 try test_f64_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);
435 try test__floattidf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);466 try test_f64_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);
436467
437 try test__floattidf(make_ti(0x8000000000000000, 0), -0x1.000000p+127);468 try test_f64_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127);
438 try test__floattidf(make_ti(0x8000000000000001, 0), -0x1.000000p+127);469 try test_f64_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.000000p+127);
439470
440 try test__floattidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);471 try test_f64_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
441472
442 try test__floattidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);473 try test_f64_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
443 try test__floattidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);474 try test_f64_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
444 try test__floattidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);475 try test_f64_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
445 try test__floattidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);476 try test_f64_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
446 try test__floattidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);477 try test_f64_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
447478
448 try test__floattidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);479 try test_f64_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
449 try test__floattidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);480 try test_f64_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
450 try test__floattidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);481 try test_f64_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
451 try test__floattidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);482 try test_f64_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
452 try test__floattidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);483 try test_f64_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
453484
454 try test__floattidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);485 try test_f64_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
455 try test__floattidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);486 try test_f64_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
456 try test__floattidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);487 try test_f64_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
457 try test__floattidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);488 try test_f64_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
458 try test__floattidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);489 try test_f64_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
459 try test__floattidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);490 try test_f64_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
460 try test__floattidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);491 try test_f64_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
461 try test__floattidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);492 try test_f64_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
462 try test__floattidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);493 try test_f64_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
463 try test__floattidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);494 try test_f64_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
464 try test__floattidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);495 try test_f64_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
465 try test__floattidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);496 try test_f64_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
466 try test__floattidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);497 try test_f64_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
467 try test__floattidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);498 try test_f64_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
468 try test__floattidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);499 try test_f64_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
469500
470 try test__floattidf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);501 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
471 try test__floattidf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);502 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);
472 try test__floattidf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);503 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);
473 try test__floattidf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);504 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);
474 try test__floattidf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);505 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);
475 try test__floattidf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);506 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);
476 try test__floattidf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);507 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);
477 try test__floattidf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);508 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);
478 try test__floattidf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);509 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);
479 try test__floattidf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);510 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);
480 try test__floattidf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);511 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);
481 try test__floattidf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);512 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);
482 try test__floattidf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);513 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);
483 try test__floattidf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);514 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);
484 try test__floattidf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);515 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
485}516}
486517
487test "floatuntidf" {518test f64_floatFromInt_u128 {
488 try test__floatuntidf(0, 0.0);519 try test_f64_floatFromInt_u128(0, 0.0);
489520
490 try test__floatuntidf(1, 1.0);521 try test_f64_floatFromInt_u128(1, 1.0);
491 try test__floatuntidf(2, 2.0);522 try test_f64_floatFromInt_u128(2, 2.0);
492 try test__floatuntidf(20, 20.0);523 try test_f64_floatFromInt_u128(20, 20.0);
493524
494 try test__floatuntidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);525 try test_f64_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
495 try test__floatuntidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);526 try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
496 try test__floatuntidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);527 try test_f64_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
497 try test__floatuntidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);528 try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
498529
499 try test__floatuntidf(make_uti(0x8000008000000000, 0), 0x1.000001p+127);530 try test_f64_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127);
500 try test__floatuntidf(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127);531 try test_f64_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127);
501 try test__floatuntidf(make_uti(0x8000010000000000, 0), 0x1.000002p+127);532 try test_f64_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127);
502 try test__floatuntidf(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127);533 try test_f64_floatFromInt_u128(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127);
503534
504 try test__floatuntidf(make_uti(0x8000000000000000, 0), 0x1.000000p+127);535 try test_f64_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127);
505 try test__floatuntidf(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127);536 try test_f64_floatFromInt_u128(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127);
506537
507 try test__floatuntidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);538 try test_f64_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
508539
509 try test__floatuntidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);540 try test_f64_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
510 try test__floatuntidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);541 try test_f64_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
511 try test__floatuntidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);542 try test_f64_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
512 try test__floatuntidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);543 try test_f64_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
513 try test__floatuntidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);544 try test_f64_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
514545
515 try test__floatuntidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);546 try test_f64_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
516 try test__floatuntidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);547 try test_f64_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
517 try test__floatuntidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);548 try test_f64_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
518 try test__floatuntidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);549 try test_f64_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
519 try test__floatuntidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);550 try test_f64_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
520551
521 try test__floatuntidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);552 try test_f64_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
522 try test__floatuntidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);553 try test_f64_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
523 try test__floatuntidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);554 try test_f64_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
524 try test__floatuntidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);555 try test_f64_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
525 try test__floatuntidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);556 try test_f64_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
526 try test__floatuntidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);557 try test_f64_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
527 try test__floatuntidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);558 try test_f64_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
528 try test__floatuntidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);559 try test_f64_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
529 try test__floatuntidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);560 try test_f64_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
530 try test__floatuntidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);561 try test_f64_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
531 try test__floatuntidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);562 try test_f64_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
532 try test__floatuntidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);563 try test_f64_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
533 try test__floatuntidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);564 try test_f64_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
534 try test__floatuntidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);565 try test_f64_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
535 try test__floatuntidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);566 try test_f64_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
536567
537 try test__floatuntidf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);568 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
538 try test__floatuntidf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);569 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);
539 try test__floatuntidf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);570 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);
540 try test__floatuntidf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);571 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);
541 try test__floatuntidf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);572 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);
542 try test__floatuntidf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);573 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);
543 try test__floatuntidf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);574 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);
544 try test__floatuntidf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);575 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);
545 try test__floatuntidf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);576 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);
546 try test__floatuntidf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);577 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);
547 try test__floatuntidf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);578 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);
548 try test__floatuntidf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);579 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);
549 try test__floatuntidf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);580 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);
550 try test__floatuntidf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);581 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);
551 try test__floatuntidf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);582 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
552}583}
553584
554fn test__floatsitf(a: i32, expected: u128) !void {585fn test_f128_floatFromInt_i32(a: i32, expected: u128) !void {
555 const r = __floatsitf(a);586 const r = f128_floatFromInt_i32(a);
556 try std.testing.expect(@as(u128, @bitCast(r)) == expected);587 try std.testing.expect(@as(u128, @bitCast(r)) == expected);
557}588}
558589
559test "floatsitf" {590fn test_f128_floatFromInt_u32(a: u32, expected_hi: u64, expected_lo: u64) !void {
560 try test__floatsitf(0, 0);591 const x = f128_floatFromInt_u32(a);
561 try test__floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000);
562 try test__floatsitf(0x12345678, 0x401b2345678000000000000000000000);
563 try test__floatsitf(-0x12345678, 0xc01b2345678000000000000000000000);
564 try test__floatsitf(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000);
565 try test__floatsitf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000);
566}
567
568fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {
569 const x = __floatunsitf(a);
570592
571 const x_repr: u128 = @bitCast(x);593 const x_repr: u128 = @bitCast(x);
572 const x_hi: u64 = @intCast(x_repr >> 64);594 const x_hi: u64 = @intCast(x_repr >> 64);
...@@ -581,24 +603,32 @@ fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {...@@ -581,24 +603,32 @@ fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {
581 return;603 return;
582 }604 }
583 }605 }
606 return error.TestFailure;
607}
584608
585 @panic("__floatunsitf test failure");609test f128_floatFromInt_i32 {
610 try test_f128_floatFromInt_i32(0, 0);
611 try test_f128_floatFromInt_i32(0x7FFFFFFF, 0x401dfffffffc00000000000000000000);
612 try test_f128_floatFromInt_i32(0x12345678, 0x401b2345678000000000000000000000);
613 try test_f128_floatFromInt_i32(-0x12345678, 0xc01b2345678000000000000000000000);
614 try test_f128_floatFromInt_i32(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000);
615 try test_f128_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000);
586}616}
587617
588test "floatunsitf" {618test f128_floatFromInt_u32 {
589 try test__floatunsitf(0x7fffffff, 0x401dfffffffc0000, 0x0);619 try test_f128_floatFromInt_u32(0x7fffffff, 0x401dfffffffc0000, 0x0);
590 try test__floatunsitf(0, 0x0, 0x0);620 try test_f128_floatFromInt_u32(0, 0x0, 0x0);
591 try test__floatunsitf(0xffffffff, 0x401efffffffe0000, 0x0);621 try test_f128_floatFromInt_u32(0xffffffff, 0x401efffffffe0000, 0x0);
592 try test__floatunsitf(0x12345678, 0x401b234567800000, 0x0);622 try test_f128_floatFromInt_u32(0x12345678, 0x401b234567800000, 0x0);
593}623}
594624
595fn test__floatditf(a: i64, expected: f128) !void {625fn test_f128_floatFromInt_i64(a: i64, expected: f128) !void {
596 const x = __floatditf(a);626 const x = f128_floatFromInt_i64(a);
597 try testing.expect(x == expected);627 try testing.expect(x == expected);
598}628}
599629
600fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void {630fn test_f128_floatFromInt_u64(a: u64, expected_hi: u64, expected_lo: u64) !void {
601 const x = __floatunditf(a);631 const x = f128_floatFromInt_u64(a);
602632
603 const x_repr: u128 = @bitCast(x);633 const x_repr: u128 = @bitCast(x);
604 const x_hi: u64 = @intCast(x_repr >> 64);634 const x_hi: u64 = @intCast(x_repr >> 64);
...@@ -613,208 +643,207 @@ fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void {...@@ -613,208 +643,207 @@ fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void {
613 return;643 return;
614 }644 }
615 }645 }
616646 return error.TestFailure;
617 @panic("__floatunditf test failure");647}
618}648
619649test f128_floatFromInt_i64 {
620test "floatditf" {650 try test_f128_floatFromInt_i64(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000));
621 try test__floatditf(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000));651 try test_f128_floatFromInt_i64(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000));
622 try test__floatditf(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000));652 try test_f128_floatFromInt_i64(0x2, make_tf(0x4000000000000000, 0x0));
623 try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0));653 try test_f128_floatFromInt_i64(0x1, make_tf(0x3fff000000000000, 0x0));
624 try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0));654 try test_f128_floatFromInt_i64(0x0, make_tf(0x0, 0x0));
625 try test__floatditf(0x0, make_tf(0x0, 0x0));655 try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0));
626 try test__floatditf(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0));656 try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0));
627 try test__floatditf(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0));657 try test_f128_floatFromInt_i64(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000));
628 try test__floatditf(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000));658 try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0));
629 try test__floatditf(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0));659}
630}660
631661test f128_floatFromInt_u64 {
632test "floatunditf" {662 try test_f128_floatFromInt_u64(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000);
633 try test__floatunditf(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000);663 try test_f128_floatFromInt_u64(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000);
634 try test__floatunditf(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000);664 try test_f128_floatFromInt_u64(0x8000000000000000, 0x403e000000000000, 0x0);
635 try test__floatunditf(0x8000000000000000, 0x403e000000000000, 0x0);665 try test_f128_floatFromInt_u64(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000);
636 try test__floatunditf(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000);666 try test_f128_floatFromInt_u64(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000);
637 try test__floatunditf(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000);667 try test_f128_floatFromInt_u64(0x2, 0x4000000000000000, 0x0);
638 try test__floatunditf(0x2, 0x4000000000000000, 0x0);668 try test_f128_floatFromInt_u64(0x1, 0x3fff000000000000, 0x0);
639 try test__floatunditf(0x1, 0x3fff000000000000, 0x0);669 try test_f128_floatFromInt_u64(0x0, 0x0, 0x0);
640 try test__floatunditf(0x0, 0x0, 0x0);670}
641}671
642672fn test_f128_floatFromInt_i128(a: i128, expected: f128) !void {
643fn test__floattitf(a: i128, expected: f128) !void {673 const x = f128_floatFromInt_i128(a);
644 const x = __floattitf(a);
645 try testing.expect(x == expected);674 try testing.expect(x == expected);
646}675}
647676
648fn test__floatuntitf(a: u128, expected: f128) !void {677fn test_f128_floatFromInt_u128(a: u128, expected: f128) !void {
649 const x = __floatuntitf(a);678 const x = f128_floatFromInt_u128(a);
650 try testing.expect(x == expected);679 try testing.expect(x == expected);
651}680}
652681
653test "floattitf" {682test f128_floatFromInt_i128 {
654 try test__floattitf(0, 0.0);683 try test_f128_floatFromInt_i128(0, 0.0);
655684
656 try test__floattitf(1, 1.0);685 try test_f128_floatFromInt_i128(1, 1.0);
657 try test__floattitf(2, 2.0);686 try test_f128_floatFromInt_i128(2, 2.0);
658 try test__floattitf(20, 20.0);687 try test_f128_floatFromInt_i128(20, 20.0);
659 try test__floattitf(-1, -1.0);688 try test_f128_floatFromInt_i128(-1, -1.0);
660 try test__floattitf(-2, -2.0);689 try test_f128_floatFromInt_i128(-2, -2.0);
661 try test__floattitf(-20, -20.0);690 try test_f128_floatFromInt_i128(-20, -20.0);
662691
663 try test__floattitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);692 try test_f128_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
664 try test__floattitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);693 try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
665 try test__floattitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);694 try test_f128_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
666 try test__floattitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);695 try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
667696
668 try test__floattitf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);697 try test_f128_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);
669 try test__floattitf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);698 try test_f128_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);
670 try test__floattitf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);699 try test_f128_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);
671 try test__floattitf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);700 try test_f128_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);
672701
673 try test__floattitf(make_ti(0x8000000000000000, 0), -0x1.000000p+127);702 try test_f128_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127);
674 try test__floattitf(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126);703 try test_f128_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126);
675704
676 try test__floattitf(0x0007FB72E8000000, 0x1.FEDCBAp+50);705 try test_f128_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
677706
678 try test__floattitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);707 try test_f128_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
679 try test__floattitf(0x0007FB72EB000000, 0x1.FEDCBACp+50);708 try test_f128_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
680 try test__floattitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);709 try test_f128_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
681 try test__floattitf(0x0007FB72EC000000, 0x1.FEDCBBp+50);710 try test_f128_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
682 try test__floattitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);711 try test_f128_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
683712
684 try test__floattitf(0x0007FB72E6000000, 0x1.FEDCB98p+50);713 try test_f128_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
685 try test__floattitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);714 try test_f128_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
686 try test__floattitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);715 try test_f128_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
687 try test__floattitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);716 try test_f128_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
688 try test__floattitf(0x0007FB72E4000000, 0x1.FEDCB9p+50);717 try test_f128_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
689718
690 try test__floattitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);719 try test_f128_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
691 try test__floattitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);720 try test_f128_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);
692 try test__floattitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);721 try test_f128_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);
693 try test__floattitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);722 try test_f128_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);
694 try test__floattitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);723 try test_f128_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);
695 try test__floattitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);724 try test_f128_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);
696 try test__floattitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);725 try test_f128_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);
697 try test__floattitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);726 try test_f128_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);
698 try test__floattitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);727 try test_f128_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);
699 try test__floattitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);728 try test_f128_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);
700 try test__floattitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);729 try test_f128_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);
701 try test__floattitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);730 try test_f128_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);
702 try test__floattitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);731 try test_f128_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);
703 try test__floattitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);732 try test_f128_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);
704 try test__floattitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);733 try test_f128_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
705734
706 try test__floattitf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);735 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
707 try test__floattitf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);736 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);
708 try test__floattitf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);737 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);
709 try test__floattitf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);738 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);
710 try test__floattitf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);739 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);
711 try test__floattitf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);740 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);
712 try test__floattitf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);741 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);
713 try test__floattitf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);742 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);
714 try test__floattitf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);743 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);
715 try test__floattitf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);744 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);
716 try test__floattitf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);745 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);
717 try test__floattitf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);746 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);
718 try test__floattitf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);747 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);
719 try test__floattitf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);748 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);
720 try test__floattitf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);749 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
721750
722 try test__floattitf(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);751 try test_f128_floatFromInt_i128(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);
723752
724 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);753 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);
725 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);754 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);
726 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);755 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);
727 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);756 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);
728 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);757 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);
729 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);758 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);
730 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);759 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);
731 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);760 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);
732 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);761 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);
733}762}
734763
735test "floatuntitf" {764test f128_floatFromInt_u128 {
736 try test__floatuntitf(0, 0.0);765 try test_f128_floatFromInt_u128(0, 0.0);
737766
738 try test__floatuntitf(1, 1.0);767 try test_f128_floatFromInt_u128(1, 1.0);
739 try test__floatuntitf(2, 2.0);768 try test_f128_floatFromInt_u128(2, 2.0);
740 try test__floatuntitf(20, 20.0);769 try test_f128_floatFromInt_u128(20, 20.0);
741770
742 try test__floatuntitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);771 try test_f128_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
743 try test__floatuntitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);772 try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
744 try test__floatuntitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);773 try test_f128_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
745 try test__floatuntitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);774 try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
746 try test__floatuntitf(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59);775 try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59);
747 try test__floatuntitf(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60);776 try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60);
748 try test__floatuntitf(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60);777 try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60);
749778
750 try test__floatuntitf(0x8000008000000000, 0x8.000008p+60);779 try test_f128_floatFromInt_u128(0x8000008000000000, 0x8.000008p+60);
751 try test__floatuntitf(0x8000000000000800, 0x8.0000000000008p+60);780 try test_f128_floatFromInt_u128(0x8000000000000800, 0x8.0000000000008p+60);
752 try test__floatuntitf(0x8000010000000000, 0x8.00001p+60);781 try test_f128_floatFromInt_u128(0x8000010000000000, 0x8.00001p+60);
753 try test__floatuntitf(0x8000000000001000, 0x8.000000000001p+60);782 try test_f128_floatFromInt_u128(0x8000000000001000, 0x8.000000000001p+60);
754783
755 try test__floatuntitf(0x8000000000000000, 0x8p+60);784 try test_f128_floatFromInt_u128(0x8000000000000000, 0x8p+60);
756 try test__floatuntitf(0x8000000000000001, 0x8.000000000000001p+60);785 try test_f128_floatFromInt_u128(0x8000000000000001, 0x8.000000000000001p+60);
757786
758 try test__floatuntitf(0x0007FB72E8000000, 0x1.FEDCBAp+50);787 try test_f128_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
759788
760 try test__floatuntitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);789 try test_f128_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
761 try test__floatuntitf(0x0007FB72EB000000, 0x1.FEDCBACp+50);790 try test_f128_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
762 try test__floatuntitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);791 try test_f128_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
763 try test__floatuntitf(0x0007FB72EC000000, 0x1.FEDCBBp+50);792 try test_f128_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
764 try test__floatuntitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);793 try test_f128_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
765794
766 try test__floatuntitf(0x0007FB72E6000000, 0x1.FEDCB98p+50);795 try test_f128_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
767 try test__floatuntitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);796 try test_f128_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
768 try test__floatuntitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);797 try test_f128_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
769 try test__floatuntitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);798 try test_f128_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
770 try test__floatuntitf(0x0007FB72E4000000, 0x1.FEDCB9p+50);799 try test_f128_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
771800
772 try test__floatuntitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);801 try test_f128_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
773 try test__floatuntitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);802 try test_f128_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);
774 try test__floatuntitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);803 try test_f128_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);
775 try test__floatuntitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);804 try test_f128_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);
776 try test__floatuntitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);805 try test_f128_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);
777 try test__floatuntitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);806 try test_f128_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);
778 try test__floatuntitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);807 try test_f128_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);
779 try test__floatuntitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);808 try test_f128_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);
780 try test__floatuntitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);809 try test_f128_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);
781 try test__floatuntitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);810 try test_f128_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);
782 try test__floatuntitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);811 try test_f128_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);
783 try test__floatuntitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);812 try test_f128_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);
784 try test__floatuntitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);813 try test_f128_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);
785 try test__floatuntitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);814 try test_f128_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);
786 try test__floatuntitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);815 try test_f128_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
787816
788 try test__floatuntitf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);817 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
789 try test__floatuntitf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);818 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);
790 try test__floatuntitf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);819 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);
791 try test__floatuntitf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);820 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);
792 try test__floatuntitf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);821 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);
793 try test__floatuntitf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);822 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);
794 try test__floatuntitf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);823 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);
795 try test__floatuntitf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);824 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);
796 try test__floatuntitf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);825 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);
797 try test__floatuntitf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);826 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);
798 try test__floatuntitf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);827 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);
799 try test__floatuntitf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);828 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);
800 try test__floatuntitf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);829 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);
801 try test__floatuntitf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);830 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);
802 try test__floatuntitf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);831 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
803832
804 try test__floatuntitf(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);833 try test_f128_floatFromInt_u128(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);
805834
806 try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127);835 try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127);
807 try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128);836 try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128);
808837
809 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);838 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);
810 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);839 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);
811 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);840 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);
812 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);841 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);
813 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);842 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);
814 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);843 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);
815 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);844 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);
816 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);845 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);
817 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);846 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);
818}847}
819848
820fn make_ti(high: u64, low: u64) i128 {849fn make_ti(high: u64, low: u64) i128 {
...@@ -838,45 +867,40 @@ fn make_tf(high: u64, low: u64) f128 {...@@ -838,45 +867,40 @@ fn make_tf(high: u64, low: u64) f128 {
838 return @bitCast(result);867 return @bitCast(result);
839}868}
840869
841test "conversion to f16" {870test f16_floatFromInt_u32 {
842 try testing.expect(__floatunsihf(@as(u32, 0)) == 0.0);871 try testing.expect(f16_floatFromInt_u32(0) == 0.0);
843 try testing.expect(__floatunsihf(@as(u32, 1)) == 1.0);872 try testing.expect(f16_floatFromInt_u32(1) == 1.0);
844 try testing.expect(__floatunsihf(@as(u32, 65504)) == 65504);873 try testing.expect(f16_floatFromInt_u32(65504) == 65504);
845 try testing.expect(__floatunsihf(@as(u32, 65504 + (1 << 4))) == math.inf(f16));874 try testing.expect(f16_floatFromInt_u32(65504 + (1 << 4)) == math.inf(f16));
846}875}
847876
848test "conversion to f32" {877test f80_floatFromInt_u32 {
849 try testing.expect(__floatunsisf(@as(u32, 0)) == 0.0);878 try testing.expect(f80_floatFromInt_u32(0) == 0.0);
850 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u32))) != 1.0);879 try testing.expect(f80_floatFromInt_u32(1) == 1.0);
851 try testing.expect(__floatsisf(@as(i32, math.minInt(i32))) != 1.0);880 try testing.expect(f80_floatFromInt_u32(math.maxInt(u24) + 0) == math.maxInt(u24));
852 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24))) == math.maxInt(u24));881}
853 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact882
854 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even883test f80_floatFromInt_u64 {
855 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact884 try testing.expect(f80_floatFromInt_u64(math.maxInt(u64) + 0) == math.maxInt(u64) + 0);
856 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even885}
857 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact886
858}887test f80_floatFromInt_i128 {
859888 try testing.expect(f80_floatFromInt_i128(-12) == -12);
860test "conversion to f80" {889}
861 const floatFromInt = @import("./float_from_int.zig").floatFromInt;890
862891test f80_floatFromInt_u128 {
863 try testing.expect(floatFromInt(f80, @as(i80, -12)) == -12);892 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1);
864 try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u64, math.maxInt(u64)) + 0))) == math.maxInt(u64) + 0);893
865 try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1);894 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 0) == math.maxInt(u64));
866895 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1); // Exact
867 try testing.expect(floatFromInt(f80, @as(u32, 0)) == 0.0);896 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 2) == math.maxInt(u64) + 1); // Rounds down
868 try testing.expect(floatFromInt(f80, @as(u32, 1)) == 1.0);897 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 3) == math.maxInt(u64) + 3); // Tie - Exact
869 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u32, math.maxInt(u24)) + 0))) == math.maxInt(u24));898 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 4) == math.maxInt(u64) + 5); // Rounds up
870 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 0))) == math.maxInt(u64));899
871 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); // Exact900 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 0) == math.maxInt(u65) + 1); // Rounds up
872 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 2))) == math.maxInt(u64) + 1); // Rounds down901 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 1) == math.maxInt(u65) + 1); // Exact
873 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 3))) == math.maxInt(u64) + 3); // Tie - Exact902 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 2) == math.maxInt(u65) + 1); // Rounds down
874 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 4))) == math.maxInt(u64) + 5); // Rounds up903 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 3) == math.maxInt(u65) + 1); // Tie - Rounds down
875904 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 4) == math.maxInt(u65) + 5); // Rounds up
876 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 0))) == math.maxInt(u65) + 1); // Rounds up905 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 5) == math.maxInt(u65) + 5); // Exact
877 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 1))) == math.maxInt(u65) + 1); // Exact
878 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 2))) == math.maxInt(u65) + 1); // Rounds down
879 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 3))) == math.maxInt(u65) + 1); // Tie - Rounds down
880 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 4))) == math.maxInt(u65) + 5); // Rounds up
881 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 5))) == math.maxInt(u65) + 5); // Exact
882}906}
lib/compiler_rt/floatdidf.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 if (compiler_rt.want_aeabi) {
8 symbol(&__aeabi_l2d, "__aeabi_l2d");
9 } else {
10 if (compiler_rt.want_windows_arm_abi) {
11 symbol(&__floatdidf, "__i64tod");
12 }
13 symbol(&__floatdidf, "__floatdidf");
14 }
15}
16
17pub fn __floatdidf(a: i64) callconv(.c) f64 {
18 return floatFromInt(f64, a);
19}
20
21fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 {
22 return floatFromInt(f64, a);
23}
lib/compiler_rt/floatdihf.zig deleted-10
...@@ -1,10 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3
4comptime {
5 symbol(&__floatdihf, "__floatdihf");
6}
7
8fn __floatdihf(a: i64) callconv(.c) f16 {
9 return floatFromInt(f16, a);
10}
lib/compiler_rt/floatdisf.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_l2f, "__aeabi_l2f");
8 } else {
9 if (compiler_rt.want_windows_arm_abi) {
10 symbol(&__floatdisf, "__i64tos");
11 }
12 symbol(&__floatdisf, "__floatdisf");
13 }
14}
15
16pub fn __floatdisf(a: i64) callconv(.c) f32 {
17 return floatFromInt(f32, a);
18}
19
20fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 {
21 return floatFromInt(f32, a);
22}
lib/compiler_rt/floatditf.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__floatditf, "__floatdikf");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_xtoq, "_Qp_xtoq");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__floatditf, "_Q_lltoq");
12 }
13 symbol(&__floatditf, "__floatditf");
14}
15
16pub fn __floatditf(a: i64) callconv(.c) f128 {
17 return floatFromInt(f128, a);
18}
19
20fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void {
21 c.* = floatFromInt(f128, a);
22}
lib/compiler_rt/floatdixf.zig deleted-10
...@@ -1,10 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3
4comptime {
5 symbol(&__floatdixf, "__floatdixf");
6}
7
8fn __floatdixf(a: i64) callconv(.c) f80 {
9 return floatFromInt(f80, a);
10}
lib/compiler_rt/floateidf.zig deleted-15
...@@ -1,15 +0,0 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6const symbol = @import("../compiler_rt.zig").symbol;
7
8comptime {
9 symbol(&__floateidf, "__floateidf");
10}
11
12pub fn __floateidf(a: [*]const u8, bits: usize) callconv(.c) f64 {
13 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
14 return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a[0..byte_size])));
15}
lib/compiler_rt/floateihf.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floateihf, "__floateihf");
9}
10
11pub fn __floateihf(a: [*]const u8, bits: usize) callconv(.c) f16 {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a[0..byte_size])));
14}
lib/compiler_rt/floateisf.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floateisf, "__floateisf");
9}
10
11pub fn __floateisf(a: [*]const u8, bits: usize) callconv(.c) f32 {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a[0..byte_size])));
14}
lib/compiler_rt/floateitf.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floateitf, "__floateitf");
9}
10
11pub fn __floateitf(a: [*]const u8, bits: usize) callconv(.c) f128 {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a[0..byte_size])));
14}
lib/compiler_rt/floateixf.zig deleted-15
...@@ -1,15 +0,0 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
7
8comptime {
9 symbol(&__floateixf, "__floateixf");
10}
11
12pub fn __floateixf(a: [*]const u8, bits: usize) callconv(.c) f80 {
13 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
14 return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a[0..byte_size])));
15}
lib/compiler_rt/floatsidf.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_i2d, "__aeabi_i2d");
8 } else {
9 symbol(&__floatsidf, "__floatsidf");
10 }
11}
12
13pub fn __floatsidf(a: i32) callconv(.c) f64 {
14 return floatFromInt(f64, a);
15}
16
17fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 {
18 return floatFromInt(f64, a);
19}
lib/compiler_rt/floatsihf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatsihf, "__floatsihf");
7}
8
9fn __floatsihf(a: i32) callconv(.c) f16 {
10 return floatFromInt(f16, a);
11}
lib/compiler_rt/floatsisf.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_i2f, "__aeabi_i2f");
8 } else {
9 symbol(&__floatsisf, "__floatsisf");
10 }
11}
12
13pub fn __floatsisf(a: i32) callconv(.c) f32 {
14 return floatFromInt(f32, a);
15}
16
17fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 {
18 return floatFromInt(f32, a);
19}
lib/compiler_rt/floatsitf.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__floatsitf, "__floatsikf");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_itoq, "_Qp_itoq");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__floatsitf, "_Q_itoq");
12 }
13 symbol(&__floatsitf, "__floatsitf");
14}
15
16pub fn __floatsitf(a: i32) callconv(.c) f128 {
17 return floatFromInt(f128, a);
18}
19
20fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void {
21 c.* = floatFromInt(f128, a);
22}
lib/compiler_rt/floatsixf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__floatsixf, "__floatsixf");
7}
8
9fn __floatsixf(a: i32) callconv(.c) f80 {
10 return floatFromInt(f80, a);
11}
lib/compiler_rt/floattidf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floattidf, "__floattidf");
7}
8
9pub fn __floattidf(a: i128) callconv(.c) f64 {
10 return floatFromInt(f64, a);
11}
lib/compiler_rt/floattihf.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 symbol(&__floattihf, "__floattihf");
8}
9
10pub fn __floattihf(a: i128) callconv(.c) f16 {
11 return floatFromInt(f16, a);
12}
lib/compiler_rt/floattisf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__floattisf, "__floattisf");
7}
8
9pub fn __floattisf(a: i128) callconv(.c) f32 {
10 return floatFromInt(f32, a);
11}
lib/compiler_rt/floattitf.zig deleted-13
...@@ -1,13 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_ppc_abi)
7 symbol(&__floattitf, "__floattikf");
8 symbol(&__floattitf, "__floattitf");
9}
10
11pub fn __floattitf(a: i128) callconv(.c) f128 {
12 return floatFromInt(f128, a);
13}
lib/compiler_rt/floattixf.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 symbol(&__floattixf, "__floattixf");
8}
9
10pub fn __floattixf(a: i128) callconv(.c) f80 {
11 return floatFromInt(f80, a);
12}
lib/compiler_rt/floatundidf.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_ul2d, "__aeabi_ul2d");
8 } else {
9 if (compiler_rt.want_windows_arm_abi) {
10 symbol(&__floatundidf, "__u64tod");
11 }
12 symbol(&__floatundidf, "__floatundidf");
13 }
14}
15
16pub fn __floatundidf(a: u64) callconv(.c) f64 {
17 return floatFromInt(f64, a);
18}
19
20fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 {
21 return floatFromInt(f64, a);
22}
lib/compiler_rt/floatundihf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatundihf, "__floatundihf");
7}
8
9fn __floatundihf(a: u64) callconv(.c) f16 {
10 return floatFromInt(f16, a);
11}
lib/compiler_rt/floatundisf.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 if (compiler_rt.want_aeabi) {
8 symbol(&__aeabi_ul2f, "__aeabi_ul2f");
9 } else {
10 if (compiler_rt.want_windows_arm_abi) {
11 symbol(&__floatundisf, "__u64tos");
12 }
13 symbol(&__floatundisf, "__floatundisf");
14 }
15}
16
17pub fn __floatundisf(a: u64) callconv(.c) f32 {
18 return floatFromInt(f32, a);
19}
20
21fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 {
22 return floatFromInt(f32, a);
23}
lib/compiler_rt/floatunditf.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__floatunditf, "__floatundikf");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_uxtoq, "_Qp_uxtoq");
10 } else if (compiler_rt.want_sparc32_abi) {
11 @export(&__floatunditf, "_Q_ulltoq");
12 }
13 symbol(&__floatunditf, "__floatunditf");
14}
15
16pub fn __floatunditf(a: u64) callconv(.c) f128 {
17 return floatFromInt(f128, a);
18}
19
20fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void {
21 c.* = floatFromInt(f128, a);
22}
lib/compiler_rt/floatundixf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatundixf, "__floatundixf");
7}
8
9fn __floatundixf(a: u64) callconv(.c) f80 {
10 return floatFromInt(f80, a);
11}
lib/compiler_rt/floatuneidf.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floatuneidf, "__floatuneidf");
9}
10
11pub fn __floatuneidf(a: [*]const u8, bits: usize) callconv(.c) f64 {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a[0..byte_size])));
14}
lib/compiler_rt/floatuneihf.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floatuneihf, "__floatuneihf");
9}
10
11pub fn __floatuneihf(a: [*]const u8, bits: usize) callconv(.c) f16 {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a[0..byte_size])));
14}
lib/compiler_rt/floatuneisf.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floatuneisf, "__floatuneisf");
9}
10
11pub fn __floatuneisf(a: [*]const u8, bits: usize) callconv(.c) f32 {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a[0..byte_size])));
14}
lib/compiler_rt/floatuneitf.zig deleted-15
...@@ -1,15 +0,0 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
7
8comptime {
9 symbol(&__floatuneitf, "__floatuneitf");
10}
11
12pub fn __floatuneitf(a: [*]const u8, bits: usize) callconv(.c) f128 {
13 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
14 return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a[0..byte_size])));
15}
lib/compiler_rt/floatuneixf.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floatuneixf, "__floatuneixf");
9}
10
11pub fn __floatuneixf(a: [*]const u8, bits: usize) callconv(.c) f80 {
12 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
13 return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a[0..byte_size])));
14}
lib/compiler_rt/floatunsidf.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_ui2d, "__aeabi_ui2d");
8 } else {
9 symbol(&__floatunsidf, "__floatunsidf");
10 }
11}
12
13pub fn __floatunsidf(a: u32) callconv(.c) f64 {
14 return floatFromInt(f64, a);
15}
16
17fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 {
18 return floatFromInt(f64, a);
19}
lib/compiler_rt/floatunsihf.zig deleted-10
...@@ -1,10 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3
4comptime {
5 symbol(&__floatunsihf, "__floatunsihf");
6}
7
8pub fn __floatunsihf(a: u32) callconv(.c) f16 {
9 return floatFromInt(f16, a);
10}
lib/compiler_rt/floatunsisf.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_ui2f, "__aeabi_ui2f");
8 } else {
9 symbol(&__floatunsisf, "__floatunsisf");
10 }
11}
12
13pub fn __floatunsisf(a: u32) callconv(.c) f32 {
14 return floatFromInt(f32, a);
15}
16
17fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 {
18 return floatFromInt(f32, a);
19}
lib/compiler_rt/floatunsitf.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__floatunsitf, "__floatunsikf");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_uitoq, "_Qp_uitoq");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__floatunsitf, "_Q_utoq");
12 }
13 symbol(&__floatunsitf, "__floatunsitf");
14}
15
16pub fn __floatunsitf(a: u32) callconv(.c) f128 {
17 return floatFromInt(f128, a);
18}
19
20fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void {
21 c.* = floatFromInt(f128, a);
22}
lib/compiler_rt/floatunsixf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatunsixf, "__floatunsixf");
7}
8
9fn __floatunsixf(a: u32) callconv(.c) f80 {
10 return floatFromInt(f80, a);
11}
lib/compiler_rt/floatuntidf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__floatuntidf, "__floatuntidf");
7}
8
9pub fn __floatuntidf(a: u128) callconv(.c) f64 {
10 return floatFromInt(f64, a);
11}
lib/compiler_rt/floatuntihf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatuntihf, "__floatuntihf");
7}
8
9pub fn __floatuntihf(a: u128) callconv(.c) f16 {
10 return floatFromInt(f16, a);
11}
lib/compiler_rt/floatuntisf.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 symbol(&__floatuntisf, "__floatuntisf");
8}
9
10pub fn __floatuntisf(a: u128) callconv(.c) f32 {
11 return floatFromInt(f32, a);
12}
lib/compiler_rt/floatuntitf.zig deleted-13
...@@ -1,13 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_ppc_abi)
7 symbol(&__floatuntitf, "__floatuntikf");
8 symbol(&__floatuntitf, "__floatuntitf");
9}
10
11pub fn __floatuntitf(a: u128) callconv(.c) f128 {
12 return floatFromInt(f128, a);
13}
lib/compiler_rt/floatuntixf.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 symbol(&__floatuntixf, "__floatuntixf");
8}
9
10pub fn __floatuntixf(a: u128) callconv(.c) f80 {
11 return floatFromInt(f80, a);
12}
lib/compiler_rt/floor_ceil.zig+173-159
...@@ -15,7 +15,7 @@ const mem = std.mem;...@@ -15,7 +15,7 @@ const mem = std.mem;
15const expect = std.testing.expect;15const expect = std.testing.expect;
1616
17const compiler_rt = @import("../compiler_rt.zig");17const compiler_rt = @import("../compiler_rt.zig");
18const symbol = @import("../compiler_rt.zig").symbol;18const symbol = compiler_rt.symbol;
1919
20comptime {20comptime {
21 // floor21 // floor
...@@ -23,10 +23,7 @@ comptime {...@@ -23,10 +23,7 @@ comptime {
23 symbol(&floorf, "floorf");23 symbol(&floorf, "floorf");
24 symbol(&floor, "floor");24 symbol(&floor, "floor");
25 symbol(&__floorx, "__floorx");25 symbol(&__floorx, "__floorx");
26 if (compiler_rt.want_ppc_abi) {26 symbol(&floorq, "floorf128");
27 symbol(&floorq, "floorf128");
28 }
29 symbol(&floorq, "floorq");
30 symbol(&floorl, "floorl");27 symbol(&floorl, "floorl");
3128
32 // ceil29 // ceil
...@@ -34,59 +31,96 @@ comptime {...@@ -34,59 +31,96 @@ comptime {
34 symbol(&ceilf, "ceilf");31 symbol(&ceilf, "ceilf");
35 symbol(&ceil, "ceil");32 symbol(&ceil, "ceil");
36 symbol(&__ceilx, "__ceilx");33 symbol(&__ceilx, "__ceilx");
37 if (compiler_rt.want_ppc_abi) {34 symbol(&ceilq, "ceilf128");
38 symbol(&ceilq, "ceilf128");
39 }
40 symbol(&ceilq, "ceilq");
41 symbol(&ceill, "ceill");35 symbol(&ceill, "ceill");
42}36}
4337
44pub fn __floorh(x: f16) callconv(.c) f16 {38fn __floorh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
39 return compiler_rt.f16.toAbi(floor_f16(compiler_rt.f16.fromAbi(x)));
40}
41pub fn floor_f16(x: f16) f16 {
45 return impl(f16, .floor, x);42 return impl(f16, .floor, x);
46}43}
4744
48pub fn floorf(x: f32) callconv(.c) f32 {45fn floorf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
46 return compiler_rt.f32.toAbi(floor_f32(compiler_rt.f32.fromAbi(x)));
47}
48pub fn floor_f32(x: f32) f32 {
49 return impl(f32, .floor, x);49 return impl(f32, .floor, x);
50}50}
5151
52pub fn floor(x: f64) callconv(.c) f64 {52fn floor(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
53 return compiler_rt.f64.toAbi(floor_f64(compiler_rt.f64.fromAbi(x)));
54}
55pub fn floor_f64(x: f64) f64 {
53 return impl(f64, .floor, x);56 return impl(f64, .floor, x);
54}57}
5558
56pub fn __floorx(x: f80) callconv(.c) f80 {59fn __floorx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
60 return compiler_rt.f80.toAbi(floor_f80(compiler_rt.f80.fromAbi(x)));
61}
62pub fn floor_f80(x: f80) f80 {
57 return impl(f80, .floor, x);63 return impl(f80, .floor, x);
58}64}
5965
60pub fn floorq(x: f128) callconv(.c) f128 {66fn floorq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
67 return compiler_rt.f128.toAbi(floor_f128(compiler_rt.f128.fromAbi(x)));
68}
69pub fn floor_f128(x: f128) f128 {
61 return impl(f128, .floor, x);70 return impl(f128, .floor, x);
62}71}
6372
64pub fn floorl(x: c_longdouble) callconv(.c) c_longdouble {73pub fn floorl(x: c_longdouble) callconv(.c) c_longdouble {
65 return impl(std.meta.Float(@bitSizeOf(c_longdouble)), .floor, x);74 switch (@typeInfo(c_longdouble).float.bits) {
75 64 => return floor_f64(x),
76 80 => return floor_f80(x),
77 128 => return floor_f128(x),
78 else => comptime unreachable,
79 }
66}80}
6781
68pub fn __ceilh(x: f16) callconv(.c) f16 {82fn __ceilh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
83 return compiler_rt.f16.toAbi(ceil_f16(compiler_rt.f16.fromAbi(x)));
84}
85pub fn ceil_f16(x: f16) f16 {
69 return impl(f16, .ceil, x);86 return impl(f16, .ceil, x);
70}87}
7188
72pub fn ceilf(x: f32) callconv(.c) f32 {89fn ceilf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
90 return compiler_rt.f32.toAbi(ceil_f32(compiler_rt.f32.fromAbi(x)));
91}
92pub fn ceil_f32(x: f32) f32 {
73 return impl(f32, .ceil, x);93 return impl(f32, .ceil, x);
74}94}
7595
76pub fn ceil(x: f64) callconv(.c) f64 {96fn ceil(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
97 return compiler_rt.f64.toAbi(ceil_f64(compiler_rt.f64.fromAbi(x)));
98}
99pub fn ceil_f64(x: f64) f64 {
77 return impl(f64, .ceil, x);100 return impl(f64, .ceil, x);
78}101}
79102
80pub fn __ceilx(x: f80) callconv(.c) f80 {103fn __ceilx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
104 return compiler_rt.f80.toAbi(ceil_f80(compiler_rt.f80.fromAbi(x)));
105}
106pub fn ceil_f80(x: f80) f80 {
81 return impl(f80, .ceil, x);107 return impl(f80, .ceil, x);
82}108}
83109
84pub fn ceilq(x: f128) callconv(.c) f128 {110fn ceilq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
111 return compiler_rt.f128.toAbi(ceil_f128(compiler_rt.f128.fromAbi(x)));
112}
113pub fn ceil_f128(x: f128) f128 {
85 return impl(f128, .ceil, x);114 return impl(f128, .ceil, x);
86}115}
87116
88pub fn ceill(x: c_longdouble) callconv(.c) c_longdouble {117pub fn ceill(x: c_longdouble) callconv(.c) c_longdouble {
89 return impl(std.meta.Float(@bitSizeOf(c_longdouble)), .ceil, x);118 switch (@typeInfo(c_longdouble).float.bits) {
119 64 => return ceil_f64(x),
120 80 => return ceil_f80(x),
121 128 => return ceil_f128(x),
122 else => comptime unreachable,
123 }
90}124}
91125
92inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T {126inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T {
...@@ -144,142 +178,122 @@ inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T {...@@ -144,142 +178,122 @@ inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T {
144 }178 }
145}179}
146180
147test "floor16" {181test floor_f16 {
148 try expect(__floorh(1.3) == 1.0);182 try expect(floor_f16(1.3) == 1.0);
149 try expect(__floorh(-1.3) == -2.0);183 try expect(floor_f16(-1.3) == -2.0);
150 try expect(__floorh(0.2) == 0.0);184 try expect(floor_f16(-0.2) == -1.0);
151}185 try expect(math.isPositiveZero(floor_f16(0.2)));
152186 try expect(math.isPositiveZero(floor_f16(0.0)));
153test "floor32" {187 try expect(math.isNegativeZero(floor_f16(-0.0)));
154 try expect(floorf(1.3) == 1.0);188 try expect(math.isPositiveInf(floor_f16(math.inf(f16))));
155 try expect(floorf(-1.3) == -2.0);189 try expect(math.isNegativeInf(floor_f16(-math.inf(f16))));
156 try expect(floorf(0.2) == 0.0);190 try expect(math.isNan(floor_f16(math.nan(f16))));
157}191}
158192
159test "floor64" {193test floor_f32 {
160 try expect(floor(1.3) == 1.0);194 try expect(floor_f32(1.3) == 1.0);
161 try expect(floor(-1.3) == -2.0);195 try expect(floor_f32(-1.3) == -2.0);
162 try expect(floor(0.2) == 0.0);196 try expect(floor_f32(-0.2) == -1.0);
163}197 try expect(math.isPositiveZero(floor_f32(0.2)));
164198 try expect(math.isPositiveZero(floor_f32(0.0)));
165test "floor80" {199 try expect(math.isNegativeZero(floor_f32(-0.0)));
166 try expect(__floorx(1.3) == 1.0);200 try expect(math.isPositiveInf(floor_f32(math.inf(f32))));
167 try expect(__floorx(-1.3) == -2.0);201 try expect(math.isNegativeInf(floor_f32(-math.inf(f32))));
168 try expect(__floorx(0.2) == 0.0);202 try expect(math.isNan(floor_f32(math.nan(f32))));
169}203}
170204
171test "floor128" {205test floor_f64 {
172 try expect(floorq(1.3) == 1.0);206 try expect(floor_f64(1.3) == 1.0);
173 try expect(floorq(-1.3) == -2.0);207 try expect(floor_f64(-1.3) == -2.0);
174 try expect(floorq(0.2) == 0.0);208 try expect(floor_f64(-0.2) == -1.0);
175}209 try expect(math.isPositiveZero(floor_f64(0.2)));
176210 try expect(math.isPositiveZero(floor_f64(0.0)));
177test "floor16.special" {211 try expect(math.isNegativeZero(floor_f64(-0.0)));
178 try expect(__floorh(0.0) == 0.0);212 try expect(math.isPositiveInf(floor_f64(math.inf(f64))));
179 try expect(__floorh(-0.0) == -0.0);213 try expect(math.isNegativeInf(floor_f64(-math.inf(f64))));
180 try expect(math.isPositiveInf(__floorh(math.inf(f16))));214 try expect(math.isNan(floor_f64(math.nan(f64))));
181 try expect(math.isNegativeInf(__floorh(-math.inf(f16))));215}
182 try expect(math.isNan(__floorh(math.nan(f16))));216
183}217test floor_f80 {
184218 try expect(floor_f80(1.3) == 1.0);
185test "floor32.special" {219 try expect(floor_f80(-1.3) == -2.0);
186 try expect(floorf(0.0) == 0.0);220 try expect(floor_f80(-0.2) == -1.0);
187 try expect(floorf(-0.0) == -0.0);221 try expect(math.isPositiveZero(floor_f80(0.2)));
188 try expect(math.isPositiveInf(floorf(math.inf(f32))));222 try expect(math.isPositiveZero(floor_f80(0.0)));
189 try expect(math.isNegativeInf(floorf(-math.inf(f32))));223 try expect(math.isNegativeZero(floor_f80(-0.0)));
190 try expect(math.isNan(floorf(math.nan(f32))));224 try expect(math.isPositiveInf(floor_f80(math.inf(f80))));
191}225 try expect(math.isNegativeInf(floor_f80(-math.inf(f80))));
192226 try expect(math.isNan(floor_f80(math.nan(f80))));
193test "floor64.special" {227}
194 try expect(floor(0.0) == 0.0);228
195 try expect(floor(-0.0) == -0.0);229test floor_f128 {
196 try expect(math.isPositiveInf(floor(math.inf(f64))));230 try expect(floor_f128(1.3) == 1.0);
197 try expect(math.isNegativeInf(floor(-math.inf(f64))));231 try expect(floor_f128(-1.3) == -2.0);
198 try expect(math.isNan(floor(math.nan(f64))));232 try expect(floor_f128(-0.2) == -1.0);
199}233 try expect(math.isPositiveZero(floor_f128(0.2)));
200234 try expect(math.isPositiveZero(floor_f128(0.0)));
201test "floor80.special" {235 try expect(math.isNegativeZero(floor_f128(-0.0)));
202 try expect(__floorx(0.0) == 0.0);236 try expect(math.isPositiveInf(floor_f128(math.inf(f128))));
203 try expect(__floorx(-0.0) == -0.0);237 try expect(math.isNegativeInf(floor_f128(-math.inf(f128))));
204 try expect(math.isPositiveInf(__floorx(math.inf(f80))));238 try expect(math.isNan(floor_f128(math.nan(f128))));
205 try expect(math.isNegativeInf(__floorx(-math.inf(f80))));239}
206 try expect(math.isNan(__floorx(math.nan(f80))));240
207}241test ceil_f16 {
208242 try expect(ceil_f16(1.3) == 2.0);
209test "floor128.special" {243 try expect(ceil_f16(-1.3) == -1.0);
210 try expect(floorq(0.0) == 0.0);244 try expect(ceil_f16(0.2) == 1.0);
211 try expect(floorq(-0.0) == -0.0);245 try expect(math.isNegativeZero(ceil_f16(-0.2)));
212 try expect(math.isPositiveInf(floorq(math.inf(f128))));246 try expect(math.isPositiveZero(ceil_f16(0.0)));
213 try expect(math.isNegativeInf(floorq(-math.inf(f128))));247 try expect(math.isNegativeZero(ceil_f16(-0.0)));
214 try expect(math.isNan(floorq(math.nan(f128))));248 try expect(math.isPositiveInf(ceil_f16(math.inf(f16))));
215}249 try expect(math.isNegativeInf(ceil_f16(-math.inf(f16))));
216250 try expect(math.isNan(ceil_f16(math.nan(f16))));
217test "ceil16" {251}
218 try expect(__ceilh(1.3) == 2.0);252
219 try expect(__ceilh(-1.3) == -1.0);253test ceil_f32 {
220 try expect(__ceilh(0.2) == 1.0);254 try expect(ceil_f32(1.3) == 2.0);
221}255 try expect(ceil_f32(-1.3) == -1.0);
222256 try expect(ceil_f32(0.2) == 1.0);
223test "ceil32" {257 try expect(math.isNegativeZero(ceil_f32(-0.2)));
224 try expect(ceilf(1.3) == 2.0);258 try expect(math.isPositiveZero(ceil_f32(0.0)));
225 try expect(ceilf(-1.3) == -1.0);259 try expect(math.isNegativeZero(ceil_f32(-0.0)));
226 try expect(ceilf(0.2) == 1.0);260 try expect(math.isPositiveInf(ceil_f32(math.inf(f32))));
227}261 try expect(math.isNegativeInf(ceil_f32(-math.inf(f32))));
228262 try expect(math.isNan(ceil_f32(math.nan(f32))));
229test "ceil64" {263}
230 try expect(ceil(1.3) == 2.0);264
231 try expect(ceil(-1.3) == -1.0);265test ceil_f64 {
232 try expect(ceil(0.2) == 1.0);266 try expect(ceil_f64(1.3) == 2.0);
233}267 try expect(ceil_f64(-1.3) == -1.0);
234268 try expect(ceil_f64(0.2) == 1.0);
235test "ceil80" {269 try expect(math.isNegativeZero(ceil_f64(-0.2)));
236 try expect(__ceilx(1.3) == 2.0);270 try expect(math.isPositiveZero(ceil_f64(0.0)));
237 try expect(__ceilx(-1.3) == -1.0);271 try expect(math.isNegativeZero(ceil_f64(-0.0)));
238 try expect(__ceilx(0.2) == 1.0);272 try expect(math.isPositiveInf(ceil_f64(math.inf(f64))));
239}273 try expect(math.isNegativeInf(ceil_f64(-math.inf(f64))));
240274 try expect(math.isNan(ceil_f64(math.nan(f64))));
241test "ceil128" {275}
242 try expect(ceilq(1.3) == 2.0);276
243 try expect(ceilq(-1.3) == -1.0);277test ceil_f80 {
244 try expect(ceilq(0.2) == 1.0);278 try expect(ceil_f80(1.3) == 2.0);
245}279 try expect(ceil_f80(-1.3) == -1.0);
246280 try expect(ceil_f80(0.2) == 1.0);
247test "ceil16.special" {281 try expect(math.isNegativeZero(ceil_f80(-0.2)));
248 try expect(__ceilh(0.0) == 0.0);282 try expect(math.isPositiveZero(ceil_f80(0.0)));
249 try expect(__ceilh(-0.0) == -0.0);283 try expect(math.isNegativeZero(ceil_f80(-0.0)));
250 try expect(math.isPositiveInf(__ceilh(math.inf(f16))));284 try expect(math.isPositiveInf(ceil_f80(math.inf(f80))));
251 try expect(math.isNegativeInf(__ceilh(-math.inf(f16))));285 try expect(math.isNegativeInf(ceil_f80(-math.inf(f80))));
252 try expect(math.isNan(__ceilh(math.nan(f16))));286 try expect(math.isNan(ceil_f80(math.nan(f80))));
253}287}
254288
255test "ceil32.special" {289test ceil_f128 {
256 try expect(ceilf(0.0) == 0.0);290 try expect(ceil_f128(1.3) == 2.0);
257 try expect(ceilf(-0.0) == -0.0);291 try expect(ceil_f128(-1.3) == -1.0);
258 try expect(math.isPositiveInf(ceilf(math.inf(f32))));292 try expect(ceil_f128(0.2) == 1.0);
259 try expect(math.isNegativeInf(ceilf(-math.inf(f32))));293 try expect(math.isNegativeZero(ceil_f128(-0.2)));
260 try expect(math.isNan(ceilf(math.nan(f32))));294 try expect(math.isPositiveZero(ceil_f128(0.0)));
261}295 try expect(math.isNegativeZero(ceil_f128(-0.0)));
262296 try expect(math.isPositiveInf(ceil_f128(math.inf(f128))));
263test "ceil64.special" {297 try expect(math.isNegativeInf(ceil_f128(-math.inf(f128))));
264 try expect(ceil(0.0) == 0.0);298 try expect(math.isNan(ceil_f128(math.nan(f128))));
265 try expect(ceil(-0.0) == -0.0);
266 try expect(math.isPositiveInf(ceil(math.inf(f64))));
267 try expect(math.isNegativeInf(ceil(-math.inf(f64))));
268 try expect(math.isNan(ceil(math.nan(f64))));
269}
270
271test "ceil80.special" {
272 try expect(__ceilx(0.0) == 0.0);
273 try expect(__ceilx(-0.0) == -0.0);
274 try expect(math.isPositiveInf(__ceilx(math.inf(f80))));
275 try expect(math.isNegativeInf(__ceilx(-math.inf(f80))));
276 try expect(math.isNan(__ceilx(math.nan(f80))));
277}
278
279test "ceil128.special" {
280 try expect(ceilq(0.0) == 0.0);
281 try expect(ceilq(-0.0) == -0.0);
282 try expect(math.isPositiveInf(ceilq(math.inf(f128))));
283 try expect(math.isNegativeInf(ceilq(-math.inf(f128))));
284 try expect(math.isNan(ceilq(math.nan(f128))));
285}299}
lib/compiler_rt/fma.zig+48-36
...@@ -16,19 +16,22 @@ comptime {...@@ -16,19 +16,22 @@ comptime {
16 symbol(&fmaf, "fmaf");16 symbol(&fmaf, "fmaf");
17 symbol(&fma, "fma");17 symbol(&fma, "fma");
18 symbol(&__fmax, "__fmax");18 symbol(&__fmax, "__fmax");
19 if (compiler_rt.want_ppc_abi) {19 symbol(&fmaq, "fmaf128");
20 symbol(&fmaq, "fmaf128");
21 }
22 symbol(&fmaq, "fmaq");
23 symbol(&fmal, "fmal");20 symbol(&fmal, "fmal");
24}21}
2522
26pub fn __fmah(x: f16, y: f16, z: f16) callconv(.c) f16 {23fn __fmah(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi, z: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
24 return compiler_rt.f16.toAbi(fma_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y), compiler_rt.f16.fromAbi(z)));
25}
26pub fn fma_f16(x: f16, y: f16, z: f16) f16 {
27 // TODO: more efficient implementation27 // TODO: more efficient implementation
28 return @floatCast(fmaf(x, y, z));28 return @floatCast(fma_f32(x, y, z));
29}29}
3030
31pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 {31fn fmaf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi, z: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
32 return compiler_rt.f32.toAbi(fma_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y), compiler_rt.f32.fromAbi(z)));
33}
34pub fn fma_f32(x: f32, y: f32, z: f32) f32 {
32 const xy = @as(f64, x) * y;35 const xy = @as(f64, x) * y;
33 const xy_z = xy + z;36 const xy_z = xy + z;
34 const u = @as(u64, @bitCast(xy_z));37 const u = @as(u64, @bitCast(xy_z));
...@@ -42,8 +45,11 @@ pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 {...@@ -42,8 +45,11 @@ pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 {
42 }45 }
43}46}
4447
48fn fma(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi, z: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
49 return compiler_rt.f64.toAbi(fma_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y), compiler_rt.f64.fromAbi(z)));
50}
45/// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately.51/// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately.
46pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 {52pub fn fma_f64(x: f64, y: f64, z: f64) f64 {
47 if (!math.isFinite(x) or !math.isFinite(y)) {53 if (!math.isFinite(x) or !math.isFinite(y)) {
48 return x * y + z;54 return x * y + z;
49 }55 }
...@@ -90,11 +96,17 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 {...@@ -90,11 +96,17 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 {
90 }96 }
91}97}
9298
93pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 {99fn __fmax(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi, c: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
100 return compiler_rt.f80.toAbi(fma_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b), compiler_rt.f80.fromAbi(c)));
101}
102pub fn fma_f80(a: f80, b: f80, c: f80) f80 {
94 // TODO: more efficient implementation103 // TODO: more efficient implementation
95 return @floatCast(fmaq(a, b, c));104 return @floatCast(fma_f128(a, b, c));
96}105}
97106
107fn fmaq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi, z: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
108 return compiler_rt.f128.toAbi(fma_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y), compiler_rt.f128.fromAbi(z)));
109}
98/// Fused multiply-add: Compute x * y + z with a single rounding error.110/// Fused multiply-add: Compute x * y + z with a single rounding error.
99///111///
100/// We use scaling to avoid overflow/underflow, along with the112/// We use scaling to avoid overflow/underflow, along with the
...@@ -102,7 +114,7 @@ pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 {...@@ -102,7 +114,7 @@ pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 {
102///114///
103/// Dekker, T. A Floating-Point Technique for Extending the115/// Dekker, T. A Floating-Point Technique for Extending the
104/// Available Precision. Numer. Math. 18, 224-242 (1971).116/// Available Precision. Numer. Math. 18, 224-242 (1971).
105pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 {117pub fn fma_f128(x: f128, y: f128, z: f128) f128 {
106 if (!math.isFinite(x) or !math.isFinite(y)) {118 if (!math.isFinite(x) or !math.isFinite(y)) {
107 return x * y + z;119 return x * y + z;
108 }120 }
...@@ -151,10 +163,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 {...@@ -151,10 +163,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 {
151163
152pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble {164pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble {
153 switch (@typeInfo(c_longdouble).float.bits) {165 switch (@typeInfo(c_longdouble).float.bits) {
154 64 => return fma(x, y, z),166 64 => return fma_f64(x, y, z),
155 80 => return __fmax(x, y, z),167 80 => return fma_f80(x, y, z),
156 128 => return fmaq(x, y, z),168 128 => return fma_f128(x, y, z),
157 else => @compileError("unreachable"),169 else => comptime unreachable,
158 }170 }
159}171}
160172
...@@ -316,35 +328,35 @@ fn dd_mul128(a: f128, b: f128) dd128 {...@@ -316,35 +328,35 @@ fn dd_mul128(a: f128, b: f128) dd128 {
316test "32" {328test "32" {
317 const epsilon = 0.000001;329 const epsilon = 0.000001;
318330
319 try expect(math.approxEqAbs(f32, fmaf(0.0, 5.0, 9.124), 9.124, epsilon));331 try expect(math.approxEqAbs(f32, fma_f32(0.0, 5.0, 9.124), 9.124, epsilon));
320 try expect(math.approxEqAbs(f32, fmaf(0.2, 5.0, 9.124), 10.124, epsilon));332 try expect(math.approxEqAbs(f32, fma_f32(0.2, 5.0, 9.124), 10.124, epsilon));
321 try expect(math.approxEqAbs(f32, fmaf(0.8923, 5.0, 9.124), 13.5855, epsilon));333 try expect(math.approxEqAbs(f32, fma_f32(0.8923, 5.0, 9.124), 13.5855, epsilon));
322 try expect(math.approxEqAbs(f32, fmaf(1.5, 5.0, 9.124), 16.624, epsilon));334 try expect(math.approxEqAbs(f32, fma_f32(1.5, 5.0, 9.124), 16.624, epsilon));
323 try expect(math.approxEqAbs(f32, fmaf(37.45, 5.0, 9.124), 196.374004, epsilon));335 try expect(math.approxEqAbs(f32, fma_f32(37.45, 5.0, 9.124), 196.374004, epsilon));
324 try expect(math.approxEqAbs(f32, fmaf(89.123, 5.0, 9.124), 454.739005, epsilon));336 try expect(math.approxEqAbs(f32, fma_f32(89.123, 5.0, 9.124), 454.739005, epsilon));
325 try expect(math.approxEqAbs(f32, fmaf(123123.234375, 5.0, 9.124), 615625.295875, epsilon));337 try expect(math.approxEqAbs(f32, fma_f32(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
326}338}
327339
328test "64" {340test "64" {
329 const epsilon = 0.000001;341 const epsilon = 0.000001;
330342
331 try expect(math.approxEqAbs(f64, fma(0.0, 5.0, 9.124), 9.124, epsilon));343 try expect(math.approxEqAbs(f64, fma_f64(0.0, 5.0, 9.124), 9.124, epsilon));
332 try expect(math.approxEqAbs(f64, fma(0.2, 5.0, 9.124), 10.124, epsilon));344 try expect(math.approxEqAbs(f64, fma_f64(0.2, 5.0, 9.124), 10.124, epsilon));
333 try expect(math.approxEqAbs(f64, fma(0.8923, 5.0, 9.124), 13.5855, epsilon));345 try expect(math.approxEqAbs(f64, fma_f64(0.8923, 5.0, 9.124), 13.5855, epsilon));
334 try expect(math.approxEqAbs(f64, fma(1.5, 5.0, 9.124), 16.624, epsilon));346 try expect(math.approxEqAbs(f64, fma_f64(1.5, 5.0, 9.124), 16.624, epsilon));
335 try expect(math.approxEqAbs(f64, fma(37.45, 5.0, 9.124), 196.374, epsilon));347 try expect(math.approxEqAbs(f64, fma_f64(37.45, 5.0, 9.124), 196.374, epsilon));
336 try expect(math.approxEqAbs(f64, fma(89.123, 5.0, 9.124), 454.739, epsilon));348 try expect(math.approxEqAbs(f64, fma_f64(89.123, 5.0, 9.124), 454.739, epsilon));
337 try expect(math.approxEqAbs(f64, fma(123123.234375, 5.0, 9.124), 615625.295875, epsilon));349 try expect(math.approxEqAbs(f64, fma_f64(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
338}350}
339351
340test "128" {352test "128" {
341 const epsilon = 0.000001;353 const epsilon = 0.000001;
342354
343 try expect(math.approxEqAbs(f128, fmaq(0.0, 5.0, 9.124), 9.124, epsilon));355 try expect(math.approxEqAbs(f128, fma_f128(0.0, 5.0, 9.124), 9.124, epsilon));
344 try expect(math.approxEqAbs(f128, fmaq(0.2, 5.0, 9.124), 10.124, epsilon));356 try expect(math.approxEqAbs(f128, fma_f128(0.2, 5.0, 9.124), 10.124, epsilon));
345 try expect(math.approxEqAbs(f128, fmaq(0.8923, 5.0, 9.124), 13.5855, epsilon));357 try expect(math.approxEqAbs(f128, fma_f128(0.8923, 5.0, 9.124), 13.5855, epsilon));
346 try expect(math.approxEqAbs(f128, fmaq(1.5, 5.0, 9.124), 16.624, epsilon));358 try expect(math.approxEqAbs(f128, fma_f128(1.5, 5.0, 9.124), 16.624, epsilon));
347 try expect(math.approxEqAbs(f128, fmaq(37.45, 5.0, 9.124), 196.374, epsilon));359 try expect(math.approxEqAbs(f128, fma_f128(37.45, 5.0, 9.124), 196.374, epsilon));
348 try expect(math.approxEqAbs(f128, fmaq(89.123, 5.0, 9.124), 454.739, epsilon));360 try expect(math.approxEqAbs(f128, fma_f128(89.123, 5.0, 9.124), 454.739, epsilon));
349 try expect(math.approxEqAbs(f128, fmaq(123123.234375, 5.0, 9.124), 615625.295875, epsilon));361 try expect(math.approxEqAbs(f128, fma_f128(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
350}362}
lib/compiler_rt/fmax.zig+25-13
...@@ -10,39 +10,51 @@ comptime {...@@ -10,39 +10,51 @@ comptime {
10 symbol(&fmaxf, "fmaxf");10 symbol(&fmaxf, "fmaxf");
11 symbol(&fmax, "fmax");11 symbol(&fmax, "fmax");
12 symbol(&__fmaxx, "__fmaxx");12 symbol(&__fmaxx, "__fmaxx");
13 if (compiler_rt.want_ppc_abi) {13 symbol(&fmaxq, "fmaxf128");
14 symbol(&fmaxq, "fmaxf128");
15 }
16 symbol(&fmaxq, "fmaxq");
17 symbol(&fmaxl, "fmaxl");14 symbol(&fmaxl, "fmaxl");
18}15}
1916
20pub fn __fmaxh(x: f16, y: f16) callconv(.c) f16 {17fn __fmaxh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
18 return compiler_rt.f16.toAbi(fmax_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y)));
19}
20pub fn fmax_f16(x: f16, y: f16) f16 {
21 return generic_fmax(f16, x, y);21 return generic_fmax(f16, x, y);
22}22}
2323
24pub fn fmaxf(x: f32, y: f32) callconv(.c) f32 {24fn fmaxf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
25 return compiler_rt.f32.toAbi(fmax_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y)));
26}
27pub fn fmax_f32(x: f32, y: f32) f32 {
25 return generic_fmax(f32, x, y);28 return generic_fmax(f32, x, y);
26}29}
2730
28pub fn fmax(x: f64, y: f64) callconv(.c) f64 {31fn fmax(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
32 return compiler_rt.f64.toAbi(fmax_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y)));
33}
34pub fn fmax_f64(x: f64, y: f64) f64 {
29 return generic_fmax(f64, x, y);35 return generic_fmax(f64, x, y);
30}36}
3137
32pub fn __fmaxx(x: f80, y: f80) callconv(.c) f80 {38fn __fmaxx(x: compiler_rt.f80.Abi, y: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
39 return compiler_rt.f80.toAbi(fmax_f80(compiler_rt.f80.fromAbi(x), compiler_rt.f80.fromAbi(y)));
40}
41pub fn fmax_f80(x: f80, y: f80) f80 {
33 return generic_fmax(f80, x, y);42 return generic_fmax(f80, x, y);
34}43}
3544
36pub fn fmaxq(x: f128, y: f128) callconv(.c) f128 {45fn fmaxq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
46 return compiler_rt.f128.toAbi(fmax_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y)));
47}
48pub fn fmax_f128(x: f128, y: f128) f128 {
37 return generic_fmax(f128, x, y);49 return generic_fmax(f128, x, y);
38}50}
3951
40pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {52pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
41 switch (@typeInfo(c_longdouble).float.bits) {53 switch (@typeInfo(c_longdouble).float.bits) {
42 64 => return fmax(x, y),54 64 => return fmax_f64(x, y),
43 80 => return __fmaxx(x, y),55 80 => return fmax_f80(x, y),
44 128 => return fmaxq(x, y),56 128 => return fmax_f128(x, y),
45 else => @compileError("unreachable"),57 else => comptime unreachable,
46 }58 }
47}59}
4860
lib/compiler_rt/fmin.zig+25-13
...@@ -10,39 +10,51 @@ comptime {...@@ -10,39 +10,51 @@ comptime {
10 symbol(&fminf, "fminf");10 symbol(&fminf, "fminf");
11 symbol(&fmin, "fmin");11 symbol(&fmin, "fmin");
12 symbol(&__fminx, "__fminx");12 symbol(&__fminx, "__fminx");
13 if (compiler_rt.want_ppc_abi) {13 symbol(&fminq, "fminf128");
14 symbol(&fminq, "fminf128");
15 }
16 symbol(&fminq, "fminq");
17 symbol(&fminl, "fminl");14 symbol(&fminl, "fminl");
18}15}
1916
20pub fn __fminh(x: f16, y: f16) callconv(.c) f16 {17fn __fminh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
18 return compiler_rt.f16.toAbi(fmin_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y)));
19}
20pub fn fmin_f16(x: f16, y: f16) f16 {
21 return generic_fmin(f16, x, y);21 return generic_fmin(f16, x, y);
22}22}
2323
24pub fn fminf(x: f32, y: f32) callconv(.c) f32 {24fn fminf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
25 return compiler_rt.f32.toAbi(fmin_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y)));
26}
27pub fn fmin_f32(x: f32, y: f32) f32 {
25 return generic_fmin(f32, x, y);28 return generic_fmin(f32, x, y);
26}29}
2730
28pub fn fmin(x: f64, y: f64) callconv(.c) f64 {31fn fmin(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
32 return compiler_rt.f64.toAbi(fmin_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y)));
33}
34pub fn fmin_f64(x: f64, y: f64) f64 {
29 return generic_fmin(f64, x, y);35 return generic_fmin(f64, x, y);
30}36}
3137
32pub fn __fminx(x: f80, y: f80) callconv(.c) f80 {38fn __fminx(x: compiler_rt.f80.Abi, y: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
39 return compiler_rt.f80.toAbi(fmin_f80(compiler_rt.f80.fromAbi(x), compiler_rt.f80.fromAbi(y)));
40}
41pub fn fmin_f80(x: f80, y: f80) f80 {
33 return generic_fmin(f80, x, y);42 return generic_fmin(f80, x, y);
34}43}
3544
36pub fn fminq(x: f128, y: f128) callconv(.c) f128 {45fn fminq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
46 return compiler_rt.f128.toAbi(fmin_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y)));
47}
48pub fn fmin_f128(x: f128, y: f128) f128 {
37 return generic_fmin(f128, x, y);49 return generic_fmin(f128, x, y);
38}50}
3951
40pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {52pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
41 switch (@typeInfo(c_longdouble).float.bits) {53 switch (@typeInfo(c_longdouble).float.bits) {
42 64 => return fmin(x, y),54 64 => return fmin_f64(x, y),
43 80 => return __fminx(x, y),55 80 => return fmin_f80(x, y),
44 128 => return fminq(x, y),56 128 => return fmin_f128(x, y),
45 else => @compileError("unreachable"),57 else => comptime unreachable,
46 }58 }
47}59}
4860
lib/compiler_rt/fmod.zig+50-38
...@@ -12,29 +12,38 @@ comptime {...@@ -12,29 +12,38 @@ comptime {
12 symbol(&fmodf, "fmodf");12 symbol(&fmodf, "fmodf");
13 symbol(&fmod, "fmod");13 symbol(&fmod, "fmod");
14 symbol(&__fmodx, "__fmodx");14 symbol(&__fmodx, "__fmodx");
15 if (compiler_rt.want_ppc_abi) {15 symbol(&fmodq, "fmodf128");
16 symbol(&fmodq, "fmodf128");
17 }
18 symbol(&fmodq, "fmodq");
19 symbol(&fmodl, "fmodl");16 symbol(&fmodl, "fmodl");
20}17}
2118
22pub fn __fmodh(x: f16, y: f16) callconv(.c) f16 {19fn __fmodh(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
20 return compiler_rt.f16.toAbi(fmod_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
21}
22pub fn fmod_f16(x: f16, y: f16) f16 {
23 // TODO: more efficient implementation23 // TODO: more efficient implementation
24 return @floatCast(fmodf(x, y));24 return @floatCast(fmod_f32(x, y));
25}25}
2626
27pub fn fmodf(x: f32, y: f32) callconv(.c) f32 {27fn fmodf(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
28 return compiler_rt.f32.toAbi(fmod_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)));
29}
30pub fn fmod_f32(x: f32, y: f32) f32 {
28 return generic_fmod(f32, x, y);31 return generic_fmod(f32, x, y);
29}32}
3033
31pub fn fmod(x: f64, y: f64) callconv(.c) f64 {34fn fmod(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
35 return compiler_rt.f64.toAbi(fmod_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)));
36}
37pub fn fmod_f64(x: f64, y: f64) f64 {
32 return generic_fmod(f64, x, y);38 return generic_fmod(f64, x, y);
33}39}
3440
41fn __fmodx(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
42 return compiler_rt.f80.toAbi(fmod_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)));
43}
35/// fmodx - floating modulo large, returns the remainder of division for f80 types44/// fmodx - floating modulo large, returns the remainder of division for f80 types
36/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits45/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits
37pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 {46pub fn fmod_f80(a: f80, b: f80) f80 {
38 const T = f80;47 const T = f80;
39 const Z = @Int(.unsigned, @bitSizeOf(T));48 const Z = @Int(.unsigned, @bitSizeOf(T));
4049
...@@ -130,9 +139,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 {...@@ -130,9 +139,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 {
130 }139 }
131}140}
132141
142fn fmodq(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
143 return compiler_rt.f128.toAbi(fmod_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)));
144}
133/// fmodq - floating modulo large, returns the remainder of division for f128 types145/// fmodq - floating modulo large, returns the remainder of division for f128 types
134/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits146/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits
135pub fn fmodq(a: f128, b: f128) callconv(.c) f128 {147pub fn fmod_f128(a: f128, b: f128) f128 {
136 var amod = a;148 var amod = a;
137 var bmod = b;149 var bmod = b;
138 const aPtr_u64: [*]u64 = @ptrCast(&amod);150 const aPtr_u64: [*]u64 = @ptrCast(&amod);
...@@ -251,10 +263,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.c) f128 {...@@ -251,10 +263,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.c) f128 {
251263
252pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble {264pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble {
253 switch (@typeInfo(c_longdouble).float.bits) {265 switch (@typeInfo(c_longdouble).float.bits) {
254 64 => return fmod(a, b),266 64 => return fmod_f64(a, b),
255 80 => return __fmodx(a, b),267 80 => return fmod_f80(a, b),
256 128 => return fmodq(a, b),268 128 => return fmod_f128(a, b),
257 else => @compileError("unreachable"),269 else => comptime unreachable,
258 }270 }
259}271}
260272
...@@ -342,42 +354,42 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -342,42 +354,42 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
342 return @bitCast(ux);354 return @bitCast(ux);
343}355}
344356
345test "fmodf" {357test fmod_f32 {
346 const nan_val = math.nan(f32);358 const nan_val = math.nan(f32);
347 const inf_val = math.inf(f32);359 const inf_val = math.inf(f32);
348360
349 try std.testing.expect(math.isNan(fmodf(nan_val, 1.0)));361 try std.testing.expect(math.isNan(fmod_f32(nan_val, 1.0)));
350 try std.testing.expect(math.isNan(fmodf(1.0, nan_val)));362 try std.testing.expect(math.isNan(fmod_f32(1.0, nan_val)));
351 try std.testing.expect(math.isNan(fmodf(inf_val, 1.0)));363 try std.testing.expect(math.isNan(fmod_f32(inf_val, 1.0)));
352 try std.testing.expect(math.isNan(fmodf(0.0, 0.0)));364 try std.testing.expect(math.isNan(fmod_f32(0.0, 0.0)));
353 try std.testing.expect(math.isNan(fmodf(1.0, 0.0)));365 try std.testing.expect(math.isNan(fmod_f32(1.0, 0.0)));
354366
355 try std.testing.expectEqual(@as(f32, 0.0), fmodf(0.0, 2.0));367 try std.testing.expectEqual(@as(f32, 0.0), fmod_f32(0.0, 2.0));
356 try std.testing.expectEqual(@as(f32, -0.0), fmodf(-0.0, 2.0));368 try std.testing.expectEqual(@as(f32, -0.0), fmod_f32(-0.0, 2.0));
357369
358 try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, 10.0));370 try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, 10.0));
359 try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, -10.0));371 try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, -10.0));
360 try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, 10.0));372 try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, 10.0));
361 try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, -10.0));373 try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, -10.0));
362}374}
363375
364test "fmod" {376test fmod_f64 {
365 const nan_val = math.nan(f64);377 const nan_val = math.nan(f64);
366 const inf_val = math.inf(f64);378 const inf_val = math.inf(f64);
367379
368 try std.testing.expect(math.isNan(fmod(nan_val, 1.0)));380 try std.testing.expect(math.isNan(fmod_f64(nan_val, 1.0)));
369 try std.testing.expect(math.isNan(fmod(1.0, nan_val)));381 try std.testing.expect(math.isNan(fmod_f64(1.0, nan_val)));
370 try std.testing.expect(math.isNan(fmod(inf_val, 1.0)));382 try std.testing.expect(math.isNan(fmod_f64(inf_val, 1.0)));
371 try std.testing.expect(math.isNan(fmod(0.0, 0.0)));383 try std.testing.expect(math.isNan(fmod_f64(0.0, 0.0)));
372 try std.testing.expect(math.isNan(fmod(1.0, 0.0)));384 try std.testing.expect(math.isNan(fmod_f64(1.0, 0.0)));
373385
374 try std.testing.expectEqual(@as(f64, 0.0), fmod(0.0, 2.0));386 try std.testing.expectEqual(@as(f64, 0.0), fmod_f64(0.0, 2.0));
375 try std.testing.expectEqual(@as(f64, -0.0), fmod(-0.0, 2.0));387 try std.testing.expectEqual(@as(f64, -0.0), fmod_f64(-0.0, 2.0));
376388
377 try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, 10.0));389 try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, 10.0));
378 try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, -10.0));390 try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, -10.0));
379 try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, 10.0));391 try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, 10.0));
380 try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, -10.0));392 try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, -10.0));
381}393}
382394
383test {395test {
lib/compiler_rt/fmodq_test.zig+32-32
...@@ -1,52 +1,52 @@...@@ -1,52 +1,52 @@
1const std = @import("std");1const std = @import("std");
2const fmod = @import("fmod.zig");2const fmod_f128 = @import("fmod.zig").fmod_f128;
3const testing = std.testing;3const testing = std.testing;
44
5fn test_fmodq(a: f128, b: f128, exp: f128) !void {5fn test_fmod_f128(a: f128, b: f128, exp: f128) !void {
6 const res = fmod.fmodq(a, b);6 const res = fmod_f128(a, b);
7 try testing.expect(exp == res);7 try testing.expect(exp == res);
8}8}
99
10fn test_fmodq_nans() !void {10fn test_fmod_f128_nans() !void {
11 try testing.expect(std.math.isNan(fmod.fmodq(1.0, std.math.nan(f128))));11 try testing.expect(std.math.isNan(fmod_f128(1.0, std.math.nan(f128))));
12 try testing.expect(std.math.isNan(fmod.fmodq(1.0, -std.math.nan(f128))));12 try testing.expect(std.math.isNan(fmod_f128(1.0, -std.math.nan(f128))));
13 try testing.expect(std.math.isNan(fmod.fmodq(std.math.nan(f128), 1.0)));13 try testing.expect(std.math.isNan(fmod_f128(std.math.nan(f128), 1.0)));
14 try testing.expect(std.math.isNan(fmod.fmodq(-std.math.nan(f128), 1.0)));14 try testing.expect(std.math.isNan(fmod_f128(-std.math.nan(f128), 1.0)));
15}15}
1616
17fn test_fmodq_infs() !void {17fn test_fmod_f128_infs() !void {
18 try testing.expect(fmod.fmodq(1.0, std.math.inf(f128)) == 1.0);18 try testing.expect(fmod_f128(1.0, std.math.inf(f128)) == 1.0);
19 try testing.expect(fmod.fmodq(1.0, -std.math.inf(f128)) == 1.0);19 try testing.expect(fmod_f128(1.0, -std.math.inf(f128)) == 1.0);
20 try testing.expect(std.math.isNan(fmod.fmodq(std.math.inf(f128), 1.0)));20 try testing.expect(std.math.isNan(fmod_f128(std.math.inf(f128), 1.0)));
21 try testing.expect(std.math.isNan(fmod.fmodq(-std.math.inf(f128), 1.0)));21 try testing.expect(std.math.isNan(fmod_f128(-std.math.inf(f128), 1.0)));
22}22}
2323
24test "fmodq" {24test fmod_f128 {
25 try test_fmodq(6.8, 4.0, 2.8);25 try test_fmod_f128(6.8, 4.0, 2.8);
26 try test_fmodq(6.8, -4.0, 2.8);26 try test_fmod_f128(6.8, -4.0, 2.8);
27 try test_fmodq(-6.8, 4.0, -2.8);27 try test_fmod_f128(-6.8, 4.0, -2.8);
28 try test_fmodq(-6.8, -4.0, -2.8);28 try test_fmod_f128(-6.8, -4.0, -2.8);
29 try test_fmodq(3.0, 2.0, 1.0);29 try test_fmod_f128(3.0, 2.0, 1.0);
30 try test_fmodq(-5.0, 3.0, -2.0);30 try test_fmod_f128(-5.0, 3.0, -2.0);
31 try test_fmodq(3.0, 2.0, 1.0);31 try test_fmod_f128(3.0, 2.0, 1.0);
32 try test_fmodq(1.0, 2.0, 1.0);32 try test_fmod_f128(1.0, 2.0, 1.0);
33 try test_fmodq(0.0, 1.0, 0.0);33 try test_fmod_f128(0.0, 1.0, 0.0);
34 try test_fmodq(-0.0, 1.0, -0.0);34 try test_fmod_f128(-0.0, 1.0, -0.0);
35 try test_fmodq(7046119.0, 5558362.0, 1487757.0);35 try test_fmod_f128(7046119.0, 5558362.0, 1487757.0);
36 try test_fmodq(9010357.0, 1957236.0, 1181413.0);36 try test_fmod_f128(9010357.0, 1957236.0, 1181413.0);
37 try test_fmodq(5192296858534827628530496329220095, 10.0, 5.0);37 try test_fmod_f128(5192296858534827628530496329220095, 10.0, 5.0);
38 try test_fmodq(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157);38 try test_fmod_f128(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157);
3939
40 // Denormals40 // Denormals
41 const a1: f128 = 0xedcb34a235253948765432134674p-16494;41 const a1: f128 = 0xedcb34a235253948765432134674p-16494;
42 const b1: f128 = 0x5d2e38791cfbc0737402da5a9518p-16494;42 const b1: f128 = 0x5d2e38791cfbc0737402da5a9518p-16494;
43 const exp1: f128 = 0x336ec3affb2db8618e4e7d5e1c44p-16494;43 const exp1: f128 = 0x336ec3affb2db8618e4e7d5e1c44p-16494;
44 try test_fmodq(a1, b1, exp1);44 try test_fmod_f128(a1, b1, exp1);
45 const a2: f128 = 0x0.7654_3210_fdec_ba98_7654_3210_fdecp-16382;45 const a2: f128 = 0x0.7654_3210_fdec_ba98_7654_3210_fdecp-16382;
46 const b2: f128 = 0x0.0012_fdac_bdef_1234_fdec_3222_1111p-16382;46 const b2: f128 = 0x0.0012_fdac_bdef_1234_fdec_3222_1111p-16382;
47 const exp2: f128 = 0x0.0001_aecd_9d66_4a6e_67b7_d7d0_a901p-16382;47 const exp2: f128 = 0x0.0001_aecd_9d66_4a6e_67b7_d7d0_a901p-16382;
48 try test_fmodq(a2, b2, exp2);48 try test_fmod_f128(a2, b2, exp2);
4949
50 try test_fmodq_nans();50 try test_fmod_f128_nans();
51 try test_fmodq_infs();51 try test_fmod_f128_infs();
52}52}
lib/compiler_rt/fmodx_test.zig+31-31
...@@ -1,52 +1,52 @@...@@ -1,52 +1,52 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const fmod = @import("fmod.zig");3const fmod_f80 = @import("fmod.zig").fmod_f80;
4const testing = std.testing;4const testing = std.testing;
55
6fn test_fmodx(a: f80, b: f80, exp: f80) !void {6fn test_fmod_f80(a: f80, b: f80, exp: f80) !void {
7 const res = fmod.__fmodx(a, b);7 const res = fmod_f80(a, b);
8 try testing.expect(exp == res);8 try testing.expect(exp == res);
9}9}
1010
11fn test_fmodx_nans() !void {11fn test_fmod_f80_nans() !void {
12 try testing.expect(std.math.isNan(fmod.__fmodx(1.0, std.math.nan(f80))));12 try testing.expect(std.math.isNan(fmod_f80(1.0, std.math.nan(f80))));
13 try testing.expect(std.math.isNan(fmod.__fmodx(1.0, -std.math.nan(f80))));13 try testing.expect(std.math.isNan(fmod_f80(1.0, -std.math.nan(f80))));
14 try testing.expect(std.math.isNan(fmod.__fmodx(std.math.nan(f80), 1.0)));14 try testing.expect(std.math.isNan(fmod_f80(std.math.nan(f80), 1.0)));
15 try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.nan(f80), 1.0)));15 try testing.expect(std.math.isNan(fmod_f80(-std.math.nan(f80), 1.0)));
16}16}
1717
18fn test_fmodx_infs() !void {18fn test_fmod_f80_infs() !void {
19 try testing.expect(fmod.__fmodx(1.0, std.math.inf(f80)) == 1.0);19 try testing.expect(fmod_f80(1.0, std.math.inf(f80)) == 1.0);
20 try testing.expect(fmod.__fmodx(1.0, -std.math.inf(f80)) == 1.0);20 try testing.expect(fmod_f80(1.0, -std.math.inf(f80)) == 1.0);
21 try testing.expect(std.math.isNan(fmod.__fmodx(std.math.inf(f80), 1.0)));21 try testing.expect(std.math.isNan(fmod_f80(std.math.inf(f80), 1.0)));
22 try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.inf(f80), 1.0)));22 try testing.expect(std.math.isNan(fmod_f80(-std.math.inf(f80), 1.0)));
23}23}
2424
25test "fmodx" {25test fmod_f80 {
26 try test_fmodx(6.4, 4.0, 2.4);26 try test_fmod_f80(6.4, 4.0, 2.4);
27 try test_fmodx(6.4, -4.0, 2.4);27 try test_fmod_f80(6.4, -4.0, 2.4);
28 try test_fmodx(-6.4, 4.0, -2.4);28 try test_fmod_f80(-6.4, 4.0, -2.4);
29 try test_fmodx(-6.4, -4.0, -2.4);29 try test_fmod_f80(-6.4, -4.0, -2.4);
30 try test_fmodx(3.0, 2.0, 1.0);30 try test_fmod_f80(3.0, 2.0, 1.0);
31 try test_fmodx(-5.0, 3.0, -2.0);31 try test_fmod_f80(-5.0, 3.0, -2.0);
32 try test_fmodx(3.0, 2.0, 1.0);32 try test_fmod_f80(3.0, 2.0, 1.0);
33 try test_fmodx(1.0, 2.0, 1.0);33 try test_fmod_f80(1.0, 2.0, 1.0);
34 try test_fmodx(0.0, 1.0, 0.0);34 try test_fmod_f80(0.0, 1.0, 0.0);
35 try test_fmodx(-0.0, 1.0, -0.0);35 try test_fmod_f80(-0.0, 1.0, -0.0);
36 try test_fmodx(7046119.0, 5558362.0, 1487757.0);36 try test_fmod_f80(7046119.0, 5558362.0, 1487757.0);
37 try test_fmodx(9010357.0, 1957236.0, 1181413.0);37 try test_fmod_f80(9010357.0, 1957236.0, 1181413.0);
38 try test_fmodx(9223372036854775807, 10.0, 7.0);38 try test_fmod_f80(9223372036854775807, 10.0, 7.0);
3939
40 // Denormals40 // Denormals
41 const a1: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;41 const a1: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;
42 const b1: f80 = 0x0.2e97_1c3c_8e7d_e03ap-16381;42 const b1: f80 = 0x0.2e97_1c3c_8e7d_e03ap-16381;
43 const exp1: f80 = 0x0.19b7_61d7_fd96_dc30p-16381;43 const exp1: f80 = 0x0.19b7_61d7_fd96_dc30p-16381;
44 try test_fmodx(a1, b1, exp1);44 try test_fmod_f80(a1, b1, exp1);
45 const a2: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;45 const a2: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;
46 const b2: f80 = 0x0.0e97_1c3c_8e7d_e03ap-16381;46 const b2: f80 = 0x0.0e97_1c3c_8e7d_e03ap-16381;
47 const exp2: f80 = 0x0.022c_b86c_a6a3_9ad4p-16381;47 const exp2: f80 = 0x0.022c_b86c_a6a3_9ad4p-16381;
48 try test_fmodx(a2, b2, exp2);48 try test_fmod_f80(a2, b2, exp2);
4949
50 try test_fmodx_nans();50 try test_fmod_f80_nans();
51 try test_fmodx_infs();51 try test_fmod_f80_infs();
52}52}
lib/compiler_rt/gedf2.zig deleted-35
...@@ -1,35 +0,0 @@
1///! The quoted behavior definitions are from
2///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
3const compiler_rt = @import("../compiler_rt.zig");
4const comparef = @import("./comparef.zig");
5const symbol = @import("../compiler_rt.zig").symbol;
6
7comptime {
8 if (compiler_rt.want_aeabi) {
9 symbol(&__aeabi_dcmpge, "__aeabi_dcmpge");
10 symbol(&__aeabi_dcmpgt, "__aeabi_dcmpgt");
11 } else {
12 symbol(&__gedf2, "__gedf2");
13 symbol(&__gtdf2, "__gtdf2");
14 }
15}
16
17/// "These functions return a value greater than or equal to zero if neither
18/// argument is NaN, and a is greater than or equal to b."
19pub fn __gedf2(a: f64, b: f64) callconv(.c) i32 {
20 return @backingInt(comparef.cmpf2(f64, comparef.GE, a, b));
21}
22
23/// "These functions return a value greater than zero if neither argument is NaN,
24/// and a is strictly greater than b."
25pub fn __gtdf2(a: f64, b: f64) callconv(.c) i32 {
26 return __gedf2(a, b);
27}
28
29fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
30 return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) != .Less);
31}
32
33fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
34 return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) == .Greater);
35}
lib/compiler_rt/gehf2.zig deleted-21
...@@ -1,21 +0,0 @@
1///! The quoted behavior definitions are from
2///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
3const symbol = @import("../compiler_rt.zig").symbol;
4const comparef = @import("./comparef.zig");
5
6comptime {
7 symbol(&__gehf2, "__gehf2");
8 symbol(&__gthf2, "__gthf2");
9}
10
11/// "These functions return a value greater than or equal to zero if neither
12/// argument is NaN, and a is greater than or equal to b."
13pub fn __gehf2(a: f16, b: f16) callconv(.c) i32 {
14 return @backingInt(comparef.cmpf2(f16, comparef.GE, a, b));
15}
16
17/// "These functions return a value greater than zero if neither argument is NaN,
18/// and a is strictly greater than b."
19pub fn __gthf2(a: f16, b: f16) callconv(.c) i32 {
20 return __gehf2(a, b);
21}
lib/compiler_rt/gesf2.zig deleted-35
...@@ -1,35 +0,0 @@
1///! The quoted behavior definitions are from
2///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const comparef = @import("./comparef.zig");
6
7comptime {
8 if (compiler_rt.want_aeabi) {
9 symbol(&__aeabi_fcmpge, "__aeabi_fcmpge");
10 symbol(&__aeabi_fcmpgt, "__aeabi_fcmpgt");
11 } else {
12 symbol(&__gesf2, "__gesf2");
13 symbol(&__gtsf2, "__gtsf2");
14 }
15}
16
17/// "These functions return a value greater than or equal to zero if neither
18/// argument is NaN, and a is greater than or equal to b."
19pub fn __gesf2(a: f32, b: f32) callconv(.c) i32 {
20 return @backingInt(comparef.cmpf2(f32, comparef.GE, a, b));
21}
22
23/// "These functions return a value greater than zero if neither argument is NaN,
24/// and a is strictly greater than b."
25pub fn __gtsf2(a: f32, b: f32) callconv(.c) i32 {
26 return __gesf2(a, b);
27}
28
29fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
30 return @intFromBool(comparef.cmpf2(f32, comparef.GE, a, b) != .Less);
31}
32
33fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
34 return @intFromBool(comparef.cmpf2(f32, comparef.LE, a, b) == .Greater);
35}
lib/compiler_rt/getf2.zig deleted-26
...@@ -1,26 +0,0 @@
1///! The quoted behavior definitions are from
2///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const comparef = @import("./comparef.zig");
6
7comptime {
8 if (compiler_rt.want_ppc_abi) {
9 symbol(&__getf2, "__gekf2");
10 symbol(&__gttf2, "__gtkf2");
11 }
12 symbol(&__getf2, "__getf2");
13 symbol(&__gttf2, "__gttf2");
14}
15
16/// "These functions return a value greater than or equal to zero if neither
17/// argument is NaN, and a is greater than or equal to b."
18fn __getf2(a: f128, b: f128) callconv(.c) i32 {
19 return @backingInt(comparef.cmpf2(f128, comparef.GE, a, b));
20}
21
22/// "These functions return a value greater than zero if neither argument is NaN,
23/// and a is strictly greater than b."
24fn __gttf2(a: f128, b: f128) callconv(.c) i32 {
25 return __getf2(a, b);
26}
lib/compiler_rt/gexf2.zig deleted-15
...@@ -1,15 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const comparef = @import("./comparef.zig");
3
4comptime {
5 symbol(&__gexf2, "__gexf2");
6 symbol(&__gtxf2, "__gtxf2");
7}
8
9fn __gexf2(a: f80, b: f80) callconv(.c) i32 {
10 return @backingInt(comparef.cmp_f80(comparef.GE, a, b));
11}
12
13fn __gtxf2(a: f80, b: f80) callconv(.c) i32 {
14 return __gexf2(a, b);
15}
lib/compiler_rt/int.zig+39-40
...@@ -36,7 +36,7 @@ comptime {...@@ -36,7 +36,7 @@ comptime {
3636
37pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 {37pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 {
38 const d = __divti3(a, b);38 const d = __divti3(a, b);
39 rem.* = a -% (d * b);39 rem.* = a - d *% b;
40 return d;40 return d;
41}41}
4242
...@@ -69,7 +69,7 @@ fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !voi...@@ -69,7 +69,7 @@ fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !voi
6969
70pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 {70pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 {
71 const d = __divdi3(a, b);71 const d = __divdi3(a, b);
72 rem.* = a -% (d * b);72 rem.* = a - d *% b;
73 return d;73 return d;
74}74}
7575
...@@ -79,21 +79,20 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void {...@@ -79,21 +79,20 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void {
79 try testing.expect(q == expected_q and r == expected_r);79 try testing.expect(q == expected_q and r == expected_r);
80}80}
8181
82const cases__divmoddi4 =82const cases__divmoddi4 = [_][4]i64{
83 [_][4]i64{83 [_]i64{ 0, 1, 0, 0 },
84 [_]i64{ 0, 1, 0, 0 },84 [_]i64{ 0, -1, 0, 0 },
85 [_]i64{ 0, -1, 0, 0 },85 [_]i64{ 2, 1, 2, 0 },
86 [_]i64{ 2, 1, 2, 0 },86 [_]i64{ 2, -1, -2, 0 },
87 [_]i64{ 2, -1, -2, 0 },87 [_]i64{ -2, 1, -2, 0 },
88 [_]i64{ -2, 1, -2, 0 },88 [_]i64{ -2, -1, 2, 0 },
89 [_]i64{ -2, -1, 2, 0 },89 [_]i64{ 7, 5, 1, 2 },
90 [_]i64{ 7, 5, 1, 2 },90 [_]i64{ -7, 5, -1, -2 },
91 [_]i64{ -7, 5, -1, -2 },91 [_]i64{ 19, 5, 3, 4 },
92 [_]i64{ 19, 5, 3, 4 },92 [_]i64{ 19, -5, -3, 4 },
93 [_]i64{ 19, -5, -3, 4 },93 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 },
94 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 },94 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },
95 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },95};
96 };
9796
98test "test_divmoddi4" {97test "test_divmoddi4" {
99 for (cases__divmoddi4) |case| {98 for (cases__divmoddi4) |case| {
...@@ -105,10 +104,6 @@ pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 {...@@ -105,10 +104,6 @@ pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 {
105 return udivmod(u64, a, b, maybe_rem);104 return udivmod(u64, a, b, maybe_rem);
106}105}
107106
108test "test_udivmoddi4" {
109 _ = @import("udivmoddi4_test.zig");
110}
111
112pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 {107pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 {
113 // Set aside the sign of the quotient.108 // Set aside the sign of the quotient.
114 const sign: u64 = @bitCast((a ^ b) >> 63);109 const sign: u64 = @bitCast((a ^ b) >> 63);
...@@ -209,25 +204,24 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void {...@@ -209,25 +204,24 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void {
209204
210pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 {205pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 {
211 const d = __divsi3(a, b);206 const d = __divsi3(a, b);
212 rem.* = a -% (d * b);207 rem.* = a - d *% b;
213 return d;208 return d;
214}209}
215210
216const cases__divmodsi4 =211const cases__divmodsi4 = [_][4]i32{
217 [_][4]i32{212 [_]i32{ 0, 1, 0, 0 },
218 [_]i32{ 0, 1, 0, 0 },213 [_]i32{ 0, -1, 0, 0 },
219 [_]i32{ 0, -1, 0, 0 },214 [_]i32{ 2, 1, 2, 0 },
220 [_]i32{ 2, 1, 2, 0 },215 [_]i32{ 2, -1, -2, 0 },
221 [_]i32{ 2, -1, -2, 0 },216 [_]i32{ -2, 1, -2, 0 },
222 [_]i32{ -2, 1, -2, 0 },217 [_]i32{ -2, -1, 2, 0 },
223 [_]i32{ -2, -1, 2, 0 },218 [_]i32{ 7, 5, 1, 2 },
224 [_]i32{ 7, 5, 1, 2 },219 [_]i32{ -7, 5, -1, -2 },
225 [_]i32{ -7, 5, -1, -2 },220 [_]i32{ 19, 5, 3, 4 },
226 [_]i32{ 19, 5, 3, 4 },221 [_]i32{ 19, -5, -3, 4 },
227 [_]i32{ 19, -5, -3, 4 },222 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 },
228 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 },223 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 },
229 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 },224};
230 };
231225
232fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void {226fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void {
233 var r: i32 = undefined;227 var r: i32 = undefined;
...@@ -243,7 +237,7 @@ test "test_divmodsi4" {...@@ -243,7 +237,7 @@ test "test_divmodsi4" {
243237
244pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 {238pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 {
245 const d = __udivsi3(a, b);239 const d = __udivsi3(a, b);
246 rem.* = @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b))));240 rem.* = a - d * b;
247 return d;241 return d;
248}242}
249243
...@@ -486,7 +480,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void {...@@ -486,7 +480,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void {
486}480}
487481
488pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 {482pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 {
489 return n -% __divsi3(n, d) * d;483 return n - __divsi3(n, d) *% d;
490}484}
491485
492test "test_modsi3" {486test "test_modsi3" {
...@@ -515,7 +509,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void {...@@ -515,7 +509,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void {
515}509}
516510
517pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 {511pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 {
518 return n -% __udivsi3(n, d) * d;512 return n - __udivsi3(n, d) * d;
519}513}
520514
521test "test_umodsi3" {515test "test_umodsi3" {
...@@ -663,3 +657,8 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void {...@@ -663,3 +657,8 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void {
663 const r: u32 = __umodsi3(a, b);657 const r: u32 = __umodsi3(a, b);
664 try testing.expect(r == expected_r);658 try testing.expect(r == expected_r);
665}659}
660
661test {
662 _ = @import("udivmodsi4_test.zig");
663 _ = @import("udivmoddi4_test.zig");
664}
lib/compiler_rt/int_from_float.zig+513-9
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const math = std.math;3const math = std.math;
3const Log2Int = std.math.Log2Int;4const Log2Int = std.math.Log2Int;
...@@ -6,29 +7,532 @@ const compiler_rt = @import("../compiler_rt.zig");...@@ -6,29 +7,532 @@ const compiler_rt = @import("../compiler_rt.zig");
6const symbol = compiler_rt.symbol;7const symbol = compiler_rt.symbol;
78
8comptime {9comptime {
9 symbol(&__fixxfti, "__fixxfti");
10 symbol(&__fixhfsi, "__fixhfsi");10 symbol(&__fixhfsi, "__fixhfsi");
11 symbol(&__fixhfdi, "__fixhfdi");11 symbol(&__fixhfdi, "__fixhfdi");
12 symbol(&__fixhfti, "__fixhfti");12 symbol(&__fixhfti, "__fixhfti");
13 symbol(&__fixhfei, "__fixhfei");
14
15 if (compiler_rt.want_aeabi) {
16 symbol(&__aeabi_f2iz, "__aeabi_f2iz");
17 symbol(&__aeabi_f2lz, "__aeabi_f2lz");
18 symbol(&__aeabi_fixsfti, "__fixsfti");
19 } else {
20 symbol(&__fixsfsi, "__fixsfsi");
21 symbol(&__fixsfdi, "__fixsfdi");
22 if (compiler_rt.want_windows_arm_abi) symbol(&__fixsfdi, "__stoi64");
23 symbol(&__fixsfti, "__fixsfti");
24 }
25 symbol(&__fixsfei, "__fixsfei");
26
27 if (compiler_rt.want_aeabi) {
28 symbol(&__aeabi_d2iz, "__aeabi_d2iz");
29 symbol(&__aeabi_d2lz, "__aeabi_d2lz");
30 symbol(&__aeabi_fixdfti, "__fixdfti");
31 } else {
32 symbol(&__fixdfsi, "__fixdfsi");
33 symbol(&__fixdfdi, "__fixdfdi");
34 if (compiler_rt.want_windows_arm_abi) symbol(&__fixdfdi, "__dtoi64");
35 symbol(&__fixdfti, "__fixdfti");
36 }
37 symbol(&__fixdfei, "__fixdfei");
38
39 symbol(&__fixxfsi, "__fixxfsi");
40 symbol(&__fixxfdi, "__fixxfdi");
41 symbol(&__fixxfti, "__fixxfti");
42 symbol(&__fixxfei, "__fixxfei");
43
44 if (compiler_rt.want_ppc_abi) {
45 symbol(&__fixtfsi, "__fixkfsi");
46 symbol(&__fixtfdi, "__fixkfdi");
47 } else if (compiler_rt.want_sparc64_abi) {
48 symbol(&_Qp_qtoi, "_Qp_qtoi");
49 symbol(&_Qp_qtox, "_Qp_qtox");
50 } else if (compiler_rt.want_sparc32_abi) {
51 symbol(&__fixtfsi, "_Q_qtoi");
52 symbol(&__fixtfdi, "_Q_qtoll");
53 } else {
54 symbol(&__fixtfsi, "__fixtfsi");
55 symbol(&__fixtfdi, "__fixtfdi");
56 }
57 if (compiler_rt.want_ppc_abi) {
58 symbol(&__fixtfti, "__fixkfti");
59 symbol(&__fixtfei, "__fixkfei");
60 } else {
61 symbol(&__fixtfti, "__fixtfti");
62 symbol(&__fixtfei, "__fixtfei");
63 }
64}
65
66fn __fixhfsi(a: compiler_rt.f16.Abi) callconv(.c) i32 {
67 return i32_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
68}
69pub fn i32_intFromFloat_f16(a: f16) i32 {
70 return intFromFloat(i32, a);
71}
72
73fn __fixhfdi(a: compiler_rt.f16.Abi) callconv(.c) i64 {
74 return i64_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
75}
76pub fn i64_intFromFloat_f16(a: f16) i64 {
77 return intFromFloat(i64, a);
78}
79
80fn __fixhfti(a: compiler_rt.f16.Abi) callconv(.c) i128 {
81 return i128_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
82}
83pub fn i128_intFromFloat_f16(a: f16) i128 {
84 return intFromFloat(i128, a);
85}
86
87fn __fixhfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void {
88 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
89 return signed_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a));
90}
91pub fn signed_intFromFloat_f16(result: []u8, a: f16) void {
92 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
93}
94
95fn __fixsfsi(a: compiler_rt.f32.Abi) callconv(.c) i32 {
96 return i32_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
97}
98fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
99 return i32_intFromFloat_f32(a);
100}
101pub fn i32_intFromFloat_f32(a: f32) i32 {
102 return intFromFloat(i32, a);
103}
104
105fn __fixsfdi(a: compiler_rt.f32.Abi) callconv(.c) i64 {
106 return i64_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
107}
108fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 {
109 return i64_intFromFloat_f32(a);
110}
111pub fn i64_intFromFloat_f32(a: f32) i64 {
112 return intFromFloat(i64, a);
113}
114
115fn __fixsfti(a: compiler_rt.f32.Abi) callconv(.c) i128 {
116 return i128_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
117}
118fn __aeabi_fixsfti(_: compiler_rt.f32.Abi) callconv(.naked) i128 {
119 switch (builtin.abi.float()) {
120 .soft => asm volatile (
121 \\ push {r0-r4, lr}
122 \\ mov r1, r0
123 \\ mov r0, sp
124 \\ bl %[__fixsfti]
125 \\ pop {r0-r4, pc}
126 :
127 : [__fixsfti] "X" (&__fixsfti),
128 ),
129 .hard => asm volatile (
130 \\ push {r0-r4, lr}
131 \\ mov r0, sp
132 \\ bl %[__fixsfti]
133 \\ pop {r0-r4, pc}
134 :
135 : [__fixsfti] "X" (&__fixsfti),
136 ),
137 }
138}
139pub fn i128_intFromFloat_f32(a: f32) i128 {
140 return intFromFloat(i128, a);
141}
142
143fn __fixsfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void {
144 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
145 return signed_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a));
146}
147pub fn signed_intFromFloat_f32(result: []u8, a: f32) void {
148 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
149}
150
151fn __fixdfsi(a: compiler_rt.f64.Abi) callconv(.c) i32 {
152 return i32_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
153}
154fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
155 return i32_intFromFloat_f64(a);
156}
157pub fn i32_intFromFloat_f64(a: f64) i32 {
158 return intFromFloat(i32, a);
159}
160
161fn __fixdfdi(a: compiler_rt.f64.Abi) callconv(.c) i64 {
162 return i64_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
163}
164fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 {
165 return i64_intFromFloat_f64(a);
166}
167pub fn i64_intFromFloat_f64(a: f64) i64 {
168 return intFromFloat(i64, a);
13}169}
14170
15pub fn __fixhfti(a: f16) callconv(.c) i128 {171fn __fixdfti(a: compiler_rt.f64.Abi) callconv(.c) i128 {
172 return i128_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
173}
174fn __aeabi_fixdfti(_: compiler_rt.f64.Abi) callconv(.naked) i128 {
175 switch (builtin.abi.float()) {
176 .soft => asm volatile (
177 \\ push {r0-r4, lr}
178 \\ mov r3, r1
179 \\ mov r2, r0
180 \\ mov r0, sp
181 \\ bl %[__fixdfti]
182 \\ pop {r0-r4, pc}
183 :
184 : [__fixdfti] "X" (&__fixdfti),
185 ),
186 .hard => asm volatile (
187 \\ push {r0-r4, lr}
188 \\ mov r0, sp
189 \\ bl %[__fixdfti]
190 \\ pop {r0-r4, pc}
191 :
192 : [__fixdfti] "X" (&__fixdfti),
193 ),
194 }
195}
196pub fn i128_intFromFloat_f64(a: f64) i128 {
16 return intFromFloat(i128, a);197 return intFromFloat(i128, a);
17}198}
18199
19fn __fixhfdi(a: f16) callconv(.c) i64 {200fn __fixdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void {
201 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
202 return signed_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a));
203}
204pub fn signed_intFromFloat_f64(result: []u8, a: f64) void {
205 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
206}
207
208fn __fixxfsi(a: compiler_rt.f80.Abi) callconv(.c) i32 {
209 return i32_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
210}
211pub fn i32_intFromFloat_f80(a: f80) i32 {
212 return intFromFloat(i32, a);
213}
214
215fn __fixxfdi(a: compiler_rt.f80.Abi) callconv(.c) i64 {
216 return i64_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
217}
218pub fn i64_intFromFloat_f80(a: f80) i64 {
20 return intFromFloat(i64, a);219 return intFromFloat(i64, a);
21}220}
22221
23fn __fixhfsi(a: f16) callconv(.c) i32 {222fn __fixxfti(a: compiler_rt.f80.Abi) callconv(.c) i128 {
223 return i128_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
224}
225pub fn i128_intFromFloat_f80(a: f80) i128 {
226 return intFromFloat(i128, a);
227}
228
229fn __fixxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void {
230 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
231 return signed_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a));
232}
233pub fn signed_intFromFloat_f80(result: []u8, a: f80) void {
234 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
235}
236
237fn __fixtfsi(a: compiler_rt.f128.Abi) callconv(.c) i32 {
238 return i32_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
239}
240fn _Qp_qtoi(a: *const f128) callconv(.c) i32 {
241 return i32_intFromFloat_f128(a.*);
242}
243pub fn i32_intFromFloat_f128(a: f128) i32 {
24 return intFromFloat(i32, a);244 return intFromFloat(i32, a);
25}245}
26246
27pub fn __fixxfti(a: f80) callconv(.c) i128 {247fn __fixtfdi(a: compiler_rt.f128.Abi) callconv(.c) i64 {
248 return i64_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
249}
250fn _Qp_qtox(a: *const f128) callconv(.c) i64 {
251 return i64_intFromFloat_f128(a.*);
252}
253pub fn i64_intFromFloat_f128(a: f128) i64 {
254 return intFromFloat(i64, a);
255}
256
257fn __fixtfti(a: compiler_rt.f128.Abi) callconv(.c) i128 {
258 return i128_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
259}
260pub fn i128_intFromFloat_f128(a: f128) i128 {
28 return intFromFloat(i128, a);261 return intFromFloat(i128, a);
29}262}
30263
31pub inline fn intFromFloat(comptime I: type, a: anytype) I {264fn __fixtfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void {
265 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
266 return signed_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a));
267}
268pub fn signed_intFromFloat_f128(result: []u8, a: f128) void {
269 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
270}
271
272comptime {
273 symbol(&__fixunshfsi, "__fixunshfsi");
274 symbol(&__fixunshfdi, "__fixunshfdi");
275 symbol(&__fixunshfti, "__fixunshfti");
276 symbol(&__fixunshfei, "__fixunshfei");
277
278 if (compiler_rt.want_aeabi) {
279 symbol(&__aeabi_f2uiz, "__aeabi_f2uiz");
280 symbol(&__aeabi_f2ulz, "__aeabi_f2ulz");
281 symbol(&__aeabi_fixunssfti, "__fixunssfti");
282 } else {
283 symbol(&__fixunssfsi, "__fixunssfsi");
284 symbol(&__fixunssfdi, "__fixunssfdi");
285 if (compiler_rt.want_windows_arm_abi) symbol(&__fixunssfdi, "__stou64");
286 symbol(&__fixunssfti, "__fixunssfti");
287 }
288 symbol(&__fixunssfei, "__fixunssfei");
289
290 if (compiler_rt.want_aeabi) {
291 symbol(&__aeabi_d2uiz, "__aeabi_d2uiz");
292 symbol(&__aeabi_d2ulz, "__aeabi_d2ulz");
293 symbol(&__aeabi_fixunsdfti, "__fixunsdfti");
294 } else {
295 symbol(&__fixunsdfsi, "__fixunsdfsi");
296 symbol(&__fixunsdfdi, "__fixunsdfdi");
297 if (compiler_rt.want_windows_arm_abi) symbol(&__fixunsdfdi, "__dtou64");
298 symbol(&__fixunsdfti, "__fixunsdfti");
299 }
300 symbol(&__fixunsdfei, "__fixunsdfei");
301
302 symbol(&__fixunsxfsi, "__fixunsxfsi");
303 symbol(&__fixunsxfdi, "__fixunsxfdi");
304 symbol(&__fixunsxfti, "__fixunsxfti");
305 symbol(&__fixunsxfei, "__fixunsxfei");
306
307 if (compiler_rt.want_ppc_abi) {
308 symbol(&__fixunstfsi, "__fixunskfsi");
309 symbol(&__fixunstfdi, "__fixunskfdi");
310 } else if (compiler_rt.want_sparc64_abi) {
311 symbol(&_Qp_qtoui, "_Qp_qtoui");
312 symbol(&_Qp_qtoux, "_Qp_qtoux");
313 } else if (compiler_rt.want_sparc32_abi) {
314 symbol(&__fixunstfsi, "_Q_qtou");
315 symbol(&__fixunstfdi, "_Q_qtoull");
316 } else {
317 symbol(&__fixunstfsi, "__fixunstfsi");
318 symbol(&__fixunstfdi, "__fixunstfdi");
319 }
320 if (compiler_rt.want_ppc_abi) {
321 symbol(&__fixunstfti, "__fixunskfti");
322 symbol(&__fixunstfei, "__fixunskfei");
323 } else {
324 symbol(&__fixunstfti, "__fixunstfti");
325 symbol(&__fixunstfei, "__fixunstfei");
326 }
327}
328
329fn __fixunshfsi(a: compiler_rt.f16.Abi) callconv(.c) u32 {
330 return u32_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
331}
332pub fn u32_intFromFloat_f16(a: f16) u32 {
333 return intFromFloat(u32, a);
334}
335
336fn __fixunshfdi(a: compiler_rt.f16.Abi) callconv(.c) u64 {
337 return u64_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
338}
339pub fn u64_intFromFloat_f16(a: f16) u64 {
340 return intFromFloat(u64, a);
341}
342
343fn __fixunshfti(a: compiler_rt.f16.Abi) callconv(.c) u128 {
344 return u128_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
345}
346pub fn u128_intFromFloat_f16(a: f16) u128 {
347 return intFromFloat(u128, a);
348}
349
350fn __fixunshfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void {
351 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
352 return unsigned_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a));
353}
354pub fn unsigned_intFromFloat_f16(result: []u8, a: f16) void {
355 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
356}
357
358fn __fixunssfsi(a: compiler_rt.f32.Abi) callconv(.c) u32 {
359 return u32_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
360}
361fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 {
362 return u32_intFromFloat_f32(a);
363}
364pub fn u32_intFromFloat_f32(a: f32) u32 {
365 return intFromFloat(u32, a);
366}
367
368fn __fixunssfdi(a: compiler_rt.f32.Abi) callconv(.c) u64 {
369 return u64_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
370}
371fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 {
372 return u64_intFromFloat_f32(a);
373}
374pub fn u64_intFromFloat_f32(a: f32) u64 {
375 return intFromFloat(u64, a);
376}
377
378fn __fixunssfti(a: compiler_rt.f32.Abi) callconv(.c) u128 {
379 return u128_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
380}
381fn __aeabi_fixunssfti(_: compiler_rt.f32.Abi) callconv(.naked) u128 {
382 switch (builtin.abi.float()) {
383 .soft => asm volatile (
384 \\ push {r0-r4, lr}
385 \\ mov r1, r0
386 \\ mov r0, sp
387 \\ bl %[__fixunssfti]
388 \\ pop {r0-r4, pc}
389 :
390 : [__fixunssfti] "X" (&__fixunssfti),
391 ),
392 .hard => asm volatile (
393 \\ push {r0-r4, lr}
394 \\ mov r0, sp
395 \\ bl %[__fixunssfti]
396 \\ pop {r0-r4, pc}
397 :
398 : [__fixunssfti] "X" (&__fixunssfti),
399 ),
400 }
401}
402pub fn u128_intFromFloat_f32(a: f32) u128 {
403 return intFromFloat(u128, a);
404}
405
406fn __fixunssfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void {
407 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
408 return unsigned_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a));
409}
410pub fn unsigned_intFromFloat_f32(result: []u8, a: f32) void {
411 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
412}
413
414fn __fixunsdfsi(a: compiler_rt.f64.Abi) callconv(.c) u32 {
415 return u32_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
416}
417fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 {
418 return u32_intFromFloat_f64(a);
419}
420pub fn u32_intFromFloat_f64(a: f64) u32 {
421 return intFromFloat(u32, a);
422}
423
424fn __fixunsdfdi(a: compiler_rt.f64.Abi) callconv(.c) u64 {
425 return u64_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
426}
427fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 {
428 return u64_intFromFloat_f64(a);
429}
430pub fn u64_intFromFloat_f64(a: f64) u64 {
431 return intFromFloat(u64, a);
432}
433
434fn __fixunsdfti(a: compiler_rt.f64.Abi) callconv(.c) u128 {
435 return u128_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
436}
437fn __aeabi_fixunsdfti(_: compiler_rt.f64.Abi) callconv(.naked) u128 {
438 switch (builtin.abi.float()) {
439 .soft => asm volatile (
440 \\ push {r0-r4, lr}
441 \\ mov r3, r1
442 \\ mov r2, r0
443 \\ mov r0, sp
444 \\ bl %[__fixunsdfti]
445 \\ pop {r0-r4, pc}
446 :
447 : [__fixunsdfti] "X" (&__fixunsdfti),
448 ),
449 .hard => asm volatile (
450 \\ push {r0-r4, lr}
451 \\ mov r0, sp
452 \\ bl %[__fixunsdfti]
453 \\ pop {r0-r4, pc}
454 :
455 : [__fixunsdfti] "X" (&__fixunsdfti),
456 ),
457 }
458}
459pub fn u128_intFromFloat_f64(a: f64) u128 {
460 return intFromFloat(u128, a);
461}
462
463fn __fixunsdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void {
464 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
465 return unsigned_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a));
466}
467pub fn unsigned_intFromFloat_f64(result: []u8, a: f64) void {
468 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
469}
470
471fn __fixunsxfsi(a: compiler_rt.f80.Abi) callconv(.c) u32 {
472 return u32_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
473}
474pub fn u32_intFromFloat_f80(a: f80) u32 {
475 return intFromFloat(u32, a);
476}
477
478fn __fixunsxfdi(a: compiler_rt.f80.Abi) callconv(.c) u64 {
479 return u64_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
480}
481pub fn u64_intFromFloat_f80(a: f80) u64 {
482 return intFromFloat(u64, a);
483}
484
485fn __fixunsxfti(a: compiler_rt.f80.Abi) callconv(.c) u128 {
486 return u128_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
487}
488pub fn u128_intFromFloat_f80(a: f80) u128 {
489 return intFromFloat(u128, a);
490}
491
492fn __fixunsxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void {
493 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
494 return unsigned_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a));
495}
496pub fn unsigned_intFromFloat_f80(result: []u8, a: f80) void {
497 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
498}
499
500fn __fixunstfsi(a: compiler_rt.f128.Abi) callconv(.c) u32 {
501 return u32_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
502}
503fn _Qp_qtoui(a: *const f128) callconv(.c) u32 {
504 return u32_intFromFloat_f128(a.*);
505}
506pub fn u32_intFromFloat_f128(a: f128) u32 {
507 return intFromFloat(u32, a);
508}
509
510fn __fixunstfdi(a: compiler_rt.f128.Abi) callconv(.c) u64 {
511 return u64_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
512}
513fn _Qp_qtoux(a: *const f128) callconv(.c) u64 {
514 return u64_intFromFloat_f128(a.*);
515}
516pub fn u64_intFromFloat_f128(a: f128) u64 {
517 return intFromFloat(u64, a);
518}
519
520fn __fixunstfti(a: compiler_rt.f128.Abi) callconv(.c) u128 {
521 return u128_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
522}
523pub fn u128_intFromFloat_f128(a: f128) u128 {
524 return intFromFloat(u128, a);
525}
526
527fn __fixunstfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void {
528 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
529 return unsigned_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a));
530}
531pub fn unsigned_intFromFloat_f128(result: []u8, a: f128) void {
532 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
533}
534
535inline fn intFromFloat(comptime I: type, a: anytype) I {
32 const F = @TypeOf(a);536 const F = @TypeOf(a);
33 const float_bits = @typeInfo(F).float.bits;537 const float_bits = @typeInfo(F).float.bits;
34 const int_bits = @typeInfo(I).int.bits;538 const int_bits = @typeInfo(I).int.bits;
...@@ -76,13 +580,14 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {...@@ -76,13 +580,14 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {
76 return result;580 return result;
77}581}
78582
79pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void {583inline fn bigIntFromFloat(comptime signedness: std.lang.Signedness, result: []u32, a: anytype) void {
584 const endian = builtin.cpu.arch.endian();
80 switch (result.len) {585 switch (result.len) {
81 0 => return,586 0 => return,
82 inline 1...4 => |limbs_len| {587 inline 1...4 => |limbs_len| {
83 const I = @Int(signedness, 32 * limbs_len);588 const I = @Int(signedness, 32 * limbs_len);
84 const low_to_high: [limbs_len]u32 = @bitCast(@as(I, @intFromFloat(a)));589 const low_to_high: [limbs_len]u32 = @bitCast(@as(I, @intFromFloat(a)));
85 result[0..limbs_len].* = switch (@import("builtin").cpu.arch.endian()) {590 result[0..limbs_len].* = switch (endian) {
86 .little => low_to_high,591 .little => low_to_high,
87 .big => switch (limbs_len) {592 .big => switch (limbs_len) {
88 1 => .{low_to_high[0]},593 1 => .{low_to_high[0]},
...@@ -111,7 +616,6 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul...@@ -111,7 +616,6 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul
111 });616 });
112 switch (signedness) {617 switch (signedness) {
113 .signed => {618 .signed => {
114 const endian = @import("builtin").cpu.arch.endian();
115 const exponent_limb = switch (endian) {619 const exponent_limb = switch (endian) {
116 .little => exponent / 32,620 .little => exponent / 32,
117 .big => result.len - 1 - exponent / 32,621 .big => result.len - 1 - exponent / 32,
lib/compiler_rt/int_from_float_test.zig+913-897
...@@ -2,1023 +2,1039 @@ const std = @import("std");...@@ -2,1023 +2,1039 @@ const std = @import("std");
2const testing = std.testing;2const testing = std.testing;
3const math = std.math;3const math = std.math;
44
5const __fixunshfti = @import("fixunshfti.zig").__fixunshfti;5const impl = @import("int_from_float.zig");
6const __fixunsxfti = @import("fixunsxfti.zig").__fixunsxfti;6
77const i32_intFromFloat_f16 = impl.i32_intFromFloat_f16;
8// Conversion from f328const u32_intFromFloat_f16 = impl.u32_intFromFloat_f16;
9const __fixsfsi = @import("fixsfsi.zig").__fixsfsi;9const i64_intFromFloat_f16 = impl.i64_intFromFloat_f16;
10const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi;10const u64_intFromFloat_f16 = impl.u64_intFromFloat_f16;
11const __fixsfdi = @import("fixsfdi.zig").__fixsfdi;11const i128_intFromFloat_f16 = impl.i128_intFromFloat_f16;
12const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi;12const u128_intFromFloat_f16 = impl.u128_intFromFloat_f16;
13const __fixsfti = @import("fixsfti.zig").__fixsfti;13const signed_intFromFloat_f16 = impl.signed_intFromFloat_f16;
14const __fixunssfti = @import("fixunssfti.zig").__fixunssfti;14const unsigned_intFromFloat_f16 = impl.unsigned_intFromFloat_f16;
15const __fixsfei = @import("fixsfei.zig").__fixsfei;15
16const __fixunssfei = @import("fixunssfei.zig").__fixunssfei;16const i32_intFromFloat_f32 = impl.i32_intFromFloat_f32;
1717const u32_intFromFloat_f32 = impl.u32_intFromFloat_f32;
18// Conversion from f6418const i64_intFromFloat_f32 = impl.i64_intFromFloat_f32;
19const __fixdfsi = @import("fixdfsi.zig").__fixdfsi;19const u64_intFromFloat_f32 = impl.u64_intFromFloat_f32;
20const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi;20const i128_intFromFloat_f32 = impl.i128_intFromFloat_f32;
21const __fixdfdi = @import("fixdfdi.zig").__fixdfdi;21const u128_intFromFloat_f32 = impl.u128_intFromFloat_f32;
22const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi;22const signed_intFromFloat_f32 = impl.signed_intFromFloat_f32;
23const __fixdfti = @import("fixdfti.zig").__fixdfti;23const unsigned_intFromFloat_f32 = impl.unsigned_intFromFloat_f32;
24const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti;24
25const __fixdfei = @import("fixdfei.zig").__fixdfei;25const i32_intFromFloat_f64 = impl.i32_intFromFloat_f64;
26const __fixunsdfei = @import("fixunsdfei.zig").__fixunsdfei;26const u32_intFromFloat_f64 = impl.u32_intFromFloat_f64;
2727const i64_intFromFloat_f64 = impl.i64_intFromFloat_f64;
28// Conversion from f12828const u64_intFromFloat_f64 = impl.u64_intFromFloat_f64;
29const __fixtfsi = @import("fixtfsi.zig").__fixtfsi;29const i128_intFromFloat_f64 = impl.i128_intFromFloat_f64;
30const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi;30const u128_intFromFloat_f64 = impl.u128_intFromFloat_f64;
31const __fixtfdi = @import("fixtfdi.zig").__fixtfdi;31const signed_intFromFloat_f64 = impl.signed_intFromFloat_f64;
32const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi;32const unsigned_intFromFloat_f64 = impl.unsigned_intFromFloat_f64;
33const __fixtfti = @import("fixtfti.zig").__fixtfti;33
34const __fixunstfti = @import("fixunstfti.zig").__fixunstfti;34const i32_intFromFloat_f80 = impl.i32_intFromFloat_f80;
3535const u32_intFromFloat_f80 = impl.u32_intFromFloat_f80;
36fn test__fixsfsi(a: f32, expected: i32) !void {36const i64_intFromFloat_f80 = impl.i64_intFromFloat_f80;
37 const x = __fixsfsi(a);37const u64_intFromFloat_f80 = impl.u64_intFromFloat_f80;
38const i128_intFromFloat_f80 = impl.i128_intFromFloat_f80;
39const u128_intFromFloat_f80 = impl.u128_intFromFloat_f80;
40const signed_intFromFloat_f80 = impl.signed_intFromFloat_f80;
41const unsigned_intFromFloat_f80 = impl.unsigned_intFromFloat_f80;
42
43const i32_intFromFloat_f128 = impl.i32_intFromFloat_f128;
44const u32_intFromFloat_f128 = impl.u32_intFromFloat_f128;
45const i64_intFromFloat_f128 = impl.i64_intFromFloat_f128;
46const u64_intFromFloat_f128 = impl.u64_intFromFloat_f128;
47const i128_intFromFloat_f128 = impl.i128_intFromFloat_f128;
48const u128_intFromFloat_f128 = impl.u128_intFromFloat_f128;
49const signed_intFromFloat_f128 = impl.signed_intFromFloat_f128;
50const unsigned_intFromFloat_f128 = impl.unsigned_intFromFloat_f128;
51
52fn test_i32_intFromFloat_f32(a: f32, expected: i32) !void {
53 const x = i32_intFromFloat_f32(a);
38 try testing.expect(x == expected);54 try testing.expect(x == expected);
39}55}
4056
41fn test__fixunssfsi(a: f32, expected: u32) !void {57fn test_u32_intFromFloat_f32(a: f32, expected: u32) !void {
42 const x = __fixunssfsi(a);58 const x = u32_intFromFloat_f32(a);
43 try testing.expect(x == expected);59 try testing.expect(x == expected);
44}60}
4561
46test "fixsfsi" {62test i32_intFromFloat_f32 {
47 try test__fixsfsi(-math.floatMax(f32), math.minInt(i32));63 try test_i32_intFromFloat_f32(-math.floatMax(f32), math.minInt(i32));
4864
49 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));65 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
50 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);66 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
5167
52 try test__fixsfsi(-0x1.0000000000000p+127, -0x80000000);68 try test_i32_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000);
53 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);69 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
54 try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);70 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
5571
56 try test__fixsfsi(-0x1.0000000000001p+63, -0x80000000);72 try test_i32_intFromFloat_f32(-0x1.0000000000001p+63, -0x80000000);
57 try test__fixsfsi(-0x1.0000000000000p+63, -0x80000000);73 try test_i32_intFromFloat_f32(-0x1.0000000000000p+63, -0x80000000);
58 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);74 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
59 try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);75 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
6076
61 try test__fixsfsi(-0x1.FFFFFEp+62, -0x80000000);77 try test_i32_intFromFloat_f32(-0x1.FFFFFEp+62, -0x80000000);
62 try test__fixsfsi(-0x1.FFFFFCp+62, -0x80000000);78 try test_i32_intFromFloat_f32(-0x1.FFFFFCp+62, -0x80000000);
6379
64 try test__fixsfsi(-0x1.000000p+31, -0x80000000);80 try test_i32_intFromFloat_f32(-0x1.000000p+31, -0x80000000);
65 try test__fixsfsi(-0x1.FFFFFFp+30, -0x80000000);81 try test_i32_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000);
66 try test__fixsfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);82 try test_i32_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80);
67 try test__fixsfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);83 try test_i32_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00);
6884
69 try test__fixsfsi(-2.01, -2);85 try test_i32_intFromFloat_f32(-2.01, -2);
70 try test__fixsfsi(-2.0, -2);86 try test_i32_intFromFloat_f32(-2.0, -2);
71 try test__fixsfsi(-1.99, -1);87 try test_i32_intFromFloat_f32(-1.99, -1);
72 try test__fixsfsi(-1.0, -1);88 try test_i32_intFromFloat_f32(-1.0, -1);
73 try test__fixsfsi(-0.99, 0);89 try test_i32_intFromFloat_f32(-0.99, 0);
74 try test__fixsfsi(-0.5, 0);90 try test_i32_intFromFloat_f32(-0.5, 0);
7591
76 try test__fixsfsi(-math.floatMin(f32), 0);92 try test_i32_intFromFloat_f32(-math.floatMin(f32), 0);
77 try test__fixsfsi(0.0, 0);93 try test_i32_intFromFloat_f32(0.0, 0);
78 try test__fixsfsi(math.floatMin(f32), 0);94 try test_i32_intFromFloat_f32(math.floatMin(f32), 0);
79 try test__fixsfsi(0.5, 0);95 try test_i32_intFromFloat_f32(0.5, 0);
80 try test__fixsfsi(0.99, 0);96 try test_i32_intFromFloat_f32(0.99, 0);
81 try test__fixsfsi(1.0, 1);97 try test_i32_intFromFloat_f32(1.0, 1);
82 try test__fixsfsi(1.5, 1);98 try test_i32_intFromFloat_f32(1.5, 1);
83 try test__fixsfsi(1.99, 1);99 try test_i32_intFromFloat_f32(1.99, 1);
84 try test__fixsfsi(2.0, 2);100 try test_i32_intFromFloat_f32(2.0, 2);
85 try test__fixsfsi(2.01, 2);101 try test_i32_intFromFloat_f32(2.01, 2);
86102
87 try test__fixsfsi(0x1.FFFFFCp+30, 0x7FFFFF00);103 try test_i32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00);
88 try test__fixsfsi(0x1.FFFFFEp+30, 0x7FFFFF80);104 try test_i32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80);
89 try test__fixsfsi(0x1.FFFFFFp+30, 0x7FFFFFFF);105 try test_i32_intFromFloat_f32(0x1.FFFFFFp+30, 0x7FFFFFFF);
90 try test__fixsfsi(0x1.000000p+31, 0x7FFFFFFF);106 try test_i32_intFromFloat_f32(0x1.000000p+31, 0x7FFFFFFF);
91107
92 try test__fixsfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);108 try test_i32_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFFFF);
93 try test__fixsfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);109 try test_i32_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFFFF);
94110
95 try test__fixsfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);111 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
96 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);112 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
97 try test__fixsfsi(0x1.0000000000000p+63, 0x7FFFFFFF);113 try test_i32_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFF);
98 try test__fixsfsi(0x1.0000000000001p+63, 0x7FFFFFFF);114 try test_i32_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFF);
99115
100 try test__fixsfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);116 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
101 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);117 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
102 try test__fixsfsi(0x1.0000000000000p+127, 0x7FFFFFFF);118 try test_i32_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFF);
103119
104 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);120 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
105 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));121 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
106122
107 try test__fixsfsi(math.floatMax(f32), math.maxInt(i32));123 try test_i32_intFromFloat_f32(math.floatMax(f32), math.maxInt(i32));
108}124}
109125
110test "fixunssfsi" {126test u32_intFromFloat_f32 {
111 try test__fixunssfsi(0.0, 0);127 try test_u32_intFromFloat_f32(0.0, 0);
112128
113 try test__fixunssfsi(0.5, 0);129 try test_u32_intFromFloat_f32(0.5, 0);
114 try test__fixunssfsi(0.99, 0);130 try test_u32_intFromFloat_f32(0.99, 0);
115 try test__fixunssfsi(1.0, 1);131 try test_u32_intFromFloat_f32(1.0, 1);
116 try test__fixunssfsi(1.5, 1);132 try test_u32_intFromFloat_f32(1.5, 1);
117 try test__fixunssfsi(1.99, 1);133 try test_u32_intFromFloat_f32(1.99, 1);
118 try test__fixunssfsi(2.0, 2);134 try test_u32_intFromFloat_f32(2.0, 2);
119 try test__fixunssfsi(2.01, 2);135 try test_u32_intFromFloat_f32(2.01, 2);
120 try test__fixunssfsi(-0.5, 0);136 try test_u32_intFromFloat_f32(-0.5, 0);
121 try test__fixunssfsi(-0.99, 0);137 try test_u32_intFromFloat_f32(-0.99, 0);
122138
123 try test__fixunssfsi(-1.0, 0);139 try test_u32_intFromFloat_f32(-1.0, 0);
124 try test__fixunssfsi(-1.5, 0);140 try test_u32_intFromFloat_f32(-1.5, 0);
125 try test__fixunssfsi(-1.99, 0);141 try test_u32_intFromFloat_f32(-1.99, 0);
126 try test__fixunssfsi(-2.0, 0);142 try test_u32_intFromFloat_f32(-2.0, 0);
127 try test__fixunssfsi(-2.01, 0);143 try test_u32_intFromFloat_f32(-2.01, 0);
128144
129 try test__fixunssfsi(0x1.000000p+31, 0x80000000);145 try test_u32_intFromFloat_f32(0x1.000000p+31, 0x80000000);
130 try test__fixunssfsi(0x1.000000p+32, 0xFFFFFFFF);146 try test_u32_intFromFloat_f32(0x1.000000p+32, 0xFFFFFFFF);
131 try test__fixunssfsi(0x1.FFFFFEp+31, 0xFFFFFF00);147 try test_u32_intFromFloat_f32(0x1.FFFFFEp+31, 0xFFFFFF00);
132 try test__fixunssfsi(0x1.FFFFFEp+30, 0x7FFFFF80);148 try test_u32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80);
133 try test__fixunssfsi(0x1.FFFFFCp+30, 0x7FFFFF00);149 try test_u32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00);
134150
135 try test__fixunssfsi(-0x1.FFFFFEp+30, 0);151 try test_u32_intFromFloat_f32(-0x1.FFFFFEp+30, 0);
136 try test__fixunssfsi(-0x1.FFFFFCp+30, 0);152 try test_u32_intFromFloat_f32(-0x1.FFFFFCp+30, 0);
137}153}
138154
139fn test__fixsfdi(a: f32, expected: i64) !void {155fn test_i64_intFromFloat_f32(a: f32, expected: i64) !void {
140 const x = __fixsfdi(a);156 const x = i64_intFromFloat_f32(a);
141 try testing.expect(x == expected);157 try testing.expect(x == expected);
142}158}
143159
144fn test__fixunssfdi(a: f32, expected: u64) !void {160fn test_u64_intFromFloat_f32(a: f32, expected: u64) !void {
145 const x = __fixunssfdi(a);161 const x = u64_intFromFloat_f32(a);
146 try testing.expect(x == expected);162 try testing.expect(x == expected);
147}163}
148164
149test "fixsfdi" {165test i64_intFromFloat_f32 {
150 try test__fixsfdi(-math.floatMax(f32), math.minInt(i64));166 try test_i64_intFromFloat_f32(-math.floatMax(f32), math.minInt(i64));
151167
152 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));168 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
153 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);169 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
154170
155 try test__fixsfdi(-0x1.0000000000000p+127, -0x8000000000000000);171 try test_i64_intFromFloat_f32(-0x1.0000000000000p+127, -0x8000000000000000);
156 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);172 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
157 try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);173 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
158174
159 try test__fixsfdi(-0x1.0000000000001p+63, -0x8000000000000000);175 try test_i64_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000);
160 try test__fixsfdi(-0x1.0000000000000p+63, -0x8000000000000000);176 try test_i64_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000);
161 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);177 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
162 try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);178 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
163179
164 try test__fixsfdi(-0x1.FFFFFFp+62, -0x8000000000000000);180 try test_i64_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000);
165 try test__fixsfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);181 try test_i64_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000);
166 try test__fixsfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);182 try test_i64_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000);
167183
168 try test__fixsfdi(-2.01, -2);184 try test_i64_intFromFloat_f32(-2.01, -2);
169 try test__fixsfdi(-2.0, -2);185 try test_i64_intFromFloat_f32(-2.0, -2);
170 try test__fixsfdi(-1.99, -1);186 try test_i64_intFromFloat_f32(-1.99, -1);
171 try test__fixsfdi(-1.0, -1);187 try test_i64_intFromFloat_f32(-1.0, -1);
172 try test__fixsfdi(-0.99, 0);188 try test_i64_intFromFloat_f32(-0.99, 0);
173 try test__fixsfdi(-0.5, 0);189 try test_i64_intFromFloat_f32(-0.5, 0);
174 try test__fixsfdi(-math.floatMin(f32), 0);190 try test_i64_intFromFloat_f32(-math.floatMin(f32), 0);
175 try test__fixsfdi(0.0, 0);191 try test_i64_intFromFloat_f32(0.0, 0);
176 try test__fixsfdi(math.floatMin(f32), 0);192 try test_i64_intFromFloat_f32(math.floatMin(f32), 0);
177 try test__fixsfdi(0.5, 0);193 try test_i64_intFromFloat_f32(0.5, 0);
178 try test__fixsfdi(0.99, 0);194 try test_i64_intFromFloat_f32(0.99, 0);
179 try test__fixsfdi(1.0, 1);195 try test_i64_intFromFloat_f32(1.0, 1);
180 try test__fixsfdi(1.5, 1);196 try test_i64_intFromFloat_f32(1.5, 1);
181 try test__fixsfdi(1.99, 1);197 try test_i64_intFromFloat_f32(1.99, 1);
182 try test__fixsfdi(2.0, 2);198 try test_i64_intFromFloat_f32(2.0, 2);
183 try test__fixsfdi(2.01, 2);199 try test_i64_intFromFloat_f32(2.01, 2);
184200
185 try test__fixsfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);201 try test_i64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
186 try test__fixsfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);202 try test_i64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
187 try test__fixsfdi(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF);203 try test_i64_intFromFloat_f32(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
188204
189 try test__fixsfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF);205 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF);
190 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF);206 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
191 try test__fixsfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);207 try test_i64_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
192 try test__fixsfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);208 try test_i64_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
193209
194 try test__fixsfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);210 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
195 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);211 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
196 try test__fixsfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);212 try test_i64_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
197213
198 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);214 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
199 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));215 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
200216
201 try test__fixsfdi(math.floatMax(f32), math.maxInt(i64));217 try test_i64_intFromFloat_f32(math.floatMax(f32), math.maxInt(i64));
202}218}
203219
204test "fixunssfdi" {220test u64_intFromFloat_f32 {
205 try test__fixunssfdi(0.0, 0);221 try test_u64_intFromFloat_f32(0.0, 0);
206222
207 try test__fixunssfdi(0.5, 0);223 try test_u64_intFromFloat_f32(0.5, 0);
208 try test__fixunssfdi(0.99, 0);224 try test_u64_intFromFloat_f32(0.99, 0);
209 try test__fixunssfdi(1.0, 1);225 try test_u64_intFromFloat_f32(1.0, 1);
210 try test__fixunssfdi(1.5, 1);226 try test_u64_intFromFloat_f32(1.5, 1);
211 try test__fixunssfdi(1.99, 1);227 try test_u64_intFromFloat_f32(1.99, 1);
212 try test__fixunssfdi(2.0, 2);228 try test_u64_intFromFloat_f32(2.0, 2);
213 try test__fixunssfdi(2.01, 2);229 try test_u64_intFromFloat_f32(2.01, 2);
214 try test__fixunssfdi(-0.5, 0);230 try test_u64_intFromFloat_f32(-0.5, 0);
215 try test__fixunssfdi(-0.99, 0);231 try test_u64_intFromFloat_f32(-0.99, 0);
216232
217 try test__fixunssfdi(-1.0, 0);233 try test_u64_intFromFloat_f32(-1.0, 0);
218 try test__fixunssfdi(-1.5, 0);234 try test_u64_intFromFloat_f32(-1.5, 0);
219 try test__fixunssfdi(-1.99, 0);235 try test_u64_intFromFloat_f32(-1.99, 0);
220 try test__fixunssfdi(-2.0, 0);236 try test_u64_intFromFloat_f32(-2.0, 0);
221 try test__fixunssfdi(-2.01, 0);237 try test_u64_intFromFloat_f32(-2.01, 0);
222238
223 try test__fixunssfdi(0x1.FFFFFEp+63, 0xFFFFFF0000000000);239 try test_u64_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000);
224 try test__fixunssfdi(0x1.000000p+63, 0x8000000000000000);240 try test_u64_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000);
225 try test__fixunssfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);241 try test_u64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
226 try test__fixunssfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);242 try test_u64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
227243
228 try test__fixunssfdi(-0x1.FFFFFEp+62, 0x0000000000000000);244 try test_u64_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000);
229 try test__fixunssfdi(-0x1.FFFFFCp+62, 0x0000000000000000);245 try test_u64_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000);
230}246}
231247
232fn test__fixsfti(a: f32, expected: i128) !void {248fn test_i128_intFromFloat_f32(a: f32, expected: i128) !void {
233 const x = __fixsfti(a);249 const x = i128_intFromFloat_f32(a);
234 try testing.expect(x == expected);250 try testing.expect(x == expected);
235}251}
236252
237fn test__fixunssfti(a: f32, expected: u128) !void {253fn test_u128_intFromFloat_f32(a: f32, expected: u128) !void {
238 const x = __fixunssfti(a);254 const x = u128_intFromFloat_f32(a);
239 try testing.expect(x == expected);255 try testing.expect(x == expected);
240}256}
241257
242test "fixsfti" {258test i128_intFromFloat_f32 {
243 try test__fixsfti(-math.floatMax(f32), math.minInt(i128));259 try test_i128_intFromFloat_f32(-math.floatMax(f32), math.minInt(i128));
244260
245 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));261 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
246 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);262 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
247263
248 try test__fixsfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);264 try test_i128_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
249 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000);265 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000);
250 try test__fixsfti(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000);266 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000);
251 try test__fixsfti(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000);267 try test_i128_intFromFloat_f32(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000);
252 try test__fixsfti(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000);268 try test_i128_intFromFloat_f32(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000);
253 try test__fixsfti(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000);269 try test_i128_intFromFloat_f32(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000);
254270
255 try test__fixsfti(-0x1.0000000000001p+63, -0x8000000000000000);271 try test_i128_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000);
256 try test__fixsfti(-0x1.0000000000000p+63, -0x8000000000000000);272 try test_i128_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000);
257 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);273 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
258 try test__fixsfti(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);274 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
259275
260 try test__fixsfti(-0x1.FFFFFFp+62, -0x8000000000000000);276 try test_i128_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000);
261 try test__fixsfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);277 try test_i128_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000);
262 try test__fixsfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);278 try test_i128_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000);
263279
264 try test__fixsfti(-0x1.000000p+31, -0x80000000);280 try test_i128_intFromFloat_f32(-0x1.000000p+31, -0x80000000);
265 try test__fixsfti(-0x1.FFFFFFp+30, -0x80000000);281 try test_i128_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000);
266 try test__fixsfti(-0x1.FFFFFEp+30, -0x7FFFFF80);282 try test_i128_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80);
267 try test__fixsfti(-0x1.FFFFFCp+30, -0x7FFFFF00);283 try test_i128_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00);
268284
269 try test__fixsfti(-2.01, -2);285 try test_i128_intFromFloat_f32(-2.01, -2);
270 try test__fixsfti(-2.0, -2);286 try test_i128_intFromFloat_f32(-2.0, -2);
271 try test__fixsfti(-1.99, -1);287 try test_i128_intFromFloat_f32(-1.99, -1);
272 try test__fixsfti(-1.0, -1);288 try test_i128_intFromFloat_f32(-1.0, -1);
273 try test__fixsfti(-0.99, 0);289 try test_i128_intFromFloat_f32(-0.99, 0);
274 try test__fixsfti(-0.5, 0);290 try test_i128_intFromFloat_f32(-0.5, 0);
275 try test__fixsfti(-math.floatMin(f32), 0);291 try test_i128_intFromFloat_f32(-math.floatMin(f32), 0);
276 try test__fixsfti(0.0, 0);292 try test_i128_intFromFloat_f32(0.0, 0);
277 try test__fixsfti(math.floatMin(f32), 0);293 try test_i128_intFromFloat_f32(math.floatMin(f32), 0);
278 try test__fixsfti(0.5, 0);294 try test_i128_intFromFloat_f32(0.5, 0);
279 try test__fixsfti(0.99, 0);295 try test_i128_intFromFloat_f32(0.99, 0);
280 try test__fixsfti(1.0, 1);296 try test_i128_intFromFloat_f32(1.0, 1);
281 try test__fixsfti(1.5, 1);297 try test_i128_intFromFloat_f32(1.5, 1);
282 try test__fixsfti(1.99, 1);298 try test_i128_intFromFloat_f32(1.99, 1);
283 try test__fixsfti(2.0, 2);299 try test_i128_intFromFloat_f32(2.0, 2);
284 try test__fixsfti(2.01, 2);300 try test_i128_intFromFloat_f32(2.01, 2);
285301
286 try test__fixsfti(0x1.FFFFFCp+30, 0x7FFFFF00);302 try test_i128_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00);
287 try test__fixsfti(0x1.FFFFFEp+30, 0x7FFFFF80);303 try test_i128_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80);
288 try test__fixsfti(0x1.FFFFFFp+30, 0x80000000);304 try test_i128_intFromFloat_f32(0x1.FFFFFFp+30, 0x80000000);
289 try test__fixsfti(0x1.000000p+31, 0x80000000);305 try test_i128_intFromFloat_f32(0x1.000000p+31, 0x80000000);
290306
291 try test__fixsfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);307 try test_i128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
292 try test__fixsfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);308 try test_i128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
293 try test__fixsfti(0x1.FFFFFFp+62, 0x8000000000000000);309 try test_i128_intFromFloat_f32(0x1.FFFFFFp+62, 0x8000000000000000);
294310
295 try test__fixsfti(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000);311 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000);
296 try test__fixsfti(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000);312 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000);
297 try test__fixsfti(0x1.0000000000000p+63, 0x8000000000000000);313 try test_i128_intFromFloat_f32(0x1.0000000000000p+63, 0x8000000000000000);
298 try test__fixsfti(0x1.0000000000001p+63, 0x8000000000000000);314 try test_i128_intFromFloat_f32(0x1.0000000000001p+63, 0x8000000000000000);
299315
300 try test__fixsfti(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000);316 try test_i128_intFromFloat_f32(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000);
301 try test__fixsfti(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000);317 try test_i128_intFromFloat_f32(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000);
302 try test__fixsfti(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);318 try test_i128_intFromFloat_f32(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
303 try test__fixsfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);319 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
304 try test__fixsfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);320 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
305 try test__fixsfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);321 try test_i128_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
306322
307 try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);323 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
308 try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));324 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
309325
310 try test__fixsfti(math.floatMax(f32), math.maxInt(i128));326 try test_i128_intFromFloat_f32(math.floatMax(f32), math.maxInt(i128));
311}327}
312328
313test "fixunssfti" {329test u128_intFromFloat_f32 {
314 try test__fixunssfti(0.0, 0);330 try test_u128_intFromFloat_f32(0.0, 0);
315331
316 try test__fixunssfti(0.5, 0);332 try test_u128_intFromFloat_f32(0.5, 0);
317 try test__fixunssfti(0.99, 0);333 try test_u128_intFromFloat_f32(0.99, 0);
318 try test__fixunssfti(1.0, 1);334 try test_u128_intFromFloat_f32(1.0, 1);
319 try test__fixunssfti(1.5, 1);335 try test_u128_intFromFloat_f32(1.5, 1);
320 try test__fixunssfti(1.99, 1);336 try test_u128_intFromFloat_f32(1.99, 1);
321 try test__fixunssfti(2.0, 2);337 try test_u128_intFromFloat_f32(2.0, 2);
322 try test__fixunssfti(2.01, 2);338 try test_u128_intFromFloat_f32(2.01, 2);
323 try test__fixunssfti(-0.5, 0);339 try test_u128_intFromFloat_f32(-0.5, 0);
324 try test__fixunssfti(-0.99, 0);340 try test_u128_intFromFloat_f32(-0.99, 0);
325341
326 try test__fixunssfti(-1.0, 0);342 try test_u128_intFromFloat_f32(-1.0, 0);
327 try test__fixunssfti(-1.5, 0);343 try test_u128_intFromFloat_f32(-1.5, 0);
328 try test__fixunssfti(-1.99, 0);344 try test_u128_intFromFloat_f32(-1.99, 0);
329 try test__fixunssfti(-2.0, 0);345 try test_u128_intFromFloat_f32(-2.0, 0);
330 try test__fixunssfti(-2.01, 0);346 try test_u128_intFromFloat_f32(-2.01, 0);
331347
332 try test__fixunssfti(0x1.FFFFFEp+63, 0xFFFFFF0000000000);348 try test_u128_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000);
333 try test__fixunssfti(0x1.000000p+63, 0x8000000000000000);349 try test_u128_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000);
334 try test__fixunssfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);350 try test_u128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
335 try test__fixunssfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);351 try test_u128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
336 try test__fixunssfti(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000);352 try test_u128_intFromFloat_f32(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000);
337 try test__fixunssfti(0x1.000000p+127, 0x80000000000000000000000000000000);353 try test_u128_intFromFloat_f32(0x1.000000p+127, 0x80000000000000000000000000000000);
338 try test__fixunssfti(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000);354 try test_u128_intFromFloat_f32(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000);
339 try test__fixunssfti(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000);355 try test_u128_intFromFloat_f32(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000);
340356
341 try test__fixunssfti(-0x1.FFFFFEp+62, 0x0000000000000000);357 try test_u128_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000);
342 try test__fixunssfti(-0x1.FFFFFCp+62, 0x0000000000000000);358 try test_u128_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000);
343 try test__fixunssfti(-0x1.FFFFFEp+126, 0x0000000000000000);359 try test_u128_intFromFloat_f32(-0x1.FFFFFEp+126, 0x0000000000000000);
344 try test__fixunssfti(-0x1.FFFFFCp+126, 0x0000000000000000);360 try test_u128_intFromFloat_f32(-0x1.FFFFFCp+126, 0x0000000000000000);
345 try test__fixunssfti(math.floatMax(f32), 0xffffff00000000000000000000000000);361 try test_u128_intFromFloat_f32(math.floatMax(f32), 0xffffff00000000000000000000000000);
346 try test__fixunssfti(math.inf(f32), math.maxInt(u128));362 try test_u128_intFromFloat_f32(math.inf(f32), math.maxInt(u128));
347}363}
348364
349fn test_fixsfei(comptime T: type, expected: T, a: f32) !void {365fn test_intFromFloat_f32(comptime T: type, expected: T, a: f32) !void {
350 const int = @typeInfo(T).int;366 const int = @typeInfo(T).int;
351 var actual: T = undefined;367 var actual: T = undefined;
352 _ = switch (int.signedness) {368 _ = switch (int.signedness) {
353 .signed => __fixsfei,369 .signed => signed_intFromFloat_f32,
354 .unsigned => __fixunssfei,370 .unsigned => unsigned_intFromFloat_f32,
355 }(@ptrCast(&actual), int.bits, a);371 }(@ptrCast(&actual), a);
356 try testing.expect(expected == actual);372 try testing.expect(expected == actual);
357}373}
358374
359test "fixsfei" {375test signed_intFromFloat_f32 {
360 try test_fixsfei(i256, -1 << 127, -0x1p127);376 try test_intFromFloat_f32(i256, -1 << 127, -0x1p127);
361 try test_fixsfei(i256, -1 << 100, -0x1p100);377 try test_intFromFloat_f32(i256, -1 << 100, -0x1p100);
362 try test_fixsfei(i256, -1 << 50, -0x1p50);378 try test_intFromFloat_f32(i256, -1 << 50, -0x1p50);
363 try test_fixsfei(i256, -1 << 1, -0x1p1);379 try test_intFromFloat_f32(i256, -1 << 1, -0x1p1);
364 try test_fixsfei(i256, -1 << 0, -0x1p0);380 try test_intFromFloat_f32(i256, -1 << 0, -0x1p0);
365 try test_fixsfei(i256, 0, 0);381 try test_intFromFloat_f32(i256, 0, 0);
366 try test_fixsfei(i256, 1 << 0, 0x1p0);382 try test_intFromFloat_f32(i256, 1 << 0, 0x1p0);
367 try test_fixsfei(i256, 1 << 1, 0x1p1);383 try test_intFromFloat_f32(i256, 1 << 1, 0x1p1);
368 try test_fixsfei(i256, 1 << 50, 0x1p50);384 try test_intFromFloat_f32(i256, 1 << 50, 0x1p50);
369 try test_fixsfei(i256, 1 << 100, 0x1p100);385 try test_intFromFloat_f32(i256, 1 << 100, 0x1p100);
370 try test_fixsfei(i256, 1 << 127, 0x1p127);386 try test_intFromFloat_f32(i256, 1 << 127, 0x1p127);
371}387}
372388
373test "fixunsfei" {389test unsigned_intFromFloat_f32 {
374 try test_fixsfei(u256, 0, 0);390 try test_intFromFloat_f32(u256, 0, 0);
375 try test_fixsfei(u256, 1 << 0, 0x1p0);391 try test_intFromFloat_f32(u256, 1 << 0, 0x1p0);
376 try test_fixsfei(u256, 1 << 1, 0x1p1);392 try test_intFromFloat_f32(u256, 1 << 1, 0x1p1);
377 try test_fixsfei(u256, 1 << 50, 0x1p50);393 try test_intFromFloat_f32(u256, 1 << 50, 0x1p50);
378 try test_fixsfei(u256, 1 << 100, 0x1p100);394 try test_intFromFloat_f32(u256, 1 << 100, 0x1p100);
379 try test_fixsfei(u256, 1 << 127, 0x1p127);395 try test_intFromFloat_f32(u256, 1 << 127, 0x1p127);
380}396}
381397
382fn test__fixdfsi(a: f64, expected: i32) !void {398fn test_i32_intFromFloat_f64(a: f64, expected: i32) !void {
383 const x = __fixdfsi(a);399 const x = i32_intFromFloat_f64(a);
384 try testing.expect(x == expected);400 try testing.expect(x == expected);
385}401}
386402
387fn test__fixunsdfsi(a: f64, expected: u32) !void {403fn test_u32_intFromFloat_f64(a: f64, expected: u32) !void {
388 const x = __fixunsdfsi(a);404 const x = u32_intFromFloat_f64(a);
389 try testing.expect(x == expected);405 try testing.expect(x == expected);
390}406}
391407
392test "fixdfsi" {408test i32_intFromFloat_f64 {
393 try test__fixdfsi(-math.floatMax(f64), math.minInt(i32));409 try test_i32_intFromFloat_f64(-math.floatMax(f64), math.minInt(i32));
394410
395 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));411 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
396 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);412 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
397413
398 try test__fixdfsi(-0x1.0000000000000p+127, -0x80000000);414 try test_i32_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000);
399 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);415 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
400 try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);416 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
401417
402 try test__fixdfsi(-0x1.0000000000001p+63, -0x80000000);418 try test_i32_intFromFloat_f64(-0x1.0000000000001p+63, -0x80000000);
403 try test__fixdfsi(-0x1.0000000000000p+63, -0x80000000);419 try test_i32_intFromFloat_f64(-0x1.0000000000000p+63, -0x80000000);
404 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);420 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
405 try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);421 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
406422
407 try test__fixdfsi(-0x1.FFFFFEp+62, -0x80000000);423 try test_i32_intFromFloat_f64(-0x1.FFFFFEp+62, -0x80000000);
408 try test__fixdfsi(-0x1.FFFFFCp+62, -0x80000000);424 try test_i32_intFromFloat_f64(-0x1.FFFFFCp+62, -0x80000000);
409425
410 try test__fixdfsi(-0x1.000000p+31, -0x80000000);426 try test_i32_intFromFloat_f64(-0x1.000000p+31, -0x80000000);
411 try test__fixdfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);427 try test_i32_intFromFloat_f64(-0x1.FFFFFFp+30, -0x7FFFFFC0);
412 try test__fixdfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);428 try test_i32_intFromFloat_f64(-0x1.FFFFFEp+30, -0x7FFFFF80);
413429
414 try test__fixdfsi(-2.01, -2);430 try test_i32_intFromFloat_f64(-2.01, -2);
415 try test__fixdfsi(-2.0, -2);431 try test_i32_intFromFloat_f64(-2.0, -2);
416 try test__fixdfsi(-1.99, -1);432 try test_i32_intFromFloat_f64(-1.99, -1);
417 try test__fixdfsi(-1.0, -1);433 try test_i32_intFromFloat_f64(-1.0, -1);
418 try test__fixdfsi(-0.99, 0);434 try test_i32_intFromFloat_f64(-0.99, 0);
419 try test__fixdfsi(-0.5, 0);435 try test_i32_intFromFloat_f64(-0.5, 0);
420 try test__fixdfsi(-math.floatMin(f64), 0);436 try test_i32_intFromFloat_f64(-math.floatMin(f64), 0);
421 try test__fixdfsi(0.0, 0);437 try test_i32_intFromFloat_f64(0.0, 0);
422 try test__fixdfsi(math.floatMin(f64), 0);438 try test_i32_intFromFloat_f64(math.floatMin(f64), 0);
423 try test__fixdfsi(0.5, 0);439 try test_i32_intFromFloat_f64(0.5, 0);
424 try test__fixdfsi(0.99, 0);440 try test_i32_intFromFloat_f64(0.99, 0);
425 try test__fixdfsi(1.0, 1);441 try test_i32_intFromFloat_f64(1.0, 1);
426 try test__fixdfsi(1.5, 1);442 try test_i32_intFromFloat_f64(1.5, 1);
427 try test__fixdfsi(1.99, 1);443 try test_i32_intFromFloat_f64(1.99, 1);
428 try test__fixdfsi(2.0, 2);444 try test_i32_intFromFloat_f64(2.0, 2);
429 try test__fixdfsi(2.01, 2);445 try test_i32_intFromFloat_f64(2.01, 2);
430446
431 try test__fixdfsi(0x1.FFFFFEp+30, 0x7FFFFF80);447 try test_i32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80);
432 try test__fixdfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);448 try test_i32_intFromFloat_f64(0x1.FFFFFFp+30, 0x7FFFFFC0);
433 try test__fixdfsi(0x1.000000p+31, 0x7FFFFFFF);449 try test_i32_intFromFloat_f64(0x1.000000p+31, 0x7FFFFFFF);
434450
435 try test__fixdfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);451 try test_i32_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFFFF);
436 try test__fixdfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);452 try test_i32_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFFFF);
437453
438 try test__fixdfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);454 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
439 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);455 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
440 try test__fixdfsi(0x1.0000000000000p+63, 0x7FFFFFFF);456 try test_i32_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFF);
441 try test__fixdfsi(0x1.0000000000001p+63, 0x7FFFFFFF);457 try test_i32_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFF);
442458
443 try test__fixdfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);459 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
444 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);460 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
445 try test__fixdfsi(0x1.0000000000000p+127, 0x7FFFFFFF);461 try test_i32_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFF);
446462
447 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);463 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
448 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));464 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
449465
450 try test__fixdfsi(math.floatMax(f64), math.maxInt(i32));466 try test_i32_intFromFloat_f64(math.floatMax(f64), math.maxInt(i32));
451}467}
452468
453test "fixunsdfsi" {469test u32_intFromFloat_f64 {
454 try test__fixunsdfsi(0.0, 0);470 try test_u32_intFromFloat_f64(0.0, 0);
455471
456 try test__fixunsdfsi(0.5, 0);472 try test_u32_intFromFloat_f64(0.5, 0);
457 try test__fixunsdfsi(0.99, 0);473 try test_u32_intFromFloat_f64(0.99, 0);
458 try test__fixunsdfsi(1.0, 1);474 try test_u32_intFromFloat_f64(1.0, 1);
459 try test__fixunsdfsi(1.5, 1);475 try test_u32_intFromFloat_f64(1.5, 1);
460 try test__fixunsdfsi(1.99, 1);476 try test_u32_intFromFloat_f64(1.99, 1);
461 try test__fixunsdfsi(2.0, 2);477 try test_u32_intFromFloat_f64(2.0, 2);
462 try test__fixunsdfsi(2.01, 2);478 try test_u32_intFromFloat_f64(2.01, 2);
463 try test__fixunsdfsi(-0.5, 0);479 try test_u32_intFromFloat_f64(-0.5, 0);
464 try test__fixunsdfsi(-0.99, 0);480 try test_u32_intFromFloat_f64(-0.99, 0);
465 try test__fixunsdfsi(-1.0, 0);481 try test_u32_intFromFloat_f64(-1.0, 0);
466 try test__fixunsdfsi(-1.5, 0);482 try test_u32_intFromFloat_f64(-1.5, 0);
467 try test__fixunsdfsi(-1.99, 0);483 try test_u32_intFromFloat_f64(-1.99, 0);
468 try test__fixunsdfsi(-2.0, 0);484 try test_u32_intFromFloat_f64(-2.0, 0);
469 try test__fixunsdfsi(-2.01, 0);485 try test_u32_intFromFloat_f64(-2.01, 0);
470486
471 try test__fixunsdfsi(0x1.000000p+31, 0x80000000);487 try test_u32_intFromFloat_f64(0x1.000000p+31, 0x80000000);
472 try test__fixunsdfsi(0x1.000000p+32, 0xFFFFFFFF);488 try test_u32_intFromFloat_f64(0x1.000000p+32, 0xFFFFFFFF);
473 try test__fixunsdfsi(0x1.FFFFFEp+31, 0xFFFFFF00);489 try test_u32_intFromFloat_f64(0x1.FFFFFEp+31, 0xFFFFFF00);
474 try test__fixunsdfsi(0x1.FFFFFEp+30, 0x7FFFFF80);490 try test_u32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80);
475 try test__fixunsdfsi(0x1.FFFFFCp+30, 0x7FFFFF00);491 try test_u32_intFromFloat_f64(0x1.FFFFFCp+30, 0x7FFFFF00);
476492
477 try test__fixunsdfsi(-0x1.FFFFFEp+30, 0);493 try test_u32_intFromFloat_f64(-0x1.FFFFFEp+30, 0);
478 try test__fixunsdfsi(-0x1.FFFFFCp+30, 0);494 try test_u32_intFromFloat_f64(-0x1.FFFFFCp+30, 0);
479495
480 try test__fixunsdfsi(0x1.FFFFFFFEp+31, 0xFFFFFFFF);496 try test_u32_intFromFloat_f64(0x1.FFFFFFFEp+31, 0xFFFFFFFF);
481 try test__fixunsdfsi(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF);497 try test_u32_intFromFloat_f64(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF);
482 try test__fixunsdfsi(0x1.FFFFFFF800000p+30, 0x7FFFFFFE);498 try test_u32_intFromFloat_f64(0x1.FFFFFFF800000p+30, 0x7FFFFFFE);
483}499}
484500
485fn test__fixdfdi(a: f64, expected: i64) !void {501fn test_i64_intFromFloat_f64(a: f64, expected: i64) !void {
486 const x = __fixdfdi(a);502 const x = i64_intFromFloat_f64(a);
487 try testing.expect(x == expected);503 try testing.expect(x == expected);
488}504}
489505
490fn test__fixunsdfdi(a: f64, expected: u64) !void {506fn test_u64_intFromFloat_f64(a: f64, expected: u64) !void {
491 const x = __fixunsdfdi(a);507 const x = u64_intFromFloat_f64(a);
492 try testing.expect(x == expected);508 try testing.expect(x == expected);
493}509}
494510
495test "fixdfdi" {511test i64_intFromFloat_f64 {
496 try test__fixdfdi(-math.floatMax(f64), math.minInt(i64));512 try test_i64_intFromFloat_f64(-math.floatMax(f64), math.minInt(i64));
497513
498 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));514 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
499 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);515 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
500516
501 try test__fixdfdi(-0x1.0000000000000p+127, -0x8000000000000000);517 try test_i64_intFromFloat_f64(-0x1.0000000000000p+127, -0x8000000000000000);
502 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);518 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
503 try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);519 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
504520
505 try test__fixdfdi(-0x1.0000000000001p+63, -0x8000000000000000);521 try test_i64_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000000);
506 try test__fixdfdi(-0x1.0000000000000p+63, -0x8000000000000000);522 try test_i64_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000);
507 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);523 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
508 try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);524 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
509525
510 try test__fixdfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);526 try test_i64_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000);
511 try test__fixdfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);527 try test_i64_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000);
512528
513 try test__fixdfdi(-2.01, -2);529 try test_i64_intFromFloat_f64(-2.01, -2);
514 try test__fixdfdi(-2.0, -2);530 try test_i64_intFromFloat_f64(-2.0, -2);
515 try test__fixdfdi(-1.99, -1);531 try test_i64_intFromFloat_f64(-1.99, -1);
516 try test__fixdfdi(-1.0, -1);532 try test_i64_intFromFloat_f64(-1.0, -1);
517 try test__fixdfdi(-0.99, 0);533 try test_i64_intFromFloat_f64(-0.99, 0);
518 try test__fixdfdi(-0.5, 0);534 try test_i64_intFromFloat_f64(-0.5, 0);
519 try test__fixdfdi(-math.floatMin(f64), 0);535 try test_i64_intFromFloat_f64(-math.floatMin(f64), 0);
520 try test__fixdfdi(0.0, 0);536 try test_i64_intFromFloat_f64(0.0, 0);
521 try test__fixdfdi(math.floatMin(f64), 0);537 try test_i64_intFromFloat_f64(math.floatMin(f64), 0);
522 try test__fixdfdi(0.5, 0);538 try test_i64_intFromFloat_f64(0.5, 0);
523 try test__fixdfdi(0.99, 0);539 try test_i64_intFromFloat_f64(0.99, 0);
524 try test__fixdfdi(1.0, 1);540 try test_i64_intFromFloat_f64(1.0, 1);
525 try test__fixdfdi(1.5, 1);541 try test_i64_intFromFloat_f64(1.5, 1);
526 try test__fixdfdi(1.99, 1);542 try test_i64_intFromFloat_f64(1.99, 1);
527 try test__fixdfdi(2.0, 2);543 try test_i64_intFromFloat_f64(2.0, 2);
528 try test__fixdfdi(2.01, 2);544 try test_i64_intFromFloat_f64(2.01, 2);
529545
530 try test__fixdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);546 try test_i64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
531 try test__fixdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);547 try test_i64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
532548
533 try test__fixdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);549 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
534 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);550 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
535 try test__fixdfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);551 try test_i64_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
536 try test__fixdfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);552 try test_i64_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
537553
538 try test__fixdfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);554 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
539 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);555 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
540 try test__fixdfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);556 try test_i64_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
541557
542 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);558 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
543 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));559 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
544560
545 try test__fixdfdi(math.floatMax(f64), math.maxInt(i64));561 try test_i64_intFromFloat_f64(math.floatMax(f64), math.maxInt(i64));
546}562}
547563
548test "fixunsdfdi" {564test u64_intFromFloat_f64 {
549 try test__fixunsdfdi(0.0, 0);565 try test_u64_intFromFloat_f64(0.0, 0);
550 try test__fixunsdfdi(0.5, 0);566 try test_u64_intFromFloat_f64(0.5, 0);
551 try test__fixunsdfdi(0.99, 0);567 try test_u64_intFromFloat_f64(0.99, 0);
552 try test__fixunsdfdi(1.0, 1);568 try test_u64_intFromFloat_f64(1.0, 1);
553 try test__fixunsdfdi(1.5, 1);569 try test_u64_intFromFloat_f64(1.5, 1);
554 try test__fixunsdfdi(1.99, 1);570 try test_u64_intFromFloat_f64(1.99, 1);
555 try test__fixunsdfdi(2.0, 2);571 try test_u64_intFromFloat_f64(2.0, 2);
556 try test__fixunsdfdi(2.01, 2);572 try test_u64_intFromFloat_f64(2.01, 2);
557 try test__fixunsdfdi(-0.5, 0);573 try test_u64_intFromFloat_f64(-0.5, 0);
558 try test__fixunsdfdi(-0.99, 0);574 try test_u64_intFromFloat_f64(-0.99, 0);
559 try test__fixunsdfdi(-1.0, 0);575 try test_u64_intFromFloat_f64(-1.0, 0);
560 try test__fixunsdfdi(-1.5, 0);576 try test_u64_intFromFloat_f64(-1.5, 0);
561 try test__fixunsdfdi(-1.99, 0);577 try test_u64_intFromFloat_f64(-1.99, 0);
562 try test__fixunsdfdi(-2.0, 0);578 try test_u64_intFromFloat_f64(-2.0, 0);
563 try test__fixunsdfdi(-2.01, 0);579 try test_u64_intFromFloat_f64(-2.01, 0);
564580
565 try test__fixunsdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);581 try test_u64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
566 try test__fixunsdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);582 try test_u64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
567583
568 try test__fixunsdfdi(-0x1.FFFFFEp+62, 0);584 try test_u64_intFromFloat_f64(-0x1.FFFFFEp+62, 0);
569 try test__fixunsdfdi(-0x1.FFFFFCp+62, 0);585 try test_u64_intFromFloat_f64(-0x1.FFFFFCp+62, 0);
570586
571 try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);587 try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);
572 try test__fixunsdfdi(0x1.0000000000000p+63, 0x8000000000000000);588 try test_u64_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000);
573 try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);589 try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
574 try test__fixunsdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);590 try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
575591
576 try test__fixunsdfdi(-0x1.FFFFFFFFFFFFFp+62, 0);592 try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0);
577 try test__fixunsdfdi(-0x1.FFFFFFFFFFFFEp+62, 0);593 try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0);
578}594}
579595
580fn test__fixdfti(a: f64, expected: i128) !void {596fn test_i128_intFromFloat_f64(a: f64, expected: i128) !void {
581 const x = __fixdfti(a);597 const x = i128_intFromFloat_f64(a);
582 try testing.expect(x == expected);598 try testing.expect(x == expected);
583}599}
584600
585fn test__fixunsdfti(a: f64, expected: u128) !void {601fn test_u128_intFromFloat_f64(a: f64, expected: u128) !void {
586 const x = __fixunsdfti(a);602 const x = u128_intFromFloat_f64(a);
587 try testing.expect(x == expected);603 try testing.expect(x == expected);
588}604}
589605
590test "fixdfti" {606test i128_intFromFloat_f64 {
591 try test__fixdfti(-math.floatMax(f64), math.minInt(i128));607 try test_i128_intFromFloat_f64(-math.floatMax(f64), math.minInt(i128));
592608
593 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));609 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
594 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);610 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
595611
596 try test__fixdfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);612 try test_i128_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
597 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);613 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
598 try test__fixdfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);614 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
599615
600 try test__fixdfti(-0x1.0000000000001p+63, -0x8000000000000800);616 try test_i128_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000800);
601 try test__fixdfti(-0x1.0000000000000p+63, -0x8000000000000000);617 try test_i128_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000);
602 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);618 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
603 try test__fixdfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);619 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
604620
605 try test__fixdfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);621 try test_i128_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000);
606 try test__fixdfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);622 try test_i128_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000);
607623
608 try test__fixdfti(-2.01, -2);624 try test_i128_intFromFloat_f64(-2.01, -2);
609 try test__fixdfti(-2.0, -2);625 try test_i128_intFromFloat_f64(-2.0, -2);
610 try test__fixdfti(-1.99, -1);626 try test_i128_intFromFloat_f64(-1.99, -1);
611 try test__fixdfti(-1.0, -1);627 try test_i128_intFromFloat_f64(-1.0, -1);
612 try test__fixdfti(-0.99, 0);628 try test_i128_intFromFloat_f64(-0.99, 0);
613 try test__fixdfti(-0.5, 0);629 try test_i128_intFromFloat_f64(-0.5, 0);
614 try test__fixdfti(-math.floatMin(f64), 0);630 try test_i128_intFromFloat_f64(-math.floatMin(f64), 0);
615 try test__fixdfti(0.0, 0);631 try test_i128_intFromFloat_f64(0.0, 0);
616 try test__fixdfti(math.floatMin(f64), 0);632 try test_i128_intFromFloat_f64(math.floatMin(f64), 0);
617 try test__fixdfti(0.5, 0);633 try test_i128_intFromFloat_f64(0.5, 0);
618 try test__fixdfti(0.99, 0);634 try test_i128_intFromFloat_f64(0.99, 0);
619 try test__fixdfti(1.0, 1);635 try test_i128_intFromFloat_f64(1.0, 1);
620 try test__fixdfti(1.5, 1);636 try test_i128_intFromFloat_f64(1.5, 1);
621 try test__fixdfti(1.99, 1);637 try test_i128_intFromFloat_f64(1.99, 1);
622 try test__fixdfti(2.0, 2);638 try test_i128_intFromFloat_f64(2.0, 2);
623 try test__fixdfti(2.01, 2);639 try test_i128_intFromFloat_f64(2.01, 2);
624640
625 try test__fixdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);641 try test_i128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
626 try test__fixdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);642 try test_i128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
627643
628 try test__fixdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);644 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
629 try test__fixdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);645 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
630 try test__fixdfti(0x1.0000000000000p+63, 0x8000000000000000);646 try test_i128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000);
631 try test__fixdfti(0x1.0000000000001p+63, 0x8000000000000800);647 try test_i128_intFromFloat_f64(0x1.0000000000001p+63, 0x8000000000000800);
632648
633 try test__fixdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);649 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
634 try test__fixdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);650 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
635 try test__fixdfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);651 try test_i128_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
636652
637 try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);653 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
638 try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));654 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
639655
640 try test__fixdfti(math.floatMax(f64), math.maxInt(i128));656 try test_i128_intFromFloat_f64(math.floatMax(f64), math.maxInt(i128));
641}657}
642658
643test "fixunsdfti" {659test u128_intFromFloat_f64 {
644 try test__fixunsdfti(0.0, 0);660 try test_u128_intFromFloat_f64(0.0, 0);
645661
646 try test__fixunsdfti(0.5, 0);662 try test_u128_intFromFloat_f64(0.5, 0);
647 try test__fixunsdfti(0.99, 0);663 try test_u128_intFromFloat_f64(0.99, 0);
648 try test__fixunsdfti(1.0, 1);664 try test_u128_intFromFloat_f64(1.0, 1);
649 try test__fixunsdfti(1.5, 1);665 try test_u128_intFromFloat_f64(1.5, 1);
650 try test__fixunsdfti(1.99, 1);666 try test_u128_intFromFloat_f64(1.99, 1);
651 try test__fixunsdfti(2.0, 2);667 try test_u128_intFromFloat_f64(2.0, 2);
652 try test__fixunsdfti(2.01, 2);668 try test_u128_intFromFloat_f64(2.01, 2);
653 try test__fixunsdfti(-0.5, 0);669 try test_u128_intFromFloat_f64(-0.5, 0);
654 try test__fixunsdfti(-0.99, 0);670 try test_u128_intFromFloat_f64(-0.99, 0);
655 try test__fixunsdfti(-1.0, 0);671 try test_u128_intFromFloat_f64(-1.0, 0);
656 try test__fixunsdfti(-1.5, 0);672 try test_u128_intFromFloat_f64(-1.5, 0);
657 try test__fixunsdfti(-1.99, 0);673 try test_u128_intFromFloat_f64(-1.99, 0);
658 try test__fixunsdfti(-2.0, 0);674 try test_u128_intFromFloat_f64(-2.0, 0);
659 try test__fixunsdfti(-2.01, 0);675 try test_u128_intFromFloat_f64(-2.01, 0);
660676
661 try test__fixunsdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);677 try test_u128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
662 try test__fixunsdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);678 try test_u128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
663679
664 try test__fixunsdfti(-0x1.FFFFFEp+62, 0);680 try test_u128_intFromFloat_f64(-0x1.FFFFFEp+62, 0);
665 try test__fixunsdfti(-0x1.FFFFFCp+62, 0);681 try test_u128_intFromFloat_f64(-0x1.FFFFFCp+62, 0);
666682
667 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);683 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);
668 try test__fixunsdfti(0x1.0000000000000p+63, 0x8000000000000000);684 try test_u128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000);
669 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);685 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
670 try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);686 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
671687
672 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000);688 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000);
673 try test__fixunsdfti(0x1.0000000000000p+127, 0x80000000000000000000000000000000);689 try test_u128_intFromFloat_f64(0x1.0000000000000p+127, 0x80000000000000000000000000000000);
674 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);690 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
675 try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);691 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
676 try test__fixunsdfti(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);692 try test_u128_intFromFloat_f64(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
677693
678 try test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0);694 try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0);
679 try test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0);695 try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0);
680}696}
681697
682fn test_fixdfei(comptime T: type, expected: T, a: f64) !void {698fn test_intFromFloat_f64(comptime T: type, expected: T, a: f64) !void {
683 const int = @typeInfo(T).int;699 const int = @typeInfo(T).int;
684 var actual: T = undefined;700 var actual: T = undefined;
685 _ = switch (int.signedness) {701 _ = switch (int.signedness) {
686 .signed => __fixdfei,702 .signed => signed_intFromFloat_f64,
687 .unsigned => __fixunsdfei,703 .unsigned => unsigned_intFromFloat_f64,
688 }(@ptrCast(&actual), int.bits, a);704 }(@ptrCast(&actual), a);
689 try testing.expect(expected == actual);705 try testing.expect(expected == actual);
690}706}
691707
692test "fixdfei" {708test signed_intFromFloat_f64 {
693 try test_fixdfei(i256, -1 << 255, -0x1p255);709 try test_intFromFloat_f64(i256, -1 << 255, -0x1p255);
694 try test_fixdfei(i256, -1 << 127, -0x1p127);710 try test_intFromFloat_f64(i256, -1 << 127, -0x1p127);
695 try test_fixdfei(i256, -1 << 100, -0x1p100);711 try test_intFromFloat_f64(i256, -1 << 100, -0x1p100);
696 try test_fixdfei(i256, -1 << 50, -0x1p50);712 try test_intFromFloat_f64(i256, -1 << 50, -0x1p50);
697 try test_fixdfei(i256, -1 << 1, -0x1p1);713 try test_intFromFloat_f64(i256, -1 << 1, -0x1p1);
698 try test_fixdfei(i256, -1 << 0, -0x1p0);714 try test_intFromFloat_f64(i256, -1 << 0, -0x1p0);
699 try test_fixdfei(i256, 0, 0);715 try test_intFromFloat_f64(i256, 0, 0);
700 try test_fixdfei(i256, 1 << 0, 0x1p0);716 try test_intFromFloat_f64(i256, 1 << 0, 0x1p0);
701 try test_fixdfei(i256, 1 << 1, 0x1p1);717 try test_intFromFloat_f64(i256, 1 << 1, 0x1p1);
702 try test_fixdfei(i256, 1 << 50, 0x1p50);718 try test_intFromFloat_f64(i256, 1 << 50, 0x1p50);
703 try test_fixdfei(i256, 1 << 100, 0x1p100);719 try test_intFromFloat_f64(i256, 1 << 100, 0x1p100);
704 try test_fixdfei(i256, 1 << 127, 0x1p127);720 try test_intFromFloat_f64(i256, 1 << 127, 0x1p127);
705 try test_fixdfei(i256, 1 << 254, 0x1p254);721 try test_intFromFloat_f64(i256, 1 << 254, 0x1p254);
706}722}
707723
708test "fixundfei" {724test unsigned_intFromFloat_f64 {
709 try test_fixdfei(u256, 0, 0);725 try test_intFromFloat_f64(u256, 0, 0);
710 try test_fixdfei(u256, 1 << 0, 0x1p0);726 try test_intFromFloat_f64(u256, 1 << 0, 0x1p0);
711 try test_fixdfei(u256, 1 << 1, 0x1p1);727 try test_intFromFloat_f64(u256, 1 << 1, 0x1p1);
712 try test_fixdfei(u256, 1 << 50, 0x1p50);728 try test_intFromFloat_f64(u256, 1 << 50, 0x1p50);
713 try test_fixdfei(u256, 1 << 100, 0x1p100);729 try test_intFromFloat_f64(u256, 1 << 100, 0x1p100);
714 try test_fixdfei(u256, 1 << 127, 0x1p127);730 try test_intFromFloat_f64(u256, 1 << 127, 0x1p127);
715 try test_fixdfei(u256, 1 << 255, 0x1p255);731 try test_intFromFloat_f64(u256, 1 << 255, 0x1p255);
716}732}
717733
718fn test__fixtfsi(a: f128, expected: i32) !void {734fn test_i32_intFromFloat_f128(a: f128, expected: i32) !void {
719 const x = __fixtfsi(a);735 const x = i32_intFromFloat_f128(a);
720 try testing.expect(x == expected);736 try testing.expect(x == expected);
721}737}
722738
723fn test__fixunstfsi(a: f128, expected: u32) !void {739fn test_u32_intFromFloat_f128(a: f128, expected: u32) !void {
724 const x = __fixunstfsi(a);740 const x = u32_intFromFloat_f128(a);
725 try testing.expect(x == expected);741 try testing.expect(x == expected);
726}742}
727743
728test "fixtfsi" {744test i32_intFromFloat_f128 {
729 try test__fixtfsi(-math.floatMax(f128), math.minInt(i32));745 try test_i32_intFromFloat_f128(-math.floatMax(f128), math.minInt(i32));
730746
731 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));747 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
732 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);748 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
733749
734 try test__fixtfsi(-0x1.0000000000000p+127, -0x80000000);750 try test_i32_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000);
735 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);751 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
736 try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);752 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
737753
738 try test__fixtfsi(-0x1.0000000000001p+63, -0x80000000);754 try test_i32_intFromFloat_f128(-0x1.0000000000001p+63, -0x80000000);
739 try test__fixtfsi(-0x1.0000000000000p+63, -0x80000000);755 try test_i32_intFromFloat_f128(-0x1.0000000000000p+63, -0x80000000);
740 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);756 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
741 try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);757 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
742758
743 try test__fixtfsi(-0x1.FFFFFEp+62, -0x80000000);759 try test_i32_intFromFloat_f128(-0x1.FFFFFEp+62, -0x80000000);
744 try test__fixtfsi(-0x1.FFFFFCp+62, -0x80000000);760 try test_i32_intFromFloat_f128(-0x1.FFFFFCp+62, -0x80000000);
745761
746 try test__fixtfsi(-0x1.000000p+31, -0x80000000);762 try test_i32_intFromFloat_f128(-0x1.000000p+31, -0x80000000);
747 try test__fixtfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);763 try test_i32_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0);
748 try test__fixtfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);764 try test_i32_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80);
749 try test__fixtfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);765 try test_i32_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00);
750766
751 try test__fixtfsi(-2.01, -2);767 try test_i32_intFromFloat_f128(-2.01, -2);
752 try test__fixtfsi(-2.0, -2);768 try test_i32_intFromFloat_f128(-2.0, -2);
753 try test__fixtfsi(-1.99, -1);769 try test_i32_intFromFloat_f128(-1.99, -1);
754 try test__fixtfsi(-1.0, -1);770 try test_i32_intFromFloat_f128(-1.0, -1);
755 try test__fixtfsi(-0.99, 0);771 try test_i32_intFromFloat_f128(-0.99, 0);
756 try test__fixtfsi(-0.5, 0);772 try test_i32_intFromFloat_f128(-0.5, 0);
757 try test__fixtfsi(-math.floatMin(f32), 0);773 try test_i32_intFromFloat_f128(-math.floatMin(f32), 0);
758 try test__fixtfsi(0.0, 0);774 try test_i32_intFromFloat_f128(0.0, 0);
759 try test__fixtfsi(math.floatMin(f32), 0);775 try test_i32_intFromFloat_f128(math.floatMin(f32), 0);
760 try test__fixtfsi(0.5, 0);776 try test_i32_intFromFloat_f128(0.5, 0);
761 try test__fixtfsi(0.99, 0);777 try test_i32_intFromFloat_f128(0.99, 0);
762 try test__fixtfsi(1.0, 1);778 try test_i32_intFromFloat_f128(1.0, 1);
763 try test__fixtfsi(1.5, 1);779 try test_i32_intFromFloat_f128(1.5, 1);
764 try test__fixtfsi(1.99, 1);780 try test_i32_intFromFloat_f128(1.99, 1);
765 try test__fixtfsi(2.0, 2);781 try test_i32_intFromFloat_f128(2.0, 2);
766 try test__fixtfsi(2.01, 2);782 try test_i32_intFromFloat_f128(2.01, 2);
767783
768 try test__fixtfsi(0x1.FFFFFCp+30, 0x7FFFFF00);784 try test_i32_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00);
769 try test__fixtfsi(0x1.FFFFFEp+30, 0x7FFFFF80);785 try test_i32_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80);
770 try test__fixtfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);786 try test_i32_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0);
771 try test__fixtfsi(0x1.000000p+31, 0x7FFFFFFF);787 try test_i32_intFromFloat_f128(0x1.000000p+31, 0x7FFFFFFF);
772788
773 try test__fixtfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);789 try test_i32_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFFFF);
774 try test__fixtfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);790 try test_i32_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFFFF);
775791
776 try test__fixtfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);792 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
777 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);793 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
778 try test__fixtfsi(0x1.0000000000000p+63, 0x7FFFFFFF);794 try test_i32_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFF);
779 try test__fixtfsi(0x1.0000000000001p+63, 0x7FFFFFFF);795 try test_i32_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFF);
780796
781 try test__fixtfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);797 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
782 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);798 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
783 try test__fixtfsi(0x1.0000000000000p+127, 0x7FFFFFFF);799 try test_i32_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFF);
784800
785 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);801 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
786 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));802 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
787803
788 try test__fixtfsi(math.floatMax(f128), math.maxInt(i32));804 try test_i32_intFromFloat_f128(math.floatMax(f128), math.maxInt(i32));
789}805}
790806
791test "fixunstfsi" {807test u32_intFromFloat_f128 {
792 try test__fixunstfsi(math.inf(f128), 0xffffffff);808 try test_u32_intFromFloat_f128(math.inf(f128), 0xffffffff);
793 try test__fixunstfsi(0, 0x0);809 try test_u32_intFromFloat_f128(0, 0x0);
794 try test__fixunstfsi(0x1.23456789abcdefp+5, 0x24);810 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+5, 0x24);
795 try test__fixunstfsi(0x1.23456789abcdefp-3, 0x0);811 try test_u32_intFromFloat_f128(0x1.23456789abcdefp-3, 0x0);
796 try test__fixunstfsi(0x1.23456789abcdefp+20, 0x123456);812 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+20, 0x123456);
797 try test__fixunstfsi(0x1.23456789abcdefp+40, 0xffffffff);813 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+40, 0xffffffff);
798 try test__fixunstfsi(0x1.23456789abcdefp+256, 0xffffffff);814 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+256, 0xffffffff);
799 try test__fixunstfsi(-0x1.23456789abcdefp+3, 0x0);815 try test_u32_intFromFloat_f128(-0x1.23456789abcdefp+3, 0x0);
800816
801 try test__fixunstfsi(0x1p+32, 0xFFFFFFFF);817 try test_u32_intFromFloat_f128(0x1p+32, 0xFFFFFFFF);
802}818}
803819
804fn test__fixtfdi(a: f128, expected: i64) !void {820fn test_i64_intFromFloat_f128(a: f128, expected: i64) !void {
805 const x = __fixtfdi(a);821 const x = i64_intFromFloat_f128(a);
806 try testing.expect(x == expected);822 try testing.expect(x == expected);
807}823}
808824
809fn test__fixunstfdi(a: f128, expected: u64) !void {825fn test_u64_intFromFloat_f128(a: f128, expected: u64) !void {
810 const x = __fixunstfdi(a);826 const x = u64_intFromFloat_f128(a);
811 try testing.expect(x == expected);827 try testing.expect(x == expected);
812}828}
813829
814test "fixtfdi" {830test i64_intFromFloat_f128 {
815 try test__fixtfdi(-math.floatMax(f128), math.minInt(i64));831 try test_i64_intFromFloat_f128(-math.floatMax(f128), math.minInt(i64));
816832
817 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));833 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
818 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);834 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
819835
820 try test__fixtfdi(-0x1.0000000000000p+127, -0x8000000000000000);836 try test_i64_intFromFloat_f128(-0x1.0000000000000p+127, -0x8000000000000000);
821 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);837 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
822 try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);838 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
823839
824 try test__fixtfdi(-0x1.0000000000001p+63, -0x8000000000000000);840 try test_i64_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000000);
825 try test__fixtfdi(-0x1.0000000000000p+63, -0x8000000000000000);841 try test_i64_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000);
826 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);842 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
827 try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);843 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
828844
829 try test__fixtfdi(-0x1.FFFFFEp+62, -0x7FFFFF8000000000);845 try test_i64_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7FFFFF8000000000);
830 try test__fixtfdi(-0x1.FFFFFCp+62, -0x7FFFFF0000000000);846 try test_i64_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7FFFFF0000000000);
831847
832 try test__fixtfdi(-0x1.000000p+31, -0x80000000);848 try test_i64_intFromFloat_f128(-0x1.000000p+31, -0x80000000);
833 try test__fixtfdi(-0x1.FFFFFFp+30, -0x7FFFFFC0);849 try test_i64_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0);
834 try test__fixtfdi(-0x1.FFFFFEp+30, -0x7FFFFF80);850 try test_i64_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80);
835 try test__fixtfdi(-0x1.FFFFFCp+30, -0x7FFFFF00);851 try test_i64_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00);
836852
837 try test__fixtfdi(-2.01, -2);853 try test_i64_intFromFloat_f128(-2.01, -2);
838 try test__fixtfdi(-2.0, -2);854 try test_i64_intFromFloat_f128(-2.0, -2);
839 try test__fixtfdi(-1.99, -1);855 try test_i64_intFromFloat_f128(-1.99, -1);
840 try test__fixtfdi(-1.0, -1);856 try test_i64_intFromFloat_f128(-1.0, -1);
841 try test__fixtfdi(-0.99, 0);857 try test_i64_intFromFloat_f128(-0.99, 0);
842 try test__fixtfdi(-0.5, 0);858 try test_i64_intFromFloat_f128(-0.5, 0);
843 try test__fixtfdi(-math.floatMin(f64), 0);859 try test_i64_intFromFloat_f128(-math.floatMin(f64), 0);
844 try test__fixtfdi(0.0, 0);860 try test_i64_intFromFloat_f128(0.0, 0);
845 try test__fixtfdi(math.floatMin(f64), 0);861 try test_i64_intFromFloat_f128(math.floatMin(f64), 0);
846 try test__fixtfdi(0.5, 0);862 try test_i64_intFromFloat_f128(0.5, 0);
847 try test__fixtfdi(0.99, 0);863 try test_i64_intFromFloat_f128(0.99, 0);
848 try test__fixtfdi(1.0, 1);864 try test_i64_intFromFloat_f128(1.0, 1);
849 try test__fixtfdi(1.5, 1);865 try test_i64_intFromFloat_f128(1.5, 1);
850 try test__fixtfdi(1.99, 1);866 try test_i64_intFromFloat_f128(1.99, 1);
851 try test__fixtfdi(2.0, 2);867 try test_i64_intFromFloat_f128(2.0, 2);
852 try test__fixtfdi(2.01, 2);868 try test_i64_intFromFloat_f128(2.01, 2);
853869
854 try test__fixtfdi(0x1.FFFFFCp+30, 0x7FFFFF00);870 try test_i64_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00);
855 try test__fixtfdi(0x1.FFFFFEp+30, 0x7FFFFF80);871 try test_i64_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80);
856 try test__fixtfdi(0x1.FFFFFFp+30, 0x7FFFFFC0);872 try test_i64_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0);
857 try test__fixtfdi(0x1.000000p+31, 0x80000000);873 try test_i64_intFromFloat_f128(0x1.000000p+31, 0x80000000);
858874
859 try test__fixtfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);875 try test_i64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
860 try test__fixtfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);876 try test_i64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
861877
862 try test__fixtfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);878 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
863 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);879 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
864 try test__fixtfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);880 try test_i64_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
865 try test__fixtfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);881 try test_i64_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
866882
867 try test__fixtfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);883 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
868 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);884 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
869 try test__fixtfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);885 try test_i64_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
870886
871 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);887 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
872 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));888 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
873889
874 try test__fixtfdi(math.floatMax(f128), math.maxInt(i64));890 try test_i64_intFromFloat_f128(math.floatMax(f128), math.maxInt(i64));
875}891}
876892
877test "fixunstfdi" {893test u64_intFromFloat_f128 {
878 try test__fixunstfdi(0.0, 0);894 try test_u64_intFromFloat_f128(0.0, 0);
879895
880 try test__fixunstfdi(0.5, 0);896 try test_u64_intFromFloat_f128(0.5, 0);
881 try test__fixunstfdi(0.99, 0);897 try test_u64_intFromFloat_f128(0.99, 0);
882 try test__fixunstfdi(1.0, 1);898 try test_u64_intFromFloat_f128(1.0, 1);
883 try test__fixunstfdi(1.5, 1);899 try test_u64_intFromFloat_f128(1.5, 1);
884 try test__fixunstfdi(1.99, 1);900 try test_u64_intFromFloat_f128(1.99, 1);
885 try test__fixunstfdi(2.0, 2);901 try test_u64_intFromFloat_f128(2.0, 2);
886 try test__fixunstfdi(2.01, 2);902 try test_u64_intFromFloat_f128(2.01, 2);
887 try test__fixunstfdi(-0.5, 0);903 try test_u64_intFromFloat_f128(-0.5, 0);
888 try test__fixunstfdi(-0.99, 0);904 try test_u64_intFromFloat_f128(-0.99, 0);
889 try test__fixunstfdi(-1.0, 0);905 try test_u64_intFromFloat_f128(-1.0, 0);
890 try test__fixunstfdi(-1.5, 0);906 try test_u64_intFromFloat_f128(-1.5, 0);
891 try test__fixunstfdi(-1.99, 0);907 try test_u64_intFromFloat_f128(-1.99, 0);
892 try test__fixunstfdi(-2.0, 0);908 try test_u64_intFromFloat_f128(-2.0, 0);
893 try test__fixunstfdi(-2.01, 0);909 try test_u64_intFromFloat_f128(-2.01, 0);
894910
895 try test__fixunstfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);911 try test_u64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
896 try test__fixunstfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);912 try test_u64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
897913
898 try test__fixunstfdi(-0x1.FFFFFEp+62, 0);914 try test_u64_intFromFloat_f128(-0x1.FFFFFEp+62, 0);
899 try test__fixunstfdi(-0x1.FFFFFCp+62, 0);915 try test_u64_intFromFloat_f128(-0x1.FFFFFCp+62, 0);
900916
901 try test__fixunstfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);917 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
902 try test__fixunstfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);918 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
903919
904 try test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0);920 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, 0);
905 try test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0);921 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, 0);
906922
907 try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);923 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);
908 try test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001);924 try test_u64_intFromFloat_f128(0x1.0000000000000002p+63, 0x8000000000000001);
909 try test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000);925 try test_u64_intFromFloat_f128(0x1.0000000000000000p+63, 0x8000000000000000);
910 try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);926 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);
911 try test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);927 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);
912 try test__fixunstfdi(0x1p+64, 0xFFFFFFFFFFFFFFFF);928 try test_u64_intFromFloat_f128(0x1p+64, 0xFFFFFFFFFFFFFFFF);
913929
914 try test__fixunstfdi(-0x1.0000000000000000p+63, 0);930 try test_u64_intFromFloat_f128(-0x1.0000000000000000p+63, 0);
915 try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0);931 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFFCp+62, 0);
916 try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0);932 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFF8p+62, 0);
917}933}
918934
919fn test__fixtfti(a: f128, expected: i128) !void {935fn test_i128_intFromFloat_f128(a: f128, expected: i128) !void {
920 const x = __fixtfti(a);936 const x = i128_intFromFloat_f128(a);
921 try testing.expect(x == expected);937 try testing.expect(x == expected);
922}938}
923939
924fn test__fixunstfti(a: f128, expected: u128) !void {940fn test_u128_intFromFloat_f128(a: f128, expected: u128) !void {
925 const x = __fixunstfti(a);941 const x = u128_intFromFloat_f128(a);
926 try testing.expect(x == expected);942 try testing.expect(x == expected);
927}943}
928944
929test "fixtfti" {945test i128_intFromFloat_f128 {
930 try test__fixtfti(-math.floatMax(f128), math.minInt(i128));946 try test_i128_intFromFloat_f128(-math.floatMax(f128), math.minInt(i128));
931947
932 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));948 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
933 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);949 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
934950
935 try test__fixtfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);951 try test_i128_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
936 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);952 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
937 try test__fixtfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);953 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
938954
939 try test__fixtfti(-0x1.0000000000001p+63, -0x8000000000000800);955 try test_i128_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000800);
940 try test__fixtfti(-0x1.0000000000000p+63, -0x8000000000000000);956 try test_i128_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000);
941 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);957 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
942 try test__fixtfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);958 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
943959
944 try test__fixtfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);960 try test_i128_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7fffff8000000000);
945 try test__fixtfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);961 try test_i128_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7fffff0000000000);
946962
947 try test__fixtfti(-2.01, -2);963 try test_i128_intFromFloat_f128(-2.01, -2);
948 try test__fixtfti(-2.0, -2);964 try test_i128_intFromFloat_f128(-2.0, -2);
949 try test__fixtfti(-1.99, -1);965 try test_i128_intFromFloat_f128(-1.99, -1);
950 try test__fixtfti(-1.0, -1);966 try test_i128_intFromFloat_f128(-1.0, -1);
951 try test__fixtfti(-0.99, 0);967 try test_i128_intFromFloat_f128(-0.99, 0);
952 try test__fixtfti(-0.5, 0);968 try test_i128_intFromFloat_f128(-0.5, 0);
953 try test__fixtfti(-math.floatMin(f128), 0);969 try test_i128_intFromFloat_f128(-math.floatMin(f128), 0);
954 try test__fixtfti(0.0, 0);970 try test_i128_intFromFloat_f128(0.0, 0);
955 try test__fixtfti(math.floatMin(f128), 0);971 try test_i128_intFromFloat_f128(math.floatMin(f128), 0);
956 try test__fixtfti(0.5, 0);972 try test_i128_intFromFloat_f128(0.5, 0);
957 try test__fixtfti(0.99, 0);973 try test_i128_intFromFloat_f128(0.99, 0);
958 try test__fixtfti(1.0, 1);974 try test_i128_intFromFloat_f128(1.0, 1);
959 try test__fixtfti(1.5, 1);975 try test_i128_intFromFloat_f128(1.5, 1);
960 try test__fixtfti(1.99, 1);976 try test_i128_intFromFloat_f128(1.99, 1);
961 try test__fixtfti(2.0, 2);977 try test_i128_intFromFloat_f128(2.0, 2);
962 try test__fixtfti(2.01, 2);978 try test_i128_intFromFloat_f128(2.01, 2);
963979
964 try test__fixtfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);980 try test_i128_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
965 try test__fixtfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);981 try test_i128_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
966982
967 try test__fixtfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);983 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
968 try test__fixtfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);984 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
969 try test__fixtfti(0x1.0000000000000p+63, 0x8000000000000000);985 try test_i128_intFromFloat_f128(0x1.0000000000000p+63, 0x8000000000000000);
970 try test__fixtfti(0x1.0000000000001p+63, 0x8000000000000800);986 try test_i128_intFromFloat_f128(0x1.0000000000001p+63, 0x8000000000000800);
971987
972 try test__fixtfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);988 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
973 try test__fixtfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);989 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
974 try test__fixtfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);990 try test_i128_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
975991
976 try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);992 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
977 try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));993 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
978994
979 try test__fixtfti(math.floatMax(f128), math.maxInt(i128));995 try test_i128_intFromFloat_f128(math.floatMax(f128), math.maxInt(i128));
980}996}
981997
982test "fixunstfti" {998test u128_intFromFloat_f128 {
983 try test__fixunstfti(math.inf(f128), 0xffffffffffffffffffffffffffffffff);999 try test_u128_intFromFloat_f128(math.inf(f128), 0xffffffffffffffffffffffffffffffff);
9841000
985 try test__fixunstfti(0.0, 0);1001 try test_u128_intFromFloat_f128(0.0, 0);
9861002
987 try test__fixunstfti(0.5, 0);1003 try test_u128_intFromFloat_f128(0.5, 0);
988 try test__fixunstfti(0.99, 0);1004 try test_u128_intFromFloat_f128(0.99, 0);
989 try test__fixunstfti(1.0, 1);1005 try test_u128_intFromFloat_f128(1.0, 1);
990 try test__fixunstfti(1.5, 1);1006 try test_u128_intFromFloat_f128(1.5, 1);
991 try test__fixunstfti(1.99, 1);1007 try test_u128_intFromFloat_f128(1.99, 1);
992 try test__fixunstfti(2.0, 2);1008 try test_u128_intFromFloat_f128(2.0, 2);
993 try test__fixunstfti(2.01, 2);1009 try test_u128_intFromFloat_f128(2.01, 2);
994 try test__fixunstfti(-0.01, 0);1010 try test_u128_intFromFloat_f128(-0.01, 0);
995 try test__fixunstfti(-0.99, 0);1011 try test_u128_intFromFloat_f128(-0.99, 0);
9961012
997 try test__fixunstfti(0x1p+128, 0xffffffffffffffffffffffffffffffff);1013 try test_u128_intFromFloat_f128(0x1p+128, 0xffffffffffffffffffffffffffffffff);
9981014
999 try test__fixunstfti(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000);1015 try test_u128_intFromFloat_f128(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000);
1000 try test__fixunstfti(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000);1016 try test_u128_intFromFloat_f128(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000);
1001 try test__fixunstfti(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff);1017 try test_u128_intFromFloat_f128(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff);
1002 try test__fixunstfti(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff);1018 try test_u128_intFromFloat_f128(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff);
1003}1019}
10041020
1005fn test__fixunshfti(a: f16, expected: u128) !void {1021fn test_u128_intFromFloat_f16(a: f16, expected: u128) !void {
1006 const x = __fixunshfti(a);1022 const x = impl.u128_intFromFloat_f16(a);
1007 try testing.expect(x == expected);1023 try testing.expect(x == expected);
1008}1024}
10091025
1010test "fixunshfti for f16" {1026test u128_intFromFloat_f16 {
1011 try test__fixunshfti(math.inf(f16), math.maxInt(u128));1027 try test_u128_intFromFloat_f16(math.inf(f16), math.maxInt(u128));
1012 try test__fixunshfti(math.floatMax(f16), 65504);1028 try test_u128_intFromFloat_f16(math.floatMax(f16), 65504);
1013}1029}
10141030
1015fn test__fixunsxfti(a: f80, expected: u128) !void {1031fn test_u128_intFromFloat_f80(a: f80, expected: u128) !void {
1016 const x = __fixunsxfti(a);1032 const x = impl.u128_intFromFloat_f80(a);
1017 try testing.expect(x == expected);1033 try testing.expect(x == expected);
1018}1034}
10191035
1020test "fixunsxfti for f80" {1036test u128_intFromFloat_f80 {
1021 try test__fixunsxfti(math.inf(f80), math.maxInt(u128));1037 try test_u128_intFromFloat_f80(math.inf(f80), math.maxInt(u128));
1022 try test__fixunsxfti(math.floatMax(f80), math.maxInt(u128));1038 try test_u128_intFromFloat_f80(math.floatMax(f80), math.maxInt(u128));
1023 try test__fixunsxfti(math.maxInt(u64), math.maxInt(u64));1039 try test_u128_intFromFloat_f80(math.maxInt(u64), math.maxInt(u64));
1024}1040}
lib/compiler_rt/limb64.zig+1-1
...@@ -6,7 +6,7 @@ const minInt = std.math.minInt;...@@ -6,7 +6,7 @@ const minInt = std.math.minInt;
66
7const builtin = @import("builtin");7const builtin = @import("builtin");
8const compiler_rt = @import("../compiler_rt.zig");8const compiler_rt = @import("../compiler_rt.zig");
9const symbol = @import("../compiler_rt.zig").symbol;9const symbol = compiler_rt.symbol;
1010
11const endian = builtin.cpu.arch.endian();11const endian = builtin.cpu.arch.endian();
1212
lib/compiler_rt/log.zig+113-101
...@@ -11,26 +11,29 @@ const expectEqual = std.testing.expectEqual;...@@ -11,26 +11,29 @@ const expectEqual = std.testing.expectEqual;
11const expectApproxEqRel = std.testing.expectApproxEqRel;11const expectApproxEqRel = std.testing.expectApproxEqRel;
1212
13const compiler_rt = @import("../compiler_rt.zig");13const compiler_rt = @import("../compiler_rt.zig");
14const symbol = @import("../compiler_rt.zig").symbol;14const symbol = compiler_rt.symbol;
1515
16comptime {16comptime {
17 symbol(&__logh, "__logh");17 symbol(&__logh, "__logh");
18 symbol(&logf, "logf");18 symbol(&logf, "logf");
19 symbol(&log, "log");19 symbol(&log, "log");
20 symbol(&__logx, "__logx");20 symbol(&__logx, "__logx");
21 if (compiler_rt.want_ppc_abi) {21 symbol(&logq, "logf128");
22 symbol(&logq, "logf128");
23 }
24 symbol(&logq, "logq");
25 symbol(&logl, "logl");22 symbol(&logl, "logl");
26}23}
2724
28pub fn __logh(a: f16) callconv(.c) f16 {25fn __logh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
26 return compiler_rt.f16.toAbi(log_f16(compiler_rt.f16.fromAbi(a)));
27}
28pub fn log_f16(a: f16) f16 {
29 // TODO: more efficient implementation29 // TODO: more efficient implementation
30 return @floatCast(logf(a));30 return @floatCast(log_f32(a));
31}31}
3232
33pub fn logf(x_: f32) callconv(.c) f32 {33fn logf(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
34 return compiler_rt.f32.toAbi(log_f32(compiler_rt.f32.fromAbi(a)));
35}
36pub fn log_f32(x_: f32) f32 {
34 const ln2_hi: f32 = 6.9313812256e-01;37 const ln2_hi: f32 = 6.9313812256e-01;
35 const ln2_lo: f32 = 9.0580006145e-06;38 const ln2_lo: f32 = 9.0580006145e-06;
36 const Lg1: f32 = 0xaaaaaa.0p-24;39 const Lg1: f32 = 0xaaaaaa.0p-24;
...@@ -82,7 +85,10 @@ pub fn logf(x_: f32) callconv(.c) f32 {...@@ -82,7 +85,10 @@ pub fn logf(x_: f32) callconv(.c) f32 {
82 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;85 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
83}86}
8487
85pub fn log(x: f64) callconv(.c) f64 {88fn log(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
89 return compiler_rt.f64.toAbi(log_f64(compiler_rt.f64.fromAbi(a)));
90}
91pub fn log_f64(x: f64) f64 {
86 const poly1 = [_]f64{92 const poly1 = [_]f64{
87 -0x1p-1,93 -0x1p-1,
88 0x1.5555555555577p-2,94 0x1.5555555555577p-2,
...@@ -432,11 +438,17 @@ pub fn log(x: f64) callconv(.c) f64 {...@@ -432,11 +438,17 @@ pub fn log(x: f64) callconv(.c) f64 {
432 return @bitCast(y);438 return @bitCast(y);
433}439}
434440
435pub fn __logx(a: f80) callconv(.c) f80 {441fn __logx(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
442 return compiler_rt.f80.toAbi(log_f80(compiler_rt.f80.fromAbi(a)));
443}
444pub fn log_f80(a: f80) f80 {
436 // TODO: more efficient implementation445 // TODO: more efficient implementation
437 return @floatCast(logq(a));446 return @floatCast(log_f128(a));
438}447}
439448
449fn logq(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
450 return compiler_rt.f128.toAbi(log_f128(compiler_rt.f128.fromAbi(a)));
451}
440/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"452/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"
441/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990453/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990
442///454///
...@@ -449,7 +461,7 @@ pub fn __logx(a: f80) callconv(.c) f80 {...@@ -449,7 +461,7 @@ pub fn __logx(a: f80) callconv(.c) f80 {
449///461///
450/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):462/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):
451/// <= 0.5 ulp: 99.96%, worst case <= 0.528 ulp463/// <= 0.5 ulp: 99.96%, worst case <= 0.528 ulp
452pub fn logq(x: f128) callconv(.c) f128 {464pub fn log_f128(x: f128) f128 {
453 const impl = @import("log_f128.zig");465 const impl = @import("log_f128.zig");
454466
455 if (impl.specialCases(x)) |y|467 if (impl.specialCases(x)) |y|
...@@ -626,123 +638,123 @@ pub fn logq(x: f128) callconv(.c) f128 {...@@ -626,123 +638,123 @@ pub fn logq(x: f128) callconv(.c) f128 {
626638
627pub fn logl(x: c_longdouble) callconv(.c) c_longdouble {639pub fn logl(x: c_longdouble) callconv(.c) c_longdouble {
628 switch (@typeInfo(c_longdouble).float.bits) {640 switch (@typeInfo(c_longdouble).float.bits) {
629 64 => return log(x),641 64 => return log_f64(x),
630 80 => return __logx(x),642 80 => return log_f80(x),
631 128 => return logq(x),643 128 => return log_f128(x),
632 else => @compileError("unreachable"),644 else => comptime unreachable,
633 }645 }
634}646}
635647
636test "logf() special" {648test "logf() special" {
637 try expectEqual(logf(0.0), -math.inf(f32));649 try expectEqual(log_f32(0.0), -math.inf(f32));
638 try expectEqual(logf(-0.0), -math.inf(f32));650 try expectEqual(log_f32(-0.0), -math.inf(f32));
639 try expect(math.isPositiveZero(logf(1.0)));651 try expect(math.isPositiveZero(log_f32(1.0)));
640 try expectEqual(logf(math.e), 1.0);652 try expectEqual(log_f32(math.e), 1.0);
641 try expectEqual(logf(math.inf(f32)), math.inf(f32));653 try expectEqual(log_f32(math.inf(f32)), math.inf(f32));
642 try expect(math.isNan(logf(-1.0)));654 try expect(math.isNan(log_f32(-1.0)));
643 try expect(math.isNan(logf(-math.inf(f32))));655 try expect(math.isNan(log_f32(-math.inf(f32))));
644 try expect(math.isNan(logf(math.nan(f32))));656 try expect(math.isNan(log_f32(math.nan(f32))));
645 try expect(math.isNan(logf(math.snan(f32))));657 try expect(math.isNan(log_f32(math.snan(f32))));
646}658}
647659
648test "logf() sanity" {660test "logf() sanity" {
649 try expect(math.isNan(logf(-0x1.0223a0p+3)));661 try expect(math.isNan(log_f32(-0x1.0223a0p+3)));
650 try expectEqual(logf(0x1.161868p+2), 0x1.7815b0p+0);662 try expectEqual(log_f32(0x1.161868p+2), 0x1.7815b0p+0);
651 try expect(math.isNan(logf(-0x1.0c34b4p+3)));663 try expect(math.isNan(log_f32(-0x1.0c34b4p+3)));
652 try expect(math.isNan(logf(-0x1.a206f0p+2)));664 try expect(math.isNan(log_f32(-0x1.a206f0p+2)));
653 try expectEqual(logf(0x1.288bbcp+3), 0x1.1cfcd6p+1);665 try expectEqual(log_f32(0x1.288bbcp+3), 0x1.1cfcd6p+1);
654 try expectEqual(logf(0x1.52efd0p-1), -0x1.a6694cp-2);666 try expectEqual(log_f32(0x1.52efd0p-1), -0x1.a6694cp-2);
655 try expect(math.isNan(logf(-0x1.a05cc8p-2)));667 try expect(math.isNan(log_f32(-0x1.a05cc8p-2)));
656 try expectEqual(logf(0x1.1f9efap-1), -0x1.2742bap-1);668 try expectEqual(log_f32(0x1.1f9efap-1), -0x1.2742bap-1);
657 try expectEqual(logf(0x1.8c5db0p-1), -0x1.062160p-2);669 try expectEqual(log_f32(0x1.8c5db0p-1), -0x1.062160p-2);
658 try expect(math.isNan(logf(-0x1.5b86eap-1)));670 try expect(math.isNan(log_f32(-0x1.5b86eap-1)));
659}671}
660672
661test "logf() boundary" {673test "logf() boundary" {
662 try expectEqual(logf(0x1.fffffep+127), 0x1.62e430p+6); // Max input value674 try expectEqual(log_f32(0x1.fffffep+127), 0x1.62e430p+6); // Max input value
663 try expectEqual(logf(0x1p-149), -0x1.9d1da0p+6); // Min positive input value675 try expectEqual(log_f32(0x1p-149), -0x1.9d1da0p+6); // Min positive input value
664 try expect(math.isNan(logf(-0x1p-149))); // Min negative input value676 try expect(math.isNan(log_f32(-0x1p-149))); // Min negative input value
665 try expectEqual(logf(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0677 try expectEqual(log_f32(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0
666 try expectEqual(logf(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0678 try expectEqual(log_f32(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0
667 try expectEqual(logf(0x1p-126), -0x1.5d58a0p+6); // First subnormal679 try expectEqual(log_f32(0x1p-126), -0x1.5d58a0p+6); // First subnormal
668 try expect(math.isNan(logf(-0x1p-126))); // First negative subnormal680 try expect(math.isNan(log_f32(-0x1p-126))); // First negative subnormal
669}681}
670682
671test "log() special" {683test "log() special" {
672 try expectEqual(log(0.0), -math.inf(f64));684 try expectEqual(log_f64(0.0), -math.inf(f64));
673 try expectEqual(log(-0.0), -math.inf(f64));685 try expectEqual(log_f64(-0.0), -math.inf(f64));
674 try expect(math.isPositiveZero(log(1.0)));686 try expect(math.isPositiveZero(log_f64(1.0)));
675 try expectEqual(log(math.e), 1.0);687 try expectEqual(log_f64(math.e), 1.0);
676 try expectEqual(log(math.inf(f64)), math.inf(f64));688 try expectEqual(log_f64(math.inf(f64)), math.inf(f64));
677 try expect(math.isNan(log(-1.0)));689 try expect(math.isNan(log_f64(-1.0)));
678 try expect(math.isNan(log(-math.inf(f64))));690 try expect(math.isNan(log_f64(-math.inf(f64))));
679 try expect(math.isNan(log(math.nan(f64))));691 try expect(math.isNan(log_f64(math.nan(f64))));
680 try expect(math.isNan(log(math.snan(f64))));692 try expect(math.isNan(log_f64(math.snan(f64))));
681}693}
682694
683test "log() sanity" {695test "log() sanity" {
684 try expect(math.isNan(log(-0x1.02239f3c6a8f1p+3)));696 try expect(math.isNan(log_f64(-0x1.02239f3c6a8f1p+3)));
685 try expectEqual(log(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0);697 try expectEqual(log_f64(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0);
686 try expect(math.isNan(log(-0x1.0c34b3e01e6e7p+3)));698 try expect(math.isNan(log_f64(-0x1.0c34b3e01e6e7p+3)));
687 try expect(math.isNan(log(-0x1.a206f0a19dcc4p+2)));699 try expect(math.isNan(log_f64(-0x1.a206f0a19dcc4p+2)));
688 try expectEqual(log(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1);700 try expectEqual(log_f64(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1);
689 try expectEqual(log(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2);701 try expectEqual(log_f64(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2);
690 try expect(math.isNan(log(-0x1.a05cc754481d1p-2)));702 try expect(math.isNan(log_f64(-0x1.a05cc754481d1p-2)));
691 try expectEqual(log(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1);703 try expectEqual(log_f64(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1);
692 try expectEqual(log(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2);704 try expectEqual(log_f64(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2);
693 try expect(math.isNan(log(-0x1.5b86ea8118a0ep-1)));705 try expect(math.isNan(log_f64(-0x1.5b86ea8118a0ep-1)));
694}706}
695707
696test "log() boundary" {708test "log() boundary" {
697 try expectEqual(log(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value709 try expectEqual(log_f64(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value
698 try expectEqual(log(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value710 try expectEqual(log_f64(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value
699 try expect(math.isNan(log(-0x1p-1074))); // Min negative input value711 try expect(math.isNan(log_f64(-0x1p-1074))); // Min negative input value
700 try expectEqual(log(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0712 try expectEqual(log_f64(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0
701 try expectEqual(log(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0713 try expectEqual(log_f64(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0
702 try expectEqual(log(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal714 try expectEqual(log_f64(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal
703 try expect(math.isNan(log(-0x1p-1022))); // First negative subnormal715 try expect(math.isNan(log_f64(-0x1p-1022))); // First negative subnormal
704}716}
705717
706test "logq() special" {718test "logq() special" {
707 try expectEqual(logq(0.0), -math.inf(f128));719 try expectEqual(log_f128(0.0), -math.inf(f128));
708 try expectEqual(logq(-0.0), -math.inf(f128));720 try expectEqual(log_f128(-0.0), -math.inf(f128));
709 try expect(math.isPositiveZero(logq(1.0)));721 try expect(math.isPositiveZero(log_f128(1.0)));
710 // Sadly, the rounding gods decided that 0.9999999999999999999999999999999999722 // Sadly, the rounding gods decided that 0.9999999999999999999999999999999999
711 // is the correctly rounded value of logq(math.e)723 // is the correctly rounded value of log_f128(math.e)
712 try expectApproxEqRel(logq(math.e), 1.0, math.floatEpsAt(f128, 1.0));724 try expectApproxEqRel(log_f128(math.e), 1.0, math.floatEpsAt(f128, 1.0));
713 try expectEqual(logq(math.inf(f128)), math.inf(f128));725 try expectEqual(log_f128(math.inf(f128)), math.inf(f128));
714 try expect(math.isNan(logq(-1.0)));726 try expect(math.isNan(log_f128(-1.0)));
715 try expect(math.isNan(logq(-math.inf(f128))));727 try expect(math.isNan(log_f128(-math.inf(f128))));
716 try expect(math.isNan(logq(math.nan(f128))));728 try expect(math.isNan(log_f128(math.nan(f128))));
717 try expect(math.isNan(logq(math.snan(f128))));729 try expect(math.isNan(log_f128(math.snan(f128))));
718}730}
719731
720test "logq() boundary" {732test "logq() boundary" {
721 try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value733 try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value
722 try expectEqual(logq(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value734 try expectEqual(log_f128(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value
723 try expect(math.isNan(logq(-0x1p-16494))); // Min negative input value735 try expect(math.isNan(log_f128(-0x1p-16494))); // Min negative input value
724 try expectEqual(logq(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0736 try expectEqual(log_f128(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0
725 try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0737 try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0
726 try expectEqual(logq(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal738 try expectEqual(log_f128(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal
727 try expect(math.isNan(logq(-0x1p-16382))); // First negative subnormal739 try expect(math.isNan(log_f128(-0x1p-16382))); // First negative subnormal
728}740}
729741
730test "logq() sanity" {742test "logq() sanity" {
731 try expectEqual(logq(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0);743 try expectEqual(log_f128(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0);
732 try expectEqual(logq(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1);744 try expectEqual(log_f128(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1);
733 try expectEqual(logq(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1);745 try expectEqual(log_f128(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1);
734 try expectEqual(logq(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1);746 try expectEqual(log_f128(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1);
735 try expectEqual(logq(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1);747 try expectEqual(log_f128(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1);
736 try expectEqual(logq(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1);748 try expectEqual(log_f128(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1);
737 try expectEqual(logq(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1);749 try expectEqual(log_f128(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1);
738 try expectEqual(logq(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1);750 try expectEqual(log_f128(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1);
739 try expectEqual(logq(1.200355637363589375e14), 3.2418809179272977400408325788186897e1);751 try expectEqual(log_f128(1.200355637363589375e14), 3.2418809179272977400408325788186897e1);
740 try expectEqual(logq(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1);752 try expectEqual(log_f128(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1);
741 try expectEqual(logq(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1);753 try expectEqual(log_f128(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1);
742 // testing near 1754 // testing near 1
743 try expectEqual(logq(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2);755 try expectEqual(log_f128(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2);
744 try expectEqual(logq(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2);756 try expectEqual(log_f128(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2);
745 try expectEqual(logq(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2);757 try expectEqual(log_f128(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2);
746 try expectEqual(logq(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2);758 try expectEqual(log_f128(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2);
747 try expectEqual(logq(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2);759 try expectEqual(log_f128(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2);
748}760}
lib/compiler_rt/log10.zig+114-102
...@@ -18,19 +18,22 @@ comptime {...@@ -18,19 +18,22 @@ comptime {
18 symbol(&log10f, "log10f");18 symbol(&log10f, "log10f");
19 symbol(&log10, "log10");19 symbol(&log10, "log10");
20 symbol(&__log10x, "__log10x");20 symbol(&__log10x, "__log10x");
21 if (compiler_rt.want_ppc_abi) {21 symbol(&log10q, "log10f128");
22 symbol(&log10q, "log10f128");
23 }
24 symbol(&log10q, "log10q");
25 symbol(&log10l, "log10l");22 symbol(&log10l, "log10l");
26}23}
2724
28pub fn __log10h(a: f16) callconv(.c) f16 {25fn __log10h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
26 return compiler_rt.f16.toAbi(log10_f16(compiler_rt.f16.fromAbi(a)));
27}
28pub fn log10_f16(a: f16) f16 {
29 // TODO: more efficient implementation29 // TODO: more efficient implementation
30 return @floatCast(log10f(a));30 return @floatCast(log10_f32(a));
31}31}
3232
33pub fn log10f(x_: f32) callconv(.c) f32 {33fn log10f(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
34 return compiler_rt.f32.toAbi(log10_f32(compiler_rt.f32.fromAbi(a)));
35}
36pub fn log10_f32(x_: f32) f32 {
34 const ivln10hi: f32 = 4.3432617188e-01;37 const ivln10hi: f32 = 4.3432617188e-01;
35 const ivln10lo: f32 = -3.1689971365e-05;38 const ivln10lo: f32 = -3.1689971365e-05;
36 const log10_2hi: f32 = 3.0102920532e-01;39 const log10_2hi: f32 = 3.0102920532e-01;
...@@ -90,7 +93,10 @@ pub fn log10f(x_: f32) callconv(.c) f32 {...@@ -90,7 +93,10 @@ pub fn log10f(x_: f32) callconv(.c) f32 {
90 return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;93 return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
91}94}
9295
93pub fn log10(x_: f64) callconv(.c) f64 {96fn log10(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
97 return compiler_rt.f64.toAbi(log10_f64(compiler_rt.f64.fromAbi(a)));
98}
99pub fn log10_f64(x_: f64) f64 {
94 const ivln10hi: f64 = 4.34294481878168880939e-01;100 const ivln10hi: f64 = 4.34294481878168880939e-01;
95 const ivln10lo: f64 = 2.50829467116452752298e-11;101 const ivln10lo: f64 = 2.50829467116452752298e-11;
96 const log10_2hi: f64 = 3.01029995663611771306e-01;102 const log10_2hi: f64 = 3.01029995663611771306e-01;
...@@ -165,11 +171,17 @@ pub fn log10(x_: f64) callconv(.c) f64 {...@@ -165,11 +171,17 @@ pub fn log10(x_: f64) callconv(.c) f64 {
165 return val_lo + val_hi;171 return val_lo + val_hi;
166}172}
167173
168pub fn __log10x(a: f80) callconv(.c) f80 {174fn __log10x(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
175 return compiler_rt.f80.toAbi(log10_f80(compiler_rt.f80.fromAbi(a)));
176}
177pub fn log10_f80(a: f80) f80 {
169 // TODO: more efficient implementation178 // TODO: more efficient implementation
170 return @floatCast(log10q(a));179 return @floatCast(log10_f128(a));
171}180}
172181
182fn log10q(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
183 return compiler_rt.f128.toAbi(log10_f128(compiler_rt.f128.fromAbi(a)));
184}
173/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"185/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"
174/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990186/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990
175///187///
...@@ -182,7 +194,7 @@ pub fn __log10x(a: f80) callconv(.c) f80 {...@@ -182,7 +194,7 @@ pub fn __log10x(a: f80) callconv(.c) f80 {
182///194///
183/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):195/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):
184/// <= 0.5 ulp: 99.96%, worst case <= 0.565 ulp196/// <= 0.5 ulp: 99.96%, worst case <= 0.565 ulp
185pub fn log10q(x: f128) callconv(.c) f128 {197pub fn log10_f128(x: f128) f128 {
186 const impl = @import("log_f128.zig");198 const impl = @import("log_f128.zig");
187199
188 if (impl.specialCases(x)) |y|200 if (impl.specialCases(x)) |y|
...@@ -359,124 +371,124 @@ pub fn log10q(x: f128) callconv(.c) f128 {...@@ -359,124 +371,124 @@ pub fn log10q(x: f128) callconv(.c) f128 {
359371
360pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble {372pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble {
361 switch (@typeInfo(c_longdouble).float.bits) {373 switch (@typeInfo(c_longdouble).float.bits) {
362 64 => return log10(x),374 64 => return log10_f64(x),
363 80 => return __log10x(x),375 80 => return log10_f80(x),
364 128 => return log10q(x),376 128 => return log10_f128(x),
365 else => @compileError("unreachable"),377 else => comptime unreachable,
366 }378 }
367}379}
368380
369test "log10f() special" {381test "log10f() special" {
370 try expectEqual(log10f(0.0), -math.inf(f32));382 try expectEqual(log10_f32(0.0), -math.inf(f32));
371 try expectEqual(log10f(-0.0), -math.inf(f32));383 try expectEqual(log10_f32(-0.0), -math.inf(f32));
372 try expect(math.isPositiveZero(log10f(1.0)));384 try expect(math.isPositiveZero(log10_f32(1.0)));
373 try expectEqual(log10f(10.0), 1.0);385 try expectEqual(log10_f32(10.0), 1.0);
374 try expectEqual(log10f(0.1), -1.0);386 try expectEqual(log10_f32(0.1), -1.0);
375 try expectEqual(log10f(math.inf(f32)), math.inf(f32));387 try expectEqual(log10_f32(math.inf(f32)), math.inf(f32));
376 try expect(math.isNan(log10f(-1.0)));388 try expect(math.isNan(log10_f32(-1.0)));
377 try expect(math.isNan(log10f(-math.inf(f32))));389 try expect(math.isNan(log10_f32(-math.inf(f32))));
378 try expect(math.isNan(log10f(math.nan(f32))));390 try expect(math.isNan(log10_f32(math.nan(f32))));
379 try expect(math.isNan(log10f(math.snan(f32))));391 try expect(math.isNan(log10_f32(math.snan(f32))));
380}392}
381393
382test "log10f() sanity" {394test "log10f() sanity" {
383 try expect(math.isNan(log10f(-0x1.0223a0p+3)));395 try expect(math.isNan(log10_f32(-0x1.0223a0p+3)));
384 try expectEqual(log10f(0x1.161868p+2), 0x1.46a9bcp-1);396 try expectEqual(log10_f32(0x1.161868p+2), 0x1.46a9bcp-1);
385 try expect(math.isNan(log10f(-0x1.0c34b4p+3)));397 try expect(math.isNan(log10_f32(-0x1.0c34b4p+3)));
386 try expect(math.isNan(log10f(-0x1.a206f0p+2)));398 try expect(math.isNan(log10_f32(-0x1.a206f0p+2)));
387 try expectEqual(log10f(0x1.288bbcp+3), 0x1.ef1300p-1);399 try expectEqual(log10_f32(0x1.288bbcp+3), 0x1.ef1300p-1);
388 try expectEqual(log10f(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit400 try expectEqual(log10_f32(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit
389 try expect(math.isNan(log10f(-0x1.a05cc8p-2)));401 try expect(math.isNan(log10_f32(-0x1.a05cc8p-2)));
390 try expectEqual(log10f(0x1.1f9efap-1), -0x1.0075ccp-2);402 try expectEqual(log10_f32(0x1.1f9efap-1), -0x1.0075ccp-2);
391 try expectEqual(log10f(0x1.8c5db0p-1), -0x1.c75df8p-4);403 try expectEqual(log10_f32(0x1.8c5db0p-1), -0x1.c75df8p-4);
392 try expect(math.isNan(log10f(-0x1.5b86eap-1)));404 try expect(math.isNan(log10_f32(-0x1.5b86eap-1)));
393}405}
394406
395test "log10f() boundary" {407test "log10f() boundary" {
396 try expectEqual(log10f(0x1.fffffep+127), 0x1.344136p+5); // Max input value408 try expectEqual(log10_f32(0x1.fffffep+127), 0x1.344136p+5); // Max input value
397 try expectEqual(log10f(0x1p-149), -0x1.66d3e8p+5); // Min positive input value409 try expectEqual(log10_f32(0x1p-149), -0x1.66d3e8p+5); // Min positive input value
398 try expect(math.isNan(log10f(-0x1p-149))); // Min negative input value410 try expect(math.isNan(log10_f32(-0x1p-149))); // Min negative input value
399 try expectEqual(log10f(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0411 try expectEqual(log10_f32(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0
400 try expectEqual(log10f(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0412 try expectEqual(log10_f32(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0
401 try expectEqual(log10f(0x1p-126), -0x1.2f7030p+5); // First subnormal413 try expectEqual(log10_f32(0x1p-126), -0x1.2f7030p+5); // First subnormal
402 try expect(math.isNan(log10f(-0x1p-126))); // First negative subnormal414 try expect(math.isNan(log10_f32(-0x1p-126))); // First negative subnormal
403}415}
404416
405test "log10() special" {417test "log10() special" {
406 try expectEqual(log10(0.0), -math.inf(f64));418 try expectEqual(log10_f64(0.0), -math.inf(f64));
407 try expectEqual(log10(-0.0), -math.inf(f64));419 try expectEqual(log10_f64(-0.0), -math.inf(f64));
408 try expect(math.isPositiveZero(log10(1.0)));420 try expect(math.isPositiveZero(log10_f64(1.0)));
409 try expectEqual(log10(10.0), 1.0);421 try expectEqual(log10_f64(10.0), 1.0);
410 try expectEqual(log10(0.1), -1.0);422 try expectEqual(log10_f64(0.1), -1.0);
411 try expectEqual(log10(math.inf(f64)), math.inf(f64));423 try expectEqual(log10_f64(math.inf(f64)), math.inf(f64));
412 try expect(math.isNan(log10(-1.0)));424 try expect(math.isNan(log10_f64(-1.0)));
413 try expect(math.isNan(log10(-math.inf(f64))));425 try expect(math.isNan(log10_f64(-math.inf(f64))));
414 try expect(math.isNan(log10(math.nan(f64))));426 try expect(math.isNan(log10_f64(math.nan(f64))));
415 try expect(math.isNan(log10(math.snan(f64))));427 try expect(math.isNan(log10_f64(math.snan(f64))));
416}428}
417429
418test "log10() sanity" {430test "log10() sanity" {
419 try expect(math.isNan(log10(-0x1.02239f3c6a8f1p+3)));431 try expect(math.isNan(log10_f64(-0x1.02239f3c6a8f1p+3)));
420 try expectEqual(log10(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1);432 try expectEqual(log10_f64(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1);
421 try expect(math.isNan(log10(-0x1.0c34b3e01e6e7p+3)));433 try expect(math.isNan(log10_f64(-0x1.0c34b3e01e6e7p+3)));
422 try expect(math.isNan(log10(-0x1.a206f0a19dcc4p+2)));434 try expect(math.isNan(log10_f64(-0x1.a206f0a19dcc4p+2)));
423 try expectEqual(log10(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1);435 try expectEqual(log10_f64(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1);
424 try expectEqual(log10(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3);436 try expectEqual(log10_f64(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3);
425 try expect(math.isNan(log10(-0x1.a05cc754481d1p-2)));437 try expect(math.isNan(log10_f64(-0x1.a05cc754481d1p-2)));
426 try expectEqual(log10(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2);438 try expectEqual(log10_f64(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2);
427 try expectEqual(log10(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4);439 try expectEqual(log10_f64(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4);
428 try expect(math.isNan(log10(-0x1.5b86ea8118a0ep-1)));440 try expect(math.isNan(log10_f64(-0x1.5b86ea8118a0ep-1)));
429}441}
430442
431test "log10() boundary" {443test "log10() boundary" {
432 try expectEqual(log10(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value444 try expectEqual(log10_f64(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value
433 try expectEqual(log10(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value445 try expectEqual(log10_f64(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value
434 try expect(math.isNan(log10(-0x1p-1074))); // Min negative input value446 try expect(math.isNan(log10_f64(-0x1p-1074))); // Min negative input value
435 try expectEqual(log10(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0447 try expectEqual(log10_f64(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0
436 try expectEqual(log10(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0448 try expectEqual(log10_f64(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0
437 try expectEqual(log10(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal449 try expectEqual(log10_f64(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal
438 try expect(math.isNan(log10(-0x1p-1022))); // First negative subnormal450 try expect(math.isNan(log10_f64(-0x1p-1022))); // First negative subnormal
439}451}
440452
441test "log10q() special" {453test "log10q() special" {
442 try expectEqual(log10q(0.0), -math.inf(f128));454 try expectEqual(log10_f128(0.0), -math.inf(f128));
443 try expectEqual(log10q(-0.0), -math.inf(f128));455 try expectEqual(log10_f128(-0.0), -math.inf(f128));
444 try expect(math.isPositiveZero(log10q(1.0)));456 try expect(math.isPositiveZero(log10_f128(1.0)));
445 try expectEqual(log10q(10.0), 1.0);457 try expectEqual(log10_f128(10.0), 1.0);
446 try expectEqual(log10q(0.1), -1.0);458 try expectEqual(log10_f128(0.1), -1.0);
447 try expectEqual(log10q(math.inf(f128)), math.inf(f128));459 try expectEqual(log10_f128(math.inf(f128)), math.inf(f128));
448 try expect(math.isNan(log10q(-1.0)));460 try expect(math.isNan(log10_f128(-1.0)));
449 try expect(math.isNan(log10q(-math.inf(f128))));461 try expect(math.isNan(log10_f128(-math.inf(f128))));
450 try expect(math.isNan(log10q(math.nan(f128))));462 try expect(math.isNan(log10_f128(math.nan(f128))));
451 try expect(math.isNan(log10q(math.snan(f128))));463 try expect(math.isNan(log10_f128(math.snan(f128))));
452}464}
453465
454test "log10q() sanity" {466test "log10q() sanity" {
455 try expectEqual(log10q(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3);467 try expectEqual(log10_f128(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3);
456 try expectEqual(log10q(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3);468 try expectEqual(log10_f128(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3);
457 try expectEqual(log10q(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2);469 try expectEqual(log10_f128(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2);
458 try expectEqual(log10q(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3);470 try expectEqual(log10_f128(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3);
459 try expectEqual(log10q(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3);471 try expectEqual(log10_f128(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3);
460 try expectEqual(log10q(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3);472 try expectEqual(log10_f128(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3);
461 try expectEqual(log10q(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3);473 try expectEqual(log10_f128(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3);
462 try expectEqual(log10q(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3);474 try expectEqual(log10_f128(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3);
463 try expectEqual(log10q(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3);475 try expectEqual(log10_f128(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3);
464 try expectEqual(log10q(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2);476 try expectEqual(log10_f128(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2);
465 // testing near 1477 // testing near 1
466 try expectEqual(log10q(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2);478 try expectEqual(log10_f128(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2);
467 try expectEqual(log10q(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2);479 try expectEqual(log10_f128(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2);
468 try expectEqual(log10q(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3);480 try expectEqual(log10_f128(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3);
469 try expectEqual(log10q(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2);481 try expectEqual(log10_f128(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2);
470 try expectEqual(log10q(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3);482 try expectEqual(log10_f128(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3);
471 try expectEqual(log10q(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2);483 try expectEqual(log10_f128(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2);
472}484}
473485
474test "log10q() boundary" {486test "log10q() boundary" {
475 try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value487 try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value
476 try expectEqual(log10q(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value488 try expectEqual(log10_f128(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value
477 try expect(math.isNan(log10q(-0x1p-16494))); // Min negative input value489 try expect(math.isNan(log10_f128(-0x1p-16494))); // Min negative input value
478 try expectEqual(log10q(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0490 try expectEqual(log10_f128(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0
479 try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0491 try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0
480 try expectEqual(log10q(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal492 try expectEqual(log10_f128(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal
481 try expect(math.isNan(log10q(-0x1p-16382))); // First negative subnormal493 try expect(math.isNan(log10_f128(-0x1p-16382))); // First negative subnormal
482}494}
lib/compiler_rt/log2.zig+106-94
...@@ -19,19 +19,22 @@ comptime {...@@ -19,19 +19,22 @@ comptime {
19 symbol(&log2f, "log2f");19 symbol(&log2f, "log2f");
20 symbol(&log2, "log2");20 symbol(&log2, "log2");
21 symbol(&__log2x, "__log2x");21 symbol(&__log2x, "__log2x");
22 if (compiler_rt.want_ppc_abi) {22 symbol(&log2q, "log2f128");
23 symbol(&log2q, "log2f128");
24 }
25 symbol(&log2q, "log2q");
26 symbol(&log2l, "log2l");23 symbol(&log2l, "log2l");
27}24}
2825
29pub fn __log2h(a: f16) callconv(.c) f16 {26fn __log2h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
27 return compiler_rt.f16.toAbi(log2_f16(compiler_rt.f16.fromAbi(a)));
28}
29pub fn log2_f16(a: f16) f16 {
30 // TODO: more efficient implementation30 // TODO: more efficient implementation
31 return @floatCast(log2f(a));31 return @floatCast(log2_f32(a));
32}32}
3333
34pub fn log2f(x_: f32) callconv(.c) f32 {34fn log2f(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
35 return compiler_rt.f32.toAbi(log2_f32(compiler_rt.f32.fromAbi(a)));
36}
37pub fn log2_f32(x_: f32) f32 {
35 const ivln2hi: f32 = 1.4428710938e+00;38 const ivln2hi: f32 = 1.4428710938e+00;
36 const ivln2lo: f32 = -1.7605285393e-04;39 const ivln2lo: f32 = -1.7605285393e-04;
37 const Lg1: f32 = 0xaaaaaa.0p-24;40 const Lg1: f32 = 0xaaaaaa.0p-24;
...@@ -87,7 +90,10 @@ pub fn log2f(x_: f32) callconv(.c) f32 {...@@ -87,7 +90,10 @@ pub fn log2f(x_: f32) callconv(.c) f32 {
87 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k));90 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k));
88}91}
8992
90pub fn log2(x_: f64) callconv(.c) f64 {93fn log2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
94 return compiler_rt.f64.toAbi(log2_f64(compiler_rt.f64.fromAbi(a)));
95}
96pub fn log2_f64(x_: f64) f64 {
91 const ivln2hi: f64 = 1.44269504072144627571e+00;97 const ivln2hi: f64 = 1.44269504072144627571e+00;
92 const ivln2lo: f64 = 1.67517131648865118353e-10;98 const ivln2lo: f64 = 1.67517131648865118353e-10;
93 const Lg1: f64 = 6.666666666666735130e-01;99 const Lg1: f64 = 6.666666666666735130e-01;
...@@ -158,11 +164,17 @@ pub fn log2(x_: f64) callconv(.c) f64 {...@@ -158,11 +164,17 @@ pub fn log2(x_: f64) callconv(.c) f64 {
158 return val_lo + val_hi;164 return val_lo + val_hi;
159}165}
160166
161pub fn __log2x(a: f80) callconv(.c) f80 {167fn __log2x(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
168 return compiler_rt.f80.toAbi(log2_f80(compiler_rt.f80.fromAbi(a)));
169}
170pub fn log2_f80(a: f80) f80 {
162 // TODO: more efficient implementation171 // TODO: more efficient implementation
163 return @floatCast(log2q(a));172 return @floatCast(log2_f128(a));
164}173}
165174
175fn log2q(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
176 return compiler_rt.f128.toAbi(log2_f128(compiler_rt.f128.fromAbi(a)));
177}
166/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"178/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"
167/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990179/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990
168///180///
...@@ -175,7 +187,7 @@ pub fn __log2x(a: f80) callconv(.c) f80 {...@@ -175,7 +187,7 @@ pub fn __log2x(a: f80) callconv(.c) f80 {
175///187///
176/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):188/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):
177/// <= 0.5 ulp: 99.86%, worst case <= 0.546 ulp189/// <= 0.5 ulp: 99.86%, worst case <= 0.546 ulp
178pub fn log2q(x: f128) callconv(.c) f128 {190pub fn log2_f128(x: f128) f128 {
179 const impl = @import("log_f128.zig");191 const impl = @import("log_f128.zig");
180192
181 if (impl.specialCases(x)) |y|193 if (impl.specialCases(x)) |y|
...@@ -351,117 +363,117 @@ pub fn log2q(x: f128) callconv(.c) f128 {...@@ -351,117 +363,117 @@ pub fn log2q(x: f128) callconv(.c) f128 {
351363
352pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble {364pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble {
353 switch (@typeInfo(c_longdouble).float.bits) {365 switch (@typeInfo(c_longdouble).float.bits) {
354 64 => return log2(x),366 64 => return log2_f64(x),
355 80 => return __log2x(x),367 80 => return log2_f80(x),
356 128 => return log2q(x),368 128 => return log2_f128(x),
357 else => @compileError("unreachable"),369 else => comptime unreachable,
358 }370 }
359}371}
360372
361test "log2f() special" {373test "log2f() special" {
362 try expectEqual(log2f(0.0), -math.inf(f32));374 try expectEqual(log2_f32(0.0), -math.inf(f32));
363 try expectEqual(log2f(-0.0), -math.inf(f32));375 try expectEqual(log2_f32(-0.0), -math.inf(f32));
364 try expect(math.isPositiveZero(log2f(1.0)));376 try expect(math.isPositiveZero(log2_f32(1.0)));
365 try expectEqual(log2f(2.0), 1.0);377 try expectEqual(log2_f32(2.0), 1.0);
366 try expectEqual(log2f(math.inf(f32)), math.inf(f32));378 try expectEqual(log2_f32(math.inf(f32)), math.inf(f32));
367 try expect(math.isNan(log2f(-1.0)));379 try expect(math.isNan(log2_f32(-1.0)));
368 try expect(math.isNan(log2f(-math.inf(f32))));380 try expect(math.isNan(log2_f32(-math.inf(f32))));
369 try expect(math.isNan(log2f(math.nan(f32))));381 try expect(math.isNan(log2_f32(math.nan(f32))));
370 try expect(math.isNan(log2f(math.snan(f32))));382 try expect(math.isNan(log2_f32(math.snan(f32))));
371}383}
372384
373test "log2f() sanity" {385test "log2f() sanity" {
374 try expect(math.isNan(log2f(-0x1.0223a0p+3)));386 try expect(math.isNan(log2_f32(-0x1.0223a0p+3)));
375 try expectEqual(log2f(0x1.161868p+2), 0x1.0f49acp+1);387 try expectEqual(log2_f32(0x1.161868p+2), 0x1.0f49acp+1);
376 try expect(math.isNan(log2f(-0x1.0c34b4p+3)));388 try expect(math.isNan(log2_f32(-0x1.0c34b4p+3)));
377 try expect(math.isNan(log2f(-0x1.a206f0p+2)));389 try expect(math.isNan(log2_f32(-0x1.a206f0p+2)));
378 try expectEqual(log2f(0x1.288bbcp+3), 0x1.9b2676p+1);390 try expectEqual(log2_f32(0x1.288bbcp+3), 0x1.9b2676p+1);
379 try expectEqual(log2f(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit391 try expectEqual(log2_f32(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit
380 try expect(math.isNan(log2f(-0x1.a05cc8p-2)));392 try expect(math.isNan(log2_f32(-0x1.a05cc8p-2)));
381 try expectEqual(log2f(0x1.1f9efap-1), -0x1.a9f89ap-1);393 try expectEqual(log2_f32(0x1.1f9efap-1), -0x1.a9f89ap-1);
382 try expectEqual(log2f(0x1.8c5db0p-1), -0x1.7a2c96p-2);394 try expectEqual(log2_f32(0x1.8c5db0p-1), -0x1.7a2c96p-2);
383 try expect(math.isNan(log2f(-0x1.5b86eap-1)));395 try expect(math.isNan(log2_f32(-0x1.5b86eap-1)));
384}396}
385397
386test "log2f() boundary" {398test "log2f() boundary" {
387 try expectEqual(log2f(0x1.fffffep+127), 0x1p+7); // Max input value399 try expectEqual(log2_f32(0x1.fffffep+127), 0x1p+7); // Max input value
388 try expectEqual(log2f(0x1p-149), -0x1.2ap+7); // Min positive input value400 try expectEqual(log2_f32(0x1p-149), -0x1.2ap+7); // Min positive input value
389 try expect(math.isNan(log2f(-0x1p-149))); // Min negative input value401 try expect(math.isNan(log2_f32(-0x1p-149))); // Min negative input value
390 try expectEqual(log2f(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0402 try expectEqual(log2_f32(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0
391 try expectEqual(log2f(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0403 try expectEqual(log2_f32(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0
392 try expectEqual(log2f(0x1p-126), -0x1.f8p+6); // First subnormal404 try expectEqual(log2_f32(0x1p-126), -0x1.f8p+6); // First subnormal
393 try expect(math.isNan(log2f(-0x1p-126))); // First negative subnormal405 try expect(math.isNan(log2_f32(-0x1p-126))); // First negative subnormal
394406
395}407}
396408
397test "log2() special" {409test "log2() special" {
398 try expectEqual(log2(0.0), -math.inf(f64));410 try expectEqual(log2_f64(0.0), -math.inf(f64));
399 try expectEqual(log2(-0.0), -math.inf(f64));411 try expectEqual(log2_f64(-0.0), -math.inf(f64));
400 try expect(math.isPositiveZero(log2(1.0)));412 try expect(math.isPositiveZero(log2_f64(1.0)));
401 try expectEqual(log2(2.0), 1.0);413 try expectEqual(log2_f64(2.0), 1.0);
402 try expectEqual(log2(math.inf(f64)), math.inf(f64));414 try expectEqual(log2_f64(math.inf(f64)), math.inf(f64));
403 try expect(math.isNan(log2(-1.0)));415 try expect(math.isNan(log2_f64(-1.0)));
404 try expect(math.isNan(log2(-math.inf(f64))));416 try expect(math.isNan(log2_f64(-math.inf(f64))));
405 try expect(math.isNan(log2(math.nan(f64))));417 try expect(math.isNan(log2_f64(math.nan(f64))));
406 try expect(math.isNan(log2(math.snan(f64))));418 try expect(math.isNan(log2_f64(math.snan(f64))));
407}419}
408420
409test "log2() sanity" {421test "log2() sanity" {
410 try expect(math.isNan(log2(-0x1.02239f3c6a8f1p+3)));422 try expect(math.isNan(log2_f64(-0x1.02239f3c6a8f1p+3)));
411 try expectEqual(log2(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1);423 try expectEqual(log2_f64(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1);
412 try expect(math.isNan(log2(-0x1.0c34b3e01e6e7p+3)));424 try expect(math.isNan(log2_f64(-0x1.0c34b3e01e6e7p+3)));
413 try expect(math.isNan(log2(-0x1.a206f0a19dcc4p+2)));425 try expect(math.isNan(log2_f64(-0x1.a206f0a19dcc4p+2)));
414 try expectEqual(log2(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1);426 try expectEqual(log2_f64(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1);
415 try expectEqual(log2(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1);427 try expectEqual(log2_f64(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1);
416 try expect(math.isNan(log2(-0x1.a05cc754481d1p-2)));428 try expect(math.isNan(log2_f64(-0x1.a05cc754481d1p-2)));
417 try expectEqual(log2(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1);429 try expectEqual(log2_f64(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1);
418 try expectEqual(log2(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2);430 try expectEqual(log2_f64(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2);
419 try expect(math.isNan(log2(-0x1.5b86ea8118a0ep-1)));431 try expect(math.isNan(log2_f64(-0x1.5b86ea8118a0ep-1)));
420}432}
421433
422test "log2() boundary" {434test "log2() boundary" {
423 try expectEqual(log2(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value435 try expectEqual(log2_f64(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value
424 try expectEqual(log2(0x1p-1074), -0x1.0c8p+10); // Min positive input value436 try expectEqual(log2_f64(0x1p-1074), -0x1.0c8p+10); // Min positive input value
425 try expect(math.isNan(log2(-0x1p-1074))); // Min negative input value437 try expect(math.isNan(log2_f64(-0x1p-1074))); // Min negative input value
426 try expectEqual(log2(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0438 try expectEqual(log2_f64(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0
427 try expectEqual(log2(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0439 try expectEqual(log2_f64(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0
428 try expectEqual(log2(0x1p-1022), -0x1.ffp+9); // First subnormal440 try expectEqual(log2_f64(0x1p-1022), -0x1.ffp+9); // First subnormal
429 try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal441 try expect(math.isNan(log2_f64(-0x1p-1022))); // First negative subnormal
430}442}
431443
432test "log2q() special" {444test "log2q() special" {
433 try expectEqual(log2q(0.0), -math.inf(f128));445 try expectEqual(log2_f128(0.0), -math.inf(f128));
434 try expectEqual(log2q(-0.0), -math.inf(f128));446 try expectEqual(log2_f128(-0.0), -math.inf(f128));
435 try expect(math.isPositiveZero(log2q(1.0)));447 try expect(math.isPositiveZero(log2_f128(1.0)));
436 try expectEqual(log2q(2.0), 1.0);448 try expectEqual(log2_f128(2.0), 1.0);
437 try expectEqual(log2q(math.inf(f128)), math.inf(f128));449 try expectEqual(log2_f128(math.inf(f128)), math.inf(f128));
438 try expect(math.isNan(log2q(-1.0)));450 try expect(math.isNan(log2_f128(-1.0)));
439 try expect(math.isNan(log2q(-math.inf(f128))));451 try expect(math.isNan(log2_f128(-math.inf(f128))));
440 try expect(math.isNan(log2q(math.nan(f128))));452 try expect(math.isNan(log2_f128(math.nan(f128))));
441 try expect(math.isNan(log2q(math.snan(f128))));453 try expect(math.isNan(log2_f128(math.snan(f128))));
442}454}
443455
444test "log2q() boundary" {456test "log2q() boundary" {
445 try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value457 try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value
446 try expectEqual(log2q(0x1p-16494), -0x1.01b8p14); // Min positive input value458 try expectEqual(log2_f128(0x1p-16494), -0x1.01b8p14); // Min positive input value
447 try expect(math.isNan(log2q(-0x1p-16494))); // Min negative input value459 try expect(math.isNan(log2_f128(-0x1p-16494))); // Min negative input value
448 try expectEqual(log2q(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0460 try expectEqual(log2_f128(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0
449 try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0461 try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0
450 try expectEqual(log2q(0x1p-16382), -0x1.fffp13); // First subnormal462 try expectEqual(log2_f128(0x1p-16382), -0x1.fffp13); // First subnormal
451 try expect(math.isNan(log2q(-0x1p-16382))); // First negative subnormal463 try expect(math.isNan(log2_f128(-0x1p-16382))); // First negative subnormal
452}464}
453465
454test "log2q() sanity" {466test "log2q() sanity" {
455 try expectEqual(log2q(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1);467 try expectEqual(log2_f128(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1);
456 try expectEqual(log2q(8.346531942223744e15), 5.28900982928636641107356163006646e1);468 try expectEqual(log2_f128(8.346531942223744e15), 5.28900982928636641107356163006646e1);
457 try expectEqual(log2q(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1);469 try expectEqual(log2_f128(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1);
458 try expectEqual(log2q(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1);470 try expectEqual(log2_f128(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1);
459 try expectEqual(log2q(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1);471 try expectEqual(log2_f128(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1);
460 try expectEqual(log2q(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1);472 try expectEqual(log2_f128(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1);
461 // test near 1473 // test near 1
462 try expectEqual(log2q(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2);474 try expectEqual(log2_f128(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2);
463 try expectEqual(log2q(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4);475 try expectEqual(log2_f128(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4);
464 try expectEqual(log2q(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2);476 try expectEqual(log2_f128(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2);
465 try expectEqual(log2q(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2);477 try expectEqual(log2_f128(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2);
466 try expectEqual(log2q(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2);478 try expectEqual(log2_f128(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2);
467}479}
lib/compiler_rt/mulc3.zig+75-10
...@@ -3,19 +3,80 @@ const isNan = std.math.isNan;...@@ -3,19 +3,80 @@ const isNan = std.math.isNan;
3const isInf = std.math.isInf;3const isInf = std.math.isInf;
4const copysign = std.math.copysign;4const copysign = std.math.copysign;
55
6pub fn Complex(comptime T: type) type {6const compiler_rt = @import("../compiler_rt.zig");
7 return extern struct {7const symbol = compiler_rt.symbol;
8 real: T,8const Complex = compiler_rt.Complex;
9 imag: T,9
10 };10comptime {
11 if (@import("builtin").zig_backend != .stage2_c) {
12 symbol(&__mulhc3, "__mulhc3");
13 symbol(&__mulsc3, "__mulsc3");
14 symbol(&__muldc3, "__muldc3");
15 symbol(&__mulxc3, "__mulxc3");
16 if (compiler_rt.want_ppc_abi) {
17 symbol(&__multc3, "__mulkc3");
18 } else {
19 symbol(&__multc3, "__multc3");
20 }
21 }
22}
23
24fn __mulhc3(lhs_real: compiler_rt.f16.Abi, lhs_imag: compiler_rt.f16.Abi, rhs_real: compiler_rt.f16.Abi, rhs_imag: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.complex.Abi {
25 return compiler_rt.f16.complex.toAbi(mul_cf16(
26 compiler_rt.f16.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
27 compiler_rt.f16.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
28 ));
29}
30pub fn mul_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) {
31 return mulc3(f16, a, b);
32}
33
34fn __mulsc3(lhs_real: compiler_rt.f32.Abi, lhs_imag: compiler_rt.f32.Abi, rhs_real: compiler_rt.f32.Abi, rhs_imag: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.complex.Abi {
35 return compiler_rt.f32.complex.toAbi(mul_cf32(
36 compiler_rt.f32.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
37 compiler_rt.f32.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
38 ));
39}
40pub fn mul_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) {
41 return mulc3(f32, a, b);
42}
43
44fn __muldc3(lhs_real: compiler_rt.f64.Abi, lhs_imag: compiler_rt.f64.Abi, rhs_real: compiler_rt.f64.Abi, rhs_imag: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.complex.Abi {
45 return compiler_rt.f64.complex.toAbi(mul_cf64(
46 compiler_rt.f64.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
47 compiler_rt.f64.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
48 ));
49}
50pub fn mul_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) {
51 return mulc3(f64, a, b);
52}
53
54fn __mulxc3(lhs_real: compiler_rt.f80.Abi, lhs_imag: compiler_rt.f80.Abi, rhs_real: compiler_rt.f80.Abi, rhs_imag: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.complex.Abi {
55 return compiler_rt.f80.complex.toAbi(mul_cf80(
56 compiler_rt.f80.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
57 compiler_rt.f80.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
58 ));
59}
60pub fn mul_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) {
61 return mulc3(f80, a, b);
62}
63
64fn __multc3(lhs_real: compiler_rt.f128.Abi, lhs_imag: compiler_rt.f128.Abi, rhs_real: compiler_rt.f128.Abi, rhs_imag: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.complex.Abi {
65 return compiler_rt.f128.complex.toAbi(mul_cf128(
66 compiler_rt.f128.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }),
67 compiler_rt.f128.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }),
68 ));
69}
70pub fn mul_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) {
71 return mulc3(f128, a, b);
11}72}
1273
13/// Implementation based on Annex G of C17 Standard (N2176)74/// Implementation based on Annex G of C17 Standard (N2176)
14pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Complex(T) {75inline fn mulc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) {
15 var a = a_in;76 var a = lhs.real;
16 var b = b_in;77 var b = lhs.imag;
17 var c = c_in;78 var c = rhs.real;
18 var d = d_in;79 var d = rhs.imag;
1980
20 const ac = a * c;81 const ac = a * c;
21 const bd = b * d;82 const bd = b * d;
...@@ -77,3 +138,7 @@ pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Comple...@@ -77,3 +138,7 @@ pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Comple
77 }138 }
78 return z;139 return z;
79}140}
141
142test {
143 _ = @import("mulc3_test.zig");
144}
lib/compiler_rt/mulc3_test.zig+23-42
...@@ -2,64 +2,45 @@ const std = @import("std");...@@ -2,64 +2,45 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5const Complex = @import("./mulc3.zig").Complex;5const Complex = @import("../compiler_rt.zig").Complex;
6const __mulhc3 = @import("./mulhc3.zig").__mulhc3;6const impl = @import("mulc3.zig");
7const __mulsc3 = @import("./mulsc3.zig").__mulsc3;7const mul_cf16 = impl.mul_cf16;
8const __muldc3 = @import("./muldc3.zig").__muldc3;8const mul_cf32 = impl.mul_cf32;
9const __mulxc3 = @import("./mulxc3.zig").__mulxc3;9const mul_cf64 = impl.mul_cf64;
10const __multc3 = @import("./multc3.zig").__multc3;10const mul_cf80 = impl.mul_cf80;
11const mul_cf128 = impl.mul_cf128;
1112
12test "mulc3" {13test "mulc3" {
13 try testMul(f16, __mulhc3);14 try testMul(f16, mul_cf16);
14 try testMul(f32, __mulsc3);15 try testMul(f32, mul_cf32);
15 try testMul(f64, __muldc3);16 try testMul(f64, mul_cf64);
16 try testMul(f80, __mulxc3);17 try testMul(f80, mul_cf80);
17 try testMul(f128, __multc3);18 try testMul(f128, mul_cf128);
18}19}
1920
20fn testMul(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void {21fn testMul(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void {
21 {22 {
22 const a: T = 1.0;23 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 });
23 const b: T = 0.0;
24 const c: T = -1.0;
25 const d: T = 0.0;
26
27 const result = f(a, b, c, d);
28 try expect(result.real == -1.0);24 try expect(result.real == -1.0);
29 try expect(result.imag == 0.0);25 try expect(math.isPositiveZero(result.imag));
30 }26 }
31 {27 {
32 const a: T = 1.0;28 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 });
33 const b: T = 0.0;
34 const c: T = -4.0;
35 const d: T = 0.0;
36
37 const result = f(a, b, c, d);
38 try expect(result.real == -4.0);29 try expect(result.real == -4.0);
39 try expect(result.imag == 0.0);30 try expect(math.isPositiveZero(result.imag));
40 }31 }
41 {32 {
42 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,33 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,
43 // then the result of the * operator is an infinity;34 // then the result of the * operator is an infinity;
44 const a: T = math.inf(T);35 const result = f(.{ .real = math.inf(T), .imag = -math.inf(T) }, .{ .real = 1.0, .imag = 0.0 });
45 const b: T = -math.inf(T);36 try expect(math.isPositiveInf(result.real));
46 const c: T = 1.0;37 try expect(math.isNegativeInf(result.imag));
47 const d: T = 0.0;
48
49 const result = f(a, b, c, d);
50 try expect(result.real == math.inf(T));
51 try expect(result.imag == -math.inf(T));
52 }38 }
53 {39 {
54 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,40 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,
55 // then the result of the * operator is an infinity;41 // then the result of the * operator is an infinity;
56 const a: T = math.inf(T);42 const result = f(.{ .real = math.inf(T), .imag = -1.0 }, .{ .real = 1.0, .imag = math.inf(T) });
57 const b: T = -1.0;43 try expect(math.isPositiveInf(result.real));
58 const c: T = 1.0;44 try expect(math.isPositiveInf(result.imag));
59 const d: T = math.inf(T);
60
61 const result = f(a, b, c, d);
62 try expect(result.real == math.inf(T));
63 try expect(result.imag == math.inf(T));
64 }45 }
65}46}
lib/compiler_rt/muldc3.zig deleted-12
...@@ -1,12 +0,0 @@
1const mulc3 = @import("./mulc3.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3
4comptime {
5 if (@import("builtin").zig_backend != .stage2_c) {
6 symbol(&__muldc3, "__muldc3");
7 }
8}
9
10pub fn __muldc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) mulc3.Complex(f64) {
11 return mulc3.mulc3(f64, a, b, c, d);
12}
lib/compiler_rt/muldf3.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_dmul, "__aeabi_dmul");
8 } else {
9 symbol(&__muldf3, "__muldf3");
10 }
11}
12
13pub fn __muldf3(a: f64, b: f64) callconv(.c) f64 {
14 return mulf3(f64, a, b);
15}
16
17fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
18 return mulf3(f64, a, b);
19}
lib/compiler_rt/mulf3.zig+67-1
...@@ -2,10 +2,76 @@ const std = @import("std");...@@ -2,10 +2,76 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const compiler_rt = @import("../compiler_rt.zig");4const compiler_rt = @import("../compiler_rt.zig");
5const symbol = compiler_rt.symbol;
6
7comptime {
8 symbol(&__mulhf3, "__mulhf3");
9 if (compiler_rt.want_aeabi) {
10 symbol(&__aeabi_fmul, "__aeabi_fmul");
11 symbol(&__aeabi_dmul, "__aeabi_dmul");
12 } else {
13 symbol(&__mulsf3, "__mulsf3");
14 symbol(&__muldf3, "__muldf3");
15 }
16 symbol(&__mulxf3, "__mulxf3");
17 if (compiler_rt.want_ppc_abi) {
18 symbol(&__multf3, "__mulkf3");
19 } else if (compiler_rt.want_sparc64_abi) {
20 symbol(&_Qp_mul, "_Qp_mul");
21 } else if (compiler_rt.want_sparc32_abi) {
22 symbol(&__multf3, "_Q_mul");
23 } else {
24 symbol(&__multf3, "__multf3");
25 }
26}
27
28fn __mulhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
29 return compiler_rt.f16.toAbi(mul_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
30}
31pub fn mul_f16(a: f16, b: f16) f16 {
32 return mulf3(f16, a, b);
33}
34
35fn __mulsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
36 return compiler_rt.f32.toAbi(mul_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)));
37}
38fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
39 return mul_f32(a, b);
40}
41pub fn mul_f32(a: f32, b: f32) f32 {
42 return mulf3(f32, a, b);
43}
44
45fn __muldf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
46 return compiler_rt.f64.toAbi(mul_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)));
47}
48fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
49 return mul_f64(a, b);
50}
51pub fn mul_f64(a: f64, b: f64) f64 {
52 return mulf3(f64, a, b);
53}
54
55fn __mulxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
56 return compiler_rt.f80.toAbi(mul_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)));
57}
58pub fn mul_f80(a: f80, b: f80) f80 {
59 return mulf3(f80, a, b);
60}
61
62fn __multf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
63 return compiler_rt.f128.toAbi(mul_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)));
64}
65fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {
66 c.* = mul_f128(a.*, b.*);
67}
68pub fn mul_f128(a: f128, b: f128) f128 {
69 return mulf3(f128, a, b);
70}
571
6/// Ported from:72/// Ported from:
7/// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc73/// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc
8pub inline fn mulf3(comptime T: type, a: T, b: T) T {74inline fn mulf3(comptime T: type, a: T, b: T) T {
9 @setRuntimeSafety(compiler_rt.test_safety);75 @setRuntimeSafety(compiler_rt.test_safety);
10 const typeWidth = @typeInfo(T).float.bits;76 const typeWidth = @typeInfo(T).float.bits;
11 const significandBits = math.floatMantissaBits(T);77 const significandBits = math.floatMantissaBits(T);
lib/compiler_rt/mulf3_test.zig+48-46
...@@ -7,10 +7,12 @@ const math = std.math;...@@ -7,10 +7,12 @@ const math = std.math;
7const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);7const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);
8const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64);8const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64);
99
10const __multf3 = @import("multf3.zig").__multf3;10const impl = @import("mulf3.zig");
11const __mulxf3 = @import("mulxf3.zig").__mulxf3;11const mul_f16 = impl.mul_f16;
12const __muldf3 = @import("muldf3.zig").__muldf3;12const mul_f32 = impl.mul_f32;
13const __mulsf3 = @import("mulsf3.zig").__mulsf3;13const mul_f64 = impl.mul_f64;
14const mul_f80 = impl.mul_f80;
15const mul_f128 = impl.mul_f128;
1416
15// return true if equal17// return true if equal
16// use two 64-bit integers instead of one 128-bit integer18// use two 64-bit integers instead of one 128-bit integer
...@@ -34,8 +36,8 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {...@@ -34,8 +36,8 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
34 return false;36 return false;
35}37}
3638
37fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {39fn test_mul_f128(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
38 const x = __multf3(a, b);40 const x = mul_f128(a, b);
3941
40 if (compareResultLD(x, expected_hi, expected_lo))42 if (compareResultLD(x, expected_hi, expected_lo))
41 return;43 return;
...@@ -49,68 +51,68 @@ fn makeNaN128(rand: u64) f128 {...@@ -49,68 +51,68 @@ fn makeNaN128(rand: u64) f128 {
49}51}
50test "multf3" {52test "multf3" {
51 // qNaN * any = qNaN53 // qNaN * any = qNaN
52 try test__multf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);54 try test_mul_f128(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
5355
54 // NaN * any = NaN56 // NaN * any = NaN
55 const a = makeNaN128(0x800030000000);57 const a = makeNaN128(0x800030000000);
56 try test__multf3(a, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);58 try test_mul_f128(a, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
57 // inf * any = inf59 // inf * any = inf
58 try test__multf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);60 try test_mul_f128(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);
5961
60 // any * any62 // any * any
61 try test__multf3(63 try test_mul_f128(
62 @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))),64 @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))),
63 @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))),65 @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))),
64 0x400423e7f9e3c9fc,66 0x400423e7f9e3c9fc,
65 0xd906c2c2a85777c4,67 0xd906c2c2a85777c4,
66 );68 );
6769
68 try test__multf3(70 try test_mul_f128(
69 @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))),71 @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))),
70 @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))),72 @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))),
71 0x3fc52a163c6223fc,73 0x3fc52a163c6223fc,
72 0xc94c4bf0430768b4,74 0xc94c4bf0430768b4,
73 );75 );
7476
75 try test__multf3(77 try test_mul_f128(
76 0x1.234425696abcad34a35eeffefdcbap+456,78 0x1.234425696abcad34a35eeffefdcbap+456,
77 0x451.ed98d76e5d46e5f24323dff21ffp+600,79 0x451.ed98d76e5d46e5f24323dff21ffp+600,
78 0x44293a91de5e0e94,80 0x44293a91de5e0e94,
79 0xe8ed17cc2cdf64ac,81 0xe8ed17cc2cdf64ac,
80 );82 );
8183
82 try test__multf3(84 try test_mul_f128(
83 @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))),85 @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))),
84 @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))),86 @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))),
85 0x3d4f37c1a3137cae,87 0x3d4f37c1a3137cae,
86 0xfc6807048bc2836a,88 0xfc6807048bc2836a,
87 );89 );
8890
89 try test__multf3(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0);91 try test_mul_f128(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0);
9092
91 // Denormal operands.93 // Denormal operands.
92 try test__multf3(94 try test_mul_f128(
93 0x0.0000000000000000000000000001p-16382,95 0x0.0000000000000000000000000001p-16382,
94 0x1p16383,96 0x1p16383,
95 0x3f90000000000000,97 0x3f90000000000000,
96 0x0,98 0x0,
97 );99 );
98 try test__multf3(100 try test_mul_f128(
99 0x1p16383,101 0x1p16383,
100 0x0.0000000000000000000000000001p-16382,102 0x0.0000000000000000000000000001p-16382,
101 0x3f90000000000000,103 0x3f90000000000000,
102 0x0,104 0x0,
103 );105 );
104106
105 try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002);107 try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002);
106 try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003);108 try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003);
107 try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002);109 try test_mul_f128(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002);
108}110}
109111
110const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));112const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));
111113
112fn test__mulxf3(a: f80, b: f80, expected: u80) !void {114fn test_mul_f80(a: f80, b: f80, expected: u80) !void {
113 const x = __mulxf3(a, b);115 const x = mul_f80(a, b);
114 const rep: u80 = @bitCast(x);116 const rep: u80 = @bitCast(x);
115117
116 if (rep == expected)118 if (rep == expected)
...@@ -124,47 +126,47 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void {...@@ -124,47 +126,47 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void {
124126
125test "mulxf3" {127test "mulxf3" {
126 // NaN * any = NaN128 // NaN * any = NaN
127 try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));129 try test_mul_f80(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
128 try test__mulxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));130 try test_mul_f80(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
129131
130 // any * NaN = NaN132 // any * NaN = NaN
131 try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80)));133 try test_mul_f80(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80)));
132 try test__mulxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));134 try test_mul_f80(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));
133135
134 // NaN * inf = NaN136 // NaN * inf = NaN
135 try test__mulxf3(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80)));137 try test_mul_f80(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80)));
136138
137 // inf * NaN = NaN139 // inf * NaN = NaN
138 try test__mulxf3(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80)));140 try test_mul_f80(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80)));
139141
140 // inf * inf = inf142 // inf * inf = inf
141 try test__mulxf3(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80))));143 try test_mul_f80(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80))));
142144
143 // inf * -inf = -inf145 // inf * -inf = -inf
144 try test__mulxf3(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80))));146 try test_mul_f80(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80))));
145147
146 // -inf + inf = -inf148 // -inf + inf = -inf
147 try test__mulxf3(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80))));149 try test_mul_f80(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80))));
148150
149 // inf * any = inf151 // inf * any = inf
150 try test__mulxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80))));152 try test_mul_f80(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80))));
151153
152 // any * inf = inf154 // any * inf = inf
153 try test__mulxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80))));155 try test_mul_f80(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80))));
154156
155 // any * any157 // any * any
156 try test__mulxf3(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800);158 try test_mul_f80(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800);
157 try test__mulxf3(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact159 try test_mul_f80(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact
158160
159 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact161 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact
160 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down162 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down
161 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even163 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even
162 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up164 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up
163 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact165 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact
164166
165 try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even167 try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even
166 try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up168 try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up
167 try test__mulxf3(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal169 try test_mul_f80(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal
168 try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal170 try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal
169 try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal171 try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal
170}172}
lib/compiler_rt/mulhc3.zig deleted-13
...@@ -1,13 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulc3 = @import("./mulc3.zig");
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__mulhc3, "__mulhc3");
8 }
9}
10
11pub fn __mulhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) mulc3.Complex(f16) {
12 return mulc3.mulc3(f16, a, b, c, d);
13}
lib/compiler_rt/mulhf3.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
6 symbol(&__mulhf3, "__mulhf3");
7}
8
9pub fn __mulhf3(a: f16, b: f16) callconv(.c) f16 {
10 return mulf3(f16, a, b);
11}
lib/compiler_rt/mulsc3.zig deleted-12
...@@ -1,12 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const mulc3 = @import("./mulc3.zig");
3
4comptime {
5 if (@import("builtin").zig_backend != .stage2_c) {
6 symbol(&__mulsc3, "__mulsc3");
7 }
8}
9
10pub fn __mulsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) mulc3.Complex(f32) {
11 return mulc3.mulc3(f32, a, b, c, d);
12}
lib/compiler_rt/mulsf3.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_fmul, "__aeabi_fmul");
8 } else {
9 symbol(&__mulsf3, "__mulsf3");
10 }
11}
12
13pub fn __mulsf3(a: f32, b: f32) callconv(.c) f32 {
14 return mulf3(f32, a, b);
15}
16
17fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
18 return mulf3(f32, a, b);
19}
lib/compiler_rt/multc3.zig deleted-15
...@@ -1,15 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const mulc3 = @import("./mulc3.zig");
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 if (compiler_rt.want_ppc_abi)
8 symbol(&__multc3, "__mulkc3");
9 symbol(&__multc3, "__multc3");
10 }
11}
12
13pub fn __multc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) mulc3.Complex(f128) {
14 return mulc3.mulc3(f128, a, b, c, d);
15}
lib/compiler_rt/multf3.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__multf3, "__mulkf3");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_mul, "_Qp_mul");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__multf3, "_Q_mul");
12 }
13 symbol(&__multf3, "__multf3");
14}
15
16pub fn __multf3(a: f128, b: f128) callconv(.c) f128 {
17 return mulf3(f128, a, b);
18}
19
20fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {
21 c.* = mulf3(f128, a.*, b.*);
22}
lib/compiler_rt/mulvsi3.zig+3-2
...@@ -1,7 +1,8 @@...@@ -1,7 +1,8 @@
1const testing = @import("std").testing;1const testing = @import("std").testing;
22
3const mulv = @import("mulo.zig");3const mulv = @import("mulo.zig");
4const symbol = @import("../compiler_rt.zig").symbol;4const compiler_rt = @import("../compiler_rt.zig");
5const symbol = compiler_rt.symbol;
56
6comptime {7comptime {
7 symbol(&__mulvsi3, "__mulvsi3");8 symbol(&__mulvsi3, "__mulvsi3");
...@@ -10,7 +11,7 @@ comptime {...@@ -10,7 +11,7 @@ comptime {
10pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 {11pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 {
11 var overflow: c_int = 0;12 var overflow: c_int = 0;
12 const sum = mulv.__mulosi4(a, b, &overflow);13 const sum = mulv.__mulosi4(a, b, &overflow);
13 if (overflow != 0) @panic("compiler-rt: integer overflow");14 if (overflow != 0) @panic("integer overflow");
14 return sum;15 return sum;
15}16}
1617
lib/compiler_rt/mulxc3.zig deleted-13
...@@ -1,13 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulc3 = @import("./mulc3.zig");
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__mulxc3, "__mulxc3");
8 }
9}
10
11pub fn __mulxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) mulc3.Complex(f80) {
12 return mulc3.mulc3(f80, a, b, c, d);
13}
lib/compiler_rt/mulxf3.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
6 symbol(&__mulxf3, "__mulxf3");
7}
8
9pub fn __mulxf3(a: f80, b: f80) callconv(.c) f80 {
10 return mulf3(f80, a, b);
11}
lib/compiler_rt/negv.zig+1-2
...@@ -33,8 +33,7 @@ inline fn negvXi(comptime ST: type, a: ST) ST {...@@ -33,8 +33,7 @@ inline fn negvXi(comptime ST: type, a: ST) ST {
33 };33 };
34 const N: UT = @bitSizeOf(ST);34 const N: UT = @bitSizeOf(ST);
35 const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1))));35 const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1))));
36 if (a == min)36 if (a == min) @panic("integer overflow");
37 @panic("compiler_rt negv: overflow");
38 return -a;37 return -a;
39}38}
4039
lib/compiler_rt/os_version_check.zig-1
...@@ -3,7 +3,6 @@ const testing = std.testing;...@@ -3,7 +3,6 @@ const testing = std.testing;
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const compiler_rt = @import("../compiler_rt.zig");4const compiler_rt = @import("../compiler_rt.zig");
5const symbol = compiler_rt.symbol;5const symbol = compiler_rt.symbol;
6const panic = @import("../compiler_rt.zig").panic;
76
8const have_availability_version_check = builtin.os.tag.isDarwin() and7const have_availability_version_check = builtin.os.tag.isDarwin() and
9 builtin.os.version_range.semver.min.order(.{ .major = 10, .minor = 15, .patch = 0 }).compare(.gte);8 builtin.os.version_range.semver.min.order(.{ .major = 10, .minor = 15, .patch = 0 }).compare(.gte);
lib/compiler_rt/parity.zig+2-1
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1//! parity - if number of bits set is even => 0, else => 11//! parity - if number of bits set is even => 0, else => 1
2//! - pariytXi2_generic for big and little endian2//! - pariytXi2_generic for big and little endian
3const symbol = @import("../compiler_rt.zig").symbol;3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
45
5comptime {6comptime {
6 symbol(&__paritysi2, "__paritysi2");7 symbol(&__paritysi2, "__paritysi2");
lib/compiler_rt/popcount.zig+2-1
...@@ -6,7 +6,8 @@...@@ -6,7 +6,8 @@
6//! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques,6//! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques,
7//! subsubsection "Working with the rightmost bits" and "Sideways addition".7//! subsubsection "Working with the rightmost bits" and "Sideways addition".
88
9const symbol = @import("../compiler_rt.zig").symbol;9const compiler_rt = @import("../compiler_rt.zig");
10const symbol = compiler_rt.symbol;
1011
11comptime {12comptime {
12 symbol(&__popcountsi2, "__popcountsi2");13 symbol(&__popcountsi2, "__popcountsi2");
lib/compiler_rt/powiXf2.zig+28-11
...@@ -4,16 +4,18 @@...@@ -4,16 +4,18 @@
4//! error propagation and this method is optimized for performance, not accuracy.4//! error propagation and this method is optimized for performance, not accuracy.
55
6const compiler_rt = @import("../compiler_rt.zig");6const compiler_rt = @import("../compiler_rt.zig");
7const symbol = @import("../compiler_rt.zig").symbol;7const symbol = compiler_rt.symbol;
88
9comptime {9comptime {
10 symbol(&__powihf2, "__powihf2");10 symbol(&__powihf2, "__powihf2");
11 symbol(&__powisf2, "__powisf2");11 symbol(&__powisf2, "__powisf2");
12 symbol(&__powidf2, "__powidf2");12 symbol(&__powidf2, "__powidf2");
13 if (compiler_rt.want_ppc_abi)
14 symbol(&__powitf2, "__powikf2");
15 symbol(&__powitf2, "__powitf2");
16 symbol(&__powixf2, "__powixf2");13 symbol(&__powixf2, "__powixf2");
14 if (compiler_rt.want_ppc_abi) {
15 symbol(&__powitf2, "__powikf2");
16 } else {
17 symbol(&__powitf2, "__powitf2");
18 }
17}19}
1820
19inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT {21inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT {
...@@ -32,26 +34,41 @@ inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT {...@@ -32,26 +34,41 @@ inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT {
32 return if (is_recip) 1 / r else r;34 return if (is_recip) 1 / r else r;
33}35}
3436
35pub fn __powihf2(a: f16, b: i32) callconv(.c) f16 {37fn __powihf2(a: compiler_rt.f16.Abi, b: i32) callconv(.c) compiler_rt.f16.Abi {
38 return compiler_rt.f16.toAbi(powi_f16(compiler_rt.f16.fromAbi(a), b));
39}
40pub fn powi_f16(a: f16, b: i32) f16 {
36 return powiXf2(f16, a, b);41 return powiXf2(f16, a, b);
37}42}
3843
39pub fn __powisf2(a: f32, b: i32) callconv(.c) f32 {44fn __powisf2(a: compiler_rt.f32.Abi, b: i32) callconv(.c) compiler_rt.f32.Abi {
45 return compiler_rt.f32.toAbi(powi_f32(compiler_rt.f32.fromAbi(a), b));
46}
47pub fn powi_f32(a: f32, b: i32) f32 {
40 return powiXf2(f32, a, b);48 return powiXf2(f32, a, b);
41}49}
4250
43pub fn __powidf2(a: f64, b: i32) callconv(.c) f64 {51fn __powidf2(a: compiler_rt.f64.Abi, b: i32) callconv(.c) compiler_rt.f64.Abi {
52 return compiler_rt.f64.toAbi(powi_f64(compiler_rt.f64.fromAbi(a), b));
53}
54pub fn powi_f64(a: f64, b: i32) f64 {
44 return powiXf2(f64, a, b);55 return powiXf2(f64, a, b);
45}56}
4657
47pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 {58fn __powixf2(a: compiler_rt.f80.Abi, b: i32) callconv(.c) compiler_rt.f80.Abi {
48 return powiXf2(f128, a, b);59 return compiler_rt.f80.toAbi(powi_f80(compiler_rt.f80.fromAbi(a), b));
49}60}
5061pub fn powi_f80(a: f80, b: i32) f80 {
51pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 {
52 return powiXf2(f80, a, b);62 return powiXf2(f80, a, b);
53}63}
5464
65fn __powitf2(a: compiler_rt.f128.Abi, b: i32) callconv(.c) compiler_rt.f128.Abi {
66 return compiler_rt.f128.toAbi(powi_f128(compiler_rt.f128.fromAbi(a), b));
67}
68pub fn powi_f128(a: f128, b: i32) f128 {
69 return powiXf2(f128, a, b);
70}
71
55test {72test {
56 _ = @import("powiXf2_test.zig");73 _ = @import("powiXf2_test.zig");
57}74}
lib/compiler_rt/powiXf2_test.zig+531-525
...@@ -2,562 +2,568 @@...@@ -2,562 +2,568 @@
2// powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c2// powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c
3// powihf2 adapted from powisf2 tests3// powihf2 adapted from powisf2 tests
44
5const powiXf2 = @import("powiXf2.zig");
6const std = @import("std");5const std = @import("std");
7const builtin = @import("builtin");
8const testing = std.testing;6const testing = std.testing;
9const math = std.math;7const math = std.math;
108
11fn test__powihf2(a: f16, b: i32, expected: f16) !void {9const impl = @import("powiXf2.zig");
12 const result = powiXf2.__powihf2(a, b);10
11const powi_f16 = impl.powi_f16;
12const powi_f32 = impl.powi_f32;
13const powi_f64 = impl.powi_f64;
14const powi_f80 = impl.powi_f80;
15const powi_f128 = impl.powi_f128;
16
17fn test_powi_f16(a: f16, b: i32, expected: f16) !void {
18 const result = powi_f16(a, b);
13 try testing.expectEqual(expected, result);19 try testing.expectEqual(expected, result);
14}20}
1521
16fn test__powisf2(a: f32, b: i32, expected: f32) !void {22fn test_powi_f32(a: f32, b: i32, expected: f32) !void {
17 const result = powiXf2.__powisf2(a, b);23 const result = powi_f32(a, b);
18 try testing.expectEqual(expected, result);24 try testing.expectEqual(expected, result);
19}25}
2026
21fn test__powidf2(a: f64, b: i32, expected: f64) !void {27fn test_powi_f64(a: f64, b: i32, expected: f64) !void {
22 const result = powiXf2.__powidf2(a, b);28 const result = powi_f64(a, b);
23 try testing.expectEqual(expected, result);29 try testing.expectEqual(expected, result);
24}30}
2531
26fn test__powitf2(a: f128, b: i32, expected: f128) !void {32fn test_powi_f80(a: f80, b: i32, expected: f80) !void {
27 const result = powiXf2.__powitf2(a, b);33 const result = powi_f80(a, b);
28 try testing.expectEqual(expected, result);34 try testing.expectEqual(expected, result);
29}35}
3036
31fn test__powixf2(a: f80, b: i32, expected: f80) !void {37fn test_powi_f128(a: f128, b: i32, expected: f128) !void {
32 const result = powiXf2.__powixf2(a, b);38 const result = powi_f128(a, b);
33 try testing.expectEqual(expected, result);39 try testing.expectEqual(expected, result);
34}40}
3541
36test "powihf2" {42test powi_f16 {
37 const inf_f16 = math.inf(f16);43 const inf_f16 = math.inf(f16);
38 try test__powisf2(0, 0, 1);44 try test_powi_f16(0, 0, 1);
39 try test__powihf2(1, 0, 1);45 try test_powi_f16(1, 0, 1);
40 try test__powihf2(1.5, 0, 1);46 try test_powi_f16(1.5, 0, 1);
41 try test__powihf2(2, 0, 1);47 try test_powi_f16(2, 0, 1);
42 try test__powihf2(inf_f16, 0, 1);48 try test_powi_f16(inf_f16, 0, 1);
4349
44 try test__powihf2(-0.0, 0, 1);50 try test_powi_f16(-0.0, 0, 1);
45 try test__powihf2(-1, 0, 1);51 try test_powi_f16(-1, 0, 1);
46 try test__powihf2(-1.5, 0, 1);52 try test_powi_f16(-1.5, 0, 1);
47 try test__powihf2(-2, 0, 1);53 try test_powi_f16(-2, 0, 1);
48 try test__powihf2(-inf_f16, 0, 1);54 try test_powi_f16(-inf_f16, 0, 1);
4955
50 try test__powihf2(0, 1, 0);56 try test_powi_f16(0, 1, 0);
51 try test__powihf2(0, 2, 0);57 try test_powi_f16(0, 2, 0);
52 try test__powihf2(0, 3, 0);58 try test_powi_f16(0, 3, 0);
53 try test__powihf2(0, 4, 0);59 try test_powi_f16(0, 4, 0);
54 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);60 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
55 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);61 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
5662
57 try test__powihf2(-0.0, 1, -0.0);63 try test_powi_f16(-0.0, 1, -0.0);
58 try test__powihf2(-0.0, 2, 0);64 try test_powi_f16(-0.0, 2, 0);
59 try test__powihf2(-0.0, 3, -0.0);65 try test_powi_f16(-0.0, 3, -0.0);
60 try test__powihf2(-0.0, 4, 0);66 try test_powi_f16(-0.0, 4, 0);
61 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);67 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
62 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);68 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
6369
64 try test__powihf2(1, 1, 1);70 try test_powi_f16(1, 1, 1);
65 try test__powihf2(1, 2, 1);71 try test_powi_f16(1, 2, 1);
66 try test__powihf2(1, 3, 1);72 try test_powi_f16(1, 3, 1);
67 try test__powihf2(1, 4, 1);73 try test_powi_f16(1, 4, 1);
68 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);74 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
69 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);75 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
7076
71 try test__powihf2(inf_f16, 1, inf_f16);77 try test_powi_f16(inf_f16, 1, inf_f16);
72 try test__powihf2(inf_f16, 2, inf_f16);78 try test_powi_f16(inf_f16, 2, inf_f16);
73 try test__powihf2(inf_f16, 3, inf_f16);79 try test_powi_f16(inf_f16, 3, inf_f16);
74 try test__powihf2(inf_f16, 4, inf_f16);80 try test_powi_f16(inf_f16, 4, inf_f16);
75 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);81 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
76 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16);82 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16);
7783
78 try test__powihf2(-inf_f16, 1, -inf_f16);84 try test_powi_f16(-inf_f16, 1, -inf_f16);
79 try test__powihf2(-inf_f16, 2, inf_f16);85 try test_powi_f16(-inf_f16, 2, inf_f16);
80 try test__powihf2(-inf_f16, 3, -inf_f16);86 try test_powi_f16(-inf_f16, 3, -inf_f16);
81 try test__powihf2(-inf_f16, 4, inf_f16);87 try test_powi_f16(-inf_f16, 4, inf_f16);
82 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);88 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
83 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16);89 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16);
84 //90 //
85 try test__powihf2(0, -1, inf_f16);91 try test_powi_f16(0, -1, inf_f16);
86 try test__powihf2(0, -2, inf_f16);92 try test_powi_f16(0, -2, inf_f16);
87 try test__powihf2(0, -3, inf_f16);93 try test_powi_f16(0, -3, inf_f16);
88 try test__powihf2(0, -4, inf_f16);94 try test_powi_f16(0, -4, inf_f16);
89 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf95 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf
90 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16);96 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16);
91 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);97 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
9298
93 try test__powihf2(-0.0, -1, -inf_f16);99 try test_powi_f16(-0.0, -1, -inf_f16);
94 try test__powihf2(-0.0, -2, inf_f16);100 try test_powi_f16(-0.0, -2, inf_f16);
95 try test__powihf2(-0.0, -3, -inf_f16);101 try test_powi_f16(-0.0, -3, -inf_f16);
96 try test__powihf2(-0.0, -4, inf_f16);102 try test_powi_f16(-0.0, -4, inf_f16);
97 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf103 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf
98 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf104 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf
99 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);105 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
100106
101 try test__powihf2(1, -1, 1);107 try test_powi_f16(1, -1, 1);
102 try test__powihf2(1, -2, 1);108 try test_powi_f16(1, -2, 1);
103 try test__powihf2(1, -3, 1);109 try test_powi_f16(1, -3, 1);
104 try test__powihf2(1, -4, 1);110 try test_powi_f16(1, -4, 1);
105 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1111 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1
106 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);112 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
107 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);113 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
108114
109 try test__powihf2(inf_f16, -1, 0);115 try test_powi_f16(inf_f16, -1, 0);
110 try test__powihf2(inf_f16, -2, 0);116 try test_powi_f16(inf_f16, -2, 0);
111 try test__powihf2(inf_f16, -3, 0);117 try test_powi_f16(inf_f16, -3, 0);
112 try test__powihf2(inf_f16, -4, 0);118 try test_powi_f16(inf_f16, -4, 0);
113 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);119 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
114 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);120 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
115 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);121 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
116 //122 //
117 try test__powihf2(-inf_f16, -1, -0.0);123 try test_powi_f16(-inf_f16, -1, -0.0);
118 try test__powihf2(-inf_f16, -2, 0);124 try test_powi_f16(-inf_f16, -2, 0);
119 try test__powihf2(-inf_f16, -3, -0.0);125 try test_powi_f16(-inf_f16, -3, -0.0);
120 try test__powihf2(-inf_f16, -4, 0);126 try test_powi_f16(-inf_f16, -4, 0);
121 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);127 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
122 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);128 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
123 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);129 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
124130
125 try test__powihf2(2, 10, 1024.0);131 try test_powi_f16(2, 10, 1024.0);
126 try test__powihf2(-2, 10, 1024.0);132 try test_powi_f16(-2, 10, 1024.0);
127 try test__powihf2(2, -10, 1.0 / 1024.0);133 try test_powi_f16(2, -10, 1.0 / 1024.0);
128 try test__powihf2(-2, -10, 1.0 / 1024.0);134 try test_powi_f16(-2, -10, 1.0 / 1024.0);
129135
130 try test__powihf2(2, 14, 16384.0);136 try test_powi_f16(2, 14, 16384.0);
131 try test__powihf2(-2, 14, 16384.0);137 try test_powi_f16(-2, 14, 16384.0);
132 try test__powihf2(2, 15, 32768.0);138 try test_powi_f16(2, 15, 32768.0);
133 try test__powihf2(-2, 15, -32768.0);139 try test_powi_f16(-2, 15, -32768.0);
134 try test__powihf2(2, 16, inf_f16);140 try test_powi_f16(2, 16, inf_f16);
135 try test__powihf2(-2, 16, inf_f16);141 try test_powi_f16(-2, 16, inf_f16);
136142
137 try test__powihf2(2, -13, 1.0 / 8192.0);143 try test_powi_f16(2, -13, 1.0 / 8192.0);
138 try test__powihf2(-2, -13, -1.0 / 8192.0);144 try test_powi_f16(-2, -13, -1.0 / 8192.0);
139 try test__powihf2(2, -15, 1.0 / 32768.0);145 try test_powi_f16(2, -15, 1.0 / 32768.0);
140 try test__powihf2(-2, -15, -1.0 / 32768.0);146 try test_powi_f16(-2, -15, -1.0 / 32768.0);
141 try test__powihf2(2, -16, 0.0); // expected = 0.0 = 1/(-2**16)147 try test_powi_f16(2, -16, 0.0); // expected = 0.0 = 1/(-2**16)
142 try test__powihf2(-2, -16, 0.0); // expected = 0.0 = 1/(2**16)148 try test_powi_f16(-2, -16, 0.0); // expected = 0.0 = 1/(2**16)
143}149}
144150
145test "powisf2" {151test powi_f32 {
146 const inf_f32 = math.inf(f32);152 const inf_f32 = math.inf(f32);
147 try test__powisf2(0, 0, 1);153 try test_powi_f32(0, 0, 1);
148 try test__powisf2(1, 0, 1);154 try test_powi_f32(1, 0, 1);
149 try test__powisf2(1.5, 0, 1);155 try test_powi_f32(1.5, 0, 1);
150 try test__powisf2(2, 0, 1);156 try test_powi_f32(2, 0, 1);
151 try test__powisf2(inf_f32, 0, 1);157 try test_powi_f32(inf_f32, 0, 1);
152158
153 try test__powisf2(-0.0, 0, 1);159 try test_powi_f32(-0.0, 0, 1);
154 try test__powisf2(-1, 0, 1);160 try test_powi_f32(-1, 0, 1);
155 try test__powisf2(-1.5, 0, 1);161 try test_powi_f32(-1.5, 0, 1);
156 try test__powisf2(-2, 0, 1);162 try test_powi_f32(-2, 0, 1);
157 try test__powisf2(-inf_f32, 0, 1);163 try test_powi_f32(-inf_f32, 0, 1);
158164
159 try test__powisf2(0, 1, 0);165 try test_powi_f32(0, 1, 0);
160 try test__powisf2(0, 2, 0);166 try test_powi_f32(0, 2, 0);
161 try test__powisf2(0, 3, 0);167 try test_powi_f32(0, 3, 0);
162 try test__powisf2(0, 4, 0);168 try test_powi_f32(0, 4, 0);
163 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);169 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
164 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);170 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
165171
166 try test__powisf2(-0.0, 1, -0.0);172 try test_powi_f32(-0.0, 1, -0.0);
167 try test__powisf2(-0.0, 2, 0);173 try test_powi_f32(-0.0, 2, 0);
168 try test__powisf2(-0.0, 3, -0.0);174 try test_powi_f32(-0.0, 3, -0.0);
169 try test__powisf2(-0.0, 4, 0);175 try test_powi_f32(-0.0, 4, 0);
170 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);176 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
171 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);177 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
172178
173 try test__powisf2(1, 1, 1);179 try test_powi_f32(1, 1, 1);
174 try test__powisf2(1, 2, 1);180 try test_powi_f32(1, 2, 1);
175 try test__powisf2(1, 3, 1);181 try test_powi_f32(1, 3, 1);
176 try test__powisf2(1, 4, 1);182 try test_powi_f32(1, 4, 1);
177 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);183 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
178 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);184 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
179185
180 try test__powisf2(inf_f32, 1, inf_f32);186 try test_powi_f32(inf_f32, 1, inf_f32);
181 try test__powisf2(inf_f32, 2, inf_f32);187 try test_powi_f32(inf_f32, 2, inf_f32);
182 try test__powisf2(inf_f32, 3, inf_f32);188 try test_powi_f32(inf_f32, 3, inf_f32);
183 try test__powisf2(inf_f32, 4, inf_f32);189 try test_powi_f32(inf_f32, 4, inf_f32);
184 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);190 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
185 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32);191 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32);
186192
187 try test__powisf2(-inf_f32, 1, -inf_f32);193 try test_powi_f32(-inf_f32, 1, -inf_f32);
188 try test__powisf2(-inf_f32, 2, inf_f32);194 try test_powi_f32(-inf_f32, 2, inf_f32);
189 try test__powisf2(-inf_f32, 3, -inf_f32);195 try test_powi_f32(-inf_f32, 3, -inf_f32);
190 try test__powisf2(-inf_f32, 4, inf_f32);196 try test_powi_f32(-inf_f32, 4, inf_f32);
191 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);197 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
192 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32);198 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32);
193199
194 try test__powisf2(0, -1, inf_f32);200 try test_powi_f32(0, -1, inf_f32);
195 try test__powisf2(0, -2, inf_f32);201 try test_powi_f32(0, -2, inf_f32);
196 try test__powisf2(0, -3, inf_f32);202 try test_powi_f32(0, -3, inf_f32);
197 try test__powisf2(0, -4, inf_f32);203 try test_powi_f32(0, -4, inf_f32);
198 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);204 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
199 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32);205 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32);
200 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);206 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
201207
202 try test__powisf2(-0.0, -1, -inf_f32);208 try test_powi_f32(-0.0, -1, -inf_f32);
203 try test__powisf2(-0.0, -2, inf_f32);209 try test_powi_f32(-0.0, -2, inf_f32);
204 try test__powisf2(-0.0, -3, -inf_f32);210 try test_powi_f32(-0.0, -3, -inf_f32);
205 try test__powisf2(-0.0, -4, inf_f32);211 try test_powi_f32(-0.0, -4, inf_f32);
206 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);212 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
207 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32);213 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32);
208 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);214 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
209215
210 try test__powisf2(1, -1, 1);216 try test_powi_f32(1, -1, 1);
211 try test__powisf2(1, -2, 1);217 try test_powi_f32(1, -2, 1);
212 try test__powisf2(1, -3, 1);218 try test_powi_f32(1, -3, 1);
213 try test__powisf2(1, -4, 1);219 try test_powi_f32(1, -4, 1);
214 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);220 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
215 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);221 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
216 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);222 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
217223
218 try test__powisf2(inf_f32, -1, 0);224 try test_powi_f32(inf_f32, -1, 0);
219 try test__powisf2(inf_f32, -2, 0);225 try test_powi_f32(inf_f32, -2, 0);
220 try test__powisf2(inf_f32, -3, 0);226 try test_powi_f32(inf_f32, -3, 0);
221 try test__powisf2(inf_f32, -4, 0);227 try test_powi_f32(inf_f32, -4, 0);
222 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);228 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
223 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);229 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
224 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);230 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
225231
226 try test__powisf2(-inf_f32, -1, -0.0);232 try test_powi_f32(-inf_f32, -1, -0.0);
227 try test__powisf2(-inf_f32, -2, 0);233 try test_powi_f32(-inf_f32, -2, 0);
228 try test__powisf2(-inf_f32, -3, -0.0);234 try test_powi_f32(-inf_f32, -3, -0.0);
229 try test__powisf2(-inf_f32, -4, 0);235 try test_powi_f32(-inf_f32, -4, 0);
230 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);236 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
231 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);237 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
232 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);238 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
233239
234 try test__powisf2(2.0, 10, 1024.0);240 try test_powi_f32(2.0, 10, 1024.0);
235 try test__powisf2(-2, 10, 1024.0);241 try test_powi_f32(-2, 10, 1024.0);
236 try test__powisf2(2, -10, 1.0 / 1024.0);242 try test_powi_f32(2, -10, 1.0 / 1024.0);
237 try test__powisf2(-2, -10, 1.0 / 1024.0);243 try test_powi_f32(-2, -10, 1.0 / 1024.0);
238 //244 //
239 try test__powisf2(2, 19, 524288.0);245 try test_powi_f32(2, 19, 524288.0);
240 try test__powisf2(-2, 19, -524288.0);246 try test_powi_f32(-2, 19, -524288.0);
241 try test__powisf2(2, -19, 1.0 / 524288.0);247 try test_powi_f32(2, -19, 1.0 / 524288.0);
242 try test__powisf2(-2, -19, -1.0 / 524288.0);248 try test_powi_f32(-2, -19, -1.0 / 524288.0);
243249
244 try test__powisf2(2, 31, 2147483648.0);250 try test_powi_f32(2, 31, 2147483648.0);
245 try test__powisf2(-2, 31, -2147483648.0);251 try test_powi_f32(-2, 31, -2147483648.0);
246 try test__powisf2(2, -31, 1.0 / 2147483648.0);252 try test_powi_f32(2, -31, 1.0 / 2147483648.0);
247 try test__powisf2(-2, -31, -1.0 / 2147483648.0);253 try test_powi_f32(-2, -31, -1.0 / 2147483648.0);
248}254}
249255
250test "powidf2" {256test powi_f64 {
251 const inf_f64 = math.inf(f64);257 const inf_f64 = math.inf(f64);
252 try test__powidf2(0, 0, 1);258 try test_powi_f64(0, 0, 1);
253 try test__powidf2(1, 0, 1);259 try test_powi_f64(1, 0, 1);
254 try test__powidf2(1.5, 0, 1);260 try test_powi_f64(1.5, 0, 1);
255 try test__powidf2(2, 0, 1);261 try test_powi_f64(2, 0, 1);
256 try test__powidf2(inf_f64, 0, 1);262 try test_powi_f64(inf_f64, 0, 1);
257263
258 try test__powidf2(-0.0, 0, 1);264 try test_powi_f64(-0.0, 0, 1);
259 try test__powidf2(-1, 0, 1);265 try test_powi_f64(-1, 0, 1);
260 try test__powidf2(-1.5, 0, 1);266 try test_powi_f64(-1.5, 0, 1);
261 try test__powidf2(-2, 0, 1);267 try test_powi_f64(-2, 0, 1);
262 try test__powidf2(-inf_f64, 0, 1);268 try test_powi_f64(-inf_f64, 0, 1);
263269
264 try test__powidf2(0, 1, 0);270 try test_powi_f64(0, 1, 0);
265 try test__powidf2(0, 2, 0);271 try test_powi_f64(0, 2, 0);
266 try test__powidf2(0, 3, 0);272 try test_powi_f64(0, 3, 0);
267 try test__powidf2(0, 4, 0);273 try test_powi_f64(0, 4, 0);
268 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);274 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
269 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);275 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
270276
271 try test__powidf2(-0.0, 1, -0.0);277 try test_powi_f64(-0.0, 1, -0.0);
272 try test__powidf2(-0.0, 2, 0);278 try test_powi_f64(-0.0, 2, 0);
273 try test__powidf2(-0.0, 3, -0.0);279 try test_powi_f64(-0.0, 3, -0.0);
274 try test__powidf2(-0.0, 4, 0);280 try test_powi_f64(-0.0, 4, 0);
275 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);281 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
276 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);282 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
277283
278 try test__powidf2(1, 1, 1);284 try test_powi_f64(1, 1, 1);
279 try test__powidf2(1, 2, 1);285 try test_powi_f64(1, 2, 1);
280 try test__powidf2(1, 3, 1);286 try test_powi_f64(1, 3, 1);
281 try test__powidf2(1, 4, 1);287 try test_powi_f64(1, 4, 1);
282 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);288 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
283 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);289 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
284290
285 try test__powidf2(inf_f64, 1, inf_f64);291 try test_powi_f64(inf_f64, 1, inf_f64);
286 try test__powidf2(inf_f64, 2, inf_f64);292 try test_powi_f64(inf_f64, 2, inf_f64);
287 try test__powidf2(inf_f64, 3, inf_f64);293 try test_powi_f64(inf_f64, 3, inf_f64);
288 try test__powidf2(inf_f64, 4, inf_f64);294 try test_powi_f64(inf_f64, 4, inf_f64);
289 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);295 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
290 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64);296 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64);
291297
292 try test__powidf2(-inf_f64, 1, -inf_f64);298 try test_powi_f64(-inf_f64, 1, -inf_f64);
293 try test__powidf2(-inf_f64, 2, inf_f64);299 try test_powi_f64(-inf_f64, 2, inf_f64);
294 try test__powidf2(-inf_f64, 3, -inf_f64);300 try test_powi_f64(-inf_f64, 3, -inf_f64);
295 try test__powidf2(-inf_f64, 4, inf_f64);301 try test_powi_f64(-inf_f64, 4, inf_f64);
296 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);302 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
297 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64);303 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64);
298304
299 try test__powidf2(0, -1, inf_f64);305 try test_powi_f64(0, -1, inf_f64);
300 try test__powidf2(0, -2, inf_f64);306 try test_powi_f64(0, -2, inf_f64);
301 try test__powidf2(0, -3, inf_f64);307 try test_powi_f64(0, -3, inf_f64);
302 try test__powidf2(0, -4, inf_f64);308 try test_powi_f64(0, -4, inf_f64);
303 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);309 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
304 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64);310 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64);
305 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);311 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
306312
307 try test__powidf2(-0.0, -1, -inf_f64);313 try test_powi_f64(-0.0, -1, -inf_f64);
308 try test__powidf2(-0.0, -2, inf_f64);314 try test_powi_f64(-0.0, -2, inf_f64);
309 try test__powidf2(-0.0, -3, -inf_f64);315 try test_powi_f64(-0.0, -3, -inf_f64);
310 try test__powidf2(-0.0, -4, inf_f64);316 try test_powi_f64(-0.0, -4, inf_f64);
311 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);317 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
312 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64);318 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64);
313 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);319 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
314320
315 try test__powidf2(1, -1, 1);321 try test_powi_f64(1, -1, 1);
316 try test__powidf2(1, -2, 1);322 try test_powi_f64(1, -2, 1);
317 try test__powidf2(1, -3, 1);323 try test_powi_f64(1, -3, 1);
318 try test__powidf2(1, -4, 1);324 try test_powi_f64(1, -4, 1);
319 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);325 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
320 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);326 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
321 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);327 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
322328
323 try test__powidf2(inf_f64, -1, 0);329 try test_powi_f64(inf_f64, -1, 0);
324 try test__powidf2(inf_f64, -2, 0);330 try test_powi_f64(inf_f64, -2, 0);
325 try test__powidf2(inf_f64, -3, 0);331 try test_powi_f64(inf_f64, -3, 0);
326 try test__powidf2(inf_f64, -4, 0);332 try test_powi_f64(inf_f64, -4, 0);
327 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);333 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
328 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);334 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
329 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);335 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
330336
331 try test__powidf2(-inf_f64, -1, -0.0);337 try test_powi_f64(-inf_f64, -1, -0.0);
332 try test__powidf2(-inf_f64, -2, 0);338 try test_powi_f64(-inf_f64, -2, 0);
333 try test__powidf2(-inf_f64, -3, -0.0);339 try test_powi_f64(-inf_f64, -3, -0.0);
334 try test__powidf2(-inf_f64, -4, 0);340 try test_powi_f64(-inf_f64, -4, 0);
335 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);341 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
336 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);342 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
337 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);343 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
338344
339 try test__powidf2(2, 10, 1024.0);345 try test_powi_f64(2, 10, 1024.0);
340 try test__powidf2(-2, 10, 1024.0);346 try test_powi_f64(-2, 10, 1024.0);
341 try test__powidf2(2, -10, 1.0 / 1024.0);347 try test_powi_f64(2, -10, 1.0 / 1024.0);
342 try test__powidf2(-2, -10, 1.0 / 1024.0);348 try test_powi_f64(-2, -10, 1.0 / 1024.0);
343349
344 try test__powidf2(2, 19, 524288.0);350 try test_powi_f64(2, 19, 524288.0);
345 try test__powidf2(-2, 19, -524288.0);351 try test_powi_f64(-2, 19, -524288.0);
346 try test__powidf2(2, -19, 1.0 / 524288.0);352 try test_powi_f64(2, -19, 1.0 / 524288.0);
347 try test__powidf2(-2, -19, -1.0 / 524288.0);353 try test_powi_f64(-2, -19, -1.0 / 524288.0);
348354
349 try test__powidf2(2, 31, 2147483648.0);355 try test_powi_f64(2, 31, 2147483648.0);
350 try test__powidf2(-2, 31, -2147483648.0);356 try test_powi_f64(-2, 31, -2147483648.0);
351 try test__powidf2(2, -31, 1.0 / 2147483648.0);357 try test_powi_f64(2, -31, 1.0 / 2147483648.0);
352 try test__powidf2(-2, -31, -1.0 / 2147483648.0);358 try test_powi_f64(-2, -31, -1.0 / 2147483648.0);
353}359}
354360
355test "powitf2" {361test powi_f80 {
356 const inf_f128 = math.inf(f128);362 const inf_f80 = math.inf(f80);
357 try test__powitf2(0, 0, 1);363 try test_powi_f80(0, 0, 1);
358 try test__powitf2(1, 0, 1);364 try test_powi_f80(1, 0, 1);
359 try test__powitf2(1.5, 0, 1);365 try test_powi_f80(1.5, 0, 1);
360 try test__powitf2(2, 0, 1);366 try test_powi_f80(2, 0, 1);
361 try test__powitf2(inf_f128, 0, 1);367 try test_powi_f80(inf_f80, 0, 1);
362368
363 try test__powitf2(-0.0, 0, 1);369 try test_powi_f80(-0.0, 0, 1);
364 try test__powitf2(-1, 0, 1);370 try test_powi_f80(-1, 0, 1);
365 try test__powitf2(-1.5, 0, 1);371 try test_powi_f80(-1.5, 0, 1);
366 try test__powitf2(-2, 0, 1);372 try test_powi_f80(-2, 0, 1);
367 try test__powitf2(-inf_f128, 0, 1);373 try test_powi_f80(-inf_f80, 0, 1);
368374
369 try test__powitf2(0, 1, 0);375 try test_powi_f80(0, 1, 0);
370 try test__powitf2(0, 2, 0);376 try test_powi_f80(0, 2, 0);
371 try test__powitf2(0, 3, 0);377 try test_powi_f80(0, 3, 0);
372 try test__powitf2(0, 4, 0);378 try test_powi_f80(0, 4, 0);
373 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);379 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
374 try test__powitf2(0, 0x7FFFFFFF, 0);380 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
375381
376 try test__powitf2(-0.0, 1, -0.0);382 try test_powi_f80(-0.0, 1, -0.0);
377 try test__powitf2(-0.0, 2, 0);383 try test_powi_f80(-0.0, 2, 0);
378 try test__powitf2(-0.0, 3, -0.0);384 try test_powi_f80(-0.0, 3, -0.0);
379 try test__powitf2(-0.0, 4, 0);385 try test_powi_f80(-0.0, 4, 0);
380 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);386 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
381 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);387 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
382388
383 try test__powitf2(1, 1, 1);389 try test_powi_f80(1, 1, 1);
384 try test__powitf2(1, 2, 1);390 try test_powi_f80(1, 2, 1);
385 try test__powitf2(1, 3, 1);391 try test_powi_f80(1, 3, 1);
386 try test__powitf2(1, 4, 1);392 try test_powi_f80(1, 4, 1);
387 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);393 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
388 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);394 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
389395
390 try test__powitf2(inf_f128, 1, inf_f128);396 try test_powi_f80(inf_f80, 1, inf_f80);
391 try test__powitf2(inf_f128, 2, inf_f128);397 try test_powi_f80(inf_f80, 2, inf_f80);
392 try test__powitf2(inf_f128, 3, inf_f128);398 try test_powi_f80(inf_f80, 3, inf_f80);
393 try test__powitf2(inf_f128, 4, inf_f128);399 try test_powi_f80(inf_f80, 4, inf_f80);
394 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);400 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
395 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128);401 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80);
396402
397 try test__powitf2(-inf_f128, 1, -inf_f128);403 try test_powi_f80(-inf_f80, 1, -inf_f80);
398 try test__powitf2(-inf_f128, 2, inf_f128);404 try test_powi_f80(-inf_f80, 2, inf_f80);
399 try test__powitf2(-inf_f128, 3, -inf_f128);405 try test_powi_f80(-inf_f80, 3, -inf_f80);
400 try test__powitf2(-inf_f128, 4, inf_f128);406 try test_powi_f80(-inf_f80, 4, inf_f80);
401 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);407 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
402 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128);408 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80);
403409
404 try test__powitf2(0, -1, inf_f128);410 try test_powi_f80(0, -1, inf_f80);
405 try test__powitf2(0, -2, inf_f128);411 try test_powi_f80(0, -2, inf_f80);
406 try test__powitf2(0, -3, inf_f128);412 try test_powi_f80(0, -3, inf_f80);
407 try test__powitf2(0, -4, inf_f128);413 try test_powi_f80(0, -4, inf_f80);
408 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);414 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
409 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128);415 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80);
410 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);416 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
411417
412 try test__powitf2(-0.0, -1, -inf_f128);418 try test_powi_f80(-0.0, -1, -inf_f80);
413 try test__powitf2(-0.0, -2, inf_f128);419 try test_powi_f80(-0.0, -2, inf_f80);
414 try test__powitf2(-0.0, -3, -inf_f128);420 try test_powi_f80(-0.0, -3, -inf_f80);
415 try test__powitf2(-0.0, -4, inf_f128);421 try test_powi_f80(-0.0, -4, inf_f80);
416 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);422 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
417 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128);423 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80);
418 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);424 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
419425
420 try test__powitf2(1, -1, 1);426 try test_powi_f80(1, -1, 1);
421 try test__powitf2(1, -2, 1);427 try test_powi_f80(1, -2, 1);
422 try test__powitf2(1, -3, 1);428 try test_powi_f80(1, -3, 1);
423 try test__powitf2(1, -4, 1);429 try test_powi_f80(1, -4, 1);
424 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);430 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
425 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);431 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
426 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);432 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
427433
428 try test__powitf2(inf_f128, -1, 0);434 try test_powi_f80(inf_f80, -1, 0);
429 try test__powitf2(inf_f128, -2, 0);435 try test_powi_f80(inf_f80, -2, 0);
430 try test__powitf2(inf_f128, -3, 0);436 try test_powi_f80(inf_f80, -3, 0);
431 try test__powitf2(inf_f128, -4, 0);437 try test_powi_f80(inf_f80, -4, 0);
432 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);438 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
433 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);439 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
434 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);440 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
435441
436 try test__powitf2(-inf_f128, -1, -0.0);442 try test_powi_f80(-inf_f80, -1, -0.0);
437 try test__powitf2(-inf_f128, -2, 0);443 try test_powi_f80(-inf_f80, -2, 0);
438 try test__powitf2(-inf_f128, -3, -0.0);444 try test_powi_f80(-inf_f80, -3, -0.0);
439 try test__powitf2(-inf_f128, -4, 0);445 try test_powi_f80(-inf_f80, -4, 0);
440 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);446 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
441 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);447 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
442 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);448 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
443449
444 try test__powitf2(2, 10, 1024.0);450 try test_powi_f80(2, 10, 1024.0);
445 try test__powitf2(-2, 10, 1024.0);451 try test_powi_f80(-2, 10, 1024.0);
446 try test__powitf2(2, -10, 1.0 / 1024.0);452 try test_powi_f80(2, -10, 1.0 / 1024.0);
447 try test__powitf2(-2, -10, 1.0 / 1024.0);453 try test_powi_f80(-2, -10, 1.0 / 1024.0);
448454
449 try test__powitf2(2, 19, 524288.0);455 try test_powi_f80(2, 19, 524288.0);
450 try test__powitf2(-2, 19, -524288.0);456 try test_powi_f80(-2, 19, -524288.0);
451 try test__powitf2(2, -19, 1.0 / 524288.0);457 try test_powi_f80(2, -19, 1.0 / 524288.0);
452 try test__powitf2(-2, -19, -1.0 / 524288.0);458 try test_powi_f80(-2, -19, -1.0 / 524288.0);
453459
454 try test__powitf2(2, 31, 2147483648.0);460 try test_powi_f80(2, 31, 2147483648.0);
455 try test__powitf2(-2, 31, -2147483648.0);461 try test_powi_f80(-2, 31, -2147483648.0);
456 try test__powitf2(2, -31, 1.0 / 2147483648.0);462 try test_powi_f80(2, -31, 1.0 / 2147483648.0);
457 try test__powitf2(-2, -31, -1.0 / 2147483648.0);463 try test_powi_f80(-2, -31, -1.0 / 2147483648.0);
458}464}
459465
460test "powixf2" {466test powi_f128 {
461 const inf_f80 = math.inf(f80);467 const inf_f128 = math.inf(f128);
462 try test__powixf2(0, 0, 1);468 try test_powi_f128(0, 0, 1);
463 try test__powixf2(1, 0, 1);469 try test_powi_f128(1, 0, 1);
464 try test__powixf2(1.5, 0, 1);470 try test_powi_f128(1.5, 0, 1);
465 try test__powixf2(2, 0, 1);471 try test_powi_f128(2, 0, 1);
466 try test__powixf2(inf_f80, 0, 1);472 try test_powi_f128(inf_f128, 0, 1);
467473
468 try test__powixf2(-0.0, 0, 1);474 try test_powi_f128(-0.0, 0, 1);
469 try test__powixf2(-1, 0, 1);475 try test_powi_f128(-1, 0, 1);
470 try test__powixf2(-1.5, 0, 1);476 try test_powi_f128(-1.5, 0, 1);
471 try test__powixf2(-2, 0, 1);477 try test_powi_f128(-2, 0, 1);
472 try test__powixf2(-inf_f80, 0, 1);478 try test_powi_f128(-inf_f128, 0, 1);
473479
474 try test__powixf2(0, 1, 0);480 try test_powi_f128(0, 1, 0);
475 try test__powixf2(0, 2, 0);481 try test_powi_f128(0, 2, 0);
476 try test__powixf2(0, 3, 0);482 try test_powi_f128(0, 3, 0);
477 try test__powixf2(0, 4, 0);483 try test_powi_f128(0, 4, 0);
478 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);484 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
479 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);485 try test_powi_f128(0, 0x7FFFFFFF, 0);
480486
481 try test__powixf2(-0.0, 1, -0.0);487 try test_powi_f128(-0.0, 1, -0.0);
482 try test__powixf2(-0.0, 2, 0);488 try test_powi_f128(-0.0, 2, 0);
483 try test__powixf2(-0.0, 3, -0.0);489 try test_powi_f128(-0.0, 3, -0.0);
484 try test__powixf2(-0.0, 4, 0);490 try test_powi_f128(-0.0, 4, 0);
485 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);491 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
486 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);492 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
487493
488 try test__powixf2(1, 1, 1);494 try test_powi_f128(1, 1, 1);
489 try test__powixf2(1, 2, 1);495 try test_powi_f128(1, 2, 1);
490 try test__powixf2(1, 3, 1);496 try test_powi_f128(1, 3, 1);
491 try test__powixf2(1, 4, 1);497 try test_powi_f128(1, 4, 1);
492 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);498 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
493 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);499 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
494500
495 try test__powixf2(inf_f80, 1, inf_f80);501 try test_powi_f128(inf_f128, 1, inf_f128);
496 try test__powixf2(inf_f80, 2, inf_f80);502 try test_powi_f128(inf_f128, 2, inf_f128);
497 try test__powixf2(inf_f80, 3, inf_f80);503 try test_powi_f128(inf_f128, 3, inf_f128);
498 try test__powixf2(inf_f80, 4, inf_f80);504 try test_powi_f128(inf_f128, 4, inf_f128);
499 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);505 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
500 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80);506 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128);
501507
502 try test__powixf2(-inf_f80, 1, -inf_f80);508 try test_powi_f128(-inf_f128, 1, -inf_f128);
503 try test__powixf2(-inf_f80, 2, inf_f80);509 try test_powi_f128(-inf_f128, 2, inf_f128);
504 try test__powixf2(-inf_f80, 3, -inf_f80);510 try test_powi_f128(-inf_f128, 3, -inf_f128);
505 try test__powixf2(-inf_f80, 4, inf_f80);511 try test_powi_f128(-inf_f128, 4, inf_f128);
506 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);512 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
507 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80);513 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128);
508514
509 try test__powixf2(0, -1, inf_f80);515 try test_powi_f128(0, -1, inf_f128);
510 try test__powixf2(0, -2, inf_f80);516 try test_powi_f128(0, -2, inf_f128);
511 try test__powixf2(0, -3, inf_f80);517 try test_powi_f128(0, -3, inf_f128);
512 try test__powixf2(0, -4, inf_f80);518 try test_powi_f128(0, -4, inf_f128);
513 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);519 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
514 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80);520 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128);
515 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);521 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
516522
517 try test__powixf2(-0.0, -1, -inf_f80);523 try test_powi_f128(-0.0, -1, -inf_f128);
518 try test__powixf2(-0.0, -2, inf_f80);524 try test_powi_f128(-0.0, -2, inf_f128);
519 try test__powixf2(-0.0, -3, -inf_f80);525 try test_powi_f128(-0.0, -3, -inf_f128);
520 try test__powixf2(-0.0, -4, inf_f80);526 try test_powi_f128(-0.0, -4, inf_f128);
521 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);527 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
522 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80);528 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128);
523 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);529 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
524530
525 try test__powixf2(1, -1, 1);531 try test_powi_f128(1, -1, 1);
526 try test__powixf2(1, -2, 1);532 try test_powi_f128(1, -2, 1);
527 try test__powixf2(1, -3, 1);533 try test_powi_f128(1, -3, 1);
528 try test__powixf2(1, -4, 1);534 try test_powi_f128(1, -4, 1);
529 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);535 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
530 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);536 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
531 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);537 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
532538
533 try test__powixf2(inf_f80, -1, 0);539 try test_powi_f128(inf_f128, -1, 0);
534 try test__powixf2(inf_f80, -2, 0);540 try test_powi_f128(inf_f128, -2, 0);
535 try test__powixf2(inf_f80, -3, 0);541 try test_powi_f128(inf_f128, -3, 0);
536 try test__powixf2(inf_f80, -4, 0);542 try test_powi_f128(inf_f128, -4, 0);
537 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);543 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
538 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);544 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
539 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);545 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
540546
541 try test__powixf2(-inf_f80, -1, -0.0);547 try test_powi_f128(-inf_f128, -1, -0.0);
542 try test__powixf2(-inf_f80, -2, 0);548 try test_powi_f128(-inf_f128, -2, 0);
543 try test__powixf2(-inf_f80, -3, -0.0);549 try test_powi_f128(-inf_f128, -3, -0.0);
544 try test__powixf2(-inf_f80, -4, 0);550 try test_powi_f128(-inf_f128, -4, 0);
545 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);551 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
546 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);552 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
547 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);553 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
548554
549 try test__powixf2(2, 10, 1024.0);555 try test_powi_f128(2, 10, 1024.0);
550 try test__powixf2(-2, 10, 1024.0);556 try test_powi_f128(-2, 10, 1024.0);
551 try test__powixf2(2, -10, 1.0 / 1024.0);557 try test_powi_f128(2, -10, 1.0 / 1024.0);
552 try test__powixf2(-2, -10, 1.0 / 1024.0);558 try test_powi_f128(-2, -10, 1.0 / 1024.0);
553559
554 try test__powixf2(2, 19, 524288.0);560 try test_powi_f128(2, 19, 524288.0);
555 try test__powixf2(-2, 19, -524288.0);561 try test_powi_f128(-2, 19, -524288.0);
556 try test__powixf2(2, -19, 1.0 / 524288.0);562 try test_powi_f128(2, -19, 1.0 / 524288.0);
557 try test__powixf2(-2, -19, -1.0 / 524288.0);563 try test_powi_f128(-2, -19, -1.0 / 524288.0);
558564
559 try test__powixf2(2, 31, 2147483648.0);565 try test_powi_f128(2, 31, 2147483648.0);
560 try test__powixf2(-2, 31, -2147483648.0);566 try test_powi_f128(-2, 31, -2147483648.0);
561 try test__powixf2(2, -31, 1.0 / 2147483648.0);567 try test_powi_f128(2, -31, 1.0 / 2147483648.0);
562 try test__powixf2(-2, -31, -1.0 / 2147483648.0);568 try test_powi_f128(-2, -31, -1.0 / 2147483648.0);
563}569}
lib/compiler_rt/round.zig+87-50
...@@ -18,19 +18,22 @@ comptime {...@@ -18,19 +18,22 @@ comptime {
18 symbol(&roundf, "roundf");18 symbol(&roundf, "roundf");
19 symbol(&round, "round");19 symbol(&round, "round");
20 symbol(&__roundx, "__roundx");20 symbol(&__roundx, "__roundx");
21 if (compiler_rt.want_ppc_abi) {21 symbol(&roundq, "roundf128");
22 symbol(&roundq, "roundf128");
23 }
24 symbol(&roundq, "roundq");
25 symbol(&roundl, "roundl");22 symbol(&roundl, "roundl");
26}23}
2724
28pub fn __roundh(x: f16) callconv(.c) f16 {25fn __roundh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
26 return compiler_rt.f16.toAbi(round_f16(compiler_rt.f16.fromAbi(x)));
27}
28pub fn round_f16(x: f16) f16 {
29 // TODO: more efficient implementation29 // TODO: more efficient implementation
30 return @floatCast(roundf(x));30 return @floatCast(round_f32(x));
31}31}
3232
33pub fn roundf(x_: f32) callconv(.c) f32 {33fn roundf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
34 return compiler_rt.f32.toAbi(round_f32(compiler_rt.f32.fromAbi(x)));
35}
36pub fn round_f32(x_: f32) f32 {
34 const f32_toint = 1.0 / math.floatEps(f32);37 const f32_toint = 1.0 / math.floatEps(f32);
3538
36 var x = x_;39 var x = x_;
...@@ -65,7 +68,10 @@ pub fn roundf(x_: f32) callconv(.c) f32 {...@@ -65,7 +68,10 @@ pub fn roundf(x_: f32) callconv(.c) f32 {
65 }68 }
66}69}
6770
68pub fn round(x_: f64) callconv(.c) f64 {71fn round(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
72 return compiler_rt.f64.toAbi(round_f64(compiler_rt.f64.fromAbi(x)));
73}
74pub fn round_f64(x_: f64) f64 {
69 const f64_toint = 1.0 / math.floatEps(f64);75 const f64_toint = 1.0 / math.floatEps(f64);
7076
71 var x = x_;77 var x = x_;
...@@ -100,12 +106,18 @@ pub fn round(x_: f64) callconv(.c) f64 {...@@ -100,12 +106,18 @@ pub fn round(x_: f64) callconv(.c) f64 {
100 }106 }
101}107}
102108
103pub fn __roundx(x: f80) callconv(.c) f80 {109fn __roundx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
110 return compiler_rt.f80.toAbi(round_f80(compiler_rt.f80.fromAbi(x)));
111}
112pub fn round_f80(x: f80) f80 {
104 // TODO: more efficient implementation113 // TODO: more efficient implementation
105 return @floatCast(roundq(x));114 return @floatCast(round_f128(x));
106}115}
107116
108pub fn roundq(x_: f128) callconv(.c) f128 {117fn roundq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
118 return compiler_rt.f128.toAbi(round_f128(compiler_rt.f128.fromAbi(x)));
119}
120pub fn round_f128(x_: f128) f128 {
109 const f128_toint = 1.0 / math.floatEps(f128);121 const f128_toint = 1.0 / math.floatEps(f128);
110122
111 var x = x_;123 var x = x_;
...@@ -142,54 +154,79 @@ pub fn roundq(x_: f128) callconv(.c) f128 {...@@ -142,54 +154,79 @@ pub fn roundq(x_: f128) callconv(.c) f128 {
142154
143pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble {155pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble {
144 switch (@typeInfo(c_longdouble).float.bits) {156 switch (@typeInfo(c_longdouble).float.bits) {
145 64 => return round(x),157 64 => return round_f64(x),
146 80 => return __roundx(x),158 80 => return round_f80(x),
147 128 => return roundq(x),159 128 => return round_f128(x),
148 else => @compileError("unreachable"),160 else => comptime unreachable,
149 }161 }
150}162}
151163
152test "round32" {164test round_f16 {
153 try expect(roundf(1.3) == 1.0);165 try expect(round_f16(1.3) == 1.0);
154 try expect(roundf(-1.3) == -1.0);166 try expect(round_f16(-1.3) == -1.0);
155 try expect(roundf(0.2) == 0.0);167 try expect(round_f16(1.8) == 2.0);
156 try expect(roundf(1.8) == 2.0);168 try expect(round_f16(-1.8) == -2.0);
157}169 try expect(math.isPositiveZero(round_f16(0.2)));
158170 try expect(math.isNegativeZero(round_f16(-0.2)));
159test "round64" {171 try expect(math.isPositiveZero(round_f16(0.0)));
160 try expect(round(1.3) == 1.0);172 try expect(math.isNegativeZero(round_f16(-0.0)));
161 try expect(round(-1.3) == -1.0);173 try expect(math.isPositiveInf(round_f16(math.inf(f32))));
162 try expect(round(0.2) == 0.0);174 try expect(math.isNegativeInf(round_f16(-math.inf(f32))));
163 try expect(round(1.8) == 2.0);175 try expect(math.isNan(round_f16(math.nan(f32))));
164}176}
165177
166test "round128" {178test round_f32 {
167 try expect(roundq(1.3) == 1.0);179 try expect(round_f32(1.3) == 1.0);
168 try expect(roundq(-1.3) == -1.0);180 try expect(round_f32(-1.3) == -1.0);
169 try expect(roundq(0.2) == 0.0);181 try expect(round_f32(1.8) == 2.0);
170 try expect(roundq(1.8) == 2.0);182 try expect(round_f32(-1.8) == -2.0);
183 try expect(math.isPositiveZero(round_f32(0.2)));
184 try expect(math.isNegativeZero(round_f32(-0.2)));
185 try expect(math.isPositiveZero(round_f32(0.0)));
186 try expect(math.isNegativeZero(round_f32(-0.0)));
187 try expect(math.isPositiveInf(round_f32(math.inf(f32))));
188 try expect(math.isNegativeInf(round_f32(-math.inf(f32))));
189 try expect(math.isNan(round_f32(math.nan(f32))));
171}190}
172191
173test "round32.special" {192test round_f64 {
174 try expect(roundf(0.0) == 0.0);193 try expect(round_f64(1.3) == 1.0);
175 try expect(roundf(-0.0) == -0.0);194 try expect(round_f64(-1.3) == -1.0);
176 try expect(math.isPositiveInf(roundf(math.inf(f32))));195 try expect(round_f64(1.8) == 2.0);
177 try expect(math.isNegativeInf(roundf(-math.inf(f32))));196 try expect(round_f64(-1.8) == -2.0);
178 try expect(math.isNan(roundf(math.nan(f32))));197 try expect(math.isPositiveZero(round_f64(0.2)));
198 try expect(math.isNegativeZero(round_f64(-0.2)));
199 try expect(math.isPositiveZero(round_f64(0.0)));
200 try expect(math.isNegativeZero(round_f64(-0.0)));
201 try expect(math.isPositiveInf(round_f64(math.inf(f64))));
202 try expect(math.isNegativeInf(round_f64(-math.inf(f64))));
203 try expect(math.isNan(round_f64(math.nan(f64))));
179}204}
180205
181test "round64.special" {206test round_f80 {
182 try expect(round(0.0) == 0.0);207 try expect(round_f80(1.3) == 1.0);
183 try expect(round(-0.0) == -0.0);208 try expect(round_f80(-1.3) == -1.0);
184 try expect(math.isPositiveInf(round(math.inf(f64))));209 try expect(round_f80(1.8) == 2.0);
185 try expect(math.isNegativeInf(round(-math.inf(f64))));210 try expect(round_f80(-1.8) == -2.0);
186 try expect(math.isNan(round(math.nan(f64))));211 try expect(math.isPositiveZero(round_f80(0.2)));
212 try expect(math.isNegativeZero(round_f80(-0.2)));
213 try expect(math.isPositiveZero(round_f80(0.0)));
214 try expect(math.isNegativeZero(round_f80(-0.0)));
215 try expect(math.isPositiveInf(round_f80(math.inf(f64))));
216 try expect(math.isNegativeInf(round_f80(-math.inf(f64))));
217 try expect(math.isNan(round_f80(math.nan(f64))));
187}218}
188219
189test "round128.special" {220test round_f128 {
190 try expect(roundq(0.0) == 0.0);221 try expect(round_f128(1.3) == 1.0);
191 try expect(roundq(-0.0) == -0.0);222 try expect(round_f128(-1.3) == -1.0);
192 try expect(math.isPositiveInf(roundq(math.inf(f128))));223 try expect(round_f128(1.8) == 2.0);
193 try expect(math.isNegativeInf(roundq(-math.inf(f128))));224 try expect(round_f128(-1.8) == -2.0);
194 try expect(math.isNan(roundq(math.nan(f128))));225 try expect(math.isPositiveZero(round_f128(0.2)));
226 try expect(math.isNegativeZero(round_f128(-0.2)));
227 try expect(math.isPositiveZero(round_f128(0.0)));
228 try expect(math.isNegativeZero(round_f128(-0.0)));
229 try expect(math.isPositiveInf(round_f128(math.inf(f128))));
230 try expect(math.isNegativeInf(round_f128(-math.inf(f128))));
231 try expect(math.isNan(round_f128(math.nan(f128))));
195}232}
lib/compiler_rt/sin.zig+66-53
...@@ -13,31 +13,34 @@ const expect = std.testing.expect;...@@ -13,31 +13,34 @@ const expect = std.testing.expect;
13const expectApproxEqAbs = std.testing.expectApproxEqAbs;13const expectApproxEqAbs = std.testing.expectApproxEqAbs;
1414
15const compiler_rt = @import("../compiler_rt.zig");15const compiler_rt = @import("../compiler_rt.zig");
16const symbol = @import("../compiler_rt.zig").symbol;16const symbol = compiler_rt.symbol;
17const trig = @import("trig.zig");17const trig = @import("trig.zig");
18const rem_pio2 = @import("rem_pio2.zig").rem_pio2;18const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
19const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;19const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
20const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;20const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
2121
22comptime {22comptime {
23 symbol(&sinh, "__sinh");23 symbol(&__sinh, "__sinh");
24 symbol(&sinl, "__sinl");
25 symbol(&sinf, "sinf");24 symbol(&sinf, "sinf");
26 symbol(&sin, "sin");25 symbol(&sin, "sin");
27 symbol(&sinx, "__sinx");26 symbol(&__sinx, "__sinx");
28 if (compiler_rt.want_ppc_abi) {27 symbol(&sinq, "sinf128");
29 symbol(&sinq, "sinf128");
30 }
31 symbol(&sinq, "sinq");
32 symbol(&sinl, "sinl");28 symbol(&sinl, "sinl");
29 symbol(&sinl, "__sinl"); // required by musl
33}30}
3431
35pub fn sinh(x: f16) callconv(.c) f16 {32fn __sinh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
33 return compiler_rt.f16.toAbi(sin_f16(compiler_rt.f16.fromAbi(x)));
34}
35pub fn sin_f16(x: f16) f16 {
36 // TODO: more efficient implementation36 // TODO: more efficient implementation
37 return @floatCast(sinf(x));37 return @floatCast(sin_f32(x));
38}38}
3939
40pub fn sinf(x: f32) callconv(.c) f32 {40fn sinf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
41 return compiler_rt.f32.toAbi(sin_f32(compiler_rt.f32.fromAbi(x)));
42}
43pub fn sin_f32(x: f32) f32 {
41 // Small multiples of pi/2 rounded to double precision.44 // Small multiples of pi/2 rounded to double precision.
42 const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D1845 const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
43 const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D1846 const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
...@@ -98,7 +101,10 @@ pub fn sinf(x: f32) callconv(.c) f32 {...@@ -98,7 +101,10 @@ pub fn sinf(x: f32) callconv(.c) f32 {
98 };101 };
99}102}
100103
101pub fn sin(x: f64) callconv(.c) f64 {104fn sin(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
105 return compiler_rt.f64.toAbi(sin_f64(compiler_rt.f64.fromAbi(x)));
106}
107pub fn sin_f64(x: f64) f64 {
102 var ix = @as(u64, @bitCast(x)) >> 32;108 var ix = @as(u64, @bitCast(x)) >> 32;
103 ix &= 0x7fffffff;109 ix &= 0x7fffffff;
104110
...@@ -133,7 +139,10 @@ pub fn sin(x: f64) callconv(.c) f64 {...@@ -133,7 +139,10 @@ pub fn sin(x: f64) callconv(.c) f64 {
133 };139 };
134}140}
135141
136fn sinx(x: f80) callconv(.c) f80 {142fn __sinx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
143 return compiler_rt.f80.toAbi(sin_f80(compiler_rt.f80.fromAbi(x)));
144}
145pub fn sin_f80(x: f80) f80 {
137 const se = ld.signExponent(x) & 0x7fff;146 const se = ld.signExponent(x) & 0x7fff;
138 if (se == 0x7fff) {147 if (se == 0x7fff) {
139 return x - x;148 return x - x;
...@@ -160,7 +169,10 @@ fn sinx(x: f80) callconv(.c) f80 {...@@ -160,7 +169,10 @@ fn sinx(x: f80) callconv(.c) f80 {
160 };169 };
161}170}
162171
163pub fn sinq(x: f128) callconv(.c) f128 {172fn sinq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
173 return compiler_rt.f128.toAbi(sin_f128(compiler_rt.f128.fromAbi(x)));
174}
175pub fn sin_f128(x: f128) f128 {
164 const se = ld.signExponent(x) & 0x7fff;176 const se = ld.signExponent(x) & 0x7fff;
165 if (se == 0x7fff) {177 if (se == 0x7fff) {
166 return x - x;178 return x - x;
...@@ -189,20 +201,21 @@ pub fn sinq(x: f128) callconv(.c) f128 {...@@ -189,20 +201,21 @@ pub fn sinq(x: f128) callconv(.c) f128 {
189201
190pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble {202pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble {
191 switch (@typeInfo(c_longdouble).float.bits) {203 switch (@typeInfo(c_longdouble).float.bits) {
192 64 => return sin(x),204 64 => return sin_f64(x),
193 80 => return sinx(x),205 80 => return sin_f80(x),
194 128 => return sinq(x),206 128 => return sin_f128(x),
195 else => @compileError("unreachable"),207 else => comptime unreachable,
196 }208 }
197}209}
198210
199fn testSinSpecial(comptime T: type) !void {211fn testSinSpecial(comptime T: type) !void {
200 const f = switch (T) {212 const f = switch (T) {
201 f32 => sinf,213 f16 => sin_f16,
202 f64 => sin,214 f32 => sin_f32,
203 f80 => sinx,215 f64 => sin_f64,
204 f128 => sinq,216 f80 => sin_f80,
205 else => @compileError("unimplemented"),217 f128 => sin_f128,
218 else => comptime unreachable,
206 };219 };
207220
208 try expect(math.isPositiveZero(f(0.0)));221 try expect(math.isPositiveZero(f(0.0)));
...@@ -214,13 +227,13 @@ fn testSinSpecial(comptime T: type) !void {...@@ -214,13 +227,13 @@ fn testSinSpecial(comptime T: type) !void {
214227
215test "sin32.normal" {228test "sin32.normal" {
216 const epsilon = math.floatEps(f32);229 const epsilon = math.floatEps(f32);
217 try expectApproxEqAbs(@as(f32, 0.0), sinf(0.0), epsilon);230 try expectApproxEqAbs(@as(f32, 0.0), sin_f32(0.0), epsilon);
218 try expectApproxEqAbs(@as(f32, 0.19866933), sinf(0.2), epsilon);231 try expectApproxEqAbs(@as(f32, 0.19866933), sin_f32(0.2), epsilon);
219 try expectApproxEqAbs(@as(f32, 0.77851737), sinf(0.8923), epsilon);232 try expectApproxEqAbs(@as(f32, 0.77851737), sin_f32(0.8923), epsilon);
220 try expectApproxEqAbs(@as(f32, 0.997495), sinf(1.5), epsilon);233 try expectApproxEqAbs(@as(f32, 0.997495), sin_f32(1.5), epsilon);
221 try expectApproxEqAbs(@as(f32, -0.997495), sinf(-1.5), epsilon);234 try expectApproxEqAbs(@as(f32, -0.997495), sin_f32(-1.5), epsilon);
222 try expectApproxEqAbs(@as(f32, -0.24654257), sinf(37.45), epsilon);235 try expectApproxEqAbs(@as(f32, -0.24654257), sin_f32(37.45), epsilon);
223 try expectApproxEqAbs(@as(f32, 0.9161657), sinf(89.123), epsilon);236 try expectApproxEqAbs(@as(f32, 0.9161657), sin_f32(89.123), epsilon);
224}237}
225238
226test "sin32.special" {239test "sin32.special" {
...@@ -229,13 +242,13 @@ test "sin32.special" {...@@ -229,13 +242,13 @@ test "sin32.special" {
229242
230test "sin64.normal" {243test "sin64.normal" {
231 const epsilon = math.floatEps(f64);244 const epsilon = math.floatEps(f64);
232 try expectApproxEqAbs(@as(f64, 0.0), sin(0.0), epsilon);245 try expectApproxEqAbs(@as(f64, 0.0), sin_f64(0.0), epsilon);
233 try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin(0.2), epsilon);246 try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin_f64(0.2), epsilon);
234 try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin(0.8923), epsilon);247 try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin_f64(0.8923), epsilon);
235 try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin(1.5), epsilon);248 try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin_f64(1.5), epsilon);
236 try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin(-1.5), epsilon);249 try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin_f64(-1.5), epsilon);
237 try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin(37.45), epsilon);250 try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin_f64(37.45), epsilon);
238 try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin(89.123), epsilon);251 try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin_f64(89.123), epsilon);
239}252}
240253
241test "sin64.special" {254test "sin64.special" {
...@@ -244,13 +257,13 @@ test "sin64.special" {...@@ -244,13 +257,13 @@ test "sin64.special" {
244257
245test "sin80.normal" {258test "sin80.normal" {
246 const epsilon = math.floatEps(f80);259 const epsilon = math.floatEps(f80);
247 try expectApproxEqAbs(@as(f80, 0.0), sinx(0.0), epsilon);260 try expectApproxEqAbs(@as(f80, 0.0), sin_f80(0.0), epsilon);
248 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sinx(0.2), epsilon);261 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sin_f80(0.2), epsilon);
249 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sinx(0.8923), epsilon);262 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sin_f80(0.8923), epsilon);
250 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sinx(1.5), epsilon);263 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sin_f80(1.5), epsilon);
251 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sinx(-1.5), epsilon);264 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sin_f80(-1.5), epsilon);
252 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sinx(37.45), epsilon);265 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sin_f80(37.45), epsilon);
253 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sinx(89.123), epsilon);266 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sin_f80(89.123), epsilon);
254}267}
255268
256test "sin80.special" {269test "sin80.special" {
...@@ -259,13 +272,13 @@ test "sin80.special" {...@@ -259,13 +272,13 @@ test "sin80.special" {
259272
260test "sin128.normal" {273test "sin128.normal" {
261 const epsilon = math.floatEps(f128);274 const epsilon = math.floatEps(f128);
262 try expectApproxEqAbs(@as(f128, 0.0), sinq(0.0), epsilon);275 try expectApproxEqAbs(@as(f128, 0.0), sin_f128(0.0), epsilon);
263 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sinq(0.2), epsilon);276 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sin_f128(0.2), epsilon);
264 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sinq(0.8923), epsilon);277 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sin_f128(0.8923), epsilon);
265 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sinq(1.5), epsilon);278 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sin_f128(1.5), epsilon);
266 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sinq(-1.5), epsilon);279 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sin_f128(-1.5), epsilon);
267 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sinq(37.45), epsilon);280 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sin_f128(37.45), epsilon);
268 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sinq(89.123), epsilon);281 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sin_f128(89.123), epsilon);
269}282}
270283
271test "sin128.special" {284test "sin128.special" {
...@@ -274,10 +287,10 @@ test "sin128.special" {...@@ -274,10 +287,10 @@ test "sin128.special" {
274287
275test "sin32 #9901" {288test "sin32 #9901" {
276 const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000));289 const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000));
277 _ = sinf(float);290 _ = sin_f32(float);
278}291}
279292
280test "sin64 #9901" {293test "sin64 #9901" {
281 const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001));294 const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001));
282 _ = sin(float);295 _ = sin_f64(float);
283}296}
lib/compiler_rt/sincos.zig+125-181
...@@ -18,23 +18,27 @@ comptime {...@@ -18,23 +18,27 @@ comptime {
18 symbol(&sincosf, "sincosf");18 symbol(&sincosf, "sincosf");
19 symbol(&sincos, "sincos");19 symbol(&sincos, "sincos");
20 symbol(&sincosx, "__sincosx");20 symbol(&sincosx, "__sincosx");
21 if (compiler_rt.want_ppc_abi) {21 symbol(&sincosq, "sincosf128");
22 symbol(&sincosq, "sincosf128");
23 }
24 symbol(&sincosq, "sincosq");
25 symbol(&sincosl, "sincosl");22 symbol(&sincosl, "sincosl");
26}23}
2724
28pub fn sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void {25fn sincosh(x: compiler_rt.f16.Abi, r_sin: *compiler_rt.f16.Abi, r_cos: *compiler_rt.f16.Abi) callconv(.c) void {
26 const s, const c = sincos_f16(compiler_rt.f16.fromAbi(x));
27 r_sin.* = compiler_rt.f16.toAbi(s);
28 r_cos.* = compiler_rt.f16.toAbi(c);
29}
30pub fn sincos_f16(x: f16) struct { f16, f16 } {
29 // TODO: more efficient implementation31 // TODO: more efficient implementation
30 var big_sin: f32 = undefined;32 const s, const c = sincos_f32(x);
31 var big_cos: f32 = undefined;33 return .{ @floatCast(s), @floatCast(c) };
32 sincosf(x, &big_sin, &big_cos);
33 r_sin.* = @as(f16, @floatCast(big_sin));
34 r_cos.* = @as(f16, @floatCast(big_cos));
35}34}
3635
37pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {36fn sincosf(x: compiler_rt.f32.Abi, r_sin: *compiler_rt.f32.Abi, r_cos: *compiler_rt.f32.Abi) callconv(.c) void {
37 const s, const c = sincos_f32(compiler_rt.f32.fromAbi(x));
38 r_sin.* = compiler_rt.f32.toAbi(s);
39 r_cos.* = compiler_rt.f32.toAbi(c);
40}
41pub fn sincos_f32(x: f32) struct { f32, f32 } {
38 const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D1842 const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
39 const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D1843 const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
40 const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D244 const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2
...@@ -56,13 +60,9 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {...@@ -56,13 +60,9 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
56 mem.doNotOptimizeAway(x + 0x1p120);60 mem.doNotOptimizeAway(x + 0x1p120);
57 }61 }
58 }62 }
59 r_sin.* = x;63 return .{ x, 1.0 };
60 r_cos.* = 1.0;
61 return;
62 }64 }
63 r_sin.* = trig.sindf(x);65 return .{ trig.sindf(x), trig.cosdf(x) };
64 r_cos.* = trig.cosdf(x);
65 return;
66 }66 }
6767
68 // |x| ~<= 5*pi/468 // |x| ~<= 5*pi/4
...@@ -70,18 +70,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {...@@ -70,18 +70,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
70 // |x| ~<= 3pi/470 // |x| ~<= 3pi/4
71 if (ix <= 0x4016cbe3) {71 if (ix <= 0x4016cbe3) {
72 if (sign) {72 if (sign) {
73 r_sin.* = -trig.cosdf(x + sc1pio2);73 return .{ -trig.cosdf(x + sc1pio2), trig.sindf(x + sc1pio2) };
74 r_cos.* = trig.sindf(x + sc1pio2);
75 } else {74 } else {
76 r_sin.* = trig.cosdf(sc1pio2 - x);75 return .{ trig.cosdf(sc1pio2 - x), trig.sindf(sc1pio2 - x) };
77 r_cos.* = trig.sindf(sc1pio2 - x);
78 }76 }
79 return;
80 }77 }
81 // -sin(x+c) is not correct if x+c could be 0: -0 vs +078 // -sin(x+c) is not correct if x+c could be 0: -0 vs +0
82 r_sin.* = -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2);79 return .{
83 r_cos.* = -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2);80 -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2),
84 return;81 -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2),
82 };
85 }83 }
8684
87 // |x| ~<= 9*pi/485 // |x| ~<= 9*pi/4
...@@ -89,25 +87,21 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {...@@ -89,25 +87,21 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
89 // |x| ~<= 7*pi/487 // |x| ~<= 7*pi/4
90 if (ix <= 0x40afeddf) {88 if (ix <= 0x40afeddf) {
91 if (sign) {89 if (sign) {
92 r_sin.* = trig.cosdf(x + sc3pio2);90 return .{ trig.cosdf(x + sc3pio2), -trig.sindf(x + sc3pio2) };
93 r_cos.* = -trig.sindf(x + sc3pio2);
94 } else {91 } else {
95 r_sin.* = -trig.cosdf(x - sc3pio2);92 return .{ -trig.cosdf(x - sc3pio2), trig.sindf(x - sc3pio2) };
96 r_cos.* = trig.sindf(x - sc3pio2);
97 }93 }
98 return;
99 }94 }
100 r_sin.* = trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2);95 return .{
101 r_cos.* = trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2);96 trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2),
102 return;97 trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2),
98 };
103 }99 }
104100
105 // sin(Inf or NaN) is NaN101 // sin(Inf or NaN) is NaN
106 if (ix >= 0x7f800000) {102 if (ix >= 0x7f800000) {
107 const result = x - x;103 const result = x - x;
108 r_sin.* = result;104 return .{ result, result };
109 r_cos.* = result;
110 return;
111 }105 }
112106
113 // general argument reduction needed107 // general argument reduction needed
...@@ -115,27 +109,20 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {...@@ -115,27 +109,20 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
115 const n = rem_pio2f(x, &y);109 const n = rem_pio2f(x, &y);
116 const s = trig.sindf(y);110 const s = trig.sindf(y);
117 const c = trig.cosdf(y);111 const c = trig.cosdf(y);
118 switch (n & 3) {112 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
119 0 => {113 0 => .{ s, c },
120 r_sin.* = s;114 1 => .{ c, -s },
121 r_cos.* = c;115 2 => .{ -s, -c },
122 },116 3 => .{ -c, s },
123 1 => {117 };
124 r_sin.* = c;
125 r_cos.* = -s;
126 },
127 2 => {
128 r_sin.* = -s;
129 r_cos.* = -c;
130 },
131 else => {
132 r_sin.* = -c;
133 r_cos.* = s;
134 },
135 }
136}118}
137119
138pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {120fn sincos(x: compiler_rt.f64.Abi, r_sin: *compiler_rt.f64.Abi, r_cos: *compiler_rt.f64.Abi) callconv(.c) void {
121 const s, const c = sincos_f64(compiler_rt.f64.fromAbi(x));
122 r_sin.* = compiler_rt.f64.toAbi(s);
123 r_cos.* = compiler_rt.f64.toAbi(c);
124}
125pub fn sincos_f64(x: f64) struct { f64, f64 } {
139 const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff;126 const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff;
140127
141 // |x| ~< pi/4128 // |x| ~< pi/4
...@@ -150,21 +137,15 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {...@@ -150,21 +137,15 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {
150 mem.doNotOptimizeAway(x + 0x1p120);137 mem.doNotOptimizeAway(x + 0x1p120);
151 }138 }
152 }139 }
153 r_sin.* = x;140 return .{ x, 1.0 };
154 r_cos.* = 1.0;
155 return;
156 }141 }
157 r_sin.* = trig.sin(x, 0.0, 0);142 return .{ trig.sin(x, 0.0, 0), trig.cos(x, 0.0) };
158 r_cos.* = trig.cos(x, 0.0);
159 return;
160 }143 }
161144
162 // sincos(Inf or NaN) is NaN145 // sincos(Inf or NaN) is NaN
163 if (ix >= 0x7ff00000) {146 if (ix >= 0x7ff00000) {
164 const result = x - x;147 const result = x - x;
165 r_sin.* = result;148 return .{ result, result };
166 r_cos.* = result;
167 return;
168 }149 }
169150
170 // argument reduction needed151 // argument reduction needed
...@@ -172,33 +153,24 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {...@@ -172,33 +153,24 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {
172 const n = rem_pio2(x, &y);153 const n = rem_pio2(x, &y);
173 const s = trig.sin(y[0], y[1], 1);154 const s = trig.sin(y[0], y[1], 1);
174 const c = trig.cos(y[0], y[1]);155 const c = trig.cos(y[0], y[1]);
175 switch (n & 3) {156 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
176 0 => {157 0 => .{ s, c },
177 r_sin.* = s;158 1 => .{ c, -s },
178 r_cos.* = c;159 2 => .{ -s, -c },
179 },160 3 => .{ -c, s },
180 1 => {161 };
181 r_sin.* = c;
182 r_cos.* = -s;
183 },
184 2 => {
185 r_sin.* = -s;
186 r_cos.* = -c;
187 },
188 else => {
189 r_sin.* = -c;
190 r_cos.* = s;
191 },
192 }
193}162}
194163
195pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void {164fn sincosx(x: compiler_rt.f80.Abi, r_sin: *compiler_rt.f80.Abi, r_cos: *compiler_rt.f80.Abi) callconv(.c) void {
165 const s, const c = sincos_f80(compiler_rt.f80.fromAbi(x));
166 r_sin.* = compiler_rt.f80.toAbi(s);
167 r_cos.* = compiler_rt.f80.toAbi(c);
168}
169pub fn sincos_f80(x: f80) struct { f80, f80 } {
196 const se = ld.signExponent(x) & 0x7fff;170 const se = ld.signExponent(x) & 0x7fff;
197 if (se == 0x7fff) {171 if (se == 0x7fff) {
198 const result = x - x;172 const result = x - x;
199 r_sin.* = result;173 return .{ result, result };
200 r_cos.* = result;
201 return;
202 }174 }
203175
204 if (@abs(x) < trig.pi_4) {176 if (@abs(x) < trig.pi_4) {
...@@ -207,47 +179,34 @@ pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void {...@@ -207,47 +179,34 @@ pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void {
207 if (compiler_rt.want_float_exceptions and se == 0) {179 if (compiler_rt.want_float_exceptions and se == 0) {
208 mem.doNotOptimizeAway(x * 0x1p-120);180 mem.doNotOptimizeAway(x * 0x1p-120);
209 }181 }
210 r_sin.* = x;
211 // raise inexact if x!=0182 // raise inexact if x!=0
212 r_cos.* = 1.0 + x;183 return .{ x, 1.0 + x };
213 return;
214 }184 }
215 r_sin.* = trig.sinx(x, 0.0, 0);185 return .{ trig.sinx(x, 0.0, 0), trig.cosx(x, 0.0) };
216 r_cos.* = trig.cosx(x, 0.0);
217 return;
218 }186 }
219187
220 var y: [2]f80 = undefined;188 var y: [2]f80 = undefined;
221 const n = rem_pio2l(f80, x, &y);189 const n = rem_pio2l(f80, x, &y);
222 const s = trig.sinx(y[0], y[1], 1);190 const s = trig.sinx(y[0], y[1], 1);
223 const c = trig.cosx(y[0], y[1]);191 const c = trig.cosx(y[0], y[1]);
224 switch (n & 3) {192 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
225 0 => {193 0 => .{ s, c },
226 r_sin.* = s;194 1 => .{ c, -s },
227 r_cos.* = c;195 2 => .{ -s, -c },
228 },196 3 => .{ -c, s },
229 1 => {197 };
230 r_sin.* = c;
231 r_cos.* = -s;
232 },
233 2 => {
234 r_sin.* = -s;
235 r_cos.* = -c;
236 },
237 else => {
238 r_sin.* = -c;
239 r_cos.* = s;
240 },
241 }
242}198}
243199
244pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void {200fn sincosq(x: compiler_rt.f128.Abi, r_sin: *compiler_rt.f128.Abi, r_cos: *compiler_rt.f128.Abi) callconv(.c) void {
201 const s, const c = sincos_f128(compiler_rt.f128.fromAbi(x));
202 r_sin.* = compiler_rt.f128.toAbi(s);
203 r_cos.* = compiler_rt.f128.toAbi(c);
204}
205pub fn sincos_f128(x: f128) struct { f128, f128 } {
245 const se = ld.signExponent(x) & 0x7fff;206 const se = ld.signExponent(x) & 0x7fff;
246 if (se == 0x7fff) {207 if (se == 0x7fff) {
247 const result = x - x;208 const result = x - x;
248 r_sin.* = result;209 return .{ result, result };
249 r_cos.* = result;
250 return;
251 }210 }
252211
253 if (@abs(x) < trig.pi_4) {212 if (@abs(x) < trig.pi_4) {
...@@ -256,78 +215,63 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void {...@@ -256,78 +215,63 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void {
256 if (compiler_rt.want_float_exceptions and se == 0) {215 if (compiler_rt.want_float_exceptions and se == 0) {
257 mem.doNotOptimizeAway(x * 0x1p-120);216 mem.doNotOptimizeAway(x * 0x1p-120);
258 }217 }
259 r_sin.* = x;
260 // raise inexact if x!=0218 // raise inexact if x!=0
261 r_cos.* = 1.0 + x;219 return .{ x, 1.0 + x };
262 return;
263 }220 }
264 r_sin.* = trig.sinq(x, 0.0, 0);221 return .{ trig.sinq(x, 0.0, 0), trig.cosq(x, 0.0) };
265 r_cos.* = trig.cosq(x, 0.0);
266 return;
267 }222 }
268223
269 var y: [2]f128 = undefined;224 var y: [2]f128 = undefined;
270 const n = rem_pio2l(f128, x, &y);225 const n = rem_pio2l(f128, x, &y);
271 const s = trig.sinq(y[0], y[1], 1);226 const s = trig.sinq(y[0], y[1], 1);
272 const c = trig.cosq(y[0], y[1]);227 const c = trig.cosq(y[0], y[1]);
273 switch (n & 3) {228 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
274 0 => {229 0 => .{ s, c },
275 r_sin.* = s;230 1 => .{ c, -s },
276 r_cos.* = c;231 2 => .{ -s, -c },
277 },232 3 => .{ -c, s },
278 1 => {233 };
279 r_sin.* = c;
280 r_cos.* = -s;
281 },
282 2 => {
283 r_sin.* = -s;
284 r_cos.* = -c;
285 },
286 else => {
287 r_sin.* = -c;
288 r_cos.* = s;
289 },
290 }
291}234}
292235
293pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void {236pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void {
294 switch (@typeInfo(c_longdouble).float.bits) {237 r_sin.*, r_cos.* = switch (@typeInfo(c_longdouble).float.bits) {
295 64 => return sincos(x, r_sin, r_cos),238 64 => sincos_f64(x),
296 80 => return sincosx(x, r_sin, r_cos),239 80 => sincos_f80(x),
297 128 => return sincosq(x, r_sin, r_cos),240 128 => sincos_f128(x),
298 else => @compileError("unreachable"),241 else => comptime unreachable,
299 }242 };
300}243}
301244
302fn testSincosSpecial(comptime T: type) !void {245fn testSincosSpecial(comptime T: type) !void {
303 const f = switch (T) {246 const f = switch (T) {
304 f32 => sincosf,247 f16 => sincos_f16,
305 f64 => sincos,248 f32 => sincos_f32,
306 f80 => sincosx,249 f64 => sincos_f64,
307 f128 => sincosq,250 f80 => sincos_f80,
251 f128 => sincos_f128,
308 else => @compileError("unimplemented"),252 else => @compileError("unimplemented"),
309 };253 };
310254
311 var s: T = undefined;255 var s: T = undefined;
312 var c: T = undefined;256 var c: T = undefined;
313257
314 f(0.0, &s, &c);258 s, c = f(0.0);
315 try expect(math.isPositiveZero(s));259 try expect(math.isPositiveZero(s));
316 try expect(c == 1.0);260 try expect(c == 1.0);
317261
318 f(-0.0, &s, &c);262 s, c = f(-0.0);
319 try expect(math.isNegativeZero(s));263 try expect(math.isNegativeZero(s));
320 try expect(c == 1.0);264 try expect(c == 1.0);
321265
322 f(math.inf(T), &s, &c);266 s, c = f(math.inf(T));
323 try expect(math.isNan(s));267 try expect(math.isNan(s));
324 try expect(math.isNan(c));268 try expect(math.isNan(c));
325269
326 f(-math.inf(T), &s, &c);270 s, c = f(-math.inf(T));
327 try expect(math.isNan(s));271 try expect(math.isNan(s));
328 try expect(math.isNan(c));272 try expect(math.isNan(c));
329273
330 f(math.nan(T), &s, &c);274 s, c = f(math.nan(T));
331 try expect(math.isNan(s));275 try expect(math.isNan(s));
332 try expect(math.isNan(c));276 try expect(math.isNan(c));
333}277}
...@@ -337,31 +281,31 @@ test "sincos32.normal" {...@@ -337,31 +281,31 @@ test "sincos32.normal" {
337 var s: f32 = undefined;281 var s: f32 = undefined;
338 var c: f32 = undefined;282 var c: f32 = undefined;
339283
340 sincosf(0.0, &s, &c);284 s, c = sincos_f32(0.0);
341 try expectApproxEqAbs(@as(f32, 0.0), s, epsilon);285 try expectApproxEqAbs(@as(f32, 0.0), s, epsilon);
342 try expectApproxEqAbs(@as(f32, 1.0), c, epsilon);286 try expectApproxEqAbs(@as(f32, 1.0), c, epsilon);
343287
344 sincosf(0.2, &s, &c);288 s, c = sincos_f32(0.2);
345 try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon);289 try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon);
346 try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon);290 try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon);
347291
348 sincosf(0.8923, &s, &c);292 s, c = sincos_f32(0.8923);
349 try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon);293 try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon);
350 try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon);294 try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon);
351295
352 sincosf(1.5, &s, &c);296 s, c = sincos_f32(1.5);
353 try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon);297 try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon);
354 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);298 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);
355299
356 sincosf(-1.5, &s, &c);300 s, c = sincos_f32(-1.5);
357 try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon);301 try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon);
358 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);302 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);
359303
360 sincosf(37.45, &s, &c);304 s, c = sincos_f32(37.45);
361 try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon);305 try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon);
362 try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon);306 try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon);
363307
364 sincosf(89.123, &s, &c);308 s, c = sincos_f32(89.123);
365 try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon);309 try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon);
366 try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon);310 try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon);
367}311}
...@@ -375,31 +319,31 @@ test "sincos64.normal" {...@@ -375,31 +319,31 @@ test "sincos64.normal" {
375 var s: f64 = undefined;319 var s: f64 = undefined;
376 var c: f64 = undefined;320 var c: f64 = undefined;
377321
378 sincos(0.0, &s, &c);322 s, c = sincos_f64(0.0);
379 try expectApproxEqAbs(@as(f64, 0.0), s, epsilon);323 try expectApproxEqAbs(@as(f64, 0.0), s, epsilon);
380 try expectApproxEqAbs(@as(f64, 1.0), c, epsilon);324 try expectApproxEqAbs(@as(f64, 1.0), c, epsilon);
381325
382 sincos(0.2, &s, &c);326 s, c = sincos_f64(0.2);
383 try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon);327 try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon);
384 try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon);328 try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon);
385329
386 sincos(0.8923, &s, &c);330 s, c = sincos_f64(0.8923);
387 try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon);331 try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon);
388 try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon);332 try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon);
389333
390 sincos(1.5, &s, &c);334 s, c = sincos_f64(1.5);
391 try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon);335 try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon);
392 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);336 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);
393337
394 sincos(-1.5, &s, &c);338 s, c = sincos_f64(-1.5);
395 try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon);339 try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon);
396 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);340 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);
397341
398 sincos(37.45, &s, &c);342 s, c = sincos_f64(37.45);
399 try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon);343 try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon);
400 try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon);344 try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon);
401345
402 sincos(89.123, &s, &c);346 s, c = sincos_f64(89.123);
403 try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon);347 try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon);
404 try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon);348 try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon);
405}349}
...@@ -413,31 +357,31 @@ test "sincos80.normal" {...@@ -413,31 +357,31 @@ test "sincos80.normal" {
413 var s: f80 = undefined;357 var s: f80 = undefined;
414 var c: f80 = undefined;358 var c: f80 = undefined;
415359
416 sincosx(0.0, &s, &c);360 s, c = sincos_f80(0.0);
417 try expectApproxEqAbs(@as(f80, 0.0), s, epsilon);361 try expectApproxEqAbs(@as(f80, 0.0), s, epsilon);
418 try expectApproxEqAbs(@as(f80, 1.0), c, epsilon);362 try expectApproxEqAbs(@as(f80, 1.0), c, epsilon);
419363
420 sincosx(0.2, &s, &c);364 s, c = sincos_f80(0.2);
421 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon);365 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon);
422 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon);366 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon);
423367
424 sincosx(0.8923, &s, &c);368 s, c = sincos_f80(0.8923);
425 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon);369 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon);
426 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon);370 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon);
427371
428 sincosx(1.5, &s, &c);372 s, c = sincos_f80(1.5);
429 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon);373 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon);
430 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);374 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);
431375
432 sincosx(-1.5, &s, &c);376 s, c = sincos_f80(-1.5);
433 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon);377 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon);
434 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);378 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);
435379
436 sincosx(37.45, &s, &c);380 s, c = sincos_f80(37.45);
437 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon);381 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon);
438 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon);382 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon);
439383
440 sincosx(89.123, &s, &c);384 s, c = sincos_f80(89.123);
441 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon);385 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon);
442 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon);386 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon);
443}387}
...@@ -451,31 +395,31 @@ test "sincos128.normal" {...@@ -451,31 +395,31 @@ test "sincos128.normal" {
451 var s: f128 = undefined;395 var s: f128 = undefined;
452 var c: f128 = undefined;396 var c: f128 = undefined;
453397
454 sincosq(0.0, &s, &c);398 s, c = sincos_f128(0.0);
455 try expectApproxEqAbs(@as(f128, 0.0), s, epsilon);399 try expectApproxEqAbs(@as(f128, 0.0), s, epsilon);
456 try expectApproxEqAbs(@as(f128, 1.0), c, epsilon);400 try expectApproxEqAbs(@as(f128, 1.0), c, epsilon);
457401
458 sincosq(0.2, &s, &c);402 s, c = sincos_f128(0.2);
459 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon);403 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon);
460 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon);404 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon);
461405
462 sincosq(0.8923, &s, &c);406 s, c = sincos_f128(0.8923);
463 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon);407 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon);
464 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon);408 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon);
465409
466 sincosq(1.5, &s, &c);410 s, c = sincos_f128(1.5);
467 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon);411 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon);
468 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);412 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);
469413
470 sincosq(-1.5, &s, &c);414 s, c = sincos_f128(-1.5);
471 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon);415 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon);
472 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);416 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);
473417
474 sincosq(37.45, &s, &c);418 s, c = sincos_f128(37.45);
475 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon);419 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon);
476 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon);420 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon);
477421
478 sincosq(89.123, &s, &c);422 s, c = sincos_f128(89.123);
479 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon);423 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon);
480 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon);424 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon);
481}425}
lib/compiler_rt/sqrt.zig+150-137
...@@ -17,18 +17,19 @@ comptime {...@@ -17,18 +17,19 @@ comptime {
17 symbol(&sqrtf, "sqrtf");17 symbol(&sqrtf, "sqrtf");
18 symbol(&sqrt, "sqrt");18 symbol(&sqrt, "sqrt");
19 symbol(&__sqrtx, "__sqrtx");19 symbol(&__sqrtx, "__sqrtx");
20 if (compiler_rt.want_ppc_abi) {20 symbol(&sqrtq, "sqrtf128");
21 symbol(&sqrtq, "sqrtf128");21 if (compiler_rt.want_sparc64_abi) {
22 } else if (compiler_rt.want_sparc64_abi) {
23 symbol(&_Qp_sqrt, "_Qp_sqrt");22 symbol(&_Qp_sqrt, "_Qp_sqrt");
24 } else if (compiler_rt.want_sparc32_abi) {23 } else if (compiler_rt.want_sparc32_abi) {
25 symbol(&sqrtq, "_Q_sqrt");24 symbol(&sqrtq, "_Q_sqrt");
26 }25 }
27 symbol(&sqrtq, "sqrtq");
28 symbol(&sqrtl, "sqrtl");26 symbol(&sqrtl, "sqrtl");
29}27}
3028
31pub fn __sqrth(x: f16) callconv(.c) f16 {29fn __sqrth(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
30 return compiler_rt.f16.toAbi(sqrt_f16(compiler_rt.f16.fromAbi(x)));
31}
32pub fn sqrt_f16(x: f16) f16 {
32 var ix: u16 = @bitCast(x);33 var ix: u16 = @bitCast(x);
33 var top = ix >> 10;34 var top = ix >> 10;
3435
...@@ -93,7 +94,10 @@ pub fn __sqrth(x: f16) callconv(.c) f16 {...@@ -93,7 +94,10 @@ pub fn __sqrth(x: f16) callconv(.c) f16 {
93 return y;94 return y;
94}95}
9596
96pub fn sqrtf(x: f32) callconv(.c) f32 {97fn sqrtf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
98 return compiler_rt.f32.toAbi(sqrt_f32(compiler_rt.f32.fromAbi(x)));
99}
100pub fn sqrt_f32(x: f32) f32 {
97 var ix: u32 = @bitCast(x);101 var ix: u32 = @bitCast(x);
98102
99 if (ix < @as(u32, @bitCast(@as(f32, 0x1p-126))) or @as(u32, @bitCast(std.math.inf(f32))) <= ix) {103 if (ix < @as(u32, @bitCast(@as(f32, 0x1p-126))) or @as(u32, @bitCast(std.math.inf(f32))) <= ix) {
...@@ -147,7 +151,10 @@ pub fn sqrtf(x: f32) callconv(.c) f32 {...@@ -147,7 +151,10 @@ pub fn sqrtf(x: f32) callconv(.c) f32 {
147 return y + t;151 return y + t;
148}152}
149153
150pub fn sqrt(x: f64) callconv(.c) f64 {154fn sqrt(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
155 return compiler_rt.f64.toAbi(sqrt_f64(compiler_rt.f64.fromAbi(x)));
156}
157pub fn sqrt_f64(x: f64) f64 {
151 var ix: u64 = @bitCast(x);158 var ix: u64 = @bitCast(x);
152 var top = ix >> 52;159 var top = ix >> 52;
153160
...@@ -284,7 +291,10 @@ pub fn sqrt(x: f64) callconv(.c) f64 {...@@ -284,7 +291,10 @@ pub fn sqrt(x: f64) callconv(.c) f64 {
284 return y;291 return y;
285}292}
286293
287pub fn __sqrtx(x: f80) callconv(.c) f80 {294fn __sqrtx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
295 return compiler_rt.f80.toAbi(sqrt_f80(compiler_rt.f80.fromAbi(x)));
296}
297pub fn sqrt_f80(x: f80) f80 {
288 var ix: u80 = @bitCast(x);298 var ix: u80 = @bitCast(x);
289 var top = ix >> 64;299 var top = ix >> 64;
290300
...@@ -381,7 +391,10 @@ pub fn __sqrtx(x: f80) callconv(.c) f80 {...@@ -381,7 +391,10 @@ pub fn __sqrtx(x: f80) callconv(.c) f80 {
381 return y;391 return y;
382}392}
383393
384pub fn sqrtq(x: f128) callconv(.c) f128 {394fn sqrtq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
395 return compiler_rt.f128.toAbi(sqrt_f128(compiler_rt.f128.fromAbi(x)));
396}
397pub fn sqrt_f128(x: f128) f128 {
385 var ix: u128 = @bitCast(x);398 var ix: u128 = @bitCast(x);
386 var top = ix >> 112;399 var top = ix >> 112;
387400
...@@ -483,10 +496,10 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void {...@@ -483,10 +496,10 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void {
483496
484pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble {497pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble {
485 switch (@typeInfo(c_longdouble).float.bits) {498 switch (@typeInfo(c_longdouble).float.bits) {
486 64 => return sqrt(x),499 64 => return sqrt_f64(x),
487 80 => return __sqrtx(x),500 80 => return sqrt_f80(x),
488 128 => return sqrtq(x),501 128 => return sqrt_f128(x),
489 else => @compileError("unreachable"),502 else => comptime unreachable,
490 }503 }
491}504}
492505
...@@ -545,187 +558,187 @@ inline fn mul80_tail(a: u80, b: u80) u80 {...@@ -545,187 +558,187 @@ inline fn mul80_tail(a: u80, b: u80) u80 {
545 return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40);558 return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40);
546}559}
547560
548test "__sqrth" {561test "sqrt_f16" {
549 // sqrt(±0) is ±0562 // sqrt(±0) is ±0
550 try std.testing.expectEqual(__sqrth(0x0.0p0), 0x0.0p0);563 try std.testing.expectEqual(sqrt_f16(0x0.0p0), 0x0.0p0);
551 try std.testing.expectEqual(__sqrth(-0x0.0p0), -0x0.0p0);564 try std.testing.expectEqual(sqrt_f16(-0x0.0p0), -0x0.0p0);
552 // sqrt(+max) is finite565 // sqrt(+max) is finite
553 try std.testing.expectEqual(__sqrth(0x1.FFCp15), 0x1.FFCp7);566 try std.testing.expectEqual(sqrt_f16(0x1.FFCp15), 0x1.FFCp7);
554 // sqrt(4)=2567 // sqrt(4)=2
555 try std.testing.expectEqual(__sqrth(0x1p2), 0x1p1);568 try std.testing.expectEqual(sqrt_f16(0x1p2), 0x1p1);
556 // sqrt(x) for x=1, 1±ulp569 // sqrt(x) for x=1, 1±ulp
557 try std.testing.expectEqual(__sqrth(0x1p0), 0x1p0);570 try std.testing.expectEqual(sqrt_f16(0x1p0), 0x1p0);
558 try std.testing.expectEqual(__sqrth(0x1.004p0), 0x1p0);571 try std.testing.expectEqual(sqrt_f16(0x1.004p0), 0x1p0);
559 try std.testing.expectEqual(__sqrth(0x1.FF8p-1), 0x1.FFCp-1);572 try std.testing.expectEqual(sqrt_f16(0x1.FF8p-1), 0x1.FFCp-1);
560 // sqrt(+min) is non-zero573 // sqrt(+min) is non-zero
561 try std.testing.expectEqual(__sqrth(0x1p-14), 0x1p-7);574 try std.testing.expectEqual(sqrt_f16(0x1p-14), 0x1p-7);
562 // sqrt(min subnormal) is non-zero575 // sqrt(min subnormal) is non-zero
563 try std.testing.expectEqual(__sqrth(0x0.004p-14), 0x1p-12);576 try std.testing.expectEqual(sqrt_f16(0x0.004p-14), 0x1p-12);
564 // sqrt(inf) is inf577 // sqrt(inf) is inf
565 try std.testing.expect(math.isInf(__sqrth(math.inf(f16))));578 try std.testing.expect(math.isInf(sqrt_f16(math.inf(f16))));
566 // sqrt(nan) is nan579 // sqrt(nan) is nan
567 try std.testing.expect(math.isNan(__sqrth(math.nan(f16))));580 try std.testing.expect(math.isNan(sqrt_f16(math.nan(f16))));
568 // sqrt(-ve) is nan581 // sqrt(-ve) is nan
569 try std.testing.expect(math.isNan(__sqrth(-0x1p-14)));582 try std.testing.expect(math.isNan(sqrt_f16(-0x1p-14)));
570 try std.testing.expect(math.isNan(__sqrth(-0x1p+0)));583 try std.testing.expect(math.isNan(sqrt_f16(-0x1p+0)));
571 try std.testing.expect(math.isNan(__sqrth(-math.inf(f16))));584 try std.testing.expect(math.isNan(sqrt_f16(-math.inf(f16))));
572 // random arguments585 // random arguments
573 try std.testing.expectEqual(__sqrth(0x1.1p14), 0x1.08p7);586 try std.testing.expectEqual(sqrt_f16(0x1.1p14), 0x1.08p7);
574 try std.testing.expectEqual(__sqrth(0x1.C9p-12), 0x1.56p-6);587 try std.testing.expectEqual(sqrt_f16(0x1.C9p-12), 0x1.56p-6);
575 try std.testing.expectEqual(__sqrth(0x1.CE8p-7), 0x1.E68p-4);588 try std.testing.expectEqual(sqrt_f16(0x1.CE8p-7), 0x1.E68p-4);
576 try std.testing.expectEqual(__sqrth(0x1.134p-7), 0x1.778p-4);589 try std.testing.expectEqual(sqrt_f16(0x1.134p-7), 0x1.778p-4);
577 try std.testing.expectEqual(__sqrth(0x1.E9Cp-10), 0x1.62p-5);590 try std.testing.expectEqual(sqrt_f16(0x1.E9Cp-10), 0x1.62p-5);
578 try std.testing.expectEqual(__sqrth(0x1.3Dp9), 0x1.92Cp4);591 try std.testing.expectEqual(sqrt_f16(0x1.3Dp9), 0x1.92Cp4);
579 try std.testing.expectEqual(__sqrth(0x1.AA4p8), 0x1.4A4p4);592 try std.testing.expectEqual(sqrt_f16(0x1.AA4p8), 0x1.4A4p4);
580 try std.testing.expectEqual(__sqrth(0x1.8A8p4), 0x1.3DCp2);593 try std.testing.expectEqual(sqrt_f16(0x1.8A8p4), 0x1.3DCp2);
581 try std.testing.expectEqual(__sqrth(0x1.8Fp-7), 0x1.C4p-4);594 try std.testing.expectEqual(sqrt_f16(0x1.8Fp-7), 0x1.C4p-4);
582 try std.testing.expectEqual(__sqrth(0x1.584p-11), 0x1.A3Cp-6);595 try std.testing.expectEqual(sqrt_f16(0x1.584p-11), 0x1.A3Cp-6);
583}596}
584597
585test "sqrtf" {598test "sqrt_f32" {
586 // sqrt(±0) is ±0599 // sqrt(±0) is ±0
587 try std.testing.expectEqual(sqrtf(0x0.0p0), 0x0.0p0);600 try std.testing.expectEqual(sqrt_f32(0x0.0p0), 0x0.0p0);
588 try std.testing.expectEqual(sqrtf(-0x0.0p0), -0x0.0p0);601 try std.testing.expectEqual(sqrt_f32(-0x0.0p0), -0x0.0p0);
589 // sqrt(+max) is finite602 // sqrt(+max) is finite
590 try std.testing.expectEqual(sqrtf(0x1.FFFFFEp127), 0x1.FFFFFEp63);603 try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp127), 0x1.FFFFFEp63);
591 // sqrt(4)=2604 // sqrt(4)=2
592 try std.testing.expectEqual(sqrtf(0x1p2), 0x1p1);605 try std.testing.expectEqual(sqrt_f32(0x1p2), 0x1p1);
593 // sqrt(x) for x=1, 1±ulp606 // sqrt(x) for x=1, 1±ulp
594 try std.testing.expectEqual(sqrtf(0x1p0), 0x1p0);607 try std.testing.expectEqual(sqrt_f32(0x1p0), 0x1p0);
595 try std.testing.expectEqual(sqrtf(0x1.000002p0), 0x1p0);608 try std.testing.expectEqual(sqrt_f32(0x1.000002p0), 0x1p0);
596 try std.testing.expectEqual(sqrtf(0x1.FFFFFEp-1), 0x1.FFFFFEp-1);609 try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp-1), 0x1.FFFFFEp-1);
597 // sqrt(+min) is non-zero610 // sqrt(+min) is non-zero
598 try std.testing.expectEqual(sqrtf(0x1p-126), 0x1p-63);611 try std.testing.expectEqual(sqrt_f32(0x1p-126), 0x1p-63);
599 // sqrt(min subnormal) is non-zero612 // sqrt(min subnormal) is non-zero
600 try std.testing.expectEqual(sqrtf(0x0.000002p-126), 0x1.6a09e6p-75);613 try std.testing.expectEqual(sqrt_f32(0x0.000002p-126), 0x1.6a09e6p-75);
601 // sqrt(inf) is inf614 // sqrt(inf) is inf
602 try std.testing.expect(math.isInf(sqrtf(math.inf(f32))));615 try std.testing.expect(math.isInf(sqrt_f32(math.inf(f32))));
603 // sqrt(nan) is nan616 // sqrt(nan) is nan
604 try std.testing.expect(math.isNan(sqrtf(math.nan(f32))));617 try std.testing.expect(math.isNan(sqrt_f32(math.nan(f32))));
605 // sqrt(-ve) is nan618 // sqrt(-ve) is nan
606 try std.testing.expect(math.isNan(sqrtf(-0x1p-149)));619 try std.testing.expect(math.isNan(sqrt_f32(-0x1p-149)));
607 try std.testing.expect(math.isNan(sqrtf(-0x1p0)));620 try std.testing.expect(math.isNan(sqrt_f32(-0x1p0)));
608 try std.testing.expect(math.isNan(sqrtf(-math.inf(f32))));621 try std.testing.expect(math.isNan(sqrt_f32(-math.inf(f32))));
609 // random arguments622 // random arguments
610 try std.testing.expectEqual(sqrtf(0x1.4DD57Ep77), 0x1.9D6DA8p38);623 try std.testing.expectEqual(sqrt_f32(0x1.4DD57Ep77), 0x1.9D6DA8p38);
611 try std.testing.expectEqual(sqrtf(0x1.871848p102), 0x1.3C6AFAp51);624 try std.testing.expectEqual(sqrt_f32(0x1.871848p102), 0x1.3C6AFAp51);
612 try std.testing.expectEqual(sqrtf(0x1.A1D748p-112), 0x1.470EFCp-56);625 try std.testing.expectEqual(sqrt_f32(0x1.A1D748p-112), 0x1.470EFCp-56);
613 try std.testing.expectEqual(sqrtf(0x1.E626C2p18), 0x1.60C80Ep9);626 try std.testing.expectEqual(sqrt_f32(0x1.E626C2p18), 0x1.60C80Ep9);
614 try std.testing.expectEqual(sqrtf(0x1.E80E66p-29), 0x1.F3E282p-15);627 try std.testing.expectEqual(sqrt_f32(0x1.E80E66p-29), 0x1.F3E282p-15);
615 try std.testing.expectEqual(sqrtf(0x1.B47204p89), 0x1.D8B732p44);628 try std.testing.expectEqual(sqrt_f32(0x1.B47204p89), 0x1.D8B732p44);
616 try std.testing.expectEqual(sqrtf(0x1.77F45p15), 0x1.B6BC3Ap7);629 try std.testing.expectEqual(sqrt_f32(0x1.77F45p15), 0x1.B6BC3Ap7);
617 try std.testing.expectEqual(sqrtf(0x1.AD5F5p-48), 0x1.4B8A72p-24);630 try std.testing.expectEqual(sqrt_f32(0x1.AD5F5p-48), 0x1.4B8A72p-24);
618 try std.testing.expectEqual(sqrtf(0x1.91A39p-76), 0x1.40A7A8p-38);631 try std.testing.expectEqual(sqrt_f32(0x1.91A39p-76), 0x1.40A7A8p-38);
619 try std.testing.expectEqual(sqrtf(0x1.DAE088p79), 0x1.ED16DCp39);632 try std.testing.expectEqual(sqrt_f32(0x1.DAE088p79), 0x1.ED16DCp39);
620}633}
621634
622test "sqrt" {635test "sqrt_f64" {
623 // sqrt(±0) is ±0636 // sqrt(±0) is ±0
624 try std.testing.expectEqual(sqrt(0x0.0p0), 0x0.0p0);637 try std.testing.expectEqual(sqrt_f64(0x0.0p0), 0x0.0p0);
625 try std.testing.expectEqual(sqrt(-0x0.0p0), -0x0.0p0);638 try std.testing.expectEqual(sqrt_f64(-0x0.0p0), -0x0.0p0);
626 // sqrt(+max) is finite639 // sqrt(+max) is finite
627 try std.testing.expectEqual(sqrt(math.floatMax(f64)), 0x1.FFFFFFFFFFFFFp511);640 try std.testing.expectEqual(sqrt_f64(math.floatMax(f64)), 0x1.FFFFFFFFFFFFFp511);
628 // sqrt(4)=2641 // sqrt(4)=2
629 try std.testing.expectEqual(sqrt(0x1p2), 0x1p1);642 try std.testing.expectEqual(sqrt_f64(0x1p2), 0x1p1);
630 // sqrt(x) for x=1, 1±ulp643 // sqrt(x) for x=1, 1±ulp
631 try std.testing.expectEqual(sqrt(0x1p0), 0x1p0);644 try std.testing.expectEqual(sqrt_f64(0x1p0), 0x1p0);
632 try std.testing.expectEqual(sqrt(0x1p0 + math.floatEps(f64)), 0x1p0);645 try std.testing.expectEqual(sqrt_f64(0x1p0 + math.floatEps(f64)), 0x1p0);
633 try std.testing.expectEqual(sqrt(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1);646 try std.testing.expectEqual(sqrt_f64(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1);
634 // sqrt(+min) is non-zero647 // sqrt(+min) is non-zero
635 try std.testing.expectEqual(sqrt(math.floatMin(f64)), 0x1p-511);648 try std.testing.expectEqual(sqrt_f64(math.floatMin(f64)), 0x1p-511);
636 // sqrt(min subnormal) is non-zero649 // sqrt(min subnormal) is non-zero
637 try std.testing.expectEqual(sqrt(math.floatTrueMin(f64)), 0x1p-537);650 try std.testing.expectEqual(sqrt_f64(math.floatTrueMin(f64)), 0x1p-537);
638 // sqrt(inf) is inf651 // sqrt(inf) is inf
639 try std.testing.expect(math.isInf(sqrt(math.inf(f64))));652 try std.testing.expect(math.isInf(sqrt_f64(math.inf(f64))));
640 // sqrt(nan) is nan653 // sqrt(nan) is nan
641 try std.testing.expect(math.isNan(sqrt(math.nan(f64))));654 try std.testing.expect(math.isNan(sqrt_f64(math.nan(f64))));
642 // sqrt(-ve) is nan655 // sqrt(-ve) is nan
643 try std.testing.expect(math.isNan(sqrt(-0x1p-1074)));656 try std.testing.expect(math.isNan(sqrt_f64(-0x1p-1074)));
644 try std.testing.expect(math.isNan(sqrt(-0x1p0)));657 try std.testing.expect(math.isNan(sqrt_f64(-0x1p0)));
645 try std.testing.expect(math.isNan(sqrt(-math.inf(f64))));658 try std.testing.expect(math.isNan(sqrt_f64(-math.inf(f64))));
646 // random arguments659 // random arguments
647 try std.testing.expectEqual(sqrt(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235);660 try std.testing.expectEqual(sqrt_f64(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235);
648 try std.testing.expectEqual(sqrt(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395);661 try std.testing.expectEqual(sqrt_f64(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395);
649 try std.testing.expectEqual(sqrt(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69);662 try std.testing.expectEqual(sqrt_f64(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69);
650 try std.testing.expectEqual(sqrt(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139);663 try std.testing.expectEqual(sqrt_f64(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139);
651 try std.testing.expectEqual(sqrt(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458);664 try std.testing.expectEqual(sqrt_f64(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458);
652 try std.testing.expectEqual(sqrt(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125);665 try std.testing.expectEqual(sqrt_f64(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125);
653 try std.testing.expectEqual(sqrt(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243);666 try std.testing.expectEqual(sqrt_f64(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243);
654 try std.testing.expectEqual(sqrt(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169);667 try std.testing.expectEqual(sqrt_f64(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169);
655 try std.testing.expectEqual(sqrt(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133);668 try std.testing.expectEqual(sqrt_f64(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133);
656 try std.testing.expectEqual(sqrt(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178);669 try std.testing.expectEqual(sqrt_f64(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178);
657}670}
658671
659test "__sqrtx" {672test "__sqrtx" {
660 // sqrt(±0) is ±0673 // sqrt(±0) is ±0
661 try std.testing.expectEqual(__sqrtx(0x0.0p0), 0x0.0p0);674 try std.testing.expectEqual(sqrt_f80(0x0.0p0), 0x0.0p0);
662 try std.testing.expectEqual(__sqrtx(-0x0.0p0), -0x0.0p0);675 try std.testing.expectEqual(sqrt_f80(-0x0.0p0), -0x0.0p0);
663 // sqrt(+max) is finite676 // sqrt(+max) is finite
664 try std.testing.expectEqual(__sqrtx(math.floatMax(f80)), 0x1.FFFFFFFFFFFFFFFEp8191);677 try std.testing.expectEqual(sqrt_f80(math.floatMax(f80)), 0x1.FFFFFFFFFFFFFFFEp8191);
665 // sqrt(4)=2678 // sqrt(4)=2
666 try std.testing.expectEqual(__sqrtx(0x1p2), 0x1p1);679 try std.testing.expectEqual(sqrt_f80(0x1p2), 0x1p1);
667 // sqrt(x) for x=1, 1±ulp680 // sqrt(x) for x=1, 1±ulp
668 try std.testing.expectEqual(__sqrtx(0x1p0), 0x1p0);681 try std.testing.expectEqual(sqrt_f80(0x1p0), 0x1p0);
669 try std.testing.expectEqual(__sqrtx(0x1p0 + math.floatEps(f80)), 0x1p0);682 try std.testing.expectEqual(sqrt_f80(0x1p0 + math.floatEps(f80)), 0x1p0);
670 try std.testing.expectEqual(__sqrtx(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1);683 try std.testing.expectEqual(sqrt_f80(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1);
671 // sqrt(+min) is non-zero684 // sqrt(+min) is non-zero
672 try std.testing.expectEqual(__sqrtx(math.floatMin(f80)), 0x1p-8191);685 try std.testing.expectEqual(sqrt_f80(math.floatMin(f80)), 0x1p-8191);
673 // sqrt(min subnormal) is non-zero686 // sqrt(min subnormal) is non-zero
674 try std.testing.expectEqual(__sqrtx(math.floatTrueMin(f80)), 0x1.6A09E667F3BCC908p-8223);687 try std.testing.expectEqual(sqrt_f80(math.floatTrueMin(f80)), 0x1.6A09E667F3BCC908p-8223);
675 // sqrt(inf) is inf688 // sqrt(inf) is inf
676 try std.testing.expect(math.isInf(__sqrtx(math.inf(f80))));689 try std.testing.expect(math.isInf(sqrt_f80(math.inf(f80))));
677 // sqrt(nan) is nan690 // sqrt(nan) is nan
678 try std.testing.expect(math.isNan(__sqrtx(math.nan(f80))));691 try std.testing.expect(math.isNan(sqrt_f80(math.nan(f80))));
679 // sqrt(-ve) is nan692 // sqrt(-ve) is nan
680 try std.testing.expect(math.isNan(__sqrtx(-0x1p-16442)));693 try std.testing.expect(math.isNan(sqrt_f80(-0x1p-16442)));
681 try std.testing.expect(math.isNan(__sqrtx(-0x1p0)));694 try std.testing.expect(math.isNan(sqrt_f80(-0x1p0)));
682 try std.testing.expect(math.isNan(__sqrtx(-math.inf(f80))));695 try std.testing.expect(math.isNan(sqrt_f80(-math.inf(f80))));
683 // random arguments696 // random arguments
684 try std.testing.expectEqual(__sqrtx(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741);697 try std.testing.expectEqual(sqrt_f80(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741);
685 try std.testing.expectEqual(__sqrtx(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165);698 try std.testing.expectEqual(sqrt_f80(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165);
686 try std.testing.expectEqual(__sqrtx(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856);699 try std.testing.expectEqual(sqrt_f80(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856);
687 try std.testing.expectEqual(__sqrtx(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432);700 try std.testing.expectEqual(sqrt_f80(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432);
688 try std.testing.expectEqual(__sqrtx(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591);701 try std.testing.expectEqual(sqrt_f80(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591);
689 try std.testing.expectEqual(__sqrtx(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315);702 try std.testing.expectEqual(sqrt_f80(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315);
690 try std.testing.expectEqual(__sqrtx(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517);703 try std.testing.expectEqual(sqrt_f80(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517);
691 try std.testing.expectEqual(__sqrtx(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706);704 try std.testing.expectEqual(sqrt_f80(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706);
692 try std.testing.expectEqual(__sqrtx(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760);705 try std.testing.expectEqual(sqrt_f80(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760);
693 try std.testing.expectEqual(__sqrtx(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685);706 try std.testing.expectEqual(sqrt_f80(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685);
694}707}
695708
696test "sqrtq" {709test "sqrt_f128" {
697 // sqrt(±0) is ±0710 // sqrt(±0) is ±0
698 try std.testing.expectEqual(sqrtq(0x0.0p0), 0x0.0p0);711 try std.testing.expectEqual(sqrt_f128(0x0.0p0), 0x0.0p0);
699 try std.testing.expectEqual(sqrtq(-0x0.0p0), -0x0.0p0);712 try std.testing.expectEqual(sqrt_f128(-0x0.0p0), -0x0.0p0);
700 // sqrt(+max) is finite713 // sqrt(+max) is finite
701 try std.testing.expectEqual(sqrtq(math.floatMax(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp8191);714 try std.testing.expectEqual(sqrt_f128(math.floatMax(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp8191);
702 // sqrt(4)=2715 // sqrt(4)=2
703 try std.testing.expectEqual(sqrtq(0x1p2), 0x1p1);716 try std.testing.expectEqual(sqrt_f128(0x1p2), 0x1p1);
704 // sqrt(x) for x=1, 1±ulp717 // sqrt(x) for x=1, 1±ulp
705 try std.testing.expectEqual(sqrtq(0x1p0), 0x1p0);718 try std.testing.expectEqual(sqrt_f128(0x1p0), 0x1p0);
706 try std.testing.expectEqual(sqrtq(0x1p0 + math.floatEps(f128)), 0x1p0);719 try std.testing.expectEqual(sqrt_f128(0x1p0 + math.floatEps(f128)), 0x1p0);
707 try std.testing.expectEqual(sqrtq(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1);720 try std.testing.expectEqual(sqrt_f128(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1);
708 // sqrt(+min) is non-zero721 // sqrt(+min) is non-zero
709 try std.testing.expectEqual(sqrtq(math.floatMin(f128)), 0x1p-8191);722 try std.testing.expectEqual(sqrt_f128(math.floatMin(f128)), 0x1p-8191);
710 // sqrt(min subnormal) is non-zero723 // sqrt(min subnormal) is non-zero
711 try std.testing.expectEqual(sqrtq(math.floatTrueMin(f128)), 0x1p-8247);724 try std.testing.expectEqual(sqrt_f128(math.floatTrueMin(f128)), 0x1p-8247);
712 // sqrt(inf) is inf725 // sqrt(inf) is inf
713 try std.testing.expect(math.isInf(sqrtq(math.inf(f128))));726 try std.testing.expect(math.isInf(sqrt_f128(math.inf(f128))));
714 // sqrt(nan) is nan727 // sqrt(nan) is nan
715 try std.testing.expect(math.isNan(sqrtq(math.nan(f128))));728 try std.testing.expect(math.isNan(sqrt_f128(math.nan(f128))));
716 // sqrt(-ve) is nan729 // sqrt(-ve) is nan
717 try std.testing.expect(math.isNan(sqrtq(-0x1p-16442)));730 try std.testing.expect(math.isNan(sqrt_f128(-0x1p-16442)));
718 try std.testing.expect(math.isNan(sqrtq(-0x1p0)));731 try std.testing.expect(math.isNan(sqrt_f128(-0x1p0)));
719 try std.testing.expect(math.isNan(sqrtq(-math.inf(f128))));732 try std.testing.expect(math.isNan(sqrt_f128(-math.inf(f128))));
720 // random arguments733 // random arguments
721 try std.testing.expectEqual(sqrtq(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681);734 try std.testing.expectEqual(sqrt_f128(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681);
722 try std.testing.expectEqual(sqrtq(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882);735 try std.testing.expectEqual(sqrt_f128(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882);
723 try std.testing.expectEqual(sqrtq(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812);736 try std.testing.expectEqual(sqrt_f128(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812);
724 try std.testing.expectEqual(sqrtq(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031);737 try std.testing.expectEqual(sqrt_f128(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031);
725 try std.testing.expectEqual(sqrtq(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513);738 try std.testing.expectEqual(sqrt_f128(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513);
726 try std.testing.expectEqual(sqrtq(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917);739 try std.testing.expectEqual(sqrt_f128(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917);
727 try std.testing.expectEqual(sqrtq(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256);740 try std.testing.expectEqual(sqrt_f128(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256);
728 try std.testing.expectEqual(sqrtq(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476);741 try std.testing.expectEqual(sqrt_f128(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476);
729 try std.testing.expectEqual(sqrtq(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446);742 try std.testing.expectEqual(sqrt_f128(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446);
730 try std.testing.expectEqual(sqrtq(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976);743 try std.testing.expectEqual(sqrt_f128(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976);
731}744}
lib/compiler_rt/subdf3.zig deleted-24
...@@ -1,24 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const addf3 = @import("./addf3.zig").addf3;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_dsub, "__aeabi_dsub");
8 } else {
9 symbol(&__subdf3, "__subdf3");
10 }
11}
12
13fn __subdf3(a: f64, b: f64) callconv(.c) f64 {
14 return sub(a, b);
15}
16
17fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
18 return sub(a, b);
19}
20
21inline fn sub(a: f64, b: f64) f64 {
22 const neg_b = @as(f64, @bitCast(@as(u64, @bitCast(b)) ^ (@as(u64, 1) << 63)));
23 return addf3(f64, a, neg_b);
24}
lib/compiler_rt/subhf3.zig deleted-12
...@@ -1,12 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 symbol(&__subhf3, "__subhf3");
7}
8
9fn __subhf3(a: f16, b: f16) callconv(.c) f16 {
10 const neg_b = @as(f16, @bitCast(@as(u16, @bitCast(b)) ^ (@as(u16, 1) << 15)));
11 return addf3(f16, a, neg_b);
12}
lib/compiler_rt/subsf3.zig deleted-24
...@@ -1,24 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_fsub, "__aeabi_fsub");
8 } else {
9 symbol(&__subsf3, "__subsf3");
10 }
11}
12
13fn __subsf3(a: f32, b: f32) callconv(.c) f32 {
14 return sub(a, b);
15}
16
17fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
18 return sub(a, b);
19}
20
21inline fn sub(a: f32, b: f32) f32 {
22 const neg_b = @as(f32, @bitCast(@as(u32, @bitCast(b)) ^ (@as(u32, 1) << 31)));
23 return addf3(f32, a, neg_b);
24}
lib/compiler_rt/subtf3.zig deleted-27
...@@ -1,27 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__subtf3, "__subkf3");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_sub, "_Qp_sub");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__subtf3, "_Q_sub");
12 }
13 symbol(&__subtf3, "__subtf3");
14}
15
16pub fn __subtf3(a: f128, b: f128) callconv(.c) f128 {
17 return sub(a, b);
18}
19
20fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {
21 c.* = sub(a.*, b.*);
22}
23
24inline fn sub(a: f128, b: f128) f128 {
25 const neg_b = @as(f128, @bitCast(@as(u128, @bitCast(b)) ^ (@as(u128, 1) << 127)));
26 return addf3(f128, a, neg_b);
27}
lib/compiler_rt/subvdi3.zig+3-2
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const testing = @import("std").testing;1const testing = @import("std").testing;
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
34
4comptime {5comptime {
5 symbol(&__subvdi3, "__subvdi3");6 symbol(&__subvdi3, "__subvdi3");
...@@ -9,7 +10,7 @@ pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 {...@@ -9,7 +10,7 @@ pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 {
9 const sum = a -% b;10 const sum = a -% b;
10 // Overflow occurred iff the operands have opposite signs, and the sign of the11 // Overflow occurred iff the operands have opposite signs, and the sign of the
11 // sum is the opposite of the lhs sign.12 // sum is the opposite of the lhs sign.
12 if (((a ^ b) & (sum ^ a)) < 0) @panic("compiler-rt: integer overflow");13 if (((a ^ b) & (sum ^ a)) < 0) @panic("integer overflow");
13 return sum;14 return sum;
14}15}
1516
lib/compiler_rt/subvsi3.zig+1-1
...@@ -10,7 +10,7 @@ pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 {...@@ -10,7 +10,7 @@ pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 {
10 const sum = a -% b;10 const sum = a -% b;
11 // Overflow occurred iff the operands have opposite signs, and the sign of the11 // Overflow occurred iff the operands have opposite signs, and the sign of the
12 // sum is the opposite of the lhs sign.12 // sum is the opposite of the lhs sign.
13 if (((a ^ b) & (sum ^ a)) < 0) @panic("compiler-rt: integer overflow");13 if (((a ^ b) & (sum ^ a)) < 0) @panic("integer overflow");
14 return sum;14 return sum;
15}15}
1616
lib/compiler_rt/subxf3.zig deleted-13
...@@ -1,13 +0,0 @@
1const std = @import("std");
2const symbol = @import("../compiler_rt.zig").symbol;
3
4comptime {
5 symbol(&__subxf3, "__subxf3");
6}
7
8fn __subxf3(a: f80, b: f80) callconv(.c) f80 {
9 var b_rep = std.math.F80.fromFloat(b);
10 b_rep.exp ^= 0x8000;
11 const neg_b = b_rep.toFloat();
12 return a + neg_b;
13}
lib/compiler_rt/tan.zig+53-37
...@@ -21,26 +21,29 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;...@@ -21,26 +21,29 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
2121
22const arch = builtin.cpu.arch;22const arch = builtin.cpu.arch;
23const compiler_rt = @import("../compiler_rt.zig");23const compiler_rt = @import("../compiler_rt.zig");
24const symbol = @import("../compiler_rt.zig").symbol;24const symbol = compiler_rt.symbol;
2525
26comptime {26comptime {
27 symbol(&tanh, "__tanh");27 symbol(&__tanh, "__tanh");
28 symbol(&tanf, "tanf");28 symbol(&tanf, "tanf");
29 symbol(&tan, "tan");29 symbol(&tan, "tan");
30 symbol(&tanx, "__tanx");30 symbol(&__tanx, "__tanx");
31 if (compiler_rt.want_ppc_abi) {31 symbol(&tanq, "tanf128");
32 symbol(&tanq, "tanf128");
33 }
34 symbol(&tanq, "tanq");
35 symbol(&tanl, "tanl");32 symbol(&tanl, "tanl");
36}33}
3734
38pub fn tanh(x: f16) callconv(.c) f16 {35fn __tanh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
36 return compiler_rt.f16.toAbi(tan_f16(compiler_rt.f16.fromAbi(x)));
37}
38pub fn tan_f16(x: f16) f16 {
39 // TODO: more efficient implementation39 // TODO: more efficient implementation
40 return @floatCast(tanf(x));40 return @floatCast(tan_f32(x));
41}41}
4242
43pub fn tanf(x: f32) callconv(.c) f32 {43fn tanf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
44 return compiler_rt.f32.toAbi(tan_f32(compiler_rt.f32.fromAbi(x)));
45}
46pub fn tan_f32(x: f32) f32 {
44 // Small multiples of pi/2 rounded to double precision.47 // Small multiples of pi/2 rounded to double precision.
45 const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D1848 const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
46 const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D1849 const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
...@@ -90,7 +93,10 @@ pub fn tanf(x: f32) callconv(.c) f32 {...@@ -90,7 +93,10 @@ pub fn tanf(x: f32) callconv(.c) f32 {
90 return kernel.tandf(y, n & 1 != 0);93 return kernel.tandf(y, n & 1 != 0);
91}94}
9295
93pub fn tan(x: f64) callconv(.c) f64 {96fn tan(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
97 return compiler_rt.f64.toAbi(tan_f64(compiler_rt.f64.fromAbi(x)));
98}
99pub fn tan_f64(x: f64) f64 {
94 var ix = @as(u64, @bitCast(x)) >> 32;100 var ix = @as(u64, @bitCast(x)) >> 32;
95 ix &= 0x7fffffff;101 ix &= 0x7fffffff;
96102
...@@ -120,7 +126,10 @@ pub fn tan(x: f64) callconv(.c) f64 {...@@ -120,7 +126,10 @@ pub fn tan(x: f64) callconv(.c) f64 {
120 return kernel.tan(y[0], y[1], n & 1 != 0);126 return kernel.tan(y[0], y[1], n & 1 != 0);
121}127}
122128
123pub fn tanx(x: f80) callconv(.c) f80 {129fn __tanx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
130 return compiler_rt.f80.toAbi(tan_f80(compiler_rt.f80.fromAbi(x)));
131}
132pub fn tan_f80(x: f80) f80 {
124 const se = ld.signExponent(x) & 0x7fff;133 const se = ld.signExponent(x) & 0x7fff;
125 if (se == 0x7fff) {134 if (se == 0x7fff) {
126 return x - x;135 return x - x;
...@@ -141,7 +150,10 @@ pub fn tanx(x: f80) callconv(.c) f80 {...@@ -141,7 +150,10 @@ pub fn tanx(x: f80) callconv(.c) f80 {
141 return kernel.tanx(y[0], y[1], n & 1);150 return kernel.tanx(y[0], y[1], n & 1);
142}151}
143152
144pub fn tanq(x: f128) callconv(.c) f128 {153fn tanq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
154 return compiler_rt.f128.toAbi(tan_f128(compiler_rt.f128.fromAbi(x)));
155}
156pub fn tan_f128(x: f128) f128 {
145 const se = ld.signExponent(x) & 0x7fff;157 const se = ld.signExponent(x) & 0x7fff;
146 if (se == 0x7fff) {158 if (se == 0x7fff) {
147 return x - x;159 return x - x;
...@@ -164,18 +176,21 @@ pub fn tanq(x: f128) callconv(.c) f128 {...@@ -164,18 +176,21 @@ pub fn tanq(x: f128) callconv(.c) f128 {
164176
165pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble {177pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble {
166 switch (@typeInfo(c_longdouble).float.bits) {178 switch (@typeInfo(c_longdouble).float.bits) {
167 64 => return tan(x),179 64 => return tan_f64(x),
168 80 => return tanx(x),180 80 => return tan_f80(x),
169 128 => return tanq(x),181 128 => return tan_f128(x),
170 else => @compileError("unreachable"),182 else => comptime unreachable,
171 }183 }
172}184}
173185
174fn testTanNormal(comptime T: type) !void {186fn testTanNormal(comptime T: type) !void {
175 const f = switch (T) {187 const f = switch (T) {
176 f32 => tanf,188 f16 => tan_f16,
177 f64 => tan,189 f32 => tan_f32,
178 else => @compileError("unimplemented"),190 f64 => tan_f64,
191 f80 => tan_f80,
192 f128 => tan_f128,
193 else => comptime unreachable,
179 };194 };
180 const epsilon = 0.00001;195 const epsilon = 0.00001;
181196
...@@ -189,11 +204,12 @@ fn testTanNormal(comptime T: type) !void {...@@ -189,11 +204,12 @@ fn testTanNormal(comptime T: type) !void {
189204
190fn testTanSpecial(comptime T: type) !void {205fn testTanSpecial(comptime T: type) !void {
191 const f = switch (T) {206 const f = switch (T) {
192 f32 => tanf,207 f16 => tan_f16,
193 f64 => tan,208 f32 => tan_f32,
194 f80 => tanx,209 f64 => tan_f64,
195 f128 => tanq,210 f80 => tan_f80,
196 else => @compileError("unimplemented"),211 f128 => tan_f128,
212 else => comptime unreachable,
197 };213 };
198214
199 try expect(math.isPositiveZero(f(0.0)));215 try expect(math.isPositiveZero(f(0.0)));
...@@ -214,23 +230,23 @@ test "tan64.normal" {...@@ -214,23 +230,23 @@ test "tan64.normal" {
214test "tan80.normal" {230test "tan80.normal" {
215 const epsilon = math.floatEps(f80);231 const epsilon = math.floatEps(f80);
216232
217 try expectApproxEqAbs(@as(f80, 0.0), tanx(0.0), epsilon);233 try expectApproxEqAbs(@as(f80, 0.0), tan_f80(0.0), epsilon);
218 try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tanx(0.2), epsilon);234 try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tan_f80(0.2), epsilon);
219 try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tanx(0.8923), epsilon);235 try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tan_f80(0.8923), epsilon);
220 try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tanx(1.5), epsilon);236 try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tan_f80(1.5), epsilon);
221 try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tanx(37.45), epsilon);237 try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tan_f80(37.45), epsilon);
222 try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tanx(89.123), epsilon);238 try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tan_f80(89.123), epsilon);
223}239}
224240
225test "tan128.normal" {241test "tan128.normal" {
226 const epsilon = math.floatEps(f128);242 const epsilon = math.floatEps(f128);
227243
228 try expectApproxEqAbs(@as(f128, 0.0), tanq(0.0), epsilon);244 try expectApproxEqAbs(@as(f128, 0.0), tan_f128(0.0), epsilon);
229 try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tanq(0.2), epsilon);245 try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tan_f128(0.2), epsilon);
230 try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tanq(0.8923), epsilon);246 try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tan_f128(0.8923), epsilon);
231 try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tanq(1.5), epsilon);247 try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tan_f128(1.5), epsilon);
232 try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tanq(37.45), epsilon);248 try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tan_f128(37.45), epsilon);
233 try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tanq(89.123), epsilon);249 try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tan_f128(89.123), epsilon);
234}250}
235251
236test "tan32.special" {252test "tan32.special" {
lib/compiler_rt/trunc.zig+77-47
...@@ -17,19 +17,22 @@ comptime {...@@ -17,19 +17,22 @@ comptime {
17 symbol(&truncf, "truncf");17 symbol(&truncf, "truncf");
18 symbol(&trunc, "trunc");18 symbol(&trunc, "trunc");
19 symbol(&__truncx, "__truncx");19 symbol(&__truncx, "__truncx");
20 if (compiler_rt.want_ppc_abi) {20 symbol(&truncq, "truncf128");
21 symbol(&truncq, "truncf128");
22 }
23 symbol(&truncq, "truncq");
24 symbol(&truncl, "truncl");21 symbol(&truncl, "truncl");
25}22}
2623
27pub fn __trunch(x: f16) callconv(.c) f16 {24fn __trunch(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
25 return compiler_rt.f16.toAbi(trunc_f16(compiler_rt.f16.fromAbi(x)));
26}
27pub fn trunc_f16(x: f16) f16 {
28 // TODO: more efficient implementation28 // TODO: more efficient implementation
29 return @floatCast(truncf(x));29 return @floatCast(trunc_f32(x));
30}30}
3131
32pub fn truncf(x: f32) callconv(.c) f32 {32fn truncf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
33 return compiler_rt.f32.toAbi(trunc_f32(compiler_rt.f32.fromAbi(x)));
34}
35pub fn trunc_f32(x: f32) f32 {
33 const u: u32 = @bitCast(x);36 const u: u32 = @bitCast(x);
34 var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9;37 var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9;
35 var m: u32 = undefined;38 var m: u32 = undefined;
...@@ -50,7 +53,10 @@ pub fn truncf(x: f32) callconv(.c) f32 {...@@ -50,7 +53,10 @@ pub fn truncf(x: f32) callconv(.c) f32 {
50 }53 }
51}54}
5255
53pub fn trunc(x: f64) callconv(.c) f64 {56fn trunc(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
57 return compiler_rt.f64.toAbi(trunc_f64(compiler_rt.f64.fromAbi(x)));
58}
59pub fn trunc_f64(x: f64) f64 {
54 const u: u64 = @bitCast(x);60 const u: u64 = @bitCast(x);
55 var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12;61 var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12;
56 var m: u64 = undefined;62 var m: u64 = undefined;
...@@ -71,12 +77,18 @@ pub fn trunc(x: f64) callconv(.c) f64 {...@@ -71,12 +77,18 @@ pub fn trunc(x: f64) callconv(.c) f64 {
71 }77 }
72}78}
7379
74pub fn __truncx(x: f80) callconv(.c) f80 {80fn __truncx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
81 return compiler_rt.f80.toAbi(trunc_f80(compiler_rt.f80.fromAbi(x)));
82}
83pub fn trunc_f80(x: f80) f80 {
75 // TODO: more efficient implementation84 // TODO: more efficient implementation
76 return @floatCast(truncq(x));85 return @floatCast(trunc_f128(x));
77}86}
7887
79pub fn truncq(x: f128) callconv(.c) f128 {88fn truncq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
89 return compiler_rt.f128.toAbi(trunc_f128(compiler_rt.f128.fromAbi(x)));
90}
91pub fn trunc_f128(x: f128) f128 {
80 const u: u128 = @bitCast(x);92 const u: u128 = @bitCast(x);
81 var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16;93 var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16;
82 var m: u128 = undefined;94 var m: u128 = undefined;
...@@ -99,51 +111,69 @@ pub fn truncq(x: f128) callconv(.c) f128 {...@@ -99,51 +111,69 @@ pub fn truncq(x: f128) callconv(.c) f128 {
99111
100pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble {112pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble {
101 switch (@typeInfo(c_longdouble).float.bits) {113 switch (@typeInfo(c_longdouble).float.bits) {
102 64 => return trunc(x),114 64 => return trunc_f64(x),
103 80 => return __truncx(x),115 80 => return trunc_f80(x),
104 128 => return truncq(x),116 128 => return trunc_f128(x),
105 else => @compileError("unreachable"),117 else => comptime unreachable,
106 }118 }
107}119}
108120
109test "trunc32" {121test trunc_f16 {
110 try expect(truncf(1.3) == 1.0);122 try expect(trunc_f16(1.3) == 1.0);
111 try expect(truncf(-1.3) == -1.0);123 try expect(trunc_f16(-1.3) == -1.0);
112 try expect(truncf(0.2) == 0.0);124 try expect(math.isPositiveZero(trunc_f16(0.2)));
113}125 try expect(math.isNegativeZero(trunc_f16(-0.2)));
114126 try expect(math.isPositiveZero(trunc_f16(0.0)));
115test "trunc64" {127 try expect(math.isNegativeZero(trunc_f16(-0.0)));
116 try expect(trunc(1.3) == 1.0);128 try expect(math.isPositiveInf(trunc_f16(math.inf(f32))));
117 try expect(trunc(-1.3) == -1.0);129 try expect(math.isNegativeInf(trunc_f16(-math.inf(f32))));
118 try expect(trunc(0.2) == 0.0);130 try expect(math.isNan(trunc_f16(math.nan(f32))));
119}131}
120132
121test "trunc128" {133test trunc_f32 {
122 try expect(truncq(1.3) == 1.0);134 try expect(trunc_f32(1.3) == 1.0);
123 try expect(truncq(-1.3) == -1.0);135 try expect(trunc_f32(-1.3) == -1.0);
124 try expect(truncq(0.2) == 0.0);136 try expect(math.isPositiveZero(trunc_f32(0.2)));
137 try expect(math.isNegativeZero(trunc_f32(-0.2)));
138 try expect(math.isPositiveZero(trunc_f32(0.0)));
139 try expect(math.isNegativeZero(trunc_f32(-0.0)));
140 try expect(math.isPositiveInf(trunc_f32(math.inf(f32))));
141 try expect(math.isNegativeInf(trunc_f32(-math.inf(f32))));
142 try expect(math.isNan(trunc_f32(math.nan(f32))));
125}143}
126144
127test "trunc32.special" {145test trunc_f64 {
128 try expect(truncf(0.0) == 0.0); // 0x3F800000146 try expect(trunc_f64(1.3) == 1.0);
129 try expect(truncf(-0.0) == -0.0);147 try expect(trunc_f64(-1.3) == -1.0);
130 try expect(math.isPositiveInf(truncf(math.inf(f32))));148 try expect(math.isPositiveZero(trunc_f64(0.2)));
131 try expect(math.isNegativeInf(truncf(-math.inf(f32))));149 try expect(math.isNegativeZero(trunc_f64(-0.2)));
132 try expect(math.isNan(truncf(math.nan(f32))));150 try expect(math.isPositiveZero(trunc_f64(0.0)));
151 try expect(math.isNegativeZero(trunc_f64(-0.0)));
152 try expect(math.isPositiveInf(trunc_f64(math.inf(f64))));
153 try expect(math.isNegativeInf(trunc_f64(-math.inf(f64))));
154 try expect(math.isNan(trunc_f64(math.nan(f64))));
133}155}
134156
135test "trunc64.special" {157test trunc_f80 {
136 try expect(trunc(0.0) == 0.0);158 try expect(trunc_f80(1.3) == 1.0);
137 try expect(trunc(-0.0) == -0.0);159 try expect(trunc_f80(-1.3) == -1.0);
138 try expect(math.isPositiveInf(trunc(math.inf(f64))));160 try expect(math.isPositiveZero(trunc_f80(0.2)));
139 try expect(math.isNegativeInf(trunc(-math.inf(f64))));161 try expect(math.isNegativeZero(trunc_f80(-0.2)));
140 try expect(math.isNan(trunc(math.nan(f64))));162 try expect(math.isPositiveZero(trunc_f80(0.0)));
163 try expect(math.isNegativeZero(trunc_f80(-0.0)));
164 try expect(math.isPositiveInf(trunc_f80(math.inf(f64))));
165 try expect(math.isNegativeInf(trunc_f80(-math.inf(f64))));
166 try expect(math.isNan(trunc_f80(math.nan(f64))));
141}167}
142168
143test "trunc128.special" {169test trunc_f128 {
144 try expect(truncq(0.0) == 0.0);170 try expect(trunc_f128(1.3) == 1.0);
145 try expect(truncq(-0.0) == -0.0);171 try expect(trunc_f128(-1.3) == -1.0);
146 try expect(math.isPositiveInf(truncq(math.inf(f128))));172 try expect(math.isPositiveZero(trunc_f128(0.2)));
147 try expect(math.isNegativeInf(truncq(-math.inf(f128))));173 try expect(math.isNegativeZero(trunc_f128(-0.2)));
148 try expect(math.isNan(truncq(math.nan(f128))));174 try expect(math.isPositiveZero(trunc_f128(0.0)));
175 try expect(math.isNegativeZero(trunc_f128(-0.0)));
176 try expect(math.isPositiveInf(trunc_f128(math.inf(f128))));
177 try expect(math.isNegativeInf(trunc_f128(-math.inf(f128))));
178 try expect(math.isNan(trunc_f128(math.nan(f128))));
149}179}
lib/compiler_rt/truncdfhf2.zig deleted-18
...@@ -1,18 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const truncf = @import("./truncf.zig").truncf;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_d2h, "__aeabi_d2h");
8 }
9 symbol(&__truncdfhf2, "__truncdfhf2");
10}
11
12pub fn __truncdfhf2(a: f64) callconv(.c) compiler_rt.F16T(f64) {
13 return @bitCast(truncf(f16, f64, a));
14}
15
16fn __aeabi_d2h(a: f64) callconv(.{ .arm_aapcs = .{} }) u16 {
17 return @bitCast(truncf(f16, f64, a));
18}
lib/compiler_rt/truncdfsf2.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const truncf = @import("./truncf.zig").truncf;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_d2f, "__aeabi_d2f");
8 } else {
9 symbol(&__truncdfsf2, "__truncdfsf2");
10 }
11}
12
13pub fn __truncdfsf2(a: f64) callconv(.c) f32 {
14 return truncf(f32, f64, a);
15}
16
17fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 {
18 return truncf(f32, f64, a);
19}
lib/compiler_rt/truncf.zig+200-2
...@@ -1,6 +1,204 @@...@@ -1,6 +1,204 @@
1const std = @import("std");1const std = @import("std");
22
3pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5
6comptime {
7 if (compiler_rt.want_aeabi) {
8 if (compiler_rt.gnu_f16_abi) {
9 symbol(&__aeabi_f2h, "__gnu_f2h_ieee");
10 } else {
11 symbol(&__aeabi_f2h, "__aeabi_f2h");
12 }
13 symbol(&__aeabi_d2h, "__aeabi_d2h");
14 } else if (compiler_rt.gnu_f16_abi) {
15 symbol(&__truncsfhf2, "__gnu_f2h_ieee");
16 }
17 symbol(&__truncsfhf2, "__truncsfhf2");
18 symbol(&__truncdfhf2, "__truncdfhf2");
19 symbol(&__truncxfhf2, "__truncxfhf2");
20 if (compiler_rt.want_ppc_abi) {
21 symbol(&__trunctfhf2, "__trunckfhf2");
22 } else {
23 symbol(&__trunctfhf2, "__trunctfhf2");
24 }
25
26 if (compiler_rt.want_aeabi) {
27 symbol(&__aeabi_d2f, "__aeabi_d2f");
28 } else {
29 symbol(&__truncdfsf2, "__truncdfsf2");
30 }
31 symbol(&__truncxfsf2, "__truncxfsf2");
32 if (compiler_rt.want_ppc_abi) {
33 symbol(&__trunctfsf2, "__trunckfsf2");
34 } else if (compiler_rt.want_sparc64_abi) {
35 symbol(&_Qp_qtos, "_Qp_qtos");
36 } else if (compiler_rt.want_sparc32_abi) {
37 symbol(&__trunctfsf2, "_Q_qtos");
38 } else {
39 symbol(&__trunctfsf2, "__trunctfsf2");
40 }
41
42 symbol(&__truncxfdf2, "__truncxfdf2");
43
44 if (compiler_rt.want_ppc_abi) {
45 symbol(&__trunctfdf2, "__trunckfdf2");
46 } else if (compiler_rt.want_sparc64_abi) {
47 symbol(&_Qp_qtod, "_Qp_qtod");
48 } else if (compiler_rt.want_sparc32_abi) {
49 symbol(&__trunctfdf2, "_Q_qtod");
50 } else {
51 symbol(&__trunctfdf2, "__trunctfdf2");
52 }
53
54 if (compiler_rt.want_ppc_abi) {
55 symbol(&__trunctfxf2, "__trunckfxf2");
56 } else {
57 symbol(&__trunctfxf2, "__trunctfxf2");
58 }
59}
60
61fn __truncsfhf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f16Conv(f32).Abi {
62 return compiler_rt.f16Conv(f32).toAbi(f16_floatCast_f32(compiler_rt.f32.fromAbi(a)));
63}
64fn __aeabi_f2h(a: u32) callconv(.{ .arm_aapcs = .{} }) u16 {
65 return @bitCast(f16_floatCast_f32(@bitCast(a)));
66}
67pub fn f16_floatCast_f32(a: f32) f16 {
68 return truncf(f16, f32, a);
69}
70
71fn __truncdfhf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f16Conv(f64).Abi {
72 return compiler_rt.f16Conv(f64).toAbi(f16_floatCast_f64(compiler_rt.f64.fromAbi(a)));
73}
74fn __aeabi_d2h(a: u64) callconv(.{ .arm_aapcs = .{} }) u16 {
75 return @bitCast(f16_floatCast_f64(@bitCast(a)));
76}
77pub fn f16_floatCast_f64(a: f64) f16 {
78 return truncf(f16, f64, a);
79}
80
81fn __truncxfhf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f16Conv(f80).Abi {
82 return compiler_rt.f16Conv(f80).toAbi(f16_floatCast_f80(compiler_rt.f80.fromAbi(a)));
83}
84pub fn f16_floatCast_f80(a: f80) f16 {
85 return trunc_f80(f16, a);
86}
87
88fn __trunctfhf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f16Conv(f128).Abi {
89 return compiler_rt.f16Conv(f128).toAbi(f16_floatCast_f128(compiler_rt.f128.fromAbi(a)));
90}
91pub fn f16_floatCast_f128(a: f128) f16 {
92 return truncf(f16, f128, a);
93}
94
95fn __truncdfsf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f32.Abi {
96 return compiler_rt.f32.toAbi(f32_floatCast_f64(compiler_rt.f64.fromAbi(a)));
97}
98fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 {
99 return f32_floatCast_f64(a);
100}
101pub fn f32_floatCast_f64(a: f64) f32 {
102 return truncf(f32, f64, a);
103}
104
105fn __truncxfsf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f32.Abi {
106 return compiler_rt.f32.toAbi(f32_floatCast_f80(compiler_rt.f80.fromAbi(a)));
107}
108pub fn f32_floatCast_f80(a: f80) f32 {
109 return trunc_f80(f32, a);
110}
111
112fn __trunctfsf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f32.Abi {
113 return compiler_rt.f32.toAbi(f32_floatCast_f128(compiler_rt.f128.fromAbi(a)));
114}
115fn _Qp_qtos(a: *const f128) callconv(.c) f32 {
116 return f32_floatCast_f128(a.*);
117}
118pub fn f32_floatCast_f128(a: f128) f32 {
119 return truncf(f32, f128, a);
120}
121
122fn __truncxfdf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f64.Abi {
123 return compiler_rt.f64.toAbi(f64_floatCast_f80(compiler_rt.f80.fromAbi(a)));
124}
125pub fn f64_floatCast_f80(a: f80) f64 {
126 return trunc_f80(f64, a);
127}
128
129fn __trunctfdf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f64.Abi {
130 return compiler_rt.f64.toAbi(f64_floatCast_f128(compiler_rt.f128.fromAbi(a)));
131}
132fn _Qp_qtod(a: *const f128) callconv(.c) f64 {
133 return f64_floatCast_f128(a.*);
134}
135pub fn f64_floatCast_f128(a: f128) f64 {
136 return truncf(f64, f128, a);
137}
138
139fn __trunctfxf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f80.Abi {
140 return compiler_rt.f80.toAbi(f80_floatCast_f128(compiler_rt.f128.fromAbi(a)));
141}
142pub fn f80_floatCast_f128(a: f128) f80 {
143 const src_sig_bits = std.math.floatMantissaBits(f128);
144 const dst_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit
145
146 // Various constants whose values follow from the type parameters.
147 // Any reasonable optimizer will fold and propagate all of these.
148 const src_bits = @typeInfo(f128).float.bits;
149 const src_exp_bits = src_bits - src_sig_bits - 1;
150 const src_inf_exp = 0x7FFF;
151
152 const src_inf = src_inf_exp << src_sig_bits;
153 const src_sign_mask = 1 << (src_sig_bits + src_exp_bits);
154 const src_abs_mask = src_sign_mask - 1;
155 const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1;
156 const halfway = 1 << (src_sig_bits - dst_sig_bits - 1);
157
158 // Break a into a sign and representation of the absolute value
159 const a_rep: u128 = @bitCast(a);
160 const a_abs = a_rep & src_abs_mask;
161 const sign: u16 = if (a_rep & src_sign_mask != 0) 0x8000 else 0;
162 const integer_bit = 1 << 63;
163
164 var res: std.math.F80 = undefined;
165
166 if (a_abs > src_inf) {
167 // a is NaN.
168 // Conjure the result by beginning with infinity, setting the qNaN
169 // bit and inserting the (truncated) trailing NaN field.
170 res.exp = 0x7fff;
171 res.fraction = 0x8000000000000000;
172 res.fraction |= @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits)));
173 } else {
174 // The exponent of a is within the range of normal numbers in the
175 // destination format. We can convert by simply right-shifting with
176 // rounding, adding the explicit integer bit, and adjusting the exponent
177 res.fraction = @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))) | integer_bit;
178 res.exp = @truncate(a_abs >> src_sig_bits);
179
180 const round_bits = a_abs & round_mask;
181 if (round_bits > halfway) {
182 // Round to nearest
183 const ov = @addWithOverflow(res.fraction, 1);
184 res.fraction = ov[0];
185 res.exp += ov[1];
186 res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry
187 } else if (round_bits == halfway) {
188 // Ties to even
189 const ov = @addWithOverflow(res.fraction, res.fraction & 1);
190 res.fraction = ov[0];
191 res.exp += ov[1];
192 res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry
193 }
194 if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals
195 }
196
197 res.exp |= sign;
198 return res.toFloat();
199}
200
201inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {
4 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);202 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);
5 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);203 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);
6 const srcSigBits = std.math.floatMantissaBits(src_t);204 const srcSigBits = std.math.floatMantissaBits(src_t);
...@@ -99,7 +297,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t...@@ -99,7 +297,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
99 return @bitCast(result);297 return @bitCast(result);
100}298}
101299
102pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t {300inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t {
103 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);301 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);
104 const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit302 const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit
105 const dst_sig_bits = std.math.floatMantissaBits(dst_t);303 const dst_sig_bits = std.math.floatMantissaBits(dst_t);
lib/compiler_rt/truncf_test.zig+160-174
...@@ -1,79 +1,82 @@...@@ -1,79 +1,82 @@
1const std = @import("std");1const std = @import("std");
2const testing = std.testing;2const testing = std.testing;
33
4const __truncsfhf2 = @import("truncsfhf2.zig").__truncsfhf2;4const impl = @import("truncf.zig");
5const __truncdfhf2 = @import("truncdfhf2.zig").__truncdfhf2;
6const __truncdfsf2 = @import("truncdfsf2.zig").__truncdfsf2;
7const __trunctfhf2 = @import("trunctfhf2.zig").__trunctfhf2;
8const __trunctfsf2 = @import("trunctfsf2.zig").__trunctfsf2;
9const __trunctfdf2 = @import("trunctfdf2.zig").__trunctfdf2;
10const __trunctfxf2 = @import("trunctfxf2.zig").__trunctfxf2;
11
12fn test__truncsfhf2(a: u32, expected: u16) !void {
13 const actual: u16 = @bitCast(__truncsfhf2(@bitCast(a)));
14
15 if (actual == expected) {
16 return;
17 }
185
19 return error.TestFailure;6const f16_floatCast_f32 = impl.f16_floatCast_f32;
7const f16_floatCast_f64 = impl.f16_floatCast_f64;
8const f16_floatCast_f80 = impl.f16_floatCast_f80;
9const f16_floatCast_f128 = impl.f16_floatCast_f128;
10
11const f32_floatCast_f64 = impl.f32_floatCast_f64;
12const f32_floatCast_f80 = impl.f32_floatCast_f80;
13const f32_floatCast_f128 = impl.f32_floatCast_f128;
14
15const f64_floatCast_f80 = impl.f64_floatCast_f80;
16const f64_floatCast_f128 = impl.f64_floatCast_f128;
17
18const f80_floatCast_f128 = impl.f80_floatCast_f128;
19
20fn test_f16_floatCast_f32(a: u32, expected: u16) !void {
21 const actual: u16 = @bitCast(f16_floatCast_f32(@bitCast(a)));
22 try testing.expect(actual == expected);
20}23}
2124
22test "truncsfhf2" {25test f16_floatCast_f32 {
23 try test__truncsfhf2(0x7fc00000, 0x7e00); // qNaN26 try test_f16_floatCast_f32(0x7fc00000, 0x7e00); // qNaN
24 try test__truncsfhf2(0x7fe00000, 0x7f00); // sNaN27 try test_f16_floatCast_f32(0x7fe00000, 0x7f00); // sNaN
2528
26 try test__truncsfhf2(0, 0); // 029 try test_f16_floatCast_f32(0, 0); // 0
27 try test__truncsfhf2(0x80000000, 0x8000); // -030 try test_f16_floatCast_f32(0x80000000, 0x8000); // -0
2831
29 try test__truncsfhf2(0x7f800000, 0x7c00); // inf32 try test_f16_floatCast_f32(0x7f800000, 0x7c00); // inf
30 try test__truncsfhf2(0xff800000, 0xfc00); // -inf33 try test_f16_floatCast_f32(0xff800000, 0xfc00); // -inf
3134
32 try test__truncsfhf2(0x477ff000, 0x7c00); // 65520 -> inf35 try test_f16_floatCast_f32(0x477ff000, 0x7c00); // 65520 -> inf
33 try test__truncsfhf2(0xc77ff000, 0xfc00); // -65520 -> -inf36 try test_f16_floatCast_f32(0xc77ff000, 0xfc00); // -65520 -> -inf
3437
35 try test__truncsfhf2(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf38 try test_f16_floatCast_f32(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf
36 try test__truncsfhf2(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf39 try test_f16_floatCast_f32(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf
3740
38 try test__truncsfhf2(0x38800000, 0x0400); // normal (min), 2**-1441 try test_f16_floatCast_f32(0x38800000, 0x0400); // normal (min), 2**-14
39 try test__truncsfhf2(0xb8800000, 0x8400); // normal (min), -2**-1442 try test_f16_floatCast_f32(0xb8800000, 0x8400); // normal (min), -2**-14
4043
41 try test__truncsfhf2(0x477fe000, 0x7bff); // normal (max), 6550444 try test_f16_floatCast_f32(0x477fe000, 0x7bff); // normal (max), 65504
42 try test__truncsfhf2(0xc77fe000, 0xfbff); // normal (max), -6550445 try test_f16_floatCast_f32(0xc77fe000, 0xfbff); // normal (max), -65504
4346
44 try test__truncsfhf2(0x477fe100, 0x7bff); // normal, 65505 -> 6550447 try test_f16_floatCast_f32(0x477fe100, 0x7bff); // normal, 65505 -> 65504
45 try test__truncsfhf2(0xc77fe100, 0xfbff); // normal, -65505 -> -6550448 try test_f16_floatCast_f32(0xc77fe100, 0xfbff); // normal, -65505 -> -65504
4649
47 try test__truncsfhf2(0x477fef00, 0x7bff); // normal, 65519 -> 6550450 try test_f16_floatCast_f32(0x477fef00, 0x7bff); // normal, 65519 -> 65504
48 try test__truncsfhf2(0xc77fef00, 0xfbff); // normal, -65519 -> -6550451 try test_f16_floatCast_f32(0xc77fef00, 0xfbff); // normal, -65519 -> -65504
4952
50 try test__truncsfhf2(0x3f802000, 0x3c01); // normal, 1 + 2**-1053 try test_f16_floatCast_f32(0x3f802000, 0x3c01); // normal, 1 + 2**-10
51 try test__truncsfhf2(0xbf802000, 0xbc01); // normal, -1 - 2**-1054 try test_f16_floatCast_f32(0xbf802000, 0xbc01); // normal, -1 - 2**-10
5255
53 try test__truncsfhf2(0x3eaaa000, 0x3555); // normal, approx. 1/356 try test_f16_floatCast_f32(0x3eaaa000, 0x3555); // normal, approx. 1/3
54 try test__truncsfhf2(0xbeaaa000, 0xb555); // normal, approx. -1/357 try test_f16_floatCast_f32(0xbeaaa000, 0xb555); // normal, approx. -1/3
5558
56 try test__truncsfhf2(0x40490fdb, 0x4248); // normal, 3.141592653559 try test_f16_floatCast_f32(0x40490fdb, 0x4248); // normal, 3.1415926535
57 try test__truncsfhf2(0xc0490fdb, 0xc248); // normal, -3.141592653560 try test_f16_floatCast_f32(0xc0490fdb, 0xc248); // normal, -3.1415926535
5861
59 try test__truncsfhf2(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+1262 try test_f16_floatCast_f32(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12
6063
61 try test__truncsfhf2(0x3f800000, 0x3c00); // normal, 164 try test_f16_floatCast_f32(0x3f800000, 0x3c00); // normal, 1
62 try test__truncsfhf2(0x38800000, 0x0400); // normal, 0x1.0p-1465 try test_f16_floatCast_f32(0x38800000, 0x0400); // normal, 0x1.0p-14
6366
64 try test__truncsfhf2(0x33800000, 0x0001); // denormal (min), 2**-2467 try test_f16_floatCast_f32(0x33800000, 0x0001); // denormal (min), 2**-24
65 try test__truncsfhf2(0xb3800000, 0x8001); // denormal (min), -2**-2468 try test_f16_floatCast_f32(0xb3800000, 0x8001); // denormal (min), -2**-24
6669
67 try test__truncsfhf2(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-2470 try test_f16_floatCast_f32(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24
68 try test__truncsfhf2(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-2471 try test_f16_floatCast_f32(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24
6972
70 try test__truncsfhf2(0x35800000, 0x0010); // denormal, 0x1.0p-2073 try test_f16_floatCast_f32(0x35800000, 0x0010); // denormal, 0x1.0p-20
71 try test__truncsfhf2(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-2474 try test_f16_floatCast_f32(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24
72 try test__truncsfhf2(0x33000000, 0x0000); // 0x1.0p-25 -> zero75 try test_f16_floatCast_f32(0x33000000, 0x0000); // 0x1.0p-25 -> zero
73}76}
7477
75fn test__truncdfhf2(a: f64, expected: u16) void {78fn test_f16_floatCast_f64(a: f64, expected: u16) !void {
76 const rep: u16 = @bitCast(__truncdfhf2(a));79 const rep: u16 = @bitCast(f16_floatCast_f64(a));
7780
78 if (rep == expected) {81 if (rep == expected) {
79 return;82 return;
...@@ -84,62 +87,56 @@ fn test__truncdfhf2(a: f64, expected: u16) void {...@@ -84,62 +87,56 @@ fn test__truncdfhf2(a: f64, expected: u16) void {
84 return;87 return;
85 }88 }
86 }89 }
8790 return error.TestFailure;
88 @panic("__truncdfhf2 test failure");
89}91}
9092
91fn test__truncdfhf2_raw(a: u64, expected: u16) void {93fn test_f16_floatCast_f64_raw(a: u64, expected: u16) !void {
92 const actual: u16 = @bitCast(__truncdfhf2(@bitCast(a)));94 const actual: u16 = @bitCast(f16_floatCast_f64(@bitCast(a)));
9395 try testing.expect(actual == expected);
94 if (actual == expected) {
95 return;
96 }
97
98 @panic("__truncdfhf2 test failure");
99}96}
10097
101test "truncdfhf2" {98test f16_floatCast_f64 {
102 test__truncdfhf2_raw(0x7ff8000000000000, 0x7e00); // qNaN99 try test_f16_floatCast_f64_raw(0x7ff8000000000000, 0x7e00); // qNaN
103 test__truncdfhf2_raw(0x7ff0000000008000, 0x7e00); // NaN100 try test_f16_floatCast_f64_raw(0x7ff0000000008000, 0x7e00); // NaN
104101
105 test__truncdfhf2_raw(0x7ff0000000000000, 0x7c00); //inf102 try test_f16_floatCast_f64_raw(0x7ff0000000000000, 0x7c00); //inf
106 test__truncdfhf2_raw(0xfff0000000000000, 0xfc00); // -inf103 try test_f16_floatCast_f64_raw(0xfff0000000000000, 0xfc00); // -inf
107104
108 test__truncdfhf2(0.0, 0x0); // zero105 try test_f16_floatCast_f64(0.0, 0x0); // zero
109 test__truncdfhf2_raw(0x80000000 << 32, 0x8000); // -zero106 try test_f16_floatCast_f64_raw(0x80000000 << 32, 0x8000); // -zero
110107
111 test__truncdfhf2(3.1415926535, 0x4248);108 try test_f16_floatCast_f64(3.1415926535, 0x4248);
112 test__truncdfhf2(-3.1415926535, 0xc248);109 try test_f16_floatCast_f64(-3.1415926535, 0xc248);
113110
114 test__truncdfhf2(0x1.987124876876324p+1000, 0x7c00);111 try test_f16_floatCast_f64(0x1.987124876876324p+1000, 0x7c00);
115 test__truncdfhf2(0x1.987124876876324p+12, 0x6e62);112 try test_f16_floatCast_f64(0x1.987124876876324p+12, 0x6e62);
116 test__truncdfhf2(0x1.0p+0, 0x3c00);113 try test_f16_floatCast_f64(0x1.0p+0, 0x3c00);
117 test__truncdfhf2(0x1.0p-14, 0x0400);114 try test_f16_floatCast_f64(0x1.0p-14, 0x0400);
118115
119 // denormal116 // denormal
120 test__truncdfhf2(0x1.0p-20, 0x0010);117 try test_f16_floatCast_f64(0x1.0p-20, 0x0010);
121 test__truncdfhf2(0x1.0p-24, 0x0001);118 try test_f16_floatCast_f64(0x1.0p-24, 0x0001);
122 test__truncdfhf2(-0x1.0p-24, 0x8001);119 try test_f16_floatCast_f64(-0x1.0p-24, 0x8001);
123 test__truncdfhf2(0x1.5p-25, 0x0001);120 try test_f16_floatCast_f64(0x1.5p-25, 0x0001);
124121
125 // and back to zero122 // and back to zero
126 test__truncdfhf2(0x1.0p-25, 0x0000);123 try test_f16_floatCast_f64(0x1.0p-25, 0x0000);
127 test__truncdfhf2(-0x1.0p-25, 0x8000);124 try test_f16_floatCast_f64(-0x1.0p-25, 0x8000);
128125
129 // max (precise)126 // max (precise)
130 test__truncdfhf2(65504.0, 0x7bff);127 try test_f16_floatCast_f64(65504.0, 0x7bff);
131128
132 // max (rounded)129 // max (rounded)
133 test__truncdfhf2(65519.0, 0x7bff);130 try test_f16_floatCast_f64(65519.0, 0x7bff);
134131
135 // max (to +inf)132 // max (to +inf)
136 test__truncdfhf2(65520.0, 0x7c00);133 try test_f16_floatCast_f64(65520.0, 0x7c00);
137 test__truncdfhf2(-65520.0, 0xfc00);134 try test_f16_floatCast_f64(-65520.0, 0xfc00);
138 test__truncdfhf2(65536.0, 0x7c00);135 try test_f16_floatCast_f64(65536.0, 0x7c00);
139}136}
140137
141fn test__trunctfsf2(a: f128, expected: u32) void {138fn test_f32_floatCast_f128(a: f128, expected: u32) !void {
142 const x = __trunctfsf2(a);139 const x = f32_floatCast_f128(a);
143140
144 const rep: u32 = @bitCast(x);141 const rep: u32 = @bitCast(x);
145 if (rep == expected) {142 if (rep == expected) {
...@@ -151,28 +148,27 @@ fn test__trunctfsf2(a: f128, expected: u32) void {...@@ -151,28 +148,27 @@ fn test__trunctfsf2(a: f128, expected: u32) void {
151 return;148 return;
152 }149 }
153 }150 }
154151 return error.TestFailure;
155 @panic("__trunctfsf2 test failure");
156}152}
157153
158test "trunctfsf2" {154test f32_floatCast_f128 {
159 // qnan155 // qnan
160 test__trunctfsf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000);156 try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000);
161 // nan157 // nan
162 test__trunctfsf2(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000);158 try test_f32_floatCast_f128(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000);
163 // inf159 // inf
164 test__trunctfsf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000);160 try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000);
165 // zero161 // zero
166 test__trunctfsf2(0.0, 0x0);162 try test_f32_floatCast_f128(0.0, 0x0);
167163
168 test__trunctfsf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156);164 try test_f32_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156);
169 test__trunctfsf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2);165 try test_f32_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2);
170 test__trunctfsf2(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000);166 try test_f32_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000);
171 test__trunctfsf2(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0);167 try test_f32_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0);
172}168}
173169
174fn test__trunctfdf2(a: f128, expected: u64) void {170fn test_f64_floatCast_f128(a: f128, expected: u64) !void {
175 const x = __trunctfdf2(a);171 const x = f64_floatCast_f128(a);
176172
177 const rep: u64 = @bitCast(x);173 const rep: u64 = @bitCast(x);
178 if (rep == expected) {174 if (rep == expected) {
...@@ -184,28 +180,27 @@ fn test__trunctfdf2(a: f128, expected: u64) void {...@@ -184,28 +180,27 @@ fn test__trunctfdf2(a: f128, expected: u64) void {
184 return;180 return;
185 }181 }
186 }182 }
187183 return error.TestFailure;
188 @panic("__trunctfsf2 test failure");
189}184}
190185
191test "trunctfdf2" {186test f64_floatCast_f128 {
192 // qnan187 // qnan
193 test__trunctfdf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000);188 try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000);
194 // nan189 // nan
195 test__trunctfdf2(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000);190 try test_f64_floatCast_f128(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000);
196 // inf191 // inf
197 test__trunctfdf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000);192 try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000);
198 // zero193 // zero
199 test__trunctfdf2(0.0, 0x0);194 try test_f64_floatCast_f128(0.0, 0x0);
200195
201 test__trunctfdf2(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb);196 try test_f64_floatCast_f128(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb);
202 test__trunctfdf2(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7);197 try test_f64_floatCast_f128(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7);
203 test__trunctfdf2(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000);198 try test_f64_floatCast_f128(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000);
204 test__trunctfdf2(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab);199 try test_f64_floatCast_f128(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab);
205}200}
206201
207fn test__truncdfsf2(a: f64, expected: u32) void {202fn test_f32_floatCast_f64(a: f64, expected: u32) !void {
208 const x = __truncdfsf2(a);203 const x = f32_floatCast_f64(a);
209204
210 const rep: u32 = @bitCast(x);205 const rep: u32 = @bitCast(x);
211 if (rep == expected) {206 if (rep == expected) {
...@@ -217,90 +212,81 @@ fn test__truncdfsf2(a: f64, expected: u32) void {...@@ -217,90 +212,81 @@ fn test__truncdfsf2(a: f64, expected: u32) void {
217 return;212 return;
218 }213 }
219 }214 }
220215 return error.TestFailure;
221 std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected });
222
223 @panic("__trunctfsf2 test failure");
224}216}
225217
226test "truncdfsf2" {218test f32_floatCast_f64 {
227 // nan & qnan219 // nan & qnan
228 test__truncdfsf2(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000);220 try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000);
229 test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000);221 try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000);
230 // inf222 // inf
231 test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000);223 try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000);
232 test__truncdfsf2(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000);224 try test_f32_floatCast_f64(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000);
233225
234 test__truncdfsf2(0.0, 0x0);226 try test_f32_floatCast_f64(0.0, 0x0);
235 test__truncdfsf2(1.0, 0x3f800000);227 try test_f32_floatCast_f64(1.0, 0x3f800000);
236 test__truncdfsf2(-1.0, 0xbf800000);228 try test_f32_floatCast_f64(-1.0, 0xbf800000);
237229
238 // huge number becomes inf230 // huge number becomes inf
239 test__truncdfsf2(340282366920938463463374607431768211456.0, 0x7f800000);231 try test_f32_floatCast_f64(340282366920938463463374607431768211456.0, 0x7f800000);
240}232}
241233
242fn test__trunctfhf2(a: f128, expected: u16) void {234fn test_f16_floatCast_f128(a: f128, expected: u16) !void {
243 const x = __trunctfhf2(a);235 const x = f16_floatCast_f128(a);
244236
245 const rep: u16 = @bitCast(x);237 const rep: u16 = @bitCast(x);
246 if (rep == expected) {238 try testing.expect(rep == expected);
247 return;
248 }
249
250 std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected });
251
252 @panic("__trunctfhf2 test failure");
253}239}
254240
255test "trunctfhf2" {241test f16_floatCast_f128 {
256 // qNaN242 // qNaN
257 test__trunctfhf2(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00);243 try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00);
258 // NaN244 // NaN
259 test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00);245 try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00);
260 // inf246 // inf
261 test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00);247 try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00);
262 test__trunctfhf2(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00);248 try test_f16_floatCast_f128(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00);
263 // zero249 // zero
264 test__trunctfhf2(0.0, 0x0);250 try test_f16_floatCast_f128(0.0, 0x0);
265 test__trunctfhf2(-0.0, 0x8000);251 try test_f16_floatCast_f128(-0.0, 0x8000);
266252
267 test__trunctfhf2(3.1415926535, 0x4248);253 try test_f16_floatCast_f128(3.1415926535, 0x4248);
268 test__trunctfhf2(-3.1415926535, 0xc248);254 try test_f16_floatCast_f128(-3.1415926535, 0xc248);
269 test__trunctfhf2(0x1.987124876876324p+100, 0x7c00);255 try test_f16_floatCast_f128(0x1.987124876876324p+100, 0x7c00);
270 test__trunctfhf2(0x1.987124876876324p+12, 0x6e62);256 try test_f16_floatCast_f128(0x1.987124876876324p+12, 0x6e62);
271 test__trunctfhf2(0x1.0p+0, 0x3c00);257 try test_f16_floatCast_f128(0x1.0p+0, 0x3c00);
272 test__trunctfhf2(0x1.0p-14, 0x0400);258 try test_f16_floatCast_f128(0x1.0p-14, 0x0400);
273 // denormal259 // denormal
274 test__trunctfhf2(0x1.0p-20, 0x0010);260 try test_f16_floatCast_f128(0x1.0p-20, 0x0010);
275 test__trunctfhf2(0x1.0p-24, 0x0001);261 try test_f16_floatCast_f128(0x1.0p-24, 0x0001);
276 test__trunctfhf2(-0x1.0p-24, 0x8001);262 try test_f16_floatCast_f128(-0x1.0p-24, 0x8001);
277 test__trunctfhf2(0x1.5p-25, 0x0001);263 try test_f16_floatCast_f128(0x1.5p-25, 0x0001);
278 // and back to zero264 // and back to zero
279 test__trunctfhf2(0x1.0p-25, 0x0000);265 try test_f16_floatCast_f128(0x1.0p-25, 0x0000);
280 test__trunctfhf2(-0x1.0p-25, 0x8000);266 try test_f16_floatCast_f128(-0x1.0p-25, 0x8000);
281 // max (precise)267 // max (precise)
282 test__trunctfhf2(65504.0, 0x7bff);268 try test_f16_floatCast_f128(65504.0, 0x7bff);
283 // max (rounded)269 // max (rounded)
284 test__trunctfhf2(65519.0, 0x7bff);270 try test_f16_floatCast_f128(65519.0, 0x7bff);
285 // max (to +inf)271 // max (to +inf)
286 test__trunctfhf2(65520.0, 0x7c00);272 try test_f16_floatCast_f128(65520.0, 0x7c00);
287 test__trunctfhf2(65536.0, 0x7c00);273 try test_f16_floatCast_f128(65536.0, 0x7c00);
288 test__trunctfhf2(-65520.0, 0xfc00);274 try test_f16_floatCast_f128(-65520.0, 0xfc00);
289275
290 test__trunctfhf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f);276 try test_f16_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f);
291 test__trunctfhf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f);277 try test_f16_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f);
292 test__trunctfhf2(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00);278 try test_f16_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00);
293 test__trunctfhf2(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0);279 try test_f16_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0);
294}280}
295281
296test "trunctfxf2" {282fn test_f80_floatCast_f128(a: f128, expected: f80) !void {
297 try test__trunctfxf2(1.5, 1.5);283 const x = f80_floatCast_f128(a);
298 try test__trunctfxf2(2.5, 2.5);284 try testing.expect(x == expected);
299 try test__trunctfxf2(-2.5, -2.5);
300 try test__trunctfxf2(0.0, 0.0);
301}285}
302286
303fn test__trunctfxf2(a: f128, expected: f80) !void {287test f80_floatCast_f128 {
304 const x = __trunctfxf2(a);288 try test_f80_floatCast_f128(1.5, 1.5);
305 try testing.expect(x == expected);289 try test_f80_floatCast_f128(2.5, 2.5);
290 try test_f80_floatCast_f128(-2.5, -2.5);
291 try test_f80_floatCast_f128(0.0, 0.0);
306}292}
lib/compiler_rt/truncsfhf2.zig deleted-24
...@@ -1,24 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const truncf = @import("./truncf.zig").truncf;
4
5comptime {
6 if (compiler_rt.gnu_f16_abi) {
7 symbol(&__gnu_f2h_ieee, "__gnu_f2h_ieee");
8 } else if (compiler_rt.want_aeabi) {
9 symbol(&__aeabi_f2h, "__aeabi_f2h");
10 }
11 symbol(&__truncsfhf2, "__truncsfhf2");
12}
13
14pub fn __truncsfhf2(a: f32) callconv(.c) compiler_rt.F16T(f32) {
15 return @bitCast(truncf(f16, f32, a));
16}
17
18fn __gnu_f2h_ieee(a: f32) callconv(.c) compiler_rt.F16T(f32) {
19 return @bitCast(truncf(f16, f32, a));
20}
21
22fn __aeabi_f2h(a: f32) callconv(.{ .arm_aapcs = .{} }) u16 {
23 return @bitCast(truncf(f16, f32, a));
24}
lib/compiler_rt/trunctfdf2.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const truncf = @import("./truncf.zig").truncf;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__trunctfdf2, "__trunckfdf2");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_qtod, "_Qp_qtod");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__trunctfdf2, "_Q_qtod");
12 }
13 symbol(&__trunctfdf2, "__trunctfdf2");
14}
15
16pub fn __trunctfdf2(a: f128) callconv(.c) f64 {
17 return truncf(f64, f128, a);
18}
19
20fn _Qp_qtod(a: *const f128) callconv(.c) f64 {
21 return truncf(f64, f128, a.*);
22}
lib/compiler_rt/trunctfhf2.zig deleted-14
...@@ -1,14 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const truncf = @import("./truncf.zig").truncf;
4
5comptime {
6 symbol(&__trunctfhf2, "__trunctfhf2");
7 if (compiler_rt.want_ppc_abi) {
8 symbol(&__trunctfhf2, "__trunckfhf2");
9 }
10}
11
12pub fn __trunctfhf2(a: f128) callconv(.c) compiler_rt.F16T(f128) {
13 return @bitCast(truncf(f16, f128, a));
14}
lib/compiler_rt/trunctfsf2.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const truncf = @import("./truncf.zig").truncf;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_ppc_abi) {
7 symbol(&__trunctfsf2, "__trunckfsf2");
8 } else if (compiler_rt.want_sparc64_abi) {
9 symbol(&_Qp_qtos, "_Qp_qtos");
10 } else if (compiler_rt.want_sparc32_abi) {
11 symbol(&__trunctfsf2, "_Q_qtos");
12 }
13 symbol(&__trunctfsf2, "__trunctfsf2");
14}
15
16pub fn __trunctfsf2(a: f128) callconv(.c) f32 {
17 return truncf(f32, f128, a);
18}
19
20fn _Qp_qtos(a: *const f128) callconv(.c) f32 {
21 return truncf(f32, f128, a.*);
22}
lib/compiler_rt/trunctfxf2.zig deleted-67
...@@ -1,67 +0,0 @@
1const math = @import("std").math;
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const trunc_f80 = @import("./truncf.zig").trunc_f80;
5
6comptime {
7 symbol(&__trunctfxf2, "__trunctfxf2");
8}
9
10pub fn __trunctfxf2(a: f128) callconv(.c) f80 {
11 const src_sig_bits = math.floatMantissaBits(f128);
12 const dst_sig_bits = math.floatMantissaBits(f80) - 1; // -1 for the integer bit
13
14 // Various constants whose values follow from the type parameters.
15 // Any reasonable optimizer will fold and propagate all of these.
16 const src_bits = @typeInfo(f128).float.bits;
17 const src_exp_bits = src_bits - src_sig_bits - 1;
18 const src_inf_exp = 0x7FFF;
19
20 const src_inf = src_inf_exp << src_sig_bits;
21 const src_sign_mask = 1 << (src_sig_bits + src_exp_bits);
22 const src_abs_mask = src_sign_mask - 1;
23 const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1;
24 const halfway = 1 << (src_sig_bits - dst_sig_bits - 1);
25
26 // Break a into a sign and representation of the absolute value
27 const a_rep = @as(u128, @bitCast(a));
28 const a_abs = a_rep & src_abs_mask;
29 const sign: u16 = if (a_rep & src_sign_mask != 0) 0x8000 else 0;
30 const integer_bit = 1 << 63;
31
32 var res: math.F80 = undefined;
33
34 if (a_abs > src_inf) {
35 // a is NaN.
36 // Conjure the result by beginning with infinity, setting the qNaN
37 // bit and inserting the (truncated) trailing NaN field.
38 res.exp = 0x7fff;
39 res.fraction = 0x8000000000000000;
40 res.fraction |= @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits)));
41 } else {
42 // The exponent of a is within the range of normal numbers in the
43 // destination format. We can convert by simply right-shifting with
44 // rounding, adding the explicit integer bit, and adjusting the exponent
45 res.fraction = @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))) | integer_bit;
46 res.exp = @truncate(a_abs >> src_sig_bits);
47
48 const round_bits = a_abs & round_mask;
49 if (round_bits > halfway) {
50 // Round to nearest
51 const ov = @addWithOverflow(res.fraction, 1);
52 res.fraction = ov[0];
53 res.exp += ov[1];
54 res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry
55 } else if (round_bits == halfway) {
56 // Ties to even
57 const ov = @addWithOverflow(res.fraction, res.fraction & 1);
58 res.fraction = ov[0];
59 res.exp += ov[1];
60 res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry
61 }
62 if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals
63 }
64
65 res.exp |= sign;
66 return res.toFloat();
67}
lib/compiler_rt/truncxfdf2.zig deleted-10
...@@ -1,10 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const trunc_f80 = @import("./truncf.zig").trunc_f80;
3
4comptime {
5 symbol(&__truncxfdf2, "__truncxfdf2");
6}
7
8fn __truncxfdf2(a: f80) callconv(.c) f64 {
9 return trunc_f80(f64, a);
10}
lib/compiler_rt/truncxfhf2.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const trunc_f80 = @import("./truncf.zig").trunc_f80;
4
5comptime {
6 symbol(&__truncxfhf2, "__truncxfhf2");
7}
8
9fn __truncxfhf2(a: f80) callconv(.c) compiler_rt.F16T(f80) {
10 return @bitCast(trunc_f80(f16, a));
11}
lib/compiler_rt/truncxfsf2.zig deleted-10
...@@ -1,10 +0,0 @@
1const trunc_f80 = @import("./truncf.zig").trunc_f80;
2const symbol = @import("../compiler_rt.zig").symbol;
3
4comptime {
5 symbol(&__truncxfsf2, "__truncxfsf2");
6}
7
8fn __truncxfsf2(a: f80) callconv(.c) f32 {
9 return trunc_f80(f32, a);
10}
lib/compiler_rt/udivmodei4.zig+1-1
...@@ -6,7 +6,7 @@ const shr = std.math.shr;...@@ -6,7 +6,7 @@ const shr = std.math.shr;
6const shl = std.math.shl;6const shl = std.math.shl;
77
8const compiler_rt = @import("../compiler_rt.zig");8const compiler_rt = @import("../compiler_rt.zig");
9const symbol = @import("../compiler_rt.zig").symbol;9const symbol = compiler_rt.symbol;
1010
11const max_limbs = @divCeil(65535, 32); // max supported type is u6553511const max_limbs = @divCeil(65535, 32); // max supported type is u65535
1212
lib/compiler_rt/unorddf2.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const comparef = @import("./comparef.zig");
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_dcmpun, "__aeabi_dcmpun");
8 } else {
9 symbol(&__unorddf2, "__unorddf2");
10 }
11}
12
13pub fn __unorddf2(a: f64, b: f64) callconv(.c) i32 {
14 return comparef.unordcmp(f64, a, b);
15}
16
17fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
18 return comparef.unordcmp(f64, a, b);
19}
lib/std/Io/Semaphore.zig-2
...@@ -4,8 +4,6 @@...@@ -4,8 +4,6 @@
4//! This API supports static initialization and does not require deinitialization.4//! This API supports static initialization and does not require deinitialization.
5const Semaphore = @This();5const Semaphore = @This();
66
7const builtin = @import("builtin");
8
9const std = @import("../std.zig");7const std = @import("../std.zig");
10const Io = std.Io;8const Io = std.Io;
11const testing = std.testing;9const testing = std.testing;
lib/std/Io/Writer.zig+9-9
...@@ -874,7 +874,7 @@ pub fn splatBytes(w: *Writer, bytes: []const u8, n: usize) Error!usize {...@@ -874,7 +874,7 @@ pub fn splatBytes(w: *Writer, bytes: []const u8, n: usize) Error!usize {
874}874}
875875
876/// Asserts the `buffer` was initialized with a capacity of at least `@sizeOf(T)` bytes.876/// Asserts the `buffer` was initialized with a capacity of at least `@sizeOf(T)` bytes.
877pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.builtin.Endian) Error!void {877pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.lang.Endian) Error!void {
878 var bytes: [@divExact(@typeInfo(T).int.bits, 8)]u8 = undefined;878 var bytes: [@divExact(@typeInfo(T).int.bits, 8)]u8 = undefined;
879 std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian);879 std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian);
880 return w.writeAll(&bytes);880 return w.writeAll(&bytes);
...@@ -882,7 +882,7 @@ pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.built...@@ -882,7 +882,7 @@ pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.built
882882
883/// The function is inline to avoid the dead code in case `endian` is883/// The function is inline to avoid the dead code in case `endian` is
884/// comptime-known and matches host endianness.884/// comptime-known and matches host endianness.
885pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.builtin.Endian) Error!void {885pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.lang.Endian) Error!void {
886 switch (@typeInfo(@TypeOf(value))) {886 switch (@typeInfo(@TypeOf(value))) {
887 .@"struct" => |info| switch (info.layout) {887 .@"struct" => |info| switch (info.layout) {
888 .auto => @compileError("ill-defined memory layout"),888 .auto => @compileError("ill-defined memory layout"),
...@@ -907,7 +907,7 @@ pub inline fn writeSliceEndian(...@@ -907,7 +907,7 @@ pub inline fn writeSliceEndian(
907 w: *Writer,907 w: *Writer,
908 Elem: type,908 Elem: type,
909 slice: []const Elem,909 slice: []const Elem,
910 endian: std.builtin.Endian,910 endian: std.lang.Endian,
911) Error!void {911) Error!void {
912 switch (@typeInfo(Elem)) {912 switch (@typeInfo(Elem)) {
913 .@"struct" => |info| comptime assert(info.layout != .auto),913 .@"struct" => |info| comptime assert(info.layout != .auto),
...@@ -2817,12 +2817,12 @@ pub const Allocating = struct {...@@ -2817,12 +2817,12 @@ pub const Allocating = struct {
2817 }2817 }
28182818
2819 test Allocating {2819 test Allocating {
2820 try testAllocating(.fromByteUnits(1));2820 try testAllocating(.@"1");
2821 try testAllocating(.fromByteUnits(4));2821 try testAllocating(.@"4");
2822 try testAllocating(.fromByteUnits(8));2822 try testAllocating(.@"8");
2823 try testAllocating(.fromByteUnits(16));2823 try testAllocating(.@"16");
2824 try testAllocating(.fromByteUnits(32));2824 try testAllocating(.@"32");
2825 try testAllocating(.fromByteUnits(64));2825 try testAllocating(.@"64");
2826 }2826 }
2827};2827};
28282828
lib/std/Random/RomuTrio.zig-1
...@@ -122,7 +122,6 @@ test fill {...@@ -122,7 +122,6 @@ test fill {
122}122}
123123
124test "buf seeding test" {124test "buf seeding test" {
125 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
126 const buf0: [24]u8 = @bitCast([3]u64{ 16294208416658607535, 13964609475759908645, 4703697494102998476 });125 const buf0: [24]u8 = @bitCast([3]u64{ 16294208416658607535, 13964609475759908645, 4703697494102998476 });
127 const resulting_state = .{ .x = 16294208416658607535, .y = 13964609475759908645, .z = 4703697494102998476 };126 const resulting_state = .{ .x = 16294208416658607535, .y = 13964609475759908645, .z = 4703697494102998476 };
128 var r = RomuTrio.init(0);127 var r = RomuTrio.init(0);
lib/std/Random/Xoshiro256.zig-2
...@@ -89,8 +89,6 @@ pub fn fill(self: *Xoshiro256, buf: []u8) void {...@@ -89,8 +89,6 @@ pub fn fill(self: *Xoshiro256, buf: []u8) void {
89}89}
9090
91test "sequence" {91test "sequence" {
92 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
93
94 var r = Xoshiro256.init(0);92 var r = Xoshiro256.init(0);
9593
96 const seq1 = [_]u64{94 const seq1 = [_]u64{
lib/std/Target.zig+26-131
...@@ -1797,6 +1797,7 @@ pub const Cpu = struct {...@@ -1797,6 +1797,7 @@ pub const Cpu = struct {
17971797
1798 .x86_sysv,1798 .x86_sysv,
1799 .x86_win,1799 .x86_win,
1800 .x86_mingw,
1800 .x86_stdcall,1801 .x86_stdcall,
1801 .x86_fastcall,1802 .x86_fastcall,
1802 .x86_thiscall,1803 .x86_thiscall,
...@@ -3066,9 +3067,13 @@ pub fn stackGrowth(target: *const Target) StackGrowth {...@@ -3066,9 +3067,13 @@ pub fn stackGrowth(target: *const Target) StackGrowth {
3066/// Default signedness of `char` for the native C compiler for this target3067/// Default signedness of `char` for the native C compiler for this target
3067/// Note that char signedness is implementation-defined and many compilers provide3068/// Note that char signedness is implementation-defined and many compilers provide
3068/// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char3069/// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char
3069pub fn cCharSignedness(target: *const Target) std.builtin.Signedness {3070/// Returns `null` if no C ABI is defined for this target.
3071pub fn cCharSignedness(target: *const Target) ?std.builtin.Signedness {
3072 switch (target.os.tag) {
3073 .opengl => return null,
3074 else => {},
3075 }
3070 if (target.os.tag.isDarwin() or target.os.tag == .windows or target.os.tag == .uefi) return .signed;3076 if (target.os.tag.isDarwin() or target.os.tag == .windows or target.os.tag == .uefi) return .signed;
3071
3072 return switch (target.cpu.arch) {3077 return switch (target.cpu.arch) {
3073 .aarch64,3078 .aarch64,
3074 .aarch64_be,3079 .aarch64_be,
...@@ -3114,7 +3119,8 @@ pub const CType = enum {...@@ -3114,7 +3119,8 @@ pub const CType = enum {
3114 longdouble,3119 longdouble,
3115};3120};
31163121
3117pub fn cTypeByteSize(t: *const Target, c_type: CType) u16 {3122/// Returns `null` if no C ABI is defined for this target.
3123pub fn cTypeByteSize(t: *const Target, c_type: CType) ?u16 {
3118 return switch (c_type) {3124 return switch (c_type) {
3119 .char,3125 .char,
3120 .short,3126 .short,
...@@ -3127,18 +3133,19 @@ pub fn cTypeByteSize(t: *const Target, c_type: CType) u16 {...@@ -3127,18 +3133,19 @@ pub fn cTypeByteSize(t: *const Target, c_type: CType) u16 {
3127 .ulonglong,3133 .ulonglong,
3128 .float,3134 .float,
3129 .double,3135 .double,
3130 => @divExact(cTypeBitSize(t, c_type), 8),3136 => @divExact(cTypeBitSize(t, c_type) orelse return null, 8),
31313137
3132 .longdouble => switch (cTypeBitSize(t, c_type)) {3138 .longdouble => switch (cTypeBitSize(t, c_type) orelse return null) {
3133 64 => 8,3139 64 => 8,
3134 80 => @intCast(std.mem.alignForward(usize, 10, cTypeAlignment(t, .longdouble))),3140 80 => @intCast(std.mem.alignForward(usize, 10, cTypeAlignment(t, c_type).?)),
3135 128 => 16,3141 128 => 16,
3136 else => unreachable,3142 else => unreachable,
3137 },3143 },
3138 };3144 };
3139}3145}
31403146
3141pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {3147/// Returns `null` if no C ABI is defined for this target.
3148pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {
3142 switch (target.os.tag) {3149 switch (target.os.tag) {
3143 .freestanding,3150 .freestanding,
3144 .other,3151 .other,
...@@ -3459,15 +3466,17 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {...@@ -3459,15 +3466,17 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
3459 .longlong, .ulonglong, .longdouble => return 64,3466 .longlong, .ulonglong, .longdouble => return 64,
3460 },3467 },
34613468
3469 .opengl => return null,
3470
3462 .ps3,3471 .ps3,
3463 .contiki,3472 .contiki,
3464 .managarm,3473 .managarm,
3465 .opengl,
3466 => @panic("specify the C integer and float type sizes for this OS"),3474 => @panic("specify the C integer and float type sizes for this OS"),
3467 }3475 }
3468}3476}
34693477
3470pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {3478/// Returns `null` if no C ABI is defined for this target.
3479pub fn cTypeAlignment(target: *const Target, c_type: CType) ?u16 {
3471 // Overrides for unusual alignments3480 // Overrides for unusual alignments
3472 switch (target.cpu.arch) {3481 switch (target.cpu.arch) {
3473 .avr,3482 .avr,
...@@ -3500,7 +3509,7 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {...@@ -3500,7 +3509,7 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
35003509
3501 // Next-power-of-two-aligned, up to a maximum.3510 // Next-power-of-two-aligned, up to a maximum.
3502 return @min(3511 return @min(
3503 std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8),3512 std.math.ceilPowerOfTwoAssert(u16, ((cTypeBitSize(target, c_type) orelse return null) + 7) / 8),
3504 @as(u16, switch (target.cpu.arch) {3513 @as(u16, switch (target.cpu.arch) {
3505 .msp430,3514 .msp430,
3506 .x86_16,3515 .x86_16,
...@@ -3575,120 +3584,6 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {...@@ -3575,120 +3584,6 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
3575 );3584 );
3576}3585}
35773586
3578pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 {
3579 // Overrides for unusual alignments
3580 switch (target.cpu.arch) {
3581 .arc, .arceb => switch (c_type) {
3582 .longdouble => return 4,
3583 else => {},
3584 },
3585 .avr,
3586 .ez80,
3587 => return 1,
3588 .x86 => switch (target.os.tag) {
3589 .windows, .uefi => switch (c_type) {
3590 .longdouble => switch (target.abi) {
3591 .gnu => return 4,
3592 else => return 8,
3593 },
3594 else => {},
3595 },
3596 else => switch (c_type) {
3597 .longdouble => return 4,
3598 else => {},
3599 },
3600 },
3601 .m68k => switch (c_type) {
3602 .int, .uint, .long, .ulong => return 2,
3603 else => {},
3604 },
3605 .wasm32, .wasm64 => switch (target.os.tag) {
3606 .emscripten => switch (c_type) {
3607 .longdouble => return 8,
3608 else => {},
3609 },
3610 else => {},
3611 },
3612 else => {},
3613 }
3614
3615 // Next-power-of-two-aligned, up to a maximum.
3616 return @min(
3617 std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8),
3618 @as(u16, switch (target.cpu.arch) {
3619 .x86_16,
3620 .msp430,
3621 => 2,
3622
3623 .arc,
3624 .arceb,
3625 .csky,
3626 .kalimba,
3627 .microblaze,
3628 .microblazeel,
3629 .or1k,
3630 .propeller,
3631 .sh,
3632 .sheb,
3633 .xcore,
3634 .xtensa,
3635 .xtensaeb,
3636 => 4,
3637
3638 .amdgcn,
3639 .arm,
3640 .armeb,
3641 .bpfeb,
3642 .bpfel,
3643 .hexagon,
3644 .hppa,
3645 .lanai,
3646 .m68k,
3647 .m88k,
3648 .mips,
3649 .mipsel,
3650 .nvptx,
3651 .nvptx64,
3652 .s390x,
3653 .sparc,
3654 .thumb,
3655 .thumbeb,
3656 .x86,
3657 => 8,
3658
3659 .aarch64,
3660 .aarch64_be,
3661 .alpha,
3662 .hppa64,
3663 .kvx,
3664 .loongarch32,
3665 .loongarch64,
3666 .mips64,
3667 .mips64el,
3668 .powerpc,
3669 .powerpcle,
3670 .powerpc64,
3671 .powerpc64le,
3672 .riscv32,
3673 .riscv32be,
3674 .riscv64,
3675 .riscv64be,
3676 .sparc64,
3677 .spirv32,
3678 .spirv64,
3679 .ve,
3680 .wasm32,
3681 .wasm64,
3682 .x86_64,
3683 => 16,
3684
3685 .avr,
3686 .ez80,
3687 => unreachable, // Handled above.
3688 }),
3689 );
3690}
3691
3692pub fn cMaxIntAlignment(target: *const Target) u16 {3587pub fn cMaxIntAlignment(target: *const Target) u16 {
3693 return switch (target.cpu.arch) {3588 return switch (target.cpu.arch) {
3694 .avr,3589 .avr,
...@@ -3712,6 +3607,11 @@ pub fn cMaxIntAlignment(target: *const Target) u16 {...@@ -3712,6 +3607,11 @@ pub fn cMaxIntAlignment(target: *const Target) u16 {
3712 .xcore,3607 .xcore,
3713 => 4,3608 => 4,
37143609
3610 .x86 => switch (target.os.tag) {
3611 else => 4,
3612 .uefi, .windows => 8,
3613 },
3614
3715 .arm,3615 .arm,
3716 .armeb,3616 .armeb,
3717 .hexagon,3617 .hexagon,
...@@ -3730,7 +3630,6 @@ pub fn cMaxIntAlignment(target: *const Target) u16 {...@@ -3730,7 +3630,6 @@ pub fn cMaxIntAlignment(target: *const Target) u16 {
3730 .sparc,3630 .sparc,
3731 .thumb,3631 .thumb,
3732 .thumbeb,3632 .thumbeb,
3733 .x86,
3734 .xtensa,3633 .xtensa,
3735 .xtensaeb,3634 .xtensaeb,
3736 => 8,3635 => 8,
...@@ -3766,18 +3665,14 @@ pub fn cMaxIntAlignment(target: *const Target) u16 {...@@ -3766,18 +3665,14 @@ pub fn cMaxIntAlignment(target: *const Target) u16 {
3766pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention {3665pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention {
3767 return switch (target.cpu.arch) {3666 return switch (target.cpu.arch) {
3768 .x86_64 => switch (target.os.tag) {3667 .x86_64 => switch (target.os.tag) {
3769 .windows,3668 .windows, .uefi => .{ .x86_64_win = .{} },
3770 .uefi,
3771 => .{ .x86_64_win = .{} },
3772 else => switch (target.abi) {3669 else => switch (target.abi) {
3773 .gnux32, .muslx32, .x32 => .{ .x86_64_x32 = .{} },3670 .gnux32, .muslx32, .x32 => .{ .x86_64_x32 = .{} },
3774 else => .{ .x86_64_sysv = .{} },3671 else => .{ .x86_64_sysv = .{} },
3775 },3672 },
3776 },3673 },
3777 .x86 => switch (target.os.tag) {3674 .x86 => switch (target.os.tag) {
3778 .windows,3675 .windows, .uefi => if (target.isMinGW()) .{ .x86_mingw = .{} } else .{ .x86_win = .{} },
3779 .uefi,
3780 => .{ .x86_win = .{} },
3781 else => .{ .x86_sysv = .{} },3676 else => .{ .x86_sysv = .{} },
3782 },3677 },
3783 .x86_16 => .{ .x86_16_cdecl = .{} },3678 .x86_16 => .{ .x86_16_cdecl = .{} },
lib/std/bit_set.zig-2
...@@ -1707,8 +1707,6 @@ fn testStaticBitSet(comptime Set: type) !void {...@@ -1707,8 +1707,6 @@ fn testStaticBitSet(comptime Set: type) !void {
1707}1707}
17081708
1709test Integer {1709test Integer {
1710 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1711
1712 try testStaticBitSet(Integer(0));1710 try testStaticBitSet(Integer(0));
1713 try testStaticBitSet(Integer(1));1711 try testStaticBitSet(Integer(1));
1714 try testStaticBitSet(Integer(2));1712 try testStaticBitSet(Integer(2));
lib/std/crypto/Certificate.zig+1-1
...@@ -1211,7 +1211,7 @@ pub const rsa = struct {...@@ -1211,7 +1211,7 @@ pub const rsa = struct {
1211 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,1211 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
1212 0x00, 0x04, 0x40,1212 0x00, 0x04, 0x40,
1213 },1213 },
1214 else => @compileError("unreachable"),1214 else => comptime unreachable,
1215 };1215 };
1216 em_index -= hash_der.len;1216 em_index -= hash_der.len;
1217 @memcpy(em[em_index..][0..hash_der.len], hash_der);1217 @memcpy(em[em_index..][0..hash_der.len], hash_der);
lib/std/crypto/aes.zig+2-2
...@@ -6,9 +6,9 @@ const has_aesni = builtin.cpu.has(.x86, .aes);...@@ -6,9 +6,9 @@ const has_aesni = builtin.cpu.has(.x86, .aes);
6const has_avx = builtin.cpu.has(.x86, .avx);6const has_avx = builtin.cpu.has(.x86, .avx);
7const has_armaes = builtin.cpu.has(.aarch64, .aes);7const has_armaes = builtin.cpu.has(.aarch64, .aes);
8// C backend doesn't currently support passing vectors to inline asm.8// C backend doesn't currently support passing vectors to inline asm.
9const impl = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c and has_aesni and has_avx) impl: {9const impl = if (builtin.cpu.arch == .x86_64 and has_aesni and has_avx) impl: {
10 break :impl @import("aes/aesni.zig");10 break :impl @import("aes/aesni.zig");
11} else if (builtin.cpu.arch == .aarch64 and builtin.zig_backend != .stage2_c and has_armaes) impl: {11} else if (builtin.cpu.arch == .aarch64 and (builtin.zig_backend != .stage2_c or !builtin.os.tag.isDarwin()) and has_armaes) impl: {
12 break :impl @import("aes/armcrypto.zig");12 break :impl @import("aes/armcrypto.zig");
13} else impl: {13} else impl: {
14 break :impl @import("aes/soft.zig");14 break :impl @import("aes/soft.zig");
lib/std/crypto/aes_ocb.zig-10
...@@ -262,8 +262,6 @@ const hexToBytes = std.fmt.hexToBytes;...@@ -262,8 +262,6 @@ const hexToBytes = std.fmt.hexToBytes;
262const testing = std.testing;262const testing = std.testing;
263263
264test "AesOcb test vector 1" {264test "AesOcb test vector 1" {
265 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
266
267 var k: [Aes128Ocb.key_length]u8 = undefined;265 var k: [Aes128Ocb.key_length]u8 = undefined;
268 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;266 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
269 var tag: [Aes128Ocb.tag_length]u8 = undefined;267 var tag: [Aes128Ocb.tag_length]u8 = undefined;
...@@ -281,8 +279,6 @@ test "AesOcb test vector 1" {...@@ -281,8 +279,6 @@ test "AesOcb test vector 1" {
281}279}
282280
283test "AesOcb test vector 2" {281test "AesOcb test vector 2" {
284 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
285
286 var k: [Aes128Ocb.key_length]u8 = undefined;282 var k: [Aes128Ocb.key_length]u8 = undefined;
287 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;283 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
288 var tag: [Aes128Ocb.tag_length]u8 = undefined;284 var tag: [Aes128Ocb.tag_length]u8 = undefined;
...@@ -303,8 +299,6 @@ test "AesOcb test vector 2" {...@@ -303,8 +299,6 @@ test "AesOcb test vector 2" {
303}299}
304300
305test "AesOcb test vector 3" {301test "AesOcb test vector 3" {
306 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
307
308 var k: [Aes128Ocb.key_length]u8 = undefined;302 var k: [Aes128Ocb.key_length]u8 = undefined;
309 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;303 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
310 var tag: [Aes128Ocb.tag_length]u8 = undefined;304 var tag: [Aes128Ocb.tag_length]u8 = undefined;
...@@ -329,8 +323,6 @@ test "AesOcb test vector 3" {...@@ -329,8 +323,6 @@ test "AesOcb test vector 3" {
329}323}
330324
331test "AesOcb test vector 4" {325test "AesOcb test vector 4" {
332 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
333
334 var k: [Aes128Ocb.key_length]u8 = undefined;326 var k: [Aes128Ocb.key_length]u8 = undefined;
335 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;327 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
336 var tag: [Aes128Ocb.tag_length]u8 = undefined;328 var tag: [Aes128Ocb.tag_length]u8 = undefined;
...@@ -356,8 +348,6 @@ test "AesOcb test vector 4" {...@@ -356,8 +348,6 @@ test "AesOcb test vector 4" {
356}348}
357349
358test "AesOcb in-place encryption-decryption" {350test "AesOcb in-place encryption-decryption" {
359 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
360
361 var k: [Aes128Ocb.key_length]u8 = undefined;351 var k: [Aes128Ocb.key_length]u8 = undefined;
362 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;352 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
363 var tag: [Aes128Ocb.tag_length]u8 = undefined;353 var tag: [Aes128Ocb.tag_length]u8 = undefined;
lib/std/crypto/ecdsa.zig-21
...@@ -1,4 +1,3 @@...@@ -1,4 +1,3 @@
1const builtin = @import("builtin");
2const std = @import("std");1const std = @import("std");
3const crypto = std.crypto;2const crypto = std.crypto;
4const fmt = std.fmt;3const fmt = std.fmt;
...@@ -415,8 +414,6 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {...@@ -415,8 +414,6 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {
415}414}
416415
417test "Basic operations over EcdsaP384Sha384" {416test "Basic operations over EcdsaP384Sha384" {
418 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
419
420 const io = testing.io;417 const io = testing.io;
421 const Scheme = EcdsaP384Sha384;418 const Scheme = EcdsaP384Sha384;
422 const kp = Scheme.KeyPair.generate(io);419 const kp = Scheme.KeyPair.generate(io);
...@@ -432,8 +429,6 @@ test "Basic operations over EcdsaP384Sha384" {...@@ -432,8 +429,6 @@ test "Basic operations over EcdsaP384Sha384" {
432}429}
433430
434test "Basic operations over Secp256k1" {431test "Basic operations over Secp256k1" {
435 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
436
437 const io = testing.io;432 const io = testing.io;
438 const Scheme = EcdsaSecp256k1Sha256oSha256;433 const Scheme = EcdsaSecp256k1Sha256oSha256;
439 const kp = Scheme.KeyPair.generate(io);434 const kp = Scheme.KeyPair.generate(io);
...@@ -449,8 +444,6 @@ test "Basic operations over Secp256k1" {...@@ -449,8 +444,6 @@ test "Basic operations over Secp256k1" {
449}444}
450445
451test "Basic operations over EcdsaP384Sha256" {446test "Basic operations over EcdsaP384Sha256" {
452 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
453
454 const io = testing.io;447 const io = testing.io;
455 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);448 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
456 const kp = Scheme.KeyPair.generate(io);449 const kp = Scheme.KeyPair.generate(io);
...@@ -466,8 +459,6 @@ test "Basic operations over EcdsaP384Sha256" {...@@ -466,8 +459,6 @@ test "Basic operations over EcdsaP384Sha256" {
466}459}
467460
468test "Verifying a existing signature with EcdsaP384Sha256" {461test "Verifying a existing signature with EcdsaP384Sha256" {
469 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
470
471 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);462 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
472 // zig fmt: off463 // zig fmt: off
473 const sk_bytes = [_]u8{464 const sk_bytes = [_]u8{
...@@ -503,8 +494,6 @@ test "Verifying a existing signature with EcdsaP384Sha256" {...@@ -503,8 +494,6 @@ test "Verifying a existing signature with EcdsaP384Sha256" {
503}494}
504495
505test "Prehashed message operations" {496test "Prehashed message operations" {
506 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
507
508 const io = testing.io;497 const io = testing.io;
509498
510 const Scheme = EcdsaP256Sha256;499 const Scheme = EcdsaP256Sha256;
...@@ -539,8 +528,6 @@ const TestVector = struct {...@@ -539,8 +528,6 @@ const TestVector = struct {
539};528};
540529
541test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" {530test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" {
542 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
543
544 const vectors: []const TestVector = &.{531 const vectors: []const TestVector = &.{
545 // well-formed DER encoding -> expected valid532 // well-formed DER encoding -> expected valid
546 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76" },533 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76" },
...@@ -711,8 +698,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" {...@@ -711,8 +698,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" {
711}698}
712699
713test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" {700test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" {
714 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
715
716 const vectors: []const TestVector = &.{701 const vectors: []const TestVector = &.{
717 // S encoded with negative sign -> expected invalid702 // S encoded with negative sign -> expected invalid
718 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db" },703 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db" },
...@@ -1026,8 +1011,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" {...@@ -1026,8 +1011,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" {
1026}1011}
10271012
1028test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" {1013test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" {
1029 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1030
1031 const vectors: []const TestVector = &.{1014 const vectors: []const TestVector = &.{
1032 // canonical sign-bit padding on R; canonical sign-bit padding on S -> expected valid1015 // canonical sign-bit padding on R; canonical sign-bit padding on S -> expected valid
1033 .{ .key = "0429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3", .msg = "4d7367", .sig = "3066023100d7143a836608b25599a7f28dec6635494c2992ad1e2bbeecb7ef601a9c01746e710ce0d9c48accb38a79ede5b9638f3402310080f9e165e8c61035bf8aa7b5533960e46dd0e211c904a064edb6de41f797c0eae4e327612ee3f816f4157272bb4fabc9" },1016 .{ .key = "0429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3", .msg = "4d7367", .sig = "3066023100d7143a836608b25599a7f28dec6635494c2992ad1e2bbeecb7ef601a9c01746e710ce0d9c48accb38a79ede5b9638f3402310080f9e165e8c61035bf8aa7b5533960e46dd0e211c904a064edb6de41f797c0eae4e327612ee3f816f4157272bb4fabc9" },
...@@ -1243,8 +1226,6 @@ test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" {...@@ -1243,8 +1226,6 @@ test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" {
1243}1226}
12441227
1245test "Test vectors from Project Wycheproof - EcdsaP384Sha384 invalid" {1228test "Test vectors from Project Wycheproof - EcdsaP384Sha384 invalid" {
1246 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1247
1248 const vectors: []const TestVector = &.{1229 const vectors: []const TestVector = &.{
1249 // S encoded with negative sign -> expected invalid1230 // S encoded with negative sign -> expected invalid
1250 .{ .key = "042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f", .msg = "313233343030", .sig = "3064023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70230e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82" },1231 .{ .key = "042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f", .msg = "313233343030", .sig = "3064023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70230e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82" },
...@@ -1631,8 +1612,6 @@ fn tvTry(comptime Scheme: type, vector: TestVector) !void {...@@ -1631,8 +1612,6 @@ fn tvTry(comptime Scheme: type, vector: TestVector) !void {
1631}1612}
16321613
1633test "Sec1 encoding/decoding" {1614test "Sec1 encoding/decoding" {
1634 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1635
1636 const io = testing.io;1615 const io = testing.io;
1637 const Scheme = EcdsaP384Sha384;1616 const Scheme = EcdsaP384Sha384;
1638 const kp = Scheme.KeyPair.generate(io);1617 const kp = Scheme.KeyPair.generate(io);
lib/std/crypto/ff.zig-4
...@@ -966,8 +966,6 @@ const ct_unprotected = struct {...@@ -966,8 +966,6 @@ const ct_unprotected = struct {
966};966};
967967
968test "finite field arithmetic" {968test "finite field arithmetic" {
969 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
970
971 const M = Modulus(256);969 const M = Modulus(256);
972 const m = try M.fromPrimitive(u256, 3429938563481314093726330772853735541133072814650493833233);970 const m = try M.fromPrimitive(u256, 3429938563481314093726330772853735541133072814650493833233);
973 var x = try M.Fe.fromPrimitive(u256, m, 80169837251094269539116136208111827396136208141182357733);971 var x = try M.Fe.fromPrimitive(u256, m, 80169837251094269539116136208111827396136208141182357733);
...@@ -1066,8 +1064,6 @@ test "finite field arithmetic" {...@@ -1066,8 +1064,6 @@ test "finite field arithmetic" {
1066}1064}
10671065
1068fn testCt(ct_: anytype) !void {1066fn testCt(ct_: anytype) !void {
1069 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1070
1071 const l0: Limb = 0;1067 const l0: Limb = 0;
1072 const l1: Limb = 1;1068 const l1: Limb = 1;
1073 try testing.expectEqual(l1, ct_.select(true, l1, l0));1069 try testing.expectEqual(l1, ct_.select(true, l1, l0));
lib/std/crypto/pcurves/p384.zig+4-6
...@@ -56,7 +56,7 @@ pub const P384 = struct {...@@ -56,7 +56,7 @@ pub const P384 = struct {
56 }56 }
5757
58 /// Create a point from serialized affine coordinates.58 /// Create a point from serialized affine coordinates.
59 pub fn fromSerializedAffineCoordinates(xs: [48]u8, ys: [48]u8, endian: std.builtin.Endian) (NonCanonicalError || EncodingError)!P384 {59 pub fn fromSerializedAffineCoordinates(xs: [48]u8, ys: [48]u8, endian: std.lang.Endian) (NonCanonicalError || EncodingError)!P384 {
60 const x = try Fe.fromBytes(xs, endian);60 const x = try Fe.fromBytes(xs, endian);
61 const y = try Fe.fromBytes(ys, endian);61 const y = try Fe.fromBytes(ys, endian);
62 return fromAffineCoordinates(.{ .x = x, .y = y });62 return fromAffineCoordinates(.{ .x = x, .y = y });
...@@ -395,7 +395,7 @@ pub const P384 = struct {...@@ -395,7 +395,7 @@ pub const P384 = struct {
395395
396 /// Multiply an elliptic curve point by a scalar.396 /// Multiply an elliptic curve point by a scalar.
397 /// Return error.IdentityElement if the result is the identity element.397 /// Return error.IdentityElement if the result is the identity element.
398 pub fn mul(p: P384, s_: [48]u8, endian: std.builtin.Endian) IdentityElementError!P384 {398 pub fn mul(p: P384, s_: [48]u8, endian: std.lang.Endian) IdentityElementError!P384 {
399 const s = if (endian == .little) s_ else Fe.orderSwap(s_);399 const s = if (endian == .little) s_ else Fe.orderSwap(s_);
400 if (p.is_base) {400 if (p.is_base) {
401 return pcMul16(&basePointPc, s, false);401 return pcMul16(&basePointPc, s, false);
...@@ -407,7 +407,7 @@ pub const P384 = struct {...@@ -407,7 +407,7 @@ pub const P384 = struct {
407407
408 /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME*408 /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME*
409 /// This can be used for signature verification.409 /// This can be used for signature verification.
410 pub fn mulPublic(p: P384, s_: [48]u8, endian: std.builtin.Endian) IdentityElementError!P384 {410 pub fn mulPublic(p: P384, s_: [48]u8, endian: std.lang.Endian) IdentityElementError!P384 {
411 const s = if (endian == .little) s_ else Fe.orderSwap(s_);411 const s = if (endian == .little) s_ else Fe.orderSwap(s_);
412 if (p.is_base) {412 if (p.is_base) {
413 return pcMul16(&basePointPc, s, true);413 return pcMul16(&basePointPc, s, true);
...@@ -419,7 +419,7 @@ pub const P384 = struct {...@@ -419,7 +419,7 @@ pub const P384 = struct {
419419
420 /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME*420 /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME*
421 /// This can be used for signature verification.421 /// This can be used for signature verification.
422 pub fn mulDoubleBasePublic(p1: P384, s1_: [48]u8, p2: P384, s2_: [48]u8, endian: std.builtin.Endian) IdentityElementError!P384 {422 pub fn mulDoubleBasePublic(p1: P384, s1_: [48]u8, p2: P384, s2_: [48]u8, endian: std.lang.Endian) IdentityElementError!P384 {
423 const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_);423 const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_);
424 const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_);424 const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_);
425 try p1.rejectIdentity();425 try p1.rejectIdentity();
...@@ -478,7 +478,5 @@ pub const AffineCoordinates = struct {...@@ -478,7 +478,5 @@ pub const AffineCoordinates = struct {
478};478};
479479
480test {480test {
481 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
482
483 _ = @import("tests/p384.zig");481 _ = @import("tests/p384.zig");
484}482}
lib/std/crypto/pcurves/secp256k1.zig+5-7
...@@ -51,7 +51,7 @@ pub const Secp256k1 = struct {...@@ -51,7 +51,7 @@ pub const Secp256k1 = struct {
51 };51 };
5252
53 /// Compute r1 and r2 so that k = r1 + r2*lambda (mod L).53 /// Compute r1 and r2 so that k = r1 + r2*lambda (mod L).
54 pub fn splitScalar(s: [32]u8, endian: std.builtin.Endian) NonCanonicalError!SplitScalar {54 pub fn splitScalar(s: [32]u8, endian: std.lang.Endian) NonCanonicalError!SplitScalar {
55 const b1_neg_s = comptime s: {55 const b1_neg_s = comptime s: {
56 var buf: [32]u8 = undefined;56 var buf: [32]u8 = undefined;
57 mem.writeInt(u256, &buf, 303414439467246543595250775667605759171, .little);57 mem.writeInt(u256, &buf, 303414439467246543595250775667605759171, .little);
...@@ -109,7 +109,7 @@ pub const Secp256k1 = struct {...@@ -109,7 +109,7 @@ pub const Secp256k1 = struct {
109 }109 }
110110
111 /// Create a point from serialized affine coordinates.111 /// Create a point from serialized affine coordinates.
112 pub fn fromSerializedAffineCoordinates(xs: [32]u8, ys: [32]u8, endian: std.builtin.Endian) (NonCanonicalError || EncodingError)!Secp256k1 {112 pub fn fromSerializedAffineCoordinates(xs: [32]u8, ys: [32]u8, endian: std.lang.Endian) (NonCanonicalError || EncodingError)!Secp256k1 {
113 const x = try Fe.fromBytes(xs, endian);113 const x = try Fe.fromBytes(xs, endian);
114 const y = try Fe.fromBytes(ys, endian);114 const y = try Fe.fromBytes(ys, endian);
115 return fromAffineCoordinates(.{ .x = x, .y = y });115 return fromAffineCoordinates(.{ .x = x, .y = y });
...@@ -423,7 +423,7 @@ pub const Secp256k1 = struct {...@@ -423,7 +423,7 @@ pub const Secp256k1 = struct {
423423
424 /// Multiply an elliptic curve point by a scalar.424 /// Multiply an elliptic curve point by a scalar.
425 /// Return error.IdentityElement if the result is the identity element.425 /// Return error.IdentityElement if the result is the identity element.
426 pub fn mul(p: Secp256k1, s_: [32]u8, endian: std.builtin.Endian) IdentityElementError!Secp256k1 {426 pub fn mul(p: Secp256k1, s_: [32]u8, endian: std.lang.Endian) IdentityElementError!Secp256k1 {
427 const s = if (endian == .little) s_ else Fe.orderSwap(s_);427 const s = if (endian == .little) s_ else Fe.orderSwap(s_);
428 if (p.is_base) {428 if (p.is_base) {
429 return pcMul16(&basePointPc, s, false);429 return pcMul16(&basePointPc, s, false);
...@@ -435,7 +435,7 @@ pub const Secp256k1 = struct {...@@ -435,7 +435,7 @@ pub const Secp256k1 = struct {
435435
436 /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME*436 /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME*
437 /// This can be used for signature verification.437 /// This can be used for signature verification.
438 pub fn mulPublic(p: Secp256k1, s_: [32]u8, endian: std.builtin.Endian) (IdentityElementError || NonCanonicalError)!Secp256k1 {438 pub fn mulPublic(p: Secp256k1, s_: [32]u8, endian: std.lang.Endian) (IdentityElementError || NonCanonicalError)!Secp256k1 {
439 const s = if (endian == .little) s_ else Fe.orderSwap(s_);439 const s = if (endian == .little) s_ else Fe.orderSwap(s_);
440 const zero = comptime scalar.Scalar.zero.toBytes(.little);440 const zero = comptime scalar.Scalar.zero.toBytes(.little);
441 if (mem.eql(u8, &zero, &s)) {441 if (mem.eql(u8, &zero, &s)) {
...@@ -497,7 +497,7 @@ pub const Secp256k1 = struct {...@@ -497,7 +497,7 @@ pub const Secp256k1 = struct {
497497
498 /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME*498 /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME*
499 /// This can be used for signature verification.499 /// This can be used for signature verification.
500 pub fn mulDoubleBasePublic(p1: Secp256k1, s1_: [32]u8, p2: Secp256k1, s2_: [32]u8, endian: std.builtin.Endian) IdentityElementError!Secp256k1 {500 pub fn mulDoubleBasePublic(p1: Secp256k1, s1_: [32]u8, p2: Secp256k1, s2_: [32]u8, endian: std.lang.Endian) IdentityElementError!Secp256k1 {
501 const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_);501 const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_);
502 const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_);502 const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_);
503 try p1.rejectIdentity();503 try p1.rejectIdentity();
...@@ -556,7 +556,5 @@ pub const AffineCoordinates = struct {...@@ -556,7 +556,5 @@ pub const AffineCoordinates = struct {
556};556};
557557
558test {558test {
559 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
560
561 _ = @import("tests/secp256k1.zig");559 _ = @import("tests/secp256k1.zig");
562}560}
lib/std/debug/cpu_context.zig+2
...@@ -2020,6 +2020,8 @@ const signal_ucontext_t = switch (native_os) {...@@ -2020,6 +2020,8 @@ const signal_ucontext_t = switch (native_os) {
2020 .mips64el,2020 .mips64el,
2021 .or1k,2021 .or1k,
2022 .s390x,2022 .s390x,
2023 .sh,
2024 .sheb,
2023 .x86,2025 .x86,
2024 .x86_64,2026 .x86_64,
2025 .xtensa,2027 .xtensa,
lib/std/fmt.zig-2
...@@ -1082,8 +1082,6 @@ test "float.libc.sanity" {...@@ -1082,8 +1082,6 @@ test "float.libc.sanity" {
1082}1082}
10831083
1084test "union" {1084test "union" {
1085 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1086
1087 const TU = union(enum) {1085 const TU = union(enum) {
1088 float: f32,1086 float: f32,
1089 int: u32,1087 int: u32,
lib/std/fmt/float.zig+1-1
...@@ -65,7 +65,7 @@ pub fn render(buf: []u8, value: anytype, options: Options) Error![]const u8 {...@@ -65,7 +65,7 @@ pub fn render(buf: []u8, value: anytype, options: Options) Error![]const u8 {
6565
66 const DT = if (@bitSizeOf(T) <= 64) u64 else u128;66 const DT = if (@bitSizeOf(T) <= 64) u64 else u128;
67 const tables = switch (DT) {67 const tables = switch (DT) {
68 u64 => if (@import("builtin").mode == .small) &Backend64_TablesSmall else &Backend64_TablesFull,68 u64 => if (builtin.mode == .small) &Backend64_TablesSmall else &Backend64_TablesFull,
69 u128 => &Backend128_Tables,69 u128 => &Backend128_Tables,
70 else => unreachable,70 else => unreachable,
71 };71 };
lib/std/fs/test.zig+2-3
...@@ -2205,7 +2205,7 @@ test "'.' and '..' in absolute functions" {...@@ -2205,7 +2205,7 @@ test "'.' and '..' in absolute functions" {
2205}2205}
22062206
2207test "chmod" {2207test "chmod" {
2208 if (native_os == .windows or native_os == .wasi) return;2208 if (native_os == .windows or native_os == .wasi) return error.SkipZigTest;
22092209
2210 const io = testing.io;2210 const io = testing.io;
22112211
...@@ -2228,8 +2228,7 @@ test "chmod" {...@@ -2228,8 +2228,7 @@ test "chmod" {
2228}2228}
22292229
2230test "change ownership" {2230test "change ownership" {
2231 if (native_os == .windows or native_os == .wasi)2231 if (native_os == .windows or native_os == .wasi) return error.SkipZigTest;
2232 return error.SkipZigTest;
22332232
2234 const io = testing.io;2233 const io = testing.io;
22352234
lib/std/hash/auto_hash.zig+1-1
...@@ -225,7 +225,7 @@ fn testHashDeepRecursive(key: anytype) u64 {...@@ -225,7 +225,7 @@ fn testHashDeepRecursive(key: anytype) u64 {
225225
226test "typeContainsSlice" {226test "typeContainsSlice" {
227 comptime {227 comptime {
228 try testing.expect(!typeContainsSlice(std.meta.Tag(std.builtin.Type)));228 try testing.expect(!typeContainsSlice(std.meta.Tag(std.lang.Type)));
229229
230 try testing.expect(typeContainsSlice([]const u8));230 try testing.expect(typeContainsSlice([]const u8));
231 try testing.expect(!typeContainsSlice(u8));231 try testing.expect(!typeContainsSlice(u8));
lib/std/hash/xxhash.zig-4
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");
3const mem = std.mem;2const mem = std.mem;
4const expectEqual = std.testing.expectEqual;3const expectEqual = std.testing.expectEqual;
54
...@@ -788,7 +787,6 @@ fn testExpect(comptime H: type, seed: anytype, input: []const u8, expected: u64)...@@ -788,7 +787,6 @@ fn testExpect(comptime H: type, seed: anytype, input: []const u8, expected: u64)
788}787}
789788
790test "xxhash3" {789test "xxhash3" {
791 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
792 const H = XxHash3;790 const H = XxHash3;
793 // Non-Seeded Tests791 // Non-Seeded Tests
794 try testExpect(H, 0, "", 0x2d06800538d394c2);792 try testExpect(H, 0, "", 0x2d06800538d394c2);
...@@ -820,7 +818,6 @@ test "xxhash3" {...@@ -820,7 +818,6 @@ test "xxhash3" {
820}818}
821819
822test "xxhash3 smhasher" {820test "xxhash3 smhasher" {
823 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
824 const Test = struct {821 const Test = struct {
825 fn do() !void {822 fn do() !void {
826 try expectEqual(verify.smhasher(XxHash3.hash), 0x9a636405);823 try expectEqual(verify.smhasher(XxHash3.hash), 0x9a636405);
...@@ -832,7 +829,6 @@ test "xxhash3 smhasher" {...@@ -832,7 +829,6 @@ test "xxhash3 smhasher" {
832}829}
833830
834test "xxhash3 iterative api" {831test "xxhash3 iterative api" {
835 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
836 const Test = struct {832 const Test = struct {
837 fn do() !void {833 fn do() !void {
838 try verify.iterativeApi(XxHash3);834 try verify.iterativeApi(XxHash3);
lib/std/hash_map.zig+1-1
...@@ -1518,7 +1518,7 @@ fn Custom(...@@ -1518,7 +1518,7 @@ fn Custom(
1518 self.available = 0;1518 self.available = 0;
1519 }1519 }
15201520
1521 /// This function is used in the debugger pretty formatters in tools/ to fetch the1521 /// This function is used in the debugger pretty formatters in lib/lldb/ to fetch the
1522 /// header type to facilitate fancy debug printing for this type.1522 /// header type to facilitate fancy debug printing for this type.
1523 fn dbHelper(self: *Self, hdr: *Header, entry: *Entry) void {1523 fn dbHelper(self: *Self, hdr: *Header, entry: *Entry) void {
1524 _ = self;1524 _ = self;
lib/std/http/test.zig+1-20
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const native_endian = builtin.cpu.arch.endian();
32
4const std = @import("std");3const std = @import("std");
5const http = std.http;4const http = std.http;
...@@ -34,7 +33,6 @@ test "content length reader state update" {...@@ -34,7 +33,6 @@ test "content length reader state update" {
34}33}
3534
36test "trailers" {35test "trailers" {
37 if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257
38 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/3080636 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806
3937
40 const io = std.testing.io;38 const io = std.testing.io;
...@@ -121,7 +119,6 @@ test "trailers" {...@@ -121,7 +119,6 @@ test "trailers" {
121}119}
122120
123test "HTTP server handles a chunked transfer coding request" {121test "HTTP server handles a chunked transfer coding request" {
124 if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257
125 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806122 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806
126123
127 const io = std.testing.io;124 const io = std.testing.io;
...@@ -190,7 +187,6 @@ test "HTTP server handles a chunked transfer coding request" {...@@ -190,7 +187,6 @@ test "HTTP server handles a chunked transfer coding request" {
190}187}
191188
192test "echo content server" {189test "echo content server" {
193 if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257
194 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806190 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806
195191
196 const io = std.testing.io;192 const io = std.testing.io;
...@@ -281,12 +277,11 @@ test "echo content server" {...@@ -281,12 +277,11 @@ test "echo content server" {
281}277}
282278
283test "Server.Request.respondStreaming non-chunked, unknown content-length" {279test "Server.Request.respondStreaming non-chunked, unknown content-length" {
284 if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257
285 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806280 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806
286281
287 const io = std.testing.io;282 const io = std.testing.io;
288283
289 if (builtin.os.tag == .windows) {284 if (builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows) {
290 // https://github.com/ziglang/zig/issues/21457285 // https://github.com/ziglang/zig/issues/21457
291 return error.SkipZigTest;286 return error.SkipZigTest;
292 }287 }
...@@ -360,7 +355,6 @@ test "Server.Request.respondStreaming non-chunked, unknown content-length" {...@@ -360,7 +355,6 @@ test "Server.Request.respondStreaming non-chunked, unknown content-length" {
360}355}
361356
362test "receiving arbitrary http headers from the client" {357test "receiving arbitrary http headers from the client" {
363 if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257
364 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806358 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806
365359
366 const io = std.testing.io;360 const io = std.testing.io;
...@@ -426,16 +420,10 @@ test "receiving arbitrary http headers from the client" {...@@ -426,16 +420,10 @@ test "receiving arbitrary http headers from the client" {
426}420}
427421
428test "general client/server API coverage" {422test "general client/server API coverage" {
429 if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257
430 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806423 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806
431424
432 const io = std.testing.io;425 const io = std.testing.io;
433426
434 if (builtin.os.tag == .windows) {
435 // This test was never passing on Windows.
436 return error.SkipZigTest;
437 }
438
439 const test_server = try createTestServer(io, struct {427 const test_server = try createTestServer(io, struct {
440 fn run(test_server: *TestServer) anyerror!void {428 fn run(test_server: *TestServer) anyerror!void {
441 const net_server = &test_server.net_server;429 const net_server = &test_server.net_server;
...@@ -922,7 +910,6 @@ test "general client/server API coverage" {...@@ -922,7 +910,6 @@ test "general client/server API coverage" {
922}910}
923911
924test "Server streams both reading and writing" {912test "Server streams both reading and writing" {
925 if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257
926 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806913 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806
927914
928 const io = std.testing.io;915 const io = std.testing.io;
...@@ -1162,10 +1149,6 @@ const TestServer = struct {...@@ -1162,10 +1149,6 @@ const TestServer = struct {
11621149
1163fn createTestServer(io: Io, S: type) !*TestServer {1150fn createTestServer(io: Io, S: type) !*TestServer {
1164 if (builtin.single_threaded) return error.SkipZigTest;1151 if (builtin.single_threaded) return error.SkipZigTest;
1165 if (builtin.zig_backend == .stage2_llvm and native_endian == .big) {
1166 // https://github.com/ziglang/zig/issues/13782
1167 return error.SkipZigTest;
1168 }
11691152
1170 const address = try net.IpAddress.parse("127.0.0.1", 0);1153 const address = try net.IpAddress.parse("127.0.0.1", 0);
11711154
...@@ -1192,7 +1175,6 @@ fn createTestServer(io: Io, S: type) !*TestServer {...@@ -1192,7 +1175,6 @@ fn createTestServer(io: Io, S: type) !*TestServer {
1192}1175}
11931176
1194test "redirect to different connection" {1177test "redirect to different connection" {
1195 if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257
1196 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/308061178 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806
11971179
1198 const io = std.testing.io;1180 const io = std.testing.io;
...@@ -1280,7 +1262,6 @@ test "redirect to different connection" {...@@ -1280,7 +1262,6 @@ test "redirect to different connection" {
1280}1262}
12811263
1282test "boot failed connections from the pool" {1264test "boot failed connections from the pool" {
1283 if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257
1284 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/308061265 if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806
12851266
1286 const io = std.testing.io;1267 const io = std.testing.io;
lib/std/lang.zig+1
...@@ -214,6 +214,7 @@ pub const CallingConvention = union(enum(u8)) {...@@ -214,6 +214,7 @@ pub const CallingConvention = union(enum(u8)) {
214 // Calling conventions for the `x86` architecture.214 // Calling conventions for the `x86` architecture.
215 x86_sysv: X86RegparmOptions,215 x86_sysv: X86RegparmOptions,
216 x86_win: X86RegparmOptions,216 x86_win: X86RegparmOptions,
217 x86_mingw: X86RegparmOptions,
217 x86_stdcall: X86RegparmOptions,218 x86_stdcall: X86RegparmOptions,
218 x86_fastcall: CommonOptions,219 x86_fastcall: CommonOptions,
219 x86_thiscall: CommonOptions,220 x86_thiscall: CommonOptions,
lib/std/math.zig+5-4
...@@ -75,7 +75,7 @@ pub const snan = float.snan;...@@ -75,7 +75,7 @@ pub const snan = float.snan;
75///75///
76/// NaN values are never considered equal to any value.76/// NaN values are never considered equal to any value.
77pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool {77pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool {
78 assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float);78 comptime assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float);
79 assert(tolerance >= 0);79 assert(tolerance >= 0);
8080
81 // Fast path for equal values (and signed zeros and infinites).81 // Fast path for equal values (and signed zeros and infinites).
...@@ -103,7 +103,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool {...@@ -103,7 +103,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool {
103///103///
104/// NaN values are never considered equal to any value.104/// NaN values are never considered equal to any value.
105pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool {105pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool {
106 assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float);106 comptime assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float);
107 assert(tolerance > 0);107 assert(tolerance > 0);
108108
109 // Fast path for equal values (and signed zeros and infinites).109 // Fast path for equal values (and signed zeros and infinites).
...@@ -461,7 +461,7 @@ pub fn wrap(x: anytype, r: anytype) @TypeOf(x) {...@@ -461,7 +461,7 @@ pub fn wrap(x: anytype, r: anytype) @TypeOf(x) {
461 }461 }
462}462}
463test wrap {463test wrap {
464 if (builtin.os.tag == .windows and builtin.cpu.arch == .x86) {464 if (builtin.os.tag == .windows and builtin.cpu.arch == .x86 and builtin.abi == .msvc) {
465 // https://codeberg.org/ziglang/zig/issues/35520465 // https://codeberg.org/ziglang/zig/issues/35520
466 return error.SkipZigTest;466 return error.SkipZigTest;
467 }467 }
...@@ -1385,7 +1385,8 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) {...@@ -1385,7 +1385,8 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) {
1385}1385}
13861386
1387test lerp {1387test lerp {
1388 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/178841388 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1389 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isX86()) return error.SkipZigTest;
1389 if (builtin.zig_backend == .stage2_x86_64 and !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/178841390 if (builtin.zig_backend == .stage2_x86_64 and !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884
13901391
1391 try testing.expectEqual(@as(f64, 75), lerp(50, 100, 0.5));1392 try testing.expectEqual(@as(f64, 75), lerp(50, 100, 0.5));
lib/std/math/acos.zig-4
...@@ -337,8 +337,6 @@ fn acosBinary128(x: f128) f128 {...@@ -337,8 +337,6 @@ fn acosBinary128(x: f128) f128 {
337}337}
338338
339test "acosBinary16.special" {339test "acosBinary16.special" {
340 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
341
342 try testing.expectApproxEqAbs(0x1.92p0, acosBinary16(0x0p+0), math.floatEpsAt(f16, 0x1.92p0));340 try testing.expectApproxEqAbs(0x1.92p0, acosBinary16(0x0p+0), math.floatEpsAt(f16, 0x1.92p0));
343 try testing.expectApproxEqAbs(0x1.92p1, acosBinary16(-0x1p+0), math.floatEpsAt(f16, 0x1.92p1));341 try testing.expectApproxEqAbs(0x1.92p1, acosBinary16(-0x1p+0), math.floatEpsAt(f16, 0x1.92p1));
344 try testing.expectEqual(0x0p+0, acosBinary16(0x1p+0));342 try testing.expectEqual(0x0p+0, acosBinary16(0x1p+0));
...@@ -350,8 +348,6 @@ test "acosBinary16.special" {...@@ -350,8 +348,6 @@ test "acosBinary16.special" {
350}348}
351349
352test "acosBinary16" {350test "acosBinary16" {
353 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
354
355 try testing.expectApproxEqAbs(0x1.834p0, acosBinary16(0x1.db4p-5), math.floatEpsAt(f16, 0x1.834p0));351 try testing.expectApproxEqAbs(0x1.834p0, acosBinary16(0x1.db4p-5), math.floatEpsAt(f16, 0x1.834p0));
356 try testing.expectApproxEqAbs(0x1.d48p0, acosBinary16(-0x1.068p-2), math.floatEpsAt(f16, 0x1.d48p0));352 try testing.expectApproxEqAbs(0x1.d48p0, acosBinary16(-0x1.068p-2), math.floatEpsAt(f16, 0x1.d48p0));
357 try testing.expectApproxEqAbs(0x1.b7cp0, acosBinary16(-0x1.2c4p-3), math.floatEpsAt(f16, 0x1.b7cp0));353 try testing.expectApproxEqAbs(0x1.b7cp0, acosBinary16(-0x1.2c4p-3), math.floatEpsAt(f16, 0x1.b7cp0));
lib/std/math/asin.zig-4
...@@ -326,8 +326,6 @@ fn asinBinary128(x: f128) f128 {...@@ -326,8 +326,6 @@ fn asinBinary128(x: f128) f128 {
326}326}
327327
328test "asinBinary16.special" {328test "asinBinary16.special" {
329 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
330
331 try testing.expectApproxEqAbs(0x1.92p0, asinBinary16(0x1p+0), math.floatEpsAt(f16, 0x1.92p0));329 try testing.expectApproxEqAbs(0x1.92p0, asinBinary16(0x1p+0), math.floatEpsAt(f16, 0x1.92p0));
332 try testing.expectApproxEqAbs(-0x1.92p0, asinBinary16(-0x1p+0), math.floatEpsAt(f16, -0x1.92p0));330 try testing.expectApproxEqAbs(-0x1.92p0, asinBinary16(-0x1p+0), math.floatEpsAt(f16, -0x1.92p0));
333 try testing.expectEqual(0x0p+0, asinBinary16(0x0p+0));331 try testing.expectEqual(0x0p+0, asinBinary16(0x0p+0));
...@@ -340,8 +338,6 @@ test "asinBinary16.special" {...@@ -340,8 +338,6 @@ test "asinBinary16.special" {
340}338}
341339
342test "asinBinary16" {340test "asinBinary16" {
343 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
344
345 try testing.expectApproxEqAbs(-0x1.e4cp-6, asinBinary16(-0x1.e4cp-6), math.floatEpsAt(f16, -0x1.e4cp-6));341 try testing.expectApproxEqAbs(-0x1.e4cp-6, asinBinary16(-0x1.e4cp-6), math.floatEpsAt(f16, -0x1.e4cp-6));
346 try testing.expectApproxEqAbs(0x1.2a8p0, asinBinary16(0x1.d68p-1), math.floatEpsAt(f16, 0x1.2a8p0));342 try testing.expectApproxEqAbs(0x1.2a8p0, asinBinary16(0x1.d68p-1), math.floatEpsAt(f16, 0x1.2a8p0));
347 try testing.expectApproxEqAbs(-0x1.eep-1, asinBinary16(-0x1.a4cp-1), math.floatEpsAt(f16, -0x1.eep-1));343 try testing.expectApproxEqAbs(-0x1.eep-1, asinBinary16(-0x1.a4cp-1), math.floatEpsAt(f16, -0x1.eep-1));
lib/std/math/atan.zig-4
...@@ -481,8 +481,6 @@ fn atanBinary128(x: f128) f128 {...@@ -481,8 +481,6 @@ fn atanBinary128(x: f128) f128 {
481}481}
482482
483test "atanBinary16.special" {483test "atanBinary16.special" {
484 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
485
486 try testing.expectEqual(0x0p+0, atanBinary16(0x0p+0));484 try testing.expectEqual(0x0p+0, atanBinary16(0x0p+0));
487 try testing.expectEqual(-0x0p+0, atanBinary16(-0x0p+0));485 try testing.expectEqual(-0x0p+0, atanBinary16(-0x0p+0));
488 try testing.expectApproxEqAbs(0x1.92p-1, atanBinary16(0x1p+0), math.floatEpsAt(f16, 0x1.92p-1));486 try testing.expectApproxEqAbs(0x1.92p-1, atanBinary16(0x1p+0), math.floatEpsAt(f16, 0x1.92p-1));
...@@ -493,8 +491,6 @@ test "atanBinary16.special" {...@@ -493,8 +491,6 @@ test "atanBinary16.special" {
493}491}
494492
495test "atanBinary16" {493test "atanBinary16" {
496 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
497
498 try testing.expectApproxEqAbs(-0x1.74cp-2, atanBinary16(-0x1.864p-2), math.floatEpsAt(f16, -0x1.74cp-2));494 try testing.expectApproxEqAbs(-0x1.74cp-2, atanBinary16(-0x1.864p-2), math.floatEpsAt(f16, -0x1.74cp-2));
499 try testing.expectApproxEqAbs(-0x1.374p0, atanBinary16(-0x1.59cp1), math.floatEpsAt(f16, -0x1.374p0));495 try testing.expectApproxEqAbs(-0x1.374p0, atanBinary16(-0x1.59cp1), math.floatEpsAt(f16, -0x1.374p0));
500 try testing.expectApproxEqAbs(-0x1.11cp0, atanBinary16(-0x1.d2cp0), math.floatEpsAt(f16, -0x1.11cp0));496 try testing.expectApproxEqAbs(-0x1.11cp0, atanBinary16(-0x1.d2cp0), math.floatEpsAt(f16, -0x1.11cp0));
lib/std/math/atan2.zig+4-4
...@@ -252,8 +252,8 @@ test "atan2_32.special" {...@@ -252,8 +252,8 @@ test "atan2_32.special" {
252252
253 try expect(math.isNan(atan2_32(1.0, math.nan(f32))));253 try expect(math.isNan(atan2_32(1.0, math.nan(f32))));
254 try expect(math.isNan(atan2_32(math.nan(f32), 1.0)));254 try expect(math.isNan(atan2_32(math.nan(f32), 1.0)));
255 try expect(atan2_32(0.0, 5.0) == 0.0);255 try expect(math.isPositiveZero(atan2_32(0.0, 5.0)));
256 try expect(atan2_32(-0.0, 5.0) == -0.0);256 try expect(math.isNegativeZero(atan2_32(-0.0, 5.0)));
257 try expect(math.approxEqAbs(f32, atan2_32(0.0, -5.0), math.pi, epsilon));257 try expect(math.approxEqAbs(f32, atan2_32(0.0, -5.0), math.pi, epsilon));
258 //expect(math.approxEqAbs(f32, atan2_32(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?258 //expect(math.approxEqAbs(f32, atan2_32(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?
259 try expect(math.approxEqAbs(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon));259 try expect(math.approxEqAbs(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon));
...@@ -276,8 +276,8 @@ test "atan2_64.special" {...@@ -276,8 +276,8 @@ test "atan2_64.special" {
276276
277 try expect(math.isNan(atan2_64(1.0, math.nan(f64))));277 try expect(math.isNan(atan2_64(1.0, math.nan(f64))));
278 try expect(math.isNan(atan2_64(math.nan(f64), 1.0)));278 try expect(math.isNan(atan2_64(math.nan(f64), 1.0)));
279 try expect(atan2_64(0.0, 5.0) == 0.0);279 try expect(math.isPositiveZero(atan2_64(0.0, 5.0)));
280 try expect(atan2_64(-0.0, 5.0) == -0.0);280 try expect(math.isNegativeZero(atan2_64(-0.0, 5.0)));
281 try expect(math.approxEqAbs(f64, atan2_64(0.0, -5.0), math.pi, epsilon));281 try expect(math.approxEqAbs(f64, atan2_64(0.0, -5.0), math.pi, epsilon));
282 //expect(math.approxEqAbs(f64, atan2_64(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?282 //expect(math.approxEqAbs(f64, atan2_64(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?
283 try expect(math.approxEqAbs(f64, atan2_64(1.0, 0.0), math.pi / 2.0, epsilon));283 try expect(math.approxEqAbs(f64, atan2_64(1.0, 0.0), math.pi / 2.0, epsilon));
lib/std/math/big/int_test.zig+1-38
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1const std = @import("../../std.zig");1const std = @import("../../std.zig");
2const builtin = @import("builtin");
3const mem = std.mem;2const mem = std.mem;
4const testing = std.testing;3const testing = std.testing;
5const Managed = std.math.big.int.Managed;4const Managed = std.math.big.int.Managed;
...@@ -276,8 +275,6 @@ fn setFloat(comptime Float: type) !void {...@@ -276,8 +275,6 @@ fn setFloat(comptime Float: type) !void {
276 try expectNormalized(1 << 10, res.toConst());275 try expectNormalized(1 << 10, res.toConst());
277}276}
278test setFloat {277test setFloat {
279 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
280
281 try setFloat(f16);278 try setFloat(f16);
282 try setFloat(f32);279 try setFloat(f32);
283 try setFloat(f64);280 try setFloat(f64);
...@@ -484,7 +481,6 @@ fn toFloat(comptime Float: type) !void {...@@ -484,7 +481,6 @@ fn toFloat(comptime Float: type) !void {
484 );481 );
485}482}
486test toFloat {483test toFloat {
487 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
488 try toFloat(f16);484 try toFloat(f16);
489 try toFloat(f32);485 try toFloat(f32);
490 try toFloat(f64);486 try toFloat(f64);
...@@ -1391,8 +1387,6 @@ test "mul multi-single" {...@@ -1391,8 +1387,6 @@ test "mul multi-single" {
1391}1387}
13921388
1393test "mul multi-multi" {1389test "mul multi-multi" {
1394 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1395
1396 var op1: u256 = 0x998888efefefefefefefef;1390 var op1: u256 = 0x998888efefefefefefefef;
1397 var op2: u256 = 0x333000abababababababab;1391 var op2: u256 = 0x333000abababababababab;
1398 _ = .{ &op1, &op2 };1392 _ = .{ &op1, &op2 };
...@@ -1514,8 +1508,6 @@ test "mulWrap single-single signed" {...@@ -1514,8 +1508,6 @@ test "mulWrap single-single signed" {
1514}1508}
15151509
1516test "mulWrap multi-multi unsigned" {1510test "mulWrap multi-multi unsigned" {
1517 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1518
1519 var op1: u256 = 0x998888efefefefefefefef;1511 var op1: u256 = 0x998888efefefefefefefef;
1520 var op2: u256 = 0x333000abababababababab;1512 var op2: u256 = 0x333000abababababababab;
1521 _ = .{ &op1, &op2 };1513 _ = .{ &op1, &op2 };
...@@ -1533,11 +1525,6 @@ test "mulWrap multi-multi unsigned" {...@@ -1533,11 +1525,6 @@ test "mulWrap multi-multi unsigned" {
1533}1525}
15341526
1535test "mulWrap multi-multi signed" {1527test "mulWrap multi-multi signed" {
1536 switch (builtin.zig_backend) {
1537 .stage2_c => return error.SkipZigTest,
1538 else => {},
1539 }
1540
1541 var a = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb) - 1);1528 var a = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb) - 1);
1542 defer a.deinit();1529 defer a.deinit();
1543 var b = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb));1530 var b = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb));
...@@ -1744,8 +1731,6 @@ test "div q=0 alias" {...@@ -1744,8 +1731,6 @@ test "div q=0 alias" {
1744}1731}
17451732
1746test "div multi-multi q < r" {1733test "div multi-multi q < r" {
1747 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1748
1749 const op1 = 0x1ffffffff0078f432;1734 const op1 = 0x1ffffffff0078f432;
1750 const op2 = 0x1ffffffff01000000;1735 const op2 = 0x1ffffffff01000000;
1751 var a = try Managed.initSet(testing.allocator, op1);1736 var a = try Managed.initSet(testing.allocator, op1);
...@@ -2166,8 +2151,6 @@ test "div ceil multi-limb" {...@@ -2166,8 +2151,6 @@ test "div ceil multi-limb" {
2166}2151}
21672152
2168test "div multi-multi with rem" {2153test "div multi-multi with rem" {
2169 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2170
2171 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);2154 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);
2172 defer a.deinit();2155 defer a.deinit();
2173 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);2156 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
...@@ -2184,8 +2167,6 @@ test "div multi-multi with rem" {...@@ -2184,8 +2167,6 @@ test "div multi-multi with rem" {
2184}2167}
21852168
2186test "div multi-multi no rem" {2169test "div multi-multi no rem" {
2187 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2188
2189 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);2170 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);
2190 defer a.deinit();2171 defer a.deinit();
2191 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);2172 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
...@@ -2202,8 +2183,6 @@ test "div multi-multi no rem" {...@@ -2202,8 +2183,6 @@ test "div multi-multi no rem" {
2202}2183}
22032184
2204test "div multi-multi (2 branch)" {2185test "div multi-multi (2 branch)" {
2205 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2206
2207 var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111);2186 var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111);
2208 defer a.deinit();2187 defer a.deinit();
2209 var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333);2188 var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333);
...@@ -2220,8 +2199,6 @@ test "div multi-multi (2 branch)" {...@@ -2220,8 +2199,6 @@ test "div multi-multi (2 branch)" {
2220}2199}
22212200
2222test "div multi-multi (3.1/3.3 branch)" {2201test "div multi-multi (3.1/3.3 branch)" {
2223 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2224
2225 var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111);2202 var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111);
2226 defer a.deinit();2203 defer a.deinit();
2227 var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171);2204 var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171);
...@@ -2238,8 +2215,6 @@ test "div multi-multi (3.1/3.3 branch)" {...@@ -2238,8 +2215,6 @@ test "div multi-multi (3.1/3.3 branch)" {
2238}2215}
22392216
2240test "div multi-single zero-limb trailing" {2217test "div multi-single zero-limb trailing" {
2241 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2242
2243 var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000);2218 var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000);
2244 defer a.deinit();2219 defer a.deinit();
2245 var b = try Managed.initSet(testing.allocator, 0x10000000000000000);2220 var b = try Managed.initSet(testing.allocator, 0x10000000000000000);
...@@ -2258,8 +2233,6 @@ test "div multi-single zero-limb trailing" {...@@ -2258,8 +2233,6 @@ test "div multi-single zero-limb trailing" {
2258}2233}
22592234
2260test "div multi-multi zero-limb trailing (with rem)" {2235test "div multi-multi zero-limb trailing (with rem)" {
2261 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2262
2263 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);2236 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
2264 defer a.deinit();2237 defer a.deinit();
2265 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);2238 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
...@@ -2279,8 +2252,6 @@ test "div multi-multi zero-limb trailing (with rem)" {...@@ -2279,8 +2252,6 @@ test "div multi-multi zero-limb trailing (with rem)" {
2279}2252}
22802253
2281test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {2254test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {
2282 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2283
2284 var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000);2255 var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000);
2285 defer a.deinit();2256 defer a.deinit();
2286 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);2257 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
...@@ -2300,8 +2271,6 @@ test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count...@@ -2300,8 +2271,6 @@ test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count
2300}2271}
23012272
2302test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {2273test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {
2303 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2304
2305 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);2274 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
2306 defer a.deinit();2275 defer a.deinit();
2307 var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000);2276 var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000);
...@@ -2832,10 +2801,6 @@ test "bitNotWrap signed multi" {...@@ -2832,10 +2801,6 @@ test "bitNotWrap signed multi" {
2832}2801}
28332802
2834test "bitNotWrap more than two limbs" {2803test "bitNotWrap more than two limbs" {
2835 // This test requires int sizes greater than 128 bits.
2836 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
2837 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2838
2839 var a = try Managed.initSet(testing.allocator, maxInt(Limb));2804 var a = try Managed.initSet(testing.allocator, maxInt(Limb));
2840 defer a.deinit();2805 defer a.deinit();
28412806
...@@ -3179,8 +3144,6 @@ test "gcd non-one large" {...@@ -3179,8 +3144,6 @@ test "gcd non-one large" {
3179}3144}
31803145
3181test "gcd large multi-limb result" {3146test "gcd large multi-limb result" {
3182 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
3183
3184 var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678);3147 var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678);
3185 defer a.deinit();3148 defer a.deinit();
3186 var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567);3149 var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567);
...@@ -3431,7 +3394,7 @@ test "big int conversion read/write twos complement" {...@@ -3431,7 +3394,7 @@ test "big int conversion read/write twos complement" {
3431 var buffer1 = try testing.allocator.alloc(u8, 64);3394 var buffer1 = try testing.allocator.alloc(u8, 64);
3432 defer testing.allocator.free(buffer1);3395 defer testing.allocator.free(buffer1);
34333396
3434 const endians = [_]std.builtin.Endian{ .little, .big };3397 const endians = [_]std.lang.Endian{ .little, .big };
3435 const abi_size = 64;3398 const abi_size = 64;
34363399
3437 for (endians) |endian| {3400 for (endians) |endian| {
lib/std/math/gamma.zig-2
...@@ -263,8 +263,6 @@ test gamma {...@@ -263,8 +263,6 @@ test gamma {
263}263}
264264
265test "gamma.special" {265test "gamma.special" {
266 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
267
268 inline for (&.{ f32, f64 }) |T| {266 inline for (&.{ f32, f64 }) |T| {
269 try expect(std.math.isNan(gamma(T, -std.math.nan(T))));267 try expect(std.math.isNan(gamma(T, -std.math.nan(T))));
270 try expect(std.math.isNan(gamma(T, std.math.nan(T))));268 try expect(std.math.isNan(gamma(T, std.math.nan(T))));
lib/std/math/hypot.zig-9
...@@ -1,4 +1,3 @@...@@ -1,4 +1,3 @@
1const builtin = @import("builtin");
2const std = @import("../std.zig");1const std = @import("../std.zig");
3const math = std.math;2const math = std.math;
4const expect = std.testing.expect;3const expect = std.testing.expect;
...@@ -93,14 +92,10 @@ const hypot_test_cases = .{...@@ -93,14 +92,10 @@ const hypot_test_cases = .{
93};92};
9493
95test hypot {94test hypot {
96 if (builtin.cpu.arch.isPowerPC() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/171869
97 try expect(hypot(0.3, 0.4) == 0.5);95 try expect(hypot(0.3, 0.4) == 0.5);
98}96}
9997
100test "hypot.correct" {98test "hypot.correct" {
101 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
102 if (builtin.cpu.arch.isPowerPC() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/171869
103
104 inline for (.{ f16, f32, f64, f128 }) |T| {99 inline for (.{ f16, f32, f64, f128 }) |T| {
105 inline for (hypot_test_cases) |v| {100 inline for (hypot_test_cases) |v| {
106 const a: T, const b: T, const c: T = v;101 const a: T, const b: T, const c: T = v;
...@@ -110,9 +105,6 @@ test "hypot.correct" {...@@ -110,9 +105,6 @@ test "hypot.correct" {
110}105}
111106
112test "hypot.precise" {107test "hypot.precise" {
113 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
114 if (builtin.cpu.arch.isPowerPC() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/171869
115
116 inline for (.{ f16, f32, f64 }) |T| { // f128 seems to be 5 ulp108 inline for (.{ f16, f32, f64 }) |T| { // f128 seems to be 5 ulp
117 inline for (hypot_test_cases) |v| {109 inline for (hypot_test_cases) |v| {
118 const a: T, const b: T, const c: T = v;110 const a: T, const b: T, const c: T = v;
...@@ -122,7 +114,6 @@ test "hypot.precise" {...@@ -122,7 +114,6 @@ test "hypot.precise" {
122}114}
123115
124test "hypot.special" {116test "hypot.special" {
125 if (builtin.cpu.arch.isPowerPC() and builtin.mode != .debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/171869
126 @setEvalBranchQuota(2000);117 @setEvalBranchQuota(2000);
127 inline for (.{ f16, f32, f64, f128 }) |T| {118 inline for (.{ f16, f32, f64, f128 }) |T| {
128 try expect(math.isNan(hypot(nan(T), 0.0)));119 try expect(math.isNan(hypot(nan(T), 0.0)));
lib/std/math/isnan.zig+1-7
...@@ -27,13 +27,6 @@ test isNan {...@@ -27,13 +27,6 @@ test isNan {
27}27}
2828
29test isSignalNan {29test isSignalNan {
30 if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;
31
32 if (builtin.os.tag == .windows) {
33 // https://codeberg.org/ziglang/zig/issues/35519
34 return error.SkipZigTest;
35 }
36
37 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {30 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
38 // TODO: Signalling NaN values get converted to quiet NaN values in31 // TODO: Signalling NaN values get converted to quiet NaN values in
39 // some cases where they shouldn't such that this can fail.32 // some cases where they shouldn't such that this can fail.
...@@ -43,6 +36,7 @@ test isSignalNan {...@@ -43,6 +36,7 @@ test isSignalNan {
43 builtin.cpu.arch != .hexagon and36 builtin.cpu.arch != .hexagon and
44 !builtin.cpu.arch.isMIPS32() and37 !builtin.cpu.arch.isMIPS32() and
45 !builtin.cpu.arch.isPowerPC() and38 !builtin.cpu.arch.isPowerPC() and
39 !(builtin.cpu.arch.isX86() and builtin.os.tag == .windows and builtin.abi == .msvc) and // https://codeberg.org/ziglang/zig/issues/35519
46 builtin.zig_backend != .stage2_c)40 builtin.zig_backend != .stage2_c)
47 {41 {
48 try expect(isSignalNan(math.snan(T)));42 try expect(isSignalNan(math.snan(T)));
lib/std/math/log10.zig-5
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const builtin = @import("builtin");
3const testing = std.testing;2const testing = std.testing;
43
5/// Returns the base-10 logarithm of x.4/// Returns the base-10 logarithm of x.
...@@ -135,10 +134,6 @@ inline fn less_than_5(x: u32) u32 {...@@ -135,10 +134,6 @@ inline fn less_than_5(x: u32) u32 {
135}134}
136135
137test log10_int {136test log10_int {
138 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
140 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
141
142 inline for (137 inline for (
143 .{ u8, u16, u32, u64, u128, u256, u512 },138 .{ u8, u16, u32, u64, u128, u256, u512 },
144 .{ 2, 4, 9, 19, 38, 77, 154 },139 .{ 2, 4, 9, 19, 38, 77, 154 },
lib/std/math/modf.zig-4
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const builtin = @import("builtin");
3const math = std.math;2const math = std.math;
4const expect = std.testing.expect;3const expect = std.testing.expect;
5const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
...@@ -85,9 +84,6 @@ fn ModfTests(comptime T: type) type {...@@ -85,9 +84,6 @@ fn ModfTests(comptime T: type) type {
85 try expectApproxEqAbs(expected_c, r.fpart, epsilon);84 try expectApproxEqAbs(expected_c, r.fpart, epsilon);
86 }85 }
87 test "vector" {86 test "vector" {
88 if (builtin.os.tag.isDarwin() and builtin.cpu.arch == .aarch64) return error.SkipZigTest;
89 if (builtin.cpu.arch == .s390x) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194256
90
91 const widths = [_]comptime_int{ 1, 2, 3, 4, 8, 16 };87 const widths = [_]comptime_int{ 1, 2, 3, 4, 8, 16 };
9288
93 inline for (widths) |len| {89 inline for (widths) |len| {
lib/std/math/signbit.zig+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("../std.zig");2const std = @import("../std.zig");
2const math = std.math;3const math = std.math;
3const expect = std.testing.expect;4const expect = std.testing.expect;
lib/std/mem.zig+35-53
...@@ -4780,62 +4780,47 @@ pub fn alignForwardLog2(addr: usize, log2_alignment: u8) usize {...@@ -4780,62 +4780,47 @@ pub fn alignForwardLog2(addr: usize, log2_alignment: u8) usize {
4780pub fn doNotOptimizeAway(val: anytype) void {4780pub fn doNotOptimizeAway(val: anytype) void {
4781 if (@inComptime()) return;4781 if (@inComptime()) return;
47824782
4783 if (builtin.zig_backend == .stage2_c and builtin.abi == .msvc) {
4784 _ = @atomicRmw(*const anyopaque, @as(*volatile *const anyopaque, &struct {
4785 var escape: *const anyopaque = undefined;
4786 }.escape), .Xchg, &val, .acq_rel); // TODO: syncscope("singlethreaded")
4787 return;
4788 }
4789
4783 const max_gp_register_bits = @bitSizeOf(c_long);4790 const max_gp_register_bits = @bitSizeOf(c_long);
4784 const t = @typeInfo(@TypeOf(val));4791 switch (@typeInfo(@TypeOf(val))) {
4785 switch (t) {
4786 .void, .null, .comptime_int, .comptime_float => return,4792 .void, .null, .comptime_int, .comptime_float => return,
4787 .@"enum" => doNotOptimizeAway(@backingInt(val)),4793 .@"enum" => doNotOptimizeAway(@backingInt(val)),
4788 .bool => doNotOptimizeAway(@intFromBool(val)),4794 .bool => doNotOptimizeAway(@intFromBool(val)),
4789 .int => {4795 .int => |int| if (int.bits <= max_gp_register_bits) {
4790 const bits = t.int.bits;4796 const val2 = @as(
4791 if (bits <= max_gp_register_bits and builtin.zig_backend != .stage2_c) {4797 @Int(int.signedness, @max(8, std.math.ceilPowerOfTwoAssert(u16, int.bits))),
4792 const val2 = @as(4798 val,
4793 @Int(t.int.signedness, @max(8, std.math.ceilPowerOfTwoAssert(u16, bits))),4799 );
4794 val,4800 asm volatile (""
4795 );4801 :
4796 asm volatile (""4802 : [_] "r" (val2),
4797 :4803 );
4798 : [_] "r" (val2),4804 } else doNotOptimizeAway(&val),
4799 );4805 .float => |float| switch (float.bits) {
4800 } else doNotOptimizeAway(&val);4806 else => comptime unreachable,
4801 },4807 16, 80, 128 => doNotOptimizeAway(&val),
4802 .float => {4808 32, 64 => asm volatile (""
4803 if ((t.float.bits == 32 or t.float.bits == 64) and builtin.zig_backend != .stage2_c) {4809 :
4804 asm volatile (""4810 : [_] "rm" (val),
4805 :4811 ),
4806 : [_] "rm" (val),
4807 );
4808 } else doNotOptimizeAway(&val);
4809 },
4810 .pointer => {
4811 if (builtin.zig_backend == .stage2_c) {
4812 doNotOptimizeAwayC(val);
4813 } else {
4814 asm volatile (""
4815 :
4816 : [_] "m" (val),
4817 : .{ .memory = true });
4818 }
4819 },
4820 .array => {
4821 if (t.array.len * @sizeOf(t.array.child) <= 64) {
4822 for (val) |v| doNotOptimizeAway(v);
4823 } else doNotOptimizeAway(&val);
4824 },4812 },
4813 .pointer => asm volatile (""
4814 :
4815 : [_] "m" (val),
4816 : .{ .memory = true }),
4817 .array => |array| if (array.len * @sizeOf(array.child) <= 64) {
4818 for (val) |v| doNotOptimizeAway(v);
4819 } else doNotOptimizeAway(&val),
4825 else => doNotOptimizeAway(&val),4820 else => doNotOptimizeAway(&val),
4826 }4821 }
4827}4822}
48284823
4829/// .stage2_c doesn't support asm blocks yet, so use volatile stores instead
4830var deopt_target: if (builtin.zig_backend == .stage2_c) u8 else void = undefined;
4831fn doNotOptimizeAwayC(ptr: anytype) void {
4832 const dest = @as(*volatile u8, @ptrCast(&deopt_target));
4833 for (asBytes(ptr)) |b| {
4834 dest.* = b;
4835 }
4836 dest.* = 0;
4837}
4838
4839test doNotOptimizeAway {4824test doNotOptimizeAway {
4840 comptime doNotOptimizeAway("test");4825 comptime doNotOptimizeAway("test");
48414826
...@@ -4994,12 +4979,9 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice...@@ -4994,12 +4979,9 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice
4994}4979}
49954980
4996test "read/write(Var)PackedInt" {4981test "read/write(Var)PackedInt" {
4997 switch (builtin.cpu.arch) {4982 // This test generates too much code to execute on WASI.
4998 // This test generates too much code to execute on WASI.4983 // LLVM backend fails with "too many locals: locals exceed maximum"
4999 // LLVM backend fails with "too many locals: locals exceed maximum"4984 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;
5000 .wasm32, .wasm64 => return error.SkipZigTest,
5001 else => {},
5002 }
50034985
5004 const foreign_endian: Endian = if (native_endian == .big) .little else .big;4986 const foreign_endian: Endian = if (native_endian == .big) .little else .big;
5005 const expect = std.testing.expect;4987 const expect = std.testing.expect;
lib/std/multi_array_list.zig+2-2
...@@ -163,7 +163,7 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -163,7 +163,7 @@ pub fn MultiArrayList(comptime T: type) type {
163 };163 };
164 }164 }
165165
166 /// This function is used in the debugger pretty formatters in tools/ to fetch the166 /// This function is used in the debugger pretty formatters in lib/lldb/ to fetch the
167 /// child field order and entry type to facilitate fancy debug printing for this type.167 /// child field order and entry type to facilitate fancy debug printing for this type.
168 fn dbHelper(self: *Slice, child: *Elem, field: *Field, entry: *Entry) void {168 fn dbHelper(self: *Slice, child: *Elem, field: *Field, entry: *Entry) void {
169 _ = self;169 _ = self;
...@@ -681,7 +681,7 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -681,7 +681,7 @@ pub fn MultiArrayList(comptime T: type) type {
681 }681 }
682 break :entry @Struct(.@"extern", null, &entry_field_names, &entry_field_types, &entry_field_attrs);682 break :entry @Struct(.@"extern", null, &entry_field_names, &entry_field_types, &entry_field_attrs);
683 };683 };
684 /// This function is used in the debugger pretty formatters in tools/ to fetch the684 /// This function is used in the debugger pretty formatters in lib/lldb/ to fetch the
685 /// child field order and entry type to facilitate fancy debug printing for this type.685 /// child field order and entry type to facilitate fancy debug printing for this type.
686 fn dbHelper(self: *Self, child: *Elem, field: *Field, entry: *Entry) void {686 fn dbHelper(self: *Self, child: *Elem, field: *Field, entry: *Entry) void {
687 _ = self;687 _ = self;
lib/std/os/linux/IoUring/test.zig-7
...@@ -1836,8 +1836,6 @@ test "accept/connect/send_zc/recv" {...@@ -1836,8 +1836,6 @@ test "accept/connect/send_zc/recv" {
1836}1836}
18371837
1838test "accept_direct" {1838test "accept_direct" {
1839 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30854
1840
1841 try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 });1839 try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 });
18421840
1843 var ring = IoUring.init(1, 0) catch |err| switch (err) {1841 var ring = IoUring.init(1, 0) catch |err| switch (err) {
...@@ -1925,11 +1923,6 @@ test "accept_direct" {...@@ -1925,11 +1923,6 @@ test "accept_direct" {
1925test "accept_multishot_direct" {1923test "accept_multishot_direct" {
1926 try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 });1924 try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 });
19271925
1928 if (builtin.cpu.arch == .riscv64) {
1929 // https://github.com/ziglang/zig/issues/25734
1930 return error.SkipZigTest;
1931 }
1932
1933 var ring = IoUring.init(1, 0) catch |err| switch (err) {1926 var ring = IoUring.init(1, 0) catch |err| switch (err) {
1934 error.SystemOutdated => return error.SkipZigTest,1927 error.SystemOutdated => return error.SkipZigTest,
1935 error.PermissionDenied => return error.SkipZigTest,1928 error.PermissionDenied => return error.SkipZigTest,
lib/std/os/linux/aarch64.zig+1-1
...@@ -154,7 +154,7 @@ pub const restore = restore_rt;...@@ -154,7 +154,7 @@ pub const restore = restore_rt;
154pub fn restore_rt() callconv(.naked) noreturn {154pub fn restore_rt() callconv(.naked) noreturn {
155 switch (builtin.zig_backend) {155 switch (builtin.zig_backend) {
156 .stage2_c => asm volatile (156 .stage2_c => asm volatile (
157 \\ mov x8, %[number]157 \\ mov w8, %[number]
158 \\ svc #0158 \\ svc #0
159 :159 :
160 : [number] "i" (@backingInt(SYS.rt_sigreturn)),160 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
lib/std/os/linux/s390x.zig+26-10
...@@ -174,19 +174,35 @@ pub fn clone() callconv(.naked) u64 {...@@ -174,19 +174,35 @@ pub fn clone() callconv(.naked) u64 {
174}174}
175175
176pub fn restore() callconv(.naked) noreturn {176pub fn restore() callconv(.naked) noreturn {
177 asm volatile (177 switch (builtin.zig_backend) {
178 \\svc 0178 .stage2_c => asm volatile (
179 :179 \\lghi %%r1, %[number]
180 : [number] "{r1}" (@backingInt(SYS.sigreturn)),180 \\svc 0
181 );181 :
182 : [number] "K" (@backingInt(SYS.sigreturn)),
183 ),
184 else => asm volatile (
185 \\svc 0
186 :
187 : [number] "{r1}" (@backingInt(SYS.sigreturn)),
188 ),
189 }
182}190}
183191
184pub fn restore_rt() callconv(.naked) noreturn {192pub fn restore_rt() callconv(.naked) noreturn {
185 asm volatile (193 switch (builtin.zig_backend) {
186 \\svc 0194 .stage2_c => asm volatile (
187 :195 \\lghi %%r1, %[number]
188 : [number] "{r1}" (@backingInt(SYS.rt_sigreturn)),196 \\svc 0
189 );197 :
198 : [number] "K" (@backingInt(SYS.rt_sigreturn)),
199 ),
200 else => asm volatile (
201 \\svc 0
202 :
203 : [number] "{r1}" (@backingInt(SYS.rt_sigreturn)),
204 ),
205 }
190}206}
191207
192pub const time_t = i64;208pub const time_t = i64;
lib/std/testing/Smith.zig+1-1
...@@ -708,7 +708,7 @@ fn constructInput(comptime values: []const union(enum) {...@@ -708,7 +708,7 @@ fn constructInput(comptime values: []const union(enum) {
708}708}
709709
710test value {710test value {
711 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO711 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
712712
713 const S = struct {713 const S = struct {
714 v: void = {},714 v: void = {},
lib/std/zig/llvm/Builder.zig+1307-471
...@@ -17,7 +17,7 @@ gpa: Allocator,...@@ -17,7 +17,7 @@ gpa: Allocator,
17strip: bool,17strip: bool,
1818
19source_filename: String,19source_filename: String,
20data_layout: String,20data_layout: DataLayout,
21target_triple: String,21target_triple: String,
22module_asm: std.ArrayList(u8),22module_asm: std.ArrayList(u8),
2323
...@@ -87,6 +87,455 @@ pub const Options = struct {...@@ -87,6 +87,455 @@ pub const Options = struct {
87 triple: []const u8 = &.{},87 triple: []const u8 = &.{},
88};88};
8989
90pub const DataLayout = struct {
91 endian: ?std.lang.Endian,
92 int_specs: PrimitiveSpec.Map,
93 float_specs: PrimitiveSpec.Map,
94 vector_specs: PrimitiveSpec.Map,
95 pointer_specs: PointerSpec.Map,
96 string_repr: String,
97
98 const PrimitiveSpec = packed struct(u32) {
99 bit_width: BitWidth,
100 abi_align: Alignment,
101 pref_align: Alignment,
102
103 const BitWidth = u20;
104
105 const Map = std.array_hash_map.Custom(PrimitiveSpec, void, Context, false);
106
107 const Context = struct {
108 pub fn hash(_: Context, spec: PrimitiveSpec) u32 {
109 return std.hash.int(spec.bit_width);
110 }
111
112 pub fn eql(_: Context, lhs_spec: PrimitiveSpec, rhs_spec: PrimitiveSpec, _: usize) bool {
113 return lhs_spec.bit_width == rhs_spec.bit_width;
114 }
115 };
116 };
117
118 const PointerSpec = struct {
119 bit_width: BitWidth,
120 index_bit_width: BitWidth,
121 flags: packed struct(u32) {
122 abi_align: Alignment,
123 pref_align: Alignment,
124 has_unstable_repr: bool,
125 has_external_state: bool,
126 null_ptr_repr: NullPtrRepr,
127 unused: u17 = 0,
128 },
129 addr_space_name: String,
130
131 const BitWidth = u32;
132
133 const NullPtrRepr = enum(u1) { all_zeros, all_ones };
134
135 const Map = std.array_hash_map.Auto(AddrSpace, PointerSpec);
136 };
137
138 pub fn stringForTarget(target: *const std.Target) []const u8 {
139 // These data layouts should match Clang.
140 return switch (target.cpu.arch) {
141 .arc => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32",
142 .xcore => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64:32-a:0:32-n32",
143 .hexagon => "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048",
144 .lanai => "E-m:e-p:32:32-i64:64-a:0:32-n32-S64",
145 .aarch64 => if (target.ofmt == .macho)
146 if (target.os.tag == .windows or target.os.tag == .uefi)
147 "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
148 else if (target.abi == .ilp32)
149 "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
150 else
151 "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
152 else if (target.os.tag == .windows or target.os.tag == .uefi)
153 "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
154 else
155 "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
156 .aarch64_be => "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
157 .arm => if (target.ofmt == .macho)
158 "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
159 else
160 "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
161 .armeb, .thumbeb => if (target.ofmt == .macho)
162 "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
163 else
164 "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
165 .thumb => if (target.ofmt == .macho)
166 "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
167 else if (target.os.tag == .windows or target.os.tag == .uefi)
168 "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
169 else
170 "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
171 .avr => "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8",
172 .bpfeb => "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
173 .bpfel => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
174 .msp430 => "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16",
175 .mips => "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64",
176 .mipsel => "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64",
177 .mips64 => switch (target.abi) {
178 .gnuabin32, .muslabin32, .abin32 => "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
179 else => "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
180 },
181 .mips64el => switch (target.abi) {
182 .gnuabin32, .muslabin32, .abin32 => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
183 else => "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
184 },
185 .m68k => "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16",
186 .powerpc => "E-m:e-p:32:32-Fn32-i64:64-n32",
187 .powerpcle => "e-m:e-p:32:32-Fn32-i64:64-n32",
188 .powerpc64 => switch (target.os.tag) {
189 .linux => "E-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512",
190 .ps3 => "E-m:e-p:32:32-Fi64-i64:64-i128:128-n32:64",
191 else => "E-m:e-Fn32-i64:64-i128:128-n32:64",
192 },
193 .powerpc64le => if (target.os.tag == .linux)
194 "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512"
195 else
196 "e-m:e-Fn32-i64:64-i128:128-n32:64",
197 .nvptx => "e-p:32:32-p6:32:32-p7:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64",
198 .nvptx64 => "e-p6:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64",
199 .amdgcn => "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9",
200 .riscv32 => if (target.cpu.has(.riscv, .e))
201 "e-m:e-p:32:32-i64:64-n32-S32"
202 else
203 "e-m:e-p:32:32-i64:64-n32-S128",
204 .riscv32be => if (target.cpu.has(.riscv, .e))
205 "E-m:e-p:32:32-i64:64-n32-S32"
206 else
207 "E-m:e-p:32:32-i64:64-n32-S128",
208 .riscv64 => if (target.cpu.has(.riscv, .e))
209 "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64"
210 else
211 "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
212 .riscv64be => if (target.cpu.has(.riscv, .e))
213 "E-m:e-p:64:64-i64:64-i128:128-n32:64-S64"
214 else
215 "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
216 .sparc => "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64",
217 .sparc64 => "E-m:e-i64:64-i128:128-n32:64-S128",
218 .s390x => "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64",
219 .x86 => if (target.os.tag == .windows or target.os.tag == .uefi) switch (target.abi) {
220 .gnu => if (target.ofmt == .coff)
221 "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"
222 else
223 "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32",
224 else => blk: {
225 const msvc = switch (target.abi) {
226 .none, .msvc => true,
227 else => false,
228 };
229
230 break :blk if (target.ofmt == .coff)
231 if (msvc)
232 "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
233 else
234 "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"
235 else if (msvc)
236 "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
237 else
238 "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32";
239 },
240 } else if (target.ofmt == .macho)
241 "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
242 else
243 "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128",
244 .x86_64 => if (target.os.tag.isDarwin() or target.ofmt == .macho)
245 "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
246 else switch (target.abi) {
247 .gnux32, .muslx32, .x32 => "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
248 else => if ((target.os.tag == .windows or target.os.tag == .uefi) and target.ofmt == .coff)
249 "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
250 else
251 "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
252 },
253 .spirv32 => switch (target.os.tag) {
254 .vulkan, .opengl => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
255 else => "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
256 },
257 .spirv64 => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
258 .wasm32 => if (target.os.tag == .emscripten)
259 "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-S128-ni:1:10:20"
260 else
261 "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20",
262 .wasm64 => if (target.os.tag == .emscripten)
263 "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-S128-ni:1:10:20"
264 else
265 "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20",
266 .ve => "e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64",
267 .csky => "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32",
268 .loongarch32 => "e-m:e-p:32:32-i64:64-n32-S128",
269 .loongarch64 => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
270 .xtensa => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32",
271
272 .alpha,
273 .arceb,
274 .ez80,
275 .hppa,
276 .hppa64,
277 .kalimba,
278 .kvx,
279 .m88k,
280 .microblaze,
281 .microblazeel,
282 .or1k,
283 .propeller,
284 .sh,
285 .sheb,
286 .x86_16,
287 .xtensaeb,
288 => unreachable,
289 };
290 }
291
292 const default_int_specs: []const PrimitiveSpec = &.{
293 .{ .bit_width = 8, .abi_align = .fromByteUnits(1), .pref_align = .fromByteUnits(1) }, // i8:8:8
294 .{ .bit_width = 16, .abi_align = .fromByteUnits(2), .pref_align = .fromByteUnits(2) }, // i16:16:16
295 .{ .bit_width = 32, .abi_align = .fromByteUnits(4), .pref_align = .fromByteUnits(4) }, // i32:32:32
296 .{ .bit_width = 64, .abi_align = .fromByteUnits(4), .pref_align = .fromByteUnits(8) }, // i64:32:64
297 };
298 const default_float_specs: []const PrimitiveSpec = &.{
299 .{ .bit_width = 16, .abi_align = .fromByteUnits(2), .pref_align = .fromByteUnits(2) }, // f16:16:16
300 .{ .bit_width = 32, .abi_align = .fromByteUnits(4), .pref_align = .fromByteUnits(4) }, // f32:32:32
301 .{ .bit_width = 64, .abi_align = .fromByteUnits(8), .pref_align = .fromByteUnits(8) }, // f64:64:64
302 .{ .bit_width = 128, .abi_align = .fromByteUnits(16), .pref_align = .fromByteUnits(16) }, // f128:128:128
303 };
304 const default_vector_specs: []const PrimitiveSpec = &.{
305 .{ .bit_width = 64, .abi_align = .fromByteUnits(8), .pref_align = .fromByteUnits(8) }, // v64:64:64
306 .{ .bit_width = 128, .abi_align = .fromByteUnits(16), .pref_align = .fromByteUnits(16) }, // v128:128:128
307 };
308
309 pub fn parseString(string_repr: String, builder: *Builder) Allocator.Error!DataLayout {
310 const gpa = builder.gpa;
311
312 var int_specs: PrimitiveSpec.Map = .empty;
313 defer int_specs.deinit(gpa);
314 var float_specs: PrimitiveSpec.Map = .empty;
315 defer float_specs.deinit(gpa);
316 var vector_specs: PrimitiveSpec.Map = .empty;
317 defer vector_specs.deinit(gpa);
318 var pointer_specs: PointerSpec.Map = .empty;
319 defer pointer_specs.deinit(gpa);
320 var non_integral_addr_spaces: std.ArrayList(AddrSpace) = .empty;
321 defer non_integral_addr_spaces.deinit(gpa);
322
323 try int_specs.ensureTotalCapacity(gpa, default_int_specs.len);
324 for (default_int_specs) |int_spec| int_specs.putAssumeCapacityNoClobber(int_spec, {});
325 try float_specs.ensureTotalCapacity(gpa, default_float_specs.len);
326 for (default_float_specs) |float_spec| float_specs.putAssumeCapacityNoClobber(float_spec, {});
327 try vector_specs.ensureTotalCapacity(gpa, default_vector_specs.len);
328 for (default_vector_specs) |vector_spec| vector_specs.putAssumeCapacityNoClobber(vector_spec, {});
329 try pointer_specs.putNoClobber(gpa, .default, comptime .{
330 .bit_width = 64,
331 .index_bit_width = 64,
332 .flags = .{
333 .abi_align = .fromByteUnits(8),
334 .pref_align = .fromByteUnits(8),
335 .has_unstable_repr = false,
336 .has_external_state = false,
337 .null_ptr_repr = .all_zeros,
338 },
339 .addr_space_name = .none,
340 });
341
342 var endian: ?std.lang.Endian = null;
343 var spec_it = std.mem.splitScalar(u8, string_repr.slice(builder).?, '-');
344 while (spec_it.next()) |spec| switch (spec[0]) {
345 else => {},
346 'E' => {
347 assert(spec.len == 1);
348 assert(endian == null);
349 endian = .big;
350 },
351 'e' => {
352 assert(spec.len == 1);
353 assert(endian == null);
354 endian = .little;
355 },
356 'p' => {
357 var field_it = std.mem.splitScalar(u8, spec[1..], ':');
358
359 const first = field_it.first();
360 var has_unstable_repr = false;
361 var has_external_state = false;
362 var null_ptr_repr: ?PointerSpec.NullPtrRepr = null;
363 var addr_space_name: String = .none;
364 const addr_space = for (first, 0..) |flag, as_start| switch (flag) {
365 'u' => has_unstable_repr = true,
366 'e' => has_external_state = true,
367 'z' => {
368 assert(null_ptr_repr == null);
369 null_ptr_repr = .all_zeros;
370 },
371 'o' => {
372 assert(null_ptr_repr == null);
373 null_ptr_repr = .all_ones;
374 },
375 else => {
376 if (first[first.len - ")".len] != ')') break first[as_start..];
377 const name_start = std.mem.findScalarPos(u8, first, as_start, '(').?;
378 addr_space_name = try builder.string(first[name_start + "(".len .. first.len - ")".len]);
379 break first[as_start..name_start];
380 },
381 } else first[first.len..];
382 const bit_width = std.fmt.parseInt(PointerSpec.BitWidth, field_it.next().?, 10) catch unreachable;
383 const abi_align: Alignment = .fromByteUnits(std.fmt.parseInt(u64, field_it.next().?, 10) catch unreachable);
384 const pref_align: Alignment = if (field_it.next()) |pref_align|
385 .fromByteUnits(std.fmt.parseInt(u64, pref_align, 10) catch unreachable)
386 else
387 abi_align;
388 const index_bit_width = if (field_it.next()) |index_bit_width|
389 std.fmt.parseInt(PointerSpec.BitWidth, index_bit_width, 10) catch unreachable
390 else
391 bit_width;
392 assert(field_it.peek() == null);
393
394 try pointer_specs.put(gpa, switch (addr_space.len) {
395 0 => .default,
396 else => @fromBackingInt(std.fmt.parseInt(u24, addr_space, 10) catch unreachable),
397 }, .{
398 .bit_width = bit_width,
399 .index_bit_width = index_bit_width,
400 .flags = .{
401 .abi_align = abi_align,
402 .pref_align = pref_align,
403 .has_unstable_repr = has_unstable_repr,
404 .has_external_state = has_external_state,
405 .null_ptr_repr = null_ptr_repr orelse .all_zeros,
406 },
407 .addr_space_name = addr_space_name,
408 });
409 },
410 'i', 'f', 'v' => |kind| {
411 if (std.mem.eql(u8, spec, "ve")) {
412 vector_specs.clearRetainingCapacity();
413 continue;
414 }
415 var field_it = std.mem.splitScalar(u8, spec[1..], ':');
416 const bit_width = std.fmt.parseInt(PrimitiveSpec.BitWidth, field_it.first(), 10) catch unreachable;
417 const abi_align: Alignment = .fromByteUnits(std.fmt.parseInt(u64, field_it.next().?, 10) catch unreachable);
418 const pref_align: Alignment = if (field_it.next()) |pref_align|
419 .fromByteUnits(std.fmt.parseInt(u64, pref_align, 10) catch unreachable)
420 else
421 abi_align;
422 assert(field_it.peek() == null);
423 const specs = switch (kind) {
424 else => unreachable,
425 'i' => &int_specs,
426 'f' => &float_specs,
427 'v' => &vector_specs,
428 };
429 try specs.put(gpa, .{ .bit_width = bit_width, .abi_align = abi_align, .pref_align = pref_align }, {});
430 },
431 'n' => {
432 var field_it = std.mem.splitScalar(u8, spec[1..], ':');
433 if (std.mem.eql(u8, field_it.first(), "i")) {
434 while (field_it.next()) |non_integral_addr_space| try non_integral_addr_spaces.append(
435 gpa,
436 @fromBackingInt(std.fmt.parseInt(u24, non_integral_addr_space, 10) catch unreachable),
437 );
438 } else {
439 field_it.reset();
440 while (field_it.next()) |native_bit_width| {
441 _ = std.fmt.parseInt(PrimitiveSpec.BitWidth, native_bit_width, 10) catch unreachable;
442 }
443 }
444 },
445 };
446
447 for (non_integral_addr_spaces.items) |non_integral_addr_space| {
448 const pointer_spec_gop = try pointer_specs.getOrPut(gpa, non_integral_addr_space);
449 if (!pointer_spec_gop.found_existing) pointer_spec_gop.value_ptr.* = pointer_specs.get(.default).?;
450 pointer_spec_gop.value_ptr.flags.has_unstable_repr = true;
451 pointer_spec_gop.value_ptr.flags.has_external_state = false;
452 }
453
454 {
455 const SortContext = struct {
456 specs: []const PrimitiveSpec,
457 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
458 return ctx.specs[lhs_index].bit_width < ctx.specs[rhs_index].bit_width;
459 }
460 };
461 int_specs.sortUnstable(SortContext{ .specs = int_specs.keys() });
462 float_specs.sortUnstable(SortContext{ .specs = float_specs.keys() });
463 vector_specs.sortUnstable(SortContext{ .specs = vector_specs.keys() });
464 }
465 {
466 const SortContext = struct {
467 addr_spaces: []const AddrSpace,
468 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
469 return @backingInt(ctx.addr_spaces[lhs_index]) < @backingInt(ctx.addr_spaces[rhs_index]);
470 }
471 };
472 pointer_specs.sortUnstable(SortContext{ .addr_spaces = pointer_specs.keys() });
473 assert(pointer_specs.keys()[0] == .default);
474 }
475
476 return .{
477 .endian = endian,
478 .int_specs = int_specs.move(),
479 .float_specs = float_specs.move(),
480 .vector_specs = vector_specs.move(),
481 .pointer_specs = pointer_specs.move(),
482 .string_repr = string_repr,
483 };
484 }
485
486 pub fn deinit(data_layout: *DataLayout, gpa: Allocator) void {
487 data_layout.int_specs.deinit(gpa);
488 data_layout.float_specs.deinit(gpa);
489 data_layout.vector_specs.deinit(gpa);
490 data_layout.pointer_specs.deinit(gpa);
491 }
492
493 pub fn getIntegerSpec(data_layout: *const DataLayout, bit_width: PrimitiveSpec.BitWidth) PrimitiveSpec {
494 const specs = data_layout.int_specs.keys();
495 return specs[
496 @min(std.sort.lowerBound(PrimitiveSpec, specs, bit_width, struct {
497 fn order(ctx: PrimitiveSpec.BitWidth, spec: PrimitiveSpec) std.math.Order {
498 return std.math.order(ctx, spec.bit_width);
499 }
500 }.order), specs.len - 1)
501 ];
502 }
503
504 pub fn getFloatSpec(data_layout: *const DataLayout, bit_width: PrimitiveSpec.BitWidth) PrimitiveSpec {
505 if (data_layout.float_specs.getEntry(.{
506 .bit_width = bit_width,
507 .abi_align = .default,
508 .pref_align = .default,
509 })) |entry| return entry.key_ptr.*;
510 const default_align: Alignment = .fromByteUnits(
511 std.math.ceilPowerOfTwoAssert(PrimitiveSpec.BitWidth, bit_width / 8),
512 );
513 return .{ .bit_width = bit_width, .abi_align = default_align, .pref_align = default_align };
514 }
515
516 pub fn getVectorSpec(
517 data_layout: *const DataLayout,
518 bit_width: PrimitiveSpec.BitWidth,
519 store_size: Type.Size,
520 ) PrimitiveSpec {
521 if (data_layout.float_specs.getEntry(.{
522 .bit_width = bit_width,
523 .abi_align = .default,
524 .pref_align = .default,
525 })) |entry| return entry.key_ptr.*;
526 const default_align: Alignment = .fromByteUnits(
527 std.math.ceilPowerOfTwoAssert(PrimitiveSpec.BitWidth, switch (store_size) {
528 .fixed, .scalable => |known_min| known_min,
529 }),
530 );
531 return .{ .bit_width = bit_width, .abi_align = default_align, .pref_align = default_align };
532 }
533
534 pub fn getPointerSpec(data_layout: *const DataLayout, addr_space: AddrSpace) PointerSpec {
535 return data_layout.pointer_specs.get(addr_space) orelse data_layout.pointer_specs.values()[0];
536 }
537};
538
90pub const String = enum(u32) {539pub const String = enum(u32) {
91 none = maxInt(u31),540 none = maxInt(u31),
92 empty,541 empty,
...@@ -142,8 +591,8 @@ pub const String = enum(u32) {...@@ -142,8 +591,8 @@ pub const String = enum(u32) {
142 }591 }
143592
144 fn fromIndex(index: ?usize) String {593 fn fromIndex(index: ?usize) String {
145 return @fromBackingInt(@intCast(@as(u32, @intCast((index orelse return .none) +594 return @fromBackingInt(@as(u32, @intCast((index orelse return .none) +
146 @backingInt(String.empty)))));595 @backingInt(String.empty))));
147 }596 }
148597
149 fn toIndex(self: String) ?usize {598 fn toIndex(self: String) ?usize {
...@@ -489,7 +938,10 @@ pub const Type = enum(u32) {...@@ -489,7 +938,10 @@ pub const Type = enum(u32) {
489 .double, .i64, .x86_mmx => 64,938 .double, .i64, .x86_mmx => 64,
490 .x86_fp80, .i80 => 80,939 .x86_fp80, .i80 => 80,
491 .fp128, .ppc_fp128, .i128 => 128,940 .fp128, .ppc_fp128, .i128 => 128,
492 .ptr, .@"ptr addrspace(4)" => @panic("TODO: query data layout"),941 .ptr => @intCast(builder.data_layout.getPointerSpec(.default).bit_width),
942 .@"ptr addrspace(4)" => @intCast(
943 builder.data_layout.getPointerSpec(@fromBackingInt(@intCast(4))).bit_width,
944 ),
493 _ => {945 _ => {
494 const item = builder.type_items.items[@backingInt(self)];946 const item = builder.type_items.items[@backingInt(self)];
495 return switch (item.tag) {947 return switch (item.tag) {
...@@ -498,7 +950,9 @@ pub const Type = enum(u32) {...@@ -498,7 +950,9 @@ pub const Type = enum(u32) {
498 .vararg_function,950 .vararg_function,
499 => unreachable,951 => unreachable,
500 .integer => @intCast(item.data),952 .integer => @intCast(item.data),
501 .pointer => @panic("TODO: query data layout"),953 .pointer => @intCast(
954 builder.data_layout.getPointerSpec(@fromBackingInt(@intCast(item.data))).bit_width,
955 ),
502 .target => unreachable,956 .target => unreachable,
503 .vector,957 .vector,
504 .scalable_vector,958 .scalable_vector,
...@@ -931,12 +1385,74 @@ pub const Type = enum(u32) {...@@ -931,12 +1385,74 @@ pub const Type = enum(u32) {
931 },1385 },
932 };1386 };
933 }1387 }
1388
1389 const Size = union(enum) { fixed: u64, scalable: u64 };
1390 pub fn bits(ty: Type, builder: *const Builder) Size {
1391 const item = builder.type_items.items[@backingInt(ty)];
1392 return switch (item.tag) {
1393 else => unreachable,
1394 .simple => switch (@as(Simple, @fromBackingInt(@intCast(item.data)))) {
1395 else => unreachable,
1396 .label => .{ .fixed = builder.data_layout.getPointerSpec(.default).bit_width },
1397 .half, .bfloat => .{ .fixed = 16 },
1398 .float => .{ .fixed = 32 },
1399 .double => .{ .fixed = 64 },
1400 .ppc_fp128, .fp128 => .{ .fixed = 128 },
1401 .x86_amx => .{ .fixed = 8192 },
1402 .x86_fp80 => .{ .fixed = 80 },
1403 },
1404 .integer => .{ .fixed = item.data },
1405 .pointer => .{
1406 .fixed = builder.data_layout.getPointerSpec(@fromBackingInt(@intCast(item.data))).bit_width,
1407 },
1408 };
1409 }
1410
1411 pub fn alignment(ty: Type, kind: enum { abi, pref }, builder: *const Builder) Alignment {
1412 const item = builder.type_items.items[@backingInt(ty)];
1413 switch (item.tag) {
1414 else => unreachable,
1415 .simple => switch (@as(Simple, @fromBackingInt(@intCast(item.data)))) {
1416 else => unreachable,
1417 .label => {
1418 const spec = builder.data_layout.getPointerSpec(.default);
1419 return switch (kind) {
1420 .abi => spec.flags.abi_align,
1421 .pref => spec.flags.pref_align,
1422 };
1423 },
1424 .half, .bfloat, .float, .double, .ppc_fp128, .fp128, .x86_fp80 => {
1425 const spec = builder.data_layout.getFloatSpec(@intCast(ty.bits(builder).fixed));
1426 return switch (kind) {
1427 .abi => spec.abi_align,
1428 .pref => spec.pref_align,
1429 };
1430 },
1431 .x86_amx => return comptime .fromByteUnits(64),
1432 },
1433 .integer => {
1434 const spec = builder.data_layout.getIntegerSpec(@intCast(item.data));
1435 return switch (kind) {
1436 .abi => spec.abi_align,
1437 .pref => spec.pref_align,
1438 };
1439 },
1440 .pointer => {
1441 const spec = builder.data_layout.getPointerSpec(@fromBackingInt(@intCast(item.data)));
1442 return switch (kind) {
1443 .abi => spec.flags.abi_align,
1444 .pref => spec.flags.pref_align,
1445 };
1446 },
1447 }
1448 }
934};1449};
9351450
936pub const Attribute = union(Kind) {1451pub const Attribute = union(Kind) {
937 // Parameter Attributes1452 // Parameter Attributes
938 zeroext,1453 zeroext,
939 signext,1454 signext,
1455 noext,
940 inreg,1456 inreg,
941 byval: Type,1457 byval: Type,
942 byref: Type,1458 byref: Type,
...@@ -947,6 +1463,7 @@ pub const Attribute = union(Kind) {...@@ -947,6 +1463,7 @@ pub const Attribute = union(Kind) {
947 @"align": Alignment.Lazy,1463 @"align": Alignment.Lazy,
948 @"noalias",1464 @"noalias",
949 nocapture,1465 nocapture,
1466 captures: Captures,
950 nofree,1467 nofree,
951 nest,1468 nest,
952 returned,1469 returned,
...@@ -965,6 +1482,11 @@ pub const Attribute = union(Kind) {...@@ -965,6 +1482,11 @@ pub const Attribute = union(Kind) {
965 readnone,1482 readnone,
966 readonly,1483 readonly,
967 writeonly,1484 writeonly,
1485 writable,
1486 initializes: []const [2]u64,
1487 dead_on_unwind,
1488 dead_on_return: ?u32,
1489 range: [2]Constant,
9681490
969 // Function Attributes1491 // Function Attributes
970 //alignstack: Alignment.Lazy,1492 //alignstack: Alignment.Lazy,
...@@ -974,7 +1496,7 @@ pub const Attribute = union(Kind) {...@@ -974,7 +1496,7 @@ pub const Attribute = union(Kind) {
974 builtin,1496 builtin,
975 cold,1497 cold,
976 convergent,1498 convergent,
977 disable_sanitizer_information,1499 disable_sanitizer_instrumentation,
978 fn_ret_thunk_extern,1500 fn_ret_thunk_extern,
979 hot,1501 hot,
980 inlinehint,1502 inlinehint,
...@@ -984,6 +1506,7 @@ pub const Attribute = union(Kind) {...@@ -984,6 +1506,7 @@ pub const Attribute = union(Kind) {
984 naked,1506 naked,
985 nobuiltin,1507 nobuiltin,
986 nocallback,1508 nocallback,
1509 nodivergencesource,
987 noduplicate,1510 noduplicate,
988 //nofree,1511 //nofree,
989 noimplicitfloat,1512 noimplicitfloat,
...@@ -1001,6 +1524,7 @@ pub const Attribute = union(Kind) {...@@ -1001,6 +1524,7 @@ pub const Attribute = union(Kind) {
1001 nosanitize_bounds,1524 nosanitize_bounds,
1002 nosanitize_coverage,1525 nosanitize_coverage,
1003 null_pointer_is_valid,1526 null_pointer_is_valid,
1527 optdebug,
1004 optforfuzzing,1528 optforfuzzing,
1005 optnone,1529 optnone,
1006 optsize,1530 optsize,
...@@ -1012,23 +1536,23 @@ pub const Attribute = union(Kind) {...@@ -1012,23 +1536,23 @@ pub const Attribute = union(Kind) {
1012 sanitize_thread,1536 sanitize_thread,
1013 sanitize_hwaddress,1537 sanitize_hwaddress,
1014 sanitize_memtag,1538 sanitize_memtag,
1539 sanitize_realtime,
1540 sanitize_realtime_blocking,
1541 sanitize_alloc_token,
1015 speculative_load_hardening,1542 speculative_load_hardening,
1016 speculatable,1543 speculatable,
1017 ssp,1544 ssp,
1018 sspstrong,1545 sspstrong,
1019 sspreq,1546 sspreq,
1020 strictfp,1547 strictfp,
1548 denormal_fpenv,
1021 uwtable: UwTable,1549 uwtable: UwTable,
1022 nocf_check,1550 nocf_check,
1023 shadowcallstack,1551 shadowcallstack,
1024 mustprogress,1552 mustprogress,
1025 vscale_range: VScaleRange,1553 vscale_range: VScaleRange,
10261554 nooutline,
1027 // Global Attributes1555 nocreateundeforpoison,
1028 no_sanitize_address,
1029 no_sanitize_hwaddress,
1030 //sanitize_memtag,
1031 sanitize_address_dyninit,
10321556
1033 string: struct { kind: String, value: String },1557 string: struct { kind: String, value: String },
1034 none: noreturn,1558 none: noreturn,
...@@ -1045,100 +1569,11 @@ pub const Attribute = union(Kind) {...@@ -1045,100 +1569,11 @@ pub const Attribute = union(Kind) {
1045 const storage = self.toStorage(builder);1569 const storage = self.toStorage(builder);
1046 if (storage.kind.toString()) |kind| return .{ .string = .{1570 if (storage.kind.toString()) |kind| return .{ .string = .{
1047 .kind = kind,1571 .kind = kind,
1048 .value = @fromBackingInt(@intCast(storage.value)),1572 .value = @fromBackingInt(storage.value),
1049 } } else return switch (storage.kind) {1573 } } else return switch (storage.kind) {
1050 inline .zeroext,1574 inline else => |kind| {
1051 .signext,
1052 .inreg,
1053 .byval,
1054 .byref,
1055 .preallocated,
1056 .inalloca,
1057 .sret,
1058 .elementtype,
1059 .@"align",
1060 .@"noalias",
1061 .nocapture,
1062 .nofree,
1063 .nest,
1064 .returned,
1065 .nonnull,
1066 .dereferenceable,
1067 .dereferenceable_or_null,
1068 .swiftself,
1069 .swiftasync,
1070 .swifterror,
1071 .immarg,
1072 .noundef,
1073 .nofpclass,
1074 .alignstack,
1075 .allocalign,
1076 .allocptr,
1077 .readnone,
1078 .readonly,
1079 .writeonly,
1080 //.alignstack,
1081 .allockind,
1082 .allocsize,
1083 .alwaysinline,
1084 .builtin,
1085 .cold,
1086 .convergent,
1087 .disable_sanitizer_information,
1088 .fn_ret_thunk_extern,
1089 .hot,
1090 .inlinehint,
1091 .jumptable,
1092 .memory,
1093 .minsize,
1094 .naked,
1095 .nobuiltin,
1096 .nocallback,
1097 .noduplicate,
1098 //.nofree,
1099 .noimplicitfloat,
1100 .@"noinline",
1101 .nomerge,
1102 .nonlazybind,
1103 .noprofile,
1104 .skipprofile,
1105 .noredzone,
1106 .noreturn,
1107 .norecurse,
1108 .willreturn,
1109 .nosync,
1110 .nounwind,
1111 .nosanitize_bounds,
1112 .nosanitize_coverage,
1113 .null_pointer_is_valid,
1114 .optforfuzzing,
1115 .optnone,
1116 .optsize,
1117 //.preallocated,
1118 .returns_twice,
1119 .safestack,
1120 .sanitize_address,
1121 .sanitize_memory,
1122 .sanitize_thread,
1123 .sanitize_hwaddress,
1124 .sanitize_memtag,
1125 .speculative_load_hardening,
1126 .speculatable,
1127 .ssp,
1128 .sspstrong,
1129 .sspreq,
1130 .strictfp,
1131 .uwtable,
1132 .nocf_check,
1133 .shadowcallstack,
1134 .mustprogress,
1135 .vscale_range,
1136 .no_sanitize_address,
1137 .no_sanitize_hwaddress,
1138 .sanitize_address_dyninit,
1139 => |kind| {
1140 const field_name, const field_type = comptime blk: {1575 const field_name, const field_type = comptime blk: {
1141 @setEvalBranchQuota(10_000);1576 @setEvalBranchQuota(12_000);
1142 const info = @typeInfo(Attribute).@"union";1577 const info = @typeInfo(Attribute).@"union";
1143 for (info.field_names, info.field_types) |field_name, field_type| {1578 for (info.field_names, info.field_types) |field_name, field_type| {
1144 if (std.mem.eql(u8, field_name, @tagName(kind))) break :blk .{ field_name, field_type };1579 if (std.mem.eql(u8, field_name, @tagName(kind))) break :blk .{ field_name, field_type };
...@@ -1149,14 +1584,17 @@ pub const Attribute = union(Kind) {...@@ -1149,14 +1584,17 @@ pub const Attribute = union(Kind) {
1149 return @unionInit(Attribute, field_name, switch (field_type) {1584 return @unionInit(Attribute, field_name, switch (field_type) {
1150 void => {},1585 void => {},
1151 u32 => storage.value,1586 u32 => storage.value,
1152 Alignment.Lazy, String, Type, UwTable => @fromBackingInt(@intCast(storage.value)),1587 Alignment.Lazy, String, Type, UwTable => @fromBackingInt(storage.value),
1153 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(storage.value),1588 AllocKind, AllocSize, Captures, FpClass, Memory, VScaleRange => @bitCast(storage.value),
1154 else => @compileError("bad payload type: " ++ field_name ++ ": " ++1589 else => @compileError("bad payload type: " ++ field_name ++ ": " ++
1155 @typeName(field_type)),1590 @typeName(field_type)),
1156 });1591 });
1157 },1592 },
1158 .string, .none => unreachable,1593 .initializes,
1159 _ => unreachable,1594 .dead_on_return,
1595 .range,
1596 => @panic("TODO"),
1597 .string, .none, _ => unreachable,
1160 };1598 };
1161 }1599 }
11621600
...@@ -1174,6 +1612,7 @@ pub const Attribute = union(Kind) {...@@ -1174,6 +1612,7 @@ pub const Attribute = union(Kind) {
1174 switch (attribute) {1612 switch (attribute) {
1175 .zeroext,1613 .zeroext,
1176 .signext,1614 .signext,
1615 .noext,
1177 .inreg,1616 .inreg,
1178 .@"noalias",1617 .@"noalias",
1179 .nocapture,1618 .nocapture,
...@@ -1191,11 +1630,13 @@ pub const Attribute = union(Kind) {...@@ -1191,11 +1630,13 @@ pub const Attribute = union(Kind) {
1191 .readnone,1630 .readnone,
1192 .readonly,1631 .readonly,
1193 .writeonly,1632 .writeonly,
1633 .writable,
1634 .dead_on_unwind,
1194 .alwaysinline,1635 .alwaysinline,
1195 .builtin,1636 .builtin,
1196 .cold,1637 .cold,
1197 .convergent,1638 .convergent,
1198 .disable_sanitizer_information,1639 .disable_sanitizer_instrumentation,
1199 .fn_ret_thunk_extern,1640 .fn_ret_thunk_extern,
1200 .hot,1641 .hot,
1201 .inlinehint,1642 .inlinehint,
...@@ -1204,6 +1645,7 @@ pub const Attribute = union(Kind) {...@@ -1204,6 +1645,7 @@ pub const Attribute = union(Kind) {
1204 .naked,1645 .naked,
1205 .nobuiltin,1646 .nobuiltin,
1206 .nocallback,1647 .nocallback,
1648 .nodivergencesource,
1207 .noduplicate,1649 .noduplicate,
1208 .noimplicitfloat,1650 .noimplicitfloat,
1209 .@"noinline",1651 .@"noinline",
...@@ -1220,6 +1662,7 @@ pub const Attribute = union(Kind) {...@@ -1220,6 +1662,7 @@ pub const Attribute = union(Kind) {
1220 .nosanitize_bounds,1662 .nosanitize_bounds,
1221 .nosanitize_coverage,1663 .nosanitize_coverage,
1222 .null_pointer_is_valid,1664 .null_pointer_is_valid,
1665 .optdebug,
1223 .optforfuzzing,1666 .optforfuzzing,
1224 .optnone,1667 .optnone,
1225 .optsize,1668 .optsize,
...@@ -1230,18 +1673,21 @@ pub const Attribute = union(Kind) {...@@ -1230,18 +1673,21 @@ pub const Attribute = union(Kind) {
1230 .sanitize_thread,1673 .sanitize_thread,
1231 .sanitize_hwaddress,1674 .sanitize_hwaddress,
1232 .sanitize_memtag,1675 .sanitize_memtag,
1676 .sanitize_realtime,
1677 .sanitize_realtime_blocking,
1678 .sanitize_alloc_token,
1233 .speculative_load_hardening,1679 .speculative_load_hardening,
1234 .speculatable,1680 .speculatable,
1235 .ssp,1681 .ssp,
1236 .sspstrong,1682 .sspstrong,
1237 .sspreq,1683 .sspreq,
1238 .strictfp,1684 .strictfp,
1685 .denormal_fpenv,
1239 .nocf_check,1686 .nocf_check,
1240 .shadowcallstack,1687 .shadowcallstack,
1241 .mustprogress,1688 .mustprogress,
1242 .no_sanitize_address,1689 .nooutline,
1243 .no_sanitize_hwaddress,1690 .nocreateundeforpoison,
1244 .sanitize_address_dyninit,
1245 => try w.print(" {s}", .{@tagName(attribute)}),1691 => try w.print(" {s}", .{@tagName(attribute)}),
1246 .byval,1692 .byval,
1247 .byref,1693 .byref,
...@@ -1254,6 +1700,45 @@ pub const Attribute = union(Kind) {...@@ -1254,6 +1700,45 @@ pub const Attribute = union(Kind) {
1254 .dereferenceable,1700 .dereferenceable,
1255 .dereferenceable_or_null,1701 .dereferenceable_or_null,
1256 => |size| try w.print(" {s}({d})", .{ @tagName(attribute), size }),1702 => |size| try w.print(" {s}({d})", .{ @tagName(attribute), size }),
1703 .captures => |captures| {
1704 try w.print(" {s}(", .{@tagName(attribute)});
1705 var need_comma = false;
1706 if (captures == Captures.none) {
1707 if (need_comma) try w.writeAll(", ");
1708 try w.writeAll("none");
1709 need_comma = true;
1710 }
1711 inline for (@typeInfo(Captures).@"struct".field_names) |field_name| {
1712 if (comptime std.mem.eql(u8, field_name, "_")) continue;
1713 const components = @field(captures, field_name);
1714 if (components != Captures.Components.none) {
1715 if (!comptime std.mem.eql(u8, field_name, "other")) {
1716 if (need_comma) try w.writeAll(", ");
1717 try w.writeAll(field_name ++ ": ");
1718 need_comma = false;
1719 }
1720 if (components.address) {
1721 if (need_comma) try w.writeAll(", ");
1722 try w.writeAll("address");
1723 need_comma = true;
1724 } else if (components.address_is_null) {
1725 if (need_comma) try w.writeAll(", ");
1726 try w.writeAll("address_is_null");
1727 need_comma = true;
1728 }
1729 if (components.provenance) {
1730 if (need_comma) try w.writeAll(", ");
1731 try w.writeAll("provenance");
1732 need_comma = true;
1733 } else if (components.read_provenance) {
1734 if (need_comma) try w.writeAll(", ");
1735 try w.writeAll("read_provenance");
1736 need_comma = true;
1737 }
1738 }
1739 }
1740 try w.writeByte(')');
1741 },
1257 .nofpclass => |fpclass| {1742 .nofpclass => |fpclass| {
1258 const Int = @typeInfo(FpClass).@"struct".backing_integer.?;1743 const Int = @typeInfo(FpClass).@"struct".backing_integer.?;
1259 try w.print(" {s}(", .{@tagName(attribute)});1744 try w.print(" {s}(", .{@tagName(attribute)});
...@@ -1281,6 +1766,9 @@ pub const Attribute = union(Kind) {...@@ -1281,6 +1766,9 @@ pub const Attribute = union(Kind) {
1281 try w.print("({d})", .{alignment_bytes});1766 try w.print("({d})", .{alignment_bytes});
1282 }1767 }
1283 },1768 },
1769 .initializes => @panic("TODO"),
1770 .dead_on_return => @panic("TODO"),
1771 .range => @panic("TODO"),
1284 .allockind => |allockind| {1772 .allockind => |allockind| {
1285 try w.print(" {t}(\"", .{attribute});1773 try w.print(" {t}(\"", .{attribute});
1286 var any = false;1774 var any = false;
...@@ -1344,100 +1832,109 @@ pub const Attribute = union(Kind) {...@@ -1344,100 +1832,109 @@ pub const Attribute = union(Kind) {
13441832
1345 pub const Kind = enum(u32) {1833 pub const Kind = enum(u32) {
1346 // Parameter Attributes1834 // Parameter Attributes
1347 zeroext = 34,1835 zeroext = @backingInt(ATTR_KIND.Z_EXT),
1348 signext = 24,1836 signext = @backingInt(ATTR_KIND.S_EXT),
1349 inreg = 5,1837 noext = @backingInt(ATTR_KIND.NO_EXT),
1350 byval = 3,1838 inreg = @backingInt(ATTR_KIND.IN_REG),
1351 byref = 69,1839 byval = @backingInt(ATTR_KIND.BY_VAL),
1352 preallocated = 65,1840 byref = @backingInt(ATTR_KIND.BYREF),
1353 inalloca = 38,1841 preallocated = @backingInt(ATTR_KIND.PREALLOCATED),
1354 sret = 29, // TODO: ?1842 inalloca = @backingInt(ATTR_KIND.IN_ALLOCA),
1355 elementtype = 77,1843 sret = @backingInt(ATTR_KIND.STRUCT_RET),
1356 @"align" = 1,1844 elementtype = @backingInt(ATTR_KIND.ELEMENTTYPE),
1357 @"noalias" = 9,1845 @"align" = @backingInt(ATTR_KIND.ALIGNMENT),
1358 nocapture = 11,1846 @"noalias" = @backingInt(ATTR_KIND.NO_ALIAS),
1359 nofree = 62,1847 nocapture = @backingInt(ATTR_KIND.NO_CAPTURE),
1360 nest = 8,1848 captures = @backingInt(ATTR_KIND.CAPTURES),
1361 returned = 22,1849 nofree = @backingInt(ATTR_KIND.NOFREE),
1362 nonnull = 39,1850 nest = @backingInt(ATTR_KIND.NEST),
1363 dereferenceable = 41,1851 returned = @backingInt(ATTR_KIND.RETURNED),
1364 dereferenceable_or_null = 42,1852 nonnull = @backingInt(ATTR_KIND.NON_NULL),
1365 swiftself = 46,1853 dereferenceable = @backingInt(ATTR_KIND.DEREFERENCEABLE),
1366 swiftasync = 75,1854 dereferenceable_or_null = @backingInt(ATTR_KIND.DEREFERENCEABLE_OR_NULL),
1367 swifterror = 47,1855 swiftself = @backingInt(ATTR_KIND.SWIFT_SELF),
1368 immarg = 60,1856 swiftasync = @backingInt(ATTR_KIND.SWIFT_ASYNC),
1369 noundef = 68,1857 swifterror = @backingInt(ATTR_KIND.SWIFT_ERROR),
1370 nofpclass = 87,1858 immarg = @backingInt(ATTR_KIND.IMMARG),
1371 alignstack = 25,1859 noundef = @backingInt(ATTR_KIND.NOUNDEF),
1372 allocalign = 80,1860 nofpclass = @backingInt(ATTR_KIND.NOFPCLASS),
1373 allocptr = 81,1861 alignstack = @backingInt(ATTR_KIND.STACK_ALIGNMENT),
1374 readnone = 20,1862 allocalign = @backingInt(ATTR_KIND.ALLOC_ALIGN),
1375 readonly = 21,1863 allocptr = @backingInt(ATTR_KIND.ALLOCATED_POINTER),
1376 writeonly = 52,1864 readnone = @backingInt(ATTR_KIND.READ_NONE),
1865 readonly = @backingInt(ATTR_KIND.READ_ONLY),
1866 writeonly = @backingInt(ATTR_KIND.WRITEONLY),
1867 writable = @backingInt(ATTR_KIND.WRITABLE),
1868 initializes = @backingInt(ATTR_KIND.INITIALIZES),
1869 dead_on_unwind = @backingInt(ATTR_KIND.DEAD_ON_UNWIND),
1870 dead_on_return = @backingInt(ATTR_KIND.DEAD_ON_RETURN),
1871 range = @backingInt(ATTR_KIND.RANGE),
13771872
1378 // Function Attributes1873 // Function Attributes
1379 //alignstack,1874 //alignstack = @intFromEnum(ATTR_KIND.STACK_ALIGNMENT),
1380 allockind = 82,1875 allockind = @backingInt(ATTR_KIND.ALLOC_KIND),
1381 allocsize = 51,1876 allocsize = @backingInt(ATTR_KIND.ALLOC_SIZE),
1382 alwaysinline = 2,1877 alwaysinline = @backingInt(ATTR_KIND.ALWAYS_INLINE),
1383 builtin = 35,1878 builtin = @backingInt(ATTR_KIND.BUILTIN),
1384 cold = 36,1879 cold = @backingInt(ATTR_KIND.COLD),
1385 convergent = 43,1880 convergent = @backingInt(ATTR_KIND.CONVERGENT),
1386 disable_sanitizer_information = 78,1881 disable_sanitizer_instrumentation = @backingInt(ATTR_KIND.DISABLE_SANITIZER_INSTRUMENTATION),
1387 fn_ret_thunk_extern = 84,1882 fn_ret_thunk_extern = @backingInt(ATTR_KIND.FNRETTHUNK_EXTERN),
1388 hot = 72,1883 hot = @backingInt(ATTR_KIND.HOT),
1389 inlinehint = 4,1884 inlinehint = @backingInt(ATTR_KIND.INLINE_HINT),
1390 jumptable = 40,1885 jumptable = @backingInt(ATTR_KIND.JUMP_TABLE),
1391 memory = 86,1886 memory = @backingInt(ATTR_KIND.MEMORY),
1392 minsize = 6,1887 minsize = @backingInt(ATTR_KIND.MIN_SIZE),
1393 naked = 7,1888 naked = @backingInt(ATTR_KIND.NAKED),
1394 nobuiltin = 10,1889 nobuiltin = @backingInt(ATTR_KIND.NO_BUILTIN),
1395 nocallback = 71,1890 nocallback = @backingInt(ATTR_KIND.NO_CALLBACK),
1396 noduplicate = 12,1891 nodivergencesource = @backingInt(ATTR_KIND.NO_DIVERGENCE_SOURCE),
1397 //nofree,1892 noduplicate = @backingInt(ATTR_KIND.NO_DUPLICATE),
1398 noimplicitfloat = 13,1893 //nofree = @intFromEnum(ATTR_KIND.NOFREE),
1399 @"noinline" = 14,1894 noimplicitfloat = @backingInt(ATTR_KIND.NO_IMPLICIT_FLOAT),
1400 nomerge = 66,1895 @"noinline" = @backingInt(ATTR_KIND.NO_INLINE),
1401 nonlazybind = 15,1896 nomerge = @backingInt(ATTR_KIND.NO_MERGE),
1402 noprofile = 73,1897 nonlazybind = @backingInt(ATTR_KIND.NON_LAZY_BIND),
1403 skipprofile = 85,1898 noprofile = @backingInt(ATTR_KIND.NO_PROFILE),
1404 noredzone = 16,1899 skipprofile = @backingInt(ATTR_KIND.SKIP_PROFILE),
1405 noreturn = 17,1900 noredzone = @backingInt(ATTR_KIND.NO_RED_ZONE),
1406 norecurse = 48,1901 noreturn = @backingInt(ATTR_KIND.NO_RETURN),
1407 willreturn = 61,1902 norecurse = @backingInt(ATTR_KIND.NO_RECURSE),
1408 nosync = 63,1903 willreturn = @backingInt(ATTR_KIND.WILLRETURN),
1409 nounwind = 18,1904 nosync = @backingInt(ATTR_KIND.NOSYNC),
1410 nosanitize_bounds = 79,1905 nounwind = @backingInt(ATTR_KIND.NO_UNWIND),
1411 nosanitize_coverage = 76,1906 nosanitize_bounds = @backingInt(ATTR_KIND.NO_SANITIZE_BOUNDS),
1412 null_pointer_is_valid = 67,1907 nosanitize_coverage = @backingInt(ATTR_KIND.NO_SANITIZE_COVERAGE),
1413 optforfuzzing = 57,1908 null_pointer_is_valid = @backingInt(ATTR_KIND.NULL_POINTER_IS_VALID),
1414 optnone = 37,1909 optdebug = @backingInt(ATTR_KIND.OPTIMIZE_FOR_DEBUGGING),
1415 optsize = 19,1910 optforfuzzing = @backingInt(ATTR_KIND.OPT_FOR_FUZZING),
1416 //preallocated,1911 optnone = @backingInt(ATTR_KIND.OPTIMIZE_NONE),
1417 returns_twice = 23,1912 optsize = @backingInt(ATTR_KIND.OPTIMIZE_FOR_SIZE),
1418 safestack = 44,1913 //preallocated = @intFromEnum(ATTR_KIND.PREALLOCATED),
1419 sanitize_address = 30,1914 returns_twice = @backingInt(ATTR_KIND.RETURNS_TWICE),
1420 sanitize_memory = 32,1915 safestack = @backingInt(ATTR_KIND.SAFESTACK),
1421 sanitize_thread = 31,1916 sanitize_address = @backingInt(ATTR_KIND.SANITIZE_ADDRESS),
1422 sanitize_hwaddress = 55,1917 sanitize_memory = @backingInt(ATTR_KIND.SANITIZE_MEMORY),
1423 sanitize_memtag = 64,1918 sanitize_thread = @backingInt(ATTR_KIND.SANITIZE_THREAD),
1424 speculative_load_hardening = 59,1919 sanitize_hwaddress = @backingInt(ATTR_KIND.SANITIZE_HWADDRESS),
1425 speculatable = 53,1920 sanitize_memtag = @backingInt(ATTR_KIND.SANITIZE_MEMTAG),
1426 ssp = 26,1921 sanitize_realtime = @backingInt(ATTR_KIND.SANITIZE_REALTIME),
1427 sspstrong = 28,1922 sanitize_realtime_blocking = @backingInt(ATTR_KIND.SANITIZE_REALTIME_BLOCKING),
1428 sspreq = 27,1923 sanitize_alloc_token = @backingInt(ATTR_KIND.SANITIZE_ALLOC_TOKEN),
1429 strictfp = 54,1924 speculative_load_hardening = @backingInt(ATTR_KIND.SPECULATIVE_LOAD_HARDENING),
1430 uwtable = 33,1925 speculatable = @backingInt(ATTR_KIND.SPECULATABLE),
1431 nocf_check = 56,1926 ssp = @backingInt(ATTR_KIND.STACK_PROTECT),
1432 shadowcallstack = 58,1927 sspstrong = @backingInt(ATTR_KIND.STACK_PROTECT_STRONG),
1433 mustprogress = 70,1928 sspreq = @backingInt(ATTR_KIND.STACK_PROTECT_REQ),
1434 vscale_range = 74,1929 strictfp = @backingInt(ATTR_KIND.STRICT_FP),
14351930 denormal_fpenv = @backingInt(ATTR_KIND.DENORMAL_FPENV),
1436 // Global Attributes1931 uwtable = @backingInt(ATTR_KIND.UW_TABLE),
1437 no_sanitize_address = 100,1932 nocf_check = @backingInt(ATTR_KIND.NOCF_CHECK),
1438 no_sanitize_hwaddress = 101,1933 shadowcallstack = @backingInt(ATTR_KIND.SHADOWCALLSTACK),
1439 //sanitize_memtag,1934 mustprogress = @backingInt(ATTR_KIND.MUSTPROGRESS),
1440 sanitize_address_dyninit = 102,1935 vscale_range = @backingInt(ATTR_KIND.VSCALE_RANGE),
1936 nooutline = @backingInt(ATTR_KIND.NOOUTLINE),
1937 nocreateundeforpoison = @backingInt(ATTR_KIND.NO_CREATE_UNDEF_OR_POISON),
14411938
1442 string = maxInt(u31),1939 string = maxInt(u31),
1443 none = maxInt(u32),1940 none = maxInt(u32),
...@@ -1447,16 +1944,128 @@ pub const Attribute = union(Kind) {...@@ -1447,16 +1944,128 @@ pub const Attribute = union(Kind) {
14471944
1448 pub fn fromString(str: String) Kind {1945 pub fn fromString(str: String) Kind {
1449 assert(!str.isAnon());1946 assert(!str.isAnon());
1450 const kind: Kind = @fromBackingInt(@intCast(@backingInt(str)));1947 const kind: Kind = @fromBackingInt(@backingInt(str));
1451 assert(kind != .none);1948 assert(kind != .none);
1452 return kind;1949 return kind;
1453 }1950 }
14541951
1455 fn toString(self: Kind) ?String {1952 fn toString(self: Kind) ?String {
1456 assert(self != .none);1953 assert(self != .none);
1457 const str: String = @fromBackingInt(@intCast(@backingInt(self)));1954 const str: String = @fromBackingInt(@backingInt(self));
1458 return if (str.isAnon()) null else str;1955 return if (str.isAnon()) null else str;
1459 }1956 }
1957
1958 /// enum AttributeKindCodes
1959 const ATTR_KIND = enum(u32) {
1960 ALIGNMENT = 1,
1961 ALWAYS_INLINE = 2,
1962 BY_VAL = 3,
1963 INLINE_HINT = 4,
1964 IN_REG = 5,
1965 MIN_SIZE = 6,
1966 NAKED = 7,
1967 NEST = 8,
1968 NO_ALIAS = 9,
1969 NO_BUILTIN = 10,
1970 NO_CAPTURE = 11,
1971 NO_DUPLICATE = 12,
1972 NO_IMPLICIT_FLOAT = 13,
1973 NO_INLINE = 14,
1974 NON_LAZY_BIND = 15,
1975 NO_RED_ZONE = 16,
1976 NO_RETURN = 17,
1977 NO_UNWIND = 18,
1978 OPTIMIZE_FOR_SIZE = 19,
1979 READ_NONE = 20,
1980 READ_ONLY = 21,
1981 RETURNED = 22,
1982 RETURNS_TWICE = 23,
1983 S_EXT = 24,
1984 STACK_ALIGNMENT = 25,
1985 STACK_PROTECT = 26,
1986 STACK_PROTECT_REQ = 27,
1987 STACK_PROTECT_STRONG = 28,
1988 STRUCT_RET = 29,
1989 SANITIZE_ADDRESS = 30,
1990 SANITIZE_THREAD = 31,
1991 SANITIZE_MEMORY = 32,
1992 UW_TABLE = 33,
1993 Z_EXT = 34,
1994 BUILTIN = 35,
1995 COLD = 36,
1996 OPTIMIZE_NONE = 37,
1997 IN_ALLOCA = 38,
1998 NON_NULL = 39,
1999 JUMP_TABLE = 40,
2000 DEREFERENCEABLE = 41,
2001 DEREFERENCEABLE_OR_NULL = 42,
2002 CONVERGENT = 43,
2003 SAFESTACK = 44,
2004 ARGMEMONLY = 45,
2005 SWIFT_SELF = 46,
2006 SWIFT_ERROR = 47,
2007 NO_RECURSE = 48,
2008 INACCESSIBLEMEM_ONLY = 49,
2009 INACCESSIBLEMEM_OR_ARGMEMONLY = 50,
2010 ALLOC_SIZE = 51,
2011 WRITEONLY = 52,
2012 SPECULATABLE = 53,
2013 STRICT_FP = 54,
2014 SANITIZE_HWADDRESS = 55,
2015 NOCF_CHECK = 56,
2016 OPT_FOR_FUZZING = 57,
2017 SHADOWCALLSTACK = 58,
2018 SPECULATIVE_LOAD_HARDENING = 59,
2019 IMMARG = 60,
2020 WILLRETURN = 61,
2021 NOFREE = 62,
2022 NOSYNC = 63,
2023 SANITIZE_MEMTAG = 64,
2024 PREALLOCATED = 65,
2025 NO_MERGE = 66,
2026 NULL_POINTER_IS_VALID = 67,
2027 NOUNDEF = 68,
2028 BYREF = 69,
2029 MUSTPROGRESS = 70,
2030 NO_CALLBACK = 71,
2031 HOT = 72,
2032 NO_PROFILE = 73,
2033 VSCALE_RANGE = 74,
2034 SWIFT_ASYNC = 75,
2035 NO_SANITIZE_COVERAGE = 76,
2036 ELEMENTTYPE = 77,
2037 DISABLE_SANITIZER_INSTRUMENTATION = 78,
2038 NO_SANITIZE_BOUNDS = 79,
2039 ALLOC_ALIGN = 80,
2040 ALLOCATED_POINTER = 81,
2041 ALLOC_KIND = 82,
2042 PRESPLIT_COROUTINE = 83,
2043 FNRETTHUNK_EXTERN = 84,
2044 SKIP_PROFILE = 85,
2045 MEMORY = 86,
2046 NOFPCLASS = 87,
2047 OPTIMIZE_FOR_DEBUGGING = 88,
2048 WRITABLE = 89,
2049 CORO_ONLY_DESTROY_WHEN_COMPLETE = 90,
2050 DEAD_ON_UNWIND = 91,
2051 RANGE = 92,
2052 SANITIZE_NUMERICAL_STABILITY = 93,
2053 INITIALIZES = 94,
2054 HYBRID_PATCHABLE = 95,
2055 SANITIZE_REALTIME = 96,
2056 SANITIZE_REALTIME_BLOCKING = 97,
2057 CORO_ELIDE_SAFE = 98,
2058 NO_EXT = 99,
2059 NO_DIVERGENCE_SOURCE = 100,
2060 SANITIZE_TYPE = 101,
2061 CAPTURES = 102,
2062 DEAD_ON_RETURN = 103,
2063 SANITIZE_ALLOC_TOKEN = 104,
2064 NO_CREATE_UNDEF_OR_POISON = 105,
2065 DENORMAL_FPENV = 106,
2066 NOOUTLINE = 107,
2067 FLATTEN = 108,
2068 };
1460 };2069 };
14612070
1462 pub const FpClass = packed struct(u32) {2071 pub const FpClass = packed struct(u32) {
...@@ -1506,6 +2115,29 @@ pub const Attribute = union(Kind) {...@@ -1506,6 +2115,29 @@ pub const Attribute = union(Kind) {
1506 pub const pnorm = FpClass{ .positive_normal = true };2115 pub const pnorm = FpClass{ .positive_normal = true };
1507 };2116 };
15082117
2118 pub const Captures = packed struct(u32) {
2119 other: Components = .none,
2120 ret: Components = .none,
2121 _: u24 = 0,
2122
2123 pub const none: Captures = .{};
2124
2125 pub const Components = packed struct(u4) {
2126 address_is_null: bool = false,
2127 address: bool = false,
2128 read_provenance: bool = false,
2129 provenance: bool = false,
2130
2131 pub const none: Components = .{};
2132 pub const all: Components = .{
2133 .address_is_null = true,
2134 .address = true,
2135 .read_provenance = true,
2136 .provenance = true,
2137 };
2138 };
2139 };
2140
1509 pub const AllocKind = packed struct(u32) {2141 pub const AllocKind = packed struct(u32) {
1510 alloc: bool,2142 alloc: bool,
1511 realloc: bool,2143 realloc: bool,
...@@ -1582,9 +2214,13 @@ pub const Attribute = union(Kind) {...@@ -1582,9 +2214,13 @@ pub const Attribute = union(Kind) {
1582 void => 0,2214 void => 0,
1583 u32 => value,2215 u32 => value,
1584 Alignment.Lazy, String, Type, UwTable => @backingInt(value),2216 Alignment.Lazy, String, Type, UwTable => @backingInt(value),
1585 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(value),2217 AllocKind, AllocSize, Captures, FpClass, Memory, VScaleRange => @bitCast(value),
1586 else => @compileError("bad payload type: " ++ @tagName(tag) ++ @typeName(@TypeOf(value))),2218 else => @compileError("bad payload type: " ++ @tagName(tag) ++ ": " ++ @typeName(@TypeOf(value))),
1587 } },2219 } },
2220 .initializes,
2221 .dead_on_return,
2222 .range,
2223 => @panic("TODO"),
1588 .string => |string_attr| .{2224 .string => |string_attr| .{
1589 .kind = Kind.fromString(string_attr.kind),2225 .kind = Kind.fromString(string_attr.kind),
1590 .value = @backingInt(string_attr.value),2226 .value = @backingInt(string_attr.value),
...@@ -1907,87 +2543,87 @@ pub const AddrSpace = enum(u24) {...@@ -1907,87 +2543,87 @@ pub const AddrSpace = enum(u24) {
19072543
1908 // See llvm/lib/Target/X86/X86.h2544 // See llvm/lib/Target/X86/X86.h
1909 pub const x86 = struct {2545 pub const x86 = struct {
1910 pub const gs: AddrSpace = @fromBackingInt(@intCast(256));2546 pub const gs: AddrSpace = @fromBackingInt(256);
1911 pub const fs: AddrSpace = @fromBackingInt(@intCast(257));2547 pub const fs: AddrSpace = @fromBackingInt(257);
1912 pub const ss: AddrSpace = @fromBackingInt(@intCast(258));2548 pub const ss: AddrSpace = @fromBackingInt(258);
19132549
1914 pub const ptr32_sptr: AddrSpace = @fromBackingInt(@intCast(270));2550 pub const ptr32_sptr: AddrSpace = @fromBackingInt(270);
1915 pub const ptr32_uptr: AddrSpace = @fromBackingInt(@intCast(271));2551 pub const ptr32_uptr: AddrSpace = @fromBackingInt(271);
1916 pub const ptr64: AddrSpace = @fromBackingInt(@intCast(272));2552 pub const ptr64: AddrSpace = @fromBackingInt(272);
1917 };2553 };
1918 pub const x86_64 = x86;2554 pub const x86_64 = x86;
19192555
1920 // See llvm/lib/Target/AVR/AVR.h2556 // See llvm/lib/Target/AVR/AVR.h
1921 pub const avr = struct {2557 pub const avr = struct {
1922 pub const data: AddrSpace = @fromBackingInt(@intCast(0));2558 pub const data: AddrSpace = @fromBackingInt(0);
1923 pub const program: AddrSpace = @fromBackingInt(@intCast(1));2559 pub const program: AddrSpace = @fromBackingInt(1);
1924 pub const program1: AddrSpace = @fromBackingInt(@intCast(2));2560 pub const program1: AddrSpace = @fromBackingInt(2);
1925 pub const program2: AddrSpace = @fromBackingInt(@intCast(3));2561 pub const program2: AddrSpace = @fromBackingInt(3);
1926 pub const program3: AddrSpace = @fromBackingInt(@intCast(4));2562 pub const program3: AddrSpace = @fromBackingInt(4);
1927 pub const program4: AddrSpace = @fromBackingInt(@intCast(5));2563 pub const program4: AddrSpace = @fromBackingInt(5);
1928 pub const program5: AddrSpace = @fromBackingInt(@intCast(6));2564 pub const program5: AddrSpace = @fromBackingInt(6);
1929 };2565 };
19302566
1931 // See llvm/lib/Target/NVPTX/NVPTX.h2567 // See llvm/lib/Target/NVPTX/NVPTX.h
1932 pub const nvptx = struct {2568 pub const nvptx = struct {
1933 pub const generic: AddrSpace = @fromBackingInt(@intCast(0));2569 pub const generic: AddrSpace = @fromBackingInt(0);
1934 pub const global: AddrSpace = @fromBackingInt(@intCast(1));2570 pub const global: AddrSpace = @fromBackingInt(1);
1935 pub const constant: AddrSpace = @fromBackingInt(@intCast(2));2571 pub const constant: AddrSpace = @fromBackingInt(2);
1936 pub const shared: AddrSpace = @fromBackingInt(@intCast(3));2572 pub const shared: AddrSpace = @fromBackingInt(3);
1937 pub const param: AddrSpace = @fromBackingInt(@intCast(4));2573 pub const param: AddrSpace = @fromBackingInt(4);
1938 pub const local: AddrSpace = @fromBackingInt(@intCast(5));2574 pub const local: AddrSpace = @fromBackingInt(5);
1939 };2575 };
19402576
1941 // See llvm/lib/Target/AMDGPU/AMDGPU.h2577 // See llvm/lib/Target/AMDGPU/AMDGPU.h
1942 pub const amdgpu = struct {2578 pub const amdgpu = struct {
1943 pub const flat: AddrSpace = @fromBackingInt(@intCast(0));2579 pub const flat: AddrSpace = @fromBackingInt(0);
1944 pub const global: AddrSpace = @fromBackingInt(@intCast(1));2580 pub const global: AddrSpace = @fromBackingInt(1);
1945 pub const region: AddrSpace = @fromBackingInt(@intCast(2));2581 pub const region: AddrSpace = @fromBackingInt(2);
1946 pub const local: AddrSpace = @fromBackingInt(@intCast(3));2582 pub const local: AddrSpace = @fromBackingInt(3);
1947 pub const constant: AddrSpace = @fromBackingInt(@intCast(4));2583 pub const constant: AddrSpace = @fromBackingInt(4);
1948 pub const private: AddrSpace = @fromBackingInt(@intCast(5));2584 pub const private: AddrSpace = @fromBackingInt(5);
1949 pub const constant_32bit: AddrSpace = @fromBackingInt(@intCast(6));2585 pub const constant_32bit: AddrSpace = @fromBackingInt(6);
1950 pub const buffer_fat_pointer: AddrSpace = @fromBackingInt(@intCast(7));2586 pub const buffer_fat_pointer: AddrSpace = @fromBackingInt(7);
1951 pub const buffer_resource: AddrSpace = @fromBackingInt(@intCast(8));2587 pub const buffer_resource: AddrSpace = @fromBackingInt(8);
1952 pub const buffer_strided_pointer: AddrSpace = @fromBackingInt(@intCast(9));2588 pub const buffer_strided_pointer: AddrSpace = @fromBackingInt(9);
1953 pub const param_d: AddrSpace = @fromBackingInt(@intCast(6));2589 pub const param_d: AddrSpace = @fromBackingInt(6);
1954 pub const param_i: AddrSpace = @fromBackingInt(@intCast(7));2590 pub const param_i: AddrSpace = @fromBackingInt(7);
1955 pub const constant_buffer_0: AddrSpace = @fromBackingInt(@intCast(8));2591 pub const constant_buffer_0: AddrSpace = @fromBackingInt(8);
1956 pub const constant_buffer_1: AddrSpace = @fromBackingInt(@intCast(9));2592 pub const constant_buffer_1: AddrSpace = @fromBackingInt(9);
1957 pub const constant_buffer_2: AddrSpace = @fromBackingInt(@intCast(10));2593 pub const constant_buffer_2: AddrSpace = @fromBackingInt(10);
1958 pub const constant_buffer_3: AddrSpace = @fromBackingInt(@intCast(11));2594 pub const constant_buffer_3: AddrSpace = @fromBackingInt(11);
1959 pub const constant_buffer_4: AddrSpace = @fromBackingInt(@intCast(12));2595 pub const constant_buffer_4: AddrSpace = @fromBackingInt(12);
1960 pub const constant_buffer_5: AddrSpace = @fromBackingInt(@intCast(13));2596 pub const constant_buffer_5: AddrSpace = @fromBackingInt(13);
1961 pub const constant_buffer_6: AddrSpace = @fromBackingInt(@intCast(14));2597 pub const constant_buffer_6: AddrSpace = @fromBackingInt(14);
1962 pub const constant_buffer_7: AddrSpace = @fromBackingInt(@intCast(15));2598 pub const constant_buffer_7: AddrSpace = @fromBackingInt(15);
1963 pub const constant_buffer_8: AddrSpace = @fromBackingInt(@intCast(16));2599 pub const constant_buffer_8: AddrSpace = @fromBackingInt(16);
1964 pub const constant_buffer_9: AddrSpace = @fromBackingInt(@intCast(17));2600 pub const constant_buffer_9: AddrSpace = @fromBackingInt(17);
1965 pub const constant_buffer_10: AddrSpace = @fromBackingInt(@intCast(18));2601 pub const constant_buffer_10: AddrSpace = @fromBackingInt(18);
1966 pub const constant_buffer_11: AddrSpace = @fromBackingInt(@intCast(19));2602 pub const constant_buffer_11: AddrSpace = @fromBackingInt(19);
1967 pub const constant_buffer_12: AddrSpace = @fromBackingInt(@intCast(20));2603 pub const constant_buffer_12: AddrSpace = @fromBackingInt(20);
1968 pub const constant_buffer_13: AddrSpace = @fromBackingInt(@intCast(21));2604 pub const constant_buffer_13: AddrSpace = @fromBackingInt(21);
1969 pub const constant_buffer_14: AddrSpace = @fromBackingInt(@intCast(22));2605 pub const constant_buffer_14: AddrSpace = @fromBackingInt(22);
1970 pub const constant_buffer_15: AddrSpace = @fromBackingInt(@intCast(23));2606 pub const constant_buffer_15: AddrSpace = @fromBackingInt(23);
1971 pub const streamout_register: AddrSpace = @fromBackingInt(@intCast(128));2607 pub const streamout_register: AddrSpace = @fromBackingInt(128);
1972 };2608 };
19732609
1974 pub const spirv = struct {2610 pub const spirv = struct {
1975 pub const function: AddrSpace = @fromBackingInt(@intCast(0));2611 pub const function: AddrSpace = @fromBackingInt(0);
1976 pub const cross_workgroup: AddrSpace = @fromBackingInt(@intCast(1));2612 pub const cross_workgroup: AddrSpace = @fromBackingInt(1);
1977 pub const uniform_constant: AddrSpace = @fromBackingInt(@intCast(2));2613 pub const uniform_constant: AddrSpace = @fromBackingInt(2);
1978 pub const workgroup: AddrSpace = @fromBackingInt(@intCast(3));2614 pub const workgroup: AddrSpace = @fromBackingInt(3);
1979 pub const generic: AddrSpace = @fromBackingInt(@intCast(4));2615 pub const generic: AddrSpace = @fromBackingInt(4);
1980 pub const device_only_intel: AddrSpace = @fromBackingInt(@intCast(5));2616 pub const device_only_intel: AddrSpace = @fromBackingInt(5);
1981 pub const host_only_intel: AddrSpace = @fromBackingInt(@intCast(6));2617 pub const host_only_intel: AddrSpace = @fromBackingInt(6);
1982 pub const input: AddrSpace = @fromBackingInt(@intCast(7));2618 pub const input: AddrSpace = @fromBackingInt(7);
1983 };2619 };
19842620
1985 // See llvm/include/llvm/CodeGen/WasmAddressSpaces.h2621 // See llvm/include/llvm/CodeGen/WasmAddressSpaces.h
1986 pub const wasm = struct {2622 pub const wasm = struct {
1987 pub const default: AddrSpace = @fromBackingInt(@intCast(0));2623 pub const default: AddrSpace = @fromBackingInt(0);
1988 pub const variable: AddrSpace = @fromBackingInt(@intCast(1));2624 pub const variable: AddrSpace = @fromBackingInt(1);
1989 pub const externref: AddrSpace = @fromBackingInt(@intCast(10));2625 pub const externref: AddrSpace = @fromBackingInt(10);
1990 pub const funcref: AddrSpace = @fromBackingInt(@intCast(20));2626 pub const funcref: AddrSpace = @fromBackingInt(20);
1991 };2627 };
19922628
1993 pub fn format(addr_space: AddrSpace, w: *Writer) Writer.Error!void {2629 pub fn format(addr_space: AddrSpace, w: *Writer) Writer.Error!void {
...@@ -2030,7 +2666,7 @@ pub const Alignment = enum(u6) {...@@ -2030,7 +2666,7 @@ pub const Alignment = enum(u6) {
2030 _,2666 _,
20312667
2032 pub fn wrap(a: Alignment) Lazy {2668 pub fn wrap(a: Alignment) Lazy {
2033 return @fromBackingInt(@intCast(@backingInt(a)));2669 return @fromBackingInt(@backingInt(a));
2034 }2670 }
2035 pub fn resolve(l: Lazy, b: *const Builder) Alignment {2671 pub fn resolve(l: Lazy, b: *const Builder) Alignment {
2036 return switch (@backingInt(l)) {2672 return switch (@backingInt(l)) {
...@@ -2061,11 +2697,18 @@ pub const Alignment = enum(u6) {...@@ -2061,11 +2697,18 @@ pub const Alignment = enum(u6) {
2061 };2697 };
2062 }2698 }
20632699
2064 /// Asserts that neither `a` nor `b` is `.default`.2700 /// Asserts that neither `lhs` nor `rhs` is `.default`.
2065 pub fn max(a: Alignment, b: Alignment) Alignment {2701 pub fn max(lhs: Alignment, rhs: Alignment) Alignment {
2066 assert(a != .default);2702 assert(lhs != .default);
2067 assert(b != .default);2703 assert(rhs != .default);
2068 return @fromBackingInt(@intCast(@max(@backingInt(a), @backingInt(b))));2704 return @fromBackingInt(@max(@backingInt(lhs), @backingInt(rhs)));
2705 }
2706
2707 /// Asserts that neither `lhs` nor `rhs` is `.default`.
2708 pub fn order(lhs: Alignment, rhs: Alignment) std.math.Order {
2709 assert(lhs != .default);
2710 assert(rhs != .default);
2711 return std.math.order(@backingInt(lhs), @backingInt(rhs));
2069 }2712 }
20702713
2071 pub fn toLlvm(self: Alignment) u6 {2714 pub fn toLlvm(self: Alignment) u6 {
...@@ -2261,8 +2904,7 @@ pub const StrtabString = enum(u32) {...@@ -2261,8 +2904,7 @@ pub const StrtabString = enum(u32) {
2261 }2904 }
22622905
2263 fn fromIndex(index: ?usize) StrtabString {2906 fn fromIndex(index: ?usize) StrtabString {
2264 return @fromBackingInt(@intCast(@as(u32, @intCast((index orelse return .none) +2907 return @fromBackingInt(@intCast((index orelse return .none) + @backingInt(StrtabString.empty)));
2265 @backingInt(StrtabString.empty)))));
2266 }2908 }
22672909
2268 fn toIndex(self: StrtabString) ?usize {2910 fn toIndex(self: StrtabString) ?usize {
...@@ -2398,7 +3040,7 @@ pub const Global = struct {...@@ -2398,7 +3040,7 @@ pub const Global = struct {
2398 }3040 }
23993041
2400 pub fn toConst(global: Index) Constant {3042 pub fn toConst(global: Index) Constant {
2401 return @fromBackingInt(@intCast(@backingInt(Constant.first_global) + @backingInt(global)));3043 return @fromBackingInt(@backingInt(Constant.first_global) + @backingInt(global));
2402 }3044 }
24033045
2404 pub fn toValue(global: Index) Value {3046 pub fn toValue(global: Index) Value {
...@@ -2526,7 +3168,7 @@ pub const Global = struct {...@@ -2526,7 +3168,7 @@ pub const Global = struct {
2526 _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]);3168 _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]);
2527 builder.globals.swapRemoveAt(index);3169 builder.globals.swapRemoveAt(index);
2528 if (!old_name.isAnon()) return;3170 if (!old_name.isAnon()) return;
2529 builder.next_unnamed_global = @fromBackingInt(@intCast(@backingInt(builder.next_unnamed_global) - 1));3171 builder.next_unnamed_global = @fromBackingInt(@backingInt(builder.next_unnamed_global) - 1);
2530 if (builder.next_unnamed_global == old_name) return;3172 if (builder.next_unnamed_global == old_name) return;
2531 builder.getGlobal(builder.next_unnamed_global).?.renameAssumeCapacity(old_name, builder);3173 builder.getGlobal(builder.next_unnamed_global).?.renameAssumeCapacity(old_name, builder);
2532 }3174 }
...@@ -2539,7 +3181,7 @@ pub const Global = struct {...@@ -2539,7 +3181,7 @@ pub const Global = struct {
25393181
2540 fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void {3182 fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void {
2541 if (self.eql(other, builder)) return;3183 if (self.eql(other, builder)) return;
2542 builder.next_replaced_global = @fromBackingInt(@intCast(@backingInt(builder.next_replaced_global) - 1));3184 builder.next_replaced_global = @fromBackingInt(@backingInt(builder.next_replaced_global) - 1);
2543 self.renameAssumeCapacity(builder.next_replaced_global, builder);3185 self.renameAssumeCapacity(builder.next_replaced_global, builder);
2544 self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) };3186 self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) };
2545 }3187 }
...@@ -2699,6 +3341,8 @@ pub const Intrinsic = enum {...@@ -2699,6 +3341,8 @@ pub const Intrinsic = enum {
2699 smin,3341 smin,
2700 umax,3342 umax,
2701 umin,3343 umin,
3344 scmp,
3345 ucmp,
2702 memcpy,3346 memcpy,
2703 @"memcpy.inline",3347 @"memcpy.inline",
2704 memmove,3348 memmove,
...@@ -2708,10 +3352,21 @@ pub const Intrinsic = enum {...@@ -2708,10 +3352,21 @@ pub const Intrinsic = enum {
2708 powi,3352 powi,
2709 sin,3353 sin,
2710 cos,3354 cos,
3355 tan,
3356 asin,
3357 acos,
3358 atan,
3359 atan2,
3360 sinh,
3361 cosh,
3362 tanh,
3363 sincos,
3364 sincospi,
3365 modf,
2711 pow,3366 pow,
2712 exp,3367 exp,
2713 exp10,
2714 exp2,3368 exp2,
3369 exp10,
2715 ldexp,3370 ldexp,
2716 frexp,3371 frexp,
2717 log,3372 log,
...@@ -2723,6 +3378,8 @@ pub const Intrinsic = enum {...@@ -2723,6 +3378,8 @@ pub const Intrinsic = enum {
2723 maxnum,3378 maxnum,
2724 minimum,3379 minimum,
2725 maximum,3380 maximum,
3381 minimumnum,
3382 maximumnum,
2726 copysign,3383 copysign,
2727 floor,3384 floor,
2728 ceil,3385 ceil,
...@@ -2744,6 +3401,7 @@ pub const Intrinsic = enum {...@@ -2744,6 +3401,7 @@ pub const Intrinsic = enum {
2744 cttz,3401 cttz,
2745 fshl,3402 fshl,
2746 fshr,3403 fshr,
3404 clmul,
27473405
2748 // Arithmetic with Overflow3406 // Arithmetic with Overflow
2749 @"sadd.with.overflow",3407 @"sadd.with.overflow",
...@@ -2904,21 +3562,21 @@ pub const Intrinsic = enum {...@@ -2904,21 +3562,21 @@ pub const Intrinsic = enum {
2904 .{ .kind = .{ .type = .ptr } },3562 .{ .kind = .{ .type = .ptr } },
2905 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },3563 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2906 },3564 },
2907 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3565 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
2908 },3566 },
2909 .addressofreturnaddress = .{3567 .addressofreturnaddress = .{
2910 .ret_len = 1,3568 .ret_len = 1,
2911 .params = &.{3569 .params = &.{
2912 .{ .kind = .overloaded },3570 .{ .kind = .overloaded },
2913 },3571 },
2914 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3572 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
2915 },3573 },
2916 .sponentry = .{3574 .sponentry = .{
2917 .ret_len = 1,3575 .ret_len = 1,
2918 .params = &.{3576 .params = &.{
2919 .{ .kind = .overloaded },3577 .{ .kind = .overloaded },
2920 },3578 },
2921 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3579 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
2922 },3580 },
2923 .frameaddress = .{3581 .frameaddress = .{
2924 .ret_len = 1,3582 .ret_len = 1,
...@@ -2926,7 +3584,7 @@ pub const Intrinsic = enum {...@@ -2926,7 +3584,7 @@ pub const Intrinsic = enum {
2926 .{ .kind = .overloaded },3584 .{ .kind = .overloaded },
2927 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },3585 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2928 },3586 },
2929 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3587 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
2930 },3588 },
2931 .prefetch = .{3589 .prefetch = .{
2932 .ret_len = 0,3590 .ret_len = 0,
...@@ -2936,14 +3594,14 @@ pub const Intrinsic = enum {...@@ -2936,14 +3594,14 @@ pub const Intrinsic = enum {
2936 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },3594 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2937 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },3595 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2938 },3596 },
2939 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.readwrite) } },3597 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.readwrite) } },
2940 },3598 },
2941 .@"thread.pointer" = .{3599 .@"thread.pointer" = .{
2942 .ret_len = 1,3600 .ret_len = 1,
2943 .params = &.{3601 .params = &.{
2944 .{ .kind = .{ .type = .ptr } },3602 .{ .kind = .{ .type = .ptr } },
2945 },3603 },
2946 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3604 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
2947 },3605 },
29483606
2949 .abs = .{3607 .abs = .{
...@@ -2953,7 +3611,7 @@ pub const Intrinsic = enum {...@@ -2953,7 +3611,7 @@ pub const Intrinsic = enum {
2953 .{ .kind = .{ .matches = 0 } },3611 .{ .kind = .{ .matches = 0 } },
2954 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },3612 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
2955 },3613 },
2956 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3614 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
2957 },3615 },
2958 .smax = .{3616 .smax = .{
2959 .ret_len = 1,3617 .ret_len = 1,
...@@ -2962,7 +3620,7 @@ pub const Intrinsic = enum {...@@ -2962,7 +3620,7 @@ pub const Intrinsic = enum {
2962 .{ .kind = .{ .matches = 0 } },3620 .{ .kind = .{ .matches = 0 } },
2963 .{ .kind = .{ .matches = 0 } },3621 .{ .kind = .{ .matches = 0 } },
2964 },3622 },
2965 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3623 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
2966 },3624 },
2967 .smin = .{3625 .smin = .{
2968 .ret_len = 1,3626 .ret_len = 1,
...@@ -2971,7 +3629,7 @@ pub const Intrinsic = enum {...@@ -2971,7 +3629,7 @@ pub const Intrinsic = enum {
2971 .{ .kind = .{ .matches = 0 } },3629 .{ .kind = .{ .matches = 0 } },
2972 .{ .kind = .{ .matches = 0 } },3630 .{ .kind = .{ .matches = 0 } },
2973 },3631 },
2974 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3632 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
2975 },3633 },
2976 .umax = .{3634 .umax = .{
2977 .ret_len = 1,3635 .ret_len = 1,
...@@ -2980,7 +3638,7 @@ pub const Intrinsic = enum {...@@ -2980,7 +3638,7 @@ pub const Intrinsic = enum {
2980 .{ .kind = .{ .matches = 0 } },3638 .{ .kind = .{ .matches = 0 } },
2981 .{ .kind = .{ .matches = 0 } },3639 .{ .kind = .{ .matches = 0 } },
2982 },3640 },
2983 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3641 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
2984 },3642 },
2985 .umin = .{3643 .umin = .{
2986 .ret_len = 1,3644 .ret_len = 1,
...@@ -2989,7 +3647,25 @@ pub const Intrinsic = enum {...@@ -2989,7 +3647,25 @@ pub const Intrinsic = enum {
2989 .{ .kind = .{ .matches = 0 } },3647 .{ .kind = .{ .matches = 0 } },
2990 .{ .kind = .{ .matches = 0 } },3648 .{ .kind = .{ .matches = 0 } },
2991 },3649 },
2992 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3650 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3651 },
3652 .scmp = .{
3653 .ret_len = 1,
3654 .params = &.{
3655 .{ .kind = .overloaded },
3656 .{ .kind = .overloaded },
3657 .{ .kind = .{ .matches = 1 } },
3658 },
3659 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3660 },
3661 .ucmp = .{
3662 .ret_len = 1,
3663 .params = &.{
3664 .{ .kind = .overloaded },
3665 .{ .kind = .overloaded },
3666 .{ .kind = .{ .matches = 1 } },
3667 },
3668 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
2993 },3669 },
2994 .memcpy = .{3670 .memcpy = .{
2995 .ret_len = 0,3671 .ret_len = 0,
...@@ -3047,7 +3723,7 @@ pub const Intrinsic = enum {...@@ -3047,7 +3723,7 @@ pub const Intrinsic = enum {
3047 .{ .kind = .overloaded },3723 .{ .kind = .overloaded },
3048 .{ .kind = .{ .matches = 0 } },3724 .{ .kind = .{ .matches = 0 } },
3049 },3725 },
3050 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3726 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3051 },3727 },
3052 .powi = .{3728 .powi = .{
3053 .ret_len = 1,3729 .ret_len = 1,
...@@ -3056,7 +3732,7 @@ pub const Intrinsic = enum {...@@ -3056,7 +3732,7 @@ pub const Intrinsic = enum {
3056 .{ .kind = .{ .matches = 0 } },3732 .{ .kind = .{ .matches = 0 } },
3057 .{ .kind = .overloaded },3733 .{ .kind = .overloaded },
3058 },3734 },
3059 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3735 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3060 },3736 },
3061 .sin = .{3737 .sin = .{
3062 .ret_len = 1,3738 .ret_len = 1,
...@@ -3064,7 +3740,7 @@ pub const Intrinsic = enum {...@@ -3064,7 +3740,7 @@ pub const Intrinsic = enum {
3064 .{ .kind = .overloaded },3740 .{ .kind = .overloaded },
3065 .{ .kind = .{ .matches = 0 } },3741 .{ .kind = .{ .matches = 0 } },
3066 },3742 },
3067 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3743 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3068 },3744 },
3069 .cos = .{3745 .cos = .{
3070 .ret_len = 1,3746 .ret_len = 1,
...@@ -3072,7 +3748,99 @@ pub const Intrinsic = enum {...@@ -3072,7 +3748,99 @@ pub const Intrinsic = enum {
3072 .{ .kind = .overloaded },3748 .{ .kind = .overloaded },
3073 .{ .kind = .{ .matches = 0 } },3749 .{ .kind = .{ .matches = 0 } },
3074 },3750 },
3075 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3751 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3752 },
3753 .tan = .{
3754 .ret_len = 1,
3755 .params = &.{
3756 .{ .kind = .overloaded },
3757 .{ .kind = .{ .matches = 0 } },
3758 },
3759 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3760 },
3761 .asin = .{
3762 .ret_len = 1,
3763 .params = &.{
3764 .{ .kind = .overloaded },
3765 .{ .kind = .{ .matches = 0 } },
3766 },
3767 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3768 },
3769 .acos = .{
3770 .ret_len = 1,
3771 .params = &.{
3772 .{ .kind = .overloaded },
3773 .{ .kind = .{ .matches = 0 } },
3774 },
3775 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3776 },
3777 .atan = .{
3778 .ret_len = 1,
3779 .params = &.{
3780 .{ .kind = .overloaded },
3781 .{ .kind = .{ .matches = 0 } },
3782 },
3783 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3784 },
3785 .atan2 = .{
3786 .ret_len = 1,
3787 .params = &.{
3788 .{ .kind = .overloaded },
3789 .{ .kind = .{ .matches = 0 } },
3790 .{ .kind = .{ .matches = 0 } },
3791 },
3792 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3793 },
3794 .sinh = .{
3795 .ret_len = 1,
3796 .params = &.{
3797 .{ .kind = .overloaded },
3798 .{ .kind = .{ .matches = 0 } },
3799 },
3800 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3801 },
3802 .cosh = .{
3803 .ret_len = 1,
3804 .params = &.{
3805 .{ .kind = .overloaded },
3806 .{ .kind = .{ .matches = 0 } },
3807 },
3808 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3809 },
3810 .tanh = .{
3811 .ret_len = 1,
3812 .params = &.{
3813 .{ .kind = .overloaded },
3814 .{ .kind = .{ .matches = 0 } },
3815 },
3816 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3817 },
3818 .sincos = .{
3819 .ret_len = 2,
3820 .params = &.{
3821 .{ .kind = .overloaded },
3822 .{ .kind = .{ .matches = 0 } },
3823 .{ .kind = .{ .matches = 0 } },
3824 },
3825 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3826 },
3827 .sincospi = .{
3828 .ret_len = 2,
3829 .params = &.{
3830 .{ .kind = .overloaded },
3831 .{ .kind = .{ .matches = 0 } },
3832 .{ .kind = .{ .matches = 0 } },
3833 },
3834 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3835 },
3836 .modf = .{
3837 .ret_len = 2,
3838 .params = &.{
3839 .{ .kind = .overloaded },
3840 .{ .kind = .{ .matches = 0 } },
3841 .{ .kind = .{ .matches = 0 } },
3842 },
3843 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3076 },3844 },
3077 .pow = .{3845 .pow = .{
3078 .ret_len = 1,3846 .ret_len = 1,
...@@ -3081,7 +3849,7 @@ pub const Intrinsic = enum {...@@ -3081,7 +3849,7 @@ pub const Intrinsic = enum {
3081 .{ .kind = .{ .matches = 0 } },3849 .{ .kind = .{ .matches = 0 } },
3082 .{ .kind = .{ .matches = 0 } },3850 .{ .kind = .{ .matches = 0 } },
3083 },3851 },
3084 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3852 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3085 },3853 },
3086 .exp = .{3854 .exp = .{
3087 .ret_len = 1,3855 .ret_len = 1,
...@@ -3089,7 +3857,7 @@ pub const Intrinsic = enum {...@@ -3089,7 +3857,7 @@ pub const Intrinsic = enum {
3089 .{ .kind = .overloaded },3857 .{ .kind = .overloaded },
3090 .{ .kind = .{ .matches = 0 } },3858 .{ .kind = .{ .matches = 0 } },
3091 },3859 },
3092 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3860 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3093 },3861 },
3094 .exp2 = .{3862 .exp2 = .{
3095 .ret_len = 1,3863 .ret_len = 1,
...@@ -3097,7 +3865,7 @@ pub const Intrinsic = enum {...@@ -3097,7 +3865,7 @@ pub const Intrinsic = enum {
3097 .{ .kind = .overloaded },3865 .{ .kind = .overloaded },
3098 .{ .kind = .{ .matches = 0 } },3866 .{ .kind = .{ .matches = 0 } },
3099 },3867 },
3100 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3868 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3101 },3869 },
3102 .exp10 = .{3870 .exp10 = .{
3103 .ret_len = 1,3871 .ret_len = 1,
...@@ -3105,7 +3873,7 @@ pub const Intrinsic = enum {...@@ -3105,7 +3873,7 @@ pub const Intrinsic = enum {
3105 .{ .kind = .overloaded },3873 .{ .kind = .overloaded },
3106 .{ .kind = .{ .matches = 0 } },3874 .{ .kind = .{ .matches = 0 } },
3107 },3875 },
3108 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3876 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3109 },3877 },
3110 .ldexp = .{3878 .ldexp = .{
3111 .ret_len = 1,3879 .ret_len = 1,
...@@ -3114,7 +3882,7 @@ pub const Intrinsic = enum {...@@ -3114,7 +3882,7 @@ pub const Intrinsic = enum {
3114 .{ .kind = .{ .matches = 0 } },3882 .{ .kind = .{ .matches = 0 } },
3115 .{ .kind = .overloaded },3883 .{ .kind = .overloaded },
3116 },3884 },
3117 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3885 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3118 },3886 },
3119 .frexp = .{3887 .frexp = .{
3120 .ret_len = 2,3888 .ret_len = 2,
...@@ -3123,7 +3891,7 @@ pub const Intrinsic = enum {...@@ -3123,7 +3891,7 @@ pub const Intrinsic = enum {
3123 .{ .kind = .overloaded },3891 .{ .kind = .overloaded },
3124 .{ .kind = .{ .matches = 0 } },3892 .{ .kind = .{ .matches = 0 } },
3125 },3893 },
3126 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3894 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3127 },3895 },
3128 .log = .{3896 .log = .{
3129 .ret_len = 1,3897 .ret_len = 1,
...@@ -3131,7 +3899,7 @@ pub const Intrinsic = enum {...@@ -3131,7 +3899,7 @@ pub const Intrinsic = enum {
3131 .{ .kind = .overloaded },3899 .{ .kind = .overloaded },
3132 .{ .kind = .{ .matches = 0 } },3900 .{ .kind = .{ .matches = 0 } },
3133 },3901 },
3134 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3902 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3135 },3903 },
3136 .log10 = .{3904 .log10 = .{
3137 .ret_len = 1,3905 .ret_len = 1,
...@@ -3139,7 +3907,7 @@ pub const Intrinsic = enum {...@@ -3139,7 +3907,7 @@ pub const Intrinsic = enum {
3139 .{ .kind = .overloaded },3907 .{ .kind = .overloaded },
3140 .{ .kind = .{ .matches = 0 } },3908 .{ .kind = .{ .matches = 0 } },
3141 },3909 },
3142 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3910 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3143 },3911 },
3144 .log2 = .{3912 .log2 = .{
3145 .ret_len = 1,3913 .ret_len = 1,
...@@ -3147,7 +3915,7 @@ pub const Intrinsic = enum {...@@ -3147,7 +3915,7 @@ pub const Intrinsic = enum {
3147 .{ .kind = .overloaded },3915 .{ .kind = .overloaded },
3148 .{ .kind = .{ .matches = 0 } },3916 .{ .kind = .{ .matches = 0 } },
3149 },3917 },
3150 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3918 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3151 },3919 },
3152 .fma = .{3920 .fma = .{
3153 .ret_len = 1,3921 .ret_len = 1,
...@@ -3157,7 +3925,7 @@ pub const Intrinsic = enum {...@@ -3157,7 +3925,7 @@ pub const Intrinsic = enum {
3157 .{ .kind = .{ .matches = 0 } },3925 .{ .kind = .{ .matches = 0 } },
3158 .{ .kind = .{ .matches = 0 } },3926 .{ .kind = .{ .matches = 0 } },
3159 },3927 },
3160 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3928 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3161 },3929 },
3162 .fabs = .{3930 .fabs = .{
3163 .ret_len = 1,3931 .ret_len = 1,
...@@ -3165,7 +3933,7 @@ pub const Intrinsic = enum {...@@ -3165,7 +3933,7 @@ pub const Intrinsic = enum {
3165 .{ .kind = .overloaded },3933 .{ .kind = .overloaded },
3166 .{ .kind = .{ .matches = 0 } },3934 .{ .kind = .{ .matches = 0 } },
3167 },3935 },
3168 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3936 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3169 },3937 },
3170 .minnum = .{3938 .minnum = .{
3171 .ret_len = 1,3939 .ret_len = 1,
...@@ -3174,7 +3942,7 @@ pub const Intrinsic = enum {...@@ -3174,7 +3942,7 @@ pub const Intrinsic = enum {
3174 .{ .kind = .{ .matches = 0 } },3942 .{ .kind = .{ .matches = 0 } },
3175 .{ .kind = .{ .matches = 0 } },3943 .{ .kind = .{ .matches = 0 } },
3176 },3944 },
3177 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3945 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3178 },3946 },
3179 .maxnum = .{3947 .maxnum = .{
3180 .ret_len = 1,3948 .ret_len = 1,
...@@ -3183,7 +3951,7 @@ pub const Intrinsic = enum {...@@ -3183,7 +3951,7 @@ pub const Intrinsic = enum {
3183 .{ .kind = .{ .matches = 0 } },3951 .{ .kind = .{ .matches = 0 } },
3184 .{ .kind = .{ .matches = 0 } },3952 .{ .kind = .{ .matches = 0 } },
3185 },3953 },
3186 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3954 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3187 },3955 },
3188 .minimum = .{3956 .minimum = .{
3189 .ret_len = 1,3957 .ret_len = 1,
...@@ -3192,7 +3960,7 @@ pub const Intrinsic = enum {...@@ -3192,7 +3960,7 @@ pub const Intrinsic = enum {
3192 .{ .kind = .{ .matches = 0 } },3960 .{ .kind = .{ .matches = 0 } },
3193 .{ .kind = .{ .matches = 0 } },3961 .{ .kind = .{ .matches = 0 } },
3194 },3962 },
3195 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3963 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3196 },3964 },
3197 .maximum = .{3965 .maximum = .{
3198 .ret_len = 1,3966 .ret_len = 1,
...@@ -3201,7 +3969,25 @@ pub const Intrinsic = enum {...@@ -3201,7 +3969,25 @@ pub const Intrinsic = enum {
3201 .{ .kind = .{ .matches = 0 } },3969 .{ .kind = .{ .matches = 0 } },
3202 .{ .kind = .{ .matches = 0 } },3970 .{ .kind = .{ .matches = 0 } },
3203 },3971 },
3204 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3972 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3973 },
3974 .minimumnum = .{
3975 .ret_len = 1,
3976 .params = &.{
3977 .{ .kind = .overloaded },
3978 .{ .kind = .{ .matches = 0 } },
3979 .{ .kind = .{ .matches = 0 } },
3980 },
3981 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3982 },
3983 .maximumnum = .{
3984 .ret_len = 1,
3985 .params = &.{
3986 .{ .kind = .overloaded },
3987 .{ .kind = .{ .matches = 0 } },
3988 .{ .kind = .{ .matches = 0 } },
3989 },
3990 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3205 },3991 },
3206 .copysign = .{3992 .copysign = .{
3207 .ret_len = 1,3993 .ret_len = 1,
...@@ -3210,7 +3996,7 @@ pub const Intrinsic = enum {...@@ -3210,7 +3996,7 @@ pub const Intrinsic = enum {
3210 .{ .kind = .{ .matches = 0 } },3996 .{ .kind = .{ .matches = 0 } },
3211 .{ .kind = .{ .matches = 0 } },3997 .{ .kind = .{ .matches = 0 } },
3212 },3998 },
3213 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3999 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3214 },4000 },
3215 .floor = .{4001 .floor = .{
3216 .ret_len = 1,4002 .ret_len = 1,
...@@ -3218,7 +4004,7 @@ pub const Intrinsic = enum {...@@ -3218,7 +4004,7 @@ pub const Intrinsic = enum {
3218 .{ .kind = .overloaded },4004 .{ .kind = .overloaded },
3219 .{ .kind = .{ .matches = 0 } },4005 .{ .kind = .{ .matches = 0 } },
3220 },4006 },
3221 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4007 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3222 },4008 },
3223 .ceil = .{4009 .ceil = .{
3224 .ret_len = 1,4010 .ret_len = 1,
...@@ -3226,7 +4012,7 @@ pub const Intrinsic = enum {...@@ -3226,7 +4012,7 @@ pub const Intrinsic = enum {
3226 .{ .kind = .overloaded },4012 .{ .kind = .overloaded },
3227 .{ .kind = .{ .matches = 0 } },4013 .{ .kind = .{ .matches = 0 } },
3228 },4014 },
3229 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4015 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3230 },4016 },
3231 .trunc = .{4017 .trunc = .{
3232 .ret_len = 1,4018 .ret_len = 1,
...@@ -3234,7 +4020,7 @@ pub const Intrinsic = enum {...@@ -3234,7 +4020,7 @@ pub const Intrinsic = enum {
3234 .{ .kind = .overloaded },4020 .{ .kind = .overloaded },
3235 .{ .kind = .{ .matches = 0 } },4021 .{ .kind = .{ .matches = 0 } },
3236 },4022 },
3237 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4023 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3238 },4024 },
3239 .rint = .{4025 .rint = .{
3240 .ret_len = 1,4026 .ret_len = 1,
...@@ -3242,7 +4028,7 @@ pub const Intrinsic = enum {...@@ -3242,7 +4028,7 @@ pub const Intrinsic = enum {
3242 .{ .kind = .overloaded },4028 .{ .kind = .overloaded },
3243 .{ .kind = .{ .matches = 0 } },4029 .{ .kind = .{ .matches = 0 } },
3244 },4030 },
3245 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4031 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3246 },4032 },
3247 .nearbyint = .{4033 .nearbyint = .{
3248 .ret_len = 1,4034 .ret_len = 1,
...@@ -3250,7 +4036,7 @@ pub const Intrinsic = enum {...@@ -3250,7 +4036,7 @@ pub const Intrinsic = enum {
3250 .{ .kind = .overloaded },4036 .{ .kind = .overloaded },
3251 .{ .kind = .{ .matches = 0 } },4037 .{ .kind = .{ .matches = 0 } },
3252 },4038 },
3253 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4039 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3254 },4040 },
3255 .round = .{4041 .round = .{
3256 .ret_len = 1,4042 .ret_len = 1,
...@@ -3258,7 +4044,7 @@ pub const Intrinsic = enum {...@@ -3258,7 +4044,7 @@ pub const Intrinsic = enum {
3258 .{ .kind = .overloaded },4044 .{ .kind = .overloaded },
3259 .{ .kind = .{ .matches = 0 } },4045 .{ .kind = .{ .matches = 0 } },
3260 },4046 },
3261 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4047 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3262 },4048 },
3263 .roundeven = .{4049 .roundeven = .{
3264 .ret_len = 1,4050 .ret_len = 1,
...@@ -3266,7 +4052,7 @@ pub const Intrinsic = enum {...@@ -3266,7 +4052,7 @@ pub const Intrinsic = enum {
3266 .{ .kind = .overloaded },4052 .{ .kind = .overloaded },
3267 .{ .kind = .{ .matches = 0 } },4053 .{ .kind = .{ .matches = 0 } },
3268 },4054 },
3269 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4055 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3270 },4056 },
3271 .lround = .{4057 .lround = .{
3272 .ret_len = 1,4058 .ret_len = 1,
...@@ -3274,7 +4060,7 @@ pub const Intrinsic = enum {...@@ -3274,7 +4060,7 @@ pub const Intrinsic = enum {
3274 .{ .kind = .overloaded },4060 .{ .kind = .overloaded },
3275 .{ .kind = .overloaded },4061 .{ .kind = .overloaded },
3276 },4062 },
3277 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4063 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3278 },4064 },
3279 .llround = .{4065 .llround = .{
3280 .ret_len = 1,4066 .ret_len = 1,
...@@ -3282,7 +4068,7 @@ pub const Intrinsic = enum {...@@ -3282,7 +4068,7 @@ pub const Intrinsic = enum {
3282 .{ .kind = .overloaded },4068 .{ .kind = .overloaded },
3283 .{ .kind = .overloaded },4069 .{ .kind = .overloaded },
3284 },4070 },
3285 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4071 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3286 },4072 },
3287 .lrint = .{4073 .lrint = .{
3288 .ret_len = 1,4074 .ret_len = 1,
...@@ -3290,7 +4076,7 @@ pub const Intrinsic = enum {...@@ -3290,7 +4076,7 @@ pub const Intrinsic = enum {
3290 .{ .kind = .overloaded },4076 .{ .kind = .overloaded },
3291 .{ .kind = .overloaded },4077 .{ .kind = .overloaded },
3292 },4078 },
3293 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4079 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3294 },4080 },
3295 .llrint = .{4081 .llrint = .{
3296 .ret_len = 1,4082 .ret_len = 1,
...@@ -3298,7 +4084,7 @@ pub const Intrinsic = enum {...@@ -3298,7 +4084,7 @@ pub const Intrinsic = enum {
3298 .{ .kind = .overloaded },4084 .{ .kind = .overloaded },
3299 .{ .kind = .overloaded },4085 .{ .kind = .overloaded },
3300 },4086 },
3301 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4087 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3302 },4088 },
33034089
3304 .bitreverse = .{4090 .bitreverse = .{
...@@ -3307,7 +4093,7 @@ pub const Intrinsic = enum {...@@ -3307,7 +4093,7 @@ pub const Intrinsic = enum {
3307 .{ .kind = .overloaded },4093 .{ .kind = .overloaded },
3308 .{ .kind = .{ .matches = 0 } },4094 .{ .kind = .{ .matches = 0 } },
3309 },4095 },
3310 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4096 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3311 },4097 },
3312 .bswap = .{4098 .bswap = .{
3313 .ret_len = 1,4099 .ret_len = 1,
...@@ -3315,7 +4101,7 @@ pub const Intrinsic = enum {...@@ -3315,7 +4101,7 @@ pub const Intrinsic = enum {
3315 .{ .kind = .overloaded },4101 .{ .kind = .overloaded },
3316 .{ .kind = .{ .matches = 0 } },4102 .{ .kind = .{ .matches = 0 } },
3317 },4103 },
3318 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4104 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3319 },4105 },
3320 .ctpop = .{4106 .ctpop = .{
3321 .ret_len = 1,4107 .ret_len = 1,
...@@ -3323,7 +4109,7 @@ pub const Intrinsic = enum {...@@ -3323,7 +4109,7 @@ pub const Intrinsic = enum {
3323 .{ .kind = .overloaded },4109 .{ .kind = .overloaded },
3324 .{ .kind = .{ .matches = 0 } },4110 .{ .kind = .{ .matches = 0 } },
3325 },4111 },
3326 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4112 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3327 },4113 },
3328 .ctlz = .{4114 .ctlz = .{
3329 .ret_len = 1,4115 .ret_len = 1,
...@@ -3332,7 +4118,7 @@ pub const Intrinsic = enum {...@@ -3332,7 +4118,7 @@ pub const Intrinsic = enum {
3332 .{ .kind = .{ .matches = 0 } },4118 .{ .kind = .{ .matches = 0 } },
3333 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },4119 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
3334 },4120 },
3335 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4121 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3336 },4122 },
3337 .cttz = .{4123 .cttz = .{
3338 .ret_len = 1,4124 .ret_len = 1,
...@@ -3341,7 +4127,7 @@ pub const Intrinsic = enum {...@@ -3341,7 +4127,7 @@ pub const Intrinsic = enum {
3341 .{ .kind = .{ .matches = 0 } },4127 .{ .kind = .{ .matches = 0 } },
3342 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },4128 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
3343 },4129 },
3344 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4130 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3345 },4131 },
3346 .fshl = .{4132 .fshl = .{
3347 .ret_len = 1,4133 .ret_len = 1,
...@@ -3351,7 +4137,7 @@ pub const Intrinsic = enum {...@@ -3351,7 +4137,7 @@ pub const Intrinsic = enum {
3351 .{ .kind = .{ .matches = 0 } },4137 .{ .kind = .{ .matches = 0 } },
3352 .{ .kind = .{ .matches = 0 } },4138 .{ .kind = .{ .matches = 0 } },
3353 },4139 },
3354 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4140 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3355 },4141 },
3356 .fshr = .{4142 .fshr = .{
3357 .ret_len = 1,4143 .ret_len = 1,
...@@ -3361,7 +4147,16 @@ pub const Intrinsic = enum {...@@ -3361,7 +4147,16 @@ pub const Intrinsic = enum {
3361 .{ .kind = .{ .matches = 0 } },4147 .{ .kind = .{ .matches = 0 } },
3362 .{ .kind = .{ .matches = 0 } },4148 .{ .kind = .{ .matches = 0 } },
3363 },4149 },
3364 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4150 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
4151 },
4152 .clmul = .{
4153 .ret_len = 1,
4154 .params = &.{
4155 .{ .kind = .overloaded },
4156 .{ .kind = .{ .matches = 0 } },
4157 .{ .kind = .{ .matches = 0 } },
4158 },
4159 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3365 },4160 },
33664161
3367 .@"sadd.with.overflow" = .{4162 .@"sadd.with.overflow" = .{
...@@ -3372,7 +4167,7 @@ pub const Intrinsic = enum {...@@ -3372,7 +4167,7 @@ pub const Intrinsic = enum {
3372 .{ .kind = .{ .matches = 0 } },4167 .{ .kind = .{ .matches = 0 } },
3373 .{ .kind = .{ .matches = 0 } },4168 .{ .kind = .{ .matches = 0 } },
3374 },4169 },
3375 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4170 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3376 },4171 },
3377 .@"uadd.with.overflow" = .{4172 .@"uadd.with.overflow" = .{
3378 .ret_len = 2,4173 .ret_len = 2,
...@@ -3382,7 +4177,7 @@ pub const Intrinsic = enum {...@@ -3382,7 +4177,7 @@ pub const Intrinsic = enum {
3382 .{ .kind = .{ .matches = 0 } },4177 .{ .kind = .{ .matches = 0 } },
3383 .{ .kind = .{ .matches = 0 } },4178 .{ .kind = .{ .matches = 0 } },
3384 },4179 },
3385 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4180 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3386 },4181 },
3387 .@"ssub.with.overflow" = .{4182 .@"ssub.with.overflow" = .{
3388 .ret_len = 2,4183 .ret_len = 2,
...@@ -3392,7 +4187,7 @@ pub const Intrinsic = enum {...@@ -3392,7 +4187,7 @@ pub const Intrinsic = enum {
3392 .{ .kind = .{ .matches = 0 } },4187 .{ .kind = .{ .matches = 0 } },
3393 .{ .kind = .{ .matches = 0 } },4188 .{ .kind = .{ .matches = 0 } },
3394 },4189 },
3395 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4190 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3396 },4191 },
3397 .@"usub.with.overflow" = .{4192 .@"usub.with.overflow" = .{
3398 .ret_len = 2,4193 .ret_len = 2,
...@@ -3402,7 +4197,7 @@ pub const Intrinsic = enum {...@@ -3402,7 +4197,7 @@ pub const Intrinsic = enum {
3402 .{ .kind = .{ .matches = 0 } },4197 .{ .kind = .{ .matches = 0 } },
3403 .{ .kind = .{ .matches = 0 } },4198 .{ .kind = .{ .matches = 0 } },
3404 },4199 },
3405 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4200 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3406 },4201 },
3407 .@"smul.with.overflow" = .{4202 .@"smul.with.overflow" = .{
3408 .ret_len = 2,4203 .ret_len = 2,
...@@ -3412,7 +4207,7 @@ pub const Intrinsic = enum {...@@ -3412,7 +4207,7 @@ pub const Intrinsic = enum {
3412 .{ .kind = .{ .matches = 0 } },4207 .{ .kind = .{ .matches = 0 } },
3413 .{ .kind = .{ .matches = 0 } },4208 .{ .kind = .{ .matches = 0 } },
3414 },4209 },
3415 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4210 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3416 },4211 },
3417 .@"umul.with.overflow" = .{4212 .@"umul.with.overflow" = .{
3418 .ret_len = 2,4213 .ret_len = 2,
...@@ -3422,7 +4217,7 @@ pub const Intrinsic = enum {...@@ -3422,7 +4217,7 @@ pub const Intrinsic = enum {
3422 .{ .kind = .{ .matches = 0 } },4217 .{ .kind = .{ .matches = 0 } },
3423 .{ .kind = .{ .matches = 0 } },4218 .{ .kind = .{ .matches = 0 } },
3424 },4219 },
3425 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4220 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3426 },4221 },
34274222
3428 .@"sadd.sat" = .{4223 .@"sadd.sat" = .{
...@@ -3432,7 +4227,7 @@ pub const Intrinsic = enum {...@@ -3432,7 +4227,7 @@ pub const Intrinsic = enum {
3432 .{ .kind = .{ .matches = 0 } },4227 .{ .kind = .{ .matches = 0 } },
3433 .{ .kind = .{ .matches = 0 } },4228 .{ .kind = .{ .matches = 0 } },
3434 },4229 },
3435 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4230 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3436 },4231 },
3437 .@"uadd.sat" = .{4232 .@"uadd.sat" = .{
3438 .ret_len = 1,4233 .ret_len = 1,
...@@ -3441,7 +4236,7 @@ pub const Intrinsic = enum {...@@ -3441,7 +4236,7 @@ pub const Intrinsic = enum {
3441 .{ .kind = .{ .matches = 0 } },4236 .{ .kind = .{ .matches = 0 } },
3442 .{ .kind = .{ .matches = 0 } },4237 .{ .kind = .{ .matches = 0 } },
3443 },4238 },
3444 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4239 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3445 },4240 },
3446 .@"ssub.sat" = .{4241 .@"ssub.sat" = .{
3447 .ret_len = 1,4242 .ret_len = 1,
...@@ -3450,7 +4245,7 @@ pub const Intrinsic = enum {...@@ -3450,7 +4245,7 @@ pub const Intrinsic = enum {
3450 .{ .kind = .{ .matches = 0 } },4245 .{ .kind = .{ .matches = 0 } },
3451 .{ .kind = .{ .matches = 0 } },4246 .{ .kind = .{ .matches = 0 } },
3452 },4247 },
3453 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4248 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3454 },4249 },
3455 .@"usub.sat" = .{4250 .@"usub.sat" = .{
3456 .ret_len = 1,4251 .ret_len = 1,
...@@ -3459,7 +4254,7 @@ pub const Intrinsic = enum {...@@ -3459,7 +4254,7 @@ pub const Intrinsic = enum {
3459 .{ .kind = .{ .matches = 0 } },4254 .{ .kind = .{ .matches = 0 } },
3460 .{ .kind = .{ .matches = 0 } },4255 .{ .kind = .{ .matches = 0 } },
3461 },4256 },
3462 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4257 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3463 },4258 },
3464 .@"sshl.sat" = .{4259 .@"sshl.sat" = .{
3465 .ret_len = 1,4260 .ret_len = 1,
...@@ -3468,7 +4263,7 @@ pub const Intrinsic = enum {...@@ -3468,7 +4263,7 @@ pub const Intrinsic = enum {
3468 .{ .kind = .{ .matches = 0 } },4263 .{ .kind = .{ .matches = 0 } },
3469 .{ .kind = .{ .matches = 0 } },4264 .{ .kind = .{ .matches = 0 } },
3470 },4265 },
3471 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4266 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3472 },4267 },
3473 .@"ushl.sat" = .{4268 .@"ushl.sat" = .{
3474 .ret_len = 1,4269 .ret_len = 1,
...@@ -3477,7 +4272,7 @@ pub const Intrinsic = enum {...@@ -3477,7 +4272,7 @@ pub const Intrinsic = enum {
3477 .{ .kind = .{ .matches = 0 } },4272 .{ .kind = .{ .matches = 0 } },
3478 .{ .kind = .{ .matches = 0 } },4273 .{ .kind = .{ .matches = 0 } },
3479 },4274 },
3480 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4275 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3481 },4276 },
34824277
3483 .@"smul.fix" = .{4278 .@"smul.fix" = .{
...@@ -3488,7 +4283,7 @@ pub const Intrinsic = enum {...@@ -3488,7 +4283,7 @@ pub const Intrinsic = enum {
3488 .{ .kind = .{ .matches = 0 } },4283 .{ .kind = .{ .matches = 0 } },
3489 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },4284 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3490 },4285 },
3491 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4286 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3492 },4287 },
3493 .@"umul.fix" = .{4288 .@"umul.fix" = .{
3494 .ret_len = 1,4289 .ret_len = 1,
...@@ -3498,7 +4293,7 @@ pub const Intrinsic = enum {...@@ -3498,7 +4293,7 @@ pub const Intrinsic = enum {
3498 .{ .kind = .{ .matches = 0 } },4293 .{ .kind = .{ .matches = 0 } },
3499 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },4294 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3500 },4295 },
3501 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4296 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3502 },4297 },
3503 .@"smul.fix.sat" = .{4298 .@"smul.fix.sat" = .{
3504 .ret_len = 1,4299 .ret_len = 1,
...@@ -3508,7 +4303,7 @@ pub const Intrinsic = enum {...@@ -3508,7 +4303,7 @@ pub const Intrinsic = enum {
3508 .{ .kind = .{ .matches = 0 } },4303 .{ .kind = .{ .matches = 0 } },
3509 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },4304 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3510 },4305 },
3511 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4306 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3512 },4307 },
3513 .@"umul.fix.sat" = .{4308 .@"umul.fix.sat" = .{
3514 .ret_len = 1,4309 .ret_len = 1,
...@@ -3518,7 +4313,7 @@ pub const Intrinsic = enum {...@@ -3518,7 +4313,7 @@ pub const Intrinsic = enum {
3518 .{ .kind = .{ .matches = 0 } },4313 .{ .kind = .{ .matches = 0 } },
3519 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },4314 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3520 },4315 },
3521 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4316 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3522 },4317 },
3523 .@"sdiv.fix" = .{4318 .@"sdiv.fix" = .{
3524 .ret_len = 1,4319 .ret_len = 1,
...@@ -3528,7 +4323,7 @@ pub const Intrinsic = enum {...@@ -3528,7 +4323,7 @@ pub const Intrinsic = enum {
3528 .{ .kind = .{ .matches = 0 } },4323 .{ .kind = .{ .matches = 0 } },
3529 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },4324 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3530 },4325 },
3531 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4326 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3532 },4327 },
3533 .@"udiv.fix" = .{4328 .@"udiv.fix" = .{
3534 .ret_len = 1,4329 .ret_len = 1,
...@@ -3538,7 +4333,7 @@ pub const Intrinsic = enum {...@@ -3538,7 +4333,7 @@ pub const Intrinsic = enum {
3538 .{ .kind = .{ .matches = 0 } },4333 .{ .kind = .{ .matches = 0 } },
3539 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },4334 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3540 },4335 },
3541 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4336 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3542 },4337 },
3543 .@"sdiv.fix.sat" = .{4338 .@"sdiv.fix.sat" = .{
3544 .ret_len = 1,4339 .ret_len = 1,
...@@ -3548,7 +4343,7 @@ pub const Intrinsic = enum {...@@ -3548,7 +4343,7 @@ pub const Intrinsic = enum {
3548 .{ .kind = .{ .matches = 0 } },4343 .{ .kind = .{ .matches = 0 } },
3549 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },4344 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3550 },4345 },
3551 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4346 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3552 },4347 },
3553 .@"udiv.fix.sat" = .{4348 .@"udiv.fix.sat" = .{
3554 .ret_len = 1,4349 .ret_len = 1,
...@@ -3558,7 +4353,7 @@ pub const Intrinsic = enum {...@@ -3558,7 +4353,7 @@ pub const Intrinsic = enum {
3558 .{ .kind = .{ .matches = 0 } },4353 .{ .kind = .{ .matches = 0 } },
3559 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },4354 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3560 },4355 },
3561 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4356 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3562 },4357 },
35634358
3564 .canonicalize = .{4359 .canonicalize = .{
...@@ -3567,7 +4362,7 @@ pub const Intrinsic = enum {...@@ -3567,7 +4362,7 @@ pub const Intrinsic = enum {
3567 .{ .kind = .overloaded },4362 .{ .kind = .overloaded },
3568 .{ .kind = .{ .matches = 0 } },4363 .{ .kind = .{ .matches = 0 } },
3569 },4364 },
3570 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4365 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3571 },4366 },
3572 .fmuladd = .{4367 .fmuladd = .{
3573 .ret_len = 1,4368 .ret_len = 1,
...@@ -3577,7 +4372,7 @@ pub const Intrinsic = enum {...@@ -3577,7 +4372,7 @@ pub const Intrinsic = enum {
3577 .{ .kind = .{ .matches = 0 } },4372 .{ .kind = .{ .matches = 0 } },
3578 .{ .kind = .{ .matches = 0 } },4373 .{ .kind = .{ .matches = 0 } },
3579 },4374 },
3580 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4375 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3581 },4376 },
35824377
3583 .@"vector.reduce.add" = .{4378 .@"vector.reduce.add" = .{
...@@ -3586,7 +4381,7 @@ pub const Intrinsic = enum {...@@ -3586,7 +4381,7 @@ pub const Intrinsic = enum {
3586 .{ .kind = .{ .matches_scalar = 1 } },4381 .{ .kind = .{ .matches_scalar = 1 } },
3587 .{ .kind = .overloaded },4382 .{ .kind = .overloaded },
3588 },4383 },
3589 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4384 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3590 },4385 },
3591 .@"vector.reduce.fadd" = .{4386 .@"vector.reduce.fadd" = .{
3592 .ret_len = 1,4387 .ret_len = 1,
...@@ -3595,7 +4390,7 @@ pub const Intrinsic = enum {...@@ -3595,7 +4390,7 @@ pub const Intrinsic = enum {
3595 .{ .kind = .{ .matches_scalar = 2 } },4390 .{ .kind = .{ .matches_scalar = 2 } },
3596 .{ .kind = .overloaded },4391 .{ .kind = .overloaded },
3597 },4392 },
3598 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4393 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3599 },4394 },
3600 .@"vector.reduce.mul" = .{4395 .@"vector.reduce.mul" = .{
3601 .ret_len = 1,4396 .ret_len = 1,
...@@ -3603,7 +4398,7 @@ pub const Intrinsic = enum {...@@ -3603,7 +4398,7 @@ pub const Intrinsic = enum {
3603 .{ .kind = .{ .matches_scalar = 1 } },4398 .{ .kind = .{ .matches_scalar = 1 } },
3604 .{ .kind = .overloaded },4399 .{ .kind = .overloaded },
3605 },4400 },
3606 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4401 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3607 },4402 },
3608 .@"vector.reduce.fmul" = .{4403 .@"vector.reduce.fmul" = .{
3609 .ret_len = 1,4404 .ret_len = 1,
...@@ -3612,7 +4407,7 @@ pub const Intrinsic = enum {...@@ -3612,7 +4407,7 @@ pub const Intrinsic = enum {
3612 .{ .kind = .{ .matches_scalar = 2 } },4407 .{ .kind = .{ .matches_scalar = 2 } },
3613 .{ .kind = .overloaded },4408 .{ .kind = .overloaded },
3614 },4409 },
3615 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4410 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3616 },4411 },
3617 .@"vector.reduce.and" = .{4412 .@"vector.reduce.and" = .{
3618 .ret_len = 1,4413 .ret_len = 1,
...@@ -3620,7 +4415,7 @@ pub const Intrinsic = enum {...@@ -3620,7 +4415,7 @@ pub const Intrinsic = enum {
3620 .{ .kind = .{ .matches_scalar = 1 } },4415 .{ .kind = .{ .matches_scalar = 1 } },
3621 .{ .kind = .overloaded },4416 .{ .kind = .overloaded },
3622 },4417 },
3623 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4418 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3624 },4419 },
3625 .@"vector.reduce.or" = .{4420 .@"vector.reduce.or" = .{
3626 .ret_len = 1,4421 .ret_len = 1,
...@@ -3628,7 +4423,7 @@ pub const Intrinsic = enum {...@@ -3628,7 +4423,7 @@ pub const Intrinsic = enum {
3628 .{ .kind = .{ .matches_scalar = 1 } },4423 .{ .kind = .{ .matches_scalar = 1 } },
3629 .{ .kind = .overloaded },4424 .{ .kind = .overloaded },
3630 },4425 },
3631 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4426 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3632 },4427 },
3633 .@"vector.reduce.xor" = .{4428 .@"vector.reduce.xor" = .{
3634 .ret_len = 1,4429 .ret_len = 1,
...@@ -3636,7 +4431,7 @@ pub const Intrinsic = enum {...@@ -3636,7 +4431,7 @@ pub const Intrinsic = enum {
3636 .{ .kind = .{ .matches_scalar = 1 } },4431 .{ .kind = .{ .matches_scalar = 1 } },
3637 .{ .kind = .overloaded },4432 .{ .kind = .overloaded },
3638 },4433 },
3639 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4434 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3640 },4435 },
3641 .@"vector.reduce.smax" = .{4436 .@"vector.reduce.smax" = .{
3642 .ret_len = 1,4437 .ret_len = 1,
...@@ -3644,7 +4439,7 @@ pub const Intrinsic = enum {...@@ -3644,7 +4439,7 @@ pub const Intrinsic = enum {
3644 .{ .kind = .{ .matches_scalar = 1 } },4439 .{ .kind = .{ .matches_scalar = 1 } },
3645 .{ .kind = .overloaded },4440 .{ .kind = .overloaded },
3646 },4441 },
3647 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4442 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3648 },4443 },
3649 .@"vector.reduce.smin" = .{4444 .@"vector.reduce.smin" = .{
3650 .ret_len = 1,4445 .ret_len = 1,
...@@ -3652,7 +4447,7 @@ pub const Intrinsic = enum {...@@ -3652,7 +4447,7 @@ pub const Intrinsic = enum {
3652 .{ .kind = .{ .matches_scalar = 1 } },4447 .{ .kind = .{ .matches_scalar = 1 } },
3653 .{ .kind = .overloaded },4448 .{ .kind = .overloaded },
3654 },4449 },
3655 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4450 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3656 },4451 },
3657 .@"vector.reduce.umax" = .{4452 .@"vector.reduce.umax" = .{
3658 .ret_len = 1,4453 .ret_len = 1,
...@@ -3660,7 +4455,7 @@ pub const Intrinsic = enum {...@@ -3660,7 +4455,7 @@ pub const Intrinsic = enum {
3660 .{ .kind = .{ .matches_scalar = 1 } },4455 .{ .kind = .{ .matches_scalar = 1 } },
3661 .{ .kind = .overloaded },4456 .{ .kind = .overloaded },
3662 },4457 },
3663 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4458 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3664 },4459 },
3665 .@"vector.reduce.umin" = .{4460 .@"vector.reduce.umin" = .{
3666 .ret_len = 1,4461 .ret_len = 1,
...@@ -3668,7 +4463,7 @@ pub const Intrinsic = enum {...@@ -3668,7 +4463,7 @@ pub const Intrinsic = enum {
3668 .{ .kind = .{ .matches_scalar = 1 } },4463 .{ .kind = .{ .matches_scalar = 1 } },
3669 .{ .kind = .overloaded },4464 .{ .kind = .overloaded },
3670 },4465 },
3671 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4466 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3672 },4467 },
3673 .@"vector.reduce.fmax" = .{4468 .@"vector.reduce.fmax" = .{
3674 .ret_len = 1,4469 .ret_len = 1,
...@@ -3676,7 +4471,7 @@ pub const Intrinsic = enum {...@@ -3676,7 +4471,7 @@ pub const Intrinsic = enum {
3676 .{ .kind = .{ .matches_scalar = 1 } },4471 .{ .kind = .{ .matches_scalar = 1 } },
3677 .{ .kind = .overloaded },4472 .{ .kind = .overloaded },
3678 },4473 },
3679 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4474 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3680 },4475 },
3681 .@"vector.reduce.fmin" = .{4476 .@"vector.reduce.fmin" = .{
3682 .ret_len = 1,4477 .ret_len = 1,
...@@ -3684,7 +4479,7 @@ pub const Intrinsic = enum {...@@ -3684,7 +4479,7 @@ pub const Intrinsic = enum {
3684 .{ .kind = .{ .matches_scalar = 1 } },4479 .{ .kind = .{ .matches_scalar = 1 } },
3685 .{ .kind = .overloaded },4480 .{ .kind = .overloaded },
3686 },4481 },
3687 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4482 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3688 },4483 },
3689 .@"vector.reduce.fmaximum" = .{4484 .@"vector.reduce.fmaximum" = .{
3690 .ret_len = 1,4485 .ret_len = 1,
...@@ -3692,7 +4487,7 @@ pub const Intrinsic = enum {...@@ -3692,7 +4487,7 @@ pub const Intrinsic = enum {
3692 .{ .kind = .{ .matches_scalar = 1 } },4487 .{ .kind = .{ .matches_scalar = 1 } },
3693 .{ .kind = .overloaded },4488 .{ .kind = .overloaded },
3694 },4489 },
3695 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4490 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3696 },4491 },
3697 .@"vector.reduce.fminimum" = .{4492 .@"vector.reduce.fminimum" = .{
3698 .ret_len = 1,4493 .ret_len = 1,
...@@ -3700,7 +4495,7 @@ pub const Intrinsic = enum {...@@ -3700,7 +4495,7 @@ pub const Intrinsic = enum {
3700 .{ .kind = .{ .matches_scalar = 1 } },4495 .{ .kind = .{ .matches_scalar = 1 } },
3701 .{ .kind = .overloaded },4496 .{ .kind = .overloaded },
3702 },4497 },
3703 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4498 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3704 },4499 },
3705 .@"vector.insert" = .{4500 .@"vector.insert" = .{
3706 .ret_len = 1,4501 .ret_len = 1,
...@@ -3710,7 +4505,7 @@ pub const Intrinsic = enum {...@@ -3710,7 +4505,7 @@ pub const Intrinsic = enum {
3710 .{ .kind = .overloaded },4505 .{ .kind = .overloaded },
3711 .{ .kind = .{ .type = .i64 } },4506 .{ .kind = .{ .type = .i64 } },
3712 },4507 },
3713 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4508 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3714 },4509 },
3715 .@"vector.extract" = .{4510 .@"vector.extract" = .{
3716 .ret_len = 1,4511 .ret_len = 1,
...@@ -3719,7 +4514,7 @@ pub const Intrinsic = enum {...@@ -3719,7 +4514,7 @@ pub const Intrinsic = enum {
3719 .{ .kind = .overloaded },4514 .{ .kind = .overloaded },
3720 .{ .kind = .{ .type = .i64 } },4515 .{ .kind = .{ .type = .i64 } },
3721 },4516 },
3722 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4517 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3723 },4518 },
37244519
3725 .@"is.fpclass" = .{4520 .@"is.fpclass" = .{
...@@ -3729,7 +4524,7 @@ pub const Intrinsic = enum {...@@ -3729,7 +4524,7 @@ pub const Intrinsic = enum {
3729 .{ .kind = .overloaded },4524 .{ .kind = .overloaded },
3730 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },4525 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3731 },4526 },
3732 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4527 .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3733 },4528 },
37344529
3735 .@"var.annotation" = .{4530 .@"var.annotation" = .{
...@@ -3814,7 +4609,7 @@ pub const Intrinsic = enum {...@@ -3814,7 +4609,7 @@ pub const Intrinsic = enum {
3814 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },4609 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
3815 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },4610 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
3816 },4611 },
3817 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4612 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3818 },4613 },
3819 .expect = .{4614 .expect = .{
3820 .ret_len = 1,4615 .ret_len = 1,
...@@ -3823,7 +4618,7 @@ pub const Intrinsic = enum {...@@ -3823,7 +4618,7 @@ pub const Intrinsic = enum {
3823 .{ .kind = .{ .matches = 0 } },4618 .{ .kind = .{ .matches = 0 } },
3824 .{ .kind = .{ .matches = 0 } },4619 .{ .kind = .{ .matches = 0 } },
3825 },4620 },
3826 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4621 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3827 },4622 },
3828 .@"expect.with.probability" = .{4623 .@"expect.with.probability" = .{
3829 .ret_len = 1,4624 .ret_len = 1,
...@@ -3833,7 +4628,7 @@ pub const Intrinsic = enum {...@@ -3833,7 +4628,7 @@ pub const Intrinsic = enum {
3833 .{ .kind = .{ .matches = 0 } },4628 .{ .kind = .{ .matches = 0 } },
3834 .{ .kind = .{ .type = .double }, .attrs = &.{.immarg} },4629 .{ .kind = .{ .type = .double }, .attrs = &.{.immarg} },
3835 },4630 },
3836 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4631 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3837 },4632 },
3838 .assume = .{4633 .assume = .{
3839 .ret_len = 0,4634 .ret_len = 0,
...@@ -3848,7 +4643,7 @@ pub const Intrinsic = enum {...@@ -3848,7 +4643,7 @@ pub const Intrinsic = enum {
3848 .{ .kind = .overloaded },4643 .{ .kind = .overloaded },
3849 .{ .kind = .{ .matches = 0 }, .attrs = &.{.returned} },4644 .{ .kind = .{ .matches = 0 }, .attrs = &.{.returned} },
3850 },4645 },
3851 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4646 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3852 },4647 },
3853 .@"type.test" = .{4648 .@"type.test" = .{
3854 .ret_len = 1,4649 .ret_len = 1,
...@@ -3857,7 +4652,7 @@ pub const Intrinsic = enum {...@@ -3857,7 +4652,7 @@ pub const Intrinsic = enum {
3857 .{ .kind = .{ .type = .ptr } },4652 .{ .kind = .{ .type = .ptr } },
3858 .{ .kind = .{ .type = .metadata } },4653 .{ .kind = .{ .type = .metadata } },
3859 },4654 },
3860 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4655 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3861 },4656 },
3862 .@"type.checked.load" = .{4657 .@"type.checked.load" = .{
3863 .ret_len = 2,4658 .ret_len = 2,
...@@ -3868,7 +4663,7 @@ pub const Intrinsic = enum {...@@ -3868,7 +4663,7 @@ pub const Intrinsic = enum {
3868 .{ .kind = .{ .type = .i32 } },4663 .{ .kind = .{ .type = .i32 } },
3869 .{ .kind = .{ .type = .metadata } },4664 .{ .kind = .{ .type = .metadata } },
3870 },4665 },
3871 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4666 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3872 },4667 },
3873 .@"type.checked.load.relative" = .{4668 .@"type.checked.load.relative" = .{
3874 .ret_len = 2,4669 .ret_len = 2,
...@@ -3879,7 +4674,7 @@ pub const Intrinsic = enum {...@@ -3879,7 +4674,7 @@ pub const Intrinsic = enum {
3879 .{ .kind = .{ .type = .i32 } },4674 .{ .kind = .{ .type = .i32 } },
3880 .{ .kind = .{ .type = .metadata } },4675 .{ .kind = .{ .type = .metadata } },
3881 },4676 },
3882 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4677 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3883 },4678 },
3884 .@"arithmetic.fence" = .{4679 .@"arithmetic.fence" = .{
3885 .ret_len = 1,4680 .ret_len = 1,
...@@ -3887,12 +4682,12 @@ pub const Intrinsic = enum {...@@ -3887,12 +4682,12 @@ pub const Intrinsic = enum {
3887 .{ .kind = .overloaded },4682 .{ .kind = .overloaded },
3888 .{ .kind = .{ .matches = 0 } },4683 .{ .kind = .{ .matches = 0 } },
3889 },4684 },
3890 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4685 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3891 },4686 },
3892 .donothing = .{4687 .donothing = .{
3893 .ret_len = 0,4688 .ret_len = 0,
3894 .params = &.{},4689 .params = &.{},
3895 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4690 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3896 },4691 },
3897 .@"load.relative" = .{4692 .@"load.relative" = .{
3898 .ret_len = 1,4693 .ret_len = 1,
...@@ -3914,7 +4709,7 @@ pub const Intrinsic = enum {...@@ -3914,7 +4709,7 @@ pub const Intrinsic = enum {
3914 .{ .kind = .{ .type = .i1 } },4709 .{ .kind = .{ .type = .i1 } },
3915 .{ .kind = .overloaded },4710 .{ .kind = .overloaded },
3916 },4711 },
3917 .attrs = &.{ .convergent, .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4712 .attrs = &.{ .convergent, .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3918 },4713 },
3919 .ptrmask = .{4714 .ptrmask = .{
3920 .ret_len = 1,4715 .ret_len = 1,
...@@ -3923,7 +4718,7 @@ pub const Intrinsic = enum {...@@ -3923,7 +4718,7 @@ pub const Intrinsic = enum {
3923 .{ .kind = .{ .matches = 0 } },4718 .{ .kind = .{ .matches = 0 } },
3924 .{ .kind = .overloaded },4719 .{ .kind = .overloaded },
3925 },4720 },
3926 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4721 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3927 },4722 },
3928 .@"threadlocal.address" = .{4723 .@"threadlocal.address" = .{
3929 .ret_len = 1,4724 .ret_len = 1,
...@@ -3931,14 +4726,14 @@ pub const Intrinsic = enum {...@@ -3931,14 +4726,14 @@ pub const Intrinsic = enum {
3931 .{ .kind = .overloaded, .attrs = &.{.nonnull} },4726 .{ .kind = .overloaded, .attrs = &.{.nonnull} },
3932 .{ .kind = .{ .matches = 0 }, .attrs = &.{.nonnull} },4727 .{ .kind = .{ .matches = 0 }, .attrs = &.{.nonnull} },
3933 },4728 },
3934 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4729 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3935 },4730 },
3936 .vscale = .{4731 .vscale = .{
3937 .ret_len = 1,4732 .ret_len = 1,
3938 .params = &.{4733 .params = &.{
3939 .{ .kind = .overloaded },4734 .{ .kind = .overloaded },
3940 },4735 },
3941 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4736 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
3942 },4737 },
39434738
3944 .@"dbg.declare" = .{4739 .@"dbg.declare" = .{
...@@ -3948,7 +4743,7 @@ pub const Intrinsic = enum {...@@ -3948,7 +4743,7 @@ pub const Intrinsic = enum {
3948 .{ .kind = .{ .type = .metadata } },4743 .{ .kind = .{ .type = .metadata } },
3949 .{ .kind = .{ .type = .metadata } },4744 .{ .kind = .{ .type = .metadata } },
3950 },4745 },
3951 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4746 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3952 },4747 },
3953 .@"dbg.value" = .{4748 .@"dbg.value" = .{
3954 .ret_len = 0,4749 .ret_len = 0,
...@@ -3957,7 +4752,7 @@ pub const Intrinsic = enum {...@@ -3957,7 +4752,7 @@ pub const Intrinsic = enum {
3957 .{ .kind = .{ .type = .metadata } },4752 .{ .kind = .{ .type = .metadata } },
3958 .{ .kind = .{ .type = .metadata } },4753 .{ .kind = .{ .type = .metadata } },
3959 },4754 },
3960 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4755 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3961 },4756 },
39624757
3963 .@"amdgcn.workitem.id.x" = .{4758 .@"amdgcn.workitem.id.x" = .{
...@@ -3965,42 +4760,42 @@ pub const Intrinsic = enum {...@@ -3965,42 +4760,42 @@ pub const Intrinsic = enum {
3965 .params = &.{4760 .params = &.{
3966 .{ .kind = .{ .type = .i32 } },4761 .{ .kind = .{ .type = .i32 } },
3967 },4762 },
3968 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4763 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3969 },4764 },
3970 .@"amdgcn.workitem.id.y" = .{4765 .@"amdgcn.workitem.id.y" = .{
3971 .ret_len = 1,4766 .ret_len = 1,
3972 .params = &.{4767 .params = &.{
3973 .{ .kind = .{ .type = .i32 } },4768 .{ .kind = .{ .type = .i32 } },
3974 },4769 },
3975 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4770 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3976 },4771 },
3977 .@"amdgcn.workitem.id.z" = .{4772 .@"amdgcn.workitem.id.z" = .{
3978 .ret_len = 1,4773 .ret_len = 1,
3979 .params = &.{4774 .params = &.{
3980 .{ .kind = .{ .type = .i32 } },4775 .{ .kind = .{ .type = .i32 } },
3981 },4776 },
3982 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4777 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3983 },4778 },
3984 .@"amdgcn.workgroup.id.x" = .{4779 .@"amdgcn.workgroup.id.x" = .{
3985 .ret_len = 1,4780 .ret_len = 1,
3986 .params = &.{4781 .params = &.{
3987 .{ .kind = .{ .type = .i32 } },4782 .{ .kind = .{ .type = .i32 } },
3988 },4783 },
3989 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4784 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3990 },4785 },
3991 .@"amdgcn.workgroup.id.y" = .{4786 .@"amdgcn.workgroup.id.y" = .{
3992 .ret_len = 1,4787 .ret_len = 1,
3993 .params = &.{4788 .params = &.{
3994 .{ .kind = .{ .type = .i32 } },4789 .{ .kind = .{ .type = .i32 } },
3995 },4790 },
3996 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4791 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
3997 },4792 },
3998 .@"amdgcn.workgroup.id.z" = .{4793 .@"amdgcn.workgroup.id.z" = .{
3999 .ret_len = 1,4794 .ret_len = 1,
4000 .params = &.{4795 .params = &.{
4001 .{ .kind = .{ .type = .i32 } },4796 .{ .kind = .{ .type = .i32 } },
4002 },4797 },
4003 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4798 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
4004 },4799 },
4005 .@"amdgcn.dispatch.ptr" = .{4800 .@"amdgcn.dispatch.ptr" = .{
4006 .ret_len = 1,4801 .ret_len = 1,
...@@ -4010,7 +4805,7 @@ pub const Intrinsic = enum {...@@ -4010,7 +4805,7 @@ pub const Intrinsic = enum {
4010 .attrs = &.{.{ .@"align" = .wrap(.fromByteUnits(4)) }},4805 .attrs = &.{.{ .@"align" = .wrap(.fromByteUnits(4)) }},
4011 },4806 },
4012 },4807 },
4013 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4808 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } },
4014 },4809 },
40154810
4016 .@"nvvm.read.ptx.sreg.tid.x" = .{4811 .@"nvvm.read.ptx.sreg.tid.x" = .{
...@@ -4085,7 +4880,7 @@ pub const Intrinsic = enum {...@@ -4085,7 +4880,7 @@ pub const Intrinsic = enum {
4085 .{ .kind = .overloaded },4880 .{ .kind = .overloaded },
4086 .{ .kind = .{ .type = .i32 } },4881 .{ .kind = .{ .type = .i32 } },
4087 },4882 },
4088 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },4883 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } },
4089 },4884 },
4090 .@"wasm.memory.grow" = .{4885 .@"wasm.memory.grow" = .{
4091 .ret_len = 1,4886 .ret_len = 1,
...@@ -4166,6 +4961,10 @@ pub const Function = struct {...@@ -4166,6 +4961,10 @@ pub const Function = struct {
4166 self.ptr(builder).attributes = new_function_attributes;4961 self.ptr(builder).attributes = new_function_attributes;
4167 }4962 }
41684963
4964 pub fn getAttributes(self: Index, builder: *Builder) FunctionAttributes {
4965 return self.ptr(builder).attributes;
4966 }
4967
4169 pub fn setSection(self: Index, section: String, builder: *Builder) void {4968 pub fn setSection(self: Index, section: String, builder: *Builder) void {
4170 self.ptr(builder).section = section;4969 self.ptr(builder).section = section;
4171 }4970 }
...@@ -4487,7 +5286,7 @@ pub const Function = struct {...@@ -4487,7 +5286,7 @@ pub const Function = struct {
4487 }5286 }
44885287
4489 pub fn toValue(self: Instruction.Index) Value {5288 pub fn toValue(self: Instruction.Index) Value {
4490 return @fromBackingInt(@intCast(@backingInt(self)));5289 return @fromBackingInt(@backingInt(self));
4491 }5290 }
44925291
4493 pub fn isTerminatorWip(self: Instruction.Index, wip: *const WipFunction) bool {5292 pub fn isTerminatorWip(self: Instruction.Index, wip: *const WipFunction) bool {
...@@ -4679,7 +5478,7 @@ pub const Function = struct {...@@ -4679,7 +5478,7 @@ pub const Function = struct {
4679 .changeScalarAssumeCapacity(.i1, wip.builder),5478 .changeScalarAssumeCapacity(.i1, wip.builder),
4680 .fneg,5479 .fneg,
4681 .@"fneg fast",5480 .@"fneg fast",
4682 => @as(Value, @fromBackingInt(@intCast(instruction.data))).typeOfWip(wip),5481 => @as(Value, @fromBackingInt(instruction.data)).typeOfWip(wip),
4683 .getelementptr,5482 .getelementptr,
4684 .@"getelementptr inbounds",5483 .@"getelementptr inbounds",
4685 => {5484 => {
...@@ -4871,7 +5670,7 @@ pub const Function = struct {...@@ -4871,7 +5670,7 @@ pub const Function = struct {
4871 .changeScalarAssumeCapacity(.i1, builder),5670 .changeScalarAssumeCapacity(.i1, builder),
4872 .fneg,5671 .fneg,
4873 .@"fneg fast",5672 .@"fneg fast",
4874 => @as(Value, @fromBackingInt(@intCast(instruction.data))).typeOf(function_index, builder),5673 => @as(Value, @fromBackingInt(instruction.data)).typeOf(function_index, builder),
4875 .getelementptr,5674 .getelementptr,
4876 .@"getelementptr inbounds",5675 .@"getelementptr inbounds",
4877 => {5676 => {
...@@ -4963,7 +5762,7 @@ pub const Function = struct {...@@ -4963,7 +5762,7 @@ pub const Function = struct {
49635762
4964 pub fn fromMetadata(metadata: Metadata) Weights {5763 pub fn fromMetadata(metadata: Metadata) Weights {
4965 assert(metadata.kind == .node);5764 assert(metadata.kind == .node);
4966 return @fromBackingInt(@intCast(metadata.index));5765 return @fromBackingInt(metadata.index);
4967 }5766 }
49685767
4969 pub fn toMetadata(weights: Weights) Metadata {5768 pub fn toMetadata(weights: Weights) Metadata {
...@@ -5156,7 +5955,7 @@ pub const Function = struct {...@@ -5156,7 +5955,7 @@ pub const Function = struct {
5156 assert(argument.tag == .arg);5955 assert(argument.tag == .arg);
5157 assert(argument.data == index);5956 assert(argument.data == index);
51585957
5159 const argument_index: Instruction.Index = @fromBackingInt(@intCast(index));5958 const argument_index: Instruction.Index = @fromBackingInt(index);
5160 return argument_index.toValue();5959 return argument_index.toValue();
5161 }5960 }
51625961
...@@ -5202,7 +6001,7 @@ pub const Function = struct {...@@ -5202,7 +6001,7 @@ pub const Function = struct {
5202 Type,6001 Type,
5203 Value,6002 Value,
5204 Instruction.BrCond.Weights,6003 Instruction.BrCond.Weights,
5205 => @fromBackingInt(@intCast(value)),6004 => @fromBackingInt(value),
5206 MemoryAccessInfo,6005 MemoryAccessInfo,
5207 Instruction.Alloca.Info,6006 Instruction.Alloca.Info,
5208 Instruction.Call.Info,6007 Instruction.Call.Info,
...@@ -5327,7 +6126,7 @@ pub const WipFunction = struct {...@@ -5327,7 +6126,7 @@ pub const WipFunction = struct {
5327 assert(argument.tag == .arg);6126 assert(argument.tag == .arg);
5328 assert(argument.data == index);6127 assert(argument.data == index);
53296128
5330 const argument_index: Instruction.Index = @fromBackingInt(@intCast(index));6129 const argument_index: Instruction.Index = @fromBackingInt(index);
5331 return argument_index.toValue();6130 return argument_index.toValue();
5332 }6131 }
53336132
...@@ -5722,7 +6521,7 @@ pub const WipFunction = struct {...@@ -5722,7 +6521,7 @@ pub const WipFunction = struct {
5722 alignment: Alignment,6521 alignment: Alignment,
5723 name: []const u8,6522 name: []const u8,
5724 ) Allocator.Error!Value {6523 ) Allocator.Error!Value {
5725 return self.loadAtomic(access_kind, ty, ptr, .system, .none, alignment, name);6524 return self.loadAtomic(access_kind, ty, ptr, undefined, .none, alignment, name);
5726 }6525 }
57276526
5728 pub fn loadAtomic(6527 pub fn loadAtomic(
...@@ -5766,7 +6565,7 @@ pub const WipFunction = struct {...@@ -5766,7 +6565,7 @@ pub const WipFunction = struct {
5766 ptr: Value,6565 ptr: Value,
5767 alignment: Alignment,6566 alignment: Alignment,
5768 ) Allocator.Error!Instruction.Index {6567 ) Allocator.Error!Instruction.Index {
5769 return self.storeAtomic(kind, val, ptr, .system, .none, alignment);6568 return self.storeAtomic(kind, val, ptr, undefined, .none, alignment);
5770 }6569 }
57716570
5772 pub fn storeAtomic(6571 pub fn storeAtomic(
...@@ -6414,24 +7213,24 @@ pub const WipFunction = struct {...@@ -6414,24 +7213,24 @@ pub const WipFunction = struct {
6414 errdefer function.instructions.shrinkRetainingCapacity(0);7213 errdefer function.instructions.shrinkRetainingCapacity(0);
64157214
6416 {7215 {
6417 var final_instruction_index: Instruction.Index = @fromBackingInt(@intCast(0));7216 var final_instruction_index: Instruction.Index = @fromBackingInt(0);
6418 for (0..params_len) |param_index| {7217 for (0..params_len) |param_index| {
6419 instructions.items[param_index] = final_instruction_index;7218 instructions.items[param_index] = final_instruction_index;
6420 final_instruction_index = @fromBackingInt(@intCast(@backingInt(final_instruction_index) + 1));7219 final_instruction_index = @fromBackingInt(@backingInt(final_instruction_index) + 1);
6421 }7220 }
6422 for (blocks, self.blocks.items) |*final_block, current_block| {7221 for (blocks, self.blocks.items) |*final_block, current_block| {
6423 assert(current_block.incoming == current_block.branches);7222 assert(current_block.incoming == current_block.branches);
6424 final_block.instruction = final_instruction_index;7223 final_block.instruction = final_instruction_index;
6425 final_instruction_index = @fromBackingInt(@intCast(@backingInt(final_instruction_index) + 1));7224 final_instruction_index = @fromBackingInt(@backingInt(final_instruction_index) + 1);
6426 for (current_block.instructions.items) |instruction| {7225 for (current_block.instructions.items) |instruction| {
6427 instructions.items[@backingInt(instruction)] = final_instruction_index;7226 instructions.items[@backingInt(instruction)] = final_instruction_index;
6428 final_instruction_index = @fromBackingInt(@intCast(@backingInt(final_instruction_index) + 1));7227 final_instruction_index = @fromBackingInt(@backingInt(final_instruction_index) + 1);
6429 }7228 }
6430 }7229 }
6431 }7230 }
64327231
6433 var wip_name: struct {7232 var wip_name: struct {
6434 next_name: String = @fromBackingInt(@intCast(0)),7233 next_name: String = @fromBackingInt(0),
6435 next_unique_name: std.AutoHashMap(String, String),7234 next_unique_name: std.AutoHashMap(String, String),
6436 builder: *Builder,7235 builder: *Builder,
64377236
...@@ -6440,19 +7239,19 @@ pub const WipFunction = struct {...@@ -6440,19 +7239,19 @@ pub const WipFunction = struct {
6440 .none => return .none,7239 .none => return .none,
6441 .empty => {7240 .empty => {
6442 assert(wip_name.next_name != .none);7241 assert(wip_name.next_name != .none);
6443 defer wip_name.next_name = @fromBackingInt(@intCast(@backingInt(wip_name.next_name) + 1));7242 defer wip_name.next_name = @fromBackingInt(@backingInt(wip_name.next_name) + 1);
6444 return wip_name.next_name;7243 return wip_name.next_name;
6445 },7244 },
6446 _ => {7245 _ => {
6447 assert(!name.isAnon());7246 assert(!name.isAnon());
6448 const gop = try wip_name.next_unique_name.getOrPut(name);7247 const gop = try wip_name.next_unique_name.getOrPut(name);
6449 if (!gop.found_existing) {7248 if (!gop.found_existing) {
6450 gop.value_ptr.* = @fromBackingInt(@intCast(0));7249 gop.value_ptr.* = @fromBackingInt(0);
6451 return name;7250 return name;
6452 }7251 }
64537252
6454 while (true) {7253 while (true) {
6455 gop.value_ptr.* = @fromBackingInt(@intCast(@backingInt(gop.value_ptr.*) + 1));7254 gop.value_ptr.* = @fromBackingInt(@backingInt(gop.value_ptr.*) + 1);
6456 const unique_name = try wip_name.builder.fmt("{f}{s}{f}", .{7255 const unique_name = try wip_name.builder.fmt("{f}{s}{f}", .{
6457 name.fmtRaw(wip_name.builder),7256 name.fmtRaw(wip_name.builder),
6458 sep,7257 sep,
...@@ -6460,7 +7259,7 @@ pub const WipFunction = struct {...@@ -6460,7 +7259,7 @@ pub const WipFunction = struct {
6460 });7259 });
6461 const unique_gop = try wip_name.next_unique_name.getOrPut(unique_name);7260 const unique_gop = try wip_name.next_unique_name.getOrPut(unique_name);
6462 if (!unique_gop.found_existing) {7261 if (!unique_gop.found_existing) {
6463 unique_gop.value_ptr.* = @fromBackingInt(@intCast(0));7262 unique_gop.value_ptr.* = @fromBackingInt(0);
6464 return unique_name;7263 return unique_name;
6465 }7264 }
6466 }7265 }
...@@ -6702,7 +7501,7 @@ pub const WipFunction = struct {...@@ -6702,7 +7501,7 @@ pub const WipFunction = struct {
6702 .fneg,7501 .fneg,
6703 .@"fneg fast",7502 .@"fneg fast",
6704 .ret,7503 .ret,
6705 => instruction.data = @backingInt(instructions.map(@fromBackingInt(@intCast(instruction.data)))),7504 => instruction.data = @backingInt(instructions.map(@fromBackingInt(instruction.data))),
6706 .getelementptr,7505 .getelementptr,
6707 .@"getelementptr inbounds",7506 .@"getelementptr inbounds",
6708 => {7507 => {
...@@ -7079,7 +7878,7 @@ pub const WipFunction = struct {...@@ -7079,7 +7878,7 @@ pub const WipFunction = struct {
7079 Type,7878 Type,
7080 Value,7879 Value,
7081 Instruction.BrCond.Weights,7880 Instruction.BrCond.Weights,
7082 => @fromBackingInt(@intCast(value)),7881 => @fromBackingInt(value),
7083 MemoryAccessInfo,7882 MemoryAccessInfo,
7084 Instruction.Alloca.Info,7883 Instruction.Alloca.Info,
7085 Instruction.Call.Info,7884 Instruction.Call.Info,
...@@ -7268,7 +8067,7 @@ pub const Constant = enum(u32) {...@@ -7268,7 +8067,7 @@ pub const Constant = enum(u32) {
7268 no_init = (1 << 30) - 1,8067 no_init = (1 << 30) - 1,
7269 _,8068 _,
72708069
7271 const first_global: Constant = @fromBackingInt(@intCast(1 << 29));8070 const first_global: Constant = @fromBackingInt(1 << 29);
72728071
7273 pub const Tag = enum(u7) {8072 pub const Tag = enum(u7) {
7274 positive_integer,8073 positive_integer,
...@@ -7405,7 +8204,18 @@ pub const Constant = enum(u32) {...@@ -7405,7 +8204,18 @@ pub const Constant = enum(u32) {
7405 val: Constant,8204 val: Constant,
7406 type: Type,8205 type: Type,
74078206
7408 pub const Signedness = enum { unsigned, signed, unneeded };8207 pub const Signedness = enum {
8208 unsigned,
8209 signed,
8210 unneeded,
8211
8212 pub fn fromStdLang(signedness: std.lang.Signedness) Signedness {
8213 return switch (signedness) {
8214 .unsigned => .unsigned,
8215 .signed => .signed,
8216 };
8217 }
8218 };
7409 };8219 };
74108220
7411 pub const GetElementPtr = struct {8221 pub const GetElementPtr = struct {
...@@ -7444,11 +8254,11 @@ pub const Constant = enum(u32) {...@@ -7444,11 +8254,11 @@ pub const Constant = enum(u32) {
7444 return if (@backingInt(self) < @backingInt(first_global))8254 return if (@backingInt(self) < @backingInt(first_global))
7445 .{ .constant = @intCast(@backingInt(self)) }8255 .{ .constant = @intCast(@backingInt(self)) }
7446 else8256 else
7447 .{ .global = @fromBackingInt(@intCast(@backingInt(self) - @backingInt(first_global))) };8257 .{ .global = @fromBackingInt(@backingInt(self) - @backingInt(first_global)) };
7448 }8258 }
74498259
7450 pub fn toValue(self: Constant) Value {8260 pub fn toValue(self: Constant) Value {
7451 return @fromBackingInt(@intCast(Value.first_constant + @backingInt(self)));8261 return @fromBackingInt(Value.first_constant + @backingInt(self));
7452 }8262 }
74538263
7454 pub fn typeOf(self: Constant, builder: *Builder) Type {8264 pub fn typeOf(self: Constant, builder: *Builder) Type {
...@@ -7474,7 +8284,7 @@ pub const Constant = enum(u32) {...@@ -7474,7 +8284,7 @@ pub const Constant = enum(u32) {
7474 .zeroinitializer,8284 .zeroinitializer,
7475 .undef,8285 .undef,
7476 .poison,8286 .poison,
7477 => @fromBackingInt(@intCast(item.data)),8287 => @fromBackingInt(item.data),
7478 .structure,8288 .structure,
7479 .packed_structure,8289 .packed_structure,
7480 .array,8290 .array,
...@@ -7482,7 +8292,7 @@ pub const Constant = enum(u32) {...@@ -7482,7 +8292,7 @@ pub const Constant = enum(u32) {
7482 => builder.constantExtraData(Aggregate, item.data).type,8292 => builder.constantExtraData(Aggregate, item.data).type,
7483 .splat => builder.constantExtraData(Splat, item.data).type,8293 .splat => builder.constantExtraData(Splat, item.data).type,
7484 .string => builder.arrayTypeAssumeCapacity(8294 .string => builder.arrayTypeAssumeCapacity(
7485 @as(String, @fromBackingInt(@intCast(item.data))).slice(builder).?.len,8295 @as(String, @fromBackingInt(item.data)).slice(builder).?.len,
7486 .i8,8296 .i8,
7487 ),8297 ),
7488 .blockaddress => builder.ptrTypeAssumeCapacity(8298 .blockaddress => builder.ptrTypeAssumeCapacity(
...@@ -7491,7 +8301,7 @@ pub const Constant = enum(u32) {...@@ -7491,7 +8301,7 @@ pub const Constant = enum(u32) {
7491 ),8301 ),
7492 .dso_local_equivalent,8302 .dso_local_equivalent,
7493 .no_cfi,8303 .no_cfi,
7494 => builder.ptrTypeAssumeCapacity(@as(Function.Index, @fromBackingInt(@intCast(item.data)))8304 => builder.ptrTypeAssumeCapacity(@as(Function.Index, @fromBackingInt(item.data))
7495 .ptrConst(builder).global.ptrConst(builder).addr_space),8305 .ptrConst(builder).global.ptrConst(builder).addr_space),
7496 .trunc,8306 .trunc,
7497 .ptrtoint,8307 .ptrtoint,
...@@ -7802,7 +8612,7 @@ pub const Constant = enum(u32) {...@@ -7802,7 +8612,7 @@ pub const Constant = enum(u32) {
7802 try w.writeByte('>');8612 try w.writeByte('>');
7803 },8613 },
7804 .string => try w.print("c{f}", .{8614 .string => try w.print("c{f}", .{
7805 @as(String, @fromBackingInt(@intCast(item.data))).fmtQ(data.builder),8615 @as(String, @fromBackingInt(item.data)).fmtQ(data.builder),
7806 }),8616 }),
7807 .blockaddress => |tag| {8617 .blockaddress => |tag| {
7808 const extra = data.builder.constantExtraData(BlockAddress, item.data);8618 const extra = data.builder.constantExtraData(BlockAddress, item.data);
...@@ -7816,7 +8626,7 @@ pub const Constant = enum(u32) {...@@ -7816,7 +8626,7 @@ pub const Constant = enum(u32) {
7816 .dso_local_equivalent,8626 .dso_local_equivalent,
7817 .no_cfi,8627 .no_cfi,
7818 => |tag| {8628 => |tag| {
7819 const function: Function.Index = @fromBackingInt(@intCast(item.data));8629 const function: Function.Index = @fromBackingInt(item.data);
7820 try w.print("{s} {f}", .{8630 try w.print("{s} {f}", .{
7821 @tagName(tag),8631 @tagName(tag),
7822 function.ptrConst(data.builder).global.fmt(data.builder),8632 function.ptrConst(data.builder).global.fmt(data.builder),
...@@ -7920,9 +8730,9 @@ pub const Value = enum(u32) {...@@ -7920,9 +8730,9 @@ pub const Value = enum(u32) {
7920 metadata: Metadata,8730 metadata: Metadata,
7921 } {8731 } {
7922 return if (@backingInt(self) < first_constant)8732 return if (@backingInt(self) < first_constant)
7923 .{ .instruction = @fromBackingInt(@intCast(@backingInt(self))) }8733 .{ .instruction = @fromBackingInt(@backingInt(self)) }
7924 else if (@backingInt(self) < first_metadata)8734 else if (@backingInt(self) < first_metadata)
7925 .{ .constant = @fromBackingInt(@intCast(@backingInt(self) - first_constant)) }8735 .{ .constant = @fromBackingInt(@backingInt(self) - first_constant) }
7926 else8736 else
7927 .{ .metadata = @bitCast(@backingInt(self) - first_metadata) };8737 .{ .metadata = @bitCast(@backingInt(self) - first_metadata) };
7928 }8738 }
...@@ -8016,7 +8826,7 @@ pub const Metadata = packed struct(u32) {...@@ -8016,7 +8826,7 @@ pub const Metadata = packed struct(u32) {
8016 return .{ .index = metadata.index, .kind = metadata.kind, .is_none = false };8826 return .{ .index = metadata.index, .kind = metadata.kind, .is_none = false };
8017 }8827 }
8018 pub fn toValue(metadata: Metadata) Value {8828 pub fn toValue(metadata: Metadata) Value {
8019 return @fromBackingInt(@intCast(Value.first_metadata + @as(u32, @bitCast(metadata))));8829 return @fromBackingInt(Value.first_metadata + @as(u32, @bitCast(metadata)));
8020 }8830 }
80218831
8022 pub const String = enum(u32) {8832 pub const String = enum(u32) {
...@@ -8032,7 +8842,7 @@ pub const Metadata = packed struct(u32) {...@@ -8032,7 +8842,7 @@ pub const Metadata = packed struct(u32) {
8032 pub fn unwrap(metadata: Metadata.String.Optional) ?Metadata.String {8842 pub fn unwrap(metadata: Metadata.String.Optional) ?Metadata.String {
8033 return switch (metadata) {8843 return switch (metadata) {
8034 .none => null,8844 .none => null,
8035 else => @fromBackingInt(@intCast(@backingInt(metadata))),8845 else => @fromBackingInt(@backingInt(metadata)),
8036 };8846 };
8037 }8847 }
8038 pub fn toMetadata(metadata: Metadata.String.Optional) Metadata.Optional {8848 pub fn toMetadata(metadata: Metadata.String.Optional) Metadata.Optional {
...@@ -8040,7 +8850,7 @@ pub const Metadata = packed struct(u32) {...@@ -8040,7 +8850,7 @@ pub const Metadata = packed struct(u32) {
8040 }8850 }
8041 };8851 };
8042 pub fn toOptional(metadata: Metadata.String) Metadata.String.Optional {8852 pub fn toOptional(metadata: Metadata.String) Metadata.String.Optional {
8043 return @fromBackingInt(@intCast(@backingInt(metadata)));8853 return @fromBackingInt(@backingInt(metadata));
8044 }8854 }
8045 pub fn toMetadata(metadata: Metadata.String) Metadata {8855 pub fn toMetadata(metadata: Metadata.String) Metadata {
8046 return .{ .index = @intCast(@backingInt(metadata)), .kind = .string };8856 return .{ .index = @intCast(@backingInt(metadata)), .kind = .string };
...@@ -8077,7 +8887,7 @@ pub const Metadata = packed struct(u32) {...@@ -8077,7 +8887,7 @@ pub const Metadata = packed struct(u32) {
8077 };8887 };
8078 pub fn toString(metadata: Metadata) Metadata.String {8888 pub fn toString(metadata: Metadata) Metadata.String {
8079 assert(metadata.kind == .string);8889 assert(metadata.kind == .string);
8080 return @fromBackingInt(@intCast(metadata.index));8890 return @fromBackingInt(metadata.index);
8081 }8891 }
80828892
8083 pub const Tag = enum(u6) {8893 pub const Tag = enum(u6) {
...@@ -8542,7 +9352,7 @@ pub const Metadata = packed struct(u32) {...@@ -8542,7 +9352,7 @@ pub const Metadata = packed struct(u32) {
8542 try w.writeByte(')');9352 try w.writeByte(')');
8543 },9353 },
8544 .constant => try Constant.format(.{9354 .constant => try Constant.format(.{
8545 .constant = @fromBackingInt(@intCast(node_item.data)),9355 .constant = @fromBackingInt(node_item.data),
8546 .builder = builder,9356 .builder = builder,
8547 .flags = data.specialized orelse .{},9357 .flags = data.specialized orelse .{},
8548 }, w),9358 }, w),
...@@ -8735,7 +9545,14 @@ pub fn init(options: Options) Allocator.Error!Builder {...@@ -8735,7 +9545,14 @@ pub fn init(options: Options) Allocator.Error!Builder {
8735 .strip = options.strip,9545 .strip = options.strip,
87369546
8737 .source_filename = .none,9547 .source_filename = .none,
8738 .data_layout = .none,9548 .data_layout = .{
9549 .endian = null,
9550 .int_specs = .empty,
9551 .float_specs = .empty,
9552 .vector_specs = .empty,
9553 .pointer_specs = .empty,
9554 .string_repr = .none,
9555 },
8739 .target_triple = .none,9556 .target_triple = .none,
8740 .module_asm = .empty,9557 .module_asm = .empty,
87419558
...@@ -8744,7 +9561,7 @@ pub fn init(options: Options) Allocator.Error!Builder {...@@ -8744,7 +9561,7 @@ pub fn init(options: Options) Allocator.Error!Builder {
8744 .string_bytes = .empty,9561 .string_bytes = .empty,
87459562
8746 .types = .empty,9563 .types = .empty,
8747 .next_unnamed_type = @fromBackingInt(@intCast(0)),9564 .next_unnamed_type = @fromBackingInt(0),
8748 .next_unique_type_id = .empty,9565 .next_unique_type_id = .empty,
8749 .type_map = .empty,9566 .type_map = .empty,
8750 .type_items = .empty,9567 .type_items = .empty,
...@@ -8758,7 +9575,7 @@ pub fn init(options: Options) Allocator.Error!Builder {...@@ -8758,7 +9575,7 @@ pub fn init(options: Options) Allocator.Error!Builder {
8758 .function_attributes_set = .empty,9575 .function_attributes_set = .empty,
87599576
8760 .globals = .empty,9577 .globals = .empty,
8761 .next_unnamed_global = @fromBackingInt(@intCast(0)),9578 .next_unnamed_global = @fromBackingInt(0),
8762 .next_replaced_global = .none,9579 .next_replaced_global = .none,
8763 .next_unique_global_id = .empty,9580 .next_unique_global_id = .empty,
8764 .aliases = .empty,9581 .aliases = .empty,
...@@ -8791,14 +9608,14 @@ pub fn init(options: Options) Allocator.Error!Builder {...@@ -8791,14 +9608,14 @@ pub fn init(options: Options) Allocator.Error!Builder {
8791 try self.string_indices.append(self.gpa, 0);9608 try self.string_indices.append(self.gpa, 0);
8792 assert(try self.string("") == .empty);9609 assert(try self.string("") == .empty);
87939610
9611 self.data_layout = try .parseString(try self.string(DataLayout.stringForTarget(options.target)), &self);
9612
8794 try self.strtab_string_indices.append(self.gpa, 0);9613 try self.strtab_string_indices.append(self.gpa, 0);
8795 assert(try self.strtabString("") == .empty);9614 assert(try self.strtabString("") == .empty);
87969615
8797 if (options.name.len > 0) self.source_filename = try self.string(options.name);9616 if (options.name.len > 0) self.source_filename = try self.string(options.name);
87989617
8799 if (options.triple.len > 0) {9618 if (options.triple.len > 0) self.target_triple = try self.string(options.triple);
8800 self.target_triple = try self.string(options.triple);
8801 }
88029619
8803 {9620 {
8804 const static_len = @typeInfo(Type).@"enum".field_names.len - 1;9621 const static_len = @typeInfo(Type).@"enum".field_names.len - 1;
...@@ -8815,7 +9632,7 @@ pub fn init(options: Options) Allocator.Error!Builder {...@@ -8815,7 +9632,7 @@ pub fn init(options: Options) Allocator.Error!Builder {
8815 assert(self.intTypeAssumeCapacity(bits) ==9632 assert(self.intTypeAssumeCapacity(bits) ==
8816 @field(Type, std.fmt.comptimePrint("i{d}", .{bits})));9633 @field(Type, std.fmt.comptimePrint("i{d}", .{bits})));
8817 inline for (.{ 0, 4 }) |addr_space_index| {9634 inline for (.{ 0, 4 }) |addr_space_index| {
8818 const addr_space: AddrSpace = @fromBackingInt(@intCast(addr_space_index));9635 const addr_space: AddrSpace = @fromBackingInt(addr_space_index);
8819 assert(self.ptrTypeAssumeCapacity(addr_space) ==9636 assert(self.ptrTypeAssumeCapacity(addr_space) ==
8820 @field(Type, std.fmt.comptimePrint("ptr{f}", .{addr_space.fmt(" ")})));9637 @field(Type, std.fmt.comptimePrint("ptr{f}", .{addr_space.fmt(" ")})));
8821 }9638 }
...@@ -8891,6 +9708,8 @@ pub fn clearAndFree(self: *Builder) void {...@@ -8891,6 +9708,8 @@ pub fn clearAndFree(self: *Builder) void {
8891pub fn deinit(self: *Builder) void {9708pub fn deinit(self: *Builder) void {
8892 const gpa = self.gpa;9709 const gpa = self.gpa;
88939710
9711 self.data_layout.deinit(gpa);
9712
8894 self.module_asm.deinit(gpa);9713 self.module_asm.deinit(gpa);
88959714
8896 self.string_map.deinit(gpa);9715 self.string_map.deinit(gpa);
...@@ -9092,17 +9911,17 @@ pub fn attrs(self: *Builder, attributes: []Attribute.Index) Allocator.Error!Attr...@@ -9092,17 +9911,17 @@ pub fn attrs(self: *Builder, attributes: []Attribute.Index) Allocator.Error!Attr
9092 return @backingInt(lhs_kind) < @backingInt(rhs_kind);9911 return @backingInt(lhs_kind) < @backingInt(rhs_kind);
9093 }9912 }
9094 }.lessThan);9913 }.lessThan);
9095 return @fromBackingInt(@intCast(try self.attrGeneric(@ptrCast(attributes))));9914 return @fromBackingInt(try self.attrGeneric(@ptrCast(attributes)));
9096}9915}
90979916
9098pub fn fnAttrs(self: *Builder, fn_attributes: []const Attributes) Allocator.Error!FunctionAttributes {9917pub fn fnAttrs(self: *Builder, fn_attributes: []const Attributes) Allocator.Error!FunctionAttributes {
9099 try self.function_attributes_set.ensureUnusedCapacity(self.gpa, 1);9918 try self.function_attributes_set.ensureUnusedCapacity(self.gpa, 1);
9100 const function_attributes: FunctionAttributes = @fromBackingInt(@intCast(try self.attrGeneric(@ptrCast(9919 const function_attributes: FunctionAttributes = @fromBackingInt(try self.attrGeneric(@ptrCast(
9101 fn_attributes[0..if (std.mem.lastIndexOfNone(Attributes, fn_attributes, &.{.none})) |last|9920 fn_attributes[0..if (std.mem.lastIndexOfNone(Attributes, fn_attributes, &.{.none})) |last|
9102 last + 19921 last + 1
9103 else9922 else
9104 0],9923 0],
9105 ))));9924 )));
91069925
9107 _ = self.function_attributes_set.getOrPutAssumeCapacity(function_attributes);9926 _ = self.function_attributes_set.getOrPutAssumeCapacity(function_attributes);
9108 return function_attributes;9927 return function_attributes;
...@@ -9121,7 +9940,7 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: StrtabString, global: Globa...@@ -9121,7 +9940,7 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: StrtabString, global: Globa
9121 if (name == .empty) {9940 if (name == .empty) {
9122 id = self.next_unnamed_global;9941 id = self.next_unnamed_global;
9123 assert(id != self.next_replaced_global);9942 assert(id != self.next_replaced_global);
9124 self.next_unnamed_global = @fromBackingInt(@intCast(@backingInt(id) + 1));9943 self.next_unnamed_global = @fromBackingInt(@backingInt(id) + 1);
9125 }9944 }
9126 while (true) {9945 while (true) {
9127 const global_gop = self.globals.getOrPutAssumeCapacity(id);9946 const global_gop = self.globals.getOrPutAssumeCapacity(id);
...@@ -9710,17 +10529,17 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void...@@ -9710,17 +10529,17 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
9710 var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined };10529 var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined };
9711 defer metadata_formatter.map.deinit(self.gpa);10530 defer metadata_formatter.map.deinit(self.gpa);
971210531
9713 if (self.source_filename != .none or self.data_layout != .none or self.target_triple != .none) {10532 if (self.source_filename != .none or self.data_layout.string_repr != .none or self.target_triple != .none) {
9714 if (need_newline) try w.writeByte('\n') else need_newline = true;10533 if (need_newline) try w.writeByte('\n') else need_newline = true;
9715 if (self.source_filename != .none) try w.print(10534 if (self.source_filename != .none) try w.print(
9716 \\; ModuleID = '{s}'10535 \\; ModuleID = '{s}'
9717 \\source_filename = {f}10536 \\source_filename = {f}
9718 \\10537 \\
9719 , .{ self.source_filename.slice(self).?, self.source_filename.fmtQ(self) });10538 , .{ self.source_filename.slice(self).?, self.source_filename.fmtQ(self) });
9720 if (self.data_layout != .none) try w.print(10539 if (self.data_layout.string_repr != .none) try w.print(
9721 \\target datalayout = {f}10540 \\target datalayout = {f}
9722 \\10541 \\
9723 , .{self.data_layout.fmtQ(self)});10542 , .{self.data_layout.string_repr.fmtQ(self)});
9724 if (self.target_triple != .none) try w.print(10543 if (self.target_triple != .none) try w.print(
9725 \\target triple = {f}10544 \\target triple = {f}
9726 \\10545 \\
...@@ -10058,7 +10877,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void...@@ -10058,7 +10877,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
10058 continue;10877 continue;
10059 },10878 },
10060 .br => |tag| {10879 .br => |tag| {
10061 const target: Function.Block.Index = @fromBackingInt(@intCast(instruction.data));10880 const target: Function.Block.Index = @fromBackingInt(instruction.data);
10062 try w.print(" {s} {f}", .{10881 try w.print(" {s} {f}", .{
10063 @tagName(tag), target.toInst(&function).fmt(function_index, self, .{ .percent = true }),10882 @tagName(tag), target.toInst(&function).fmt(function_index, self, .{ .percent = true }),
10064 });10883 });
...@@ -10187,7 +11006,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void...@@ -10187,7 +11006,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
10187 .fneg,11006 .fneg,
10188 .@"fneg fast",11007 .@"fneg fast",
10189 => |tag| {11008 => |tag| {
10190 const val: Value = @fromBackingInt(@intCast(instruction.data));11009 const val: Value = @fromBackingInt(instruction.data);
10191 try w.print(" %{f} = {s} {f}", .{11010 try w.print(" %{f} = {s} {f}", .{
10192 instruction_index.name(&function).fmt(self),11011 instruction_index.name(&function).fmt(self),
10193 @tagName(tag),11012 @tagName(tag),
...@@ -10288,7 +11107,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void...@@ -10288,7 +11107,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
10288 }11107 }
10289 },11108 },
10290 .ret => |tag| {11109 .ret => |tag| {
10291 const val: Value = @fromBackingInt(@intCast(instruction.data));11110 const val: Value = @fromBackingInt(instruction.data);
10292 try w.print(" {s} {f}", .{11111 try w.print(" {s} {f}", .{
10293 @tagName(tag),11112 @tagName(tag),
10294 val.fmt(function_index, self, .{ .percent = true }),11113 val.fmt(function_index, self, .{ .percent = true }),
...@@ -11020,7 +11839,7 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {...@@ -11020,7 +11839,7 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {
11020 if (name == .empty) {11839 if (name == .empty) {
11021 id = self.next_unnamed_type;11840 id = self.next_unnamed_type;
11022 assert(id != .none);11841 assert(id != .none);
11023 self.next_unnamed_type = @fromBackingInt(@intCast(@backingInt(id) + 1));11842 self.next_unnamed_type = @fromBackingInt(@backingInt(id) + 1);
11024 } else assert(!name.isAnon());11843 } else assert(!name.isAnon());
11025 while (true) {11844 while (true) {
11026 const type_gop = self.types.getOrPutAssumeCapacity(id);11845 const type_gop = self.types.getOrPutAssumeCapacity(id);
...@@ -11135,7 +11954,7 @@ fn typeExtraDataTrail(...@@ -11135,7 +11954,7 @@ fn typeExtraDataTrail(
11135 ) |field_name, field_type, value|11954 ) |field_name, field_type, value|
11136 @field(result, field_name) = switch (field_type) {11955 @field(result, field_name) = switch (field_type) {
11137 u32 => value,11956 u32 => value,
11138 String, Type => @fromBackingInt(@intCast(value)),11957 String, Type => @fromBackingInt(value),
11139 else => @compileError("bad field type: " ++ @typeName(field_type)),11958 else => @compileError("bad field type: " ++ @typeName(field_type)),
11140 };11959 };
11141 return .{11960 return .{
...@@ -11746,7 +12565,7 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty:...@@ -11746,7 +12565,7 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty:
11746 return std.meta.eql(lhs_key.cast, rhs_extra);12565 return std.meta.eql(lhs_key.cast, rhs_extra);
11747 }12566 }
11748 };12567 };
11749 const data = Key{ .tag = tag, .cast = .{ .val = val, .type = ty } };12568 const data: Key = .{ .tag = tag, .cast = .{ .val = val, .type = ty } };
11750 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });12569 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
11751 if (!gop.found_existing) {12570 if (!gop.found_existing) {
11752 gop.key_ptr.* = {};12571 gop.key_ptr.* = {};
...@@ -11828,10 +12647,10 @@ fn gepConstAssumeCapacity(...@@ -11828,10 +12647,10 @@ fn gepConstAssumeCapacity(
11828 std.mem.eql(Constant, lhs_key.indices, rhs_indices);12647 std.mem.eql(Constant, lhs_key.indices, rhs_indices);
11829 }12648 }
11830 };12649 };
11831 const data = Key{12650 const data: Key = .{
11832 .type = ty,12651 .type = ty,
11833 .base = base,12652 .base = base,
11834 .inrange = if (inrange) |index| @fromBackingInt(@intCast(index)) else .none,12653 .inrange = if (inrange) |index| @fromBackingInt(index) else .none,
11835 .indices = indices,12654 .indices = indices,
11836 };12655 };
11837 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });12656 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
...@@ -11885,7 +12704,7 @@ fn binConstAssumeCapacity(...@@ -11885,7 +12704,7 @@ fn binConstAssumeCapacity(
11885 return std.meta.eql(lhs_key.extra, rhs_extra);12704 return std.meta.eql(lhs_key.extra, rhs_extra);
11886 }12705 }
11887 };12706 };
11888 const data = Key{ .tag = tag, .extra = .{ .lhs = lhs, .rhs = rhs } };12707 const data: Key = .{ .tag = tag, .extra = .{ .lhs = lhs, .rhs = rhs } };
11889 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });12708 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
11890 if (!gop.found_existing) {12709 if (!gop.found_existing) {
11891 gop.key_ptr.* = {};12710 gop.key_ptr.* = {};
...@@ -11924,8 +12743,8 @@ fn asmConstAssumeCapacity(...@@ -11924,8 +12743,8 @@ fn asmConstAssumeCapacity(
11924 }12743 }
11925 };12744 };
1192612745
11927 const data = Key{12746 const data: Key = .{
11928 .tag = @fromBackingInt(@intCast(@backingInt(Constant.Tag.@"asm") + @as(u4, @bitCast(info)))),12747 .tag = @fromBackingInt(@backingInt(Constant.Tag.@"asm") + @as(u4, @bitCast(info))),
11929 .extra = .{ .type = ty, .assembly = assembly, .constraints = constraints },12748 .extra = .{ .type = ty, .assembly = assembly, .constraints = constraints },
11930 };12749 };
11931 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });12750 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
...@@ -12073,7 +12892,7 @@ fn constantExtraDataTrail(...@@ -12073,7 +12892,7 @@ fn constantExtraDataTrail(
12073 ) |field_name, field_type, value|12892 ) |field_name, field_type, value|
12074 @field(result, field_name) = switch (field_type) {12893 @field(result, field_name) = switch (field_type) {
12075 u32 => value,12894 u32 => value,
12076 String, Type, Constant, Function.Index, Function.Block.Index => @fromBackingInt(@intCast(value)),12895 String, Type, Constant, Function.Index, Function.Block.Index => @fromBackingInt(value),
12077 Constant.GetElementPtr.Info => @bitCast(value),12896 Constant.GetElementPtr.Info => @bitCast(value),
12078 else => @compileError("bad field type: " ++ @typeName(field_type)),12897 else => @compileError("bad field type: " ++ @typeName(field_type)),
12079 };12898 };
...@@ -12151,7 +12970,7 @@ fn metadataExtraDataTrail(...@@ -12151,7 +12970,7 @@ fn metadataExtraDataTrail(
12151 ) |field_name, field_type, value|12970 ) |field_name, field_type, value|
12152 @field(result, field_name) = switch (field_type) {12971 @field(result, field_name) = switch (field_type) {
12153 u32 => value,12972 u32 => value,
12154 Metadata.String, Metadata.String.Optional, Variable.Index, Value => @fromBackingInt(@intCast(value)),12973 Metadata.String, Metadata.String.Optional, Variable.Index, Value => @fromBackingInt(value),
12155 Metadata, Metadata.Optional, Metadata.DIFlags => @bitCast(value),12974 Metadata, Metadata.Optional, Metadata.DIFlags => @bitCast(value),
12156 else => @compileError("bad field type: " ++ @typeName(field_type)),12975 else => @compileError("bad field type: " ++ @typeName(field_type)),
12157 };12976 };
...@@ -12759,8 +13578,8 @@ fn debugSubprogramAssumeCapacity(...@@ -12759,8 +13578,8 @@ fn debugSubprogramAssumeCapacity(
12759 compile_unit: ?Metadata,13578 compile_unit: ?Metadata,
12760) Metadata {13579) Metadata {
12761 assert(!self.strip);13580 assert(!self.strip);
12762 const tag: Metadata.Tag = @fromBackingInt(@intCast(@backingInt(Metadata.Tag.subprogram) +13581 const tag: Metadata.Tag = @fromBackingInt(@backingInt(Metadata.Tag.subprogram) +
12763 @as(u3, @truncate(@as(u32, @bitCast(options.sp_flags)) >> 2))));13582 @as(u3, @truncate(@as(u32, @bitCast(options.sp_flags)) >> 2)));
12764 return self.metadataDistinctAssumeCapacity(tag, Metadata.Subprogram{13583 return self.metadataDistinctAssumeCapacity(tag, Metadata.Subprogram{
12765 .file = .wrap(file),13584 .file = .wrap(file),
12766 .name = .wrap(name),13585 .name = .wrap(name),
...@@ -13345,7 +14164,7 @@ fn metadataConstantAssumeCapacity(self: *Builder, constant: Constant) Metadata {...@@ -13345,7 +14164,7 @@ fn metadataConstantAssumeCapacity(self: *Builder, constant: Constant) Metadata {
1334514164
13346 pub fn eql(ctx: @This(), lhs_key: Constant, _: void, rhs_index: usize) bool {14165 pub fn eql(ctx: @This(), lhs_key: Constant, _: void, rhs_index: usize) bool {
13347 if (Metadata.Tag.constant != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false;14166 if (Metadata.Tag.constant != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false;
13348 const rhs_data: Constant = @fromBackingInt(@intCast(ctx.builder.metadata_items.items(.data)[rhs_index]));14167 const rhs_data: Constant = @fromBackingInt(ctx.builder.metadata_items.items(.data)[rhs_index]);
13349 return rhs_data == lhs_key;14168 return rhs_data == lhs_key;
13350 }14169 }
13351 };14170 };
...@@ -13418,7 +14237,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13418,7 +14237,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13418 });14237 });
13419 }14238 }
1342014239
13421 if (self.data_layout.slice(self)) |data_layout| {14240 if (self.data_layout.string_repr.slice(self)) |data_layout| {
13422 try module_block.writeAbbrev(ModuleBlock.String{14241 try module_block.writeAbbrev(ModuleBlock.String{
13423 .code = 3,14242 .code = 3,
13424 .string = data_layout,14243 .string = data_layout,
...@@ -13577,6 +14396,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13577,6 +14396,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13577 switch (attr_index.toAttribute(self)) {14396 switch (attr_index.toAttribute(self)) {
13578 .zeroext,14397 .zeroext,
13579 .signext,14398 .signext,
14399 .noext,
13580 .inreg,14400 .inreg,
13581 .@"noalias",14401 .@"noalias",
13582 .nocapture,14402 .nocapture,
...@@ -13594,11 +14414,13 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13594,11 +14414,13 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13594 .readnone,14414 .readnone,
13595 .readonly,14415 .readonly,
13596 .writeonly,14416 .writeonly,
14417 .writable,
14418 .dead_on_unwind,
13597 .alwaysinline,14419 .alwaysinline,
13598 .builtin,14420 .builtin,
13599 .cold,14421 .cold,
13600 .convergent,14422 .convergent,
13601 .disable_sanitizer_information,14423 .disable_sanitizer_instrumentation,
13602 .fn_ret_thunk_extern,14424 .fn_ret_thunk_extern,
13603 .hot,14425 .hot,
13604 .inlinehint,14426 .inlinehint,
...@@ -13607,6 +14429,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13607,6 +14429,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13607 .naked,14429 .naked,
13608 .nobuiltin,14430 .nobuiltin,
13609 .nocallback,14431 .nocallback,
14432 .nodivergencesource,
13610 .noduplicate,14433 .noduplicate,
13611 .noimplicitfloat,14434 .noimplicitfloat,
13612 .@"noinline",14435 .@"noinline",
...@@ -13623,6 +14446,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13623,6 +14446,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13623 .nosanitize_bounds,14446 .nosanitize_bounds,
13624 .nosanitize_coverage,14447 .nosanitize_coverage,
13625 .null_pointer_is_valid,14448 .null_pointer_is_valid,
14449 .optdebug,
13626 .optforfuzzing,14450 .optforfuzzing,
13627 .optnone,14451 .optnone,
13628 .optsize,14452 .optsize,
...@@ -13633,18 +14457,21 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13633,18 +14457,21 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13633 .sanitize_thread,14457 .sanitize_thread,
13634 .sanitize_hwaddress,14458 .sanitize_hwaddress,
13635 .sanitize_memtag,14459 .sanitize_memtag,
14460 .sanitize_realtime,
14461 .sanitize_realtime_blocking,
14462 .sanitize_alloc_token,
13636 .speculative_load_hardening,14463 .speculative_load_hardening,
13637 .speculatable,14464 .speculatable,
13638 .ssp,14465 .ssp,
13639 .sspstrong,14466 .sspstrong,
13640 .sspreq,14467 .sspreq,
13641 .strictfp,14468 .strictfp,
14469 .denormal_fpenv,
13642 .nocf_check,14470 .nocf_check,
13643 .shadowcallstack,14471 .shadowcallstack,
13644 .mustprogress,14472 .mustprogress,
13645 .no_sanitize_address,14473 .nooutline,
13646 .no_sanitize_hwaddress,14474 .nocreateundeforpoison,
13647 .sanitize_address_dyninit,
13648 => {14475 => {
13649 try record.ensureUnusedCapacity(self.gpa, 2);14476 try record.ensureUnusedCapacity(self.gpa, 2);
13650 record.appendAssumeCapacity(0);14477 record.appendAssumeCapacity(0);
...@@ -13670,6 +14497,12 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13670,6 +14497,12 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13670 record.appendAssumeCapacity(@backingInt(kind));14497 record.appendAssumeCapacity(@backingInt(kind));
13671 record.appendAssumeCapacity(alignment.resolve(self).toByteUnits() orelse 0);14498 record.appendAssumeCapacity(alignment.resolve(self).toByteUnits() orelse 0);
13672 },14499 },
14500 .captures => |captures| {
14501 try record.ensureUnusedCapacity(self.gpa, 3);
14502 record.appendAssumeCapacity(1);
14503 record.appendAssumeCapacity(@backingInt(kind));
14504 record.appendAssumeCapacity(@as(u32, @bitCast(captures)));
14505 },
13673 .dereferenceable,14506 .dereferenceable,
13674 .dereferenceable_or_null,14507 .dereferenceable_or_null,
13675 => |size| {14508 => |size| {
...@@ -13684,6 +14517,9 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13684,6 +14517,9 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13684 record.appendAssumeCapacity(@backingInt(kind));14517 record.appendAssumeCapacity(@backingInt(kind));
13685 record.appendAssumeCapacity(@as(u32, @bitCast(fpclass)));14518 record.appendAssumeCapacity(@as(u32, @bitCast(fpclass)));
13686 },14519 },
14520 .initializes => @panic("TODO"),
14521 .dead_on_return => @panic("TODO"),
14522 .range => @panic("TODO"),
13687 .allockind => |allockind| {14523 .allockind => |allockind| {
13688 try record.ensureUnusedCapacity(self.gpa, 3);14524 try record.ensureUnusedCapacity(self.gpa, 3);
13689 record.appendAssumeCapacity(1);14525 record.appendAssumeCapacity(1);
...@@ -14099,7 +14935,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -14099,7 +14935,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
14099 }14935 }
14100 },14936 },
14101 .string => {14937 .string => {
14102 const str: String = @fromBackingInt(@intCast(data));14938 const str: String = @fromBackingInt(data);
14103 if (str == .none) {14939 if (str == .none) {
14104 try constants_block.writeAbbrev(ConstantsBlock.Null{});14940 try constants_block.writeAbbrev(ConstantsBlock.Null{});
14105 } else {14941 } else {
...@@ -14226,7 +15062,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -14226,7 +15062,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
14226 .dso_local_equivalent,15062 .dso_local_equivalent,
14227 .no_cfi,15063 .no_cfi,
14228 => |tag| {15064 => |tag| {
14229 const function: Function.Index = @fromBackingInt(@intCast(data));15065 const function: Function.Index = @fromBackingInt(data);
14230 try constants_block.writeAbbrev(ConstantsBlock.DsoLocalEquivalentOrNoCfi{15066 try constants_block.writeAbbrev(ConstantsBlock.DsoLocalEquivalentOrNoCfi{
14231 .code = switch (tag) {15067 .code = switch (tag) {
14232 .dso_local_equivalent => .DSO_LOCAL_EQUIVALENT,15068 .dso_local_equivalent => .DSO_LOCAL_EQUIVALENT,
...@@ -14609,7 +15445,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -14609,7 +15445,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
14609 }, metadata_adapter);15445 }, metadata_adapter);
14610 },15446 },
14611 .constant => {15447 .constant => {
14612 const constant: Constant = @fromBackingInt(@intCast(data));15448 const constant: Constant = @fromBackingInt(data);
14613 try metadata_block.writeAbbrevAdapted(MetadataBlock.Constant{15449 try metadata_block.writeAbbrevAdapted(MetadataBlock.Constant{
14614 .ty = constant.typeOf(self),15450 .ty = constant.typeOf(self),
14615 .constant = constant,15451 .constant = constant,
...@@ -14778,7 +15614,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -14778,7 +15614,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
14778 var adapter: FunctionAdapter = .{15614 var adapter: FunctionAdapter = .{
14779 .metadata_adapter = metadata_adapter,15615 .metadata_adapter = metadata_adapter,
14780 .func = &func,15616 .func = &func,
14781 .instruction_index = @fromBackingInt(@intCast(0)),15617 .instruction_index = @fromBackingInt(0),
14782 };15618 };
1478315619
14784 // Emit function level metadata block15620 // Emit function level metadata block
...@@ -14789,7 +15625,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -14789,7 +15625,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
14789 for (func.debug_values) |value| {15625 for (func.debug_values) |value| {
14790 try metadata_block.writeAbbrev(MetadataBlock.Value{15626 try metadata_block.writeAbbrev(MetadataBlock.Value{
14791 .ty = value.typeOf(@fromBackingInt(@intCast(func_index)), self),15627 .ty = value.typeOf(@fromBackingInt(@intCast(func_index)), self),
14792 .value = @fromBackingInt(@intCast(adapter.getValueIndex(value.toValue()))),15628 .value = @fromBackingInt(adapter.getValueIndex(value.toValue())),
14793 });15629 });
14794 }15630 }
1479515631
...@@ -15071,10 +15907,10 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -15071,10 +15907,10 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
15071 });15907 });
15072 },15908 },
15073 .fneg => try function_block.writeAbbrev(FunctionBlock.FNeg{15909 .fneg => try function_block.writeAbbrev(FunctionBlock.FNeg{
15074 .val = adapter.getOffsetValueIndex(@fromBackingInt(@intCast(data))),15910 .val = adapter.getOffsetValueIndex(@fromBackingInt(data)),
15075 }),15911 }),
15076 .@"fneg fast" => try function_block.writeAbbrev(FunctionBlock.FNegFast{15912 .@"fneg fast" => try function_block.writeAbbrev(FunctionBlock.FNegFast{
15077 .val = adapter.getOffsetValueIndex(@fromBackingInt(@intCast(data))),15913 .val = adapter.getOffsetValueIndex(@fromBackingInt(data)),
15078 .fast_math = FastMath.fast,15914 .fast_math = FastMath.fast,
15079 }),15915 }),
15080 .extractvalue => {15916 .extractvalue => {
...@@ -15274,7 +16110,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -15274,7 +16110,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
15274 try function_block.writeUnabbrev(16, record.items);16110 try function_block.writeUnabbrev(16, record.items);
15275 },16111 },
15276 .ret => try function_block.writeAbbrev(FunctionBlock.Ret{16112 .ret => try function_block.writeAbbrev(FunctionBlock.Ret{
15277 .val = adapter.getOffsetValueIndex(@fromBackingInt(@intCast(data))),16113 .val = adapter.getOffsetValueIndex(@fromBackingInt(data)),
15278 }),16114 }),
15279 .@"ret void" => try function_block.writeAbbrev(FunctionBlock.RetVoid{}),16115 .@"ret void" => try function_block.writeAbbrev(FunctionBlock.RetVoid{}),
15280 .atomicrmw => {16116 .atomicrmw => {
lib/std/zig/target.zig+23-25
...@@ -499,34 +499,32 @@ pub fn intByteSize(target: *const std.Target, bits: u16) u16 {...@@ -499,34 +499,32 @@ pub fn intByteSize(target: *const std.Target, bits: u16) u16 {
499}499}
500500
501pub fn intAlignment(target: *const std.Target, bits: u16) u16 {501pub fn intAlignment(target: *const std.Target, bits: u16) u16 {
502 return switch (target.cpu.arch) {502 return switch (bits) {
503 .x86 => switch (bits) {503 0 => 1,
504 0...8 => 1,504 else => @min(
505 9...16 => 2,505 std.math.ceilPowerOfTwoPromote(u16, @intCast((@as(u17, bits) + 7) / 8)),
506 17...32 => 4,506 target.cMaxIntAlignment(),
507 33...64 => switch (target.os.tag) {507 ),
508 .uefi, .windows => 8,
509 else => 4,
510 },
511 else => 16,
512 },
513 .x86_64 => switch (bits) {
514 0...8 => 1,
515 9...16 => 2,
516 17...32 => 4,
517 33...64 => 8,
518 else => 16,
519 },
520 else => switch (bits) {
521 0 => 1,
522 else => @min(
523 std.math.ceilPowerOfTwoPromote(u16, @intCast((@as(u17, bits) + 7) / 8)),
524 target.cMaxIntAlignment(),
525 ),
526 },
527 };508 };
528}509}
529510
511pub fn compilerRtFloatAbi(target: *const std.Target, bits: u16) std.Target.Abi.Float {
512 if (target.cpu.has(.x86, .soft_float)) return .soft;
513 // Marks targets where clang does not even provide a usable C type.
514 const no_c_type_available = .soft;
515 switch (bits) {
516 else => unreachable,
517 16 => if (target.cpu.arch.isMIPS() or target.cpu.arch.isPowerPC()) return no_c_type_available,
518 32, 64 => {},
519 80 => if (target.cTypeBitSize(.longdouble) != 80) return no_c_type_available,
520 128 => {
521 if (target.cpu.arch.isX86()) return .hard; // if (target.abi == .msvc) __m128i else __float128
522 if (target.cTypeBitSize(.longdouble) != 128) return no_c_type_available;
523 },
524 }
525 return .hard;
526}
527
530const std = @import("std");528const std = @import("std");
531const assert = std.debug.assert;529const assert = std.debug.assert;
532const Allocator = std.mem.Allocator;530const Allocator = std.mem.Allocator;
lib/std/zon/parse.zig+1-6
...@@ -9,7 +9,6 @@...@@ -9,7 +9,6 @@
9//! For lower level control over parsing, see `std.zig.Zoir`.9//! For lower level control over parsing, see `std.zig.Zoir`.
1010
11const std = @import("std");11const std = @import("std");
12const builtin = @import("builtin");
13const Allocator = std.mem.Allocator;12const Allocator = std.mem.Allocator;
14const Ast = std.zig.Ast;13const Ast = std.zig.Ast;
15const Zoir = std.zig.Zoir;14const Zoir = std.zig.Zoir;
...@@ -1868,8 +1867,6 @@ test "std.zon tuples" {...@@ -1868,8 +1867,6 @@ test "std.zon tuples" {
18681867
1869// Test sizes 0 to 3 since small sizes get parsed differently1868// Test sizes 0 to 3 since small sizes get parsed differently
1870test "std.zon arrays and slices" {1869test "std.zon arrays and slices" {
1871 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/20881
1872
1873 const gpa = std.testing.allocator;1870 const gpa = std.testing.allocator;
18741871
1875 // Literals1872 // Literals
...@@ -2802,8 +2799,6 @@ test "std.zon negative char" {...@@ -2802,8 +2799,6 @@ test "std.zon negative char" {
2802}2799}
28032800
2804test "std.zon parse float" {2801test "std.zon parse float" {
2805 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
2806
2807 const gpa = std.testing.allocator;2802 const gpa = std.testing.allocator;
28082803
2809 // Test decimals2804 // Test decimals
...@@ -3135,7 +3130,7 @@ test "std.zon free on error" {...@@ -3135,7 +3130,7 @@ test "std.zon free on error" {
3135}3130}
31363131
3137test "std.zon vector" {3132test "std.zon vector" {
3138 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/153303133 const builtin = @import("builtin");
3139 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .s390x) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/259573134 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .s390x) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25957
31403135
3141 const gpa = std.testing.allocator;3136 const gpa = std.testing.allocator;
lib/std/zon/stringify.zig-3
...@@ -1151,9 +1151,6 @@ test "std.zon depth limits" {...@@ -1151,9 +1151,6 @@ test "std.zon depth limits" {
1151}1151}
11521152
1153test "std.zon stringify primitives" {1153test "std.zon stringify primitives" {
1154 // Issue: https://github.com/ziglang/zig/issues/20880
1155 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
1156
1157 try expectSerializeEqual(1154 try expectSerializeEqual(
1158 \\.{1155 \\.{
1159 \\ .a = 1.5,1156 \\ .a = 1.5,
lib/zig.h+3079-991
...@@ -166,6 +166,12 @@...@@ -166,6 +166,12 @@
166#endif166#endif
167#define zig_expand_has_builtin(b) zig_has_builtin(b)167#define zig_expand_has_builtin(b) zig_has_builtin(b)
168168
169#if defined(__has_feature)
170#define zig_has_feature(feature) __has_feature(feature)
171#else
172#define zig_has_feature(feature) 0
173#endif
174
169#if defined(__has_attribute)175#if defined(__has_attribute)
170#define zig_has_attribute(attribute) __has_attribute(attribute)176#define zig_has_attribute(attribute) __has_attribute(attribute)
171#else177#else
...@@ -175,9 +181,9 @@...@@ -175,9 +181,9 @@
175#if __STDC_VERSION__ >= 201112L181#if __STDC_VERSION__ >= 201112L
176#define zig_static_assert(cond, msg) _Static_assert(cond, msg)182#define zig_static_assert(cond, msg) _Static_assert(cond, msg)
177#elif zig_has_attribute(unused)183#elif zig_has_attribute(unused)
178#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)] __attribute__((unused))184#define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1] __attribute__((unused))
179#else185#else
180#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)]186#define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1]
181#endif187#endif
182188
183#if __STDC_VERSION__ >= 202311L189#if __STDC_VERSION__ >= 202311L
...@@ -193,10 +199,8 @@...@@ -193,10 +199,8 @@
193#endif199#endif
194200
195#if defined(zig_msvc)201#if defined(zig_msvc)
196#define zig_const_arr
197#define zig_callconv(c) __##c202#define zig_callconv(c) __##c
198#else203#else
199#define zig_const_arr static const
200#define zig_callconv(c) __attribute__((c))204#define zig_callconv(c) __attribute__((c))
201#endif205#endif
202206
...@@ -267,12 +271,20 @@...@@ -267,12 +271,20 @@
267271
268#if __STDC_VERSION__ >= 202311L272#if __STDC_VERSION__ >= 202311L
269#define zig_align(alignment) alignas(alignment)273#define zig_align(alignment) alignas(alignment)
270#elif __STDC_VERSION__ >= 201112L274#elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignas)
271#define zig_align(alignment) _Alignas(alignment)275#define zig_align(alignment) _Alignas(alignment)
272#else276#else
273#define zig_align(alignment) zig_under_align(alignment)277#define zig_align(alignment) zig_under_align(alignment)
274#endif278#endif
275279
280#if __STDC_VERSION__ >= 202311L
281#define zig_alignOf(Type) alignof(Type)
282#elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignof)
283#define zig_alignOf(Type) _Alignof(Type)
284#else
285#define zig_alignOf(Type) (sizeof(struct { char c; Type t; }) - sizeof(Type))
286#endif
287
276#if zig_has_attribute(aligned) || defined(zig_tinyc)288#if zig_has_attribute(aligned) || defined(zig_tinyc)
277#define zig_align_fn(alignment) __attribute__((aligned(alignment)))289#define zig_align_fn(alignment) __attribute__((aligned(alignment)))
278#elif defined(zig_msvc)290#elif defined(zig_msvc)
...@@ -350,11 +362,9 @@...@@ -350,11 +362,9 @@
350#define zig_export(symbol, name) __attribute__((alias(symbol)))362#define zig_export(symbol, name) __attribute__((alias(symbol)))
351#else363#else
352#define zig_export(symbol, name) ; \364#define zig_export(symbol, name) ; \
353 __asm(zig_mangle_c(name) " = " zig_mangle_c(symbol))365 __asm("\t.globl\t" zig_mangle_c(name) "\n" zig_mangle_c(name) " = " zig_mangle_c(symbol))
354#endif366#endif
355367
356#define zig_mangled_tentative zig_mangled
357#define zig_mangled_final zig_mangled
358#if defined(zig_msvc)368#if defined(zig_msvc)
359#define zig_mangled(mangled, unmangled) ; \369#define zig_mangled(mangled, unmangled) ; \
360 zig_export(#mangled, unmangled)370 zig_export(#mangled, unmangled)
...@@ -364,7 +374,7 @@...@@ -364,7 +374,7 @@
364#else /* zig_msvc */374#else /* zig_msvc */
365#define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled))375#define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled))
366#define zig_mangled_export(mangled, unmangled, symbol) \376#define zig_mangled_export(mangled, unmangled, symbol) \
367 zig_mangled_final(mangled, unmangled) \377 zig_mangled(mangled, unmangled) \
368 zig_export(symbol, unmangled)378 zig_export(symbol, unmangled)
369#endif /* zig_msvc */379#endif /* zig_msvc */
370380
...@@ -550,6 +560,9 @@...@@ -550,6 +560,9 @@
550#define zig_noreturn560#define zig_noreturn
551#endif561#endif
552562
563#define zig_has_always 1
564#define zig_has_never 0
565
553#define zig_compiler_rt_abbrev_uint32_t si566#define zig_compiler_rt_abbrev_uint32_t si
554#define zig_compiler_rt_abbrev_int32_t si567#define zig_compiler_rt_abbrev_int32_t si
555#define zig_compiler_rt_abbrev_uint64_t di568#define zig_compiler_rt_abbrev_uint64_t di
...@@ -560,7 +573,11 @@...@@ -560,7 +573,11 @@
560#define zig_compiler_rt_abbrev_zig_f32 sf573#define zig_compiler_rt_abbrev_zig_f32 sf
561#define zig_compiler_rt_abbrev_zig_f64 df574#define zig_compiler_rt_abbrev_zig_f64 df
562#define zig_compiler_rt_abbrev_zig_f80 xf575#define zig_compiler_rt_abbrev_zig_f80 xf
576#ifdef zig_powerpc
577#define zig_compiler_rt_abbrev_zig_f128 kf
578#else
563#define zig_compiler_rt_abbrev_zig_f128 tf579#define zig_compiler_rt_abbrev_zig_f128 tf
580#endif
564581
565zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);582zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);
566zig_extern void *memset (void *, int, size_t);583zig_extern void *memset (void *, int, size_t);
...@@ -645,16 +662,6 @@ typedef signed long long int16_t;...@@ -645,16 +662,6 @@ typedef signed long long int16_t;
645#define INT16_MAX ( INT16_C(0x7FFF))662#define INT16_MAX ( INT16_C(0x7FFF))
646#define UINT16_MAX ( INT16_C(0xFFFF))663#define UINT16_MAX ( INT16_C(0xFFFF))
647664
648#if defined(zig_ez80)
649typedef unsigned int uint24_t;
650typedef signed int int24_t;
651#define INT24_C(c) c
652#define UINT24_C(c) c##U
653#endif
654#define INT24_MIN (~INT24_C(0x7FFF))
655#define INT24_MAX ( INT24_C(0x7FFF))
656#define UINT24_MAX ( INT24_C(0xFFFF))
657
658#if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF665#if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF
659typedef unsigned char uint32_t;666typedef unsigned char uint32_t;
660typedef signed char int32_t;667typedef signed char int32_t;
...@@ -685,17 +692,6 @@ typedef signed long long int32_t;...@@ -685,17 +692,6 @@ typedef signed long long int32_t;
685#define INT32_MAX ( INT32_C(0x7FFFFFFF))692#define INT32_MAX ( INT32_C(0x7FFFFFFF))
686#define UINT32_MAX ( INT32_C(0xFFFFFFFF))693#define UINT32_MAX ( INT32_C(0xFFFFFFFF))
687694
688#if defined(zig_ez80)
689typedef unsigned __int48 uint48_t;
690typedef signed __int48 int48_t;
691#define INT48_C(c) c
692/* no suffix */
693#define UINT48_C(c) ((uint48_t)(c))
694#endif
695#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF))
696#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF))
697#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF))
698
699#if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF695#if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF
700typedef unsigned char uint64_t;696typedef unsigned char uint64_t;
701typedef signed char int64_t;697typedef signed char int64_t;
...@@ -726,6 +722,27 @@ typedef signed long long int64_t;...@@ -726,6 +722,27 @@ typedef signed long long int64_t;
726#define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF))722#define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF))
727#define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF))723#define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF))
728724
725#if defined(zig_ez80)
726
727typedef unsigned int uint24_t;
728typedef signed int int24_t;
729#define INT24_C(c) c
730#define UINT24_C(c) c##U
731#define INT24_MIN (~INT24_C(0x7FFF))
732#define INT24_MAX ( INT24_C(0x7FFF))
733#define UINT24_MAX ( INT24_C(0xFFFF))
734
735typedef unsigned __int48 uint48_t;
736typedef signed __int48 int48_t;
737#define INT48_C(c) c
738/* no suffix */
739#define UINT48_C(c) ((uint48_t)(c))
740#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF))
741#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF))
742#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF))
743
744#endif
745
729typedef size_t uintptr_t;746typedef size_t uintptr_t;
730typedef ptrdiff_t intptr_t;747typedef ptrdiff_t intptr_t;
731748
...@@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t;...@@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t;
739#define zig_maxInt_i16 INT16_MAX756#define zig_maxInt_i16 INT16_MAX
740#define zig_minInt_u16 UINT16_C(0)757#define zig_minInt_u16 UINT16_C(0)
741#define zig_maxInt_u16 UINT16_MAX758#define zig_maxInt_u16 UINT16_MAX
742#define zig_minInt_i24 INT24_MIN
743#define zig_maxInt_i24 INT24_MAX
744#define zig_minInt_u24 UINT24_C(0)
745#define zig_maxInt_u24 UINT24_MAX
746#define zig_minInt_i32 INT32_MIN759#define zig_minInt_i32 INT32_MIN
747#define zig_maxInt_i32 INT32_MAX760#define zig_maxInt_i32 INT32_MAX
748#define zig_minInt_u32 UINT32_C(0)761#define zig_minInt_u32 UINT32_C(0)
749#define zig_maxInt_u32 UINT32_MAX762#define zig_maxInt_u32 UINT32_MAX
750#define zig_minInt_i48 INT48_MIN
751#define zig_maxInt_i48 INT48_MAX
752#define zig_minInt_u48 UINT48_C(0)
753#define zig_maxInt_u48 UINT48_MAX
754#define zig_minInt_i64 INT64_MIN763#define zig_minInt_i64 INT64_MIN
755#define zig_maxInt_i64 INT64_MAX764#define zig_maxInt_i64 INT64_MAX
756#define zig_minInt_u64 UINT64_C(0)765#define zig_minInt_u64 UINT64_C(0)
757#define zig_maxInt_u64 UINT64_MAX766#define zig_maxInt_u64 UINT64_MAX
758767
768// zig_promoted_T implements C integral promotions except with signedness preserved, which
769// allows wrapping operations to avoid the ub that would be caused by the normal promotion.
770
771#if INT8_MAX <= INT_MAX
772typedef unsigned int zig_promoted_i8;
773#elif INT8_MAX <= LONG_MAX
774typedef unsigned long zig_promoted_i8;
775#elif INT8_MAX <= LLONG_MAX
776typedef unsigned long long zig_promoted_i8;
777#else
778typedef int8_t zig_promoted_i8;
779#endif
780#if UINT8_MAX <= UINT_MAX
781typedef unsigned int zig_promoted_u8;
782#elif UINT8_MAX <= ULONG_MAX
783typedef unsigned long zig_promoted_u8;
784#elif UINT8_MAX <= ULLONG_MAX
785typedef unsigned long long zig_promoted_u8;
786#else
787typedef uint8_t zig_promoted_u8;
788#endif
789
790#if INT16_MAX <= INT_MAX
791typedef unsigned int zig_promoted_i16;
792#elif INT16_MAX <= LONG_MAX
793typedef unsigned long zig_promoted_i16;
794#elif INT16_MAX <= LLONG_MAX
795typedef unsigned long long zig_promoted_i16;
796#else
797typedef int16_t zig_promoted_i16;
798#endif
799#if UINT16_MAX <= UINT_MAX
800typedef unsigned int zig_promoted_u16;
801#elif UINT16_MAX <= ULONG_MAX
802typedef unsigned long zig_promoted_u16;
803#elif UINT16_MAX <= ULLONG_MAX
804typedef unsigned long long zig_promoted_u16;
805#else
806typedef uint16_t zig_promoted_u16;
807#endif
808
809#if INT32_MAX <= INT_MAX
810typedef unsigned int zig_promoted_i32;
811#elif INT32_MAX <= LONG_MAX
812typedef unsigned long zig_promoted_i32;
813#elif INT32_MAX <= LLONG_MAX
814typedef unsigned long long zig_promoted_i32;
815#else
816typedef int32_t zig_promoted_i32;
817#endif
818#if UINT32_MAX <= UINT_MAX
819typedef unsigned int zig_promoted_u32;
820#elif UINT32_MAX <= ULONG_MAX
821typedef unsigned long zig_promoted_u32;
822#elif UINT32_MAX <= ULLONG_MAX
823typedef unsigned long long zig_promoted_u32;
824#else
825typedef uint32_t zig_promoted_u32;
826#endif
827
828#if INT64_MAX <= INT_MAX
829typedef unsigned int zig_promoted_i64;
830#elif INT64_MAX <= LONG_MAX
831typedef unsigned long zig_promoted_i64;
832#elif INT64_MAX <= LLONG_MAX
833typedef unsigned long long zig_promoted_i64;
834#else
835typedef int64_t zig_promoted_i64;
836#endif
837#if UINT64_MAX <= UINT_MAX
838typedef unsigned int zig_promoted_u64;
839#elif UINT64_MAX <= ULONG_MAX
840typedef unsigned long zig_promoted_u64;
841#elif UINT64_MAX <= ULLONG_MAX
842typedef unsigned long long zig_promoted_u64;
843#else
844typedef uint64_t zig_promoted_u64;
845#endif
846
847#ifdef zig_ez80
848
849#define zig_minInt_i24 INT24_MIN
850#define zig_maxInt_i24 INT24_MAX
851#define zig_minInt_u24 UINT24_C(0)
852#define zig_maxInt_u24 UINT24_MAX
853#define zig_minInt_i48 INT48_MIN
854#define zig_maxInt_i48 INT48_MAX
855#define zig_minInt_u48 UINT48_C(0)
856#define zig_maxInt_u48 UINT48_MAX
857
858#if INT24_MAX <= INT_MAX
859typedef unsigned int zig_promoted_i24;
860#elif INT24_MAX <= LONG_MAX
861typedef unsigned long zig_promoted_i24;
862#elif INT24_MAX <= LLONG_MAX
863typedef unsigned long long zig_promoted_i24;
864#else
865typedef int24_t zig_promoted_i24;
866#endif
867#if UINT24_MAX <= UINT_MAX
868typedef unsigned int zig_promoted_u24;
869#elif UINT24_MAX <= ULONG_MAX
870typedef unsigned long zig_promoted_u24;
871#elif UINT24_MAX <= ULLONG_MAX
872typedef unsigned long long zig_promoted_u24;
873#else
874typedef uint24_t zig_promoted_u24;
875#endif
876
877#if INT48_MAX <= INT_MAX
878typedef unsigned int zig_promoted_i48;
879#elif INT48_MAX <= LONG_MAX
880typedef unsigned long zig_promoted_i48;
881#elif INT48_MAX <= LLONG_MAX
882typedef unsigned long long zig_promoted_i48;
883#else
884typedef int48_t zig_promoted_i48;
885#endif
886#if UINT48_MAX <= UINT_MAX
887typedef unsigned int zig_promoted_u48;
888#elif UINT48_MAX <= ULONG_MAX
889typedef unsigned long zig_promoted_u48;
890#elif UINT48_MAX <= ULLONG_MAX
891typedef unsigned long long zig_promoted_u48;
892#else
893typedef uint48_t zig_promoted_u48;
894#endif
895
896#endif
897
759#define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits))898#define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits))
760#define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits)899#define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits)
761#define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits)900#define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits)
...@@ -770,7 +909,33 @@ typedef ptrdiff_t intptr_t;...@@ -770,7 +909,33 @@ typedef ptrdiff_t intptr_t;
770 zig_operator(Type, Type, operation, operator)909 zig_operator(Type, Type, operation, operator)
771#define zig_shift_operator(Type, operation, operator) \910#define zig_shift_operator(Type, operation, operator) \
772 zig_operator(Type, uint8_t, operation, operator)911 zig_operator(Type, uint8_t, operation, operator)
773#define zig_int_helpers(w, PromotedUnsigned) \912
913#define zig_int_casts_common(bw, sw) \
914 static inline uint##bw##_t zig_u##bw##_intCast_u##sw(uint##sw##_t arg) { \
915 return arg; \
916 } \
917\
918 static inline uint##bw##_t zig_u##bw##_intCast_i##sw(int##sw##_t arg) { \
919 return (uint##bw##_t)arg; \
920 } \
921\
922 static inline int##bw##_t zig_i##bw##_intCast_u##sw(uint##sw##_t arg) { \
923 return arg; \
924 } \
925\
926 static inline int##bw##_t zig_i##bw##_intCast_i##sw(int##sw##_t arg) { \
927 return arg; \
928 } \
929\
930 static inline uint##sw##_t zig_u##sw##_truncate_u##bw(uint##bw##_t arg, uint8_t bits) { \
931 return (uint##sw##_t)arg & zig_maxInt_u(sw, bits); \
932 } \
933\
934 static inline int##sw##_t zig_i##sw##_truncate_i##bw(int##bw##_t arg, uint8_t bits) { \
935 return ((uint##sw##_t)arg & UINT##sw##_C(1) << (bits - UINT8_C(1))) != UINT##sw##_C(0) \
936 ? (int##sw##_t)arg | zig_minInt_i(sw, bits) : (int##sw##_t)arg & zig_maxInt_i(sw, bits); \
937 }
938#define zig_int_operators(w) \
774 zig_basic_operator(uint##w##_t, and_u##w, &) \939 zig_basic_operator(uint##w##_t, and_u##w, &) \
775 zig_basic_operator( int##w##_t, and_i##w, &) \940 zig_basic_operator( int##w##_t, and_i##w, &) \
776 zig_basic_operator(uint##w##_t, or_u##w, |) \941 zig_basic_operator(uint##w##_t, or_u##w, |) \
...@@ -786,44 +951,48 @@ typedef ptrdiff_t intptr_t;...@@ -786,44 +951,48 @@ typedef ptrdiff_t intptr_t;
786 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \951 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \
787 } \952 } \
788\953\
789 static inline uint##w##_t zig_not_u##w(uint##w##_t val, uint8_t bits) { \954 static inline uint##w##_t zig_not_u##w(uint##w##_t arg, uint8_t bits) { \
790 return val ^ zig_maxInt_u(w, bits); \955 return arg ^ zig_maxInt_u(w, bits); \
791 } \956 } \
792\957\
793 static inline int##w##_t zig_not_i##w(int##w##_t val, uint8_t bits) { \958 static inline int##w##_t zig_not_i##w(int##w##_t arg, uint8_t bits) { \
794 (void)bits; \959 (void)bits; \
795 return ~val; \960 return ~arg; \
796 } \961 } \
797\962\
798 static inline uint##w##_t zig_wrap_u##w(uint##w##_t val, uint8_t bits) { \963 zig_basic_operator(uint##w##_t, divFloor_u##w, /) \
799 return val & zig_maxInt_u(w, bits); \964\
965 static inline int##w##_t zig_divFloor_i##w(int##w##_t lhs, int##w##_t rhs) { \
966 return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \
800 } \967 } \
801\968\
802 static inline int##w##_t zig_wrap_i##w(int##w##_t val, uint8_t bits) { \969 static inline uint##w##_t zig_divCeil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
803 return (val & UINT##w##_C(1) << (bits - UINT8_C(1))) != 0 \970 return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \
804 ? val | zig_minInt_i(w, bits) : val & zig_maxInt_i(w, bits); \
805 } \971 } \
806\972\
807 static inline uint##w##_t zig_abs_i##w(int##w##_t val) { \973 static inline int##w##_t zig_divCeil_i##w(int##w##_t lhs, int##w##_t rhs) { \
808 return (val < 0) ? -(uint##w##_t)val : (uint##w##_t)val; \974 return lhs / rhs + (lhs % rhs != INT##w##_C(0) \
975 ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \
809 } \976 } \
810\977\
811 zig_basic_operator(uint##w##_t, div_floor_u##w, /) \978 zig_basic_operator(uint##w##_t, mod_u##w, %) \
979 zig_int_casts_common(w, w) \
812\980\
813 static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \981 static inline uint##w##_t zig_u##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \
814 return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \982 return zig_u##w##_truncate_u##w(arg, bits); \
815 } \983 } \
816\984\
817 static inline uint##w##_t zig_div_ceil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \985 static inline uint##w##_t zig_u##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \
818 return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \986 return zig_u##w##_bitCast_u##w((uint##w##_t)arg, bits); \
819 } \987 } \
820\988\
821 static inline int##w##_t zig_div_ceil_i##w(int##w##_t lhs, int##w##_t rhs) { \989 static inline int##w##_t zig_i##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \
822 return lhs / rhs + (lhs % rhs != INT##w##_C(0) \990 return zig_i##w##_truncate_i##w(arg, bits); \
823 ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \
824 } \991 } \
825\992\
826 zig_basic_operator(uint##w##_t, mod_u##w, %) \993 static inline int##w##_t zig_i##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \
994 return zig_i##w##_bitCast_i##w((int##w##_t)arg, bits); \
995 } \
827\996\
828 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \997 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \
829 int##w##_t rem = lhs % rhs; \998 int##w##_t rem = lhs % rhs; \
...@@ -831,100 +1000,102 @@ typedef ptrdiff_t intptr_t;...@@ -831,100 +1000,102 @@ typedef ptrdiff_t intptr_t;
831 } \1000 } \
832\1001\
833 static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \1002 static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
834 return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \1003 return zig_u##w##_truncate_u##w(zig_shl_u##w(lhs, rhs), bits); \
835 } \1004 } \
836\1005\
837 static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \1006 static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \
838 return zig_wrap_i##w((int##w##_t)zig_shl_u##w((uint##w##_t)lhs, rhs), bits); \1007 return zig_i##w##_bitCast_u##w(zig_shl_u##w(zig_u##w##_bitCast_i##w(lhs, bits), rhs), bits); \
839 } \1008 } \
840\1009\
841 static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1010 static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
842 return zig_wrap_u##w(lhs + rhs, bits); \1011 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs + rhs, bits); \
843 } \1012 } \
844\1013\
845 static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \1014 static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
846 return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs + (uint##w##_t)rhs), bits); \1015 return zig_i##w##_bitCast_u##w(zig_addw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
847 } \1016 } \
848\1017\
849 static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1018 static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
850 return zig_wrap_u##w(lhs - rhs, bits); \1019 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs - rhs, bits); \
851 } \1020 } \
852\1021\
853 static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \1022 static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
854 return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs - (uint##w##_t)rhs), bits); \1023 return zig_i##w##_bitCast_u##w(zig_subw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
855 } \1024 } \
856\1025\
857 static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1026 static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
858 return zig_wrap_u##w((PromotedUnsigned)lhs * rhs, bits); \1027 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs * rhs, bits); \
859 } \1028 } \
860\1029\
861 static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \1030 static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
862 return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs * (uint##w##_t)rhs), bits); \1031 return zig_i##w##_bitCast_u##w(zig_mulw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
1032 } \
1033\
1034 static inline uint##w##_t zig_abs_i##w(int##w##_t arg) { \
1035 int##w##_t tmp = zig_shr_i##w(arg, UINT8_C(w) - UINT8_C(1)); \
1036 return zig_u##w##_bitCast_i##w(zig_subw_i##w(zig_xor_i##w(arg, tmp), tmp, UINT8_C(w)), UINT8_C(w)); \
1037 } \
1038\
1039 static inline uint##w##_t zig_min_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
1040 return lhs < rhs ? lhs : rhs; \
1041 } \
1042\
1043 static inline int##w##_t zig_min_i##w(int##w##_t lhs, int##w##_t rhs) { \
1044 return lhs < rhs ? lhs : rhs; \
1045 } \
1046\
1047 static inline uint##w##_t zig_max_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
1048 return lhs >= rhs ? lhs : rhs; \
1049 } \
1050\
1051 static inline int##w##_t zig_max_i##w(int##w##_t lhs, int##w##_t rhs) { \
1052 return lhs >= rhs ? lhs : rhs; \
863 }1053 }
864#if UINT8_MAX <= UINT_MAX1054zig_int_operators(8)
865zig_int_helpers(8, unsigned int)1055zig_int_operators(16)
866#elif UINT8_MAX <= ULONG_MAX1056zig_int_operators(32)
867zig_int_helpers(8, unsigned long)1057zig_int_operators(64)
868#elif UINT8_MAX <= ULLONG_MAX1058#ifdef zig_ez80
869zig_int_helpers(8, unsigned long long)1059zig_int_operators(24)
870#else1060zig_int_operators(48)
871zig_int_helpers(8, uint8_t)1061#endif
872#endif1062
873#if UINT16_MAX <= UINT_MAX1063#define zig_int_casts(bw, sw) \
874zig_int_helpers(16, unsigned int)1064 static inline uint##sw##_t zig_u##sw##_intCast_u##bw(uint##bw##_t arg) { \
875#elif UINT16_MAX <= ULONG_MAX1065 return (uint##sw##_t)arg; \
876zig_int_helpers(16, unsigned long)1066 } \
877#elif UINT16_MAX <= ULLONG_MAX1067\
878zig_int_helpers(16, unsigned long long)1068 static inline uint##sw##_t zig_u##sw##_intCast_i##bw(int##bw##_t arg) { \
879#else1069 return (uint##sw##_t)arg; \
880zig_int_helpers(16, uint16_t)1070 } \
881#endif1071\
882#if defined(zig_ez80)1072 static inline int##sw##_t zig_i##sw##_intCast_u##bw(uint##bw##_t arg) { \
883#if UINT24_MAX <= UINT_MAX1073 return (int##sw##_t)arg; \
884zig_int_helpers(24, unsigned int)1074 } \
885#elif UINT24_MAX <= ULONG_MAX1075\
886zig_int_helpers(24, unsigned long)1076 static inline int##sw##_t zig_i##sw##_intCast_i##bw(int##bw##_t arg) { \
887#elif UINT24_MAX <= ULLONG_MAX1077 return (int##sw##_t)arg; \
888zig_int_helpers(24, unsigned long long)1078 } \
889#else1079\
890zig_int_helpers(24, uint24_t)1080 zig_int_casts_common(bw, sw)
891#endif1081zig_int_casts(16, 8)
892#endif1082zig_int_casts(32, 8)
893#if UINT32_MAX <= UINT_MAX1083zig_int_casts(64, 8)
894zig_int_helpers(32, unsigned int)1084zig_int_casts(32, 16)
895#elif UINT32_MAX <= ULONG_MAX1085zig_int_casts(64, 16)
896zig_int_helpers(32, unsigned long)1086zig_int_casts(64, 32)
897#elif UINT32_MAX <= ULLONG_MAX1087#ifdef zig_ez80
898zig_int_helpers(32, unsigned long long)1088zig_int_casts(32, 24)
899#else1089zig_int_casts(48, 24)
900zig_int_helpers(32, uint32_t)1090zig_int_casts(64, 24)
901#endif1091zig_int_casts(64, 48)
902#if defined(zig_ez80)
903#if UINT24_MAX <= UINT_MAX
904zig_int_helpers(48, unsigned int)
905#elif UINT24_MAX <= ULONG_MAX
906zig_int_helpers(48, unsigned long)
907#elif UINT24_MAX <= ULLONG_MAX
908zig_int_helpers(48, unsigned long long)
909#else
910zig_int_helpers(48, uint48_t)
911#endif
912#endif
913#if UINT64_MAX <= UINT_MAX
914zig_int_helpers(64, unsigned int)
915#elif UINT64_MAX <= ULONG_MAX
916zig_int_helpers(64, unsigned long)
917#elif UINT64_MAX <= ULLONG_MAX
918zig_int_helpers(64, unsigned long long)
919#else
920zig_int_helpers(64, uint64_t)
921#endif1092#endif
9221093
923static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {1094static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
924#if zig_has_builtin(add_overflow) || defined(zig_gcc)1095#if zig_has_builtin(add_overflow) || defined(zig_gcc)
925 uint32_t full_res;1096 uint32_t full_res;
926 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1097 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
927 *res = zig_wrap_u32(full_res, bits);1098 *res = zig_u32_truncate_u32(full_res, bits);
928 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);1099 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
929#else1100#else
930 *res = zig_addw_u32(lhs, rhs, bits);1101 *res = zig_addw_u32(lhs, rhs, bits);
...@@ -936,19 +1107,19 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t...@@ -936,19 +1107,19 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
936#if zig_has_builtin(add_overflow) || defined(zig_gcc)1107#if zig_has_builtin(add_overflow) || defined(zig_gcc)
937 int32_t full_res;1108 int32_t full_res;
938 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1109 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1110 *res = zig_i32_truncate_i32(full_res, bits);
1111 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
939#else1112#else
940 int32_t full_res = (int32_t)((uint32_t)lhs + (uint32_t)rhs);1113 *res = zig_addw_i32(lhs, rhs, bits);
941 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;1114 return ((*res ^ lhs) & (*res ^ rhs)) < INT32_C(0);
942#endif1115#endif
943 *res = zig_wrap_i32(full_res, bits);
944 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
945}1116}
9461117
947static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {1118static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
948#if zig_has_builtin(add_overflow) || defined(zig_gcc)1119#if zig_has_builtin(add_overflow) || defined(zig_gcc)
949 uint64_t full_res;1120 uint64_t full_res;
950 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1121 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
951 *res = zig_wrap_u64(full_res, bits);1122 *res = zig_u64_truncate_u64(full_res, bits);
952 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);1123 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
953#else1124#else
954 *res = zig_addw_u64(lhs, rhs, bits);1125 *res = zig_addw_u64(lhs, rhs, bits);
...@@ -960,24 +1131,24 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t...@@ -960,24 +1131,24 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
960#if zig_has_builtin(add_overflow) || defined(zig_gcc)1131#if zig_has_builtin(add_overflow) || defined(zig_gcc)
961 int64_t full_res;1132 int64_t full_res;
962 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1133 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1134 *res = zig_i64_truncate_i64(full_res, bits);
1135 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
963#else1136#else
964 int64_t full_res = (int64_t)((uint64_t)lhs + (uint64_t)rhs);1137 *res = zig_addw_i64(lhs, rhs, bits);
965 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;1138 return ((*res ^ lhs) & (*res ^ rhs)) < INT64_C(0);
966#endif1139#endif
967 *res = zig_wrap_i64(full_res, bits);
968 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
969}1140}
9701141
971static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {1142static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
972#if zig_has_builtin(add_overflow) || defined(zig_gcc)1143#if zig_has_builtin(add_overflow) || defined(zig_gcc)
973 uint8_t full_res;1144 uint8_t full_res;
974 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1145 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
975 *res = zig_wrap_u8(full_res, bits);1146 *res = zig_u8_truncate_u8(full_res, bits);
976 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);1147 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
977#else1148#else
978 uint32_t full_res;1149 uint32_t full_res;
979 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);1150 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
980 *res = (uint8_t)full_res;1151 *res = zig_u8_intCast_u32(full_res);
981 return overflow;1152 return overflow;
982#endif1153#endif
983}1154}
...@@ -986,12 +1157,12 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits...@@ -986,12 +1157,12 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
986#if zig_has_builtin(add_overflow) || defined(zig_gcc)1157#if zig_has_builtin(add_overflow) || defined(zig_gcc)
987 int8_t full_res;1158 int8_t full_res;
988 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1159 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
989 *res = zig_wrap_i8(full_res, bits);1160 *res = zig_i8_truncate_i8(full_res, bits);
990 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);1161 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
991#else1162#else
992 int32_t full_res;1163 int32_t full_res;
993 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);1164 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
994 *res = (int8_t)full_res;1165 *res = zig_i8_intCast_i32(full_res);
995 return overflow;1166 return overflow;
996#endif1167#endif
997}1168}
...@@ -1000,12 +1171,12 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8...@@ -1000,12 +1171,12 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
1000#if zig_has_builtin(add_overflow) || defined(zig_gcc)1171#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1001 uint16_t full_res;1172 uint16_t full_res;
1002 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1173 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1003 *res = zig_wrap_u16(full_res, bits);1174 *res = zig_u16_truncate_u16(full_res, bits);
1004 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);1175 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
1005#else1176#else
1006 uint32_t full_res;1177 uint32_t full_res;
1007 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);1178 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
1008 *res = (uint16_t)full_res;1179 *res = zig_u16_intCast_u32(full_res);
1009 return overflow;1180 return overflow;
1010#endif1181#endif
1011}1182}
...@@ -1014,27 +1185,28 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t...@@ -1014,27 +1185,28 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
1014#if zig_has_builtin(add_overflow) || defined(zig_gcc)1185#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1015 int16_t full_res;1186 int16_t full_res;
1016 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1187 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1017 *res = zig_wrap_i16(full_res, bits);1188 *res = zig_i16_truncate_i16(full_res, bits);
1018 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);1189 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
1019#else1190#else
1020 int32_t full_res;1191 int32_t full_res;
1021 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);1192 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
1022 *res = (int16_t)full_res;1193 *res = zig_i16_intCast_i32(full_res);
1023 return overflow;1194 return overflow;
1024#endif1195#endif
1025}1196}
10261197
1027#if defined(zig_ez80)1198#if defined(zig_ez80)
1199
1028static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {1200static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1029#if zig_has_builtin(add_overflow) || defined(zig_gcc)1201#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1030 uint24_t full_res;1202 uint24_t full_res;
1031 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1203 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1032 *res = zig_wrap_u24(full_res, bits);1204 *res = zig_u24_truncate_u24(full_res, bits);
1033 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);1205 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1034#else1206#else
1035 uint32_t full_res;1207 uint32_t full_res;
1036 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);1208 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
1037 *res = (uint24_t)full_res;1209 *res = zig_u24_intCast_u32(full_res);
1038 return overflow;1210 return overflow;
1039#endif1211#endif
1040}1212}
...@@ -1043,28 +1215,26 @@ static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t...@@ -1043,28 +1215,26 @@ static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t
1043#if zig_has_builtin(add_overflow) || defined(zig_gcc)1215#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1044 int24_t full_res;1216 int24_t full_res;
1045 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1217 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1046 *res = zig_wrap_i24(full_res, bits);1218 *res = zig_i24_truncate_i24(full_res, bits);
1047 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);1219 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1048#else1220#else
1049 int32_t full_res;1221 int32_t full_res;
1050 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);1222 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
1051 *res = (int24_t)full_res;1223 *res = zig_i24_intCast_i32(full_res);
1052 return overflow;1224 return overflow;
1053#endif1225#endif
1054}1226}
1055#endif
10561227
1057#if defined(zig_ez80)
1058static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {1228static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1059#if zig_has_builtin(add_overflow) || defined(zig_gcc)1229#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1060 uint48_t full_res;1230 uint48_t full_res;
1061 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1231 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1062 *res = zig_wrap_u48(full_res, bits);1232 *res = zig_u48_truncate_u48(full_res, bits);
1063 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);1233 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1064#else1234#else
1065 uint64_t full_res;1235 uint64_t full_res;
1066 bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits);1236 bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits);
1067 *res = (uint48_t)full_res;1237 *res = zig_u48_intCast_u64(full_res);
1068 return overflow;1238 return overflow;
1069#endif1239#endif
1070}1240}
...@@ -1073,22 +1243,23 @@ static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1073,22 +1243,23 @@ static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1073#if zig_has_builtin(add_overflow) || defined(zig_gcc)1243#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1074 int48_t full_res;1244 int48_t full_res;
1075 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1245 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1076 *res = zig_wrap_i48(full_res, bits);1246 *res = zig_i48_truncate_i48(full_res, bits);
1077 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);1247 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1078#else1248#else
1079 int64_t full_res;1249 int64_t full_res;
1080 bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits);1250 bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits);
1081 *res = (int48_t)full_res;1251 *res = zig_i48_intCast_i64(full_res);
1082 return overflow;1252 return overflow;
1083#endif1253#endif
1084}1254}
1255
1085#endif1256#endif
10861257
1087static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {1258static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
1088#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1259#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1089 uint32_t full_res;1260 uint32_t full_res;
1090 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1261 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1091 *res = zig_wrap_u32(full_res, bits);1262 *res = zig_u32_truncate_u32(full_res, bits);
1092 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);1263 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
1093#else1264#else
1094 *res = zig_subw_u32(lhs, rhs, bits);1265 *res = zig_subw_u32(lhs, rhs, bits);
...@@ -1100,20 +1271,19 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t...@@ -1100,20 +1271,19 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
1100#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1271#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1101 int32_t full_res;1272 int32_t full_res;
1102 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1273 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1274 *res = zig_i32_truncate_i32(full_res, bits);
1275 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
1103#else1276#else
1104 int32_t full_res = (int32_t)((uint32_t)lhs - (uint32_t)rhs);1277 *res = zig_subw_i32(lhs, rhs, bits);
1105 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;1278 return ((lhs ^ rhs) & (*res ^ lhs)) < INT32_C(0);
1106#endif1279#endif
1107 *res = zig_wrap_i32(full_res, bits);
1108 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
1109}1280}
11101281
1111
1112static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {1282static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
1113#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1283#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1114 uint64_t full_res;1284 uint64_t full_res;
1115 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1285 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1116 *res = zig_wrap_u64(full_res, bits);1286 *res = zig_u64_truncate_u64(full_res, bits);
1117 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);1287 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
1118#else1288#else
1119 *res = zig_subw_u64(lhs, rhs, bits);1289 *res = zig_subw_u64(lhs, rhs, bits);
...@@ -1125,24 +1295,24 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t...@@ -1125,24 +1295,24 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
1125#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1295#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1126 int64_t full_res;1296 int64_t full_res;
1127 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1297 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1298 *res = zig_i64_truncate_i64(full_res, bits);
1299 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
1128#else1300#else
1129 int64_t full_res = (int64_t)((uint64_t)lhs - (uint64_t)rhs);1301 *res = zig_subw_i64(lhs, rhs, bits);
1130 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;1302 return ((lhs ^ rhs) & (*res ^ lhs)) < INT64_C(0);
1131#endif1303#endif
1132 *res = zig_wrap_i64(full_res, bits);
1133 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
1134}1304}
11351305
1136static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {1306static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
1137#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1307#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1138 uint8_t full_res;1308 uint8_t full_res;
1139 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1309 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1140 *res = zig_wrap_u8(full_res, bits);1310 *res = zig_u8_truncate_u8(full_res, bits);
1141 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);1311 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
1142#else1312#else
1143 uint32_t full_res;1313 uint32_t full_res;
1144 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);1314 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1145 *res = (uint8_t)full_res;1315 *res = zig_u8_intCast_u32(full_res);
1146 return overflow;1316 return overflow;
1147#endif1317#endif
1148}1318}
...@@ -1151,12 +1321,12 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits...@@ -1151,12 +1321,12 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
1151#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1321#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1152 int8_t full_res;1322 int8_t full_res;
1153 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1323 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1154 *res = zig_wrap_i8(full_res, bits);1324 *res = zig_i8_truncate_i8(full_res, bits);
1155 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);1325 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
1156#else1326#else
1157 int32_t full_res;1327 int32_t full_res;
1158 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);1328 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1159 *res = (int8_t)full_res;1329 *res = zig_i8_intCast_i32(full_res);
1160 return overflow;1330 return overflow;
1161#endif1331#endif
1162}1332}
...@@ -1165,12 +1335,12 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8...@@ -1165,12 +1335,12 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
1165#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1335#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1166 uint16_t full_res;1336 uint16_t full_res;
1167 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1337 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1168 *res = zig_wrap_u16(full_res, bits);1338 *res = zig_u16_truncate_u16(full_res, bits);
1169 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);1339 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
1170#else1340#else
1171 uint32_t full_res;1341 uint32_t full_res;
1172 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);1342 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1173 *res = (uint16_t)full_res;1343 *res = zig_u16_intCast_u32(full_res);
1174 return overflow;1344 return overflow;
1175#endif1345#endif
1176}1346}
...@@ -1179,27 +1349,28 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t...@@ -1179,27 +1349,28 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
1179#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1349#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1180 int16_t full_res;1350 int16_t full_res;
1181 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1351 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1182 *res = zig_wrap_i16(full_res, bits);1352 *res = zig_i16_truncate_i16(full_res, bits);
1183 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);1353 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
1184#else1354#else
1185 int32_t full_res;1355 int32_t full_res;
1186 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);1356 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1187 *res = (int16_t)full_res;1357 *res = zig_i16_intCast_i32(full_res);
1188 return overflow;1358 return overflow;
1189#endif1359#endif
1190}1360}
11911361
1192#if defined(zig_ez80)1362#if defined(zig_ez80)
1363
1193static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {1364static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1194#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1365#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1195 uint24_t full_res;1366 uint24_t full_res;
1196 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1367 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1197 *res = zig_wrap_u24(full_res, bits);1368 *res = zig_u24_truncate_u24(full_res, bits);
1198 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);1369 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1199#else1370#else
1200 uint32_t full_res;1371 uint32_t full_res;
1201 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);1372 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1202 *res = (uint24_t)full_res;1373 *res = zig_u24_intCast_u32(full_res);
1203 return overflow;1374 return overflow;
1204#endif1375#endif
1205}1376}
...@@ -1208,28 +1379,26 @@ static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t...@@ -1208,28 +1379,26 @@ static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t
1208#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1379#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1209 int24_t full_res;1380 int24_t full_res;
1210 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1381 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1211 *res = zig_wrap_i24(full_res, bits);1382 *res = zig_i24_truncate_i24(full_res, bits);
1212 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);1383 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1213#else1384#else
1214 int32_t full_res;1385 int32_t full_res;
1215 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);1386 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1216 *res = (int24_t)full_res;1387 *res = zig_i24_intCast_i32(full_res);
1217 return overflow;1388 return overflow;
1218#endif1389#endif
1219}1390}
1220#endif
12211391
1222#if defined(zig_ez80)
1223static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {1392static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1224#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1393#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1225 uint48_t full_res;1394 uint48_t full_res;
1226 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1395 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1227 *res = zig_wrap_u48(full_res, bits);1396 *res = zig_u48_truncate_u48(full_res, bits);
1228 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);1397 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1229#else1398#else
1230 uint64_t full_res;1399 uint64_t full_res;
1231 bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits);1400 bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits);
1232 *res = (uint48_t)full_res;1401 *res = zig_u48_intCast_u64(full_res);
1233 return overflow;1402 return overflow;
1234#endif1403#endif
1235}1404}
...@@ -1238,22 +1407,23 @@ static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1238,22 +1407,23 @@ static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1238#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1407#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1239 int48_t full_res;1408 int48_t full_res;
1240 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1409 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1241 *res = zig_wrap_i48(full_res, bits);1410 *res = zig_i48_truncate_i48(full_res, bits);
1242 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);1411 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1243#else1412#else
1244 int64_t full_res;1413 int64_t full_res;
1245 bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits);1414 bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits);
1246 *res = (int48_t)full_res;1415 *res = zig_i48_intCast_i64(full_res);
1247 return overflow;1416 return overflow;
1248#endif1417#endif
1249}1418}
1419
1250#endif1420#endif
12511421
1252static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {1422static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
1253#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1423#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1254 uint32_t full_res;1424 uint32_t full_res;
1255 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1425 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1256 *res = zig_wrap_u32(full_res, bits);1426 *res = zig_u32_truncate_u32(full_res, bits);
1257 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);1427 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
1258#else1428#else
1259 *res = zig_mulw_u32(lhs, rhs, bits);1429 *res = zig_mulw_u32(lhs, rhs, bits);
...@@ -1261,8 +1431,8 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8...@@ -1261,8 +1431,8 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8
1261#endif1431#endif
1262}1432}
12631433
1264zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow);
1265static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {1434static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {
1435 zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow);
1266#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1436#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1267 int32_t full_res;1437 int32_t full_res;
1268 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1438 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
...@@ -1271,7 +1441,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t...@@ -1271,7 +1441,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
1271 int32_t full_res = __mulosi4(lhs, rhs, &overflow_int);1441 int32_t full_res = __mulosi4(lhs, rhs, &overflow_int);
1272 bool overflow = overflow_int != 0;1442 bool overflow = overflow_int != 0;
1273#endif1443#endif
1274 *res = zig_wrap_i32(full_res, bits);1444 *res = zig_i32_truncate_i32(full_res, bits);
1275 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);1445 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
1276}1446}
12771447
...@@ -1279,7 +1449,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8...@@ -1279,7 +1449,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8
1279#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1449#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1280 uint64_t full_res;1450 uint64_t full_res;
1281 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1451 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1282 *res = zig_wrap_u64(full_res, bits);1452 *res = zig_u64_truncate_u64(full_res, bits);
1283 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);1453 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
1284#else1454#else
1285 *res = zig_mulw_u64(lhs, rhs, bits);1455 *res = zig_mulw_u64(lhs, rhs, bits);
...@@ -1287,8 +1457,8 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8...@@ -1287,8 +1457,8 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8
1287#endif1457#endif
1288}1458}
12891459
1290zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
1291static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {1460static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {
1461 zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
1292#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1462#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1293 int64_t full_res;1463 int64_t full_res;
1294 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1464 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
...@@ -1297,7 +1467,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t...@@ -1297,7 +1467,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
1297 int64_t full_res = __mulodi4(lhs, rhs, &overflow_int);1467 int64_t full_res = __mulodi4(lhs, rhs, &overflow_int);
1298 bool overflow = overflow_int != 0;1468 bool overflow = overflow_int != 0;
1299#endif1469#endif
1300 *res = zig_wrap_i64(full_res, bits);1470 *res = zig_i64_truncate_i64(full_res, bits);
1301 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);1471 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
1302}1472}
13031473
...@@ -1305,12 +1475,12 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b...@@ -1305,12 +1475,12 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b
1305#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1475#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1306 uint8_t full_res;1476 uint8_t full_res;
1307 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1477 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1308 *res = zig_wrap_u8(full_res, bits);1478 *res = zig_u8_truncate_u8(full_res, bits);
1309 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);1479 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
1310#else1480#else
1311 uint32_t full_res;1481 uint32_t full_res;
1312 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);1482 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1313 *res = (uint8_t)full_res;1483 *res = zig_u8_intCast_u32(full_res);
1314 return overflow;1484 return overflow;
1315#endif1485#endif
1316}1486}
...@@ -1319,12 +1489,12 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits...@@ -1319,12 +1489,12 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
1319#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1489#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1320 int8_t full_res;1490 int8_t full_res;
1321 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1491 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1322 *res = zig_wrap_i8(full_res, bits);1492 *res = zig_i8_truncate_i8(full_res, bits);
1323 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);1493 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
1324#else1494#else
1325 int32_t full_res;1495 int32_t full_res;
1326 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);1496 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1327 *res = (int8_t)full_res;1497 *res = zig_i8_intCast_i32(full_res);
1328 return overflow;1498 return overflow;
1329#endif1499#endif
1330}1500}
...@@ -1333,12 +1503,12 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8...@@ -1333,12 +1503,12 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
1333#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1503#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1334 uint16_t full_res;1504 uint16_t full_res;
1335 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1505 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1336 *res = zig_wrap_u16(full_res, bits);1506 *res = zig_u16_truncate_u16(full_res, bits);
1337 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);1507 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
1338#else1508#else
1339 uint32_t full_res;1509 uint32_t full_res;
1340 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);1510 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1341 *res = (uint16_t)full_res;1511 *res = zig_u16_intCast_u32(full_res);
1342 return overflow;1512 return overflow;
1343#endif1513#endif
1344}1514}
...@@ -1347,27 +1517,28 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t...@@ -1347,27 +1517,28 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
1347#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1517#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1348 int16_t full_res;1518 int16_t full_res;
1349 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1519 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1350 *res = zig_wrap_i16(full_res, bits);1520 *res = zig_i16_truncate_i16(full_res, bits);
1351 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);1521 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
1352#else1522#else
1353 int32_t full_res;1523 int32_t full_res;
1354 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);1524 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1355 *res = (int16_t)full_res;1525 *res = zig_i16_intCast_i32(full_res);
1356 return overflow;1526 return overflow;
1357#endif1527#endif
1358}1528}
13591529
1360#if defined(zig_ez80)1530#if defined(zig_ez80)
1531
1361static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {1532static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1362#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1533#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1363 uint24_t full_res;1534 uint24_t full_res;
1364 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1535 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1365 *res = zig_wrap_u24(full_res, bits);1536 *res = zig_u24_truncate_u24(full_res, bits);
1366 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);1537 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1367#else1538#else
1368 uint32_t full_res;1539 uint32_t full_res;
1369 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);1540 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1370 *res = (uint24_t)full_res;1541 *res = zig_u24_intCast_u32(full_res);
1371 return overflow;1542 return overflow;
1372#endif1543#endif
1373}1544}
...@@ -1376,28 +1547,26 @@ static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t...@@ -1376,28 +1547,26 @@ static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t
1376#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1547#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1377 int24_t full_res;1548 int24_t full_res;
1378 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1549 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1379 *res = zig_wrap_i24(full_res, bits);1550 *res = zig_i24_truncate_i24(full_res, bits);
1380 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);1551 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1381#else1552#else
1382 int32_t full_res;1553 int32_t full_res;
1383 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);1554 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1384 *res = (int24_t)full_res;1555 *res = zig_i24_intCast_i32(full_res);
1385 return overflow;1556 return overflow;
1386#endif1557#endif
1387}1558}
1388#endif
13891559
1390#if defined(zig_ez80)
1391static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {1560static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1392#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1561#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1393 uint48_t full_res;1562 uint48_t full_res;
1394 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1563 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1395 *res = zig_wrap_u48(full_res, bits);1564 *res = zig_u48_truncate_u48(full_res, bits);
1396 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);1565 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1397#else1566#else
1398 uint64_t full_res;1567 uint64_t full_res;
1399 bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits);1568 bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits);
1400 *res = (uint48_t)full_res;1569 *res = zig_u48_intCast_u64(full_res);
1401 return overflow;1570 return overflow;
1402#endif1571#endif
1403}1572}
...@@ -1406,18 +1575,32 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1406,18 +1575,32 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1406#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1575#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1407 int48_t full_res;1576 int48_t full_res;
1408 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1577 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1409 *res = zig_wrap_i48(full_res, bits);1578 *res = zig_i48_truncate_i48(full_res, bits);
1410 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);1579 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1411#else1580#else
1412 int64_t full_res;1581 int64_t full_res;
1413 bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits);1582 bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits);
1414 *res = (int48_t)full_res;1583 *res = zig_i48_intCast_i64(full_res);
1415 return overflow;1584 return overflow;
1416#endif1585#endif
1417}1586}
1587
1418#endif1588#endif
14191589
1420#define zig_int_builtins(w) \1590#define zig_shls_builtins(lw, rw) \
1591 static inline uint##lw##_t zig_shls_u##lw##_u##rw(uint##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \
1592 uint##lw##_t res; \
1593 if (rhs < bits && !zig_shlo_u##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
1594 return lhs == INT##lw##_C(0) ? zig_minInt_u(lw, bits) : zig_maxInt_u(lw, bits); \
1595 } \
1596\
1597 static inline int##lw##_t zig_shls_i##lw##_u##rw(int##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \
1598 int##lw##_t res; \
1599 if (rhs < bits && !zig_shlo_i##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
1600 return lhs == INT##lw##_C(0) ? INT##lw##_C(0) : \
1601 lhs < INT##lw##_C(0) ? zig_minInt_i(lw, bits) : zig_maxInt_i(lw, bits); \
1602 }
1603#define zig_int_sat_builtins(w) \
1421 static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \1604 static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
1422 *res = zig_shlw_u##w(lhs, rhs, bits); \1605 *res = zig_shlw_u##w(lhs, rhs, bits); \
1423 return lhs > zig_maxInt_u(w, bits) >> rhs; \1606 return lhs > zig_maxInt_u(w, bits) >> rhs; \
...@@ -1429,18 +1612,10 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1429,18 +1612,10 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1429 return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \1612 return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \
1430 } \1613 } \
1431\1614\
1432 static inline uint##w##_t zig_shls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1615 zig_shls_builtins(w, 8) \
1433 uint##w##_t res; \1616 zig_shls_builtins(w, 16) \
1434 if (rhs < bits && !zig_shlo_u##w(&res, lhs, rhs, bits)) return res; \1617 zig_shls_builtins(w, 32) \
1435 return lhs == INT##w##_C(0) ? INT##w##_C(0) : zig_maxInt_u(w, bits); \1618 zig_shls_builtins(w, 64) \
1436 } \
1437\
1438 static inline int##w##_t zig_shls_i##w(int##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1439 int##w##_t res; \
1440 if (rhs < bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \
1441 return lhs == INT##w##_C(0) ? INT##w##_C(0) : \
1442 lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1443 } \
1444\1619\
1445 static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1620 static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1446 uint##w##_t res; \1621 uint##w##_t res; \
...@@ -1474,332 +1649,321 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1474,332 +1649,321 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1474 if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \1649 if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \
1475 return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \1650 return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1476 }1651 }
1477zig_int_builtins(8)1652zig_int_sat_builtins(8)
1478zig_int_builtins(16)1653zig_int_sat_builtins(16)
1479#if defined(zig_ez80)1654zig_int_sat_builtins(32)
1480zig_int_builtins(24)1655zig_int_sat_builtins(64)
1481#endif
1482zig_int_builtins(32)
1483#if defined(zig_ez80)1656#if defined(zig_ez80)
1484zig_int_builtins(48)1657zig_int_sat_builtins(24)
1658zig_int_sat_builtins(48)
1485#endif1659#endif
1486zig_int_builtins(64)
14871660
1488#define zig_builtin8(name, val) __builtin_##name(val)1661#define zig_builtin8(name, arg) __builtin_##name(arg)
1489typedef unsigned int zig_Builtin8;1662typedef unsigned int zig_Builtin8;
14901663
1491#define zig_builtin16(name, val) __builtin_##name(val)1664#define zig_builtin16(name, arg) __builtin_##name(arg)
1492typedef unsigned int zig_Builtin16;1665typedef unsigned int zig_Builtin16;
14931666
1494#if defined(zig_ez80)
1495#define zig_builtin24(name, val) __builtin_##name(val)
1496typedef unsigned int zig_Builtin24;
1497#endif
1498
1499#if INT_MIN <= INT32_MIN1667#if INT_MIN <= INT32_MIN
1500#define zig_builtin32(name, val) __builtin_##name(val)1668#define zig_builtin32(name, arg) __builtin_##name(arg)
1501typedef unsigned int zig_Builtin32;1669typedef unsigned int zig_Builtin32;
1502#elif LONG_MIN <= INT32_MIN1670#elif LONG_MIN <= INT32_MIN
1503#define zig_builtin32(name, val) __builtin_##name##l(val)1671#define zig_builtin32(name, arg) __builtin_##name##l(arg)
1504typedef unsigned long zig_Builtin32;1672typedef unsigned long zig_Builtin32;
1505#endif1673#endif
15061674
1507#if defined(zig_ez80)
1508#define zig_builtin48(name, val) __builtin_##name(val)
1509typedef unsigned long long zig_Builtin48;
1510#endif
1511
1512#if INT_MIN <= INT64_MIN1675#if INT_MIN <= INT64_MIN
1513#define zig_builtin64(name, val) __builtin_##name(val)1676#define zig_builtin64(name, arg) __builtin_##name(arg)
1514typedef unsigned int zig_Builtin64;1677typedef unsigned int zig_Builtin64;
1515#elif LONG_MIN <= INT64_MIN1678#elif LONG_MIN <= INT64_MIN
1516#define zig_builtin64(name, val) __builtin_##name##l(val)1679#define zig_builtin64(name, arg) __builtin_##name##l(arg)
1517typedef unsigned long zig_Builtin64;1680typedef unsigned long zig_Builtin64;
1518#elif LLONG_MIN <= INT64_MIN1681#elif LLONG_MIN <= INT64_MIN
1519#define zig_builtin64(name, val) __builtin_##name##ll(val)1682#define zig_builtin64(name, arg) __builtin_##name##ll(arg)
1520typedef unsigned long long zig_Builtin64;1683typedef unsigned long long zig_Builtin64;
1521#endif1684#endif
15221685
1523static inline uint8_t zig_byte_swap_u8(uint8_t val, uint8_t bits) {1686#if defined(zig_ez80)
1524 return zig_wrap_u8(val >> (8 - bits), bits);1687#define zig_builtin24(name, arg) __builtin_##name(arg)
1688typedef unsigned int zig_Builtin24;
1689#define zig_builtin48(name, arg) __builtin_##name(arg)
1690typedef unsigned long long zig_Builtin48;
1691#endif
1692
1693static inline uint8_t zig_byteSwap_u8(uint8_t arg, uint8_t bits) {
1694 return zig_u8_truncate_u8(arg >> (8 - bits), bits);
1525}1695}
15261696
1527static inline int8_t zig_byte_swap_i8(int8_t val, uint8_t bits) {1697static inline int8_t zig_byteSwap_i8(int8_t arg, uint8_t bits) {
1528 return zig_wrap_i8((int8_t)zig_byte_swap_u8((uint8_t)val, bits), bits);1698 return zig_i8_truncate_i8((int8_t)zig_byteSwap_u8((uint8_t)arg, bits), bits);
1529}1699}
15301700
1531static inline uint16_t zig_byte_swap_u16(uint16_t val, uint8_t bits) {1701static inline uint16_t zig_byteSwap_u16(uint16_t arg, uint8_t bits) {
1532 uint16_t full_res;1702 uint16_t full_res;
1533#if zig_has_builtin(bswap16) || defined(zig_gcc)1703#if zig_has_builtin(bswap16) || defined(zig_gcc)
1534 full_res = __builtin_bswap16(val);1704 full_res = __builtin_bswap16(arg);
1535#else1705#else
1536 full_res = (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 8 |1706 full_res = (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 8 |
1537 (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 8), 8) >> 0;1707 (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 8), 8) >> 0;
1538#endif1708#endif
1539 return zig_wrap_u16(full_res >> (16 - bits), bits);1709 return zig_u16_truncate_u16(full_res >> (16 - bits), bits);
1540}1710}
15411711
1542static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) {1712static inline int16_t zig_byteSwap_i16(int16_t arg, uint8_t bits) {
1543 return zig_wrap_i16((int16_t)zig_byte_swap_u16((uint16_t)val, bits), bits);1713 return zig_i16_truncate_i16((int16_t)zig_byteSwap_u16((uint16_t)arg, bits), bits);
1544}1714}
15451715
1546#if defined(zig_ez80)1716#if defined(zig_ez80)
1547static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) {1717static inline uint16_t zig_byteSwap_u24(uint24_t arg, uint8_t bits) {
1548 uint24_t full_res;1718 uint24_t full_res;
1549#if zig_has_builtin(bswap24) || defined(zig_gcc)1719#if zig_has_builtin(bswap24) || defined(zig_gcc)
1550 full_res = __builtin_bswap24(val);1720 full_res = __builtin_bswap24(arg);
1551#else1721#else
1552 full_res = (uint24_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 16 |1722 full_res = (uint24_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 16 |
1553 (uint24_t)zig_byte_swap_u16((uint16_t)(val >> 8), 16) >> 0;1723 (uint24_t)zig_byteSwap_u16((uint16_t)(arg >> 8), 16) >> 0;
1554#endif1724#endif
1555 return zig_wrap_u24(full_res >> (24 - bits), bits);1725 return zig_u24_truncate_u24(full_res >> (24 - bits), bits);
1556}1726}
15571727
1558static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) {1728static inline int16_t zig_byteSwap_i24(int24_t arg, uint8_t bits) {
1559 return zig_wrap_i24((int24_t)zig_byte_swap_u24((uint24_t)val, bits), bits);1729 return zig_i24_truncate_i24((int24_t)zig_byteSwap_u24((uint24_t)arg, bits), bits);
1560}1730}
1561#endif1731#endif
15621732
1563static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) {1733static inline uint32_t zig_byteSwap_u32(uint32_t arg, uint8_t bits) {
1564 uint32_t full_res;1734 uint32_t full_res;
1565#if zig_has_builtin(bswap32) || defined(zig_gcc)1735#if zig_has_builtin(bswap32) || defined(zig_gcc)
1566 full_res = __builtin_bswap32(val);1736 full_res = __builtin_bswap32(arg);
1567#else1737#else
1568 full_res = (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 0), 16) << 16 |1738 full_res = (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 0), 16) << 16 |
1569 (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 16), 16) >> 0;1739 (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 16), 16) >> 0;
1570#endif1740#endif
1571 return zig_wrap_u32(full_res >> (32 - bits), bits);1741 return zig_u32_truncate_u32(full_res >> (32 - bits), bits);
1572}1742}
15731743
1574static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) {1744static inline int32_t zig_byteSwap_i32(int32_t arg, uint8_t bits) {
1575 return zig_wrap_i32((int32_t)zig_byte_swap_u32((uint32_t)val, bits), bits);1745 return zig_i32_truncate_i32((int32_t)zig_byteSwap_u32((uint32_t)arg, bits), bits);
1576}1746}
15771747
1578#if defined(zig_ez80)1748#if defined(zig_ez80)
1579static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) {1749static inline uint32_t zig_byteSwap_u48(uint48_t arg, uint8_t bits) {
1580 uint48_t full_res;1750 uint48_t full_res;
1581#if zig_has_builtin(bswap48) || defined(zig_gcc)1751#if zig_has_builtin(bswap48) || defined(zig_gcc)
1582 full_res = __builtin_bswap48(val);1752 full_res = __builtin_bswap48(arg);
1583#else1753#else
1584 full_res = (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 0), 24) << 24 |1754 full_res = (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 0), 24) << 24 |
1585 (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 24), 24) >> 0;1755 (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 24), 24) >> 0;
1586#endif1756#endif
1587 return zig_wrap_u48(full_res >> (48 - bits), bits);1757 return zig_u48_truncate_u48(full_res >> (48 - bits), bits);
1588}1758}
15891759
1590static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) {1760static inline int32_t zig_byteSwap_i48(int48_t arg, uint8_t bits) {
1591 return zig_wrap_i48((int48_t)zig_byte_swap_u48((uint48_t)val, bits), bits);1761 return zig_i48_truncate_i48((int48_t)zig_byteSwap_u48((uint48_t)arg, bits), bits);
1592}1762}
1593#endif1763#endif
15941764
1595static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) {1765static inline uint64_t zig_byteSwap_u64(uint64_t arg, uint8_t bits) {
1596 uint64_t full_res;1766 uint64_t full_res;
1597#if zig_has_builtin(bswap64) || defined(zig_gcc)1767#if zig_has_builtin(bswap64) || defined(zig_gcc)
1598 full_res = __builtin_bswap64(val);1768 full_res = __builtin_bswap64(arg);
1599#else1769#else
1600 full_res = (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 0), 32) << 32 |1770 full_res = (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 0), 32) << 32 |
1601 (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 32), 32) >> 0;1771 (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 32), 32) >> 0;
1602#endif1772#endif
1603 return zig_wrap_u64(full_res >> (64 - bits), bits);1773 return zig_u64_truncate_u64(full_res >> (64 - bits), bits);
1604}1774}
16051775
1606static inline int64_t zig_byte_swap_i64(int64_t val, uint8_t bits) {1776static inline int64_t zig_byteSwap_i64(int64_t arg, uint8_t bits) {
1607 return zig_wrap_i64((int64_t)zig_byte_swap_u64((uint64_t)val, bits), bits);1777 return zig_i64_truncate_i64((int64_t)zig_byteSwap_u64((uint64_t)arg, bits), bits);
1608}1778}
16091779
1610static inline uint8_t zig_bit_reverse_u8(uint8_t val, uint8_t bits) {1780static inline uint8_t zig_bitReverse_u8(uint8_t arg, uint8_t bits) {
1611 uint8_t full_res;1781 uint8_t full_res;
1612#if zig_has_builtin(bitreverse8)1782#if zig_has_builtin(bitreverse8)
1613 full_res = __builtin_bitreverse8(val);1783 full_res = __builtin_bitreverse8(arg);
1614#else1784#else
1615 static uint8_t const lut[0x10] = {1785 static uint8_t const lut[0x10] = {
1616 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,1786 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
1617 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf1787 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
1618 };1788 };
1619 full_res = lut[val >> 0 & 0xF] << 4 | lut[val >> 4 & 0xF] << 0;1789 full_res = lut[arg >> 0 & 0xF] << 4 | lut[arg >> 4 & 0xF] << 0;
1620#endif1790#endif
1621 return zig_wrap_u8(full_res >> (8 - bits), bits);1791 return zig_u8_truncate_u8(full_res >> (8 - bits), bits);
1622}1792}
16231793
1624static inline int8_t zig_bit_reverse_i8(int8_t val, uint8_t bits) {1794static inline int8_t zig_bitReverse_i8(int8_t arg, uint8_t bits) {
1625 return zig_wrap_i8((int8_t)zig_bit_reverse_u8((uint8_t)val, bits), bits);1795 return zig_i8_truncate_i8((int8_t)zig_bitReverse_u8((uint8_t)arg, bits), bits);
1626}1796}
16271797
1628static inline uint16_t zig_bit_reverse_u16(uint16_t val, uint8_t bits) {1798static inline uint16_t zig_bitReverse_u16(uint16_t arg, uint8_t bits) {
1629 uint16_t full_res;1799 uint16_t full_res;
1630#if zig_has_builtin(bitreverse16)1800#if zig_has_builtin(bitreverse16)
1631 full_res = __builtin_bitreverse16(val);1801 full_res = __builtin_bitreverse16(arg);
1632#else1802#else
1633 full_res = (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 8 |1803 full_res = (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 8 |
1634 (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 8), 8) >> 0;1804 (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 8), 8) >> 0;
1635#endif1805#endif
1636 return zig_wrap_u16(full_res >> (16 - bits), bits);1806 return zig_u16_truncate_u16(full_res >> (16 - bits), bits);
1637}1807}
16381808
1639static inline int16_t zig_bit_reverse_i16(int16_t val, uint8_t bits) {1809static inline int16_t zig_bitReverse_i16(int16_t arg, uint8_t bits) {
1640 return zig_wrap_i16((int16_t)zig_bit_reverse_u16((uint16_t)val, bits), bits);1810 return zig_i16_truncate_i16((int16_t)zig_bitReverse_u16((uint16_t)arg, bits), bits);
1641}1811}
16421812
1643#if defined(zig_ez80)1813#if defined(zig_ez80)
1644static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) {1814static inline uint24_t zig_bitReverse_u24(uint24_t arg, uint8_t bits) {
1645 uint24_t full_res;1815 uint24_t full_res;
1646#if zig_has_builtin(bitreverse24)1816#if zig_has_builtin(bitreverse24)
1647 full_res = __builtin_bitreverse24(val);1817 full_res = __builtin_bitreverse24(arg);
1648#else1818#else
1649 full_res = (uint24_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 16 |1819 full_res = (uint24_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 16 |
1650 (uint24_t)zig_bit_reverse_u16((uint16_t)(val >> 8), 16) >> 0;1820 (uint24_t)zig_bitReverse_u16((uint16_t)(arg >> 8), 16) >> 0;
1651#endif1821#endif
1652 return zig_wrap_u24(full_res >> (24 - bits), bits);1822 return zig_u24_truncate_u24(full_res >> (24 - bits), bits);
1653}1823}
16541824
1655static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) {1825static inline int24_t zig_bitReverse_i24(int24_t arg, uint8_t bits) {
1656 return zig_wrap_i24((int24_t)zig_bit_reverse_u24((uint24_t)val, bits), bits);1826 return zig_i24_truncate_i24((int24_t)zig_bitReverse_u24((uint24_t)arg, bits), bits);
1657}1827}
1658#endif1828#endif
16591829
1660static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) {1830static inline uint32_t zig_bitReverse_u32(uint32_t arg, uint8_t bits) {
1661 uint32_t full_res;1831 uint32_t full_res;
1662#if zig_has_builtin(bitreverse32)1832#if zig_has_builtin(bitreverse32)
1663 full_res = __builtin_bitreverse32(val);1833 full_res = __builtin_bitreverse32(arg);
1664#else1834#else
1665 full_res = (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 0), 16) << 16 |1835 full_res = (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 0), 16) << 16 |
1666 (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 16), 16) >> 0;1836 (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 16), 16) >> 0;
1667#endif1837#endif
1668 return zig_wrap_u32(full_res >> (32 - bits), bits);1838 return zig_u32_truncate_u32(full_res >> (32 - bits), bits);
1669}1839}
16701840
1671static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) {1841static inline int32_t zig_bitReverse_i32(int32_t arg, uint8_t bits) {
1672 return zig_wrap_i32((int32_t)zig_bit_reverse_u32((uint32_t)val, bits), bits);1842 return zig_i32_truncate_i32((int32_t)zig_bitReverse_u32((uint32_t)arg, bits), bits);
1673}1843}
16741844
1675#if defined(zig_ez80)1845#if defined(zig_ez80)
1676static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) {1846static inline uint32_t zig_bitReverse_u48(uint48_t arg, uint8_t bits) {
1677 uint48_t full_res;1847 uint48_t full_res;
1678#if zig_has_builtin(bitreverse48)1848#if zig_has_builtin(bitreverse48)
1679 full_res = __builtin_bitreverse48(val);1849 full_res = __builtin_bitreverse48(arg);
1680#else1850#else
1681 full_res = (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 0), 24) << 24 |1851 full_res = (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 0), 24) << 24 |
1682 (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 24), 24) >> 0;1852 (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 24), 24) >> 0;
1683#endif1853#endif
1684 return zig_wrap_u32(full_res >> (48 - bits), bits);1854 return zig_u48_truncate_u48(full_res >> (48 - bits), bits);
1685}1855}
16861856
1687static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) {1857static inline int32_t zig_bitReverse_i48(int48_t arg, uint8_t bits) {
1688 return zig_wrap_i48((int48_t)zig_bit_reverse_u48((uint48_t)val, bits), bits);1858 return zig_i48_truncate_i48((int48_t)zig_bitReverse_u48((uint48_t)arg, bits), bits);
1689}1859}
1690#endif1860#endif
16911861
1692static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) {1862static inline uint64_t zig_bitReverse_u64(uint64_t arg, uint8_t bits) {
1693 uint64_t full_res;1863 uint64_t full_res;
1694#if zig_has_builtin(bitreverse64)1864#if zig_has_builtin(bitreverse64)
1695 full_res = __builtin_bitreverse64(val);1865 full_res = __builtin_bitreverse64(arg);
1696#else1866#else
1697 full_res = (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 0), 32) << 32 |1867 full_res = (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 0), 32) << 32 |
1698 (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 32), 32) >> 0;1868 (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 32), 32) >> 0;
1699#endif1869#endif
1700 return zig_wrap_u64(full_res >> (64 - bits), bits);1870 return zig_u64_truncate_u64(full_res >> (64 - bits), bits);
1701}1871}
17021872
1703static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) {1873static inline int64_t zig_bitReverse_i64(int64_t arg, uint8_t bits) {
1704 return zig_wrap_i64((int64_t)zig_bit_reverse_u64((uint64_t)val, bits), bits);1874 return zig_i64_truncate_i64((int64_t)zig_bitReverse_u64((uint64_t)arg, bits), bits);
1705}1875}
17061876
1707#define zig_builtin_popcount_common(w) \1877#define zig_builtin_popCount_common(w) \
1708 static inline uint8_t zig_popcount_i##w(int##w##_t val, uint8_t bits) { \1878 static inline uint8_t zig_popCount_i##w(int##w##_t arg, uint8_t bits) { \
1709 return zig_popcount_u##w((uint##w##_t)val, bits); \1879 return zig_popCount_u##w((uint##w##_t)arg, bits); \
1710 }1880 }
1711#if zig_has_builtin(popcount) || defined(zig_gcc) || defined(zig_tinyc)1881#if zig_has_builtin(popCount) || defined(zig_gcc) || defined(zig_tinyc)
1712#define zig_builtin_popcount(w) \1882#define zig_builtin_popCount(w) \
1713 static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \1883 static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \
1714 (void)bits; \1884 (void)bits; \
1715 return zig_builtin##w(popcount, val); \1885 return zig_builtin##w(popcount, arg); \
1716 } \1886 } \
1717\1887\
1718 zig_builtin_popcount_common(w)1888 zig_builtin_popCount_common(w)
1719#else1889#else
1720#define zig_builtin_popcount(w) \1890#define zig_builtin_popCount(w) \
1721 static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \1891 static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \
1722 (void)bits; \1892 (void)bits; \
1723 uint##w##_t temp = val - ((val >> 1) & (UINT##w##_MAX / 3)); \1893 uint##w##_t temp = arg - ((arg >> 1) & (UINT##w##_MAX / 3)); \
1724 temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \1894 temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \
1725 temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \1895 temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \
1726 return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \1896 return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \
1727 } \1897 } \
1728\1898\
1729 zig_builtin_popcount_common(w)1899 zig_builtin_popCount_common(w)
1730#endif
1731zig_builtin_popcount(8)
1732zig_builtin_popcount(16)
1733#if defined(zig_ez80)
1734zig_builtin_popcount(24)
1735#endif1900#endif
1736zig_builtin_popcount(32)1901zig_builtin_popCount(8)
1902zig_builtin_popCount(16)
1903zig_builtin_popCount(32)
1904zig_builtin_popCount(64)
1737#if defined(zig_ez80)1905#if defined(zig_ez80)
1738zig_builtin_popcount(48)1906zig_builtin_popCount(24)
1907zig_builtin_popCount(48)
1739#endif1908#endif
1740zig_builtin_popcount(64)
17411909
1742#define zig_builtin_ctz_common(w) \1910#define zig_builtin_ctz_common(w) \
1743 static inline uint8_t zig_ctz_i##w(int##w##_t val, uint8_t bits) { \1911 static inline uint8_t zig_ctz_i##w(int##w##_t arg, uint8_t bits) { \
1744 return zig_ctz_u##w((uint##w##_t)val, bits); \1912 return zig_ctz_u##w((uint##w##_t)arg, bits); \
1745 }1913 }
1746#if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc)1914#if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc)
1747#define zig_builtin_ctz(w) \1915#define zig_builtin_ctz(w) \
1748 static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \1916 static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \
1749 if (val == 0) return bits; \1917 if (arg == 0) return bits; \
1750 return zig_builtin##w(ctz, val); \1918 return zig_builtin##w(ctz, arg); \
1751 } \1919 } \
1752\1920\
1753 zig_builtin_ctz_common(w)1921 zig_builtin_ctz_common(w)
1754#else1922#else
1755#define zig_builtin_ctz(w) \1923#define zig_builtin_ctz(w) \
1756 static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \1924 static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \
1757 return zig_popcount_u##w(zig_not_u##w(val, bits) & zig_subw_u##w(val, 1, bits), bits); \1925 return zig_popCount_u##w(zig_not_u##w(arg, bits) & zig_subw_u##w(arg, 1, bits), bits); \
1758 } \1926 } \
1759\1927\
1760 zig_builtin_ctz_common(w)1928 zig_builtin_ctz_common(w)
1761#endif1929#endif
1762zig_builtin_ctz(8)1930zig_builtin_ctz(8)
1763zig_builtin_ctz(16)1931zig_builtin_ctz(16)
1764#if defined(zig_ez80)
1765zig_builtin_ctz(24)
1766#endif
1767zig_builtin_ctz(32)1932zig_builtin_ctz(32)
1933zig_builtin_ctz(64)
1768#if defined(zig_ez80)1934#if defined(zig_ez80)
1935zig_builtin_ctz(24)
1769zig_builtin_ctz(48)1936zig_builtin_ctz(48)
1770#endif1937#endif
1771zig_builtin_ctz(64)
17721938
1773#define zig_builtin_clz_common(w) \1939#define zig_builtin_clz_common(w) \
1774 static inline uint8_t zig_clz_i##w(int##w##_t val, uint8_t bits) { \1940 static inline uint8_t zig_clz_i##w(int##w##_t arg, uint8_t bits) { \
1775 return zig_clz_u##w((uint##w##_t)val, bits); \1941 return zig_clz_u##w((uint##w##_t)arg, bits); \
1776 }1942 }
1777#if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc)1943#if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc)
1778#define zig_builtin_clz(w) \1944#define zig_builtin_clz(w) \
1779 static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \1945 static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \
1780 if (val == 0) return bits; \1946 if (arg == 0) return bits; \
1781 return zig_builtin##w(clz, val) - (zig_bitSizeOf(zig_Builtin##w) - bits); \1947 return zig_builtin##w(clz, arg) - (zig_bitSizeOf(zig_Builtin##w) - bits); \
1782 } \1948 } \
1783\1949\
1784 zig_builtin_clz_common(w)1950 zig_builtin_clz_common(w)
1785#else1951#else
1786#define zig_builtin_clz(w) \1952#define zig_builtin_clz(w) \
1787 static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \1953 static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \
1788 return zig_ctz_u##w(zig_bit_reverse_u##w(val, bits), bits); \1954 return zig_ctz_u##w(zig_bitReverse_u##w(arg, bits), bits); \
1789 } \1955 } \
1790\1956\
1791 zig_builtin_clz_common(w)1957 zig_builtin_clz_common(w)
1792#endif1958#endif
1793zig_builtin_clz(8)1959zig_builtin_clz(8)
1794zig_builtin_clz(16)1960zig_builtin_clz(16)
1795#if defined(zig_ez80)
1796zig_builtin_clz(24)
1797#endif
1798zig_builtin_clz(32)1961zig_builtin_clz(32)
1962zig_builtin_clz(64)
1799#if defined(zig_ez80)1963#if defined(zig_ez80)
1964zig_builtin_clz(24)
1800zig_builtin_clz(48)1965zig_builtin_clz(48)
1801#endif1966#endif
1802zig_builtin_clz(64)
18031967
1804/* ======================== 128-bit Integer Support ========================= */1968/* ======================== 128-bit Integer Support ========================= */
18051969
...@@ -1816,16 +1980,14 @@ zig_builtin_clz(64)...@@ -1816,16 +1980,14 @@ zig_builtin_clz(64)
1816typedef unsigned __int128 zig_u128;1980typedef unsigned __int128 zig_u128;
1817typedef signed __int128 zig_i128;1981typedef signed __int128 zig_i128;
18181982
1819#define zig_make_u128(hi, lo) ((zig_u128)(hi)<<64|(lo))1983#define zig_init_u128(hi, lo) ((zig_u128)(hi)<<64|(lo))
1820#define zig_make_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo))1984#define zig_init_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo))
1821#define zig_init_u128(hi, lo) zig_make_u128(hi, lo)1985#define zig_make_u128(hi, lo) zig_init_u128(hi, lo)
1822#define zig_init_i128(hi, lo) zig_make_i128(hi, lo)1986#define zig_make_i128(hi, lo) zig_init_i128(hi, lo)
1823#define zig_hi_u128(val) ((uint64_t)((val) >> 64))1987#define zig_hi_u128(arg) ((uint64_t)((arg) >> 64))
1824#define zig_lo_u128(val) ((uint64_t)((val) >> 0))1988#define zig_lo_u128(arg) ((uint64_t)((arg) >> 0))
1825#define zig_hi_i128(val) (( int64_t)((val) >> 64))1989#define zig_hi_i128(arg) (( int64_t)((arg) >> 64))
1826#define zig_lo_i128(val) ((uint64_t)((val) >> 0))1990#define zig_lo_i128(arg) ((uint64_t)((arg) >> 0))
1827#define zig_bitCast_u128(val) ((zig_u128)(val))
1828#define zig_bitCast_i128(val) ((zig_i128)(val))
1829#define zig_cmp_int128(Type) \1991#define zig_cmp_int128(Type) \
1830 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \1992 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
1831 return (lhs > rhs) - (lhs < rhs); \1993 return (lhs > rhs) - (lhs < rhs); \
...@@ -1835,32 +1997,49 @@ typedef signed __int128 zig_i128;...@@ -1835,32 +1997,49 @@ typedef signed __int128 zig_i128;
1835 return lhs operator rhs; \1997 return lhs operator rhs; \
1836 }1998 }
18371999
1838#else /* zig_has_int128 */2000static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
2001 return lhs << rhs;
2002}
18392003
1840#if zig_little_endian2004static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
1841typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128;2005 return lhs >> rhs;
1842typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128;2006}
2007
2008static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
2009 return lhs << rhs;
2010}
2011
2012static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
2013 // This works around a GCC miscompilation, but it has the side benefit of
2014 // emitting better code. It is behind the `#if` because it depends on
2015 // arithmetic right shift, which is implementation-defined in C, but should
2016 // be guaranteed on any GCC-compatible compiler.
2017#if defined(zig_gnuc)
2018 return lhs >> rhs;
1843#else2019#else
1844typedef struct { zig_align(16) uint64_t hi; uint64_t lo; } zig_u128;2020 zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);
1845typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;2021 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;
1846#endif2022#endif
2023}
18472024
1848#define zig_make_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) })2025#else /* zig_has_int128 */
1849#define zig_make_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) })
18502026
1851#if defined(zig_msvc) /* MSVC doesn't allow struct literals in constant expressions */2027#if zig_little_endian
1852#define zig_init_u128(hi, lo) { .h##i = (hi), .l##o = (lo) }2028typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; uint64_t hi; } zig_u128;
1853#define zig_init_i128(hi, lo) { .h##i = (hi), .l##o = (lo) }2029typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; int64_t hi; } zig_i128;
1854#else /* But non-MSVC doesn't like the unprotected commas */2030#else
1855#define zig_init_u128(hi, lo) zig_make_u128(hi, lo)2031typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t hi; uint64_t lo; } zig_u128;
1856#define zig_init_i128(hi, lo) zig_make_i128(hi, lo)2032typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) int64_t hi; uint64_t lo; } zig_i128;
1857#endif2033#endif
1858#define zig_hi_u128(val) ((val).hi)2034
1859#define zig_lo_u128(val) ((val).lo)2035#define zig_init_u128(hi, lo) { .h##i = hi, .l##o = lo }
1860#define zig_hi_i128(val) ((val).hi)2036#define zig_init_i128(hi, lo) { .h##i = hi, .l##o = lo }
1861#define zig_lo_i128(val) ((val).lo)2037#define zig_make_u128(hi, lo) (zig_u128)zig_init_u128(hi, lo)
1862#define zig_bitCast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo)2038#define zig_make_i128(hi, lo) (zig_i128)zig_init_i128(hi, lo)
1863#define zig_bitCast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo)2039#define zig_hi_u128(arg) (arg).hi
2040#define zig_lo_u128(arg) (arg).lo
2041#define zig_hi_i128(arg) (arg).hi
2042#define zig_lo_i128(arg) (arg).lo
1864#define zig_cmp_int128(Type) \2043#define zig_cmp_int128(Type) \
1865 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \2044 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
1866 return (lhs.hi == rhs.hi) \2045 return (lhs.hi == rhs.hi) \
...@@ -1872,6 +2051,30 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;...@@ -1872,6 +2051,30 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
1872 return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \2051 return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \
1873 }2052 }
18742053
2054static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
2055 if (rhs == UINT8_C(0)) return lhs;
2056 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
2057 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2058}
2059
2060static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
2061 if (rhs == UINT8_C(0)) return lhs;
2062 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) };
2063 return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs };
2064}
2065
2066static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
2067 if (rhs == UINT8_C(0)) return lhs;
2068 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
2069 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2070}
2071
2072static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
2073 if (rhs == UINT8_C(0)) return lhs;
2074 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) };
2075 return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) };
2076}
2077
1875#endif /* zig_has_int128 */2078#endif /* zig_has_int128 */
18762079
1877#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)2080#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)
...@@ -1891,42 +2094,177 @@ zig_bit_int128(i128, or, |)...@@ -1891,42 +2094,177 @@ zig_bit_int128(i128, or, |)
1891zig_bit_int128(u128, xor, ^)2094zig_bit_int128(u128, xor, ^)
1892zig_bit_int128(i128, xor, ^)2095zig_bit_int128(i128, xor, ^)
18932096
1894static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs);2097static inline uint8_t zig_u8_intCast_u128(zig_u128 arg) {
2098 return (uint8_t)zig_lo_u128(arg);
2099}
2100static inline uint8_t zig_u8_intCast_i128(zig_i128 arg) {
2101 return (uint8_t)zig_lo_i128(arg);
2102}
2103static inline int8_t zig_i8_intCast_i128(zig_i128 arg) {
2104 return (int8_t)zig_lo_i128(arg);
2105}
2106static inline int8_t zig_i8_intCast_u128(zig_u128 arg) {
2107 return (int8_t)zig_lo_u128(arg);
2108}
18952109
1896#if zig_has_int1282110static inline uint16_t zig_u16_intCast_u128(zig_u128 arg) {
2111 return (uint16_t)zig_lo_u128(arg);
2112}
2113static inline uint16_t zig_u16_intCast_i128(zig_i128 arg) {
2114 return (uint16_t)zig_lo_i128(arg);
2115}
2116static inline int16_t zig_i16_intCast_i128(zig_i128 arg) {
2117 return (int16_t)zig_lo_i128(arg);
2118}
2119static inline int16_t zig_i16_intCast_u128(zig_u128 arg) {
2120 return (int16_t)zig_lo_u128(arg);
2121}
18972122
1898static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) {2123static inline uint32_t zig_u32_intCast_u128(zig_u128 arg) {
1899 return val ^ zig_maxInt_u(128, bits);2124 return (uint32_t)zig_lo_u128(arg);
2125}
2126static inline uint32_t zig_u32_intCast_i128(zig_i128 arg) {
2127 return (uint32_t)zig_lo_i128(arg);
2128}
2129static inline int32_t zig_i32_intCast_i128(zig_i128 arg) {
2130 return (int32_t)zig_lo_i128(arg);
2131}
2132static inline int32_t zig_i32_intCast_u128(zig_u128 arg) {
2133 return (int32_t)zig_lo_u128(arg);
1900}2134}
19012135
1902static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) {2136static inline uint64_t zig_u64_intCast_u128(zig_u128 arg) {
1903 (void)bits;2137 return zig_lo_u128(arg);
1904 return ~val;2138}
2139static inline uint64_t zig_u64_intCast_i128(zig_i128 arg) {
2140 return zig_lo_i128(arg);
2141}
2142static inline int64_t zig_i64_intCast_i128(zig_i128 arg) {
2143 return (int64_t)zig_lo_i128(arg);
2144}
2145static inline int64_t zig_i64_intCast_u128(zig_u128 arg) {
2146 return (int64_t)zig_lo_u128(arg);
1905}2147}
19062148
1907static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {2149static inline zig_u128 zig_u128_intCast_u8(uint8_t arg) {
1908 return lhs >> rhs;2150 return zig_make_u128(UINT8_C(0), arg);
2151}
2152static inline zig_u128 zig_u128_intCast_i8(int8_t arg) {
2153 return zig_make_u128(UINT8_C(0), (uint8_t)arg);
2154}
2155static inline zig_i128 zig_i128_intCast_i8(int8_t arg) {
2156 return zig_make_i128(zig_shr_i64(arg, 63), (uint8_t)arg);
2157}
2158static inline zig_i128 zig_i128_intCast_u8(uint8_t arg) {
2159 return zig_make_i128(INT8_C(0), arg);
1909}2160}
19102161
1911static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {2162static inline zig_u128 zig_u128_intCast_u16(uint16_t arg) {
1912 return lhs << rhs;2163 return zig_make_u128(UINT16_C(0), arg);
2164}
2165static inline zig_u128 zig_u128_intCast_i16(int16_t arg) {
2166 return zig_make_u128(UINT16_C(0), (uint16_t)arg);
2167}
2168static inline zig_i128 zig_i128_intCast_i16(int16_t arg) {
2169 return zig_make_i128(zig_shr_i64(arg, 63), (uint16_t)arg);
2170}
2171static inline zig_i128 zig_i128_intCast_u16(uint16_t arg) {
2172 return zig_make_i128(INT16_C(0), arg);
1913}2173}
19142174
1915static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {2175static inline zig_u128 zig_u128_intCast_u32(uint32_t arg) {
1916 // This works around a GCC miscompilation, but it has the side benefit of2176 return zig_make_u128(UINT32_C(0), arg);
1917 // emitting better code. It is behind the `#if` because it depends on2177}
1918 // arithmetic right shift, which is implementation-defined in C, but should2178static inline zig_u128 zig_u128_intCast_i32(int32_t arg) {
1919 // be guaranteed on any GCC-compatible compiler.2179 return zig_make_u128(UINT32_C(0), (uint32_t)arg);
1920#if defined(zig_gnuc)2180}
1921 return lhs >> rhs;2181static inline zig_i128 zig_i128_intCast_i32(int32_t arg) {
2182 return zig_make_i128(zig_shr_i64(arg, 63), (uint32_t)arg);
2183}
2184static inline zig_i128 zig_i128_intCast_u32(uint32_t arg) {
2185 return zig_make_i128(INT32_C(0), arg);
2186}
2187
2188static inline zig_u128 zig_u128_intCast_u64(uint64_t arg) {
2189 return zig_make_u128(UINT64_C(0), arg);
2190}
2191static inline zig_u128 zig_u128_intCast_i64(int64_t arg) {
2192 return zig_make_u128(UINT64_C(0), (uint64_t)arg);
2193}
2194static inline zig_i128 zig_i128_intCast_i64(int64_t arg) {
2195 return zig_make_i128(zig_shr_i64(arg, 63), (uint64_t)arg);
2196}
2197static inline zig_i128 zig_i128_intCast_u64(uint64_t arg) {
2198 return zig_make_i128(INT64_C(0), arg);
2199}
2200
2201static inline zig_u128 zig_u128_intCast_u128(zig_u128 arg) {
2202 return arg;
2203}
2204static inline zig_u128 zig_u128_intCast_i128(zig_i128 arg) {
2205#if zig_has_int128
2206 return (zig_u128)arg;
1922#else2207#else
1923 zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);2208 return zig_make_u128(zig_u64_bitCast_i64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg));
1924 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;2209#endif
2210}
2211static inline zig_i128 zig_i128_intCast_i128(zig_i128 arg) {
2212 return arg;
2213}
2214static inline zig_i128 zig_i128_intCast_u128(zig_u128 arg) {
2215#if zig_has_int128
2216 return (zig_i128)arg;
2217#else
2218 return zig_make_i128(zig_i64_bitCast_u64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg));
1925#endif2219#endif
1926}2220}
19272221
1928static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {2222#define zig_int128_cast_builtins(w) \
1929 return lhs << rhs;2223 static inline uint##w##_t zig_u##w##_truncate_u128(zig_u128 arg, uint8_t bits) { \
2224 return zig_u##w##_truncate_u##w((uint##w##_t)zig_lo_u128(arg), bits); \
2225 } \
2226\
2227 static inline int##w##_t zig_i##w##_truncate_i128(zig_i128 arg, uint8_t bits) { \
2228 return zig_i##w##_truncate_i##w((int##w##_t)zig_lo_i128(arg), bits); \
2229 }
2230zig_int128_cast_builtins(8)
2231zig_int128_cast_builtins(16)
2232zig_int128_cast_builtins(32)
2233zig_int128_cast_builtins(64)
2234
2235static inline zig_u128 zig_u128_truncate_u128(zig_u128 arg, uint8_t bits) {
2236 return zig_and_u128(arg, zig_maxInt_u(128, bits));
2237}
2238static inline zig_i128 zig_i128_truncate_i128(zig_i128 arg, uint8_t bits) {
2239 if (bits > UINT8_C(64)) return zig_make_i128(zig_i64_truncate_i64(zig_hi_i128(arg), bits - UINT8_C(64)), zig_lo_i128(arg));
2240 int64_t lo = zig_i64_truncate_i128(arg, bits);
2241 return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo);
2242}
2243
2244static inline zig_u128 zig_u128_bitCast_u128(zig_u128 arg, uint8_t bits) {
2245 (void)bits;
2246 return arg;
2247}
2248static inline zig_u128 zig_u128_bitCast_i128(zig_i128 arg, uint8_t bits) {
2249 return zig_u128_truncate_u128(zig_u128_intCast_i128(arg), bits);
2250}
2251static inline zig_i128 zig_i128_bitCast_i128(zig_i128 arg, uint8_t bits) {
2252 (void)bits;
2253 return arg;
2254}
2255static inline zig_i128 zig_i128_bitCast_u128(zig_u128 arg, uint8_t bits) {
2256 return zig_i128_truncate_i128(zig_i128_intCast_u128(arg), bits);
2257}
2258
2259#if zig_has_int128
2260
2261static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) {
2262 return arg ^ zig_maxInt_u(128, bits);
2263}
2264
2265static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) {
2266 (void)bits;
2267 return ~arg;
1930}2268}
19312269
1932static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {2270static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
...@@ -1953,11 +2291,11 @@ static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -1953,11 +2291,11 @@ static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
1953 return lhs * rhs;2291 return lhs * rhs;
1954}2292}
19552293
1956static inline zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {2294static inline zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) {
1957 return lhs / rhs;2295 return lhs / rhs;
1958}2296}
19592297
1960static inline zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {2298static inline zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) {
1961 return lhs / rhs;2299 return lhs / rhs;
1962}2300}
19632301
...@@ -1971,36 +2309,14 @@ static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -1971,36 +2309,14 @@ static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
19712309
1972#else /* zig_has_int128 */2310#else /* zig_has_int128 */
19732311
1974static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) {2312static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) {
1975 return (zig_u128){ .hi = zig_not_u64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) };2313 if (bits <= UINT8_C(64)) return (zig_u128){ .hi = UINT64_C(0), .lo = zig_not_u64(arg.lo, bits) };
1976}2314 return (zig_u128){ .hi = zig_not_u64(arg.hi, bits - UINT8_C(64)), .lo = zig_not_u64(arg.lo, UINT8_C(64)) };
1977
1978static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) {
1979 return (zig_i128){ .hi = zig_not_i64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) };
1980}
1981
1982static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
1983 if (rhs == UINT8_C(0)) return lhs;
1984 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) };
1985 return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs };
1986}
1987
1988static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
1989 if (rhs == UINT8_C(0)) return lhs;
1990 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
1991 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
1992}
1993
1994static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
1995 if (rhs == UINT8_C(0)) return lhs;
1996 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) };
1997 return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) };
1998}2315}
19992316
2000static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {2317static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) {
2001 if (rhs == UINT8_C(0)) return lhs;2318 (void)bits;
2002 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };2319 return (zig_i128){ .hi = ~arg.hi, .lo = ~arg.lo };
2003 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2004}2320}
20052321
2006static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {2322static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
...@@ -2027,59 +2343,59 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -2027,59 +2343,59 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
2027 return res;2343 return res;
2028}2344}
20292345
2030zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
2031static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {2346static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
2347 zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
2032 return __multi3(lhs, rhs);2348 return __multi3(lhs, rhs);
2033}2349}
20342350
2035static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {2351static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
2036 return zig_bitCast_u128(zig_mul_i128(zig_bitCast_i128(lhs), zig_bitCast_i128(rhs)));2352 return zig_u128_bitCast_i128(zig_mul_i128(zig_i128_bitCast_u128(lhs, UINT8_C(128)), zig_i128_bitCast_u128(rhs, UINT8_C(128))), UINT8_C(128));
2037}2353}
20382354
2039zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);2355static zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) {
2040static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {2356 zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);
2041 return __udivti3(lhs, rhs);2357 return __udivti3(lhs, rhs);
2042}2358}
20432359
2044zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);2360static zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) {
2045static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {2361 zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);
2046 return __divti3(lhs, rhs);2362 return __divti3(lhs, rhs);
2047}2363}
20482364
2049zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
2050static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {2365static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {
2366 zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
2051 return __umodti3(lhs, rhs);2367 return __umodti3(lhs, rhs);
2052}2368}
20532369
2054zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs);
2055static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {2370static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
2371 zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs);
2056 return __modti3(lhs, rhs);2372 return __modti3(lhs, rhs);
2057}2373}
20582374
2059#endif /* zig_has_int128 */2375#endif /* zig_has_int128 */
20602376
2061#define zig_div_floor_u128 zig_div_trunc_u1282377#define zig_divFloor_u128 zig_divTrunc_u128
20622378
2063static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) {2379static inline zig_i128 zig_divFloor_i128(zig_i128 lhs, zig_i128 rhs) {
2064 zig_i128 rem = zig_rem_i128(lhs, rhs);2380 zig_i128 rem = zig_rem_i128(lhs, rhs);
2065 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)2381 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)
2066 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0);2382 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0);
2067 return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask));2383 return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask));
2068}2384}
20692385
2070static inline zig_u128 zig_div_ceil_u128(zig_u128 lhs, zig_u128 rhs) {2386static inline zig_u128 zig_divCeil_u128(zig_u128 lhs, zig_u128 rhs) {
2071 zig_u128 rem = zig_rem_u128(lhs, rhs);2387 zig_u128 rem = zig_rem_u128(lhs, rhs);
2072 uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0)2388 uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0)
2073 ? UINT64_C(1) : UINT64_C(0);2389 ? UINT64_C(1) : UINT64_C(0);
2074 return zig_add_u128(zig_div_trunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask));2390 return zig_add_u128(zig_divTrunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask));
2075}2391}
20762392
2077static inline zig_i128 zig_div_ceil_i128(zig_i128 lhs, zig_i128 rhs) {2393static inline zig_i128 zig_divCeil_i128(zig_i128 lhs, zig_i128 rhs) {
2078 zig_i128 rem = zig_rem_i128(lhs, rhs);2394 zig_i128 rem = zig_rem_i128(lhs, rhs);
2079 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)2395 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)
2080 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1)2396 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1)
2081 : INT64_C(0);2397 : INT64_C(0);
2082 return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask));2398 return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask));
2083}2399}
20842400
2085#define zig_mod_u128 zig_rem_u1282401#define zig_mod_u128 zig_rem_u128
...@@ -2107,51 +2423,41 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -2107,51 +2423,41 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) {
2107 return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs;2423 return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs;
2108}2424}
21092425
2110static inline zig_u128 zig_wrap_u128(zig_u128 val, uint8_t bits) {
2111 return zig_and_u128(val, zig_maxInt_u(128, bits));
2112}
2113
2114static inline zig_i128 zig_wrap_i128(zig_i128 val, uint8_t bits) {
2115 if (bits > UINT8_C(64)) return zig_make_i128(zig_wrap_i64(zig_hi_i128(val), bits - UINT8_C(64)), zig_lo_i128(val));
2116 int64_t lo = zig_wrap_i64((int64_t)zig_lo_i128(val), bits);
2117 return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo);
2118}
2119
2120static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {2426static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {
2121 return zig_wrap_u128(zig_shl_u128(lhs, rhs), bits);2427 return zig_u128_truncate_u128(zig_shl_u128(lhs, rhs), bits);
2122}2428}
21232429
2124static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) {2430static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) {
2125 return zig_wrap_i128(zig_bitCast_i128(zig_shl_u128(zig_bitCast_u128(lhs), rhs)), bits);2431 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_shl_u128(zig_u128_bitCast_i128(lhs, bits), rhs), bits), bits);
2126}2432}
21272433
2128static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2434static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2129 return zig_wrap_u128(zig_add_u128(lhs, rhs), bits);2435 return zig_u128_truncate_u128(zig_add_u128(lhs, rhs), bits);
2130}2436}
21312437
2132static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2438static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2133 return zig_wrap_i128(zig_bitCast_i128(zig_add_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);2439 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_add_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
2134}2440}
21352441
2136static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2442static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2137 return zig_wrap_u128(zig_sub_u128(lhs, rhs), bits);2443 return zig_u128_truncate_u128(zig_sub_u128(lhs, rhs), bits);
2138}2444}
21392445
2140static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2446static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2141 return zig_wrap_i128(zig_bitCast_i128(zig_sub_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);2447 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_sub_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
2142}2448}
21432449
2144static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2450static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2145 return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits);2451 return zig_u128_truncate_u128(zig_mul_u128(lhs, rhs), bits);
2146}2452}
21472453
2148static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2454static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2149 return zig_wrap_i128(zig_bitCast_i128(zig_mul_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);2455 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_mul_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
2150}2456}
21512457
2152static inline zig_u128 zig_abs_i128(zig_i128 val) {2458static inline zig_u128 zig_abs_i128(zig_i128 arg) {
2153 zig_i128 tmp = zig_shr_i128(val, 127);2459 zig_u128 tmp = zig_u128_bitCast_i128(zig_shr_i128(arg, 127), UINT8_C(128));
2154 return zig_bitCast_u128(zig_sub_i128(zig_xor_i128(val, tmp), tmp));2460 return zig_sub_u128(zig_xor_u128(zig_u128_bitCast_i128(arg, UINT8_C(128)), tmp), tmp);
2155}2461}
21562462
2157#if zig_has_int1282463#if zig_has_int128
...@@ -2160,7 +2466,7 @@ static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint...@@ -2160,7 +2466,7 @@ static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
2160#if zig_has_builtin(add_overflow)2466#if zig_has_builtin(add_overflow)
2161 zig_u128 full_res;2467 zig_u128 full_res;
2162 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);2468 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
2163 *res = zig_wrap_u128(full_res, bits);2469 *res = zig_u128_truncate_u128(full_res, bits);
2164 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);2470 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
2165#else2471#else
2166 *res = zig_addw_u128(lhs, rhs, bits);2472 *res = zig_addw_u128(lhs, rhs, bits);
...@@ -2176,7 +2482,7 @@ static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint...@@ -2176,7 +2482,7 @@ static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
2176 zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs);2482 zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs);
2177 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;2483 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;
2178#endif2484#endif
2179 *res = zig_wrap_i128(full_res, bits);2485 *res = zig_i128_truncate_i128(full_res, bits);
2180 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);2486 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
2181}2487}
21822488
...@@ -2184,7 +2490,7 @@ static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint...@@ -2184,7 +2490,7 @@ static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
2184#if zig_has_builtin(sub_overflow)2490#if zig_has_builtin(sub_overflow)
2185 zig_u128 full_res;2491 zig_u128 full_res;
2186 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);2492 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
2187 *res = zig_wrap_u128(full_res, bits);2493 *res = zig_u128_truncate_u128(full_res, bits);
2188 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);2494 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
2189#else2495#else
2190 *res = zig_subw_u128(lhs, rhs, bits);2496 *res = zig_subw_u128(lhs, rhs, bits);
...@@ -2200,7 +2506,7 @@ static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint...@@ -2200,7 +2506,7 @@ static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
2200 zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs);2506 zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs);
2201 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;2507 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;
2202#endif2508#endif
2203 *res = zig_wrap_i128(full_res, bits);2509 *res = zig_i128_truncate_i128(full_res, bits);
2204 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);2510 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
2205}2511}
22062512
...@@ -2208,7 +2514,7 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint...@@ -2208,7 +2514,7 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
2208#if zig_has_builtin(mul_overflow)2514#if zig_has_builtin(mul_overflow)
2209 zig_u128 full_res;2515 zig_u128 full_res;
2210 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);2516 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
2211 *res = zig_wrap_u128(full_res, bits);2517 *res = zig_u128_truncate_u128(full_res, bits);
2212 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);2518 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
2213#else2519#else
2214 *res = zig_mulw_u128(lhs, rhs, bits);2520 *res = zig_mulw_u128(lhs, rhs, bits);
...@@ -2216,8 +2522,8 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint...@@ -2216,8 +2522,8 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
2216#endif2522#endif
2217}2523}
22182524
2219zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2220static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2525static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2526 zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2221#if zig_has_builtin(mul_overflow)2527#if zig_has_builtin(mul_overflow)
2222 zig_i128 full_res;2528 zig_i128 full_res;
2223 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);2529 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
...@@ -2226,50 +2532,78 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint...@@ -2226,50 +2532,78 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
2226 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);2532 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
2227 bool overflow = overflow_int != 0;2533 bool overflow = overflow_int != 0;
2228#endif2534#endif
2229 *res = zig_wrap_i128(full_res, bits);2535 *res = zig_i128_truncate_i128(full_res, bits);
2230 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);2536 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
2231}2537}
22322538
2233#else /* zig_has_int128 */2539#else /* zig_has_int128 */
22342540
2235static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2541static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2236 uint64_t hi;2542 if (bits <= UINT8_C(64)) {
2237 bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - 64);2543 uint64_t lo;
2238 return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);2544 bool overflow = zig_addo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits);
2545 *res = zig_u128_intCast_u64(lo);
2546 return overflow;
2547 } else {
2548 uint64_t hi;
2549 bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2550 return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2551 }
2239}2552}
22402553
2241static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2554static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2242 int64_t hi;2555 if (bits <= UINT8_C(64)) {
2243 bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - 64);2556 int64_t lo;
2244 return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);2557 bool overflow = zig_addo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits);
2558 *res = zig_i128_intCast_i64(lo);
2559 return overflow;
2560 } else {
2561 int64_t hi;
2562 bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2563 return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2564 }
2245}2565}
22462566
2247static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2567static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2248 uint64_t hi;2568 if (bits <= UINT8_C(64)) {
2249 bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - 64);2569 uint64_t lo;
2250 return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);2570 bool overflow = zig_subo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits);
2571 *res = zig_u128_intCast_u64(lo);
2572 return overflow;
2573 } else {
2574 uint64_t hi;
2575 bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2576 return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2577 }
2251}2578}
22522579
2253static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2580static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2254 int64_t hi;2581 if (bits <= UINT8_C(64)) {
2255 bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - 64);2582 int64_t lo;
2256 return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);2583 bool overflow = zig_subo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits);
2584 *res = zig_i128_intCast_i64(lo);
2585 return overflow;
2586 } else {
2587 int64_t hi;
2588 bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2589 return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2590 }
2257}2591}
22582592
2259static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2593static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2260 *res = zig_mulw_u128(lhs, rhs, bits);2594 *res = zig_mulw_u128(lhs, rhs, bits);
2261 return zig_cmp_u128(*res, zig_make_u128(0, 0)) != INT32_C(0) &&2595 return zig_cmp_u128(rhs, zig_make_u128(0, 0)) != INT32_C(0) &&
2262 zig_cmp_u128(lhs, zig_div_trunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0);2596 zig_cmp_u128(lhs, zig_divTrunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0);
2263}2597}
22642598
2265zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2266static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2599static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2600 zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2267 int overflow_int;2601 int overflow_int;
2268 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);2602 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
2269 bool overflow = overflow_int != 0 ||2603 bool overflow = overflow_int != 0 ||
2270 zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) ||2604 zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) ||
2271 zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0);2605 zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0);
2272 *res = zig_wrap_i128(full_res, bits);2606 *res = zig_i128_truncate_i128(full_res, bits);
2273 return overflow;2607 return overflow;
2274}2608}
22752609
...@@ -2282,28 +2616,54 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8...@@ -2282,28 +2616,54 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8
22822616
2283static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {2617static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {
2284 *res = zig_shlw_i128(lhs, rhs, bits);2618 *res = zig_shlw_i128(lhs, rhs, bits);
2285 zig_i128 mask = zig_bitCast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)));2619 zig_i128 mask = zig_i128_bitCast_u128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)), bits);
2286 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&2620 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&
2287 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);2621 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);
2288}2622}
22892623
2290static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2624#define zig_int128_shls_builtins(rw) \
2625 static inline zig_u128 zig_shls_u128_u##rw(zig_u128 lhs, uint##rw##_t rhs, uint8_t bits) { \
2626 zig_u128 res; \
2627 if (rhs < bits && !zig_shlo_u128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
2628 switch (zig_cmp_u128(lhs, zig_make_u128(UINT64_C(0), UINT64_C(0)))) { \
2629 case 0: return zig_minInt_u(128, bits); \
2630 case 1: return zig_maxInt_u(128, bits); \
2631 default: zig_unreachable(); \
2632 } \
2633 } \
2634\
2635 static inline zig_i128 zig_shls_i128_u##rw(zig_i128 lhs, uint##rw##_t rhs, uint8_t bits) { \
2636 zig_i128 res; \
2637 if (rhs < bits && !zig_shlo_i128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
2638 switch (zig_cmp_i128(lhs, zig_make_i128(INT64_C(0), UINT64_C(0)))) { \
2639 case -1: return zig_minInt_i(128, bits); \
2640 case 0: return zig_make_i128(INT64_C(0), UINT64_C(0)); \
2641 case 1: return zig_maxInt_i(128, bits); \
2642 default: zig_unreachable(); \
2643 } \
2644 }
2645zig_int128_shls_builtins(8)
2646zig_int128_shls_builtins(16)
2647zig_int128_shls_builtins(32)
2648zig_int128_shls_builtins(64)
2649
2650static inline zig_u128 zig_shls_u128_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2291 zig_u128 res;2651 zig_u128 res;
2292 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;2652 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
2293 switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) {2653 switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) {
2294 case 0: return zig_make_u128(0, 0);2654 case INT32_C(0): return zig_make_u128(0, 0);
2295 case 1: return zig_maxInt_u(128, bits);2655 case INT32_C(1): return zig_maxInt_u(128, bits);
2296 default: zig_unreachable();2656 default: zig_unreachable();
2297 }2657 }
2298}2658}
22992659
2300static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) {2660static inline zig_i128 zig_shls_i128_u128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) {
2301 zig_i128 res;2661 zig_i128 res;
2302 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;2662 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
2303 switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) {2663 switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) {
2304 case -1: return zig_minInt_i(128, bits);2664 case -INT32_C(1): return zig_minInt_i(128, bits);
2305 case 0: return zig_make_i128(0, 0);2665 case INT32_C(0): return zig_make_i128(0, 0);
2306 case 1: return zig_maxInt_i(128, bits);2666 case INT32_C(1): return zig_maxInt_i(128, bits);
2307 default: zig_unreachable();2667 default: zig_unreachable();
2308 }2668 }
2309}2669}
...@@ -2341,57 +2701,60 @@ static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {...@@ -2341,57 +2701,60 @@ static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2341 return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);2701 return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
2342}2702}
23432703
2344static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) {2704static inline uint8_t zig_clz_u128(zig_u128 arg, uint8_t bits) {
2345 if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(val), bits);2705 if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(arg), bits);
2346 if (zig_hi_u128(val) != 0) return zig_clz_u64(zig_hi_u128(val), bits - UINT8_C(64));2706 if (zig_hi_u128(arg) != 0) return zig_clz_u64(zig_hi_u128(arg), bits - UINT8_C(64));
2347 return zig_clz_u64(zig_lo_u128(val), UINT8_C(64)) + (bits - UINT8_C(64));2707 return zig_clz_u64(zig_lo_u128(arg), UINT8_C(64)) + (bits - UINT8_C(64));
2348}2708}
23492709
2350static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) {2710static inline uint8_t zig_clz_i128(zig_i128 arg, uint8_t bits) {
2351 return zig_clz_u128(zig_bitCast_u128(val), bits);2711 return zig_clz_u128(zig_u128_bitCast_i128(arg, bits), bits);
2352}2712}
23532713
2354static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) {2714static inline uint8_t zig_ctz_u128(zig_u128 arg, uint8_t bits) {
2355 if (zig_lo_u128(val) != 0) return zig_ctz_u64(zig_lo_u128(val), UINT8_C(64));2715 if (zig_lo_u128(arg) != 0) return zig_ctz_u64(zig_lo_u128(arg), UINT8_C(64));
2356 return zig_ctz_u64(zig_hi_u128(val), bits - UINT8_C(64)) + UINT8_C(64);2716 return zig_ctz_u64(zig_hi_u128(arg), bits - UINT8_C(64)) + UINT8_C(64);
2357}2717}
23582718
2359static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) {2719static inline uint8_t zig_ctz_i128(zig_i128 arg, uint8_t bits) {
2360 return zig_ctz_u128(zig_bitCast_u128(val), bits);2720 return zig_ctz_u128(zig_u128_bitCast_i128(arg, bits), bits);
2361}2721}
23622722
2363static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) {2723static inline uint8_t zig_popCount_u128(zig_u128 arg, uint8_t bits) {
2364 return zig_popcount_u64(zig_hi_u128(val), bits - UINT8_C(64)) +2724 return (bits > UINT8_C(64) ? zig_popCount_u64(zig_hi_u128(arg), bits - UINT8_C(64)) : UINT8_C(0)) +
2365 zig_popcount_u64(zig_lo_u128(val), UINT8_C(64));2725 zig_popCount_u64(zig_lo_u128(arg), UINT8_C(64));
2366}2726}
23672727
2368static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) {2728static inline uint8_t zig_popCount_i128(zig_i128 arg, uint8_t bits) {
2369 return zig_popcount_u128(zig_bitCast_u128(val), bits);2729 return zig_popCount_u128(zig_u128_bitCast_i128(arg, bits), bits);
2370}2730}
23712731
2372static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) {2732static inline zig_u128 zig_byteSwap_u128(zig_u128 arg, uint8_t bits) {
2373 zig_u128 full_res;2733 zig_u128 full_res;
2374#if zig_has_builtin(bswap128)2734#if zig_has_builtin(bswap128)
2375 full_res = __builtin_bswap128(val);2735 full_res = __builtin_bswap128(arg);
2376#else2736#else
2377 full_res = zig_make_u128(zig_byte_swap_u64(zig_lo_u128(val), UINT8_C(64)),2737 full_res = zig_make_u128(
2378 zig_byte_swap_u64(zig_hi_u128(val), UINT8_C(64)));2738 zig_byteSwap_u64(zig_lo_u128(arg), UINT8_C(64)),
2739 zig_byteSwap_u64(zig_hi_u128(arg), UINT8_C(64))
2740 );
2379#endif2741#endif
2380 return zig_shr_u128(full_res, UINT8_C(128) - bits);2742 return zig_shr_u128(full_res, UINT8_C(128) - bits);
2381}2743}
23822744
2383static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) {2745static inline zig_i128 zig_byteSwap_i128(zig_i128 arg, uint8_t bits) {
2384 return zig_bitCast_i128(zig_byte_swap_u128(zig_bitCast_u128(val), bits));2746 return zig_i128_bitCast_u128(zig_byteSwap_u128(zig_u128_bitCast_i128(arg, bits), bits), bits);
2385}2747}
23862748
2387static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) {2749static inline zig_u128 zig_bitReverse_u128(zig_u128 arg, uint8_t bits) {
2388 return zig_shr_u128(zig_make_u128(zig_bit_reverse_u64(zig_lo_u128(val), UINT8_C(64)),2750 return zig_shr_u128(zig_make_u128(
2389 zig_bit_reverse_u64(zig_hi_u128(val), UINT8_C(64))),2751 zig_bitReverse_u64(zig_lo_u128(arg), UINT8_C(64)),
2390 UINT8_C(128) - bits);2752 zig_bitReverse_u64(zig_hi_u128(arg), UINT8_C(64))
2753 ), UINT8_C(128) - bits);
2391}2754}
23922755
2393static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {2756static inline zig_i128 zig_bitReverse_i128(zig_i128 arg, uint8_t bits) {
2394 return zig_bitCast_i128(zig_bit_reverse_u128(zig_bitCast_u128(val), bits));2757 return zig_i128_bitCast_u128(zig_bitReverse_u128(zig_u128_bitCast_i128(arg, bits), bits), bits);
2395}2758}
23962759
2397#if zig_has_int1282760#if zig_has_int128
...@@ -2411,15 +2774,218 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {...@@ -2411,15 +2774,218 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {
2411/* ========================== Big Integer Support =========================== */2774/* ========================== Big Integer Support =========================== */
24122775
2413static inline uint16_t zig_int_bytes(uint16_t bits) {2776static inline uint16_t zig_int_bytes(uint16_t bits) {
2414 uint16_t bytes = (bits + CHAR_BIT - 1) / CHAR_BIT;2777 uint16_t bytes = (bits - UINT16_C(1)) / CHAR_BIT + UINT16_C(1);
2415 uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT;2778 uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT;
2779
2416 while (alignment / 2 >= bytes) alignment /= 2;2780 while (alignment / 2 >= bytes) alignment /= 2;
2417 return (bytes + alignment - 1) / alignment * alignment;2781 return (bytes + alignment - 1) / alignment * alignment;
2418}2782}
24192783
2420static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {2784static inline void zig_minInt_big(void *res, bool is_signed, uint16_t bits) {
2785 uint8_t *res_bytes = res;
2786 uint16_t size = zig_int_bytes(bits);
2787 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2788 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2789 uint8_t sign_byte;
2790 uint8_t fill_byte;
2791
2792 if (is_signed) {
2793 int8_t signed_sign_byte = zig_minInt_i(8, remainder_bits);
2794
2795 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2796 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2797 } else {
2798 sign_byte = zig_minInt_u(8, remainder_bits);
2799 fill_byte = UINT8_C(0);
2800 }
2801
2802#if zig_little_endian
2803 memset(&res_bytes[0], zig_minInt_u8, byte_offset);
2804 res_bytes[byte_offset] = sign_byte;
2805 byte_offset += UINT16_C(1);
2806 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2807#else
2808 byte_offset = size - UINT16_C(1) - byte_offset;
2809 memset(&res_bytes[0], fill_byte, byte_offset);
2810 res_bytes[byte_offset] = sign_byte;
2811 byte_offset += UINT16_C(1);
2812 memset(&res_bytes[byte_offset], zig_minInt_u8, size - byte_offset);
2813#endif
2814}
2815
2816static inline void zig_maxInt_big(void *res, bool is_signed, uint16_t bits) {
2817 uint8_t *res_bytes = res;
2818 uint16_t size = zig_int_bytes(bits);
2819 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2820 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2821 uint8_t sign_byte;
2822 uint8_t fill_byte;
2823
2824 if (is_signed) {
2825 int8_t signed_sign_byte = zig_maxInt_i(8, remainder_bits);
2826
2827 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2828 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2829 } else {
2830 sign_byte = zig_maxInt_u(8, remainder_bits);
2831 fill_byte = UINT8_C(0);
2832 }
2833
2834#if zig_little_endian
2835 memset(&res_bytes[0], zig_maxInt_u8, byte_offset);
2836 res_bytes[byte_offset] = sign_byte;
2837 byte_offset += UINT16_C(1);
2838 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2839#else
2840 byte_offset = size - UINT16_C(1) - byte_offset;
2841 memset(&res_bytes[0], fill_byte, byte_offset);
2842 res_bytes[byte_offset] = sign_byte;
2843 byte_offset += UINT16_C(1);
2844 memset(&res_bytes[byte_offset], zig_maxInt_u8, size - byte_offset);
2845#endif
2846}
2847
2848static inline int8_t zig_signFill_big(const void *arg, bool is_signed, uint16_t bits) {
2849 const uint8_t *arg_bytes = arg;
2850 uint16_t byte_offset = 0;
2851
2852 if (!is_signed) return INT8_C(0);
2853#if zig_little_endian
2854 byte_offset = zig_int_bytes(bits) - 1;
2855#endif
2856 return zig_shr_i8(zig_i8_bitCast_u8(arg_bytes[byte_offset], UINT8_C(8)), UINT8_C(7));
2857}
2858
2859static inline void zig_big_intCast_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) {
2860 uint8_t *res_bytes = res;
2861 const uint8_t *arg_bytes = arg;
2862 uint16_t res_size = zig_int_bytes(res_bits);
2863 uint16_t arg_size = zig_int_bytes(arg_bits);
2864 uint16_t copy_size = zig_min_u16(res_size, arg_size);
2865 uint8_t sign_fill = zig_u8_bitCast_i8(zig_signFill_big(arg, arg_is_signed, arg_bits), UINT8_C(8));
2866
2867#if zig_little_endian
2868 memcpy(&res_bytes[0], &arg_bytes[0], copy_size);
2869 memset(&res_bytes[copy_size], sign_fill, res_size - copy_size);
2870#else
2871 memset(&res_bytes[0], sign_fill, res_size - copy_size);
2872 memcpy(&res_bytes[res_size - copy_size], &arg_bytes[arg_size - copy_size], copy_size);
2873#endif
2874}
2875
2876static inline void zig_big_truncate_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) {
2877 uint8_t *res_bytes = res;
2878 const uint8_t *arg_bytes = arg;
2879 uint16_t res_size = zig_int_bytes(res_bits);
2880
2881 if (res_is_signed != arg_is_signed) zig_unreachable();
2882 if (res_bits > arg_bits) zig_unreachable();
2883
2884 if (res_is_signed) {
2885 uint16_t arg_byte_offset = UINT16_C(0);
2886
2887#if zig_big_endian
2888 arg_byte_offset = zig_int_bytes(arg_bits) - res_size;
2889#endif
2890
2891 memcpy(&res_bytes[0], &arg_bytes[arg_byte_offset], res_size);
2892 } else {
2893 uint16_t res_byte_offset = zig_shr_u16(res_bits - UINT16_C(1), UINT8_C(3));
2894 uint16_t arg_byte_offset = res_byte_offset;
2895
2896#if zig_little_endian
2897 memcpy(&res_bytes[0], &arg_bytes[0], res_byte_offset);
2898#else
2899 res_byte_offset = res_size - UINT16_C(1) - res_byte_offset;
2900 arg_byte_offset = zig_int_bytes(arg_bits) - UINT16_C(1) - arg_byte_offset;
2901
2902 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
2903#endif
2904
2905 res_bytes[res_byte_offset] = zig_u8_truncate_u8(
2906 arg_bytes[arg_byte_offset],
2907 zig_u8_truncate_u8(res_bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1)
2908 );
2909 res_byte_offset += UINT16_C(1);
2910 arg_byte_offset += UINT16_C(1);
2911
2912#if zig_little_endian
2913 memset(&res_bytes[res_byte_offset], zig_minInt_u8, res_size - res_byte_offset);
2914#else
2915 memcpy(&res_bytes[res_byte_offset], &arg_bytes[arg_byte_offset], res_size - res_byte_offset);
2916#endif
2917 }
2918}
2919
2920#define zig_big_casts(is, s, w, IntType) \
2921 static inline IntType zig_##s##w##_intCast_big(const void *arg, bool arg_is_signed, uint16_t arg_bits) { \
2922 IntType res; \
2923 zig_big_intCast_big(&res, arg, is, w, arg_is_signed, arg_bits); \
2924 return res; \
2925 } \
2926\
2927 static inline void zig_big_intCast_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \
2928 zig_big_intCast_big(res, &arg, res_is_signed, res_bits, is, w); \
2929 } \
2930\
2931 static inline IntType zig_##s##w##_truncate_big(const void *arg, uint8_t res_bits, bool arg_is_signed, uint16_t arg_bits) { \
2932 IntType res; \
2933 zig_big_truncate_big(&res, arg, is, res_bits, arg_is_signed, arg_bits); \
2934 return res; \
2935 } \
2936\
2937 static inline void zig_big_truncate_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \
2938 zig_big_truncate_big(res, &arg, res_is_signed, res_bits, is, w); \
2939 }
2940zig_big_casts(false, u, 8, uint8_t)
2941zig_big_casts(true , i, 8, int8_t)
2942zig_big_casts(false, u, 16, uint16_t)
2943zig_big_casts(true , i, 16, int16_t)
2944zig_big_casts(false, u, 32, uint32_t)
2945zig_big_casts(true , i, 32, int32_t)
2946zig_big_casts(false, u, 64, uint64_t)
2947zig_big_casts(true , i, 64, int64_t)
2948zig_big_casts(false, u, 128, zig_u128)
2949zig_big_casts(true , i, 128, zig_i128)
2950
2951static inline void zig_big_bitCast_big(void *res, const void *arg, bool res_is_signed, uint16_t bits) {
2952 uint8_t *res_bytes = res;
2953 const uint8_t *arg_bytes = arg;
2954 uint16_t size = zig_int_bytes(bits);
2955 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2956 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2957 uint8_t sign_byte;
2958 uint8_t fill_byte;
2959
2960#if zig_big_endian
2961 byte_offset = size - UINT16_C(1) - byte_offset;
2962#endif
2963
2964 if (res_is_signed) {
2965 int8_t signed_sign_byte = zig_i8_bitCast_u8(arg_bytes[byte_offset], remainder_bits);
2966
2967 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2968 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2969 } else {
2970 sign_byte = zig_u8_bitCast_u8(arg_bytes[byte_offset], remainder_bits);
2971 fill_byte = UINT8_C(0);
2972 }
2973
2974#if zig_little_endian
2975 memcpy(&res_bytes[0], &arg_bytes[0], byte_offset);
2976 res_bytes[byte_offset] = sign_byte;
2977 byte_offset += UINT16_C(1);
2978 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2979#else
2980 memset(&res_bytes[0], fill_byte, byte_offset);
2981 res_bytes[byte_offset] = sign_byte;
2982 byte_offset += UINT16_C(1);
2983 memcpy(&res_bytes[byte_offset], &arg_bytes[byte_offset], size - byte_offset);
2984#endif
2985}
2986
2987static inline int32_t zig_cmp_big_u8(const void *lhs, uint8_t rhs, bool is_signed, uint16_t bits) {
2421 const uint8_t *lhs_bytes = lhs;2988 const uint8_t *lhs_bytes = lhs;
2422 const uint8_t *rhs_bytes = rhs;
2423 uint16_t byte_offset = 0;2989 uint16_t byte_offset = 0;
2424 bool do_signed = is_signed;2990 bool do_signed = is_signed;
2425 uint16_t remaining_bytes = zig_int_bytes(bits);2991 uint16_t remaining_bytes = zig_int_bytes(bits);
...@@ -2429,6 +2995,7 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2429,6 +2995,7 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2429#endif2995#endif
24302996
2431 while (remaining_bytes >= 128 / CHAR_BIT) {2997 while (remaining_bytes >= 128 / CHAR_BIT) {
2998 uint8_t rhs_byte = remaining_bytes == 128 / CHAR_BIT ? rhs : UINT8_C(0);
2432 int32_t limb_cmp;2999 int32_t limb_cmp;
24333000
2434#if zig_little_endian3001#if zig_little_endian
...@@ -2437,18 +3004,16 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2437,18 +3004,16 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
24373004
2438 if (do_signed) {3005 if (do_signed) {
2439 zig_i128 lhs_limb;3006 zig_i128 lhs_limb;
2440 zig_i128 rhs_limb;3007 zig_i128 rhs_limb = zig_i128_intCast_u8(rhs_byte);
24413008
2442 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3009 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2443 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2444 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);3010 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);
2445 do_signed = false;3011 do_signed = false;
2446 } else {3012 } else {
2447 zig_u128 lhs_limb;3013 zig_u128 lhs_limb;
2448 zig_u128 rhs_limb;3014 zig_u128 rhs_limb = zig_u128_intCast_u8(rhs_byte);
24493015
2450 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3016 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2451 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2452 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);3017 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);
2453 }3018 }
24543019
...@@ -2461,24 +3026,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2461,24 +3026,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2461 }3026 }
24623027
2463 while (remaining_bytes >= 64 / CHAR_BIT) {3028 while (remaining_bytes >= 64 / CHAR_BIT) {
3029 uint8_t rhs_byte = remaining_bytes == 64 / CHAR_BIT ? rhs : UINT8_C(0);
3030
2464#if zig_little_endian3031#if zig_little_endian
2465 byte_offset -= 64 / CHAR_BIT;3032 byte_offset -= 64 / CHAR_BIT;
2466#endif3033#endif
24673034
2468 if (do_signed) {3035 if (do_signed) {
2469 int64_t lhs_limb;3036 int64_t lhs_limb;
2470 int64_t rhs_limb;3037 int64_t rhs_limb = zig_i64_intCast_u8(rhs_byte);
24713038
2472 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3039 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2473 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2474 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3040 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2475 do_signed = false;3041 do_signed = false;
2476 } else {3042 } else {
2477 uint64_t lhs_limb;3043 uint64_t lhs_limb;
2478 uint64_t rhs_limb;3044 uint64_t rhs_limb = zig_u64_intCast_u8(rhs_byte);
24793045
2480 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3046 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2481 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2482 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3047 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2483 }3048 }
24843049
...@@ -2490,24 +3055,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2490,24 +3055,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2490 }3055 }
24913056
2492 while (remaining_bytes >= 32 / CHAR_BIT) {3057 while (remaining_bytes >= 32 / CHAR_BIT) {
3058 uint8_t rhs_byte = remaining_bytes == 32 / CHAR_BIT ? rhs : UINT8_C(0);
3059
2493#if zig_little_endian3060#if zig_little_endian
2494 byte_offset -= 32 / CHAR_BIT;3061 byte_offset -= 32 / CHAR_BIT;
2495#endif3062#endif
24963063
2497 if (do_signed) {3064 if (do_signed) {
2498 int32_t lhs_limb;3065 int32_t lhs_limb;
2499 int32_t rhs_limb;3066 int32_t rhs_limb = zig_i32_intCast_u8(rhs_byte);
25003067
2501 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3068 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2502 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2503 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3069 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2504 do_signed = false;3070 do_signed = false;
2505 } else {3071 } else {
2506 uint32_t lhs_limb;3072 uint32_t lhs_limb;
2507 uint32_t rhs_limb;3073 uint32_t rhs_limb = zig_u32_intCast_u8(rhs_byte);
25083074
2509 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3075 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2510 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2511 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3076 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2512 }3077 }
25133078
...@@ -2519,24 +3084,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2519,24 +3084,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2519 }3084 }
25203085
2521 while (remaining_bytes >= 16 / CHAR_BIT) {3086 while (remaining_bytes >= 16 / CHAR_BIT) {
3087 uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0);
3088
2522#if zig_little_endian3089#if zig_little_endian
2523 byte_offset -= 16 / CHAR_BIT;3090 byte_offset -= 16 / CHAR_BIT;
2524#endif3091#endif
25253092
2526 if (do_signed) {3093 if (do_signed) {
2527 int16_t lhs_limb;3094 int16_t lhs_limb;
2528 int16_t rhs_limb;3095 int16_t rhs_limb = zig_i16_intCast_u8(rhs_byte);
25293096
2530 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3097 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2531 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2532 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3098 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2533 do_signed = false;3099 do_signed = false;
2534 } else {3100 } else {
2535 uint16_t lhs_limb;3101 uint16_t lhs_limb;
2536 uint16_t rhs_limb;3102 uint16_t rhs_limb = zig_u16_intCast_u8(rhs_byte);
25373103
2538 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3104 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2539 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2540 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3105 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2541 }3106 }
25423107
...@@ -2548,24 +3113,26 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2548,24 +3113,26 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2548 }3113 }
25493114
2550 while (remaining_bytes >= 8 / CHAR_BIT) {3115 while (remaining_bytes >= 8 / CHAR_BIT) {
3116 uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0);
3117
2551#if zig_little_endian3118#if zig_little_endian
2552 byte_offset -= 8 / CHAR_BIT;3119 byte_offset -= 8 / CHAR_BIT;
2553#endif3120#endif
25543121
2555 if (do_signed) {3122 if (do_signed) {
2556 int8_t lhs_limb;3123 int8_t lhs_limb;
2557 int8_t rhs_limb;3124 int16_t lhs_cmp_limb;
3125 int16_t rhs_cmp_limb = zig_i16_intCast_u8(rhs_byte);
25583126
2559 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3127 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2560 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3128 lhs_cmp_limb = zig_i16_intCast_i8(lhs_limb);
2561 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3129 if (lhs_cmp_limb != rhs_cmp_limb) return (lhs_cmp_limb > rhs_cmp_limb) - (lhs_cmp_limb < rhs_cmp_limb);
2562 do_signed = false;3130 do_signed = false;
2563 } else {3131 } else {
2564 uint8_t lhs_limb;3132 uint8_t lhs_limb;
2565 uint8_t rhs_limb;3133 uint8_t rhs_limb = rhs_byte;
25663134
2567 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3135 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2568 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2569 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3136 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2570 }3137 }
25713138
...@@ -2579,148 +3146,472 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2579,148 +3146,472 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2579 return 0;3146 return 0;
2580}3147}
25813148
2582static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {3149static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2583 uint8_t *res_bytes = res;
2584 const uint8_t *lhs_bytes = lhs;3150 const uint8_t *lhs_bytes = lhs;
2585 const uint8_t *rhs_bytes = rhs;3151 const uint8_t *rhs_bytes = rhs;
2586 uint16_t byte_offset = 0;3152 uint16_t byte_offset = 0;
3153 bool do_signed = is_signed;
2587 uint16_t remaining_bytes = zig_int_bytes(bits);3154 uint16_t remaining_bytes = zig_int_bytes(bits);
2588 (void)is_signed;3155
3156#if zig_little_endian
3157 byte_offset = remaining_bytes;
3158#endif
25893159
2590 while (remaining_bytes >= 128 / CHAR_BIT) {3160 while (remaining_bytes >= 128 / CHAR_BIT) {
2591 zig_u128 res_limb;3161 int32_t limb_cmp;
2592 zig_u128 lhs_limb;
2593 zig_u128 rhs_limb;
25943162
2595 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3163#if zig_little_endian
2596 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3164 byte_offset -= 128 / CHAR_BIT;
2597 res_limb = zig_and_u128(lhs_limb, rhs_limb);3165#endif
2598 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3166
3167 if (do_signed) {
3168 zig_i128 lhs_limb;
3169 zig_i128 rhs_limb;
3170
3171 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3172 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3173 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);
3174 do_signed = false;
3175 } else {
3176 zig_u128 lhs_limb;
3177 zig_u128 rhs_limb;
3178
3179 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3180 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3181 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);
3182 }
25993183
3184 if (limb_cmp != 0) return limb_cmp;
2600 remaining_bytes -= 128 / CHAR_BIT;3185 remaining_bytes -= 128 / CHAR_BIT;
3186
3187#if zig_big_endian
2601 byte_offset += 128 / CHAR_BIT;3188 byte_offset += 128 / CHAR_BIT;
3189#endif
2602 }3190 }
26033191
2604 while (remaining_bytes >= 64 / CHAR_BIT) {3192 while (remaining_bytes >= 64 / CHAR_BIT) {
2605 uint64_t res_limb;3193#if zig_little_endian
2606 uint64_t lhs_limb;3194 byte_offset -= 64 / CHAR_BIT;
2607 uint64_t rhs_limb;3195#endif
26083196
2609 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3197 if (do_signed) {
2610 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3198 int64_t lhs_limb;
2611 res_limb = zig_and_u64(lhs_limb, rhs_limb);3199 int64_t rhs_limb;
2612 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3200
3201 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3202 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3203 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3204 do_signed = false;
3205 } else {
3206 uint64_t lhs_limb;
3207 uint64_t rhs_limb;
3208
3209 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3210 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3211 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3212 }
26133213
2614 remaining_bytes -= 64 / CHAR_BIT;3214 remaining_bytes -= 64 / CHAR_BIT;
3215
3216#if zig_big_endian
2615 byte_offset += 64 / CHAR_BIT;3217 byte_offset += 64 / CHAR_BIT;
3218#endif
2616 }3219 }
26173220
2618 while (remaining_bytes >= 32 / CHAR_BIT) {3221 while (remaining_bytes >= 32 / CHAR_BIT) {
2619 uint32_t res_limb;3222#if zig_little_endian
2620 uint32_t lhs_limb;3223 byte_offset -= 32 / CHAR_BIT;
2621 uint32_t rhs_limb;3224#endif
26223225
2623 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3226 if (do_signed) {
2624 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3227 int32_t lhs_limb;
2625 res_limb = zig_and_u32(lhs_limb, rhs_limb);3228 int32_t rhs_limb;
2626 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3229
3230 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3231 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3232 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3233 do_signed = false;
3234 } else {
3235 uint32_t lhs_limb;
3236 uint32_t rhs_limb;
3237
3238 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3239 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3240 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3241 }
26273242
2628 remaining_bytes -= 32 / CHAR_BIT;3243 remaining_bytes -= 32 / CHAR_BIT;
3244
3245#if zig_big_endian
2629 byte_offset += 32 / CHAR_BIT;3246 byte_offset += 32 / CHAR_BIT;
3247#endif
2630 }3248 }
26313249
2632 while (remaining_bytes >= 16 / CHAR_BIT) {3250 while (remaining_bytes >= 16 / CHAR_BIT) {
2633 uint16_t res_limb;3251#if zig_little_endian
2634 uint16_t lhs_limb;3252 byte_offset -= 16 / CHAR_BIT;
2635 uint16_t rhs_limb;3253#endif
26363254
2637 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3255 if (do_signed) {
2638 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3256 int16_t lhs_limb;
2639 res_limb = zig_and_u16(lhs_limb, rhs_limb);3257 int16_t rhs_limb;
2640 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3258
3259 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3260 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3261 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3262 do_signed = false;
3263 } else {
3264 uint16_t lhs_limb;
3265 uint16_t rhs_limb;
3266
3267 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3268 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3269 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3270 }
26413271
2642 remaining_bytes -= 16 / CHAR_BIT;3272 remaining_bytes -= 16 / CHAR_BIT;
3273
3274#if zig_big_endian
2643 byte_offset += 16 / CHAR_BIT;3275 byte_offset += 16 / CHAR_BIT;
3276#endif
2644 }3277 }
26453278
2646 while (remaining_bytes >= 8 / CHAR_BIT) {3279 while (remaining_bytes >= 8 / CHAR_BIT) {
2647 uint8_t res_limb;3280#if zig_little_endian
2648 uint8_t lhs_limb;3281 byte_offset -= 8 / CHAR_BIT;
2649 uint8_t rhs_limb;3282#endif
26503283
2651 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3284 if (do_signed) {
2652 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3285 int8_t lhs_limb;
2653 res_limb = zig_and_u8(lhs_limb, rhs_limb);3286 int8_t rhs_limb;
2654 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3287
3288 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3289 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3290 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3291 do_signed = false;
3292 } else {
3293 uint8_t lhs_limb;
3294 uint8_t rhs_limb;
3295
3296 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3297 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3298 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3299 }
26553300
2656 remaining_bytes -= 8 / CHAR_BIT;3301 remaining_bytes -= 8 / CHAR_BIT;
3302
3303#if zig_big_endian
2657 byte_offset += 8 / CHAR_BIT;3304 byte_offset += 8 / CHAR_BIT;
3305#endif
2658 }3306 }
3307
3308 return 0;
2659}3309}
26603310
2661static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {3311static inline void zig_not_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
2662 uint8_t *res_bytes = res;3312 uint8_t *res_bytes = res;
2663 const uint8_t *lhs_bytes = lhs;3313 const uint8_t *arg_bytes = arg;
2664 const uint8_t *rhs_bytes = rhs;
2665 uint16_t byte_offset = 0;3314 uint16_t byte_offset = 0;
2666 uint16_t remaining_bytes = zig_int_bytes(bits);3315 uint16_t remaining_bytes = zig_int_bytes(bits);
2667 (void)is_signed;3316 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3317
3318#if zig_big_endian
3319 byte_offset = remaining_bytes;
3320#endif
26683321
2669 while (remaining_bytes >= 128 / CHAR_BIT) {3322 while (remaining_bytes >= 128 / CHAR_BIT) {
2670 zig_u128 res_limb;3323 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
2671 zig_u128 lhs_limb;
2672 zig_u128 rhs_limb;
26733324
2674 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3325#if zig_big_endian
2675 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3326 byte_offset -= 128 / CHAR_BIT;
2676 res_limb = zig_or_u128(lhs_limb, rhs_limb);3327#endif
2677 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3328
3329 if (remaining_bytes != 128 / CHAR_BIT || is_signed) {
3330 zig_i128 res_limb;
3331 zig_i128 arg_limb;
3332
3333 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3334 res_limb = zig_not_i128(arg_limb, limb_bits);
3335 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3336 } else {
3337 zig_u128 res_limb;
3338 zig_u128 arg_limb;
3339
3340 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3341 res_limb = zig_not_u128(arg_limb, limb_bits);
3342 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3343 }
26783344
2679 remaining_bytes -= 128 / CHAR_BIT;3345 remaining_bytes -= 128 / CHAR_BIT;
3346
3347#if zig_little_endian
2680 byte_offset += 128 / CHAR_BIT;3348 byte_offset += 128 / CHAR_BIT;
3349#endif
2681 }3350 }
26823351
2683 while (remaining_bytes >= 64 / CHAR_BIT) {3352 while (remaining_bytes >= 64 / CHAR_BIT) {
2684 uint64_t res_limb;3353 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
2685 uint64_t lhs_limb;
2686 uint64_t rhs_limb;
26873354
2688 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3355#if zig_big_endian
2689 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3356 byte_offset -= 64 / CHAR_BIT;
2690 res_limb = zig_or_u64(lhs_limb, rhs_limb);3357#endif
2691 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3358
3359 if (remaining_bytes != 64 / CHAR_BIT || is_signed) {
3360 int64_t res_limb;
3361 int64_t arg_limb;
3362
3363 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3364 res_limb = zig_not_i64(arg_limb, limb_bits);
3365 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3366 } else {
3367 uint64_t res_limb;
3368 uint64_t arg_limb;
3369
3370 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3371 res_limb = zig_not_u64(arg_limb, limb_bits);
3372 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3373 }
26923374
2693 remaining_bytes -= 64 / CHAR_BIT;3375 remaining_bytes -= 64 / CHAR_BIT;
3376
3377#if zig_little_endian
2694 byte_offset += 64 / CHAR_BIT;3378 byte_offset += 64 / CHAR_BIT;
3379#endif
2695 }3380 }
26963381
2697 while (remaining_bytes >= 32 / CHAR_BIT) {3382 while (remaining_bytes >= 32 / CHAR_BIT) {
2698 uint32_t res_limb;3383 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
2699 uint32_t lhs_limb;
2700 uint32_t rhs_limb;
27013384
2702 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3385#if zig_big_endian
2703 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3386 byte_offset -= 32 / CHAR_BIT;
2704 res_limb = zig_or_u32(lhs_limb, rhs_limb);3387#endif
2705 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3388
3389 if (remaining_bytes != 32 / CHAR_BIT || is_signed) {
3390 int32_t res_limb;
3391 int32_t arg_limb;
3392
3393 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3394 res_limb = zig_not_i32(arg_limb, limb_bits);
3395 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3396 } else {
3397 uint32_t res_limb;
3398 uint32_t arg_limb;
3399
3400 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3401 res_limb = zig_not_u32(arg_limb, limb_bits);
3402 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3403 }
27063404
2707 remaining_bytes -= 32 / CHAR_BIT;3405 remaining_bytes -= 32 / CHAR_BIT;
3406
3407#if zig_little_endian
2708 byte_offset += 32 / CHAR_BIT;3408 byte_offset += 32 / CHAR_BIT;
3409#endif
2709 }3410 }
27103411
2711 while (remaining_bytes >= 16 / CHAR_BIT) {3412 while (remaining_bytes >= 16 / CHAR_BIT) {
2712 uint16_t res_limb;3413 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
2713 uint16_t lhs_limb;
2714 uint16_t rhs_limb;
27153414
2716 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3415#if zig_big_endian
2717 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3416 byte_offset -= 16 / CHAR_BIT;
2718 res_limb = zig_or_u16(lhs_limb, rhs_limb);3417#endif
2719 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
27203418
2721 remaining_bytes -= 16 / CHAR_BIT;3419 if (remaining_bytes != 16 / CHAR_BIT || is_signed) {
2722 byte_offset += 16 / CHAR_BIT;3420 int16_t res_limb;
2723 }3421 int16_t arg_limb;
3422
3423 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3424 res_limb = zig_not_i16(arg_limb, limb_bits);
3425 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3426 } else {
3427 uint16_t res_limb;
3428 uint16_t arg_limb;
3429
3430 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3431 res_limb = zig_not_u16(arg_limb, limb_bits);
3432 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3433 }
3434
3435 remaining_bytes -= 16 / CHAR_BIT;
3436
3437#if zig_little_endian
3438 byte_offset += 16 / CHAR_BIT;
3439#endif
3440 }
3441
3442 while (remaining_bytes >= 8 / CHAR_BIT) {
3443 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3444
3445#if zig_big_endian
3446 byte_offset -= 8 / CHAR_BIT;
3447#endif
3448
3449 if (remaining_bytes != 8 / CHAR_BIT || is_signed) {
3450 int8_t res_limb;
3451 int8_t arg_limb;
3452
3453 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3454 res_limb = zig_not_i8(arg_limb, limb_bits);
3455 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3456 } else {
3457 uint8_t res_limb;
3458 uint8_t arg_limb;
3459
3460 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3461 res_limb = zig_not_u8(arg_limb, limb_bits);
3462 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3463 }
3464
3465 remaining_bytes -= 8 / CHAR_BIT;
3466
3467#if zig_little_endian
3468 byte_offset += 8 / CHAR_BIT;
3469#endif
3470 }
3471}
3472
3473static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3474 uint8_t *res_bytes = res;
3475 const uint8_t *lhs_bytes = lhs;
3476 const uint8_t *rhs_bytes = rhs;
3477 uint16_t byte_offset = 0;
3478 uint16_t remaining_bytes = zig_int_bytes(bits);
3479 (void)is_signed;
3480
3481 while (remaining_bytes >= 128 / CHAR_BIT) {
3482 zig_u128 res_limb;
3483 zig_u128 lhs_limb;
3484 zig_u128 rhs_limb;
3485
3486 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3487 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3488 res_limb = zig_and_u128(lhs_limb, rhs_limb);
3489 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3490
3491 remaining_bytes -= 128 / CHAR_BIT;
3492 byte_offset += 128 / CHAR_BIT;
3493 }
3494
3495 while (remaining_bytes >= 64 / CHAR_BIT) {
3496 uint64_t res_limb;
3497 uint64_t lhs_limb;
3498 uint64_t rhs_limb;
3499
3500 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3501 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3502 res_limb = zig_and_u64(lhs_limb, rhs_limb);
3503 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3504
3505 remaining_bytes -= 64 / CHAR_BIT;
3506 byte_offset += 64 / CHAR_BIT;
3507 }
3508
3509 while (remaining_bytes >= 32 / CHAR_BIT) {
3510 uint32_t res_limb;
3511 uint32_t lhs_limb;
3512 uint32_t rhs_limb;
3513
3514 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3515 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3516 res_limb = zig_and_u32(lhs_limb, rhs_limb);
3517 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3518
3519 remaining_bytes -= 32 / CHAR_BIT;
3520 byte_offset += 32 / CHAR_BIT;
3521 }
3522
3523 while (remaining_bytes >= 16 / CHAR_BIT) {
3524 uint16_t res_limb;
3525 uint16_t lhs_limb;
3526 uint16_t rhs_limb;
3527
3528 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3529 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3530 res_limb = zig_and_u16(lhs_limb, rhs_limb);
3531 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3532
3533 remaining_bytes -= 16 / CHAR_BIT;
3534 byte_offset += 16 / CHAR_BIT;
3535 }
3536
3537 while (remaining_bytes >= 8 / CHAR_BIT) {
3538 uint8_t res_limb;
3539 uint8_t lhs_limb;
3540 uint8_t rhs_limb;
3541
3542 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3543 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3544 res_limb = zig_and_u8(lhs_limb, rhs_limb);
3545 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3546
3547 remaining_bytes -= 8 / CHAR_BIT;
3548 byte_offset += 8 / CHAR_BIT;
3549 }
3550}
3551
3552static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3553 uint8_t *res_bytes = res;
3554 const uint8_t *lhs_bytes = lhs;
3555 const uint8_t *rhs_bytes = rhs;
3556 uint16_t byte_offset = 0;
3557 uint16_t remaining_bytes = zig_int_bytes(bits);
3558 (void)is_signed;
3559
3560 while (remaining_bytes >= 128 / CHAR_BIT) {
3561 zig_u128 res_limb;
3562 zig_u128 lhs_limb;
3563 zig_u128 rhs_limb;
3564
3565 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3566 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3567 res_limb = zig_or_u128(lhs_limb, rhs_limb);
3568 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3569
3570 remaining_bytes -= 128 / CHAR_BIT;
3571 byte_offset += 128 / CHAR_BIT;
3572 }
3573
3574 while (remaining_bytes >= 64 / CHAR_BIT) {
3575 uint64_t res_limb;
3576 uint64_t lhs_limb;
3577 uint64_t rhs_limb;
3578
3579 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3580 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3581 res_limb = zig_or_u64(lhs_limb, rhs_limb);
3582 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3583
3584 remaining_bytes -= 64 / CHAR_BIT;
3585 byte_offset += 64 / CHAR_BIT;
3586 }
3587
3588 while (remaining_bytes >= 32 / CHAR_BIT) {
3589 uint32_t res_limb;
3590 uint32_t lhs_limb;
3591 uint32_t rhs_limb;
3592
3593 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3594 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3595 res_limb = zig_or_u32(lhs_limb, rhs_limb);
3596 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3597
3598 remaining_bytes -= 32 / CHAR_BIT;
3599 byte_offset += 32 / CHAR_BIT;
3600 }
3601
3602 while (remaining_bytes >= 16 / CHAR_BIT) {
3603 uint16_t res_limb;
3604 uint16_t lhs_limb;
3605 uint16_t rhs_limb;
3606
3607 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3608 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3609 res_limb = zig_or_u16(lhs_limb, rhs_limb);
3610 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3611
3612 remaining_bytes -= 16 / CHAR_BIT;
3613 byte_offset += 16 / CHAR_BIT;
3614 }
27243615
2725 while (remaining_bytes >= 8 / CHAR_BIT) {3616 while (remaining_bytes >= 8 / CHAR_BIT) {
2726 uint8_t res_limb;3617 uint8_t res_limb;
...@@ -2816,13 +3707,415 @@ static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool...@@ -2816,13 +3707,415 @@ static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool
2816 }3707 }
2817}3708}
28183709
3710static inline void zig_increment_big(void *res, bool is_signed, uint16_t bits) {
3711 uint8_t *res_bytes = res;
3712 uint16_t byte_offset = 0;
3713 uint16_t remaining_bytes = zig_int_bytes(bits);
3714 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3715
3716#if zig_big_endian
3717 byte_offset = remaining_bytes;
3718#endif
3719
3720 while (remaining_bytes >= 128 / CHAR_BIT) {
3721 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3722
3723#if zig_big_endian
3724 byte_offset -= 128 / CHAR_BIT;
3725#endif
3726
3727 {
3728 zig_u128 res_limb;
3729 bool limb_overflow;
3730
3731 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3732 limb_overflow = zig_addo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits);
3733 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3734 if (!limb_overflow) return;
3735 }
3736
3737 remaining_bytes -= 128 / CHAR_BIT;
3738
3739#if zig_little_endian
3740 byte_offset += 128 / CHAR_BIT;
3741#endif
3742 }
3743
3744 while (remaining_bytes >= 64 / CHAR_BIT) {
3745 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
3746
3747#if zig_big_endian
3748 byte_offset -= 64 / CHAR_BIT;
3749#endif
3750
3751 {
3752 uint64_t res_limb;
3753 bool limb_overflow;
3754
3755 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3756 limb_overflow = zig_addo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits);
3757 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3758 if (!limb_overflow) return;
3759 }
3760
3761 remaining_bytes -= 64 / CHAR_BIT;
3762
3763#if zig_little_endian
3764 byte_offset += 64 / CHAR_BIT;
3765#endif
3766 }
3767
3768 while (remaining_bytes >= 32 / CHAR_BIT) {
3769 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
3770
3771#if zig_big_endian
3772 byte_offset -= 32 / CHAR_BIT;
3773#endif
3774
3775 {
3776 uint32_t res_limb;
3777 bool limb_overflow;
3778
3779 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3780 limb_overflow = zig_addo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits);
3781 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3782 if (!limb_overflow) return;
3783 }
3784
3785 remaining_bytes -= 32 / CHAR_BIT;
3786
3787#if zig_little_endian
3788 byte_offset += 32 / CHAR_BIT;
3789#endif
3790 }
3791
3792 while (remaining_bytes >= 16 / CHAR_BIT) {
3793 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
3794
3795#if zig_big_endian
3796 byte_offset -= 16 / CHAR_BIT;
3797#endif
3798
3799 {
3800 uint16_t res_limb;
3801 bool limb_overflow;
3802
3803 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3804 limb_overflow = zig_addo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits);
3805 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3806 if (!limb_overflow) return;
3807 }
3808
3809 remaining_bytes -= 16 / CHAR_BIT;
3810
3811#if zig_little_endian
3812 byte_offset += 16 / CHAR_BIT;
3813#endif
3814 }
3815
3816 while (remaining_bytes >= 8 / CHAR_BIT) {
3817 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3818
3819#if zig_big_endian
3820 byte_offset -= 8 / CHAR_BIT;
3821#endif
3822
3823 {
3824 uint8_t res_limb;
3825 bool limb_overflow;
3826
3827 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3828 limb_overflow = zig_addo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits);
3829 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3830 if (!limb_overflow) return;
3831 }
3832
3833 remaining_bytes -= 8 / CHAR_BIT;
3834
3835#if zig_little_endian
3836 byte_offset += 8 / CHAR_BIT;
3837#endif
3838 }
3839}
3840
3841static inline void zig_decrement_big(void *res, bool is_signed, uint16_t bits) {
3842 uint8_t *res_bytes = res;
3843 uint16_t byte_offset = 0;
3844 uint16_t remaining_bytes = zig_int_bytes(bits);
3845 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3846
3847#if zig_big_endian
3848 byte_offset = remaining_bytes;
3849#endif
3850
3851 while (remaining_bytes >= 128 / CHAR_BIT) {
3852 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3853
3854#if zig_big_endian
3855 byte_offset -= 128 / CHAR_BIT;
3856#endif
3857
3858 {
3859 zig_u128 res_limb;
3860 bool limb_overflow;
3861
3862 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3863 limb_overflow = zig_subo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits);
3864 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3865 if (!limb_overflow) return;
3866 }
3867
3868 remaining_bytes -= 128 / CHAR_BIT;
3869
3870#if zig_little_endian
3871 byte_offset += 128 / CHAR_BIT;
3872#endif
3873 }
3874
3875 while (remaining_bytes >= 64 / CHAR_BIT) {
3876 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
3877
3878#if zig_big_endian
3879 byte_offset -= 64 / CHAR_BIT;
3880#endif
3881
3882 {
3883 uint64_t res_limb;
3884 bool limb_overflow;
3885
3886 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3887 limb_overflow = zig_subo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits);
3888 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3889 if (!limb_overflow) return;
3890 }
3891
3892 remaining_bytes -= 64 / CHAR_BIT;
3893
3894#if zig_little_endian
3895 byte_offset += 64 / CHAR_BIT;
3896#endif
3897 }
3898
3899 while (remaining_bytes >= 32 / CHAR_BIT) {
3900 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
3901
3902#if zig_big_endian
3903 byte_offset -= 32 / CHAR_BIT;
3904#endif
3905
3906 {
3907 uint32_t res_limb;
3908 bool limb_overflow;
3909
3910 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3911 limb_overflow = zig_subo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits);
3912 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3913 if (!limb_overflow) return;
3914 }
3915
3916 remaining_bytes -= 32 / CHAR_BIT;
3917
3918#if zig_little_endian
3919 byte_offset += 32 / CHAR_BIT;
3920#endif
3921 }
3922
3923 while (remaining_bytes >= 16 / CHAR_BIT) {
3924 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
3925
3926#if zig_big_endian
3927 byte_offset -= 16 / CHAR_BIT;
3928#endif
3929
3930 {
3931 uint16_t res_limb;
3932 bool limb_overflow;
3933
3934 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3935 limb_overflow = zig_subo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits);
3936 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3937 if (!limb_overflow) return;
3938 }
3939
3940 remaining_bytes -= 16 / CHAR_BIT;
3941
3942#if zig_little_endian
3943 byte_offset += 16 / CHAR_BIT;
3944#endif
3945 }
3946
3947 while (remaining_bytes >= 8 / CHAR_BIT) {
3948 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3949
3950#if zig_big_endian
3951 byte_offset -= 8 / CHAR_BIT;
3952#endif
3953
3954 {
3955 uint8_t res_limb;
3956 bool limb_overflow;
3957
3958 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3959 limb_overflow = zig_subo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits);
3960 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3961 if (!limb_overflow) return;
3962 }
3963
3964 remaining_bytes -= 8 / CHAR_BIT;
3965
3966#if zig_little_endian
3967 byte_offset += 8 / CHAR_BIT;
3968#endif
3969 }
3970}
3971
3972static inline void zig_abs_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
3973 uint8_t *res_bytes = res;
3974 const uint8_t *arg_bytes = arg;
3975 uint16_t byte_offset = 0;
3976 uint16_t remaining_bytes = zig_int_bytes(bits);
3977 if (zig_signFill_big(arg, is_signed, bits) >= INT8_C(0)) {
3978 memcpy(res, arg, remaining_bytes);
3979 return;
3980 }
3981 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3982 bool overflow = true;
3983
3984#if zig_big_endian
3985 byte_offset = remaining_bytes;
3986#endif
3987
3988 while (remaining_bytes >= 128 / CHAR_BIT) {
3989 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3990
3991#if zig_big_endian
3992 byte_offset -= 128 / CHAR_BIT;
3993#endif
3994
3995 {
3996 zig_u128 res_limb;
3997 zig_u128 arg_limb;
3998
3999 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4000 overflow = zig_addo_u128(&res_limb, zig_not_u128(arg_limb, UINT8_C(128)), zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits);
4001 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4002 }
4003
4004 remaining_bytes -= 128 / CHAR_BIT;
4005
4006#if zig_little_endian
4007 byte_offset += 128 / CHAR_BIT;
4008#endif
4009 }
4010
4011 while (remaining_bytes >= 64 / CHAR_BIT) {
4012 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
4013
4014#if zig_big_endian
4015 byte_offset -= 64 / CHAR_BIT;
4016#endif
4017
4018 {
4019 uint64_t res_limb;
4020 uint64_t arg_limb;
4021
4022 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4023 overflow = zig_addo_u64(&res_limb, zig_not_u64(arg_limb, UINT8_C(64)), overflow ? UINT64_C(1) : UINT64_C(0), limb_bits);
4024 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4025 }
4026
4027 remaining_bytes -= 64 / CHAR_BIT;
4028
4029#if zig_little_endian
4030 byte_offset += 64 / CHAR_BIT;
4031#endif
4032 }
4033
4034 while (remaining_bytes >= 32 / CHAR_BIT) {
4035 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
4036
4037#if zig_big_endian
4038 byte_offset -= 32 / CHAR_BIT;
4039#endif
4040
4041 {
4042 uint32_t res_limb;
4043 uint32_t arg_limb;
4044
4045 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4046 overflow = zig_addo_u32(&res_limb, zig_not_u32(arg_limb, UINT8_C(32)), overflow ? UINT32_C(1) : UINT32_C(0), limb_bits);
4047 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4048 }
4049
4050 remaining_bytes -= 32 / CHAR_BIT;
4051
4052#if zig_little_endian
4053 byte_offset += 32 / CHAR_BIT;
4054#endif
4055 }
4056
4057 while (remaining_bytes >= 16 / CHAR_BIT) {
4058 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
4059
4060#if zig_big_endian
4061 byte_offset -= 16 / CHAR_BIT;
4062#endif
4063
4064 {
4065 uint16_t res_limb;
4066 uint16_t arg_limb;
4067
4068 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4069 overflow = zig_addo_u16(&res_limb, zig_not_u16(arg_limb, UINT8_C(16)), overflow ? UINT16_C(1) : UINT16_C(0), limb_bits);
4070 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4071 }
4072
4073 remaining_bytes -= 16 / CHAR_BIT;
4074
4075#if zig_little_endian
4076 byte_offset += 16 / CHAR_BIT;
4077#endif
4078 }
4079
4080 while (remaining_bytes >= 8 / CHAR_BIT) {
4081 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
4082
4083#if zig_big_endian
4084 byte_offset -= 8 / CHAR_BIT;
4085#endif
4086
4087 {
4088 uint8_t res_limb;
4089 uint8_t arg_limb;
4090
4091 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4092 overflow = zig_addo_u8(&res_limb, zig_not_u8(arg_limb, UINT8_C(8)), overflow ? UINT8_C(1) : UINT8_C(0), limb_bits);
4093 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4094 }
4095
4096 remaining_bytes -= 8 / CHAR_BIT;
4097
4098#if zig_little_endian
4099 byte_offset += 8 / CHAR_BIT;
4100#endif
4101 }
4102}
4103
4104static inline void zig_min_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4105 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) < INT32_C(0) ? lhs : rhs, zig_int_bytes(bits));
4106}
4107
4108static inline void zig_max_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4109 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) >= INT32_C(0) ? lhs : rhs, zig_int_bytes(bits));
4110}
4111
2819static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {4112static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2820 uint8_t *res_bytes = res;4113 uint8_t *res_bytes = res;
2821 const uint8_t *lhs_bytes = lhs;4114 const uint8_t *lhs_bytes = lhs;
2822 const uint8_t *rhs_bytes = rhs;4115 const uint8_t *rhs_bytes = rhs;
2823 uint16_t byte_offset = 0;4116 uint16_t byte_offset = 0;
2824 uint16_t remaining_bytes = zig_int_bytes(bits);4117 uint16_t remaining_bytes = zig_int_bytes(bits);
2825 uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits);4118 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
2826 bool overflow = false;4119 bool overflow = false;
28274120
2828#if zig_big_endian4121#if zig_big_endian
...@@ -3038,7 +4331,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -3038,7 +4331,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
3038 const uint8_t *rhs_bytes = rhs;4331 const uint8_t *rhs_bytes = rhs;
3039 uint16_t byte_offset = 0;4332 uint16_t byte_offset = 0;
3040 uint16_t remaining_bytes = zig_int_bytes(bits);4333 uint16_t remaining_bytes = zig_int_bytes(bits);
3041 uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits);4334 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3042 bool overflow = false;4335 bool overflow = false;
30434336
3044#if zig_big_endian4337#if zig_big_endian
...@@ -3238,218 +4531,890 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -3238,218 +4531,890 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
3238 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));4531 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3239 }4532 }
32404533
3241 remaining_bytes -= 8 / CHAR_BIT;4534 remaining_bytes -= 8 / CHAR_BIT;
4535
4536#if zig_little_endian
4537 byte_offset += 8 / CHAR_BIT;
4538#endif
4539 }
4540
4541 return overflow;
4542}
4543
4544static inline void zig_add_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4545 if (zig_addo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4546}
4547
4548static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4549 (void)zig_addo_big(res, lhs, rhs, is_signed, bits);
4550}
4551
4552static inline void zig_adds_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4553 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits);
4554
4555 if (!zig_addo_big(res, lhs, rhs, is_signed, bits)) return;
4556 switch (sat_sign) {
4557 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4558 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4559 }
4560}
4561
4562static inline void zig_sub_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4563 if (zig_subo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4564}
4565
4566static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4567 (void)zig_subo_big(res, lhs, rhs, is_signed, bits);
4568}
4569
4570static inline void zig_subs_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4571 int8_t sat_sign = is_signed ? zig_signFill_big(lhs, is_signed, bits) : -INT8_C(1);
4572
4573 if (!zig_subo_big(res, lhs, rhs, is_signed, bits)) return;
4574 switch (sat_sign) {
4575 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4576 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4577 }
4578}
4579
4580static inline bool zig_mulo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4581 uint8_t *res_bytes = res;
4582 const uint8_t *lhs_bytes = lhs;
4583 const uint8_t *rhs_bytes = rhs;
4584 uint16_t size = zig_int_bytes(bits);
4585 uint16_t sign_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4586 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8));
4587 uint8_t rhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(rhs, is_signed, bits), UINT8_C(8));
4588 uint16_t lhs_byte_offset = sign_byte_offset;
4589 uint16_t lhs_end_byte_offset = UINT16_C(0);
4590 bool overflow = false;
4591
4592#if zig_big_endian
4593 lhs_byte_offset = size - lhs_byte_offset;
4594 lhs_end_byte_offset = size - lhs_end_byte_offset;
4595#endif
4596
4597 while (lhs_byte_offset != lhs_end_byte_offset) {
4598 uint16_t rhs_byte_offset = UINT16_C(0);
4599 uint16_t end_byte_offset = sign_byte_offset;
4600 uint16_t res_byte_offset;
4601 uint16_t lhs_byte;
4602 uint8_t res_byte = UINT8_C(0);
4603 uint16_t mul_res = UINT16_C(0);
4604 uint8_t carry = UINT8_C(0);
4605
4606#if zig_little_endian
4607 lhs_byte_offset -= UINT16_C(1);
4608#else
4609 rhs_byte_offset = size - rhs_byte_offset;
4610 end_byte_offset = size - end_byte_offset;
4611#endif
4612
4613 lhs_byte = zig_u16_intCast_u8(lhs_bytes[lhs_byte_offset]) ^ lhs_sign_fill;
4614
4615#if zig_big_endian
4616 lhs_byte_offset += UINT16_C(1);
4617#endif
4618
4619 res_byte_offset = lhs_byte_offset;
4620
4621 while (res_byte_offset != end_byte_offset) {
4622 bool res_byte_initialized = res_byte_offset != lhs_byte_offset;
4623
4624#if zig_big_endian
4625 rhs_byte_offset -= UINT16_C(1);
4626 res_byte_offset -= UINT16_C(1);
4627#endif
4628
4629 if (res_byte_initialized) res_byte = res_bytes[res_byte_offset];
4630 carry = zig_addo_u8(&res_byte, res_byte, carry, UINT8_C(8));
4631 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_intCast_u16(
4632 zig_shr_u16(mul_res, UINT8_C(8))
4633 ), UINT8_C(8));
4634 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill);
4635 carry += zig_addo_u8(&res_bytes[res_byte_offset], res_byte, zig_u8_truncate_u16(
4636 mul_res,
4637 UINT8_C(8)
4638 ), UINT8_C(8));
4639
4640#if zig_little_endian
4641 rhs_byte_offset += UINT16_C(1);
4642 res_byte_offset += UINT16_C(1);
4643#endif
4644 }
4645
4646 while (rhs_byte_offset != end_byte_offset) {
4647#if zig_big_endian
4648 rhs_byte_offset -= UINT16_C(1);
4649#endif
4650
4651 carry = zig_addo_u8(
4652 &res_byte,
4653 zig_u8_intCast_u16(zig_shr_u16(mul_res, UINT8_C(8))),
4654 carry,
4655 UINT8_C(8)
4656 );
4657 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill);
4658 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_truncate_u16(
4659 mul_res,
4660 UINT8_C(8)
4661 ), UINT8_C(8));
4662 overflow |= res_byte != UINT8_C(0);
4663
4664#if zig_little_endian
4665 rhs_byte_offset += UINT16_C(1);
4666#endif
4667 }
4668
4669 overflow |= zig_shr_u16(mul_res, UINT8_C(8)) != UINT16_C(0);
4670 overflow |= carry != UINT8_C(0);
4671 }
4672
4673#if zig_little_endian
4674 sign_byte_offset -= UINT64_C(1);
4675#else
4676 sign_byte_offset = size - sign_byte_offset;
4677#endif
4678
4679 if (lhs_sign_fill != rhs_sign_fill) {
4680 uint16_t byte_offset = UINT16_C(0);
4681 uint16_t end_byte_offset = sign_byte_offset;
4682 uint8_t res_byte;
4683 int8_t signed_res_byte;
4684 uint8_t carry = UINT8_C(0);
4685
4686#if zig_big_endian
4687 byte_offset = size - byte_offset;
4688 end_byte_offset += UINT16_C(1);
4689#endif
4690
4691 while (byte_offset != end_byte_offset) {
4692#if zig_big_endian
4693 byte_offset -= UINT16_C(1);
4694#endif
4695
4696 carry = zig_subo_u8(&res_byte, UINT8_C(0), carry, UINT8_C(8));
4697 carry += zig_subo_u8(&res_byte, res_byte, res_bytes[byte_offset], UINT8_C(8));
4698 carry += zig_subo_u8(
4699 &res_bytes[byte_offset],
4700 res_byte,
4701 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset],
4702 UINT8_C(8)
4703 );
4704
4705#if zig_little_endian
4706 byte_offset += UINT16_C(1);
4707#endif
4708 }
4709
4710#if zig_big_endian
4711 byte_offset -= UINT16_C(1);
4712#endif
4713
4714 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8));
4715 overflow |= signed_res_byte < INT8_C(0);
4716 overflow |= zig_subo_i8(&signed_res_byte, INT8_C(0), signed_res_byte, UINT8_C(8));
4717 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8));
4718 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4719 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset],
4720 UINT8_C(8)
4721 ), UINT8_C(8));
4722 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8));
4723 } else if (lhs_sign_fill != UINT8_C(0)) {
4724 uint16_t byte_offset = UINT16_C(0);
4725 uint16_t end_byte_offset = sign_byte_offset;
4726 uint8_t res_byte;
4727 int8_t signed_res_byte;
4728 uint8_t carry = UINT8_C(1);
4729
4730#if zig_big_endian
4731 byte_offset = size - byte_offset;
4732 end_byte_offset += UINT16_C(1);
4733#endif
4734
4735 while (byte_offset != end_byte_offset) {
4736#if zig_big_endian
4737 byte_offset -= UINT16_C(1);
4738#endif
4739
4740 carry = zig_subo_u8(&res_byte, res_bytes[byte_offset], carry, UINT8_C(8));
4741 carry += zig_subo_u8(&res_byte, res_byte, lhs_bytes[byte_offset], UINT8_C(8));
4742 carry += zig_subo_u8(&res_bytes[byte_offset], res_byte, rhs_bytes[byte_offset], UINT8_C(8));
4743
4744#if zig_little_endian
4745 byte_offset += UINT16_C(1);
4746#endif
4747 }
4748
4749#if zig_big_endian
4750 byte_offset -= UINT16_C(1);
4751#endif
4752
4753 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8));
4754 overflow |= signed_res_byte < INT8_C(0);
4755 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8));
4756 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4757 lhs_bytes[byte_offset],
4758 UINT8_C(8)
4759 ), UINT8_C(8));
4760 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4761 rhs_bytes[byte_offset],
4762 UINT8_C(8)
4763 ), UINT8_C(8));
4764 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8));
4765 } else if (is_signed) {
4766 int8_t signed_res_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8));
4767
4768 overflow |= signed_res_byte < INT8_C(0);
4769 }
4770
4771 {
4772 uint8_t truncate_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4773 uint8_t fill_byte = UINT8_C(0);
4774
4775 if (is_signed) {
4776 int8_t sign_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8));
4777 int8_t truncated = zig_i8_truncate_i8(sign_byte, truncate_bits);
4778
4779 overflow |= sign_byte != truncated;
4780 res_bytes[sign_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8));
4781 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8));
4782 } else {
4783 uint8_t sign_byte = res_bytes[sign_byte_offset];
4784 uint8_t truncated = zig_u8_truncate_u8(sign_byte, truncate_bits);
4785
4786 overflow |= sign_byte != truncated;
4787 res_bytes[sign_byte_offset] = truncated;
4788 }
4789
4790#if zig_little_endian
4791 sign_byte_offset += UINT16_C(1);
4792 memset(&res_bytes[sign_byte_offset], fill_byte, size - sign_byte_offset);
4793#else
4794 memset(&res_bytes[0], fill_byte, sign_byte_offset);
4795#endif
4796 }
4797
4798 return overflow;
4799}
4800
4801static inline void zig_mul_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4802 if (zig_mulo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4803}
4804
4805static inline void zig_mulw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4806 (void)zig_mulo_big(res, lhs, rhs, is_signed, bits);
4807}
4808
4809static inline void zig_muls_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4810 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits) ^ zig_signFill_big(rhs, is_signed, bits);
4811
4812 if (!zig_mulo_big(res, lhs, rhs, is_signed, bits)) return;
4813 switch (sat_sign) {
4814 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4815 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4816 }
4817}
4818
4819static inline void zig_divTrunc_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4820 if (is_signed) {
4821 zig_extern void __divei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4822 __divei5(res, lhs, rhs, temp, bits);
4823 } else {
4824 zig_extern void __udivei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4825 __udivei5(res, lhs, rhs, temp, bits);
4826 }
4827}
4828
4829static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4830 if (is_signed) {
4831 zig_extern void __modei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4832 __modei5(res, lhs, rhs, temp, bits);
4833 } else {
4834 zig_extern void __umodei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4835 __umodei5(res, lhs, rhs, temp, bits);
4836 }
4837}
4838
4839static inline void zig_divFloor_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4840 bool decrement = false;
4841
4842 if (is_signed) {
4843 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4844 decrement = zig_u32_bitCast_i32(zig_xor_i32(
4845 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4846 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4847 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32));
4848 }
4849 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits);
4850 if (decrement) zig_decrement_big(res, is_signed, bits);
4851}
4852
4853static inline void zig_divCeil_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4854 bool increment = false;
4855
4856 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4857 increment = zig_xor_i32(
4858 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4859 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4860 ) > INT32_C(0);
4861 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits);
4862 if (increment) zig_increment_big(res, is_signed, bits);
4863}
4864
4865static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4866 bool fixup = false;
4867
4868 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4869 if (is_signed && zig_u32_bitCast_i32(zig_xor_i32(
4870 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4871 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4872 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32))) zig_add_big(res, res, rhs, is_signed, bits);
4873}
4874
4875static inline void zig_shr_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
4876 uint8_t *res_bytes = res;
4877 const uint8_t *lhs_bytes = lhs;
4878 uint16_t size = zig_int_bytes(bits);
4879 uint16_t res_byte_offset = UINT16_C(0);
4880 uint16_t lhs_byte_offset = zig_shr_u16(rhs, UINT8_C(3));
4881 uint16_t end_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4882 uint8_t lhs_prev_byte;
4883 uint8_t byte_shift = zig_u8_truncate_u16(rhs, UINT8_C(3));
4884
4885#if zig_big_endian
4886 res_byte_offset = size - res_byte_offset;
4887 lhs_byte_offset = size - lhs_byte_offset;
4888 end_byte_offset = size - end_byte_offset;
4889#endif
4890
4891 {
4892#if zig_big_endian
4893 lhs_byte_offset -= UINT16_C(1);
4894#endif
4895
4896 lhs_prev_byte = lhs_bytes[lhs_byte_offset];
4897
4898#if zig_little_endian
4899 lhs_byte_offset += UINT16_C(1);
4900#endif
4901 }
4902
4903 while (lhs_byte_offset != end_byte_offset) {
4904#if zig_big_endian
4905 res_byte_offset -= UINT16_C(1);
4906 lhs_byte_offset -= UINT16_C(1);
4907#endif
4908
4909 {
4910 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset];
4911
4912 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
4913 zig_shl_u16(zig_u16_intCast_u8(lhs_byte), UINT8_C(8)),
4914 zig_u16_intCast_u8(lhs_prev_byte)
4915 ), byte_shift));
4916 lhs_prev_byte = lhs_byte;
4917 }
4918
4919#if zig_little_endian
4920 res_byte_offset += UINT16_C(1);
4921 lhs_byte_offset += UINT16_C(1);
4922#endif
4923 }
4924
4925 {
4926 uint8_t lhs_sign_fill = UINT8_C(0);
4927
4928#if zig_big_endian
4929 res_byte_offset -= UINT16_C(1);
4930#endif
4931
4932 if (is_signed) {
4933 int8_t signed_byte = zig_i8_bitCast_u8(lhs_prev_byte, UINT8_C(8));
4934
4935 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift);
4936 lhs_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8));
4937 } else {
4938 res_bytes[res_byte_offset] = zig_shr_u8(lhs_prev_byte, byte_shift);
4939 }
4940
4941#if zig_little_endian
4942 res_byte_offset += UINT16_C(1);
4943 memset(&res_bytes[res_byte_offset], lhs_sign_fill, size - res_byte_offset);
4944#else
4945 memset(&res_bytes[0], lhs_sign_fill, res_byte_offset);
4946#endif
4947 }
4948}
4949
4950static inline bool zig_shlo_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
4951 uint8_t *res_bytes = res;
4952 const uint8_t *lhs_bytes = lhs;
4953 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8));
4954 uint16_t size = zig_int_bytes(bits);
4955 uint16_t res_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4956 uint16_t lhs_byte_offset = UINT16_C(0);
4957 uint16_t end_byte_offset = res_byte_offset - UINT16_C(1) - zig_shr_u16(rhs, UINT8_C(3));
4958 uint8_t lhs_prev_byte = lhs_sign_fill;
4959 uint8_t byte_shift = UINT8_C(8) - zig_u8_truncate_u16(rhs, UINT8_C(3));
4960 bool overflow = false;
4961
4962#if zig_little_endian
4963 lhs_byte_offset = size - lhs_byte_offset;
4964#else
4965 res_byte_offset = size - res_byte_offset;
4966 end_byte_offset = size - end_byte_offset;
4967#endif
4968
4969 while (lhs_byte_offset != end_byte_offset) {
4970#if zig_little_endian
4971 lhs_byte_offset -= UINT16_C(1);
4972#endif
4973
4974 overflow |= lhs_prev_byte != lhs_sign_fill;
4975 lhs_prev_byte = lhs_bytes[lhs_byte_offset];
4976
4977#if zig_big_endian
4978 lhs_byte_offset += UINT16_C(1);
4979#endif
4980 }
4981
4982#if zig_little_endian
4983 end_byte_offset = UINT16_C(0);
4984#else
4985 end_byte_offset = size;
4986#endif
4987
4988 {
4989 bool lhs_more_bytes = lhs_byte_offset != end_byte_offset;
4990
4991#if zig_little_endian
4992 if (lhs_more_bytes) lhs_byte_offset -= UINT16_C(1);
4993#endif
4994
4995 {
4996 uint8_t lhs_byte = UINT8_C(0);
4997
4998 if (lhs_more_bytes) lhs_byte = lhs_bytes[lhs_byte_offset];
4999
5000 if (is_signed) {
5001 int16_t shifted = zig_shr_i16(zig_or_i16(
5002 zig_shl_i16(zig_i16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5003 zig_i16_intCast_u8(lhs_byte)
5004 ), byte_shift);
5005 int8_t truncated = zig_i8_truncate_i16(
5006 shifted,
5007 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1)
5008 );
5009 uint8_t fill = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8));
5010
5011 overflow |= zig_i16_intCast_i8(truncated) != shifted;
5012#if zig_little_endian
5013 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset);
5014 res_byte_offset -= UINT16_C(1);
5015#else
5016 memset(&res_bytes[0], fill, res_byte_offset);
5017#endif
5018 res_bytes[res_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8));
5019 } else {
5020 uint16_t shifted = zig_shr_u16(zig_or_u16(
5021 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5022 zig_u16_intCast_u8(lhs_byte)
5023 ), byte_shift);
5024 uint8_t truncated = zig_u8_truncate_u16(
5025 shifted,
5026 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1)
5027 );
5028
5029 overflow |= zig_u16_intCast_u8(truncated) != shifted;
5030#if zig_little_endian
5031 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset);
5032 res_byte_offset -= UINT16_C(1);
5033#else
5034 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
5035#endif
5036 res_bytes[res_byte_offset] = truncated;
5037 }
5038
5039 lhs_prev_byte = lhs_byte;
5040 }
5041
5042#if zig_big_endian
5043 res_byte_offset += UINT16_C(1);
5044 if (lhs_more_bytes) lhs_byte_offset += UINT16_C(1);
5045#endif
5046 }
5047
5048 while (lhs_byte_offset != end_byte_offset) {
5049#if zig_little_endian
5050 res_byte_offset -= UINT16_C(1);
5051 lhs_byte_offset -= UINT16_C(1);
5052#endif
5053
5054 {
5055 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset];
5056
5057 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
5058 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5059 zig_u16_intCast_u8(lhs_byte)
5060 ), byte_shift));
5061 lhs_prev_byte = lhs_byte;
5062 }
5063
5064#if zig_big_endian
5065 res_byte_offset += UINT16_C(1);
5066 lhs_byte_offset += UINT16_C(1);
5067#endif
5068 }
5069
5070 {
5071#if zig_little_endian
5072 res_byte_offset -= UINT16_C(1);
5073#endif
5074
5075 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(
5076 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5077 byte_shift
5078 ));
5079
5080#if zig_big_endian
5081 res_byte_offset += UINT16_C(1);
5082#endif
5083 }
5084
5085#if zig_little_endian
5086 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
5087#else
5088 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset);
5089#endif
5090
5091 return overflow;
5092}
5093
5094static inline void zig_shl_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
5095 if (zig_shlo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: left shift overflowed bits
5096}
5097
5098static inline void zig_shlw_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
5099 (void)zig_shlo_big(res, lhs, rhs, is_signed, bits);
5100}
5101
5102#define zig_big_shls_builtin(w) \
5103 static inline uint##w##_t zig_shls_u##w##_big(uint##w##_t lhs, const void *rhs, \
5104 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \
5105 uint##w##_t res; \
5106 const uint8_t *rhs_bytes = rhs; \
5107 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \
5108 !zig_shlo_u##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \
5109 return lhs == INT##w##_C(0) ? zig_minInt_u(w, lhs_bits) : zig_maxInt_u(w, lhs_bits); \
5110 } \
5111\
5112 static inline int##w##_t zig_shls_i##w##_big(int##w##_t lhs, const void *rhs, \
5113 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \
5114 int##w##_t res; \
5115 const uint8_t *rhs_bytes = rhs; \
5116 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \
5117 !zig_shlo_i##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \
5118 return lhs == INT##w##_C(0) ? INT##w##_C(0) : \
5119 lhs < INT##w##_C(0) ? zig_minInt_i(w, lhs_bits) : zig_maxInt_i(w, lhs_bits); \
5120 } \
5121\
5122 static inline void zig_shls_big_u##w(void *res, const void *lhs, uint##w##_t rhs, bool is_signed, uint16_t bits) { \
5123 const uint8_t *lhs_bytes = lhs; \
5124 if (rhs < bits && !zig_shlo_big(res, lhs, zig_u16_intCast_u##w(rhs), is_signed, bits)) return; \
5125 switch (zig_cmp_big_u8(lhs, UINT8_C(0), is_signed, bits)) { \
5126 case -INT32_C(1): return zig_minInt_big(res, is_signed, bits); \
5127 case INT32_C(0): return zig_minInt_big(res, false, bits); \
5128 case INT32_C(1): return zig_maxInt_big(res, is_signed, bits); \
5129 default: zig_unreachable(); \
5130 } \
5131 }
5132zig_big_shls_builtin(8)
5133zig_big_shls_builtin(16)
5134zig_big_shls_builtin(32)
5135zig_big_shls_builtin(64)
5136
5137static inline void zig_byteSwap_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
5138 uint8_t *res_bytes = res;
5139 const uint8_t *arg_bytes = arg;
5140 uint16_t res_byte_offset = UINT16_C(0);
5141 uint16_t arg_byte_offset = bits / CHAR_BIT;
5142 uint16_t end_byte_offset = UINT16_C(1);
5143 uint16_t size = zig_int_bytes(bits);
5144
5145#if zig_big_endian
5146 res_byte_offset = size - res_byte_offset;
5147 arg_byte_offset = size - arg_byte_offset;
5148 end_byte_offset = size - end_byte_offset;
5149#endif
5150
5151 while (arg_byte_offset != end_byte_offset) {
5152#if zig_little_endian
5153 arg_byte_offset -= UINT16_C(1);
5154#else
5155 res_byte_offset -= UINT16_C(1);
5156#endif
5157
5158 res_bytes[res_byte_offset] = arg_bytes[arg_byte_offset];
32425159
3243#if zig_little_endian5160#if zig_little_endian
3244 byte_offset += 8 / CHAR_BIT;5161 res_byte_offset += UINT16_C(1);
5162#else
5163 arg_byte_offset += UINT16_C(1);
3245#endif5164#endif
3246 }5165 }
32475166
3248 return overflow;5167 {
3249}5168#if zig_little_endian
5169 arg_byte_offset -= UINT16_C(1);
5170#else
5171 res_byte_offset -= UINT16_C(1);
5172#endif
32505173
3251static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5174 {
3252 (void)zig_addo_big(res, lhs, rhs, is_signed, bits);5175 uint8_t byte = arg_bytes[arg_byte_offset];
3253}5176 uint8_t fill = is_signed
5177 ? zig_u8_bitCast_i8(zig_shr_i8(zig_i8_bitCast_u8(byte, UINT8_C(8)), UINT8_C(7)), UINT8_C(8))
5178 : UINT8_C(0);
32545179
3255static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5180 res_bytes[res_byte_offset] = byte;
3256 (void)zig_subo_big(res, lhs, rhs, is_signed, bits);
3257}
32585181
3259zig_extern void __udivei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits);5182#if zig_little_endian
3260static inline void zig_div_trunc_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5183 res_byte_offset += UINT16_C(1);
3261 if (!is_signed) {5184 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset);
3262 __udivei4(res, lhs, rhs, bits);5185#else
3263 return;5186 memset(&res_bytes[0], fill, res_byte_offset);
5187#endif
5188 }
3264 }5189 }
3265
3266 zig_trap();
3267}5190}
32685191
3269static inline void zig_div_floor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5192static inline void zig_bitReverse_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
3270 if (!is_signed) {5193 uint8_t *res_bytes = res;
3271 zig_div_trunc_big(res, lhs, rhs, is_signed, bits);5194 const uint8_t *arg_bytes = arg;
3272 return;5195 uint16_t size = zig_int_bytes(bits);
3273 }5196 uint16_t res_byte_offset = UINT16_C(0);
5197 uint16_t arg_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5198 uint16_t end_byte_offset = UINT16_C(0);
5199 uint8_t arg_prev_byte;
5200 uint8_t byte_shift = zig_u8_intCast_u16(zig_subw_u16(UINT16_C(0), bits, UINT8_C(3)));
32745201
3275 zig_trap();5202#if zig_big_endian
3276}5203 res_byte_offset = size - res_byte_offset;
5204 arg_byte_offset = size - arg_byte_offset;
5205 end_byte_offset = size - end_byte_offset;
5206#endif
32775207
3278static inline void zig_div_ceil_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5208 {
3279 zig_trap();5209#if zig_little_endian
3280}5210 arg_byte_offset -= UINT16_C(1);
5211#endif
32815212
3282zig_extern void __umodei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits);5213 arg_prev_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8));
3283static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5214
3284 if (!is_signed) {5215#if zig_big_endian
3285 __umodei4(res, lhs, rhs, bits);5216 arg_byte_offset += UINT16_C(1);
3286 return;5217#endif
3287 }5218 }
32885219
3289 zig_trap();5220 while (arg_byte_offset != end_byte_offset) {
3290}5221#if zig_big_endian
5222 res_byte_offset -= UINT16_C(1);
5223#else
5224 arg_byte_offset -= UINT16_C(1);
5225#endif
32915226
3292static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5227 {
3293 if (!is_signed) {5228 uint8_t arg_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8));
3294 zig_rem_big(res, lhs, rhs, is_signed, bits);5229
3295 return;5230 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
5231 zig_shl_u16(zig_u16_intCast_u8(arg_byte), UINT8_C(8)),
5232 zig_u16_intCast_u8(arg_prev_byte)
5233 ), byte_shift));
5234 arg_prev_byte = arg_byte;
5235 }
5236
5237#if zig_little_endian
5238 res_byte_offset += UINT16_C(1);
5239#else
5240 arg_byte_offset += UINT16_C(1);
5241#endif
3296 }5242 }
32975243
3298 zig_trap();5244 {
5245 uint8_t arg_sign_fill = UINT8_C(0);
5246
5247#if zig_big_endian
5248 res_byte_offset -= UINT16_C(1);
5249#endif
5250
5251 if (is_signed) {
5252 int8_t signed_byte = zig_i8_bitCast_u8(arg_prev_byte, UINT8_C(8));
5253
5254 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift);
5255 arg_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8));
5256 } else {
5257 res_bytes[res_byte_offset] = zig_shr_u8(arg_prev_byte, byte_shift);
5258 }
5259
5260#if zig_little_endian
5261 res_byte_offset += UINT16_C(1);
5262 memset(&res_bytes[res_byte_offset], arg_sign_fill, size - res_byte_offset);
5263#else
5264 memset(&res_bytes[0], arg_sign_fill, res_byte_offset);
5265#endif
5266 }
3299}5267}
33005268
3301static inline uint16_t zig_clz_big(const void *val, bool is_signed, uint16_t bits) {5269static inline uint16_t zig_popCount_big(const void *arg, bool is_signed, uint16_t bits) {
3302 const uint8_t *val_bytes = val;5270 const uint8_t *arg_bytes = arg;
3303 uint16_t byte_offset = 0;5271 uint16_t byte_offset = 0;
3304 uint16_t remaining_bytes = zig_int_bytes(bits);5272 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
3305 uint16_t skip_bits = remaining_bytes * 8 - bits;5273 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3306 uint16_t total_lz = 0;5274 uint16_t total_pc = 0;
3307 uint16_t limb_lz;
3308 (void)is_signed;5275 (void)is_signed;
33095276
3310#if zig_little_endian5277#if zig_big_endian
3311 byte_offset = remaining_bytes;5278 byte_offset = zig_int_bytes(bits);
3312#endif5279#endif
33135280
3314 while (remaining_bytes >= 128 / CHAR_BIT) {5281 while (remaining_bytes >= 128 / CHAR_BIT) {
3315#if zig_little_endian5282 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
5283
5284#if zig_big_endian
3316 byte_offset -= 128 / CHAR_BIT;5285 byte_offset -= 128 / CHAR_BIT;
3317#endif5286#endif
33185287
3319 {5288 {
3320 zig_u128 val_limb;5289 zig_u128 arg_limb;
33215290
3322 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5291 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3323 limb_lz = zig_clz_u128(val_limb, 128 - skip_bits);5292 total_pc += zig_popCount_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
3324 }5293 }
33255294
3326 total_lz += limb_lz;
3327 if (limb_lz < 128 - skip_bits) return total_lz;
3328 skip_bits = 0;
3329 remaining_bytes -= 128 / CHAR_BIT;5295 remaining_bytes -= 128 / CHAR_BIT;
33305296
3331#if zig_big_endian5297#if zig_little_endian
3332 byte_offset += 128 / CHAR_BIT;5298 byte_offset += 128 / CHAR_BIT;
3333#endif5299#endif
3334 }5300 }
33355301
3336 while (remaining_bytes >= 64 / CHAR_BIT) {5302 while (remaining_bytes >= 64 / CHAR_BIT) {
3337#if zig_little_endian5303 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
5304
5305#if zig_big_endian
3338 byte_offset -= 64 / CHAR_BIT;5306 byte_offset -= 64 / CHAR_BIT;
3339#endif5307#endif
33405308
3341 {5309 {
3342 uint64_t val_limb;5310 uint64_t arg_limb;
33435311
3344 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5312 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3345 limb_lz = zig_clz_u64(val_limb, 64 - skip_bits);5313 total_pc += zig_popCount_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
3346 }5314 }
33475315
3348 total_lz += limb_lz;
3349 if (limb_lz < 64 - skip_bits) return total_lz;
3350 skip_bits = 0;
3351 remaining_bytes -= 64 / CHAR_BIT;5316 remaining_bytes -= 64 / CHAR_BIT;
33525317
3353#if zig_big_endian5318#if zig_little_endian
3354 byte_offset += 64 / CHAR_BIT;5319 byte_offset += 64 / CHAR_BIT;
3355#endif5320#endif
3356 }5321 }
33575322
3358 while (remaining_bytes >= 32 / CHAR_BIT) {5323 while (remaining_bytes >= 32 / CHAR_BIT) {
3359#if zig_little_endian5324 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
5325
5326#if zig_big_endian
3360 byte_offset -= 32 / CHAR_BIT;5327 byte_offset -= 32 / CHAR_BIT;
3361#endif5328#endif
33625329
3363 {5330 {
3364 uint32_t val_limb;5331 uint32_t arg_limb;
33655332
3366 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5333 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3367 limb_lz = zig_clz_u32(val_limb, 32 - skip_bits);5334 total_pc += zig_popCount_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
3368 }5335 }
33695336
3370 total_lz += limb_lz;
3371 if (limb_lz < 32 - skip_bits) return total_lz;
3372 skip_bits = 0;
3373 remaining_bytes -= 32 / CHAR_BIT;5337 remaining_bytes -= 32 / CHAR_BIT;
33745338
3375#if zig_big_endian5339#if zig_little_endian
3376 byte_offset += 32 / CHAR_BIT;5340 byte_offset += 32 / CHAR_BIT;
3377#endif5341#endif
3378 }5342 }
33795343
3380 while (remaining_bytes >= 16 / CHAR_BIT) {5344 while (remaining_bytes >= 16 / CHAR_BIT) {
3381#if zig_little_endian5345 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
5346
5347#if zig_big_endian
3382 byte_offset -= 16 / CHAR_BIT;5348 byte_offset -= 16 / CHAR_BIT;
3383#endif5349#endif
33845350
3385 {5351 {
3386 uint16_t val_limb;5352 uint16_t arg_limb;
33875353
3388 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5354 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3389 limb_lz = zig_clz_u16(val_limb, 16 - skip_bits);5355 total_pc += zig_popCount_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
3390 }5356 }
33915357
3392 total_lz += limb_lz;
3393 if (limb_lz < 16 - skip_bits) return total_lz;
3394 skip_bits = 0;
3395 remaining_bytes -= 16 / CHAR_BIT;5358 remaining_bytes -= 16 / CHAR_BIT;
33965359
3397#if zig_big_endian5360#if zig_little_endian
3398 byte_offset += 16 / CHAR_BIT;5361 byte_offset += 16 / CHAR_BIT;
3399#endif5362#endif
3400 }5363 }
34015364
3402 while (remaining_bytes >= 8 / CHAR_BIT) {5365 while (remaining_bytes >= 8 / CHAR_BIT) {
3403#if zig_little_endian5366 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
5367
5368#if zig_big_endian
3404 byte_offset -= 8 / CHAR_BIT;5369 byte_offset -= 8 / CHAR_BIT;
3405#endif5370#endif
34065371
3407 {5372 {
3408 uint8_t val_limb;5373 uint8_t arg_limb;
34095374
3410 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5375 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3411 limb_lz = zig_clz_u8(val_limb, 8 - skip_bits);5376 total_pc += zig_popCount_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
3412 }5377 }
34135378
3414 total_lz += limb_lz;
3415 if (limb_lz < 8 - skip_bits) return total_lz;
3416 skip_bits = 0;
3417 remaining_bytes -= 8 / CHAR_BIT;5379 remaining_bytes -= 8 / CHAR_BIT;
34185380
3419#if zig_big_endian5381#if zig_little_endian
3420 byte_offset += 8 / CHAR_BIT;5382 byte_offset += 8 / CHAR_BIT;
3421#endif5383#endif
3422 }5384 }
34235385
3424 return total_lz;5386 return total_pc;
3425}5387}
34265388
3427static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bits) {5389static inline uint16_t zig_ctz_big(const void *arg, bool is_signed, uint16_t bits) {
3428 const uint8_t *val_bytes = val;5390 const uint8_t *arg_bytes = arg;
3429 uint16_t byte_offset = 0;5391 uint16_t byte_offset = UINT16_C(0);
3430 uint16_t remaining_bytes = zig_int_bytes(bits);5392 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
3431 uint16_t total_tz = 0;5393 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5394 uint16_t total_tz = UINT16_C(0);
3432 uint16_t limb_tz;5395 uint16_t limb_tz;
3433 (void)is_signed;5396 (void)is_signed;
34345397
3435#if zig_big_endian5398#if zig_big_endian
3436 byte_offset = remaining_bytes;5399 byte_offset = zig_int_bytes(bits);
3437#endif5400#endif
34385401
3439 while (remaining_bytes >= 128 / CHAR_BIT) {5402 while (remaining_bytes >= 128 / CHAR_BIT) {
5403 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
5404
3440#if zig_big_endian5405#if zig_big_endian
3441 byte_offset -= 128 / CHAR_BIT;5406 byte_offset -= 128 / CHAR_BIT;
3442#endif5407#endif
34435408
3444 {5409 {
3445 zig_u128 val_limb;5410 zig_u128 arg_limb;
34465411
3447 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5412 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3448 limb_tz = zig_ctz_u128(val_limb, 128);5413 limb_tz = zig_ctz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
3449 }5414 }
34505415
3451 total_tz += limb_tz;5416 total_tz += limb_tz;
3452 if (limb_tz < 128) return total_tz;5417 if (limb_tz < limb_bits) return total_tz;
3453 remaining_bytes -= 128 / CHAR_BIT;5418 remaining_bytes -= 128 / CHAR_BIT;
34545419
3455#if zig_little_endian5420#if zig_little_endian
...@@ -3458,19 +5423,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3458,19 +5423,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3458 }5423 }
34595424
3460 while (remaining_bytes >= 64 / CHAR_BIT) {5425 while (remaining_bytes >= 64 / CHAR_BIT) {
5426 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
5427
3461#if zig_big_endian5428#if zig_big_endian
3462 byte_offset -= 64 / CHAR_BIT;5429 byte_offset -= 64 / CHAR_BIT;
3463#endif5430#endif
34645431
3465 {5432 {
3466 uint64_t val_limb;5433 uint64_t arg_limb;
34675434
3468 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5435 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3469 limb_tz = zig_ctz_u64(val_limb, 64);5436 limb_tz = zig_ctz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
3470 }5437 }
34715438
3472 total_tz += limb_tz;5439 total_tz += limb_tz;
3473 if (limb_tz < 64) return total_tz;5440 if (limb_tz < limb_bits) return total_tz;
3474 remaining_bytes -= 64 / CHAR_BIT;5441 remaining_bytes -= 64 / CHAR_BIT;
34755442
3476#if zig_little_endian5443#if zig_little_endian
...@@ -3479,19 +5446,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3479,19 +5446,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3479 }5446 }
34805447
3481 while (remaining_bytes >= 32 / CHAR_BIT) {5448 while (remaining_bytes >= 32 / CHAR_BIT) {
5449 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
5450
3482#if zig_big_endian5451#if zig_big_endian
3483 byte_offset -= 32 / CHAR_BIT;5452 byte_offset -= 32 / CHAR_BIT;
3484#endif5453#endif
34855454
3486 {5455 {
3487 uint32_t val_limb;5456 uint32_t arg_limb;
34885457
3489 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5458 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3490 limb_tz = zig_ctz_u32(val_limb, 32);5459 limb_tz = zig_ctz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
3491 }5460 }
34925461
3493 total_tz += limb_tz;5462 total_tz += limb_tz;
3494 if (limb_tz < 32) return total_tz;5463 if (limb_tz < limb_bits) return total_tz;
3495 remaining_bytes -= 32 / CHAR_BIT;5464 remaining_bytes -= 32 / CHAR_BIT;
34965465
3497#if zig_little_endian5466#if zig_little_endian
...@@ -3500,19 +5469,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3500,19 +5469,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3500 }5469 }
35015470
3502 while (remaining_bytes >= 16 / CHAR_BIT) {5471 while (remaining_bytes >= 16 / CHAR_BIT) {
5472 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
5473
3503#if zig_big_endian5474#if zig_big_endian
3504 byte_offset -= 16 / CHAR_BIT;5475 byte_offset -= 16 / CHAR_BIT;
3505#endif5476#endif
35065477
3507 {5478 {
3508 uint16_t val_limb;5479 uint16_t arg_limb;
35095480
3510 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5481 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3511 limb_tz = zig_ctz_u16(val_limb, 16);5482 limb_tz = zig_ctz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
3512 }5483 }
35135484
3514 total_tz += limb_tz;5485 total_tz += limb_tz;
3515 if (limb_tz < 16) return total_tz;5486 if (limb_tz < limb_bits) return total_tz;
3516 remaining_bytes -= 16 / CHAR_BIT;5487 remaining_bytes -= 16 / CHAR_BIT;
35175488
3518#if zig_little_endian5489#if zig_little_endian
...@@ -3521,19 +5492,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3521,19 +5492,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3521 }5492 }
35225493
3523 while (remaining_bytes >= 8 / CHAR_BIT) {5494 while (remaining_bytes >= 8 / CHAR_BIT) {
5495 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
5496
3524#if zig_big_endian5497#if zig_big_endian
3525 byte_offset -= 8 / CHAR_BIT;5498 byte_offset -= 8 / CHAR_BIT;
3526#endif5499#endif
35275500
3528 {5501 {
3529 uint8_t val_limb;5502 uint8_t arg_limb;
35305503
3531 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5504 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3532 limb_tz = zig_ctz_u8(val_limb, 8);5505 limb_tz = zig_ctz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
3533 }5506 }
35345507
3535 total_tz += limb_tz;5508 total_tz += limb_tz;
3536 if (limb_tz < 8) return total_tz;5509 if (limb_tz < limb_bits) return total_tz;
3537 remaining_bytes -= 8 / CHAR_BIT;5510 remaining_bytes -= 8 / CHAR_BIT;
35385511
3539#if zig_little_endian5512#if zig_little_endian
...@@ -3544,113 +5517,141 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3544,113 +5517,141 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3544 return total_tz;5517 return total_tz;
3545}5518}
35465519
3547static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_t bits) {5520static inline uint16_t zig_clz_big(const void *arg, bool is_signed, uint16_t bits) {
3548 const uint8_t *val_bytes = val;5521 const uint8_t *arg_bytes = arg;
3549 uint16_t byte_offset = 0;5522 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
3550 uint16_t remaining_bytes = zig_int_bytes(bits);5523 uint16_t remaining_bytes = byte_offset;
3551 uint16_t total_pc = 0;5524 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5525 bool sign_limb = true;
5526 uint16_t total_lz = UINT16_C(0);
5527 uint16_t limb_lz;
3552 (void)is_signed;5528 (void)is_signed;
35535529
3554#if zig_big_endian5530#if zig_big_endian
3555 byte_offset = remaining_bytes;5531 byte_offset = zig_int_bytes(bits) - remaining_bytes;
3556#endif5532#endif
35575533
3558 while (remaining_bytes >= 128 / CHAR_BIT) {5534 while (remaining_bytes >= 128 / CHAR_BIT) {
3559#if zig_big_endian5535 uint8_t limb_bits = UINT8_C(128) - (sign_limb ? top_bits : UINT8_C(0));
5536
5537#if zig_little_endian
3560 byte_offset -= 128 / CHAR_BIT;5538 byte_offset -= 128 / CHAR_BIT;
3561#endif5539#endif
35625540
3563 {5541 {
3564 zig_u128 val_limb;5542 zig_u128 arg_limb;
35655543
3566 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5544 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3567 total_pc += zig_popcount_u128(val_limb, 128);5545 limb_lz = zig_clz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
3568 }5546 }
35695547
5548 total_lz += limb_lz;
5549 if (limb_lz < limb_bits) return total_lz;
5550 sign_limb = false;
3570 remaining_bytes -= 128 / CHAR_BIT;5551 remaining_bytes -= 128 / CHAR_BIT;
35715552
3572#if zig_little_endian5553#if zig_big_endian
3573 byte_offset += 128 / CHAR_BIT;5554 byte_offset += 128 / CHAR_BIT;
3574#endif5555#endif
3575 }5556 }
35765557
3577 while (remaining_bytes >= 64 / CHAR_BIT) {5558 while (remaining_bytes >= 64 / CHAR_BIT) {
3578#if zig_big_endian5559 uint8_t limb_bits = UINT8_C(64) - (sign_limb ? top_bits : UINT8_C(0));
5560
5561#if zig_little_endian
3579 byte_offset -= 64 / CHAR_BIT;5562 byte_offset -= 64 / CHAR_BIT;
3580#endif5563#endif
35815564
3582 {5565 {
3583 uint64_t val_limb;5566 uint64_t arg_limb;
35845567
3585 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5568 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3586 total_pc += zig_popcount_u64(val_limb, 64);5569 limb_lz = zig_clz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
3587 }5570 }
35885571
5572 total_lz += limb_lz;
5573 if (limb_lz < limb_bits) return total_lz;
5574 sign_limb = false;
3589 remaining_bytes -= 64 / CHAR_BIT;5575 remaining_bytes -= 64 / CHAR_BIT;
35905576
3591#if zig_little_endian5577#if zig_big_endian
3592 byte_offset += 64 / CHAR_BIT;5578 byte_offset += 64 / CHAR_BIT;
3593#endif5579#endif
3594 }5580 }
35955581
3596 while (remaining_bytes >= 32 / CHAR_BIT) {5582 while (remaining_bytes >= 32 / CHAR_BIT) {
3597#if zig_big_endian5583 uint8_t limb_bits = UINT8_C(32) - (sign_limb ? top_bits : UINT8_C(0));
5584
5585#if zig_little_endian
3598 byte_offset -= 32 / CHAR_BIT;5586 byte_offset -= 32 / CHAR_BIT;
3599#endif5587#endif
36005588
3601 {5589 {
3602 uint32_t val_limb;5590 uint32_t arg_limb;
36035591
3604 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5592 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3605 total_pc += zig_popcount_u32(val_limb, 32);5593 limb_lz = zig_clz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
3606 }5594 }
36075595
5596 total_lz += limb_lz;
5597 if (limb_lz < limb_bits) return total_lz;
5598 sign_limb = false;
3608 remaining_bytes -= 32 / CHAR_BIT;5599 remaining_bytes -= 32 / CHAR_BIT;
36095600
3610#if zig_little_endian5601#if zig_big_endian
3611 byte_offset += 32 / CHAR_BIT;5602 byte_offset += 32 / CHAR_BIT;
3612#endif5603#endif
3613 }5604 }
36145605
3615 while (remaining_bytes >= 16 / CHAR_BIT) {5606 while (remaining_bytes >= 16 / CHAR_BIT) {
3616#if zig_big_endian5607 uint8_t limb_bits = UINT8_C(16) - (sign_limb ? top_bits : UINT8_C(0));
5608
5609#if zig_little_endian
3617 byte_offset -= 16 / CHAR_BIT;5610 byte_offset -= 16 / CHAR_BIT;
3618#endif5611#endif
36195612
3620 {5613 {
3621 uint16_t val_limb;5614 uint16_t arg_limb;
36225615
3623 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5616 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3624 total_pc = zig_popcount_u16(val_limb, 16);5617 limb_lz = zig_clz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
3625 }5618 }
36265619
5620 total_lz += limb_lz;
5621 if (limb_lz < limb_bits) return total_lz;
5622 sign_limb = false;
3627 remaining_bytes -= 16 / CHAR_BIT;5623 remaining_bytes -= 16 / CHAR_BIT;
36285624
3629#if zig_little_endian5625#if zig_big_endian
3630 byte_offset += 16 / CHAR_BIT;5626 byte_offset += 16 / CHAR_BIT;
3631#endif5627#endif
3632 }5628 }
36335629
3634 while (remaining_bytes >= 8 / CHAR_BIT) {5630 while (remaining_bytes >= 8 / CHAR_BIT) {
3635#if zig_big_endian5631 uint8_t limb_bits = UINT8_C(8) - (sign_limb ? top_bits : UINT8_C(0));
5632
5633#if zig_little_endian
3636 byte_offset -= 8 / CHAR_BIT;5634 byte_offset -= 8 / CHAR_BIT;
3637#endif5635#endif
36385636
3639 {5637 {
3640 uint8_t val_limb;5638 uint8_t arg_limb;
36415639
3642 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5640 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3643 total_pc = zig_popcount_u8(val_limb, 8);5641 limb_lz = zig_clz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
3644 }5642 }
36455643
5644 total_lz += limb_lz;
5645 if (limb_lz < limb_bits) return total_lz;
5646 sign_limb = false;
3646 remaining_bytes -= 8 / CHAR_BIT;5647 remaining_bytes -= 8 / CHAR_BIT;
36475648
3648#if zig_little_endian5649#if zig_big_endian
3649 byte_offset += 8 / CHAR_BIT;5650 byte_offset += 8 / CHAR_BIT;
3650#endif5651#endif
3651 }5652 }
36525653
3653 return total_pc;5654 return total_lz;
3654}5655}
36555656
3656/* ========================= Floating Point Support ========================= */5657/* ========================= Floating Point Support ========================= */
...@@ -3687,29 +5688,29 @@ long double __cdecl nanl(char const* input);...@@ -3687,29 +5688,29 @@ long double __cdecl nanl(char const* input);
3687#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg)5688#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg)
3688#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)5689#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)
3689#else5690#else
3690#define zig_make_special_f16(sign, name, arg, repr) zig_bitCast_f16 (repr)5691#define zig_make_special_f16(sign, name, arg, repr) zig_f16_bitCast_u16 (repr)
3691#define zig_make_special_f32(sign, name, arg, repr) zig_bitCast_f32 (repr)5692#define zig_make_special_f32(sign, name, arg, repr) zig_f32_bitCast_u32 (repr)
3692#define zig_make_special_f64(sign, name, arg, repr) zig_bitCast_f64 (repr)5693#define zig_make_special_f64(sign, name, arg, repr) zig_f64_bitCast_u64 (repr)
3693#define zig_make_special_f80(sign, name, arg, repr) zig_bitCast_f80 (repr)5694#define zig_make_special_f80(sign, name, arg, repr) zig_f80_bitCast_u128(repr)
3694#define zig_make_special_f128(sign, name, arg, repr) zig_bitCast_f128(repr)5695#define zig_make_special_f128(sign, name, arg, repr) zig_f128_bitCast_u128(repr)
3695#endif5696#endif
36965697
3697#define zig_has_f16 15698#define zig_has_f16 1
3698#define zig_libc_name_f16(name) __##name##h5699#define zig_libc_name_f16(name) __##name##h
3699#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)5700#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)
3700#if FLT_MANT_DIG == 115701#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT_MANT_DIG == 11
3701typedef float zig_f16;5702typedef float zig_f16;
3702#define zig_make_f16(fp, repr) fp##f5703#define zig_make_f16(fp, repr) fp##f
3703#elif DBL_MANT_DIG == 115704#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && DBL_MANT_DIG == 11
3704typedef double zig_f16;5705typedef double zig_f16;
3705#define zig_make_f16(fp, repr) fp5706#define zig_make_f16(fp, repr) fp
3706#elif LDBL_MANT_DIG == 115707#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && LDBL_MANT_DIG == 11
3707typedef long double zig_f16;5708typedef long double zig_f16;
3708#define zig_make_f16(fp, repr) fp##l5709#define zig_make_f16(fp, repr) fp##l
3709#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc))5710#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc))
3710typedef _Float16 zig_f16;5711typedef _Float16 zig_f16;
3711#define zig_make_f16(fp, repr) fp##f165712#define zig_make_f16(fp, repr) fp##f16
3712#elif defined(__SIZEOF_FP16__)5713#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && defined(__SIZEOF_FP16__)
3713typedef __fp16 zig_f16;5714typedef __fp16 zig_f16;
3714#define zig_make_f16(fp, repr) fp##f165715#define zig_make_f16(fp, repr) fp##f16
3715#else5716#else
...@@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16;...@@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16;
3723#undef zig_init_special_f165724#undef zig_init_special_f16
3724#define zig_init_special_f16(sign, name, arg, repr) repr5725#define zig_init_special_f16(sign, name, arg, repr) repr
3725#endif5726#endif
3726#if defined(zig_darwin) && defined(zig_x86)
3727typedef uint16_t zig_compiler_rt_f16;
3728#else
3729typedef zig_f16 zig_compiler_rt_f16;
3730#endif
37315727
3732#define zig_has_f32 15728#define zig_has_f32 1
3733#define zig_libc_name_f32(name) name##f5729#define zig_libc_name_f32(name) name##f
...@@ -3736,16 +5732,16 @@ typedef zig_f16 zig_compiler_rt_f16;...@@ -3736,16 +5732,16 @@ typedef zig_f16 zig_compiler_rt_f16;
3736#else5732#else
3737#define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr)5733#define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr)
3738#endif5734#endif
3739#if FLT_MANT_DIG == 245735#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT_MANT_DIG == 24
3740typedef float zig_f32;5736typedef float zig_f32;
3741#define zig_make_f32(fp, repr) fp##f5737#define zig_make_f32(fp, repr) fp##f
3742#elif DBL_MANT_DIG == 245738#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && DBL_MANT_DIG == 24
3743typedef double zig_f32;5739typedef double zig_f32;
3744#define zig_make_f32(fp, repr) fp5740#define zig_make_f32(fp, repr) fp
3745#elif LDBL_MANT_DIG == 245741#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && LDBL_MANT_DIG == 24
3746typedef long double zig_f32;5742typedef long double zig_f32;
3747#define zig_make_f32(fp, repr) fp##l5743#define zig_make_f32(fp, repr) fp##l
3748#elif FLT32_MANT_DIG == 245744#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT32_MANT_DIG == 24
3749typedef _Float32 zig_f32;5745typedef _Float32 zig_f32;
3750#define zig_make_f32(fp, repr) fp##f325746#define zig_make_f32(fp, repr) fp##f32
3751#else5747#else
...@@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32;...@@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32;
3768#else5764#else
3769#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)5765#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)
3770#endif5766#endif
3771#if FLT_MANT_DIG == 535767#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT_MANT_DIG == 53
3772typedef float zig_f64;5768typedef float zig_f64;
3773#define zig_make_f64(fp, repr) fp##f5769#define zig_make_f64(fp, repr) fp##f
3774#elif DBL_MANT_DIG == 535770#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && DBL_MANT_DIG == 53
3775typedef double zig_f64;5771typedef double zig_f64;
3776#define zig_make_f64(fp, repr) fp5772#define zig_make_f64(fp, repr) fp
3777#elif LDBL_MANT_DIG == 535773#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && LDBL_MANT_DIG == 53
3778typedef long double zig_f64;5774typedef long double zig_f64;
3779#define zig_make_f64(fp, repr) fp##l5775#define zig_make_f64(fp, repr) fp##l
3780#elif FLT64_MANT_DIG == 535776#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT64_MANT_DIG == 53
3781typedef _Float64 zig_f64;5777typedef _Float64 zig_f64;
3782#define zig_make_f64(fp, repr) fp##f645778#define zig_make_f64(fp, repr) fp##f64
3783#elif FLT32X_MANT_DIG == 535779#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT32X_MANT_DIG == 53
3784typedef _Float32x zig_f64;5780typedef _Float32x zig_f64;
3785#define zig_make_f64(fp, repr) fp##f32x5781#define zig_make_f64(fp, repr) fp##f32x
3786#else5782#else
...@@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64;...@@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64;
3798#define zig_has_f80 15794#define zig_has_f80 1
3799#define zig_libc_name_f80(name) __##name##x5795#define zig_libc_name_f80(name) __##name##x
3800#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)5796#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)
3801#if FLT_MANT_DIG == 645797#ifdef ZIG_TARGET_SOFT_COMPILER_RT_F80_ABI
5798#undef zig_has_f80
5799typedef struct { uint64_t mantissa; uint16_t exponent; } zig_f80;
5800#define zig_init_repr_f80(mantissa, exponent) { .mant##issa = mantissa, .expo##nent = exponent }
5801#define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent)
5802#define zig_mantissa_repr_f80(arg) (arg).mantissa
5803#define zig_exponent_repr_f80(arg) (arg).exponent
5804#elif FLT_MANT_DIG == 64
3802typedef float zig_f80;5805typedef float zig_f80;
3803#define zig_make_f80(fp, repr) fp##f5806#define zig_make_f80(fp, repr) fp##f
3804#elif DBL_MANT_DIG == 645807#elif DBL_MANT_DIG == 64
...@@ -3818,68 +5821,91 @@ typedef __float80 zig_f80;...@@ -3818,68 +5821,91 @@ typedef __float80 zig_f80;
3818#define zig_make_f80(fp, repr) fp##l5821#define zig_make_f80(fp, repr) fp##l
3819#else5822#else
3820#undef zig_has_f805823#undef zig_has_f80
3821#define zig_has_f80 0
3822#define zig_repr_f80 u128
3823typedef zig_u128 zig_f80;5824typedef zig_u128 zig_f80;
5825#define zig_init_repr_f80(mantissa, exponent) zig_init_u128(exponent, mantissa)
5826#define zig_make_repr_f80(mantissa, exponent) zig_make_u128(exponent, mantissa)
5827#define zig_mantissa_repr_f80(arg) zig_lo_u128(arg)
5828#define zig_exponent_repr_f80(arg) (uint16_t)zig_hi_u128(arg)
5829#endif
5830#ifndef zig_has_f80
5831#define zig_has_f80 0
3824#define zig_make_f80(fp, repr) repr5832#define zig_make_f80(fp, repr) repr
5833#ifndef zig_make_repr_f80
5834#define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent)
5835#endif
3825#undef zig_make_special_f805836#undef zig_make_special_f80
3826#define zig_make_special_f80(sign, name, arg, repr) repr5837#define zig_make_special_f80(sign, name, arg, repr) repr
3827#undef zig_init_special_f805838#undef zig_init_special_f80
3828#define zig_init_special_f80(sign, name, arg, repr) repr5839#define zig_init_special_f80(sign, name, arg, repr) repr
3829#endif5840#endif
38305841
3831#if defined(zig_gcc) && defined(zig_x86)
3832#define zig_f128_has_miscompilations 1
3833#else
3834#define zig_f128_has_miscompilations 0
3835#endif
3836
3837#define zig_has_f128 15842#define zig_has_f128 1
3838#define zig_libc_name_f128(name) name##q5843#define zig_libc_name_f128(name) name##f128
3839#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)5844#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
3840#if !zig_f128_has_miscompilations && FLT_MANT_DIG == 1135845#ifdef ZIG_TARGET_SOFT_COMPILER_RT_F128_ABI
5846#undef zig_has_f128
5847#if zig_little_endian
5848typedef struct { uint64_t lo, hi; } zig_f128;
5849#else
5850typedef struct { uint64_t hi, lo; } zig_f128;
5851#endif
5852#define zig_init_repr_f128(hi, lo) { .h##i = hi, .l##o = lo }
5853#define zig_lo_repr_f128(arg) (arg).lo
5854#define zig_hi_repr_f128(arg) (arg).hi
5855#elif FLT_MANT_DIG == 113
3841typedef float zig_f128;5856typedef float zig_f128;
3842#define zig_make_f128(fp, repr) fp##f5857#define zig_make_f128(fp, repr) fp##f
3843#elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 1135858#elif DBL_MANT_DIG == 113
3844typedef double zig_f128;5859typedef double zig_f128;
3845#define zig_make_f128(fp, repr) fp5860#define zig_make_f128(fp, repr) fp
3846#elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 1135861#elif LDBL_MANT_DIG == 113
3847typedef long double zig_f128;5862typedef long double zig_f128;
3848#define zig_make_f128(fp, repr) fp##l5863#define zig_make_f128(fp, repr) fp##l
3849#elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 1135864#elif FLT128_MANT_DIG == 113
3850typedef _Float128 zig_f128;5865typedef _Float128 zig_f128;
3851#define zig_make_f128(fp, repr) fp##f1285866#define zig_make_f128(fp, repr) fp##f128
3852#elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 1135867#elif FLT64X_MANT_DIG == 113
3853typedef _Float64x zig_f128;5868typedef _Float64x zig_f128;
3854#define zig_make_f128(fp, repr) fp##f64x5869#define zig_make_f128(fp, repr) fp##f64x
3855#elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__)5870#elif defined(__SIZEOF_FLOAT128__)
3856typedef __float128 zig_f128;5871typedef __float128 zig_f128;
3857#define zig_make_f128(fp, repr) fp##q5872#define zig_make_f128(fp, repr) fp##q
3858#undef zig_make_special_f1285873#undef zig_make_special_f128
3859#define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg)5874#define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg)
3860#else5875#else
3861#undef zig_has_f1285876#undef zig_has_f128
3862#define zig_has_f128 05877#if defined(zig_x86_64) && defined(ZIG_TARGET_ABI_MSVC)
3863#undef zig_make_special_f1285878#if defined(zig_msvc) && !defined(__clang__)
3864#undef zig_init_special_f1285879#include <emmintrin.h>
3865#if defined(zig_darwin) || defined(zig_aarch64)5880typedef __m128i zig_f128;
3866typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64;5881#define zig_init_repr_f128(hi, lo) { .m128i_u64 = { lo, hi } }
3867zig_basic_operator(zig_v2u64, xor_v2u64, ^)5882#define zig_lo_repr_f128(arg) (arg).m128i_u64[0]
3868#define zig_repr_f128 v2u645883#define zig_hi_repr_f128(arg) (arg).m128i_u64[1]
3869typedef zig_v2u64 zig_f128;5884#else
3870#define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi }5885typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_f128;
3871#define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u1285886#define zig_init_repr_f128(hi, lo) { lo, hi }
3872#define zig_make_f128(fp, repr) zig_make_f128_##repr5887#define zig_lo_repr_f128(arg) (arg)[0]
3873#define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr5888#define zig_hi_repr_f128(arg) (arg)[1]
3874#define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr5889#endif
3875#else5890#else
3876#define zig_repr_f128 u128
3877typedef zig_u128 zig_f128;5891typedef zig_u128 zig_f128;
5892#define zig_init_repr_f128(hi, lo) zig_init_u128(hi, lo)
5893#define zig_make_repr_f128(hi, lo) zig_make_u128(hi, lo)
5894#define zig_lo_repr_f128(arg) zig_lo_u128(arg)
5895#define zig_hi_repr_f128(arg) zig_hi_u128(arg)
5896#endif
5897#endif
5898#ifndef zig_has_f128
5899#define zig_has_f128 0
3878#define zig_make_f128(fp, repr) repr5900#define zig_make_f128(fp, repr) repr
5901#ifndef zig_make_repr_f128
5902#define zig_make_repr_f128(hi, lo) (zig_f128)zig_init_repr_f128(hi, lo)
5903#endif
5904#undef zig_make_special_f128
3879#define zig_make_special_f128(sign, name, arg, repr) repr5905#define zig_make_special_f128(sign, name, arg, repr) repr
5906#undef zig_init_special_f128
3880#define zig_init_special_f128(sign, name, arg, repr) repr5907#define zig_init_special_f128(sign, name, arg, repr) repr
3881#endif5908#endif
3882#endif
38835909
3884#if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC)5910#if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC)
3885/* Emulate msvc abi on a gnu compiler */5911/* Emulate msvc abi on a gnu compiler */
...@@ -3892,84 +5918,141 @@ typedef zig_f128 zig_c_longdouble;...@@ -3892,84 +5918,141 @@ typedef zig_f128 zig_c_longdouble;
3892typedef long double zig_c_longdouble;5918typedef long double zig_c_longdouble;
3893#endif5919#endif
38945920
3895#define zig_bitCast_float(Type, ReprType) \5921#if __AVR__
3896 static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \5922typedef signed char zig_FloatCompareResult;
3897 zig_##Type result; \5923#elif defined(zig_aarch64)
3898 memcpy(&result, &repr, sizeof(result)); \5924typedef signed int zig_FloatCompareResult;
3899 return result; \5925#elif __SIZEOF_LONG__ >= __SIZEOF_POINTER__
5926typedef signed long zig_FloatCompareResult;
5927#else
5928typedef signed long long zig_FloatCompareResult;
5929#endif
5930
5931#define zig_bitCast_float(w, iw, UnsignedReprType, SignedReprType) \
5932 static inline zig_f##w zig_f##w##_bitCast_u##iw(UnsignedReprType arg) { \
5933 zig_f##w res; \
5934 memcpy(&res, &arg, sizeof(zig_f##w)); \
5935 return res; \
5936 } \
5937 static inline zig_f##w zig_f##w##_bitCast_i##iw(SignedReprType arg) { \
5938 zig_f##w res; \
5939 memcpy(&res, &arg, sizeof(zig_f##w)); \
5940 return res; \
5941 } \
5942 static inline UnsignedReprType zig_u##iw##_bitCast_f##w(zig_f##w arg) { \
5943 UnsignedReprType res; \
5944 memcpy(&res, &arg, sizeof(zig_f##w)); \
5945 return zig_u##iw##_truncate_u##iw(res, w); \
5946 } \
5947 static inline SignedReprType zig_i##iw##_bitCast_f##w(zig_f##w arg) { \
5948 SignedReprType res; \
5949 memcpy(&res, &arg, sizeof(zig_f##w)); \
5950 return zig_i##iw##_truncate_i##iw(res, w); \
3900 }5951 }
3901zig_bitCast_float(f16, uint16_t)5952zig_bitCast_float(16, 16, uint16_t, int16_t)
3902zig_bitCast_float(f32, uint32_t)5953zig_bitCast_float(32, 32, uint32_t, int32_t)
3903zig_bitCast_float(f64, uint64_t)5954zig_bitCast_float(64, 64, uint64_t, int64_t)
3904zig_bitCast_float(f80, zig_u128)5955#if zig_has_f80
3905zig_bitCast_float(f128, zig_u128)5956zig_bitCast_float(80, 128, zig_u128, zig_i128)
5957#else
5958static inline zig_f80 zig_f80_bitCast_u128(zig_u128 arg) {
5959 return zig_make_repr_f80(zig_lo_u128(arg), (uint16_t)zig_hi_u128(arg));
5960}
5961static inline zig_f80 zig_f80_bitCast_i128(zig_i128 arg) {
5962 return zig_make_repr_f80(zig_lo_i128(arg), (uint16_t)zig_hi_i128(arg));
5963}
5964static inline zig_u128 zig_u128_bitCast_f80(zig_f80 arg) {
5965 return zig_make_u128(zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg));
5966}
5967static inline zig_i128 zig_i128_bitCast_f80(zig_f80 arg) {
5968 return zig_make_i128((int16_t)zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg));
5969}
5970#endif
5971static inline zig_f80 zig_f80_bitCast_big(const void *arg) {
5972 return zig_f80_bitCast_u128(zig_u128_truncate_big(arg, UINT8_C(80), false, UINT16_C(80)));
5973}
5974static inline void zig_big_bitCast_f80(void *res, zig_f80 arg, bool res_is_signed, uint16_t res_bits) {
5975 if (res_is_signed) {
5976 zig_big_truncate_i128(res, zig_i128_bitCast_f80(arg), res_is_signed, res_bits);
5977 } else {
5978 zig_big_truncate_u128(res, zig_u128_bitCast_f80(arg), res_is_signed, res_bits);
5979 }
5980}
5981#if zig_has_f128
5982zig_bitCast_float(128, 128, zig_u128, zig_i128)
5983#else
5984static inline zig_f128 zig_f128_bitCast_u128(zig_u128 arg) {
5985 return zig_make_repr_f128(zig_hi_u128(arg), zig_lo_u128(arg));
5986}
5987static inline zig_f128 zig_f128_bitCast_i128(zig_i128 arg) {
5988 return zig_make_repr_f128((uint64_t)zig_hi_i128(arg), zig_lo_i128(arg));
5989}
5990static inline zig_u128 zig_u128_bitCast_f128(zig_f128 arg) {
5991 return zig_make_u128(zig_hi_repr_f128(arg), zig_lo_repr_f128(arg));
5992}
5993static inline zig_i128 zig_i128_bitCast_f128(zig_f128 arg) {
5994 return zig_make_i128((int64_t)zig_hi_repr_f128(arg), zig_lo_repr_f128(arg));
5995}
5996#endif
39065997
3907#define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \5998#define zig_convert_float_00(ResType, operation, ArgType, version) \
3908 zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \5999 zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
3909 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \6000 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType arg); \
6001 return zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
6002 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(arg)
6003#define zig_convert_float_01(ResType, operation, ArgType, version) \
6004 zig_convert_float_00(ResType, operation, ArgType, version)
6005#define zig_convert_float_10(ResType, operation, ArgType, version) \
6006 zig_convert_float_00(ResType, operation, ArgType, version)
6007#define zig_convert_float_11(ResType, operation, ArgType, version) \
6008 return (ResType)arg
6009#define zig_convert_float(res_when, ResType, operation, arg_when, ArgType, version) \
3910 static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \6010 static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \
3911 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \6011 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \
3912 ResType res; \6012 zig_expand_concat(zig_expand_concat(zig_convert_float_, zig_has_##res_when), \
3913 ExternResType extern_res; \6013 zig_has_##arg_when)(ResType, operation, ArgType, version); \
3914 ExternArgType extern_arg; \6014 }
3915 memcpy(&extern_arg, &arg, sizeof(extern_arg)); \6015
3916 extern_res = zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \6016#define zig_convert_floats(SmallType, BigType) \
3917 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(extern_arg); \6017 zig_convert_float(SmallType, zig_##SmallType, trunc, BigType, zig_##BigType, 2) \
3918 memcpy(&res, &extern_res, sizeof(res)); \6018 zig_convert_float(BigType, zig_##BigType, extend, SmallType, zig_##SmallType, 2)
3919 return extern_res; \6019zig_convert_floats(f16, f32)
3920 }6020zig_convert_floats(f16, f64)
3921zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2)6021zig_convert_floats(f16, f80)
3922zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2)6022zig_convert_floats(f16, f128)
3923zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2)6023zig_convert_floats(f32, f64)
3924zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2)6024zig_convert_floats(f32, f80)
3925zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2)6025zig_convert_floats(f32, f128)
3926zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2)6026zig_convert_floats(f64, f80)
3927zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2)6027zig_convert_floats(f64, f128)
3928zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2)6028zig_convert_floats(f80, f128)
3929zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2)6029
3930zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2)6030#define zig_float_negate_builtin_0(w, sb) \
3931zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2)6031 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, sb))
3932zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2)6032#define zig_float_negate_builtin_1(w, sb) -arg
3933zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2)6033#define zig_float_negate_builtin(w, sb) \
3934zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2)
3935zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2)
3936zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2)
3937zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2)
3938zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2)
3939
3940#ifdef __ARM_EABI__
3941
3942zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_d2f(zig_f64);
3943static inline zig_f32 zig_truncdfsf(zig_f64 arg) { return __aeabi_d2f(arg); }
3944
3945zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_f2d(zig_f32);
3946static inline zig_f64 zig_extendsfdf(zig_f32 arg) { return __aeabi_f2d(arg); }
3947
3948#else /* __ARM_EABI__ */
3949
3950zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2)
3951zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2)
3952
3953#endif /* __ARM_EABI__ */
3954
3955#define zig_float_negate_builtin_0(w, c, sb) \
3956 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, c sb))
3957#define zig_float_negate_builtin_1(w, c, sb) -arg
3958#define zig_float_negate_builtin(w, c, sb) \
3959 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \6034 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \
3960 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, c, sb); \6035 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, sb); \
3961 }6036 }
3962zig_float_negate_builtin(16, , UINT16_C(1) << 15 )6037zig_float_negate_builtin(16, UINT16_C(1) << 15)
3963zig_float_negate_builtin(32, , UINT32_C(1) << 31 )6038zig_float_negate_builtin(32, UINT32_C(1) << 31)
3964zig_float_negate_builtin(64, , UINT64_C(1) << 63 )6039zig_float_negate_builtin(64, UINT64_C(1) << 63)
3965zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0)))6040
3966zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))6041#undef zig_float_negate_builtin_0
6042#define zig_float_negate_builtin_0(w, sb) \
6043 zig_make_repr_f##w(zig_mantissa_repr_f##w(arg), zig_xor_u16(zig_exponent_repr_f##w(arg), sb))
6044zig_float_negate_builtin(80, UINT16_C(1) << 15)
6045
6046#undef zig_float_negate_builtin_0
6047#define zig_float_negate_builtin_0(w, sb) \
6048 zig_make_repr_f##w(zig_xor_u64(zig_hi_repr_f##w(arg), sb), zig_lo_repr_f##w(arg))
6049zig_float_negate_builtin(128, UINT64_C(1) << 63)
39676050
3968#define zig_float_less_builtin_0(Type, operation) \6051#define zig_float_less_builtin_0(Type, operation) \
3969 zig_extern int32_t zig_expand_concat(zig_expand_concat(__##operation, \6052 zig_extern zig_FloatCompareResult zig_expand_concat(zig_expand_concat(__##operation, \
3970 zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \6053 zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \
3971 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \6054 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
3972 return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \6055 return (int32_t)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \
3973 }6056 }
3974#define zig_float_less_builtin_1(Type, operation) \6057#define zig_float_less_builtin_1(Type, operation) \
3975 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \6058 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
...@@ -3994,13 +6077,52 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))...@@ -3994,13 +6077,52 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
3994 return lhs operator rhs; \6077 return lhs operator rhs; \
3995 }6078 }
39966079
6080#define zig_float_builtins(w) \
6081 zig_common_float_builtins(w) \
6082 zig_convert_float(f##w, zig_f##w, float, int128, zig_i128, ) \
6083 zig_convert_float(f##w, zig_f##w, floatun, int128, zig_u128, )
3997#define zig_common_float_builtins(w) \6084#define zig_common_float_builtins(w) \
3998 zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \6085 zig_convert_float(always, int32_t, fix, f##w, zig_f##w, ) \
3999 zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \6086 zig_convert_float(always, int64_t, fix, f##w, zig_f##w, ) \
4000 zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \6087 zig_convert_float(int128, zig_i128, fix, f##w, zig_f##w, ) \
4001 zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \6088 zig_convert_float(always, uint32_t, fixuns, f##w, zig_f##w, ) \
4002 zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \6089 zig_convert_float(always, uint64_t, fixuns, f##w, zig_f##w, ) \
4003 zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \6090 zig_convert_float(int128, zig_u128, fixuns, f##w, zig_f##w, ) \
6091 zig_convert_float(f##w, zig_f##w, float, always, int32_t, ) \
6092 zig_convert_float(f##w, zig_f##w, float, always, int64_t, ) \
6093 zig_convert_float(f##w, zig_f##w, floatun, always, uint32_t, ) \
6094 zig_convert_float(f##w, zig_f##w, floatun, always, uint64_t, ) \
6095\
6096 static inline void zig_expand_concat(zig_expand_concat(zig_fix, \
6097 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \
6098 zig_extern void zig_expand_concat(zig_expand_concat(__fix, \
6099 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \
6100 zig_expand_concat(zig_expand_concat(__fix, \
6101 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \
6102 } \
6103\
6104 static inline void zig_expand_concat(zig_expand_concat(zig_fixuns, \
6105 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \
6106 zig_extern void zig_expand_concat(zig_expand_concat(__fixuns, \
6107 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \
6108 zig_expand_concat(zig_expand_concat(__fixuns, \
6109 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \
6110 } \
6111\
6112 static inline zig_f##w zig_expand_concat(zig_floatei, \
6113 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \
6114 zig_extern zig_f##w zig_expand_concat(__floatei, \
6115 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \
6116 return zig_expand_concat(__floatei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \
6117 } \
6118\
6119 static inline zig_f##w zig_expand_concat(zig_floatunei, \
6120 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \
6121 zig_extern zig_f##w zig_expand_concat(__floatunei, \
6122 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \
6123 return zig_expand_concat(__floatunei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \
6124 } \
6125\
4004 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \6126 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \
4005 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \6127 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \
4006 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \6128 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \
...@@ -4031,82 +6153,48 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))...@@ -4031,82 +6153,48 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
4031 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \6153 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \
4032 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \6154 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \
4033\6155\
4034 static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \6156 static inline zig_f##w zig_divTrunc_f##w(zig_f##w lhs, zig_f##w rhs) { \
4035 return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \6157 return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \
4036 } \6158 } \
4037\6159\
4038 static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \6160 static inline zig_f##w zig_divFloor_f##w(zig_f##w lhs, zig_f##w rhs) { \
4039 return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \6161 return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \
4040 } \6162 } \
4041\6163\
4042 static inline zig_f##w zig_div_ceil_f##w(zig_f##w lhs, zig_f##w rhs) { \6164 static inline zig_f##w zig_divCeil_f##w(zig_f##w lhs, zig_f##w rhs) { \
4043 return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \6165 return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \
4044 } \6166 } \
4045\6167\
4046 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \6168 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \
4047 return zig_sub_f##w(lhs, zig_mul_f##w(zig_div_floor_f##w(lhs, rhs), rhs)); \6169 return zig_sub_f##w(lhs, zig_mul_f##w(zig_divFloor_f##w(lhs, rhs), rhs)); \
4048 }6170 }
4049zig_common_float_builtins(16)
4050zig_common_float_builtins(32)
4051zig_common_float_builtins(64)
4052zig_common_float_builtins(80)
4053zig_common_float_builtins(128)
4054
4055#define zig_float_builtins(w) \
4056 zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \
4057 zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \
4058 zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \
4059 zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \
4060 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \
4061 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, )
4062zig_float_builtins(16)6171zig_float_builtins(16)
4063zig_float_builtins(80)
4064zig_float_builtins(128)
4065
4066#ifdef __ARM_EABI__
4067
4068zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_f2iz(zig_f32);
4069static inline int32_t zig_fixsfsi(zig_f32 arg) { return __aeabi_f2iz(arg); }
4070
4071zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_f2uiz(zig_f32);
4072static inline uint32_t zig_fixunssfsi(zig_f32 arg) { return __aeabi_f2uiz(arg); }
4073
4074zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_f2ulz(zig_f32);
4075static inline uint64_t zig_fixunssfdi(zig_f32 arg) { return __aeabi_f2ulz(arg); }
4076
4077zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_i2f(int32_t);
4078static inline zig_f32 zig_floatsisf(int32_t arg) { return __aeabi_i2f(arg); }
4079
4080zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ui2f(uint32_t);
4081static inline zig_f32 zig_floatunsisf(uint32_t arg) { return __aeabi_ui2f(arg); }
4082
4083zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ul2f(uint64_t);
4084static inline zig_f32 zig_floatundisf(uint64_t arg) { return __aeabi_ul2f(arg); }
4085
4086zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_d2iz(zig_f64);
4087static inline int32_t zig_fixdfsi(zig_f64 arg) { return __aeabi_d2iz(arg); }
4088
4089zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_d2uiz(zig_f64);
4090static inline uint32_t zig_fixunsdfsi(zig_f64 arg) { return __aeabi_d2uiz(arg); }
4091
4092zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_d2ulz(zig_f64);
4093static inline uint64_t zig_fixunsdfdi(zig_f64 arg) { return __aeabi_d2ulz(arg); }
4094
4095zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_i2d(int32_t);
4096static inline zig_f64 zig_floatsidf(int32_t arg) { return __aeabi_i2d(arg); }
4097
4098zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ui2d(uint32_t);
4099static inline zig_f64 zig_floatunsidf(uint32_t arg) { return __aeabi_ui2d(arg); }
4100
4101zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ul2d(uint64_t);
4102static inline zig_f64 zig_floatundidf(uint64_t arg) { return __aeabi_ul2d(arg); }
4103
4104#else /* __ARM_EABI__ */
4105
4106zig_float_builtins(32)6172zig_float_builtins(32)
4107zig_float_builtins(64)6173zig_float_builtins(64)
41086174zig_float_builtins(80)
4109#endif /* __ARM_EABI__ */6175#if defined(zig_x86_32)
6176zig_common_float_builtins(128)
6177static inline zig_f128 zig_floattitf(zig_i128 arg) {
6178 extern zig_f128 __floattitf(zig_f128 arg);
6179 return __floattitf(zig_f128_bitCast_i128(arg));
6180}
6181static inline zig_f128 zig_floatuntitf(zig_u128 arg) {
6182 extern zig_f128 __floatuntitf(zig_f128 arg);
6183 return __floatuntitf(zig_f128_bitCast_u128(arg));
6184}
6185#elif defined(zig_x86_64) && defined(zig_windows)
6186zig_common_float_builtins(128)
6187static inline zig_f128 zig_floattitf(zig_i128 arg) {
6188 extern zig_f128 __floattitf(zig_i128 arg);
6189 return __floattitf(arg);
6190}
6191static inline zig_f128 zig_floatuntitf(zig_u128 arg) {
6192 extern zig_f128 __floatuntitf(uint64_t arg_lo, uint64_t arg_hi);
6193 return __floatuntitf(zig_lo_u128(arg), zig_hi_u128(arg));
6194}
6195#else
6196zig_float_builtins(128)
6197#endif
41106198
4111/* ============================ Atomics Support ============================= */6199/* ============================ Atomics Support ============================= */
41126200
...@@ -4410,19 +6498,19 @@ typedef int zig_memory_order;...@@ -4410,19 +6498,19 @@ typedef int zig_memory_order;
4410 } \6498 } \
4411 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \6499 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \
4412 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \6500 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \
4413 } \6501 } \
4414 static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \6502 static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \
4415 return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6503 return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4416 } \6504 } \
4417 static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \6505 static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \
4418 Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6506 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4419 _ReadWriteBarrier(); \6507 _ReadWriteBarrier(); \
4420 return val; \6508 return value; \
4421 } \6509 } \
4422 static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \6510 static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \
4423 Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6511 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4424 _ReadWriteBarrier(); \6512 _ReadWriteBarrier(); \
4425 return val; \6513 return value; \
4426 }6514 }
44276515
4428zig_msvc_atomics( u8, uint8_t, char, 8, 8)6516zig_msvc_atomics( u8, uint8_t, char, 8, 8)
...@@ -4465,14 +6553,14 @@ zig_msvc_atomics(i64, int64_t, __int64, 64, 64)...@@ -4465,14 +6553,14 @@ zig_msvc_atomics(i64, int64_t, __int64, 64, 64)
4465 zig_##Type result; \6553 zig_##Type result; \
4466 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6554 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4467 _ReadWriteBarrier(); \6555 _ReadWriteBarrier(); \
4468 memcpy(&result, &initial, sizeof(result)); \6556 memcpy(&result, &initial, sizeof(result)); \
4469 return result; \6557 return result; \
4470 } \6558 } \
4471 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \6559 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \
4472 zig_##Type result; \6560 zig_##Type result; \
4473 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6561 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4474 _ReadWriteBarrier(); \6562 _ReadWriteBarrier(); \
4475 memcpy(&result, &initial, sizeof(result)); \6563 memcpy(&result, &initial, sizeof(result)); \
4476 return result; \6564 return result; \
4477 }6565 }
44786566
...@@ -4502,9 +6590,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volat...@@ -4502,9 +6590,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volat
4502}6590}
45036591
4504static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) {6592static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) {
4505 void* val = (void*)__iso_volatile_load32(obj);6593 void* value = (void*)__iso_volatile_load32(obj);
4506 _ReadWriteBarrier();6594 _ReadWriteBarrier();
4507 return val;6595 return value;
4508}6596}
45096597
4510static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) {6598static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) {
...@@ -4532,9 +6620,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volat...@@ -4532,9 +6620,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volat
4532}6620}
45336621
4534static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) {6622static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) {
4535 void* val = (void*)__iso_volatile_load64(obj);6623 void* value = (void*)__iso_volatile_load64(obj);
4536 _ReadWriteBarrier();6624 _ReadWriteBarrier();
4537 return val;6625 return value;
4538}6626}
45396627
4540static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) {6628static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) {
src/Compilation.zig+3
...@@ -2134,6 +2134,9 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2134,6 +2134,9 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2134 comp.config.any_fuzz = any_fuzz;2134 comp.config.any_fuzz = any_fuzz;
21352135
2136 if (opt_zcu) |zcu| {2136 if (opt_zcu) |zcu| {
2137 // Finish initializing the `zcu` after the fields on `comp` have been initialized.
2138 zcu.initAfterCompilation();
2139
2137 // Populate `zcu.module_roots`.2140 // Populate `zcu.module_roots`.
2138 const active = zcu.acquire();2141 const active = zcu.acquire();
2139 defer active.release();2142 defer active.release();
src/InternPool.zig+27-27
...@@ -4193,7 +4193,7 @@ pub const Index = enum(u32) {...@@ -4193,7 +4193,7 @@ pub const Index = enum(u32) {
4193 };4193 };
4194 }4194 }
41954195
4196 /// This function is used in the debugger pretty formatters in tools/ to fetch the4196 /// This function is used in the debugger pretty formatters in lib/lldb/ to fetch the
4197 /// Tag to encoding mapping to facilitate fancy debug printing for this type.4197 /// Tag to encoding mapping to facilitate fancy debug printing for this type.
4198 fn dbHelper(self: *Index, tag_to_encoding_map: *struct {4198 fn dbHelper(self: *Index, tag_to_encoding_map: *struct {
4199 const DataIsIndex = struct { data: Index };4199 const DataIsIndex = struct { data: Index };
...@@ -4219,26 +4219,17 @@ pub const Index = enum(u32) {...@@ -4219,26 +4219,17 @@ pub const Index = enum(u32) {
4219 type_inferred_error_set: DataIsIndex,4219 type_inferred_error_set: DataIsIndex,
4220 simple_type: void,4220 simple_type: void,
4221 type_function: struct {4221 type_function: struct {
4222 const @"data.flags.has_comptime_bits" = opaque {};
4223 const @"data.flags.has_noalias_bits" = opaque {};
4224 const @"data.flags.cc.extraLen()" = opaque {};
4225 const @"data.params_len" = opaque {};4222 const @"data.params_len" = opaque {};
4226 data: *Tag.TypeFunction,4223 data: *Tag.TypeFunction,
4227 @"trailing.comptime_bits.len": *@"data.flags.has_comptime_bits",
4228 @"trailing.noalias_bits.len": *@"data.flags.has_noalias_bits",
4229 @"trailing.cc_bits.len": *@"data.flags.cc.extraLen()",
4230 @"trailing.param_types.len": *@"data.params_len",4224 @"trailing.param_types.len": *@"data.params_len",
4231 trailing: struct { comptime_bits: []u32, noalias_bits: []u32, cc_bits: []u32, param_types: []Index },4225 trailing: struct { param_types: []Index },
4232 },4226 },
4233 type_tuple: struct {4227 type_tuple: struct {
4234 const @"data.fields_len" = opaque {};4228 const @"data.fields_len" = opaque {};
4235 data: *TypeTuple,4229 data: *TypeTuple,
4236 @"trailing.types.len": *@"data.fields_len",4230 @"trailing.types.len": *@"data.fields_len",
4237 @"trailing.values.len": *@"data.fields_len",4231 @"trailing.values.len": *@"data.fields_len",
4238 trailing: struct {4232 trailing: struct { types: []Index, values: []Index },
4239 types: []Index,
4240 values: []Index,
4241 },
4242 },4233 },
42434234
4244 type_struct: struct { data: *Tag.TypeStruct },4235 type_struct: struct { data: *Tag.TypeStruct },
...@@ -4350,7 +4341,7 @@ pub const Index = enum(u32) {...@@ -4350,7 +4341,7 @@ pub const Index = enum(u32) {
4350 const encoding = @field(Tag.encodings, tag_name);4341 const encoding = @field(Tag.encodings, tag_name);
4351 if (@hasField(@TypeOf(encoding), "trailing")) {4342 if (@hasField(@TypeOf(encoding), "trailing")) {
4352 const trailing_info = @typeInfo(encoding.trailing).@"struct";4343 const trailing_info = @typeInfo(encoding.trailing).@"struct";
4353 for (trailing_info.field_names, trailing_info.field_types) |field_name, field_type| {4344 for (trailing_info.field_names, trailing_info.field_types) |trailing_field_name, trailing_field_type| {
4354 struct {4345 struct {
4355 fn checkConfig(name: []const u8) void {4346 fn checkConfig(name: []const u8) void {
4356 if (!@hasField(@TypeOf(encoding.config), name)) @compileError("missing field: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ ".config.@\"" ++ name ++ "\"");4347 if (!@hasField(@TypeOf(encoding.config), name)) @compileError("missing field: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ ".config.@\"" ++ name ++ "\"");
...@@ -4359,22 +4350,30 @@ pub const Index = enum(u32) {...@@ -4359,22 +4350,30 @@ pub const Index = enum(u32) {
4359 }4350 }
4360 fn checkField(name: []const u8, Type: type) void {4351 fn checkField(name: []const u8, Type: type) void {
4361 switch (@typeInfo(Type)) {4352 switch (@typeInfo(Type)) {
4362 .int => {},4353 .int, .@"enum" => return,
4363 .@"enum" => {},4354 .@"struct" => |info| switch (info.layout) {
4364 .@"struct" => |info| assert(info.layout == .@"packed"),4355 .auto => unreachable,
4356 .@"extern" => {
4357 for (info.field_names, info.field_types) |field_name, field_type| checkField(name ++ "." ++ field_name, field_type);
4358 return;
4359 },
4360 .@"packed" => return,
4361 },
4365 .optional => |info| {4362 .optional => |info| {
4366 checkConfig(name ++ ".?");4363 checkConfig(name ++ ".?");
4367 checkField(name ++ ".?", info.child);4364 checkField(name ++ ".?", info.child);
4365 return;
4368 },4366 },
4369 .pointer => |info| {4367 .pointer => |info| if (info.size == .slice) {
4370 assert(info.size == .slice);
4371 checkConfig(name ++ ".len");4368 checkConfig(name ++ ".len");
4372 checkField(name ++ "[0]", info.child);4369 checkField(name ++ "[0]", info.child);
4370 return;
4373 },4371 },
4374 else => @compileError("unsupported type: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ "." ++ name ++ ": " ++ @typeName(Type)),4372 else => {},
4375 }4373 }
4374 @compileError("unsupported type: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ "." ++ name ++ ": " ++ @typeName(Type));
4376 }4375 }
4377 }.checkField("trailing." ++ field_name, field_type);4376 }.checkField("trailing." ++ trailing_field_name, trailing_field_type);
4378 }4377 }
4379 }4378 }
4380 },4379 },
...@@ -5186,17 +5185,18 @@ pub const Tag = enum(u8) {...@@ -5186,17 +5185,18 @@ pub const Tag = enum(u8) {
5186 .trailing = struct {5185 .trailing = struct {
5187 param_comptime_bits: ?[]u32,5186 param_comptime_bits: ?[]u32,
5188 param_noalias_bits: ?[]u32,5187 param_noalias_bits: ?[]u32,
5189 param_cc_bits: ?[]u32,5188 spirv_kernel_options: ?extern struct { x: u32, y: u32, z: u32 },
5190 param_type: []Index,5189 spirv_mesh_options: ?extern struct { max_primitives: u32, max_vertices: u32 },
5190 param_types: []Index,
5191 },5191 },
5192 .config = .{5192 .config = .{
5193 .@"trailing.param_comptime_bits.?" = .@"payload.flags.has_comptime_bits",5193 .@"trailing.param_comptime_bits.?" = .@"payload.flags.has_comptime_bits",
5194 .@"trailing.param_comptime_bits.?.len" = .@"(payload.params_len + 31) / 32",5194 .@"trailing.param_comptime_bits.?.len" = .@"(payload.params_len + 31) / 32",
5195 .@"trailing.param_noalias_bits.?" = .@"payload.flags.has_noalias_bits",5195 .@"trailing.param_noalias_bits.?" = .@"payload.flags.has_noalias_bits",
5196 .@"trailing.param_noalias_bits.?.len" = .@"(payload.params_len + 31) / 32",5196 .@"trailing.param_noalias_bits.?.len" = .@"(payload.params_len + 31) / 32",
5197 .@"trailing.param_cc_bits.?" = .@"payload.flags.cc.extraLen() != 0",5197 .@"trailing.spirv_kernel_options.?" = .@"payload.flags.cc.tag == .spirv_kernel or payload.flags.cc.tag == .spirv_task",
5198 .@"trailing.param_cc_bits.?.len" = .@"payload.flags.cc.extraLen()",5198 .@"trailing.spirv_mesh_options.?" = .@"payload.flags.cc.tag == .spirv_mesh",
5199 .@"trailing.param_type.len" = .@"payload.params_len",5199 .@"trailing.param_types.len" = .@"payload.params_len",
5200 },5200 },
5201 },5201 },
52025202
...@@ -5225,7 +5225,7 @@ pub const Tag = enum(u8) {...@@ -5225,7 +5225,7 @@ pub const Tag = enum(u8) {
5225 .@"trailing.field_defaults.?" = .@"payload.flags.any_field_defaults",5225 .@"trailing.field_defaults.?" = .@"payload.flags.any_field_defaults",
5226 .@"trailing.field_defaults.?.len" = .@"payload.fields_len",5226 .@"trailing.field_defaults.?.len" = .@"payload.fields_len",
5227 .@"trailing.field_aligns.?" = .@"payload.flags.any_field_aligns",5227 .@"trailing.field_aligns.?" = .@"payload.flags.any_field_aligns",
5228 .@"trailing.field_aligns.?.len" = .@"payload.fields_len",5228 .@"trailing.field_aligns.?.len" = .@"(payload.fields_len + 3) / 4",
5229 .@"trailing.field_is_comptime_bits.?" = .@"payload.flags.any_comptime_fields",5229 .@"trailing.field_is_comptime_bits.?" = .@"payload.flags.any_comptime_fields",
5230 .@"trailing.field_is_comptime_bits.?.len" = .@"(payload.fields_len + 31) / 32",5230 .@"trailing.field_is_comptime_bits.?.len" = .@"(payload.fields_len + 31) / 32",
5231 .@"trailing.field_runtime_order.?" = .@"payload.flags.layout == .auto",5231 .@"trailing.field_runtime_order.?" = .@"payload.flags.layout == .auto",
...@@ -5254,7 +5254,7 @@ pub const Tag = enum(u8) {...@@ -5254,7 +5254,7 @@ pub const Tag = enum(u8) {
5254 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",5254 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",
5255 .@"trailing.field_types.len" = .@"payload.fields_len",5255 .@"trailing.field_types.len" = .@"payload.fields_len",
5256 .@"trailing.field_aligns.?" = .@"payloads.flags.any_field_aligns",5256 .@"trailing.field_aligns.?" = .@"payloads.flags.any_field_aligns",
5257 .@"trailing.field_aligns.?.len" = .@"payload.fields_len",5257 .@"trailing.field_aligns.?.len" = .@"(payload.fields_len + 3) / 4",
5258 },5258 },
5259 },5259 },
5260 .type_union_packed_auto = union_packed_encoding,5260 .type_union_packed_auto = union_packed_encoding,
src/Sema.zig+6-5
...@@ -8501,6 +8501,7 @@ const calling_conventions_supporting_var_args = [_]std.lang.CallingConvention.Ta...@@ -8501,6 +8501,7 @@ const calling_conventions_supporting_var_args = [_]std.lang.CallingConvention.Ta
8501 .x86_64_win,8501 .x86_64_win,
8502 .x86_sysv,8502 .x86_sysv,
8503 .x86_win,8503 .x86_win,
8504 .x86_mingw,
8504 .aarch64_aapcs,8505 .aarch64_aapcs,
8505 .aarch64_aapcs_darwin,8506 .aarch64_aapcs_darwin,
8506 .aarch64_aapcs_win,8507 .aarch64_aapcs_win,
...@@ -25675,7 +25676,6 @@ pub fn explainWhyTypeIsNotExtern(...@@ -25675,7 +25676,6 @@ pub fn explainWhyTypeIsNotExtern(
2567525676
25676 .@"opaque",25677 .@"opaque",
25677 .bool,25678 .bool,
25678 .float,
25679 .@"anyframe",25679 .@"anyframe",
25680 => unreachable, // these *are* allowed25680 => unreachable, // these *are* allowed
2568125681
...@@ -25684,6 +25684,7 @@ pub fn explainWhyTypeIsNotExtern(...@@ -25684,6 +25684,7 @@ pub fn explainWhyTypeIsNotExtern(
25684 try sema.errNote(src_loc, msg, "SPIR-V runtime arrays must be the last field of an extern struct", .{});25684 try sema.errNote(src_loc, msg, "SPIR-V runtime arrays must be the last field of an extern struct", .{});
25685 },25685 },
2568625686
25687 .float => try sema.errNote(src_loc, msg, "'{f}' is not extern compatible on this target", .{ty.fmt(pt)}),
25687 .pointer => if (ty.isSlice(zcu)) {25688 .pointer => if (ty.isSlice(zcu)) {
25688 try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});25689 try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
25689 } else {25690 } else {
...@@ -29657,7 +29658,7 @@ fn coerceVarArgParam(...@@ -29657,7 +29658,7 @@ fn coerceVarArgParam(
29657 .array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),29658 .array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
29658 .float => float: {29659 .float => float: {
29659 const target = zcu.getTarget();29660 const target = zcu.getTarget();
29660 const double_bits = target.cTypeBitSize(.double);29661 const double_bits = target.cTypeBitSize(.double) orelse break :float inst;
29661 const inst_bits = uncasted_ty.floatBits(target);29662 const inst_bits = uncasted_ty.floatBits(target);
29662 if (inst_bits >= double_bits) break :float inst;29663 if (inst_bits >= double_bits) break :float inst;
29663 switch (double_bits) {29664 switch (double_bits) {
...@@ -29673,21 +29674,21 @@ fn coerceVarArgParam(...@@ -29673,21 +29674,21 @@ fn coerceVarArgParam(
29673 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {29674 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {
29674 .signed => .int,29675 .signed => .int,
29675 .unsigned => .uint,29676 .unsigned => .uint,
29676 })) break :int try sema.coerce(block, switch (uncasted_info.signedness) {29677 }) orelse break :int inst) break :int try sema.coerce(block, switch (uncasted_info.signedness) {
29677 .signed => .c_int,29678 .signed => .c_int,
29678 .unsigned => .c_uint,29679 .unsigned => .c_uint,
29679 }, inst, inst_src);29680 }, inst, inst_src);
29680 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {29681 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {
29681 .signed => .long,29682 .signed => .long,
29682 .unsigned => .ulong,29683 .unsigned => .ulong,
29683 })) break :int try sema.coerce(block, switch (uncasted_info.signedness) {29684 }).?) break :int try sema.coerce(block, switch (uncasted_info.signedness) {
29684 .signed => .c_long,29685 .signed => .c_long,
29685 .unsigned => .c_ulong,29686 .unsigned => .c_ulong,
29686 }, inst, inst_src);29687 }, inst, inst_src);
29687 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {29688 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {
29688 .signed => .longlong,29689 .signed => .longlong,
29689 .unsigned => .ulonglong,29690 .unsigned => .ulonglong,
29690 })) break :int try sema.coerce(block, switch (uncasted_info.signedness) {29691 }).?) break :int try sema.coerce(block, switch (uncasted_info.signedness) {
29691 .signed => .c_longlong,29692 .signed => .c_longlong,
29692 .unsigned => .c_ulonglong,29693 .unsigned => .c_ulonglong,
29693 }, inst, inst_src);29694 }, inst, inst_src);
src/Sema/type_resolution.zig+1-1
...@@ -364,7 +364,7 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {...@@ -364,7 +364,7 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
364 const a = struct_obj.field_aligns.get(ip)[field_idx];364 const a = struct_obj.field_aligns.get(ip)[field_idx];
365 if (a != .none) break :a a;365 if (a != .none) break :a a;
366 }366 }
367 break :a field_ty.defaultStructFieldAlignment(struct_obj.layout, zcu);367 break :a field_ty.abiAlignment(zcu);
368 };368 };
369 align_out.* = field_align;369 align_out.* = field_align;
370 if (struct_obj.field_is_comptime_bits.get(ip, field_idx)) {370 if (struct_obj.field_is_comptime_bits.get(ip, field_idx)) {
src/Type.zig+107-86
...@@ -957,12 +957,27 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {...@@ -957,12 +957,27 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {
957 if (vector_type.len == 0) return .@"1";957 if (vector_type.len == 0) return .@"1";
958 switch (zcu.comp.getZigBackend()) {958 switch (zcu.comp.getZigBackend()) {
959 else => {959 else => {
960 const elem_bits: u32 = @intCast(Type.fromInterned(vector_type.child).bitSize(zcu));960 const elem_ty: Type = .fromInterned(vector_type.child);
961 switch (if (elem_ty.isRuntimeFloat())
962 std.zig.target.compilerRtFloatAbi(target, elem_ty.floatBits(target))
963 else
964 .hard) {
965 .hard => {},
966 .soft => return elem_ty.abiAlignment(zcu),
967 }
968 const elem_bits: u32 = @intCast(elem_ty.bitSize(zcu));
961 if (elem_bits == 0) return .@"1";969 if (elem_bits == 0) return .@"1";
962 const bytes = ((elem_bits * vector_type.len) + 7) / 8;970 const bytes = ((elem_bits * vector_type.len) + 7) / 8;
963 return .fromByteUnits(std.math.ceilPowerOfTwoAssert(u32, bytes));971 const arch = target.cpu.arch;
972 return .fromByteUnits(std.math.ceilPowerOfTwoAssert(
973 u32,
974 if (arch.isArm() or arch.isAARCH64() or arch == .s390x)
975 @min(bytes, target.stackAlignment())
976 else
977 bytes,
978 ));
964 },979 },
965 .stage2_c, .stage2_wasm => return Type.fromInterned(vector_type.child).defaultStructFieldAlignment(.auto, zcu),980 .stage2_c, .stage2_wasm => return Type.fromInterned(vector_type.child).abiAlignment(zcu),
966 .stage2_x86_64 => {981 .stage2_x86_64 => {
967 if (vector_type.child == .bool_type) {982 if (vector_type.child == .bool_type) {
968 if (vector_type.len > 256 and target.cpu.has(.x86, .avx512f)) return .@"64";983 if (vector_type.len > 256 and target.cpu.has(.x86, .avx512f)) return .@"64";
...@@ -1018,19 +1033,33 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {...@@ -1018,19 +1033,33 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {
1018 .c_ulonglong => cTypeAlign(target, .ulonglong),1033 .c_ulonglong => cTypeAlign(target, .ulonglong),
1019 .c_longdouble => cTypeAlign(target, .longdouble),1034 .c_longdouble => cTypeAlign(target, .longdouble),
10201035
1021 .f16 => .@"2",1036 .f16 => .fromByteUnits(std.zig.target.intAlignment(target, 16)), // repr: u16
1022 .f32 => if (target.os.tag == .opengl) .@"4" else cTypeAlign(target, .float),1037 .f32 => if (target.cTypeBitSize(.float) == 32)
1023 .f64 => if (target.os.tag == .opengl) .@"8" else switch (target.cTypeBitSize(.double)) {1038 cTypeAlign(target, .float) // abi: c_float,
1024 64 => cTypeAlign(target, .double),1039 else
1025 else => .@"8",1040 .fromByteUnits(std.zig.target.intAlignment(target, 32)), // repr: u32,
1026 },1041 .f64 => if (target.cTypeBitSize(.double) == 64)
1027 .f80 => switch (target.cTypeBitSize(.longdouble)) {1042 cTypeAlign(target, .double) // abi: c_double,
1028 80 => cTypeAlign(target, .longdouble),1043 else
1029 else => Type.u80.abiAlignment(zcu),1044 .fromByteUnits(std.zig.target.intAlignment(target, 64)), // repr: u64,
1030 },1045 .f80 => if (target.cTypeBitSize(.longdouble) == 80)
1031 .f128 => switch (target.cTypeBitSize(.longdouble)) {1046 cTypeAlign(target, .longdouble) // abi: c_longdouble,
1032 128 => cTypeAlign(target, .longdouble),1047 else
1033 else => .@"16",1048 .fromByteUnits(switch (std.zig.target.compilerRtFloatAbi(target, 80)) {
1049 .hard => std.zig.target.intAlignment(target, 80), // repr: u80,
1050 .soft => @max(
1051 std.zig.target.intAlignment(target, 64), // mantissa: u64,
1052 std.zig.target.intAlignment(target, 16), // exponent: u16,
1053 ),
1054 }),
1055 .f128 => if (target.cTypeBitSize(.longdouble) == 128)
1056 cTypeAlign(target, .longdouble) // abi: c_longdouble,
1057 else switch (std.zig.target.compilerRtFloatAbi(target, 128)) {
1058 .hard => if (target.cpu.arch.isX86())
1059 .@"16" // abi: c___float128,
1060 else
1061 .fromByteUnits(std.zig.target.intAlignment(target, 128)), // repr: u128,
1062 .soft => .fromByteUnits(std.zig.target.intAlignment(target, 64)), // lo: u64, hi: u64,
1034 },1063 },
10351064
1036 .generic_poison => unreachable,1065 .generic_poison => unreachable,
...@@ -1111,7 +1140,13 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {...@@ -1111,7 +1140,13 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
1111 .vector_type => |vec| {1140 .vector_type => |vec| {
1112 const elem_ty: Type = .fromInterned(vec.child);1141 const elem_ty: Type = .fromInterned(vec.child);
1113 const bytes = switch (zcu.comp.getZigBackend()) {1142 const bytes = switch (zcu.comp.getZigBackend()) {
1114 else => @divCeil(vec.len * elem_ty.bitSize(zcu), 8),1143 else => switch (if (elem_ty.isRuntimeFloat())
1144 std.zig.target.compilerRtFloatAbi(target, elem_ty.floatBits(target))
1145 else
1146 .hard) {
1147 .hard => @divCeil(vec.len * elem_ty.bitSize(zcu), 8),
1148 .soft => vec.len * elem_ty.abiSize(zcu),
1149 },
1115 .stage2_c, .stage2_wasm => vec.len * elem_ty.abiSize(zcu),1150 .stage2_c, .stage2_wasm => vec.len * elem_ty.abiSize(zcu),
1116 .stage2_x86_64 => switch (elem_ty.toIntern()) {1151 .stage2_x86_64 => switch (elem_ty.toIntern()) {
1117 .bool_type => @divCeil(vec.len, 8),1152 .bool_type => @divCeil(vec.len, 8),
...@@ -1167,25 +1202,44 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {...@@ -1167,25 +1202,44 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
1167 .anyerror, .adhoc_inferred_error_set => errorAbiSize(zcu),1202 .anyerror, .adhoc_inferred_error_set => errorAbiSize(zcu),
1168 .usize, .isize => ptrAbiSize(target),1203 .usize, .isize => ptrAbiSize(target),
11691204
1170 .c_char => target.cTypeByteSize(.char),1205 .c_char => target.cTypeByteSize(.char).?,
1171 .c_short => target.cTypeByteSize(.short),1206 .c_short => target.cTypeByteSize(.short).?,
1172 .c_ushort => target.cTypeByteSize(.ushort),1207 .c_ushort => target.cTypeByteSize(.ushort).?,
1173 .c_int => target.cTypeByteSize(.int),1208 .c_int => target.cTypeByteSize(.int).?,
1174 .c_uint => target.cTypeByteSize(.uint),1209 .c_uint => target.cTypeByteSize(.uint).?,
1175 .c_long => target.cTypeByteSize(.long),1210 .c_long => target.cTypeByteSize(.long).?,
1176 .c_ulong => target.cTypeByteSize(.ulong),1211 .c_ulong => target.cTypeByteSize(.ulong).?,
1177 .c_longlong => target.cTypeByteSize(.longlong),1212 .c_longlong => target.cTypeByteSize(.longlong).?,
1178 .c_ulonglong => target.cTypeByteSize(.ulonglong),1213 .c_ulonglong => target.cTypeByteSize(.ulonglong).?,
1179 .c_longdouble => target.cTypeByteSize(.longdouble),1214 .c_longdouble => target.cTypeByteSize(.longdouble).?,
11801215
1181 .f16 => 2,1216 .f16 => std.zig.target.intByteSize(target, 16), // repr: u16
1182 .f32 => 4,1217 .f32 => if (target.cTypeBitSize(.float) == 32)
1183 .f64 => 8,1218 target.cTypeByteSize(.float).? // abi: c_float,
1184 .f80 => switch (target.cTypeBitSize(.longdouble)) {1219 else
1185 80 => target.cTypeByteSize(.longdouble),1220 std.zig.target.intByteSize(target, 32), // repr: u32,
1186 else => Type.u80.abiSize(zcu),1221 .f64 => if (target.cTypeBitSize(.double) == 64)
1222 target.cTypeByteSize(.double).? // abi: c_double,
1223 else
1224 std.zig.target.intByteSize(target, 64), // repr: u64,
1225 .f80 => if (target.cTypeBitSize(.longdouble) == 80)
1226 target.cTypeByteSize(.longdouble).? // abi: c_longdouble,
1227 else switch (std.zig.target.compilerRtFloatAbi(target, 80)) {
1228 .hard => std.zig.target.intByteSize(target, 80), // repr: u80,
1229 .soft => ty.abiAlignment(zcu).forward(
1230 std.zig.target.intByteSize(target, 64) + // mantissa: u64,
1231 std.zig.target.intByteSize(target, 16), // exponent: u16
1232 ),
1233 },
1234 .f128 => if (target.cTypeBitSize(.longdouble) == 128)
1235 target.cTypeByteSize(.longdouble).? // abi: c_longdouble,
1236 else switch (std.zig.target.compilerRtFloatAbi(target, 128)) {
1237 .hard => if (target.cpu.arch.isX86())
1238 16 // abi: c___float128,
1239 else
1240 std.zig.target.intByteSize(target, 128), // repr: u128,
1241 .soft => std.zig.target.intByteSize(target, 64) * 2, // lo: u64, hi: u64,
1187 },1242 },
1188 .f128 => 16,
11891243
1190 .anyopaque => unreachable,1244 .anyopaque => unreachable,
1191 .generic_poison => unreachable,1245 .generic_poison => unreachable,
...@@ -1733,7 +1787,7 @@ pub fn isInt(self: Type, zcu: *const Zcu) bool {...@@ -1733,7 +1787,7 @@ pub fn isInt(self: Type, zcu: *const Zcu) bool {
1733/// Returns true if and only if the type is a fixed-width, signed integer.1787/// Returns true if and only if the type is a fixed-width, signed integer.
1734pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool {1788pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool {
1735 return switch (ty.toIntern()) {1789 return switch (ty.toIntern()) {
1736 .c_char_type => zcu.getTarget().cCharSignedness() == .signed,1790 .c_char_type => zcu.getTarget().cCharSignedness().? == .signed,
1737 .isize_type, .c_short_type, .c_int_type, .c_long_type, .c_longlong_type => true,1791 .isize_type, .c_short_type, .c_int_type, .c_long_type, .c_longlong_type => true,
1738 else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) {1792 else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1739 .int_type => |int_type| int_type.signedness == .signed,1793 .int_type => |int_type| int_type.signedness == .signed,
...@@ -1745,7 +1799,7 @@ pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool {...@@ -1745,7 +1799,7 @@ pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool {
1745/// Returns true if and only if the type is a fixed-width, unsigned integer.1799/// Returns true if and only if the type is a fixed-width, unsigned integer.
1746pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool {1800pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool {
1747 return switch (ty.toIntern()) {1801 return switch (ty.toIntern()) {
1748 .c_char_type => zcu.getTarget().cCharSignedness() == .unsigned,1802 .c_char_type => zcu.getTarget().cCharSignedness().? == .unsigned,
1749 .usize_type, .c_ushort_type, .c_uint_type, .c_ulong_type, .c_ulonglong_type => true,1803 .usize_type, .c_ushort_type, .c_uint_type, .c_ulong_type, .c_ulonglong_type => true,
1750 else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) {1804 else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1751 .int_type => |int_type| int_type.signedness == .unsigned,1805 .int_type => |int_type| int_type.signedness == .unsigned,
...@@ -1776,15 +1830,15 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {...@@ -1776,15 +1830,15 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
1776 },1830 },
1777 .usize_type => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() },1831 .usize_type => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() },
1778 .isize_type => return .{ .signedness = .signed, .bits = target.ptrBitWidth() },1832 .isize_type => return .{ .signedness = .signed, .bits = target.ptrBitWidth() },
1779 .c_char_type => return .{ .signedness = zcu.getTarget().cCharSignedness(), .bits = target.cTypeBitSize(.char) },1833 .c_char_type => return .{ .signedness = target.cCharSignedness().?, .bits = target.cTypeBitSize(.char).? },
1780 .c_short_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.short) },1834 .c_short_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.short).? },
1781 .c_ushort_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ushort) },1835 .c_ushort_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ushort).? },
1782 .c_int_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.int) },1836 .c_int_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.int).? },
1783 .c_uint_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.uint) },1837 .c_uint_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.uint).? },
1784 .c_long_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.long) },1838 .c_long_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.long).? },
1785 .c_ulong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulong) },1839 .c_ulong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulong).? },
1786 .c_longlong_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.longlong) },1840 .c_longlong_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.longlong).? },
1787 .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulonglong) },1841 .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulonglong).? },
1788 else => switch (ip.indexToKey(ty.toIntern())) {1842 else => switch (ip.indexToKey(ty.toIntern())) {
1789 .int_type => |int_type| return int_type,1843 .int_type => |int_type| return int_type,
1790 .struct_type => {1844 .struct_type => {
...@@ -1882,7 +1936,7 @@ pub fn floatBits(ty: Type, target: *const Target) u16 {...@@ -1882,7 +1936,7 @@ pub fn floatBits(ty: Type, target: *const Target) u16 {
1882 .f64_type => 64,1936 .f64_type => 64,
1883 .f80_type => 80,1937 .f80_type => 80,
1884 .f128_type, .comptime_float_type => 128,1938 .f128_type, .comptime_float_type => 128,
1885 .c_longdouble_type => target.cTypeBitSize(.longdouble),1939 .c_longdouble_type => target.cTypeBitSize(.longdouble).?,
18861940
1887 else => unreachable,1941 else => unreachable,
1888 };1942 };
...@@ -2147,13 +2201,6 @@ pub fn isVector(ty: Type, zcu: *const Zcu) bool {...@@ -2147,13 +2201,6 @@ pub fn isVector(ty: Type, zcu: *const Zcu) bool {
2147 return ty.zigTypeTag(zcu) == .vector;2201 return ty.zigTypeTag(zcu) == .vector;
2148}2202}
21492203
2150/// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len.
2151pub fn totalVectorBits(ty: Type, zcu: *Zcu) u64 {
2152 if (!ty.isVector(zcu)) return 0;
2153 const v = zcu.intern_pool.indexToKey(ty.toIntern()).vector_type;
2154 return v.len * Type.fromInterned(v.child).bitSize(zcu);
2155}
2156
2157pub fn isArrayOrVector(ty: Type, zcu: *const Zcu) bool {2204pub fn isArrayOrVector(ty: Type, zcu: *const Zcu) bool {
2158 return switch (ty.zigTypeTag(zcu)) {2205 return switch (ty.zigTypeTag(zcu)) {
2159 .array, .vector => true,2206 .array, .vector => true,
...@@ -2416,34 +2463,6 @@ pub fn explicitFieldAlignment(ty: Type, index: usize, zcu: *const Zcu) Alignment...@@ -2416,34 +2463,6 @@ pub fn explicitFieldAlignment(ty: Type, index: usize, zcu: *const Zcu) Alignment
2416 };2463 };
2417}2464}
24182465
2419/// Returns the alignment a struct field of type `field_ty` will be given if no alignment is
2420/// explicitly specified. However, in an `extern struct`, a higher alignment may be available due
2421/// to the struct's full layout (i.e. a field might coincidentally be more aligned).
2422///
2423/// Asserts that the layout of `field_ty` is resolved. Asserts that `layout` is not `.@"packed"`.
2424pub fn defaultStructFieldAlignment(
2425 field_ty: Type,
2426 layout: std.lang.Type.ContainerLayout,
2427 zcu: *const Zcu,
2428) Alignment {
2429 const overalign_big_int = switch (layout) {
2430 .@"packed" => unreachable,
2431 .auto => zcu.getTarget().ofmt == .c,
2432 .@"extern" => true,
2433 };
2434 const abi_align = field_ty.abiAlignment(zcu);
2435 assert(abi_align != .none);
2436 // We check for anything over 64 here, because the C backend will lower e.g. u64 to a 128-bit
2437 // integer, which has 16-byte alignment.
2438 if (overalign_big_int and
2439 ((field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits > 64) or
2440 (field_ty.toIntern() == .f80_type and zcu.getTarget().cTypeBitSize(.longdouble) != 80)))
2441 {
2442 return abi_align.maxStrict(if (zcu.getTarget().cpu.arch == .s390x) .@"8" else .@"16");
2443 }
2444 return abi_align;
2445}
2446
2447pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) ?Value {2466pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) ?Value {
2448 const ip = &zcu.intern_pool;2467 const ip = &zcu.intern_pool;
2449 switch (ip.indexToKey(ty.toIntern())) {2468 switch (ip.indexToKey(ty.toIntern())) {
...@@ -2961,8 +2980,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator...@@ -2961,8 +2980,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator
2961 }2980 }
2962 const actual_field_align = switch (field_align) {2981 const actual_field_align = switch (field_align) {
2963 .none => switch (ip.indexToKey(aggregate_ty.toIntern())) {2982 .none => switch (ip.indexToKey(aggregate_ty.toIntern())) {
2964 .tuple_type, .union_type => field_ty.abiAlignment(zcu),2983 .struct_type, .tuple_type, .union_type => field_ty.abiAlignment(zcu),
2965 .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu),
2966 .ptr_type => Type.usize.abiAlignment(zcu),2984 .ptr_type => Type.usize.abiAlignment(zcu),
2967 else => unreachable,2985 else => unreachable,
2968 },2986 },
...@@ -3122,7 +3140,6 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool...@@ -3122,7 +3140,6 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool
31223140
3123 .@"opaque",3141 .@"opaque",
3124 .bool,3142 .bool,
3125 .float,
3126 .@"anyframe",3143 .@"anyframe",
3127 => true,3144 => true,
31283145
...@@ -3144,6 +3161,10 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool...@@ -3144,6 +3161,10 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool
3144 24, 48 => zcu.getTarget().cpu.arch == .ez80,3161 24, 48 => zcu.getTarget().cpu.arch == .ez80,
3145 else => false,3162 else => false,
3146 },3163 },
3164 .float => switch (ty.floatBits(zcu.getTarget())) {
3165 else => true,
3166 80 => zcu.getTarget().cTypeBitSize(.longdouble) == 80,
3167 },
3147 .@"fn" => {3168 .@"fn" => {
3148 if (position != .other) return false;3169 if (position != .other) return false;
3149 return validateExternCallconv(ty.fnCallingConvention(zcu));3170 return validateExternCallconv(ty.fnCallingConvention(zcu));
...@@ -3600,5 +3621,5 @@ pub fn smallestUnsignedBits(max: u64) u16 {...@@ -3600,5 +3621,5 @@ pub fn smallestUnsignedBits(max: u64) u16 {
3600pub const packed_struct_layout_version = 2;3621pub const packed_struct_layout_version = 2;
36013622
3602fn cTypeAlign(target: *const Target, c_type: Target.CType) Alignment {3623fn cTypeAlign(target: *const Target, c_type: Target.CType) Alignment {
3603 return Alignment.fromByteUnits(target.cTypeAlignment(c_type));3624 return .fromByteUnits(target.cTypeAlignment(c_type).?);
3604}3625}
src/Value.zig+1-6
...@@ -611,12 +611,7 @@ pub fn toFloat(val: Value, comptime T: type, zcu: *const Zcu) T {...@@ -611,12 +611,7 @@ pub fn toFloat(val: Value, comptime T: type, zcu: *const Zcu) T {
611 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {611 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
612 .int => |int| switch (int.storage) {612 .int => |int| switch (int.storage) {
613 .big_int => |big_int| big_int.toFloat(T, .nearest_even)[0],613 .big_int => |big_int| big_int.toFloat(T, .nearest_even)[0],
614 inline .u64, .i64 => |x| {614 inline .u64, .i64 => |x| @floatFromInt(x),
615 if (T == f80) {
616 @panic("TODO we can't lower this properly on non-x86 llvm backend yet");
617 }
618 return @floatFromInt(x);
619 },
620 },615 },
621 .float => |float| switch (float.storage) {616 .float => |float| switch (float.storage) {
622 inline else => |x| @floatCast(x),617 inline else => |x| @floatCast(x),
src/Zcu.zig+13-24
...@@ -2825,6 +2825,11 @@ pub const CompileError = error{...@@ -2825,6 +2825,11 @@ pub const CompileError = error{
28252825
2826pub fn init(zcu: *Zcu, gpa: Allocator, io: Io, thread_count: usize) !void {2826pub fn init(zcu: *Zcu, gpa: Allocator, io: Io, thread_count: usize) !void {
2827 try zcu.intern_pool.init(gpa, io, thread_count);2827 try zcu.intern_pool.init(gpa, io, thread_count);
2828}
2829
2830/// It is valid to not call this function before `deinit` in error paths.
2831/// Requires the fields on `zcu.comp` to already be initialized.
2832pub fn initAfterCompilation(zcu: *Zcu) void {
2828 zcu.initTracyPlots();2833 zcu.initTracyPlots();
2829}2834}
28302835
...@@ -4612,43 +4617,26 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)...@@ -4612,43 +4617,26 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)
4612 .m68k_rtd,4617 .m68k_rtd,
4613 .m68k_interrupt,4618 .m68k_interrupt,
4614 .msp430_interrupt,4619 .msp430_interrupt,
4615 => |opts| opts.incoming_stack_alignment == null,
4616
4617 .arm_aapcs_vfp,4620 .arm_aapcs_vfp,
4618 => |opts| opts.incoming_stack_alignment == null,
4619
4620 .arc_interrupt,4621 .arc_interrupt,
4621 => |opts| opts.incoming_stack_alignment == null,
4622
4623 .arm_interrupt,4622 .arm_interrupt,
4624 => |opts| opts.incoming_stack_alignment == null,
4625
4626 .microblaze_interrupt,4623 .microblaze_interrupt,
4627 => |opts| opts.incoming_stack_alignment == null,
4628
4629 .mips_interrupt,4624 .mips_interrupt,
4630 .mips64_interrupt,4625 .mips64_interrupt,
4631 => |opts| opts.incoming_stack_alignment == null,
4632
4633 .riscv32_interrupt,4626 .riscv32_interrupt,
4634 .riscv64_interrupt,4627 .riscv64_interrupt,
4635 => |opts| opts.incoming_stack_alignment == null,
4636
4637 .sh_interrupt,4628 .sh_interrupt,
4638 => |opts| opts.incoming_stack_alignment == null,4629 .avr_interrupt,
4630 .avr_signal,
4631 .ez80_tiflags,
4632 .naked,
4633 => true, // incoming stack alignment supported
46394634
4640 .x86_sysv,4635 .x86_sysv,
4641 .x86_win,4636 .x86_win,
4637 .x86_mingw,
4642 .x86_stdcall,4638 .x86_stdcall,
4643 => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0,4639 => |opts| opts.register_params == 0, // incoming stack alignment supported
4644
4645 .avr_interrupt,
4646 .avr_signal,
4647 => true,
4648
4649 .ez80_tiflags => true,
4650
4651 .naked => true,
46524640
4653 else => false,4641 else => false,
4654 };4642 };
...@@ -4673,6 +4661,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)...@@ -4673,6 +4661,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)
4673 .stage2_x86 => switch (cc) {4661 .stage2_x86 => switch (cc) {
4674 .x86_sysv,4662 .x86_sysv,
4675 .x86_win,4663 .x86_win,
4664 .x86_mingw,
4676 => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0,4665 => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0,
4677 .naked => true,4666 .naked => true,
4678 else => false,4667 else => false,
src/codegen.zig+195
...@@ -1124,6 +1124,201 @@ pub fn fieldOffset(ptr_agg_ty: Type, ptr_field_ty: Type, field_index: u32, zcu:...@@ -1124,6 +1124,201 @@ pub fn fieldOffset(ptr_agg_ty: Type, ptr_field_ty: Type, field_index: u32, zcu:
1124 };1124 };
1125}1125}
11261126
1127pub const FlattenedItem = struct { offset: u64, type: ?Type };
1128pub fn flattenType(items_buf: []FlattenedItem, ty: Type, zcu: *Zcu, opts: struct {
1129 offset: u64 = 0,
1130 allow_arrays: bool = true,
1131 fn increaseOffset(opts: @This(), offset: u64) @This() {
1132 return .{
1133 .offset = opts.offset + offset,
1134 .allow_arrays = opts.allow_arrays,
1135 };
1136 }
1137}) ?[]FlattenedItem {
1138 const ip = &zcu.intern_pool;
1139 switch (ip.indexToKey(ty.toIntern())) {
1140 .int_type => |int_type| {
1141 if (int_type.bits == 0) return items_buf[0..0];
1142 if (items_buf.len < 1) return null;
1143 const items = items_buf[0..1];
1144 items.* = .{.{ .offset = opts.offset, .type = ty }};
1145 return items;
1146 },
1147 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1148 .one, .many, .c => {
1149 if (items_buf.len < 1) return null;
1150 const items = items_buf[0..1];
1151 items.* = .{.{ .offset = opts.offset, .type = ty }};
1152 return items;
1153 },
1154 .slice => {
1155 if (items_buf.len < 2) return null;
1156 const items = items_buf[0..2];
1157 const ptr_field_ty = ty.slicePtrFieldType(zcu);
1158 items.* = .{
1159 .{ .offset = opts.offset, .type = ptr_field_ty },
1160 .{ .offset = opts.offset + ptr_field_ty.abiSize(zcu), .type = .usize },
1161 };
1162 return items;
1163 },
1164 },
1165 .array_type => |array_type| {
1166 const len = array_type.lenIncludingSentinel();
1167 if (len == 0) return items_buf[0..0];
1168 const elem_ty: Type = .fromInterned(array_type.child);
1169 const elem_items = flattenType(items_buf, elem_ty, zcu, opts) orelse return null;
1170 if (elem_items.len == 0) return items_buf[0..0];
1171 if (!opts.allow_arrays) return null;
1172 const items_len, const items_overflow = @mulWithOverflow(elem_items.len, len);
1173 if (items_overflow != 0 or items_buf.len < items_len) return null;
1174 var items_index = elem_items.len;
1175 const elem_size = elem_ty.abiSize(zcu);
1176 var elem_offset: u64 = elem_size;
1177 while (items_index != items_len) : ({
1178 items_index += elem_items.len;
1179 elem_offset += elem_size;
1180 }) for (items_buf[items_index..][0..elem_items.len], elem_items) |*item, elem_item| {
1181 item.* = .{ .offset = elem_offset + elem_item.offset, .type = elem_item.type };
1182 };
1183 return items_buf[0..@intCast(items_len)];
1184 },
1185 .vector_type => |vector_type| {
1186 if (vector_type.len == 0) return items_buf[0..0];
1187 if (items_buf.len < 1) return null;
1188 const items = items_buf[0..1];
1189 items.* = .{.{ .offset = opts.offset, .type = ty }};
1190 return items;
1191 },
1192 .opt_type, .error_union_type => return null,
1193 .simple_type => |simple_type| switch (simple_type) {
1194 .f16,
1195 .f32,
1196 .f64,
1197 .f80,
1198 .f128,
1199 .usize,
1200 .isize,
1201 .c_char,
1202 .c_short,
1203 .c_ushort,
1204 .c_int,
1205 .c_uint,
1206 .c_long,
1207 .c_ulong,
1208 .c_longlong,
1209 .c_ulonglong,
1210 .c_longdouble,
1211 .bool,
1212 .anyerror,
1213 => {
1214 if (items_buf.len < 1) return null;
1215 const items = items_buf[0..1];
1216 items.* = .{.{ .offset = opts.offset, .type = ty }};
1217 return items;
1218 },
1219 .anyopaque, .noreturn => return null,
1220 .void,
1221 .type,
1222 .comptime_int,
1223 .comptime_float,
1224 .null,
1225 .undefined,
1226 .enum_literal,
1227 => return items_buf[0..0],
1228 .adhoc_inferred_error_set, .generic_poison => unreachable,
1229 },
1230 .struct_type => {
1231 const loaded_struct = ip.loadStructType(ty.toIntern());
1232 switch (loaded_struct.layout) {
1233 .auto, .@"extern" => {},
1234 .@"packed" => return flattenType(items_buf, .fromInterned(
1235 loaded_struct.packed_backing_int_type,
1236 ), zcu, opts),
1237 }
1238 var items_len: usize = 0;
1239 var offset: u64 = 0;
1240 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1241 while (field_it.next()) |field_index| {
1242 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1243 const field_offset = loaded_struct.field_offsets.get(ip)[field_index];
1244 if (field_offset - offset > 0 and
1245 (items_len == 0 or items_buf[items_len - 1].type != null))
1246 {
1247 if (items_len == items_buf.len) return null;
1248 items_buf[items_len] = .{ .offset = offset, .type = null };
1249 items_len += 1;
1250 }
1251 items_len += (flattenType(items_buf[items_len..], field_ty, zcu, opts.increaseOffset(
1252 field_offset,
1253 )) orelse return null).len;
1254 offset = field_offset + field_ty.abiSize(zcu);
1255 }
1256 if (ty.abiSize(zcu) - offset > 0 and
1257 (items_len == 0 or items_buf[items_len - 1].type != null))
1258 {
1259 if (items_len == items_buf.len) return null;
1260 items_buf[items_len] = .{ .offset = offset, .type = null };
1261 items_len += 1;
1262 }
1263 return items_buf[0..items_len];
1264 },
1265 .tuple_type => |tuple_type| {
1266 if (items_buf.len < tuple_type.types.len) return null;
1267 var items_len: usize = 0;
1268 var offset: u64 = 0;
1269 for (tuple_type.types.get(ip)) |field_ty_ip| {
1270 const field_ty: Type = .fromInterned(field_ty_ip);
1271 offset = field_ty.abiAlignment(zcu).forward(offset);
1272 items_len += (flattenType(items_buf[items_len..], field_ty, zcu, opts.increaseOffset(
1273 offset,
1274 )) orelse return null).len;
1275 offset += field_ty.abiSize(zcu);
1276 }
1277 return items_buf[0..items_len];
1278 },
1279 .union_type => {
1280 const loaded_union = ip.loadUnionType(ty.toIntern());
1281 return switch (loaded_union.layout) {
1282 .auto, .@"extern" => return null,
1283 .@"packed" => return flattenType(items_buf, .fromInterned(
1284 loaded_union.packed_backing_int_type,
1285 ), zcu, opts),
1286 };
1287 },
1288 .opaque_type, .spirv_type, .func_type => return null,
1289 .enum_type => return flattenType(items_buf, .fromInterned(
1290 ip.loadEnumType(ty.toIntern()).int_tag_type,
1291 ), zcu, opts),
1292 .error_set_type, .inferred_error_set_type => {
1293 if (items_buf.len < 1) return null;
1294 const items = items_buf[0..1];
1295 items.* = .{.{ .offset = opts.offset, .type = ty }};
1296 return items;
1297 },
1298 .anyframe_type,
1299 // values, not types
1300 .undef,
1301 .simple_value,
1302 .@"extern",
1303 .func,
1304 .int,
1305 .err,
1306 .error_union,
1307 .enum_literal,
1308 .enum_tag,
1309 .float,
1310 .ptr,
1311 .slice,
1312 .opt,
1313 .aggregate,
1314 .un,
1315 .bitpack,
1316 // memoization, not types
1317 .memoized_call,
1318 => unreachable,
1319 }
1320}
1321
1127test {1322test {
1128 _ = aarch64;1323 _ = aarch64;
1129}1324}
src/codegen/aarch64/Select.zig+20-20
...@@ -2099,7 +2099,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2099,7 +2099,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2099 32 => "truncf",2099 32 => "truncf",
2100 64 => "trunc",2100 64 => "trunc",
2101 80 => "__truncx",2101 80 => "__truncx",
2102 128 => "truncq",2102 128 => "truncf128",
2103 },2103 },
2104 .reloc = .{ .label = @intCast(isel.instructions.items.len) },2104 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
2105 });2105 });
...@@ -2113,7 +2113,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2113,7 +2113,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2113 32 => "floorf",2113 32 => "floorf",
2114 64 => "floor",2114 64 => "floor",
2115 80 => "__floorx",2115 80 => "__floorx",
2116 128 => "floorq",2116 128 => "floorf128",
2117 },2117 },
2118 .reloc = .{ .label = @intCast(isel.instructions.items.len) },2118 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
2119 });2119 });
...@@ -2431,7 +2431,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2431,7 +2431,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2431 32 => "fmodf",2431 32 => "fmodf",
2432 64 => "fmod",2432 64 => "fmod",
2433 80 => "__fmodx",2433 80 => "__fmodx",
2434 128 => "fmodq",2434 128 => "fmodf128",
2435 },2435 },
2436 .reloc = .{ .label = @intCast(isel.instructions.items.len) },2436 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
2437 });2437 });
...@@ -2599,7 +2599,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2599,7 +2599,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2599 32 => "fmaxf",2599 32 => "fmaxf",
2600 64 => "fmax",2600 64 => "fmax",
2601 80 => "__fmaxx",2601 80 => "__fmaxx",
2602 128 => "fmaxq",2602 128 => "fmaxf128",
2603 },2603 },
2604 .min => switch (bits) {2604 .min => switch (bits) {
2605 else => unreachable,2605 else => unreachable,
...@@ -2607,7 +2607,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2607,7 +2607,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2607 32 => "fminf",2607 32 => "fminf",
2608 64 => "fmin",2608 64 => "fmin",
2609 80 => "__fminx",2609 80 => "__fminx",
2610 128 => "fminq",2610 128 => "fminf128",
2611 },2611 },
2612 },2612 },
2613 .reloc = .{ .label = @intCast(isel.instructions.items.len) },2613 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
...@@ -4055,7 +4055,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4055,7 +4055,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4055 32 => "sqrtf",4055 32 => "sqrtf",
4056 64 => "sqrt",4056 64 => "sqrt",
4057 80 => "__sqrtx",4057 80 => "__sqrtx",
4058 128 => "sqrtq",4058 128 => "sqrtf128",
4059 },4059 },
4060 .floor => switch (bits) {4060 .floor => switch (bits) {
4061 else => unreachable,4061 else => unreachable,
...@@ -4063,7 +4063,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4063,7 +4063,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4063 32 => "floorf",4063 32 => "floorf",
4064 64 => "floor",4064 64 => "floor",
4065 80 => "__floorx",4065 80 => "__floorx",
4066 128 => "floorq",4066 128 => "floorf128",
4067 },4067 },
4068 .ceil => switch (bits) {4068 .ceil => switch (bits) {
4069 else => unreachable,4069 else => unreachable,
...@@ -4071,7 +4071,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4071,7 +4071,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4071 32 => "ceilf",4071 32 => "ceilf",
4072 64 => "ceil",4072 64 => "ceil",
4073 80 => "__ceilx",4073 80 => "__ceilx",
4074 128 => "ceilq",4074 128 => "ceilf128",
4075 },4075 },
4076 .round => switch (bits) {4076 .round => switch (bits) {
4077 else => unreachable,4077 else => unreachable,
...@@ -4079,7 +4079,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4079,7 +4079,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4079 32 => "roundf",4079 32 => "roundf",
4080 64 => "round",4080 64 => "round",
4081 80 => "__roundx",4081 80 => "__roundx",
4082 128 => "roundq",4082 128 => "roundf128",
4083 },4083 },
4084 .trunc_float => switch (bits) {4084 .trunc_float => switch (bits) {
4085 else => unreachable,4085 else => unreachable,
...@@ -4087,7 +4087,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4087,7 +4087,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4087 32 => "truncf",4087 32 => "truncf",
4088 64 => "trunc",4088 64 => "trunc",
4089 80 => "__truncx",4089 80 => "__truncx",
4090 128 => "truncq",4090 128 => "truncf128",
4091 },4091 },
4092 },4092 },
4093 .reloc = .{ .label = @intCast(isel.instructions.items.len) },4093 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
...@@ -4147,7 +4147,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4147,7 +4147,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4147 32 => "sinf",4147 32 => "sinf",
4148 64 => "sin",4148 64 => "sin",
4149 80 => "__sinx",4149 80 => "__sinx",
4150 128 => "sinq",4150 128 => "sinf128",
4151 },4151 },
4152 .cos => switch (bits) {4152 .cos => switch (bits) {
4153 else => unreachable,4153 else => unreachable,
...@@ -4155,7 +4155,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4155,7 +4155,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4155 32 => "cosf",4155 32 => "cosf",
4156 64 => "cos",4156 64 => "cos",
4157 80 => "__cosx",4157 80 => "__cosx",
4158 128 => "cosq",4158 128 => "cosf128",
4159 },4159 },
4160 .tan => switch (bits) {4160 .tan => switch (bits) {
4161 else => unreachable,4161 else => unreachable,
...@@ -4163,7 +4163,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4163,7 +4163,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4163 32 => "tanf",4163 32 => "tanf",
4164 64 => "tan",4164 64 => "tan",
4165 80 => "__tanx",4165 80 => "__tanx",
4166 128 => "tanq",4166 128 => "tanf128",
4167 },4167 },
4168 .exp => switch (bits) {4168 .exp => switch (bits) {
4169 else => unreachable,4169 else => unreachable,
...@@ -4171,7 +4171,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4171,7 +4171,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4171 32 => "expf",4171 32 => "expf",
4172 64 => "exp",4172 64 => "exp",
4173 80 => "__expx",4173 80 => "__expx",
4174 128 => "expq",4174 128 => "expf128",
4175 },4175 },
4176 .exp2 => switch (bits) {4176 .exp2 => switch (bits) {
4177 else => unreachable,4177 else => unreachable,
...@@ -4179,7 +4179,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4179,7 +4179,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4179 32 => "exp2f",4179 32 => "exp2f",
4180 64 => "exp2",4180 64 => "exp2",
4181 80 => "__exp2x",4181 80 => "__exp2x",
4182 128 => "exp2q",4182 128 => "exp2f128",
4183 },4183 },
4184 .log => switch (bits) {4184 .log => switch (bits) {
4185 else => unreachable,4185 else => unreachable,
...@@ -4187,7 +4187,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4187,7 +4187,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4187 32 => "logf",4187 32 => "logf",
4188 64 => "log",4188 64 => "log",
4189 80 => "__logx",4189 80 => "__logx",
4190 128 => "logq",4190 128 => "logf128",
4191 },4191 },
4192 .log2 => switch (bits) {4192 .log2 => switch (bits) {
4193 else => unreachable,4193 else => unreachable,
...@@ -4195,7 +4195,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4195,7 +4195,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4195 32 => "log2f",4195 32 => "log2f",
4196 64 => "log2",4196 64 => "log2",
4197 80 => "__log2x",4197 80 => "__log2x",
4198 128 => "log2q",4198 128 => "log2f128",
4199 },4199 },
4200 .log10 => switch (bits) {4200 .log10 => switch (bits) {
4201 else => unreachable,4201 else => unreachable,
...@@ -4203,7 +4203,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4203,7 +4203,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4203 32 => "log10f",4203 32 => "log10f",
4204 64 => "log10",4204 64 => "log10",
4205 80 => "__log10x",4205 80 => "__log10x",
4206 128 => "log10q",4206 128 => "log10f128",
4207 },4207 },
4208 },4208 },
4209 .reloc = .{ .label = @intCast(isel.instructions.items.len) },4209 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
...@@ -7118,7 +7118,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -7118,7 +7118,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
7118 32 => "fmaf",7118 32 => "fmaf",
7119 64 => "fma",7119 64 => "fma",
7120 80 => "__fmax",7120 80 => "__fmax",
7121 128 => "fmaq",7121 128 => "fmaf128",
7122 },7122 },
7123 .reloc = .{ .label = @intCast(isel.instructions.items.len) },7123 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
7124 });7124 });
...@@ -12388,7 +12388,7 @@ pub const CallAbiIterator = struct {...@@ -12388,7 +12388,7 @@ pub const CallAbiIterator = struct {
12388 .f32 => .single,12388 .f32 => .single,
12389 .f64 => .double,12389 .f64 => .double,
12390 .f128 => .quad,12390 .f128 => .quad,
12391 .c_longdouble => switch (zcu.getTarget().cTypeBitSize(.longdouble)) {12391 .c_longdouble => switch (zcu.getTarget().cTypeBitSize(.longdouble).?) {
12392 else => unreachable,12392 else => unreachable,
12393 64 => .double,12393 64 => .double,
12394 80 => null,12394 80 => null,
src/codegen/aarch64/abi.zig+7-2
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1const assert = @import("std").debug.assert;1const assert = std.debug.assert;
2const std = @import("std");2const std = @import("std");
3const InternPool = @import("../../InternPool.zig");3const InternPool = @import("../../InternPool.zig");
4const Type = @import("../../Type.zig");4const Type = @import("../../Type.zig");
...@@ -35,7 +35,12 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {...@@ -35,7 +35,12 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {
35 if (bit_size > 64) return .double_integer;35 if (bit_size > 64) return .double_integer;
36 return .integer;36 return .integer;
37 },37 },
38 .int, .@"enum", .error_set, .float, .bool => return .byval,38 .int, .@"enum", .error_set, .bool => return .byval,
39 .float => return switch (ty.floatBits(zcu.getTarget())) {
40 else => unreachable,
41 16, 32, 64, 128 => .byval,
42 80 => .double_integer,
43 },
39 .vector => {44 .vector => {
40 const bit_size = ty.bitSize(zcu);45 const bit_size = ty.bitSize(zcu);
41 // TODO is this controlled by a cpu feature?46 // TODO is this controlled by a cpu feature?
src/codegen/arm/abi.zig+9-7
...@@ -39,7 +39,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {...@@ -39,7 +39,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
39 const float_count = countFloats(ty, zcu, &maybe_float_bits);39 const float_count = countFloats(ty, zcu, &maybe_float_bits);
40 if (float_count <= byval_float_count) return .byval;40 if (float_count <= byval_float_count) return .byval;
4141
42 if (ty.abiAlignment(zcu).compare(.gt, .@"32")) {42 if (ty.abiAlignment(zcu).compare(.gt, .@"4")) {
43 return Class.arrSize(bit_size, 64);43 return Class.arrSize(bit_size, 64);
44 }44 }
4545
...@@ -62,7 +62,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {...@@ -62,7 +62,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
62 const float_count = countFloats(ty, zcu, &maybe_float_bits);62 const float_count = countFloats(ty, zcu, &maybe_float_bits);
63 if (float_count <= byval_float_count) return .byval;63 if (float_count <= byval_float_count) return .byval;
6464
65 if (union_obj.alignment.compareStrict(.gt, .@"32")) {65 if (union_obj.alignment.compareStrict(.gt, .@"4")) {
66 return Class.arrSize(bit_size, 64);66 return Class.arrSize(bit_size, 64);
67 }67 }
6868
...@@ -73,14 +73,16 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {...@@ -73,14 +73,16 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
73 }73 }
74 return Class.arrSize(bit_size, 32);74 return Class.arrSize(bit_size, 32);
75 },75 },
76 .bool, .float => return .byval,76 .bool => return .byval,
77 .int => {77 .int => {
78 // TODO this is incorrect for _BitInt(128) but implementing78 if (ctx == .ret and ty.intInfo(zcu).bits > 64) return .memory;
79 // this correctly makes implementing compiler-rt impossible.
80 // const bit_size = ty.bitSize(zcu);
81 // if (bit_size > 64) return .memory;
82 return .byval;79 return .byval;
83 },80 },
81 .float => return switch (ty.floatBits(zcu.getTarget())) {
82 else => unreachable,
83 16, 32, 64 => .byval,
84 80, 128 => .{ .i64_array = 2 },
85 },
84 .@"enum", .error_set => {86 .@"enum", .error_set => {
85 const bit_size = ty.bitSize(zcu);87 const bit_size = ty.bitSize(zcu);
86 if (bit_size > 64) return .memory;88 if (bit_size > 64) return .memory;
src/codegen/c.zig+745-604
...@@ -164,7 +164,8 @@ const BlockData = struct {...@@ -164,7 +164,8 @@ const BlockData = struct {
164164
165const LocalType = struct {165const LocalType = struct {
166 type: Type,166 type: Type,
167 alignment: Alignment,167 alignment: Alignment = .none,
168 array_len: u2 = 1,
168};169};
169170
170const LocalIndex = u16;171const LocalIndex = u16;
...@@ -184,13 +185,11 @@ const ValueRenderLocation = enum {...@@ -184,13 +185,11 @@ const ValueRenderLocation = enum {
184 }185 }
185};186};
186187
187const BuiltinInfo = enum { none, bits };188const BuiltinInfo = enum { none, bits, bits_none, big_temp_bits };
188189
189const reserved_idents = std.StaticStringMap(void).initComptime(.{190const reserved_idents = std.StaticStringMap(void).initComptime(.{
190 // C language191 // C language
191 .{ "alignas", {192 .{ "alignas", {} },
192 @setEvalBranchQuota(4000);
193 } },
194 .{ "alignof", {} },193 .{ "alignof", {} },
195 .{ "asm", {} },194 .{ "asm", {} },
196 .{ "atomic_bool", {} },195 .{ "atomic_bool", {} },
...@@ -302,7 +301,100 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{...@@ -302,7 +301,100 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
302 // stddef.h301 // stddef.h
303 .{ "offsetof", {} },302 .{ "offsetof", {} },
304303
304 // math.h (only symbols exported by compiler-rt)
305 .{ "ceil", {} },
306 .{ "ceilf", {} },
307 .{ "ceilf128", {} },
308 .{ "ceill", {} },
309 .{ "cos", {} },
310 .{ "cosf", {} },
311 .{ "cosf128", {} },
312 .{ "cosl", {} },
313 .{ "exp", {} },
314 .{ "exp2", {} },
315 .{ "exp2f", {} },
316 .{ "exp2f128", {} },
317 .{ "exp2l", {} },
318 .{ "expf", {} },
319 .{ "expf128", {} },
320 .{ "expl", {} },
321 .{ "fabs", {} },
322 .{ "fabsf", {} },
323 .{ "fabsf128", {} },
324 .{ "fabsl", {} },
325 .{ "floor", {} },
326 .{ "floorf", {} },
327 .{ "floorf128", {} },
328 .{ "floorl", {} },
329 .{ "fma", {} },
330 .{ "fmaf", {} },
331 .{ "fmaf128", {} },
332 .{ "fmal", {} },
333 .{ "fmax", {} },
334 .{ "fmaxf", {} },
335 .{ "fmaxf128", {} },
336 .{ "fmaxl", {} },
337 .{ "fmin", {} },
338 .{ "fminf", {} },
339 .{ "fminf128", {} },
340 .{ "fminl", {} },
341 .{ "fmod", {} },
342 .{ "fmodf", {} },
343 .{ "fmodf128", {} },
344 .{ "fmodl", {} },
345 .{ "log", {} },
346 .{ "log10", {} },
347 .{ "log10f", {} },
348 .{ "log10f128", {} },
349 .{ "log10l", {} },
350 .{ "log2", {} },
351 .{ "log2f", {} },
352 .{ "log2f128", {} },
353 .{ "log2l", {} },
354 .{ "logf", {} },
355 .{ "logf128", {} },
356 .{ "logl", {} },
357 .{ "round", {} },
358 .{ "roundf", {} },
359 .{ "roundf128", {} },
360 .{ "roundl", {} },
361 .{ "sin", {} },
362 .{ "sincos", {} },
363 .{ "sincosf", {} },
364 .{ "sincosf128", {} },
365 .{ "sincosl", {} },
366 .{ "sinf", {} },
367 .{ "sinf128", {} },
368 .{ "sinl", {} },
369 .{ "sqrt", {} },
370 .{ "sqrtf", {} },
371 .{ "sqrtf128", {} },
372 .{ "sqrtl", {} },
373 .{ "tan", {} },
374 .{ "tanf", {} },
375 .{ "tanf128", {} },
376 .{ "tanl", {} },
377 .{ "trunc", {} },
378 .{ "truncf", {} },
379 .{ "truncf128", {} },
380 .{ "truncl", {} },
381
305 // windows.h382 // windows.h
383 .{"DUMMYSTRUCTNAME"},
384 .{"DUMMYSTRUCTNAME2"},
385 .{"DUMMYSTRUCTNAME3"},
386 .{"DUMMYSTRUCTNAME4"},
387 .{"DUMMYSTRUCTNAME5"},
388 .{"DUMMYSTRUCTNAME6"},
389 .{"DUMMYUNIONNAME"},
390 .{"DUMMYUNIONNAME2"},
391 .{"DUMMYUNIONNAME3"},
392 .{"DUMMYUNIONNAME4"},
393 .{"DUMMYUNIONNAME5"},
394 .{"DUMMYUNIONNAME6"},
395 .{"DUMMYUNIONNAME7"},
396 .{"DUMMYUNIONNAME8"},
397 .{"DUMMYUNIONNAME9"},
306 .{ "max", {} },398 .{ "max", {} },
307 .{ "min", {} },399 .{ "min", {} },
308});400});
...@@ -316,13 +408,6 @@ fn isReservedIdent(ident: []const u8) bool {...@@ -316,13 +408,6 @@ fn isReservedIdent(ident: []const u8) bool {
316 }408 }
317 }409 }
318410
319 // windows.h
320 if (mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or
321 mem.startsWith(u8, ident, "DUMMYUNIONNAME"))
322 {
323 return true;
324 }
325
326 // CType411 // CType
327 if (mem.startsWith(u8, ident, "enum__") or412 if (mem.startsWith(u8, ident, "enum__") or
328 mem.startsWith(u8, ident, "bitpack__") or413 mem.startsWith(u8, ident, "bitpack__") or
...@@ -469,10 +554,7 @@ pub const Function = struct {...@@ -469,10 +554,7 @@ pub const Function = struct {
469 }554 }
470555
471 fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue {556 fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue {
472 return f.allocAlignedLocal(inst, .{557 return f.allocAlignedLocal(inst, .{ .type = ty });
473 .type = ty,
474 .alignment = .none,
475 });
476 }558 }
477559
478 /// Only allocates the local; does not print anything. Will attempt to re-use locals, so should560 /// Only allocates the local; does not print anything. Will attempt to re-use locals, so should
...@@ -564,10 +646,6 @@ pub const Function = struct {...@@ -564,10 +646,6 @@ pub const Function = struct {
564 return f.dg.renderType(w, ty);646 return f.dg.renderType(w, ty);
565 }647 }
566648
567 fn renderIntCast(f: *Function, w: *Writer, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
568 return f.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
569 }
570
571 fn fmtIntLiteralDec(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {649 fn fmtIntLiteralDec(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {
572 return f.dg.fmtIntLiteralDec(val, .other);650 return f.dg.fmtIntLiteralDec(val, .other);
573 }651 }
...@@ -672,7 +750,9 @@ pub const DeclGen = struct {...@@ -672,7 +750,9 @@ pub const DeclGen = struct {
672 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.750 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
673 const ptr_ty: Type = .fromInterned(uav.orig_ty);751 const ptr_ty: Type = .fromInterned(uav.orig_ty);
674 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {752 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
675 return dg.renderUndefValue(w, ptr_ty, location);753 try w.writeByte('(');
754 try dg.renderOpvPointer(w, ptr_ty, location);
755 return w.writeByte(')');
676 }756 }
677757
678 switch (ip.indexToKey(uav.val)) {758 switch (ip.indexToKey(uav.val)) {
...@@ -737,8 +817,10 @@ pub const DeclGen = struct {...@@ -737,8 +817,10 @@ pub const DeclGen = struct {
737 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.817 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
738 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).resolved.?.type);818 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).resolved.?.type);
739 const ptr_ty = try pt.navPtrType(owner_nav);819 const ptr_ty = try pt.navPtrType(owner_nav);
740 if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {820 if (nav_ty.zigTypeTag(zcu) != .@"opaque" and !nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
741 return dg.renderUndefValue(w, ptr_ty, location);821 try w.writeByte('(');
822 try dg.renderOpvPointer(w, ptr_ty, location);
823 return w.writeByte(')');
742 }824 }
743825
744 // We shouldn't cast C function pointers as this is UB (when you call826 // We shouldn't cast C function pointers as this is UB (when you call
...@@ -758,6 +840,26 @@ pub const DeclGen = struct {...@@ -758,6 +840,26 @@ pub const DeclGen = struct {
758 if (need_cast) try w.writeByte(')');840 if (need_cast) try w.writeByte(')');
759 }841 }
760842
843 fn renderOpvPointer(
844 dg: *DeclGen,
845 w: *Writer,
846 ptr_ty: Type,
847 location: ValueRenderLocation,
848 ) Error!void {
849 const zcu = dg.pt.zcu;
850 const target = zcu.getTarget();
851 try w.writeByte('(');
852 try dg.renderType(w, ptr_ty);
853 return w.print("){f}", .{fmtUnsignedIntLiteralSmall(
854 target,
855 .uintptr_t,
856 ptr_ty.ptrAlignment(zcu).forward(undefPattern(u64) >> @intCast(64 - target.ptrBitWidth())),
857 location == .static_initializer,
858 16,
859 .lower,
860 )});
861 }
862
761 fn renderPointer(863 fn renderPointer(
762 dg: *DeclGen,864 dg: *DeclGen,
763 w: *Writer,865 w: *Writer,
...@@ -959,9 +1061,6 @@ pub const DeclGen = struct {...@@ -959,9 +1061,6 @@ pub const DeclGen = struct {
959 const bits = ty.floatBits(target);1061 const bits = ty.floatBits(target);
960 const f128_val = val.toFloat(f128, zcu);1062 const f128_val = val.toFloat(f128, zcu);
9611063
962 // All unsigned ints matching float types are pre-allocated.
963 const repr_ty = pt.intType(.unsigned, bits) catch unreachable;
964
965 assert(bits <= 128);1064 assert(bits <= 128);
966 var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined;1065 var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined;
967 var repr_val_big = BigInt.Mutable{1066 var repr_val_big = BigInt.Mutable{
...@@ -971,29 +1070,27 @@ pub const DeclGen = struct {...@@ -971,29 +1070,27 @@ pub const DeclGen = struct {
971 };1070 };
9721071
973 switch (bits) {1072 switch (bits) {
1073 else => unreachable,
974 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, zcu)))),1074 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, zcu)))),
975 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, zcu)))),1075 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, zcu)))),
976 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, zcu)))),1076 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, zcu)))),
977 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, zcu)))),1077 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, zcu)))),
978 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))),1078 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))),
979 else => unreachable,
980 }1079 }
9811080
982 var empty = true;
983 if (std.math.isFinite(f128_val)) {1081 if (std.math.isFinite(f128_val)) {
984 try w.writeAll("zig_make_");1082 try w.writeAll("zig_make_");
985 try dg.renderTypeForBuiltinFnName(w, ty);1083 try dg.renderTypeForBuiltinFnName(w, ty);
986 try w.writeByte('(');1084 try w.writeByte('(');
987 switch (bits) {1085 switch (bits) {
1086 else => unreachable,
988 16 => try w.print("{x}", .{val.toFloat(f16, zcu)}),1087 16 => try w.print("{x}", .{val.toFloat(f16, zcu)}),
989 32 => try w.print("{x}", .{val.toFloat(f32, zcu)}),1088 32 => try w.print("{x}", .{val.toFloat(f32, zcu)}),
990 64 => try w.print("{x}", .{val.toFloat(f64, zcu)}),1089 64 => try w.print("{x}", .{val.toFloat(f64, zcu)}),
991 80 => try w.print("{x}", .{val.toFloat(f80, zcu)}),1090 80 => try w.print("{x}", .{val.toFloat(f80, zcu)}),
992 128 => try w.print("{x}", .{f128_val}),1091 128 => try w.print("{x}", .{f128_val}),
993 else => unreachable,
994 }1092 }
995 try w.writeAll(", ");1093 try w.writeAll(", ");
996 empty = false;
997 } else {1094 } else {
998 // isSignalNan is equivalent to isNan currently, and MSVC doesn't have nans, so prefer nan1095 // isSignalNan is equivalent to isNan currently, and MSVC doesn't have nans, so prefer nan
999 const operation = if (std.math.isNan(f128_val))1096 const operation = if (std.math.isNan(f128_val))
...@@ -1028,6 +1125,7 @@ pub const DeclGen = struct {...@@ -1028,6 +1125,7 @@ pub const DeclGen = struct {
1028 try w.writeAll(operation);1125 try w.writeAll(operation);
1029 try w.writeAll(", ");1126 try w.writeAll(", ");
1030 if (std.math.isNan(f128_val)) switch (bits) {1127 if (std.math.isNan(f128_val)) switch (bits) {
1128 else => unreachable,
1031 // We only actually need to pass the significand, but it will get1129 // We only actually need to pass the significand, but it will get
1032 // properly masked anyway, so just pass the whole value.1130 // properly masked anyway, so just pass the whole value.
1033 16 => try w.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}),1131 16 => try w.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}),
...@@ -1035,16 +1133,23 @@ pub const DeclGen = struct {...@@ -1035,16 +1133,23 @@ pub const DeclGen = struct {
1035 64 => try w.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}),1133 64 => try w.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}),
1036 80 => try w.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}),1134 80 => try w.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}),
1037 128 => try w.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}),1135 128 => try w.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}),
1038 else => unreachable,
1039 };1136 };
1040 try w.writeAll(", ");1137 try w.writeAll(", ");
1041 empty = false;
1042 }1138 }
1043 try w.print("{f}", .{try dg.fmtIntLiteralHex(1139 switch (bits) {
1044 try pt.intValue_big(repr_ty, repr_val_big.toConst()),1140 else => unreachable,
1045 location,1141 16, 32, 64 => {
1046 )});1142 // All unsigned ints matching float types are pre-allocated.
1047 if (!empty) try w.writeByte(')');1143 const repr_ty = pt.intType(.unsigned, bits) catch unreachable;
1144 try w.print("{f}", .{try dg.fmtIntLiteralHex(
1145 try pt.intValue_big(repr_ty, repr_val_big.toConst()),
1146 location,
1147 )});
1148 },
1149 80 => try F80Repr.write(@bitCast(val.toFloat(f80, zcu)), w, target, location == .static_initializer),
1150 128 => try F128Repr.write(@bitCast(f128_val), w, target, location == .static_initializer),
1151 }
1152 try w.writeByte(')');
1048 },1153 },
1049 .slice => |slice| {1154 .slice => |slice| {
1050 if (!location.isInitializer()) {1155 if (!location.isInitializer()) {
...@@ -1319,22 +1424,29 @@ pub const DeclGen = struct {...@@ -1319,22 +1424,29 @@ pub const DeclGen = struct {
1319 .f128_type,1424 .f128_type,
1320 => {1425 => {
1321 const bits = ty.floatBits(target);1426 const bits = ty.floatBits(target);
1322 // All unsigned ints matching float types are pre-allocated.
1323 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;
13241427
1325 try w.writeAll("zig_make_");1428 try w.writeAll("zig_make_");
1326 try dg.renderTypeForBuiltinFnName(w, ty);1429 try dg.renderTypeForBuiltinFnName(w, ty);
1327 try w.writeByte('(');1430 try w.writeByte('(');
1328 switch (bits) {1431 switch (bits) {
1329 16 => try w.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),
1330 32 => try w.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),
1331 64 => try w.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),
1332 80 => try w.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),
1333 128 => try w.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),
1334 else => unreachable,1432 else => unreachable,
1433 16 => try w.print("{x}", .{undefPattern(f16)}),
1434 32 => try w.print("{x}", .{undefPattern(f32)}),
1435 64 => try w.print("{x}", .{undefPattern(f64)}),
1436 80 => try w.print("{x}", .{undefPattern(f80)}),
1437 128 => try w.print("{x}", .{undefPattern(f128)}),
1335 }1438 }
1336 try w.writeAll(", ");1439 try w.writeAll(", ");
1337 try dg.renderUndefValue(w, repr_ty, .other);1440 switch (bits) {
1441 else => unreachable,
1442 16, 32, 64 => {
1443 // All unsigned ints matching float types are pre-allocated.
1444 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;
1445 try dg.renderUndefValue(w, repr_ty, .other);
1446 },
1447 80 => try undefPattern(F80Repr).write(w, target, location == .static_initializer),
1448 128 => try undefPattern(F128Repr).write(w, target, location == .static_initializer),
1449 }
1338 return w.writeByte(')');1450 return w.writeByte(')');
1339 },1451 },
1340 .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"),1452 .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"),
...@@ -1638,8 +1750,6 @@ pub const DeclGen = struct {...@@ -1638,8 +1750,6 @@ pub const DeclGen = struct {
1638 try w.writeAll("zig_no_builtin ");1750 try w.writeAll("zig_no_builtin ");
1639 }1751 }
16401752
1641 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
1642
1643 // While incomplete types are usually an acceptable substitute for "void", this is not true1753 // While incomplete types are usually an acceptable substitute for "void", this is not true
1644 // in function return types, where "void" is the only incomplete type permitted.1754 // in function return types, where "void" is the only incomplete type permitted.
1645 const actual_return_type: Type = .fromInterned(fn_info.return_type);1755 const actual_return_type: Type = .fromInterned(fn_info.return_type);
...@@ -1651,8 +1761,9 @@ pub const DeclGen = struct {...@@ -1651,8 +1761,9 @@ pub const DeclGen = struct {
16511761
1652 const ret_cty: CType = try .lower(effective_return_type, &dg.ctype_deps, dg.arena, zcu);1762 const ret_cty: CType = try .lower(effective_return_type, &dg.ctype_deps, dg.arena, zcu);
1653 try w.print("{f}", .{ret_cty.fmtDeclaratorPrefix(zcu)});1763 try w.print("{f}", .{ret_cty.fmtDeclaratorPrefix(zcu)});
1654 if (toCallingConvention(fn_info.cc, zcu)) |call_conv| {1764 switch (CType.CallingConvention.fromLang(fn_info.cc, zcu.getTarget())) {
1655 try w.print("zig_callconv({s}) ", .{call_conv});1765 .c => {},
1766 else => |cc| try w.print("zig_callconv({t}) ", .{cc}),
1656 }1767 }
1657 switch (name) {1768 switch (name) {
1658 .nav => |nav| try renderNavName(w, nav, ip),1769 .nav => |nav| try renderNavName(w, nav, ip),
...@@ -1726,136 +1837,6 @@ pub const DeclGen = struct {...@@ -1726,136 +1837,6 @@ pub const DeclGen = struct {
1726 try w.print("{f}", .{cty.fmtTypeName(zcu)});1837 try w.print("{f}", .{cty.fmtTypeName(zcu)});
1727 }1838 }
17281839
1729 const IntCastContext = union(enum) {
1730 c_value: struct {
1731 f: *Function,
1732 value: CValue,
1733 v: Vectorize,
1734 },
1735 value: struct {
1736 value: Value,
1737 },
1738
1739 pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, w: *Writer, location: ValueRenderLocation) !void {
1740 switch (self.*) {
1741 .c_value => |v| {
1742 try v.f.writeCValue(w, v.value, location);
1743 try v.v.elem(v.f, w);
1744 },
1745 .value => |v| try dg.renderValue(w, v.value, location),
1746 }
1747 }
1748 };
1749 fn intCastIsNoop(dg: *DeclGen, dest_ty: Type, src_ty: Type) bool {
1750 const pt = dg.pt;
1751 const zcu = pt.zcu;
1752 const dest_bits = dest_ty.bitSize(zcu);
1753 const dest_int_info = dest_ty.intInfo(pt.zcu);
1754
1755 const src_is_ptr = src_ty.isPtrAtRuntime(pt.zcu);
1756 const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {
1757 .unsigned => .usize,
1758 .signed => .isize,
1759 } else src_ty;
1760
1761 const src_bits = src_eff_ty.bitSize(zcu);
1762 const src_int_info = if (src_eff_ty.isAbiInt(pt.zcu)) src_eff_ty.intInfo(pt.zcu) else null;
1763 if (dest_bits <= 64 and src_bits <= 64) {
1764 const needs_cast = src_int_info == null or
1765 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
1766 dest_int_info.signedness != src_int_info.?.signedness);
1767 return !needs_cast and !src_is_ptr;
1768 } else return false;
1769 }
1770 /// Renders a cast to an int type, from either an int or a pointer.
1771 ///
1772 /// Some platforms don't have 128 bit integers, so we need to use
1773 /// the zig_make_ and zig_lo_ macros in those cases.
1774 ///
1775 /// | Dest type bits | Src type | Result
1776 /// |------------------|------------------|---------------------------|
1777 /// | < 64 bit integer | pointer | (zig_<dest_ty>)(zig_<u|i>size)src
1778 /// | < 64 bit integer | < 64 bit integer | (zig_<dest_ty>)src
1779 /// | < 64 bit integer | > 64 bit integer | zig_lo(src)
1780 /// | > 64 bit integer | pointer | zig_make_<dest_ty>(0, (zig_<u|i>size)src)
1781 /// | > 64 bit integer | < 64 bit integer | zig_make_<dest_ty>(0, src)
1782 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
1783 fn renderIntCast(
1784 dg: *DeclGen,
1785 w: *Writer,
1786 dest_ty: Type,
1787 context: IntCastContext,
1788 src_ty: Type,
1789 location: ValueRenderLocation,
1790 ) !void {
1791 const pt = dg.pt;
1792 const zcu = pt.zcu;
1793 const dest_bits = dest_ty.bitSize(zcu);
1794 const dest_int_info = dest_ty.intInfo(zcu);
1795
1796 const src_is_ptr = src_ty.isPtrAtRuntime(zcu);
1797 const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {
1798 .unsigned => .usize,
1799 .signed => .isize,
1800 } else src_ty;
1801
1802 const src_bits = src_eff_ty.bitSize(zcu);
1803 const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null;
1804 if (dest_bits <= 64 and src_bits <= 64) {
1805 const needs_cast = src_int_info == null or
1806 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
1807 dest_int_info.signedness != src_int_info.?.signedness);
1808
1809 if (needs_cast) {
1810 try w.writeByte('(');
1811 try dg.renderType(w, dest_ty);
1812 try w.writeByte(')');
1813 }
1814 if (src_is_ptr) {
1815 try w.writeByte('(');
1816 try dg.renderType(w, src_eff_ty);
1817 try w.writeByte(')');
1818 }
1819 try context.writeValue(dg, w, location);
1820 } else if (dest_bits <= 64 and src_bits > 64) {
1821 assert(!src_is_ptr);
1822 if (dest_bits < 64) {
1823 try w.writeByte('(');
1824 try dg.renderType(w, dest_ty);
1825 try w.writeByte(')');
1826 }
1827 try w.writeAll("zig_lo_");
1828 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
1829 try w.writeByte('(');
1830 try context.writeValue(dg, w, .other);
1831 try w.writeByte(')');
1832 } else if (dest_bits > 64 and src_bits <= 64) {
1833 try w.writeAll("zig_make_");
1834 try dg.renderTypeForBuiltinFnName(w, dest_ty);
1835 try w.writeAll("(0, ");
1836 if (src_is_ptr) {
1837 try w.writeByte('(');
1838 try dg.renderType(w, src_eff_ty);
1839 try w.writeByte(')');
1840 }
1841 try context.writeValue(dg, w, .other);
1842 try w.writeByte(')');
1843 } else {
1844 assert(!src_is_ptr);
1845 try w.writeAll("zig_make_");
1846 try dg.renderTypeForBuiltinFnName(w, dest_ty);
1847 try w.writeAll("(zig_hi_");
1848 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
1849 try w.writeByte('(');
1850 try context.writeValue(dg, w, .other);
1851 try w.writeAll("), zig_lo_");
1852 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
1853 try w.writeByte('(');
1854 try context.writeValue(dg, w, .other);
1855 try w.writeAll("))");
1856 }
1857 }
1858
1859 /// Renders to `w` a C declarator whose type is the C lowering of the given Zig type.1840 /// Renders to `w` a C declarator whose type is the C lowering of the given Zig type.
1860 fn renderTypeAndName(1841 fn renderTypeAndName(
1861 dg: *DeclGen,1842 dg: *DeclGen,
...@@ -2000,6 +1981,7 @@ pub const DeclGen = struct {...@@ -2000,6 +1981,7 @@ pub const DeclGen = struct {
2000 switch (info) {1981 switch (info) {
2001 .none => if (!is_big) return,1982 .none => if (!is_big) return,
2002 .bits => {},1983 .bits => {},
1984 .bits_none, .big_temp_bits => unreachable,
2003 }1985 }
20041986
2005 const int_info: std.lang.Type.Int = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{1987 const int_info: std.lang.Type.Int = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{
...@@ -2056,6 +2038,72 @@ const CQualifiers = packed struct {...@@ -2056,6 +2038,72 @@ const CQualifiers = packed struct {
2056 restrict: bool = false,2038 restrict: bool = false,
2057};2039};
20582040
2041pub fn genHeader(zcu: *Zcu, w: *Writer) !void {
2042 const gpa = zcu.comp.gpa;
2043
2044 var arena: std.heap.ArenaAllocator = .init(gpa);
2045 defer arena.deinit();
2046 var ctype_deps: CType.Dependencies = .empty;
2047 defer ctype_deps.deinit(gpa);
2048
2049 const target = zcu.getTarget();
2050 switch (target.abi) {
2051 .msvc, .itanium => try w.writeAll("#define ZIG_TARGET_ABI_MSVC\n"),
2052 else => {},
2053 }
2054 for ([_]u16{ 16, 32, 64, 80, 128 }) |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
2055 .hard => {},
2056 .soft => try w.print("#define ZIG_TARGET_SOFT_COMPILER_RT_F{d}_ABI\n", .{bits}),
2057 };
2058 try w.print(
2059 \\#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}
2060 \\#include "zig.h"
2061 \\
2062 \\
2063 ,
2064 .{target.cMaxIntAlignment()},
2065 );
2066
2067 var basic_ty: Type = .fromInterned(.first_type);
2068 while (true) : ({
2069 basic_ty = .fromInterned(@fromBackingInt(@intCast(@backingInt(basic_ty.toIntern()) + 1)));
2070 if (basic_ty.toIntern() == InternPool.Index.last_type) break;
2071 }) {
2072 switch (basic_ty.toIntern()) {
2073 else => {},
2074 .anyframe_type,
2075 .adhoc_inferred_error_set_type,
2076 .generic_poison_type,
2077 => continue, // skip unsupported types
2078 }
2079 const basic_cty: CType = try .lower(basic_ty, &ctype_deps, arena.allocator(), zcu);
2080 switch (basic_cty) {
2081 .void => {}, // no layout to check
2082 .bool,
2083 .int,
2084 .float,
2085 => try CType.render_defs.writeStaticAssertTypeLayout(basic_ty, basic_cty, w, zcu),
2086 .@"fn",
2087 .@"enum",
2088 .bitpack,
2089 .@"struct",
2090 .union_auto,
2091 .union_extern,
2092 .slice,
2093 .opt,
2094 .arr,
2095 .vec,
2096 .errunion,
2097 .aligned,
2098 .bigint,
2099 .pointer,
2100 .array,
2101 .function,
2102 => {},
2103 }
2104 }
2105}
2106
2059pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {2107pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {
2060 for (zcu.global_assembly.values()) |asm_source| {2108 for (zcu.global_assembly.values()) |asm_source| {
2061 try w.print("__asm({f});\n", .{fmtStringLiteral(asm_source, null)});2109 try w.print("__asm({f});\n", .{fmtStringLiteral(asm_source, null)});
...@@ -2070,16 +2118,16 @@ pub fn genErrDecls(...@@ -2070,16 +2118,16 @@ pub fn genErrDecls(
2070 const ip = &zcu.intern_pool;2118 const ip = &zcu.intern_pool;
20712119
2072 const names = ip.global_error_set.getNamesFromMainThread();2120 const names = ip.global_error_set.getNamesFromMainThread();
2073 // Don't generate an invalid empty enum if the global error set is empty!2121 // Don't generate an invalid empty enum/array if the global error set is empty!
2074 if (names.len > 0) {2122 if (names.len == 0) return;
2075 try w.writeAll("enum {\n");2123
2076 for (names, 1..) |name_nts, value| {2124 try w.writeAll("enum {\n");
2077 try w.writeByte(' ');2125 for (names, 1..) |name_nts, value| {
2078 try renderErrorName(w, name_nts.toSlice(ip));2126 try w.writeByte(' ');
2079 try w.print(" = {d}u,\n", .{value});2127 try renderErrorName(w, name_nts.toSlice(ip));
2080 }2128 try w.print(" = {d}u,\n", .{value});
2081 try w.writeAll("};\n");
2082 }2129 }
2130 try w.writeAll("};\n");
20832131
2084 for (names) |name_nts| {2132 for (names) |name_nts| {
2085 const name = name_nts.toSlice(ip);2133 const name = name_nts.toSlice(ip);
...@@ -2093,7 +2141,7 @@ pub fn genErrDecls(...@@ -2093,7 +2141,7 @@ pub fn genErrDecls(
2093 "static {s} const zig_errorName[{d}] = {{",2141 "static {s} const zig_errorName[{d}] = {{",
2094 .{ slice_const_u8_sentinel_0_type_name, names.len },2142 .{ slice_const_u8_sentinel_0_type_name, names.len },
2095 );2143 );
2096 if (names.len > 0) try w.writeByte('\n');2144 try w.writeByte('\n');
2097 for (names) |name_nts| {2145 for (names) |name_nts| {
2098 const name = name_nts.toSlice(ip);2146 const name = name_nts.toSlice(ip);
2099 try w.print(2147 try w.print(
...@@ -2114,10 +2162,18 @@ pub fn genTagNameFn(...@@ -2114,10 +2162,18 @@ pub fn genTagNameFn(
2114 const ip = &zcu.intern_pool;2162 const ip = &zcu.intern_pool;
2115 const loaded_enum = ip.loadEnumType(enum_ty.toIntern());2163 const loaded_enum = ip.loadEnumType(enum_ty.toIntern());
2116 assert(loaded_enum.field_names.len > 0);2164 assert(loaded_enum.field_names.len > 0);
2117 if (Type.fromInterned(loaded_enum.int_tag_type).bitSize(zcu) > 64) {2165 switch (CType.classifyInt(enum_ty, zcu)) {
2118 @panic("TODO CBE: tagName for enum over 64 bits");2166 .void => unreachable,
2167 .small => |int| switch (int) {
2168 else => {},
2169 .zig_u128, .zig_i128 => @panic("TODO CBE: tagName for 128-bit enums"),
2170 },
2171 .big => @panic("TODO CBE: tagName for bigint enums"),
2119 }2172 }
21202173
2174 if (!zcu.comp.config.root_strip) try w.print("/* @tagName({f}) */\n", .{
2175 loaded_enum.name.fmt(ip),
2176 });
2121 try w.print("static {s} zig_tagName_{f}__{d}({s} tag) {{\n", .{2177 try w.print("static {s} zig_tagName_{f}__{d}({s} tag) {{\n", .{
2122 slice_const_u8_sentinel_0_type_name,2178 slice_const_u8_sentinel_0_type_name,
2123 fmtIdentUnsolo(loaded_enum.name.toSlice(ip)),2179 fmtIdentUnsolo(loaded_enum.name.toSlice(ip)),
...@@ -2164,6 +2220,7 @@ pub fn genLazyCallModifierFn(...@@ -2164,6 +2220,7 @@ pub fn genLazyCallModifierFn(
21642220
2165 const fn_val = zcu.navValue(fn_nav);2221 const fn_val = zcu.navValue(fn_nav);
21662222
2223 if (fn_val.typeOf(zcu).fnReturnType(zcu).isNoReturn(zcu)) try w.writeAll("zig_noreturn ");
2167 try w.print("static zig_{t} ", .{kind});2224 try w.print("static zig_{t} ", .{kind});
2168 try dg.renderFunctionSignature(w, fn_val, .none, .definition, switch (kind) {2225 try dg.renderFunctionSignature(w, fn_val, .none, .definition, switch (kind) {
2169 .never_tail => .{ .nav_never_tail = fn_nav },2226 .never_tail => .{ .nav_never_tail = fn_nav },
...@@ -2269,8 +2326,10 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E...@@ -2269,8 +2326,10 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E
2269 const gpa = f.dg.gpa;2326 const gpa = f.dg.gpa;
2270 const nav_index = f.dg.owner_nav.unwrap().?;2327 const nav_index = f.dg.owner_nav.unwrap().?;
2271 const nav_val = zcu.navValue(nav_index);2328 const nav_val = zcu.navValue(nav_index);
2329 const fn_info = zcu.typeToFunc(nav_val.typeOf(zcu)).?;
2272 const nav = ip.getNav(nav_index);2330 const nav = ip.getNav(nav_index);
22732331
2332 if (Type.fromInterned(fn_info.return_type).isNoReturn(zcu)) try fwd_decl_writer.writeAll("zig_noreturn ");
2274 try fwd_decl_writer.writeAll("static ");2333 try fwd_decl_writer.writeAll("static ");
2275 try f.dg.renderFunctionSignature(2334 try f.dg.renderFunctionSignature(
2276 fwd_decl_writer,2335 fwd_decl_writer,
...@@ -2291,11 +2350,41 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E...@@ -2291,11 +2350,41 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E
2291 .{ .nav = nav_index },2350 .{ .nav = nav_index },
2292 );2351 );
2293 try header_writer.writeAll(" {\n ");2352 try header_writer.writeAll(" {\n ");
2353 if (!f.dg.mod.strip) try header_writer.print("/* {f} */\n ", .{nav.fqn.fmt(ip)});
22942354
2295 f.free_locals_map.clearRetainingCapacity();2355 f.free_locals_map.clearRetainingCapacity();
22962356
2297 const main_body = f.air.getMainBody();2357 const main_body = f.air.getMainBody();
2298 f.indent();2358 f.indent();
2359 if (switch (fn_info.cc) {
2360 inline else => |pl| switch (@TypeOf(pl)) {
2361 void,
2362 std.lang.CallingConvention.SpirvKernelOptions,
2363 std.lang.CallingConvention.SpirvFragmentOptions,
2364 std.lang.CallingConvention.SpirvMeshOptions,
2365 => null,
2366 std.lang.CallingConvention.ArcInterruptOptions,
2367 std.lang.CallingConvention.ArmInterruptOptions,
2368 std.lang.CallingConvention.RiscvInterruptOptions,
2369 std.lang.CallingConvention.ShInterruptOptions,
2370 std.lang.CallingConvention.MicroblazeInterruptOptions,
2371 std.lang.CallingConvention.MipsInterruptOptions,
2372 std.lang.CallingConvention.CommonOptions,
2373 std.lang.CallingConvention.X86RegparmOptions,
2374 => pl.incoming_stack_alignment,
2375 else => @compileError(@tagName(pl)),
2376 },
2377 }) |incoming_stack_alignment| realign_stack: {
2378 const normal_stack_align = zcu.getTarget().stackAlignment();
2379 if (incoming_stack_alignment >= normal_stack_align) break :realign_stack;
2380 try header_writer.print("char zig_align({d}) zig_realign_stack;\n ", .{
2381 normal_stack_align << 1,
2382 });
2383 try f.code.writer.writeAll(
2384 \\__asm volatile("" :: [zig_realign_stack] "m" (zig_realign_stack));
2385 );
2386 try f.newline();
2387 }
2299 try genBodyResolveState(f, undefined, &.{}, main_body, true);2388 try genBodyResolveState(f, undefined, &.{}, main_body, true);
2300 try f.outdent();2389 try f.outdent();
2301 try f.code.writer.writeByte('}');2390 try f.code.writer.writeByte('}');
...@@ -2346,6 +2435,7 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E...@@ -2346,6 +2435,7 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E
2346 for (list.keys()) |local_index| {2435 for (list.keys()) |local_index| {
2347 const local = f.locals.items[local_index];2436 const local = f.locals.items[local_index];
2348 try f.dg.renderTypeAndName(header_writer, local.type, .{ .local = local_index }, .{}, local.alignment);2437 try f.dg.renderTypeAndName(header_writer, local.type, .{ .local = local_index }, .{}, local.alignment);
2438 if (local.array_len != 1) try header_writer.print("[{d}]", .{local.array_len});
2349 try header_writer.writeAll(";\n ");2439 try header_writer.writeAll(";\n ");
2350 }2440 }
2351 }2441 }
...@@ -2397,10 +2487,12 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void {...@@ -2397,10 +2487,12 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void {
23972487
2398 .@"extern" => |@"extern"| switch (nav_ty.zigTypeTag(zcu)) {2488 .@"extern" => |@"extern"| switch (nav_ty.zigTypeTag(zcu)) {
2399 .@"fn" => {2489 .@"fn" => {
2490 const fn_val: Value = .fromInterned(nav.resolved.?.value);
2491 if (fn_val.typeOf(zcu).fnReturnType(zcu).isNoReturn(zcu)) try w.writeAll("zig_noreturn ");
2400 try w.writeAll("zig_extern ");2492 try w.writeAll("zig_extern ");
2401 try dg.renderFunctionSignature(2493 try dg.renderFunctionSignature(
2402 w,2494 w,
2403 .fromInterned(nav.resolved.?.value),2495 fn_val,
2404 nav.resolved.?.@"align",2496 nav.resolved.?.@"align",
2405 .forward_decl,2497 .forward_decl,
2406 .{ .@"export" = .{2498 .{ .@"export" = .{
...@@ -2461,7 +2553,12 @@ pub fn genDeclValue(dg: *DeclGen, w: *Writer, options: struct {...@@ -2461,7 +2553,12 @@ pub fn genDeclValue(dg: *DeclGen, w: *Writer, options: struct {
2461 try dg.renderTypeAndName(w, ty, options.name, .{ .@"const" = options.@"const" }, .none);2553 try dg.renderTypeAndName(w, ty, options.name, .{ .@"const" = options.@"const" }, .none);
2462 try w.writeAll(" = ");2554 try w.writeAll(" = ");
2463 try dg.renderValue(w, options.init_val, .static_initializer);2555 try dg.renderValue(w, options.init_val, .static_initializer);
2464 try w.writeAll(";\n");2556 try w.writeByte(';');
2557 if (dg.owner_nav.unwrap()) |nav_index| {
2558 const ip = &zcu.intern_pool;
2559 if (!dg.mod.strip) try w.print(" /* {f} */", .{ip.getNav(nav_index).fqn.fmt(ip)});
2560 }
2561 try w.writeByte('\n');
2465}2562}
2466pub fn genDeclValueFwd(dg: *DeclGen, w: *Writer, options: struct {2563pub fn genDeclValueFwd(dg: *DeclGen, w: *Writer, options: struct {
2467 name: CValue,2564 name: CValue,
...@@ -2496,11 +2593,13 @@ pub fn genExports(dg: *DeclGen, w: *Writer, exported: Zcu.Exported, export_indic...@@ -2496,11 +2593,13 @@ pub fn genExports(dg: *DeclGen, w: *Writer, exported: Zcu.Exported, export_indic
2496 const exported_val = exported.getValue(zcu);2593 const exported_val = exported.getValue(zcu);
2497 if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| {2594 if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| {
2498 const @"export" = export_index.ptr(zcu);2595 const @"export" = export_index.ptr(zcu);
2596 const fn_val = exported.getValue(zcu);
2597 if (fn_val.typeOf(zcu).fnReturnType(zcu).isNoReturn(zcu)) try w.writeAll("zig_noreturn ");
2499 try w.writeAll("zig_extern ");2598 try w.writeAll("zig_extern ");
2500 if (@"export".opts.linkage == .weak) try w.writeAll("zig_weak_linkage_fn ");2599 if (@"export".opts.linkage == .weak) try w.writeAll("zig_weak_linkage_fn ");
2501 try dg.renderFunctionSignature(2600 try dg.renderFunctionSignature(
2502 w,2601 w,
2503 exported.getValue(zcu),2602 fn_val,
2504 exported.getAlign(zcu),2603 exported.getAlign(zcu),
2505 .forward_decl,2604 .forward_decl,
2506 .{ .@"export" = .{2605 .{ .@"export" = .{
...@@ -2662,22 +2761,22 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {...@@ -2662,22 +2761,22 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
2662 .mul => try airBinOp(f, inst, "*", "mul", .none),2761 .mul => try airBinOp(f, inst, "*", "mul", .none),
26632762
2664 .neg => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "neg", .none),2763 .neg => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "neg", .none),
2665 .div_float => try airBinBuiltinCall(f, inst, "div", .none),2764 .div_float => try airBinBuiltinCall(f, inst, "div", .big_temp_bits),
26662765
2667 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),2766 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "divTrunc", .big_temp_bits),
2668 .rem => blk: {2767 .rem => blk: {
2669 const bin_op = air_datas[@intFromEnum(inst)].bin_op;2768 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
2670 const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(zcu);2769 const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(zcu);
2671 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),2770 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
2672 // so we only check one.2771 // so we only check one.
2673 break :blk if (lhs_scalar_ty.isInt(zcu))2772 break :blk if (lhs_scalar_ty.isInt(zcu))
2674 try airBinOp(f, inst, "%", "rem", .none)2773 try airBinOp(f, inst, "%", "rem", .big_temp_bits)
2675 else2774 else
2676 try airBinBuiltinCall(f, inst, "fmod", .none);2775 try airBinBuiltinCall(f, inst, "fmod", .none);
2677 },2776 },
2678 .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .none),2777 .div_floor => try airBinBuiltinCall(f, inst, "divFloor", .big_temp_bits),
2679 .div_ceil => try airBinBuiltinCall(f, inst, "div_ceil", .none),2778 .div_ceil => try airBinBuiltinCall(f, inst, "divCeil", .big_temp_bits),
2680 .mod => try airBinBuiltinCall(f, inst, "mod", .none),2779 .mod => try airBinBuiltinCall(f, inst, "mod", .big_temp_bits),
2681 .abs => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "abs", .none),2780 .abs => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "abs", .none),
26822781
2683 .add_wrap => try airBinBuiltinCall(f, inst, "addw", .bits),2782 .add_wrap => try airBinBuiltinCall(f, inst, "addw", .bits),
...@@ -2687,7 +2786,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {...@@ -2687,7 +2786,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
2687 .add_sat => try airBinBuiltinCall(f, inst, "adds", .bits),2786 .add_sat => try airBinBuiltinCall(f, inst, "adds", .bits),
2688 .sub_sat => try airBinBuiltinCall(f, inst, "subs", .bits),2787 .sub_sat => try airBinBuiltinCall(f, inst, "subs", .bits),
2689 .mul_sat => try airBinBuiltinCall(f, inst, "muls", .bits),2788 .mul_sat => try airBinBuiltinCall(f, inst, "muls", .bits),
2690 .shl_sat => try airBinBuiltinCall(f, inst, "shls", .bits),2789 .shl_sat => try airBinBuiltinCall(f, inst, "shls", .bits_none),
26912790
2692 .sqrt => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sqrt", .none),2791 .sqrt => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sqrt", .none),
2693 .sin => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sin", .none),2792 .sin => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sin", .none),
...@@ -2764,8 +2863,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {...@@ -2764,8 +2863,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
2764 .int_from_error => try airNopCast(f, inst),2863 .int_from_error => try airNopCast(f, inst),
2765 .union_from_enum => try airUnionFromEnum(f, inst),2864 .union_from_enum => try airUnionFromEnum(f, inst),
2766 .bit_cast => try airBitCast(f, inst),2865 .bit_cast => try airBitCast(f, inst),
2767 .int_cast => try airIntCast(f, inst),2866 .int_cast => try airIntCast(f, inst, "intCast", .none),
2768 .trunc => try airTrunc(f, inst),2867 .trunc => try airIntCast(f, inst, "truncate", .bits),
2769 .load => try airLoad(f, inst),2868 .load => try airLoad(f, inst),
2770 .store => try airStore(f, inst, false),2869 .store => try airStore(f, inst, false),
2771 .store_safe => try airStore(f, inst, true),2870 .store_safe => try airStore(f, inst, true),
...@@ -2783,9 +2882,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {...@@ -2783,9 +2882,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
2783 .get_union_tag => try airGetUnionTag(f, inst),2882 .get_union_tag => try airGetUnionTag(f, inst),
2784 .clz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "clz", .bits),2883 .clz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "clz", .bits),
2785 .ctz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "ctz", .bits),2884 .ctz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "ctz", .bits),
2786 .popcount => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "popcount", .bits),2885 .popcount => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "popCount", .bits),
2787 .byte_swap => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "byte_swap", .bits),2886 .byte_swap => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "byteSwap", .bits),
2788 .bit_reverse => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "bit_reverse", .bits),2887 .bit_reverse => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "bitReverse", .bits),
2789 .tag_name => try airTagName(f, inst),2888 .tag_name => try airTagName(f, inst),
2790 .error_name => try airErrorName(f, inst),2889 .error_name => try airErrorName(f, inst),
2791 .splat => try airSplat(f, inst),2890 .splat => try airSplat(f, inst),
...@@ -3124,7 +3223,16 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3124,7 +3223,16 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3124 const zcu = pt.zcu;3223 const zcu = pt.zcu;
3125 const inst_ty = f.typeOfIndex(inst);3224 const inst_ty = f.typeOfIndex(inst);
3126 const elem_ty = inst_ty.childType(zcu);3225 const elem_ty = inst_ty.childType(zcu);
3127 if (!elem_ty.hasRuntimeBits(zcu)) return .{ .undef = inst_ty };3226 if (!elem_ty.hasRuntimeBits(zcu)) {
3227 const w = &f.code.writer;
3228 const local = try f.allocLocal(inst, inst_ty);
3229 try f.writeCValue(w, local, .other);
3230 try w.writeAll(" = ");
3231 try f.dg.renderOpvPointer(w, inst_ty, .other);
3232 try w.writeByte(';');
3233 try f.newline();
3234 return local;
3235 }
31283236
3129 const local = try f.allocLocalValue(.{3237 const local = try f.allocLocalValue(.{
3130 .type = elem_ty,3238 .type = elem_ty,
...@@ -3298,120 +3406,57 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {...@@ -3298,120 +3406,57 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
3298 }3406 }
3299}3407}
33003408
3301fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {3409fn airIntCast(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {
3302 const pt = f.dg.pt;3410 const pt = f.dg.pt;
3303 const zcu = pt.zcu;3411 const zcu = pt.zcu;
3304 const ty_op = f.air.instructions.items(.data)[@backingInt(inst)].ty_op;3412 const ty_op = f.air.instructions.items(.data)[@backingInt(inst)].ty_op;
33053413
3306 const operand = try f.resolveInst(ty_op.operand);3414 const inst_ty = ty_op.ty.toType();
3307 try reap(f, inst, &.{ty_op.operand});
3308
3309 const inst_ty = f.typeOfIndex(inst);
3310 const inst_scalar_ty = inst_ty.scalarType(zcu);3415 const inst_scalar_ty = inst_ty.scalarType(zcu);
3311 const operand_ty = f.typeOf(ty_op.operand);3416 const operand_ty = f.typeOf(ty_op.operand);
3312 const scalar_ty = operand_ty.scalarType(zcu);3417 const operand_scalar_ty = operand_ty.scalarType(zcu);
33133418 const is_big = lowersToBigInt(operand_ty, zcu);
3314 // `intCastIsNoop` doesn't apply to vectors because every vector lowers to a different C struct.
3315 if (inst_ty.zigTypeTag(zcu) != .vector and f.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) {
3316 return f.moveCValue(inst, inst_ty, operand);
3317 }
3318
3319 const w = &f.code.writer;
3320 const local = try f.allocLocal(inst, inst_ty);
3321 const v = try Vectorize.start(f, inst, w, operand_ty);
3322 try f.writeCValue(w, local, .other);
3323 try v.elem(f, w);
3324 try w.writeAll(" = ");
3325 try f.renderIntCast(w, inst_scalar_ty, operand, v, scalar_ty, .other);
3326 try w.writeByte(';');
3327 try f.newline();
3328 try v.end(f, inst, w);
3329 return local;
3330}
3331
3332fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3333 const pt = f.dg.pt;
3334 const zcu = pt.zcu;
3335 const ty_op = f.air.instructions.items(.data)[@backingInt(inst)].ty_op;
33363419
3337 const operand = try f.resolveInst(ty_op.operand);3420 const operand = try f.resolveInst(ty_op.operand);
3338 try reap(f, inst, &.{ty_op.operand});3421 if (!is_big) try reap(f, inst, &.{ty_op.operand});
33393422
3340 const inst_ty = f.typeOfIndex(inst);3423 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
3341 const inst_scalar_ty = inst_ty.scalarType(zcu);3424 const ref_arg = lowersToBigInt(operand_scalar_ty, zcu);
3342 const dest_int_info = inst_scalar_ty.intInfo(zcu);
3343 const dest_bits = dest_int_info.bits;
3344 const dest_c_bits = toCIntBits(dest_bits) orelse
3345 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3346 const operand_ty = f.typeOf(ty_op.operand);
3347 const scalar_ty = operand_ty.scalarType(zcu);
3348 const scalar_int_info = scalar_ty.intInfo(zcu);
3349
3350 const need_cast = dest_c_bits < 64;
3351 const need_lo = scalar_int_info.bits > 64 and dest_bits <= 64;
3352 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);
3353 if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand);
33543425
3355 const w = &f.code.writer;3426 const w = &f.code.writer;
3356 const local = try f.allocLocal(inst, inst_ty);3427 const local = try f.allocLocal(inst, inst_ty);
3428 if (is_big) try reap(f, inst, &.{ty_op.operand});
3357 const v = try Vectorize.start(f, inst, w, operand_ty);3429 const v = try Vectorize.start(f, inst, w, operand_ty);
3358 try f.writeCValue(w, local, .other);3430 if (!ref_ret) {
3359 try v.elem(f, w);3431 try f.writeCValue(w, local, .other);
3360 try w.writeAll(" = ");3432 try v.elem(f, w);
3361 if (need_cast) {3433 try w.writeAll(" = ");
3362 try w.writeByte('(');
3363 try f.renderType(w, inst_scalar_ty);
3364 try w.writeByte(')');
3365 }
3366 if (need_lo) {
3367 try w.writeAll("zig_lo_");
3368 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3369 try w.writeByte('(');
3370 }3434 }
3371 if (!need_mask) {3435 try w.writeAll("zig_");
3372 try f.writeCValue(w, operand, .other);3436 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
3437 try w.print("_{s}_", .{operation});
3438 try f.dg.renderTypeForBuiltinFnName(w, operand_scalar_ty);
3439 try w.writeByte('(');
3440 if (ref_ret) {
3441 try w.writeByte('&');
3442 try f.writeCValue(w, local, .other);
3373 try v.elem(f, w);3443 try v.elem(f, w);
3374 } else switch (dest_int_info.signedness) {3444 try w.writeAll(", ");
3375 .unsigned => {
3376 try w.writeAll("zig_and_");
3377 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3378 try w.writeByte('(');
3379 try f.writeCValue(w, operand, .other);
3380 try v.elem(f, w);
3381 try w.print(", {f})", .{
3382 try f.fmtIntLiteralHex(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),
3383 });
3384 },
3385 .signed => {
3386 const c_bits = toCIntBits(scalar_int_info.bits) orelse
3387 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3388 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);
3389
3390 try w.writeAll("zig_shr_");
3391 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3392 if (c_bits == 128) {
3393 try w.print("(zig_bitCast_i{d}(", .{c_bits});
3394 } else {
3395 try w.print("((int{d}_t)", .{c_bits});
3396 }
3397 try w.print("zig_shl_u{d}(", .{c_bits});
3398 if (c_bits == 128) {
3399 try w.print("zig_bitCast_u{d}(", .{c_bits});
3400 } else {
3401 try w.print("(uint{d}_t)", .{c_bits});
3402 }
3403 try f.writeCValue(w, operand, .other);
3404 try v.elem(f, w);
3405 if (c_bits == 128) try w.writeByte(')');
3406 try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});
3407 if (c_bits == 128) try w.writeByte(')');
3408 try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});
3409 },
3410 }3445 }
3411 if (need_lo) try w.writeByte(')');3446 if (ref_arg) {
3412 try w.writeByte(';');3447 try w.writeByte('&');
3448 switch (operand) {
3449 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
3450 else => try f.writeCValue(w, operand, .other),
3451 }
3452 } else try f.writeCValue(w, operand, .other);
3453 try v.elem(f, w);
3454 try f.dg.renderBuiltinInfo(w, inst_scalar_ty, info);
3455 try f.dg.renderBuiltinInfo(w, operand_scalar_ty, .none);
3456 try w.writeAll(");");
3413 try f.newline();3457 try f.newline();
3414 try v.end(f, inst, w);3458 try v.end(f, inst, w);
3459
3415 return local;3460 return local;
3416}3461}
34173462
...@@ -3525,39 +3570,46 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -3525,39 +3570,46 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
3525 const ty_pl = f.air.instructions.items(.data)[@backingInt(inst)].ty_pl;3570 const ty_pl = f.air.instructions.items(.data)[@backingInt(inst)].ty_pl;
3526 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3571 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
35273572
3573 const lhs_ty = f.typeOf(bin_op.lhs);
3574 const rhs_ty = f.typeOf(bin_op.rhs);
3575 const is_big = lowersToBigInt(lhs_ty, zcu);
3576
3528 const lhs = try f.resolveInst(bin_op.lhs);3577 const lhs = try f.resolveInst(bin_op.lhs);
3529 const rhs = try f.resolveInst(bin_op.rhs);3578 const rhs = try f.resolveInst(bin_op.rhs);
3530 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3579 if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
35313580
3532 const inst_ty = f.typeOfIndex(inst);3581 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
3533 const operand_ty = f.typeOf(bin_op.lhs);3582 const rhs_scalar_ty = rhs_ty.scalarType(zcu);
3534 const scalar_ty = operand_ty.scalarType(zcu);
35353583
3536 const ref_arg = lowersToBigInt(scalar_ty, zcu);3584 const ref_lhs = lowersToBigInt(lhs_scalar_ty, zcu);
3585 const ref_rhs = lowersToBigInt(rhs_scalar_ty, zcu);
35373586
3538 const w = &f.code.writer;3587 const w = &f.code.writer;
3539 const local = try f.allocLocal(inst, inst_ty);3588 const local = try f.allocLocal(inst, f.typeOfIndex(inst));
3540 const v = try Vectorize.start(f, inst, w, operand_ty);3589 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3590 const v = try Vectorize.start(f, inst, w, lhs_ty);
3541 try f.writeCValueMember(w, local, .{ .field = 1 });3591 try f.writeCValueMember(w, local, .{ .field = 1 });
3542 try v.elem(f, w);3592 try v.elem(f, w);
3543 try w.writeAll(" = zig_");3593 try w.writeAll(" = ");
3594 try w.writeAll("zig_");
3544 try w.writeAll(operation);3595 try w.writeAll(operation);
3545 try w.writeAll("o_");3596 try w.writeAll("o_");
3546 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);3597 try f.dg.renderTypeForBuiltinFnName(w, lhs_scalar_ty);
3547 try w.writeByte('(');3598 try w.writeByte('(');
35483599
3549 // '&dest', possibly preceded by a cast3600 // '&dest', possibly preceded by a cast
3550 switch (zcu.intern_pool.indexToKey(scalar_ty.toIntern())) {3601 switch (zcu.intern_pool.indexToKey(lhs_scalar_ty.toIntern())) {
3551 .int_type => {}, // we already have a '[u]intX_t *'3602 .int_type => {}, // we already have a '[u]intX_t *'
3552 .simple_type => {3603 .simple_type => {
3553 // '&dest' will be something like a 'uintptr_t *', which might be a different C type to3604 // '&dest' will be something like a 'uintptr_t *', which might be a different C type to
3554 // the equivalent sized integer (e.g. 'uint64_t *'), so we need a cast. We don't need a3605 // the equivalent sized integer (e.g. 'uint64_t *'), so we need a cast. We don't need a
3555 // cast on the *operands* because they are passed by value (except for big integers,3606 // cast on the *operands* because they are passed by value (except for big integers,
3556 // where this issue doesn't exist because no "simple" int type needs bigint repr).3607 // where this issue doesn't exist because no "simple" int type needs bigint repr).
3557 try w.print("({s}int{d}_t *)", .{3608 const inst_int_info = lhs_scalar_ty.intInfo(zcu);
3558 if (scalar_ty.isUnsignedInt(zcu)) "u" else "",3609 try w.print("({s}int{d}_t *)", .{ switch (inst_int_info.signedness) {
3559 scalar_ty.abiSize(zcu) * 8,3610 .signed => "",
3560 });3611 .unsigned => "u",
3612 }, inst_int_info.bits });
3561 },3613 },
3562 else => unreachable,3614 else => unreachable,
3563 }3615 }
...@@ -3566,14 +3618,24 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -3566,14 +3618,24 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
3566 try v.elem(f, w);3618 try v.elem(f, w);
35673619
3568 try w.writeAll(", ");3620 try w.writeAll(", ");
3569 if (ref_arg) try w.writeByte('&');3621 if (ref_lhs) {
3570 try f.writeCValue(w, lhs, .other);3622 try w.writeByte('&');
3623 switch (lhs) {
3624 .constant => |lhs_val| try f.dg.renderValueAsLvalue(w, lhs_val),
3625 else => try f.writeCValue(w, lhs, .other),
3626 }
3627 } else try f.writeCValue(w, lhs, .other);
3571 try v.elem(f, w);3628 try v.elem(f, w);
3572 try w.writeAll(", ");3629 try w.writeAll(", ");
3573 if (ref_arg) try w.writeByte('&');3630 if (ref_rhs) {
3574 try f.writeCValue(w, rhs, .other);3631 try w.writeByte('&');
3575 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);3632 switch (rhs) {
3576 try f.dg.renderBuiltinInfo(w, scalar_ty, info);3633 .constant => |rhs_val| try f.dg.renderValueAsLvalue(w, rhs_val),
3634 else => try f.writeCValue(w, rhs, .other),
3635 }
3636 } else try f.writeCValue(w, rhs, .other);
3637 try v.elem(f, w);
3638 try f.dg.renderBuiltinInfo(w, lhs_scalar_ty, info);
3577 try w.writeAll(");");3639 try w.writeAll(");");
3578 try f.newline();3640 try f.newline();
3579 try v.end(f, inst, w);3641 try v.end(f, inst, w);
...@@ -3622,8 +3684,18 @@ fn airBinOp(...@@ -3622,8 +3684,18 @@ fn airBinOp(
3622 const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op;3684 const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op;
3623 const operand_ty = f.typeOf(bin_op.lhs);3685 const operand_ty = f.typeOf(bin_op.lhs);
3624 const scalar_ty = operand_ty.scalarType(zcu);3686 const scalar_ty = operand_ty.scalarType(zcu);
3625 if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(zcu) > 64) or scalar_ty.isRuntimeFloat())3687
3626 return try airBinBuiltinCall(f, inst, operation, info);3688 builtin: {
3689 if (scalar_ty.isInt(zcu)) switch (CType.classifyInt(scalar_ty, zcu)) {
3690 .void => unreachable,
3691 .small => |int| switch (int) {
3692 else => break :builtin,
3693 .zig_u128, .zig_i128 => {},
3694 },
3695 .big => {},
3696 } else if (!scalar_ty.isRuntimeFloat()) break :builtin;
3697 return airBinBuiltinCall(f, inst, operation, info);
3698 }
36273699
3628 const lhs = try f.resolveInst(bin_op.lhs);3700 const lhs = try f.resolveInst(bin_op.lhs);
3629 const rhs = try f.resolveInst(bin_op.rhs);3701 const rhs = try f.resolveInst(bin_op.rhs);
...@@ -3662,19 +3734,21 @@ fn airCmpOp(...@@ -3662,19 +3734,21 @@ fn airCmpOp(
3662 const lhs_ty = f.typeOf(data.lhs);3734 const lhs_ty = f.typeOf(data.lhs);
3663 const scalar_ty = lhs_ty.scalarType(zcu);3735 const scalar_ty = lhs_ty.scalarType(zcu);
36643736
3665 if (scalar_ty.isInt(zcu)) {3737 builtin: {
3666 const scalar_bits = scalar_ty.bitSize(zcu);3738 if (scalar_ty.isInt(zcu)) {
3667 if (scalar_bits > 64) return airCmpBuiltinCall(3739 switch (CType.classifyInt(scalar_ty, zcu)) {
3668 f,3740 .void => unreachable,
3669 inst,3741 .small => |int| switch (int) {
3670 data,3742 else => break :builtin,
3671 operator,3743 .zig_u128, .zig_i128 => {},
3672 .cmp,3744 },
3673 if (scalar_bits > 128) .bits else .none,3745 .big => {},
3674 );3746 }
3747 return airCmpBuiltinCall(f, inst, data, operator, .cmp, .none);
3748 }
3749 if (scalar_ty.isRuntimeFloat())
3750 return airCmpBuiltinCall(f, inst, data, operator, .operator, .none);
3675 }3751 }
3676 if (scalar_ty.isRuntimeFloat())
3677 return airCmpBuiltinCall(f, inst, data, operator, .operator, .none);
36783752
3679 const inst_ty = f.typeOfIndex(inst);3753 const inst_ty = f.typeOfIndex(inst);
3680 const lhs = try f.resolveInst(data.lhs);3754 const lhs = try f.resolveInst(data.lhs);
...@@ -3716,21 +3790,23 @@ fn airEquality(...@@ -3716,21 +3790,23 @@ fn airEquality(
3716 const pt = f.dg.pt;3790 const pt = f.dg.pt;
3717 const zcu = pt.zcu;3791 const zcu = pt.zcu;
3718 const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op;3792 const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op;
3719
3720 const operand_ty = f.typeOf(bin_op.lhs);3793 const operand_ty = f.typeOf(bin_op.lhs);
3721 if (operand_ty.isAbiInt(zcu)) {3794
3722 const operand_bits = operand_ty.bitSize(zcu);3795 builtin: {
3723 if (operand_bits > 64) return airCmpBuiltinCall(3796 if (operand_ty.isAbiInt(zcu)) {
3724 f,3797 switch (CType.classifyInt(operand_ty, zcu)) {
3725 inst,3798 .void => unreachable,
3726 bin_op,3799 .small => |int| switch (int) {
3727 operator,3800 else => break :builtin,
3728 .cmp,3801 .zig_u128, .zig_i128 => {},
3729 if (operand_bits > 128) .bits else .none,3802 },
3730 );3803 .big => {},
3804 }
3805 return airCmpBuiltinCall(f, inst, bin_op, operator, .cmp, .none);
3806 }
3807 if (operand_ty.isRuntimeFloat())
3808 return airCmpBuiltinCall(f, inst, bin_op, operator, .operator, .none);
3731 }3809 }
3732 if (operand_ty.isRuntimeFloat())
3733 return airCmpBuiltinCall(f, inst, bin_op, operator, .operator, .none);
37343810
3735 const lhs = try f.resolveInst(bin_op.lhs);3811 const lhs = try f.resolveInst(bin_op.lhs);
3736 const rhs = try f.resolveInst(bin_op.rhs);3812 const rhs = try f.resolveInst(bin_op.rhs);
...@@ -3809,7 +3885,7 @@ fn airCmpLteErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3809,7 +3885,7 @@ fn airCmpLteErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
3809 try f.writeCValue(w, local, .other);3885 try f.writeCValue(w, local, .other);
3810 try w.writeAll(" = ");3886 try w.writeAll(" = ");
3811 try f.writeCValue(w, operand, .other);3887 try f.writeCValue(w, operand, .other);
3812 try w.writeAll(" < sizeof(zig_errorName) / sizeof(*zig_errorName);");3888 try w.writeAll(" <= sizeof(zig_errorName) / sizeof(*zig_errorName);");
3813 try f.newline();3889 try f.newline();
3814 return local;3890 return local;
3815}3891}
...@@ -3862,8 +3938,17 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons...@@ -3862,8 +3938,17 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
3862 const inst_ty = f.typeOfIndex(inst);3938 const inst_ty = f.typeOfIndex(inst);
3863 const inst_scalar_ty = inst_ty.scalarType(zcu);3939 const inst_scalar_ty = inst_ty.scalarType(zcu);
38643940
3865 if ((inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(zcu) > 64) or inst_scalar_ty.isRuntimeFloat())3941 builtin: {
3866 return try airBinBuiltinCall(f, inst, operation, .none);3942 if (inst_scalar_ty.isInt(zcu)) switch (CType.classifyInt(inst_scalar_ty, zcu)) {
3943 .void => unreachable,
3944 .small => |int| switch (int) {
3945 else => break :builtin,
3946 .zig_u128, .zig_i128 => {},
3947 },
3948 .big => {},
3949 } else if (!inst_scalar_ty.isRuntimeFloat()) break :builtin;
3950 return airBinBuiltinCall(f, inst, operation, .none);
3951 }
38673952
3868 const lhs = try f.resolveInst(bin_op.lhs);3953 const lhs = try f.resolveInst(bin_op.lhs);
3869 const rhs = try f.resolveInst(bin_op.rhs);3954 const rhs = try f.resolveInst(bin_op.rhs);
...@@ -3979,10 +4064,7 @@ fn airCall(...@@ -3979,10 +4064,7 @@ fn airCall(
3979 try w.writeAll("(void)");4064 try w.writeAll("(void)");
3980 break :result .none;4065 break :result .none;
3981 } else {4066 } else {
3982 const local = try f.allocAlignedLocal(inst, .{4067 const local = try f.allocAlignedLocal(inst, .{ .type = ret_ty });
3983 .type = ret_ty,
3984 .alignment = .none,
3985 });
3986 try f.writeCValue(w, local, .other);4068 try f.writeCValue(w, local, .other);
3987 try w.writeAll(" = ");4069 try w.writeAll(" = ");
3988 break :result local;4070 break :result local;
...@@ -4058,16 +4140,7 @@ fn airCall(...@@ -4058,16 +4140,7 @@ fn airCall(
4058fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {4140fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4059 const dbg_stmt = f.air.instructions.items(.data)[@backingInt(inst)].dbg_stmt;4141 const dbg_stmt = f.air.instructions.items(.data)[@backingInt(inst)].dbg_stmt;
4060 const w = &f.code.writer;4142 const w = &f.code.writer;
4061 // TODO re-evaluate whether to emit these or not. If we naively emit4143 try w.print("/* {d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
4062 // these directives, the output file will report bogus line numbers because
4063 // every newline after the #line directive adds one to the line.
4064 // We also don't print the filename yet, so the output is strictly unhelpful.
4065 // If we wanted to go this route, we would need to go all the way and not output
4066 // newlines until the next dbg_stmt occurs.
4067 // Perhaps an additional compilation option is in order?
4068 //try w.print("#line {d}", .{dbg_stmt.line + 1});
4069 //try f.newline();
4070 try w.print("/* file:{d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
4071 try f.newline();4144 try f.newline();
4072 return .none;4145 return .none;
4073}4146}
...@@ -4433,12 +4506,12 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue {...@@ -4433,12 +4506,12 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue {
4433 const operand_scalar_ty = operand_ty.scalarType(zcu);4506 const operand_scalar_ty = operand_ty.scalarType(zcu);
4434 const dest_scalar_ty = dest_ty.scalarType(zcu);4507 const dest_scalar_ty = dest_ty.scalarType(zcu);
44354508
4436 // Some cases are handled with a simple cast:
4437 // * float -> float
4438 // * bool -> int
4439 if ((operand_scalar_ty.isRuntimeFloat() and dest_scalar_ty.isRuntimeFloat()) or4509 if ((operand_scalar_ty.isRuntimeFloat() and dest_scalar_ty.isRuntimeFloat()) or
4440 (operand_scalar_ty.toIntern() == .bool_type and dest_scalar_ty.isAbiInt(zcu)))4510 (operand_scalar_ty.toIntern() == .bool_type and dest_scalar_ty.isAbiInt(zcu)))
4441 {4511 {
4512 // Some cases are handled with a simple cast:
4513 // * float -> float
4514 // * bool -> int
4442 try f.writeCValue(w, dest_local, .other);4515 try f.writeCValue(w, dest_local, .other);
4443 try v.elem(f, w);4516 try v.elem(f, w);
4444 try w.writeAll(" = (");4517 try w.writeAll(" = (");
...@@ -4458,85 +4531,44 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue {...@@ -4458,85 +4531,44 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue {
4458 try v.elem(f, w);4531 try v.elem(f, w);
4459 try w.writeAll(" != 0;");4532 try w.writeAll(" != 0;");
4460 try f.newline();4533 try f.newline();
4461 } else if (dest_scalar_ty.isRuntimeFloat()) {
4462 // For int->float, just do a memcpy.
4463 assert(operand_scalar_ty.isAbiInt(zcu));
4464 try w.writeAll("memcpy(&");
4465 try f.writeCValue(w, dest_local, .other);
4466 try v.elem(f, w);
4467 try w.writeAll(", &");
4468 switch (operand) {
4469 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
4470 else => try f.writeCValue(w, operand, .other),
4471 }
4472 try v.elem(f, w);
4473 try w.print(", {d});", .{@min(operand_scalar_ty.abiSize(zcu), dest_scalar_ty.abiSize(zcu))});
4474 try f.newline();
4475 } else {4534 } else {
4476 // The only remaining possibility is that the result is an integer. We will need to use
4477 // `zig_wrap_*` to correct the "padding" bits after we populate the value bits.
4478 assert(dest_scalar_ty.isAbiInt(zcu));
4479 assert(operand_scalar_ty.isRuntimeFloat() or operand_scalar_ty.isAbiInt(zcu));4535 assert(operand_scalar_ty.isRuntimeFloat() or operand_scalar_ty.isAbiInt(zcu));
4536 assert(dest_scalar_ty.isRuntimeFloat() or dest_scalar_ty.isAbiInt(zcu));
44804537
4481 // memcpy the value...4538 const ref_ret = lowersToBigInt(dest_scalar_ty, zcu);
4482 try w.writeAll("memcpy(&");4539 const ref_arg = lowersToBigInt(operand_scalar_ty, zcu);
4483 try f.writeCValue(w, dest_local, .other);4540
4484 try v.elem(f, w);4541 if (!ref_ret) {
4485 try w.writeAll(", &");4542 try f.writeCValue(w, dest_local, .other);
4486 switch (operand) {4543 try v.elem(f, w);
4487 .constant => |val| try f.dg.renderValueAsLvalue(w, val),4544 try w.writeAll(" = ");
4488 else => try f.writeCValue(w, operand, .other),
4489 }4545 }
4546 try w.writeAll("zig_");
4547 try f.dg.renderTypeForBuiltinFnName(w, dest_scalar_ty);
4548 try w.writeAll("_bitCast_");
4549 try f.dg.renderTypeForBuiltinFnName(w, operand_scalar_ty);
4550 try w.writeByte('(');
4551 if (ref_ret) {
4552 try w.writeByte('&');
4553 try f.writeCValue(w, dest_local, .other);
4554 try v.elem(f, w);
4555 try w.writeAll(", ");
4556 }
4557 if (ref_arg) {
4558 try w.writeByte('&');
4559 switch (operand) {
4560 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
4561 else => try f.writeCValue(w, operand, .other),
4562 }
4563 } else try f.writeCValue(w, operand, .other);
4490 try v.elem(f, w);4564 try v.elem(f, w);
4491 try w.print(", {d});", .{@min(operand_scalar_ty.abiSize(zcu), dest_scalar_ty.abiSize(zcu))});4565 try f.dg.renderBuiltinInfo(
4566 w,
4567 dest_scalar_ty,
4568 if (operand_scalar_ty.isRuntimeFloat() or dest_scalar_ty.isRuntimeFloat()) .none else .bits,
4569 );
4570 try w.writeAll(");");
4492 try f.newline();4571 try f.newline();
4493
4494 // ...and ensure padding bits have the correct value.
4495 switch (CType.classifyInt(dest_scalar_ty, zcu)) {
4496 .void => unreachable, // opv
4497 .small => {
4498 try f.writeCValue(w, dest_local, .other);
4499 try v.elem(f, w);
4500 try w.writeAll(" = zig_wrap_");
4501 try f.dg.renderTypeForBuiltinFnName(w, dest_scalar_ty);
4502 try w.writeByte('(');
4503 try f.writeCValue(w, dest_local, .other);
4504 try v.elem(f, w);
4505 try f.dg.renderBuiltinInfo(w, dest_scalar_ty, .bits);
4506 try w.writeAll(");");
4507 try f.newline();
4508 },
4509 .big => |big| {
4510 const dest_info = dest_scalar_ty.intInfo(zcu);
4511 const padding_index: u16 = switch (f.dg.mod.resolved_target.result.cpu.arch.endian()) {
4512 .little => big.limbs_len - 1,
4513 .big => 0,
4514 };
4515 const wrap_bits = ((dest_info.bits - 1) % big.limb_size.bits()) + 1;
4516 if (big.limb_size != .@"128" or dest_info.signedness == .unsigned) {
4517 try f.writeCValue(w, dest_local, .other);
4518 try v.elem(f, w);
4519 try w.print(".limbs[{d}] = zig_wrap_{c}{d}(", .{
4520 padding_index,
4521 signAbbrev(dest_info.signedness),
4522 big.limb_size.bits(),
4523 });
4524 try f.writeCValue(w, dest_local, .other);
4525 try v.elem(f, w);
4526 try w.print(".limbs[{d}], {d});", .{ padding_index, wrap_bits });
4527 } else {
4528 try f.writeCValue(w, dest_local, .other);
4529 try v.elem(f, w);
4530 try w.print(".limbs[{d}] = zig_bitCast_u128(zig_wrap_i128(zig_bitCast_i128(", .{
4531 padding_index,
4532 });
4533 try f.writeCValue(w, dest_local, .other);
4534 try v.elem(f, w);
4535 try w.print(".limbs[{d}]), {d}));", .{ padding_index, wrap_bits });
4536 try f.newline();
4537 }
4538 },
4539 }
4540 }4572 }
45414573
4542 try v.end(f, inst, w);4574 try v.end(f, inst, w);
...@@ -4906,11 +4938,9 @@ fn lowerSwitchCmp(...@@ -4906,11 +4938,9 @@ fn lowerSwitchCmp(
49064938
4907fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {4939fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {
4908 const dg = f.dg;4940 const dg = f.dg;
4909 const target = &dg.mod.resolved_target.result;
4910 return switch (constraint[0]) {4941 return switch (constraint[0]) {
4911 '{' => true,4942 '{' => true,
4912 'i', 'r' => false,4943 'r', 'i', 'n', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P' => false,
4913 'I' => !target.cpu.arch.isArm(),
4914 else => switch (value) {4944 else => switch (value) {
4915 .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) {4945 .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
4916 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {4946 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
...@@ -4937,10 +4967,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4937,10 +4967,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4937 const w = &f.code.writer;4967 const w = &f.code.writer;
4938 const inst_ty = f.typeOfIndex(inst);4968 const inst_ty = f.typeOfIndex(inst);
4939 const inst_local = if (inst_ty.hasRuntimeBits(zcu)) local: {4969 const inst_local = if (inst_ty.hasRuntimeBits(zcu)) local: {
4940 const inst_local = try f.allocLocalValue(.{4970 const inst_local = try f.allocLocalValue(.{ .type = inst_ty });
4941 .type = inst_ty,
4942 .alignment = .none,
4943 });
4944 if (f.wantSafety()) {4971 if (f.wantSafety()) {
4945 try f.writeCValue(w, inst_local, .other);4972 try f.writeCValue(w, inst_local, .other);
4946 try w.writeAll(" = ");4973 try w.writeAll(" = ");
...@@ -4967,10 +4994,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4967,10 +4994,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4967 if (is_reg) {4994 if (is_reg) {
4968 const output_ty = if (output.operand == .none) inst_ty else f.typeOf(output.operand).childType(zcu);4995 const output_ty = if (output.operand == .none) inst_ty else f.typeOf(output.operand).childType(zcu);
4969 try w.writeAll("register ");4996 try w.writeAll("register ");
4970 const output_local = try f.allocLocalValue(.{4997 const output_local = try f.allocLocalValue(.{ .type = output_ty });
4971 .type = output_ty,
4972 .alignment = .none,
4973 });
4974 try f.allocs.put(gpa, output_local.new_local, false);4998 try f.allocs.put(gpa, output_local.new_local, false);
4975 try f.dg.renderTypeAndName(w, output_ty, output_local, .{}, .none);4999 try f.dg.renderTypeAndName(w, output_ty, output_local, .{}, .none);
4976 try w.writeAll(" __asm(\"");5000 try w.writeAll(" __asm(\"");
...@@ -5000,10 +5024,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5000,10 +5024,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5000 if (asmInputNeedsLocal(f, constraint, input_val)) {5024 if (asmInputNeedsLocal(f, constraint, input_val)) {
5001 const input_ty = f.typeOf(input.operand);5025 const input_ty = f.typeOf(input.operand);
5002 if (is_reg) try w.writeAll("register ");5026 if (is_reg) try w.writeAll("register ");
5003 const input_local = try f.allocLocalValue(.{5027 const input_local = try f.allocLocalValue(.{ .type = input_ty });
5004 .type = input_ty,
5005 .alignment = .none,
5006 });
5007 try f.allocs.put(gpa, input_local.new_local, false);5028 try f.allocs.put(gpa, input_local.new_local, false);
5008 // Do not render the declaration as `const` qualified if we're generating an5029 // Do not render the declaration as `const` qualified if we're generating an
5009 // explicit `register` local, as GCC will ignore the constraint completely.5030 // explicit `register` local, as GCC will ignore the constraint completely.
...@@ -5853,28 +5874,124 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5853,28 +5874,124 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
5853 else5874 else
5854 unreachable;5875 unreachable;
58555876
5877 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
5878 const ref_operand = lowersToBigInt(scalar_ty, zcu);
5879
5856 const w = &f.code.writer;5880 const w = &f.code.writer;
5857 const local = try f.allocLocal(inst, inst_ty);5881 const local = try f.allocLocal(inst, inst_ty);
5858 const v = try Vectorize.start(f, inst, w, operand_ty);5882 const v = try Vectorize.start(f, inst, w, operand_ty);
5859 try f.writeCValue(w, local, .other);5883 if (ref_ret) {
5860 try v.elem(f, w);5884 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5861 try w.writeAll(" = ");5885 if (inst_int_info.bits <= 128) {
5886 try w.writeAll("zig_");
5887 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
5888 try w.print("_intCast_{c}{d}", .{
5889 @as(u8, switch (inst_int_info.signedness) {
5890 .signed => 'i',
5891 .unsigned => 'u',
5892 }),
5893 std.math.ceilPowerOfTwoAssert(u16, @max(inst_int_info.bits, 32)),
5894 });
5895 try w.writeAll("(&");
5896 try f.writeCValue(w, local, .other);
5897 try v.elem(f, w);
5898 try w.writeAll(", ");
5899 }
5900 } else {
5901 try f.writeCValue(w, local, .other);
5902 try v.elem(f, w);
5903 try w.writeAll(" = ");
5904 }
5862 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {5905 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
5863 try w.writeAll("zig_wrap_");5906 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5864 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);5907 if (inst_int_info.bits <= 128) try w.print("zig_{c}{d}_truncate_{[0]c}{[1]d}(", .{
5865 try w.writeByte('(');5908 @as(u8, switch (inst_int_info.signedness) {
5909 .signed => 'i',
5910 .unsigned => 'u',
5911 }),
5912 std.math.ceilPowerOfTwoAssert(u16, @max(inst_int_info.bits, 32)),
5913 });
5866 }5914 }
5867 try w.writeAll("zig_");5915 try w.writeAll("zig_");
5868 try w.writeAll(operation);5916 try w.writeAll(operation);
5869 try w.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));5917 try w.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));
5870 try w.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));5918 try w.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));
5871 try w.writeByte('(');5919 try w.writeByte('(');
5872 try f.writeCValue(w, operand, .other);5920 if (ref_ret) {
5873 try v.elem(f, w);5921 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5922 if (inst_int_info.bits > 128) {
5923 try w.writeByte('&');
5924 try f.writeCValue(w, local, .other);
5925 try v.elem(f, w);
5926 try w.writeAll(", ");
5927 }
5928 }
5929 if (ref_operand) {
5930 const operand_int_info = scalar_ty.intInfo(zcu);
5931 if (operand_int_info.bits <= 128) {
5932 try w.print("zig_{c}{d}_intCast_", .{
5933 @as(u8, switch (operand_int_info.signedness) {
5934 .signed => 'i',
5935 .unsigned => 'u',
5936 }),
5937 std.math.ceilPowerOfTwoAssert(u16, @max(operand_int_info.bits, 32)),
5938 });
5939 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
5940 try w.writeAll("(&");
5941 switch (operand) {
5942 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
5943 else => try f.writeCValue(w, operand, .other),
5944 }
5945 try v.elem(f, w);
5946 try f.dg.renderBuiltinInfo(w, scalar_ty, .none);
5947 try w.writeByte(')');
5948 } else {
5949 try w.writeByte('&');
5950 switch (operand) {
5951 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
5952 else => try f.writeCValue(w, operand, .other),
5953 }
5954 try v.elem(f, w);
5955 try w.print(", {f}", .{fmtUnsignedIntLiteralSmall(
5956 target,
5957 .uint16_t,
5958 operand_int_info.bits,
5959 false,
5960 10,
5961 .lower,
5962 )});
5963 }
5964 } else {
5965 try f.writeCValue(w, operand, .other);
5966 try v.elem(f, w);
5967 }
5968 if (ref_ret) {
5969 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5970 if (inst_int_info.bits > 128) try w.print(", {f}", .{fmtUnsignedIntLiteralSmall(
5971 target,
5972 .uint16_t,
5973 inst_int_info.bits,
5974 false,
5975 10,
5976 .lower,
5977 )});
5978 }
5874 try w.writeByte(')');5979 try w.writeByte(')');
5875 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {5980 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
5876 try f.dg.renderBuiltinInfo(w, inst_scalar_ty, .bits);5981 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5877 try w.writeByte(')');5982 if (inst_int_info.bits <= 128) {
5983 try w.print(", {f}", .{
5984 try f.dg.fmtIntLiteralDec(try pt.intValue(.u8, inst_int_info.bits), .other),
5985 });
5986 try w.writeByte(')');
5987 }
5988 }
5989 if (ref_ret) {
5990 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5991 if (inst_int_info.bits <= 128) {
5992 try f.dg.renderBuiltinInfo(w, inst_scalar_ty, .none);
5993 try w.writeByte(')');
5994 }
5878 }5995 }
5879 try w.writeByte(';');5996 try w.writeByte(';');
5880 try f.newline();5997 try f.newline();
...@@ -5893,18 +6010,21 @@ fn airUnBuiltinCall(...@@ -5893,18 +6010,21 @@ fn airUnBuiltinCall(
5893 const pt = f.dg.pt;6010 const pt = f.dg.pt;
5894 const zcu = pt.zcu;6011 const zcu = pt.zcu;
58956012
5896 const operand = try f.resolveInst(operand_ref);
5897 try reap(f, inst, &.{operand_ref});
5898 const inst_ty = f.typeOfIndex(inst);6013 const inst_ty = f.typeOfIndex(inst);
5899 const inst_scalar_ty = inst_ty.scalarType(zcu);6014 const inst_scalar_ty = inst_ty.scalarType(zcu);
5900 const operand_ty = f.typeOf(operand_ref);6015 const operand_ty = f.typeOf(operand_ref);
5901 const scalar_ty = operand_ty.scalarType(zcu);6016 const scalar_ty = operand_ty.scalarType(zcu);
6017 const is_big = lowersToBigInt(operand_ty, zcu);
6018
6019 const operand = try f.resolveInst(operand_ref);
6020 if (!is_big) try reap(f, inst, &.{operand_ref});
59026021
5903 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);6022 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
5904 const ref_arg = lowersToBigInt(scalar_ty, zcu);6023 const ref_arg = lowersToBigInt(scalar_ty, zcu);
59056024
5906 const w = &f.code.writer;6025 const w = &f.code.writer;
5907 const local = try f.allocLocal(inst, inst_ty);6026 const local = try f.allocLocal(inst, inst_ty);
6027 if (is_big) try reap(f, inst, &.{operand_ref});
5908 const v = try Vectorize.start(f, inst, w, operand_ty);6028 const v = try Vectorize.start(f, inst, w, operand_ty);
5909 if (!ref_ret) {6029 if (!ref_ret) {
5910 try f.writeCValue(w, local, .other);6030 try f.writeCValue(w, local, .other);
...@@ -5920,8 +6040,13 @@ fn airUnBuiltinCall(...@@ -5920,8 +6040,13 @@ fn airUnBuiltinCall(
5920 try v.elem(f, w);6040 try v.elem(f, w);
5921 try w.writeAll(", ");6041 try w.writeAll(", ");
5922 }6042 }
5923 if (ref_arg) try w.writeByte('&');6043 if (ref_arg) {
5924 try f.writeCValue(w, operand, .other);6044 try w.writeByte('&');
6045 switch (operand) {
6046 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
6047 else => try f.writeCValue(w, operand, .other),
6048 }
6049 } else try f.writeCValue(w, operand, .other);
5925 try v.elem(f, w);6050 try v.elem(f, w);
5926 try f.dg.renderBuiltinInfo(w, scalar_ty, info);6051 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
5927 try w.writeAll(");");6052 try w.writeAll(");");
...@@ -5941,8 +6066,9 @@ fn airBinBuiltinCall(...@@ -5941,8 +6066,9 @@ fn airBinBuiltinCall(
5941 const zcu = pt.zcu;6066 const zcu = pt.zcu;
5942 const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op;6067 const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op;
59436068
5944 const operand_ty = f.typeOf(bin_op.lhs);6069 const lhs_ty = f.typeOf(bin_op.lhs);
5945 const is_big = lowersToBigInt(operand_ty, zcu);6070 const rhs_ty = f.typeOf(bin_op.rhs);
6071 const is_big = lowersToBigInt(lhs_ty, zcu);
59466072
5947 const lhs = try f.resolveInst(bin_op.lhs);6073 const lhs = try f.resolveInst(bin_op.lhs);
5948 const rhs = try f.resolveInst(bin_op.rhs);6074 const rhs = try f.resolveInst(bin_op.rhs);
...@@ -5950,22 +6076,31 @@ fn airBinBuiltinCall(...@@ -5950,22 +6076,31 @@ fn airBinBuiltinCall(
59506076
5951 const inst_ty = f.typeOfIndex(inst);6077 const inst_ty = f.typeOfIndex(inst);
5952 const inst_scalar_ty = inst_ty.scalarType(zcu);6078 const inst_scalar_ty = inst_ty.scalarType(zcu);
5953 const scalar_ty = operand_ty.scalarType(zcu);6079 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
6080 const rhs_scalar_ty = rhs_ty.scalarType(zcu);
59546081
5955 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);6082 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
5956 const ref_arg = lowersToBigInt(scalar_ty, zcu);6083 const ref_lhs = lowersToBigInt(lhs_scalar_ty, zcu);
6084 const ref_rhs = lowersToBigInt(rhs_scalar_ty, zcu);
59576085
5958 const w = &f.code.writer;6086 const w = &f.code.writer;
5959 const local = try f.allocLocal(inst, inst_ty);6087 const local = try f.allocLocal(inst, inst_ty);
5960 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6088 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
5961 const v = try Vectorize.start(f, inst, w, operand_ty);6089 const v = try Vectorize.start(f, inst, w, lhs_ty);
5962 if (!ref_ret) {6090 if (!ref_ret) {
5963 try f.writeCValue(w, local, .other);6091 try f.writeCValue(w, local, .other);
5964 try v.elem(f, w);6092 try v.elem(f, w);
5965 try w.writeAll(" = ");6093 try w.writeAll(" = ");
5966 }6094 }
5967 try w.print("zig_{s}_", .{operation});6095 try w.print("zig_{s}_", .{operation});
5968 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);6096 try f.dg.renderTypeForBuiltinFnName(w, lhs_scalar_ty);
6097 switch (info) {
6098 .bits, .none, .big_temp_bits => {},
6099 .bits_none => {
6100 try w.writeByte('_');
6101 try f.dg.renderTypeForBuiltinFnName(w, rhs_scalar_ty);
6102 },
6103 }
5969 try w.writeByte('(');6104 try w.writeByte('(');
5970 if (ref_ret) {6105 if (ref_ret) {
5971 try w.writeByte('&');6106 try w.writeByte('&');
...@@ -5973,15 +6108,45 @@ fn airBinBuiltinCall(...@@ -5973,15 +6108,45 @@ fn airBinBuiltinCall(
5973 try v.elem(f, w);6108 try v.elem(f, w);
5974 try w.writeAll(", ");6109 try w.writeAll(", ");
5975 }6110 }
5976 if (ref_arg) try w.writeByte('&');6111 if (ref_lhs) {
5977 try f.writeCValue(w, lhs, .other);6112 try w.writeByte('&');
6113 switch (lhs) {
6114 .constant => |lhs_val| try f.dg.renderValueAsLvalue(w, lhs_val),
6115 else => try f.writeCValue(w, lhs, .other),
6116 }
6117 } else try f.writeCValue(w, lhs, .other);
5978 try v.elem(f, w);6118 try v.elem(f, w);
5979 try w.writeAll(", ");6119 try w.writeAll(", ");
5980 if (ref_arg) try w.writeByte('&');6120 if (ref_rhs) {
5981 try f.writeCValue(w, rhs, .other);6121 try w.writeByte('&');
5982 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);6122 switch (rhs) {
5983 try f.dg.renderBuiltinInfo(w, scalar_ty, info);6123 .constant => |rhs_val| try f.dg.renderValueAsLvalue(w, rhs_val),
5984 try w.writeAll(");\n");6124 else => try f.writeCValue(w, rhs, .other),
6125 }
6126 } else try f.writeCValue(w, rhs, .other);
6127 try v.elem(f, w);
6128 try f.dg.renderBuiltinInfo(w, lhs_scalar_ty, info: switch (info) {
6129 .none => .none,
6130 .bits, .bits_none => .bits,
6131 .big_temp_bits => {
6132 if (lowersToBigInt(lhs_scalar_ty, zcu)) {
6133 const temp_local = try f.allocAlignedLocal(inst, .{
6134 .type = lhs_scalar_ty,
6135 .array_len = 2,
6136 });
6137 try w.writeAll(", &");
6138 try f.writeCValue(w, temp_local, .other);
6139 try freeLocal(f, inst, temp_local.new_local, null);
6140 }
6141 break :info .none;
6142 },
6143 });
6144 switch (info) {
6145 .none, .bits, .big_temp_bits => {},
6146 .bits_none => try f.dg.renderBuiltinInfo(w, rhs_scalar_ty, .none),
6147 }
6148 try w.writeAll(");");
6149 try f.newline();
5985 try v.end(f, inst, w);6150 try v.end(f, inst, w);
59866151
5987 return local;6152 return local;
...@@ -6029,12 +6194,22 @@ fn airCmpBuiltinCall(...@@ -6029,12 +6194,22 @@ fn airCmpBuiltinCall(
6029 try v.elem(f, w);6194 try v.elem(f, w);
6030 try w.writeAll(", ");6195 try w.writeAll(", ");
6031 }6196 }
6032 if (ref_arg) try w.writeByte('&');6197 if (ref_arg) {
6033 try f.writeCValue(w, lhs, .other);6198 try w.writeByte('&');
6199 switch (lhs) {
6200 .constant => |lhs_val| try f.dg.renderValueAsLvalue(w, lhs_val),
6201 else => try f.writeCValue(w, lhs, .other),
6202 }
6203 } else try f.writeCValue(w, lhs, .other);
6034 try v.elem(f, w);6204 try v.elem(f, w);
6035 try w.writeAll(", ");6205 try w.writeAll(", ");
6036 if (ref_arg) try w.writeByte('&');6206 if (ref_arg) {
6037 try f.writeCValue(w, rhs, .other);6207 try w.writeByte('&');
6208 switch (rhs) {
6209 .constant => |rhs_val| try f.dg.renderValueAsLvalue(w, rhs_val),
6210 else => try f.writeCValue(w, rhs, .other),
6211 }
6212 } else try f.writeCValue(w, rhs, .other);
6038 try v.elem(f, w);6213 try v.elem(f, w);
6039 try f.dg.renderBuiltinInfo(w, scalar_ty, info);6214 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
6040 try w.writeByte(')');6215 try w.writeByte(')');
...@@ -6595,7 +6770,8 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6595,7 +6770,8 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
6595 },6770 },
6596 .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other),6771 .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other),
6597 }6772 }
6598 try w.writeAll(";\n");6773 try w.writeByte(';');
6774 try f.newline();
6599 }6775 }
66006776
6601 return local;6777 return local;
...@@ -6653,7 +6829,14 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6653,7 +6829,14 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6653 const operand_ty = f.typeOf(reduce.operand);6829 const operand_ty = f.typeOf(reduce.operand);
6654 const w = &f.code.writer;6830 const w = &f.code.writer;
66556831
6656 const use_operator = scalar_ty.bitSize(zcu) <= 64;6832 const use_operator, const is_big = if (scalar_ty.isInt(zcu)) switch (CType.classifyInt(scalar_ty, zcu)) {
6833 .void => unreachable,
6834 .small => |int| switch (int) {
6835 else => .{ true, false },
6836 .zig_u128, .zig_i128 => .{ false, false },
6837 },
6838 .big => .{ false, true },
6839 } else .{ false, false };
6657 const op: union(enum) {6840 const op: union(enum) {
6658 const Func = struct { operation: []const u8, info: BuiltinInfo = .none };6841 const Func = struct { operation: []const u8, info: BuiltinInfo = .none };
6659 builtin: Func,6842 builtin: Func,
...@@ -6742,25 +6925,57 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6742,25 +6925,57 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6742 try f.newline();6925 try f.newline();
67436926
6744 const v = try Vectorize.start(f, inst, w, operand_ty);6927 const v = try Vectorize.start(f, inst, w, operand_ty);
6745 try f.writeCValue(w, accum, .other);
6746 switch (op) {6928 switch (op) {
6747 .builtin => |func| {6929 .builtin => |func| {
6748 try w.print(" = zig_{s}_", .{func.operation});6930 const prev_accum = if (is_big) prev_accum: {
6931 const prev_accum = try f.allocLocal(inst, scalar_ty);
6932 try f.writeCValue(w, prev_accum, .other);
6933 try w.writeAll(" = ");
6934 try f.writeCValue(w, accum, .other);
6935 try w.writeByte(';');
6936 try f.newline();
6937 break :prev_accum prev_accum;
6938 } else prev_accum: {
6939 try f.writeCValue(w, accum, .other);
6940 try w.writeAll(" = ");
6941 break :prev_accum accum;
6942 };
6943 try w.print("zig_{s}_", .{func.operation});
6749 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);6944 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
6750 try w.writeByte('(');6945 try w.writeByte('(');
6751 try f.writeCValue(w, accum, .other);6946 if (is_big) {
6947 try w.writeByte('&');
6948 switch (accum) {
6949 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
6950 else => try f.writeCValue(w, accum, .other),
6951 }
6952 try w.writeAll(", &");
6953 switch (prev_accum) {
6954 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
6955 else => try f.writeCValue(w, prev_accum, .other),
6956 }
6957 } else try f.writeCValue(w, prev_accum, .other);
6752 try w.writeAll(", ");6958 try w.writeAll(", ");
6753 try f.writeCValue(w, operand, .other);6959 if (is_big) {
6960 try w.writeByte('&');
6961 switch (operand) {
6962 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
6963 else => try f.writeCValue(w, operand, .other),
6964 }
6965 } else try f.writeCValue(w, operand, .other);
6754 try v.elem(f, w);6966 try v.elem(f, w);
6755 try f.dg.renderBuiltinInfo(w, scalar_ty, func.info);6967 try f.dg.renderBuiltinInfo(w, scalar_ty, func.info);
6756 try w.writeByte(')');6968 try w.writeByte(')');
6969 if (is_big) try freeLocal(f, inst, prev_accum.new_local, null);
6757 },6970 },
6758 .infix => |ass| {6971 .infix => |ass| {
6972 try f.writeCValue(w, accum, .other);
6759 try w.writeAll(ass);6973 try w.writeAll(ass);
6760 try f.writeCValue(w, operand, .other);6974 try f.writeCValue(w, operand, .other);
6761 try v.elem(f, w);6975 try v.elem(f, w);
6762 },6976 },
6763 .ternary => |cmp| {6977 .ternary => |cmp| {
6978 try f.writeCValue(w, accum, .other);
6764 try w.writeAll(" = ");6979 try w.writeAll(" = ");
6765 try f.writeCValue(w, accum, .other);6980 try f.writeCValue(w, accum, .other);
6766 try w.writeAll(cmp);6981 try w.writeAll(cmp);
...@@ -7097,101 +7312,6 @@ fn writeMemoryOrder(w: *Writer, order: std.lang.AtomicOrder) !void {...@@ -7097,101 +7312,6 @@ fn writeMemoryOrder(w: *Writer, order: std.lang.AtomicOrder) !void {
7097 return w.writeAll(toMemoryOrder(order));7312 return w.writeAll(toMemoryOrder(order));
7098}7313}
70997314
7100fn toCallingConvention(cc: std.lang.CallingConvention, zcu: *Zcu) ?[]const u8 {
7101 if (zcu.getTarget().cCallingConvention()) |ccc| {
7102 if (cc.eql(ccc)) {
7103 return null;
7104 }
7105 }
7106 return switch (cc) {
7107 .auto, .naked => null,
7108
7109 .x86_16_cdecl => "cdecl",
7110 .x86_16_regparmcall => "regparmcall",
7111 .x86_64_sysv, .x86_sysv => "sysv_abi",
7112 .x86_64_win, .x86_win => "ms_abi",
7113 .x86_16_stdcall, .x86_stdcall => "stdcall",
7114 .x86_fastcall => "fastcall",
7115 .x86_thiscall => "thiscall",
7116
7117 .x86_vectorcall,
7118 .x86_64_vectorcall,
7119 => "vectorcall",
7120
7121 .x86_64_regcall_v3_sysv,
7122 .x86_64_regcall_v4_win,
7123 .x86_regcall_v3,
7124 .x86_regcall_v4_win,
7125 => "regcall",
7126
7127 .aarch64_vfabi => "aarch64_vector_pcs",
7128 .aarch64_vfabi_sve => "aarch64_sve_pcs",
7129
7130 .arm_aapcs => "pcs(\"aapcs\")",
7131 .arm_aapcs_vfp => "pcs(\"aapcs-vfp\")",
7132
7133 .arc_interrupt => |opts| switch (opts.type) {
7134 inline else => |t| "interrupt(\"" ++ @tagName(t) ++ "\")",
7135 },
7136
7137 .arm_interrupt => |opts| switch (opts.type) {
7138 .generic => "interrupt",
7139 .irq => "interrupt(\"IRQ\")",
7140 .fiq => "interrupt(\"FIQ\")",
7141 .swi => "interrupt(\"SWI\")",
7142 .abort => "interrupt(\"ABORT\")",
7143 .undef => "interrupt(\"UNDEF\")",
7144 },
7145
7146 .avr_signal => "signal",
7147
7148 .microblaze_interrupt => |opts| switch (opts.type) {
7149 .user => "save_volatiles",
7150 .regular => "interrupt_handler",
7151 .fast => "fast_interrupt",
7152 .breakpoint => "break_handler",
7153 },
7154
7155 .mips_interrupt,
7156 .mips64_interrupt,
7157 => |opts| switch (opts.mode) {
7158 inline else => |m| "interrupt(\"" ++ @tagName(m) ++ "\")",
7159 },
7160
7161 .riscv64_lp64_v, .riscv32_ilp32_v => "riscv_vector_cc",
7162
7163 .riscv32_interrupt,
7164 .riscv64_interrupt,
7165 => |opts| switch (opts.mode) {
7166 inline else => |m| "interrupt(\"" ++ @tagName(m) ++ "\")",
7167 },
7168
7169 .sh_renesas => "renesas",
7170 .sh_interrupt => |opts| switch (opts.save) {
7171 .fpscr => "trapa_handler", // Implies `interrupt_handler`.
7172 .high => "interrupt_handler, nosave_low_regs",
7173 .full => "interrupt_handler",
7174 .bank => "interrupt_handler, resbank",
7175 },
7176
7177 .m68k_rtd => "m68k_rtd",
7178
7179 .avr_interrupt,
7180 .csky_interrupt,
7181 .m68k_interrupt,
7182 .msp430_interrupt,
7183 .x86_16_interrupt,
7184 .x86_interrupt,
7185 .x86_64_interrupt,
7186 => "interrupt",
7187
7188 .ez80_tiflags,
7189 => "__tiflags__",
7190
7191 else => unreachable, // `Zcu.callconvSupported`
7192 };
7193}
7194
7195fn toAtomicRmwSuffix(order: std.lang.AtomicRmwOp) []const u8 {7315fn toAtomicRmwSuffix(order: std.lang.AtomicRmwOp) []const u8 {
7196 return switch (order) {7316 return switch (order) {
7197 .Xchg => "xchg",7317 .Xchg => "xchg",
...@@ -7224,17 +7344,18 @@ fn signAbbrev(signedness: std.lang.Signedness) u8 {...@@ -7224,17 +7344,18 @@ fn signAbbrev(signedness: std.lang.Signedness) u8 {
72247344
7225fn compilerRtAbbrev(ty: Type, zcu: *Zcu, target: *const std.Target) []const u8 {7345fn compilerRtAbbrev(ty: Type, zcu: *Zcu, target: *const std.Target) []const u8 {
7226 return if (ty.isInt(zcu)) switch (ty.intInfo(zcu).bits) {7346 return if (ty.isInt(zcu)) switch (ty.intInfo(zcu).bits) {
7347 0 => unreachable,
7227 1...32 => "si",7348 1...32 => "si",
7228 33...64 => "di",7349 33...64 => "di",
7229 65...128 => "ti",7350 65...128 => "ti",
7230 else => unreachable,7351 else => "ei",
7231 } else if (ty.isRuntimeFloat()) switch (ty.floatBits(target)) {7352 } else if (ty.isRuntimeFloat()) switch (ty.floatBits(target)) {
7353 else => unreachable,
7232 16 => "hf",7354 16 => "hf",
7233 32 => "sf",7355 32 => "sf",
7234 64 => "df",7356 64 => "df",
7235 80 => "xf",7357 80 => "xf",
7236 128 => "tf",7358 128 => if (target.cpu.arch.isPowerPC()) "kf" else "tf",
7237 else => unreachable,
7238 } else unreachable;7359 } else unreachable;
7239}7360}
72407361
...@@ -7390,10 +7511,8 @@ fn fmtStringLiteral(str: []const u8, sentinel: ?u8) std.fmt.Alt(FormatStringCont...@@ -7390,10 +7511,8 @@ fn fmtStringLiteral(str: []const u8, sentinel: ?u8) std.fmt.Alt(FormatStringCont
7390 return .{ .data = .{ .str = str, .sentinel = sentinel } };7511 return .{ .data = .{ .str = str, .sentinel = sentinel } };
7391}7512}
73927513
7393fn undefPattern(comptime IntType: type) IntType {7514fn undefPattern(comptime Result: type) Result {
7394 const int_info = @typeInfo(IntType).int;7515 return @bitCast(@as(@Int(.unsigned, @bitSizeOf(Result)), (1 << (@bitSizeOf(Result) | 1)) / 3));
7395 const UnsignedType = @Int(.unsigned, int_info.bits);
7396 return @bitCast(@as(UnsignedType, (1 << (int_info.bits | 1)) / 3));
7397}7516}
73987517
7399const FormatIntLiteralContext = struct {7518const FormatIntLiteralContext = struct {
...@@ -7580,11 +7699,9 @@ const FormatSignedIntLiteralSmall = struct {...@@ -7580,11 +7699,9 @@ const FormatSignedIntLiteralSmall = struct {
7580 case: std.fmt.Case,7699 case: std.fmt.Case,
7581 pub fn format(data: FormatSignedIntLiteralSmall, w: *Writer) Writer.Error!void {7700 pub fn format(data: FormatSignedIntLiteralSmall, w: *Writer) Writer.Error!void {
7582 const bits = data.int_cty.bits(data.target);7701 const bits = data.int_cty.bits(data.target);
7583 const max_int: i64 = @bitCast((@as(u64, 1) << @intCast(bits - 1)) - 1);7702 if (data.val == @as(i64, std.math.maxInt(i64)) >> @intCast(64 - bits)) {
7584 const min_int: i64 = @bitCast(@as(u64, 1) << @intCast(bits - 1));
7585 if (data.val == max_int) {
7586 return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)});7703 return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)});
7587 } else if (data.val == min_int) {7704 } else if (data.val == @as(i64, std.math.minInt(i64)) >> @intCast(64 - bits)) {
7588 return w.print("{s}_MIN", .{minMaxMacroPrefix(data.int_cty)});7705 return w.print("{s}_MIN", .{minMaxMacroPrefix(data.int_cty)});
7589 }7706 }
7590 if (data.val < 0) try w.writeByte('-');7707 if (data.val < 0) try w.writeByte('-');
...@@ -7596,7 +7713,7 @@ const FormatSignedIntLiteralSmall = struct {...@@ -7596,7 +7713,7 @@ const FormatSignedIntLiteralSmall = struct {
7596 16 => try w.writeAll("0x"),7713 16 => try w.writeAll("0x"),
7597 else => unreachable,7714 else => unreachable,
7598 }7715 }
7599 // This `@abs` is safe thanks to the `min_int` case above.7716 // This `@abs` is safe thanks to the min int check above.
7600 try w.printInt(@abs(data.val), data.base, data.case, .{});7717 try w.printInt(@abs(data.val), data.base, data.case, .{});
7601 try w.writeAll(intLiteralSuffix(data.int_cty));7718 try w.writeAll(intLiteralSuffix(data.int_cty));
7602 }7719 }
...@@ -7610,8 +7727,7 @@ const FormatUnsignedIntLiteralSmall = struct {...@@ -7610,8 +7727,7 @@ const FormatUnsignedIntLiteralSmall = struct {
7610 case: std.fmt.Case,7727 case: std.fmt.Case,
7611 pub fn format(data: FormatUnsignedIntLiteralSmall, w: *Writer) Writer.Error!void {7728 pub fn format(data: FormatUnsignedIntLiteralSmall, w: *Writer) Writer.Error!void {
7612 const bits = data.int_cty.bits(data.target);7729 const bits = data.int_cty.bits(data.target);
7613 const max_int: u64 = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - bits);7730 if (data.val == @as(u64, std.math.maxInt(u64)) >> @intCast(64 - bits)) {
7614 if (data.val == max_int) {
7615 return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)});7731 return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)});
7616 }7732 }
7617 try w.writeAll(intLiteralPrefix(data.int_cty, data.is_global));7733 try w.writeAll(intLiteralPrefix(data.int_cty, data.is_global));
...@@ -7735,6 +7851,31 @@ fn intLiteralSuffix(cty: CType.Int) []const u8 {...@@ -7735,6 +7851,31 @@ fn intLiteralSuffix(cty: CType.Int) []const u8 {
7735 };7851 };
7736}7852}
77377853
7854const F80Repr = packed struct {
7855 mantissa: u64,
7856 exponent: u16,
7857
7858 fn write(repr: F80Repr, w: *Writer, target: *const std.Target, is_global: bool) Writer.Error!void {
7859 try w.print("zig_{s}_repr_f80({f}, {f})", .{
7860 if (is_global) "init" else "make",
7861 fmtUnsignedIntLiteralSmall(target, .uint64_t, repr.mantissa, is_global, 16, .lower),
7862 fmtUnsignedIntLiteralSmall(target, .uint16_t, repr.exponent, is_global, 16, .lower),
7863 });
7864 }
7865};
7866const F128Repr = packed struct {
7867 lo: u64,
7868 hi: u64,
7869
7870 fn write(repr: F128Repr, w: *Writer, target: *const std.Target, is_global: bool) Writer.Error!void {
7871 try w.print("zig_{s}_repr_f128({f}, {f})", .{
7872 if (is_global) "init" else "make",
7873 fmtUnsignedIntLiteralSmall(target, .uint64_t, repr.hi, is_global, 16, .lower),
7874 fmtUnsignedIntLiteralSmall(target, .uint64_t, repr.lo, is_global, 16, .lower),
7875 });
7876 }
7877};
7878
7738const Materialize = struct {7879const Materialize = struct {
7739 local: CValue,7880 local: CValue,
77407881
src/codegen/c/type.zig+198-23
...@@ -44,8 +44,175 @@ pub const CType = union(enum) {...@@ -44,8 +44,175 @@ pub const CType = union(enum) {
44 param_tys: []const CType,44 param_tys: []const CType,
45 ret_ty: *const CType,45 ret_ty: *const CType,
46 varargs: bool,46 varargs: bool,
47 cc: CallingConvention,
47 },48 },
4849
50 pub const CallingConvention = enum {
51 c,
52
53 cdecl,
54 regparmcall,
55 sysv_abi,
56 ms_abi,
57 stdcall,
58 fastcall,
59 thiscall,
60
61 vectorcall,
62
63 regcall,
64
65 aarch64_vector_pcs,
66 aarch64_sve_pcs,
67
68 @"pcs(\"aapcs\")",
69 @"pcs(\"aapcs-vfp\")",
70
71 @"interrupt(\"ilink1\")",
72 @"interrupt(\"ilink2\")",
73 @"interrupt(\"ilink\")",
74 @"interrupt(\"firq\")",
75
76 interrupt,
77 @"interrupt(\"IRQ\")",
78 @"interrupt(\"FIQ\")",
79 @"interrupt(\"SWI\")",
80 @"interrupt(\"ABORT\")",
81 @"interrupt(\"UNDEF\")",
82
83 signal,
84
85 save_volatiles,
86 interrupt_handler,
87 fast_interrupt,
88 break_handler,
89
90 @"interrupt(\"eic\")",
91 @"interrupt(\"sw0\")",
92 @"interrupt(\"sw1\")",
93 @"interrupt(\"hw0\")",
94 @"interrupt(\"hw1\")",
95 @"interrupt(\"hw2\")",
96 @"interrupt(\"hw3\")",
97 @"interrupt(\"hw4\")",
98 @"interrupt(\"hw5\")",
99
100 riscv_vector_cc,
101 @"interrupt(\"supervisor\")",
102 @"interrupt(\"machine\")",
103
104 renesas,
105 /// Implies `interrupt_handler`.
106 trapa_handler,
107 @"interrupt_handler, nosave_low_regs",
108 @"interrupt_handler, resbank",
109
110 m68k_rtd,
111
112 tiflags,
113
114 pub fn fromLang(cc: std.lang.CallingConvention, target: *const std.Target) CallingConvention {
115 if (target.cCallingConvention()) |ccc| {
116 if (cc.eql(ccc)) {
117 return .c;
118 }
119 }
120 return switch (cc) {
121 .auto, .naked => .c,
122
123 .x86_16_cdecl => .cdecl,
124 .x86_16_regparmcall => .regparmcall,
125 .x86_64_sysv, .x86_sysv => .sysv_abi,
126 .x86_64_win, .x86_win, .x86_mingw => .ms_abi,
127 .x86_16_stdcall, .x86_stdcall => .stdcall,
128 .x86_fastcall => .fastcall,
129 .x86_thiscall => .thiscall,
130
131 .x86_vectorcall,
132 .x86_64_vectorcall,
133 => .vectorcall,
134
135 .x86_64_regcall_v3_sysv,
136 .x86_64_regcall_v4_win,
137 .x86_regcall_v3,
138 .x86_regcall_v4_win,
139 => .regcall,
140
141 .aarch64_vfabi => .aarch64_vector_pcs,
142 .aarch64_vfabi_sve => .aarch64_sve_pcs,
143
144 .arm_aapcs => .@"pcs(\"aapcs\")",
145 .arm_aapcs_vfp => .@"pcs(\"aapcs-vfp\")",
146
147 .arc_interrupt => |opts| switch (opts.type) {
148 .ilink1 => .@"interrupt(\"ilink1\")",
149 .ilink2 => .@"interrupt(\"ilink2\")",
150 .ilink => .@"interrupt(\"ilink\")",
151 .firq => .@"interrupt(\"firq\")",
152 },
153
154 .arm_interrupt => |opts| switch (opts.type) {
155 .generic => .interrupt,
156 .irq => .@"interrupt(\"IRQ\")",
157 .fiq => .@"interrupt(\"FIQ\")",
158 .swi => .@"interrupt(\"SWI\")",
159 .abort => .@"interrupt(\"ABORT\")",
160 .undef => .@"interrupt(\"UNDEF\")",
161 },
162
163 .avr_signal => .signal,
164
165 .microblaze_interrupt => |opts| switch (opts.type) {
166 .user => .save_volatiles,
167 .regular => .interrupt_handler,
168 .fast => .fast_interrupt,
169 .breakpoint => .break_handler,
170 },
171
172 .mips_interrupt, .mips64_interrupt => |opts| switch (opts.mode) {
173 .eic => .@"interrupt(\"eic\")",
174 .sw0 => .@"interrupt(\"sw0\")",
175 .sw1 => .@"interrupt(\"sw1\")",
176 .hw0 => .@"interrupt(\"hw0\")",
177 .hw1 => .@"interrupt(\"hw1\")",
178 .hw2 => .@"interrupt(\"hw2\")",
179 .hw3 => .@"interrupt(\"hw3\")",
180 .hw4 => .@"interrupt(\"hw4\")",
181 .hw5 => .@"interrupt(\"hw5\")",
182 },
183
184 .riscv64_lp64_v, .riscv32_ilp32_v => .riscv_vector_cc,
185 .riscv32_interrupt, .riscv64_interrupt => |opts| switch (opts.mode) {
186 .supervisor => .@"interrupt(\"supervisor\")",
187 .machine => .@"interrupt(\"machine\")",
188 },
189
190 .sh_renesas => .renesas,
191 .sh_interrupt => |opts| switch (opts.save) {
192 .fpscr => .trapa_handler,
193 .high => .@"interrupt_handler, nosave_low_regs",
194 .full => .interrupt_handler,
195 .bank => .@"interrupt_handler, resbank",
196 },
197
198 .m68k_rtd => .m68k_rtd,
199
200 .avr_interrupt,
201 .csky_interrupt,
202 .m68k_interrupt,
203 .msp430_interrupt,
204 .x86_16_interrupt,
205 .x86_interrupt,
206 .x86_64_interrupt,
207 => .interrupt,
208
209 .ez80_tiflags => .tiflags,
210
211 else => unreachable, // `Zcu.callconvSupported`
212 };
213 }
214 };
215
49 /// Returns `true` if this node has a postfix operator, meaning an `[...]` or `(...)` appears216 /// Returns `true` if this node has a postfix operator, meaning an `[...]` or `(...)` appears
50 /// after the identifier in a declarator with this type. In this case, if this node is wrapped217 /// after the identifier in a declarator with this type. In this case, if this node is wrapped
51 /// in a pointer type, we will need to add parentheses due to operator precedence.218 /// in a pointer type, we will need to add parentheses due to operator precedence.
...@@ -130,28 +297,28 @@ pub const CType = union(enum) {...@@ -130,28 +297,28 @@ pub const CType = union(enum) {
130 pub fn bits(int: Int, target: *const std.Target) u16 {297 pub fn bits(int: Int, target: *const std.Target) u16 {
131 return switch (int) {298 return switch (int) {
132 // zig fmt: off299 // zig fmt: off
133 .char => target.cTypeBitSize(.char),300 .char => target.cTypeBitSize(.char).?,
134301
135 .@"unsigned short" => target.cTypeBitSize(.ushort),302 .@"unsigned short" => target.cTypeBitSize(.ushort).?,
136 .@"unsigned int" => target.cTypeBitSize(.uint),303 .@"unsigned int" => target.cTypeBitSize(.uint).?,
137 .@"unsigned long" => target.cTypeBitSize(.ulong),304 .@"unsigned long" => target.cTypeBitSize(.ulong).?,
138 .@"unsigned long long" => target.cTypeBitSize(.ulonglong),305 .@"unsigned long long" => target.cTypeBitSize(.ulonglong).?,
139306
140 .@"signed short" => target.cTypeBitSize(.short),307 .@"signed short" => target.cTypeBitSize(.short).?,
141 .@"signed int" => target.cTypeBitSize(.int),308 .@"signed int" => target.cTypeBitSize(.int).?,
142 .@"signed long" => target.cTypeBitSize(.long),309 .@"signed long" => target.cTypeBitSize(.long).?,
143 .@"signed long long" => target.cTypeBitSize(.longlong),310 .@"signed long long" => target.cTypeBitSize(.longlong).?,
144311
145 .uintptr_t, .intptr_t => target.ptrBitWidth(),312 .uintptr_t, .intptr_t => target.ptrBitWidth(),
146313
147 .uint8_t, .int8_t => 8,314 .uint8_t, .int8_t => 8,
148 .uint16_t, .int16_t => 16,315 .uint16_t, .int16_t => 16,
149 .uint24_t, .int24_t => 24,316 .uint24_t, .int24_t => 24,
150 .uint32_t, .int32_t => 32,317 .uint32_t, .int32_t => 32,
151 .uint48_t, .int48_t => 48,318 .uint48_t, .int48_t => 48,
152 .uint64_t, .int64_t => 64,319 .uint64_t, .int64_t => 64,
153 .zig_u128, .zig_i128 => 128,320 .zig_u128, .zig_i128 => 128,
154 // zig fmt: on321 // zig fmt: on
155 };322 };
156 }323 }
157 };324 };
...@@ -376,6 +543,7 @@ pub const CType = union(enum) {...@@ -376,6 +543,7 @@ pub const CType = union(enum) {
376 .ret_ty = ret_cty_buf,543 .ret_ty = ret_cty_buf,
377 .param_tys = param_cty_buf,544 .param_tys = param_cty_buf,
378 .varargs = func_type.is_var_args,545 .varargs = func_type.is_var_args,
546 .cc = .fromLang(func_type.cc, zcu.getTarget()),
379 } };547 } };
380 }548 }
381 try deps.addType(gpa, cur_ty, allow_incomplete);549 try deps.addType(gpa, cur_ty, allow_incomplete);
...@@ -763,6 +931,13 @@ pub const CType = union(enum) {...@@ -763,6 +931,13 @@ pub const CType = union(enum) {
763 try w.writeByte('(');931 try w.writeByte('(');
764 },932 },
765 }933 }
934 switch (ptr.elem_ty.*) {
935 else => {},
936 .function => |function| switch (function.cc) {
937 .c => {},
938 else => |cc| try w.print("zig_callconv({t}) ", .{cc}),
939 },
940 }
766 try w.writeByte('*');941 try w.writeByte('*');
767 },942 },
768943
...@@ -812,7 +987,7 @@ pub const CType = union(enum) {...@@ -812,7 +987,7 @@ pub const CType = union(enum) {
812 => {},987 => {},
813988
814 .pointer => |ptr| {989 .pointer => |ptr| {
815 // Match opening paren "(" write `writeTypePrefix`.990 // Match opening paren "(" in `writeTypePrefix`.
816 switch (ptr.elem_ty.kind()) {991 switch (ptr.elem_ty.kind()) {
817 .specifier, .pointer => {},992 .specifier, .pointer => {},
818 .postfix_op => try w.writeByte(')'),993 .postfix_op => try w.writeByte(')'),
src/codegen/c/type/render_defs.zig+143-155
...@@ -21,16 +21,21 @@ pub fn defineAligned(...@@ -21,16 +21,21 @@ pub fn defineAligned(
21 if (complete and alignment.compareStrict(.lt, ty.abiAlignment(zcu))) {21 if (complete and alignment.compareStrict(.lt, ty.abiAlignment(zcu))) {
22 try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?});22 try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?});
23 }23 }
24 try w.print("{f}{f}{f}; /* align({d}) {f} */\n", .{24 try w.print("{f}{f}{f};", .{
25 cty.fmtDeclaratorPrefix(zcu),25 cty.fmtDeclaratorPrefix(zcu),
26 name_cty.fmtTypeName(zcu),26 name_cty.fmtTypeName(zcu),
27 cty.fmtDeclaratorSuffix(zcu),27 cty.fmtDeclaratorSuffix(zcu),
28 });
29 if (!zcu.comp.config.root_strip) try w.print(" /* align({d}) {f} */", .{
28 alignment.toByteUnits().?,30 alignment.toByteUnits().?,
29 ty.fmt(pt),31 ty.fmt(pt),
30 });32 });
33 try w.writeByte('\n');
31}34}
32/// Renders the definition of a big-int `struct`.35/// Renders the definition of a big-int `struct`.
33pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error!void {36pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error!void {
37 const target = zcu.getTarget();
38 const bits = big.limb_size.bits() *| big.limbs_len;
34 const name_cty: CType = .{ .bigint = .{39 const name_cty: CType = .{ .bigint = .{
35 .limb_size = big.limb_size,40 .limb_size = big.limb_size,
36 .limbs_len = big.limbs_len,41 .limbs_len = big.limbs_len,
...@@ -41,12 +46,20 @@ pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error...@@ -41,12 +46,20 @@ pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error
41 .elem_ty = &limb_cty,46 .elem_ty = &limb_cty,
42 .nonstring = limb_cty.isStringElem(),47 .nonstring = limb_cty.isStringElem(),
43 } };48 } };
44 try w.print("{f} {{ {f}limbs{f}; }}; /* {d} bits */\n", .{49 try w.print("{f} {{ {f}limbs{f}; }};", .{
45 name_cty.fmtTypeName(zcu),50 name_cty.fmtTypeName(zcu),
46 array_cty.fmtDeclaratorPrefix(zcu),51 array_cty.fmtDeclaratorPrefix(zcu),
47 array_cty.fmtDeclaratorSuffix(zcu),52 array_cty.fmtDeclaratorSuffix(zcu),
48 big.limb_size.bits() * @as(u17, big.limbs_len),
49 });53 });
54 if (!zcu.comp.config.root_strip) try w.print(" /* u{d}, i{d} */", .{ bits, bits });
55 try w.writeByte('\n');
56 try writeStaticAssertCTypeLayout(
57 name_cty,
58 std.zig.target.intByteSize(target, bits),
59 .fromByteUnits(std.zig.target.intAlignment(target, bits)),
60 w,
61 zcu,
62 );
50}63}
5164
52/// Renders a forward declaration of the `struct` which represents an error union whose payload type65/// Renders a forward declaration of the `struct` which represents an error union whose payload type
...@@ -81,27 +94,28 @@ pub fn errunionDefineComplete(...@@ -81,27 +94,28 @@ pub fn errunionDefineComplete(
81 if (payload_ty.hasRuntimeBits(zcu)) {94 if (payload_ty.hasRuntimeBits(zcu)) {
82 const payload_cty: CType = try .lower(payload_ty, deps, arena, zcu);95 const payload_cty: CType = try .lower(payload_ty, deps, arena, zcu);
83 try w.print(96 try w.print(
84 \\{f} {{ /* anyerror!{f} */97 \\{f} {{
85 \\ {f}payload{f};98 \\ {f}payload{f};
86 \\ {f}error{f};99 \\ {f}error{f};
87 \\}};100 \\}};
88 \\
89 , .{101 , .{
90 name_cty.fmtTypeName(zcu),102 name_cty.fmtTypeName(zcu),
91 payload_ty.fmt(pt),
92 payload_cty.fmtDeclaratorPrefix(zcu),103 payload_cty.fmtDeclaratorPrefix(zcu),
93 payload_cty.fmtDeclaratorSuffix(zcu),104 payload_cty.fmtDeclaratorSuffix(zcu),
94 error_cty.fmtDeclaratorPrefix(zcu),105 error_cty.fmtDeclaratorPrefix(zcu),
95 error_cty.fmtDeclaratorSuffix(zcu),106 error_cty.fmtDeclaratorSuffix(zcu),
96 });107 });
97 } else {108 } else {
98 try w.print("{f} {{ {f}error{f}; }}; /* anyerror!{f} */\n", .{109 try w.print("{f} {{ {f}error{f}; }};", .{
99 name_cty.fmtTypeName(zcu),110 name_cty.fmtTypeName(zcu),
100 error_cty.fmtDeclaratorPrefix(zcu),111 error_cty.fmtDeclaratorPrefix(zcu),
101 error_cty.fmtDeclaratorSuffix(zcu),112 error_cty.fmtDeclaratorSuffix(zcu),
102 payload_ty.fmt(pt),
103 });113 });
104 }114 }
115 if (!zcu.comp.config.root_strip) try w.print(" /* anyerror!{f} */", .{
116 payload_ty.fmt(pt),
117 });
118 try w.writeByte('\n');
105}119}
106120
107/// If the Zig type `ty` lowers to a `struct` or `union` type, renders a forward declaration of that121/// If the Zig type `ty` lowers to a `struct` or `union` type, renders a forward declaration of that
...@@ -141,10 +155,13 @@ pub fn defineIncomplete(ty: Type, w: *Writer, pt: Zcu.PerThread) Writer.Error!vo...@@ -141,10 +155,13 @@ pub fn defineIncomplete(ty: Type, w: *Writer, pt: Zcu.PerThread) Writer.Error!vo
141 },155 },
142 else => return,156 else => return,
143 };157 };
144 try w.print("typedef void {f}; /* {f} */\n", .{158 try w.print("typedef void {f};", .{
145 name_cty.fmtTypeName(zcu),159 name_cty.fmtTypeName(zcu),
160 });
161 if (!zcu.comp.config.root_strip) try w.print(" /* {f} */", .{
146 ty.fmt(pt),162 ty.fmt(pt),
147 });163 });
164 try w.writeByte('\n');
148}165}
149166
150/// If the Zig type `ty` lowers to a `struct` or `union` type, or to a `typedef`, renders the167/// If the Zig type `ty` lowers to a `struct` or `union` type, or to a `typedef`, renders the
...@@ -163,13 +180,13 @@ pub fn defineComplete(...@@ -163,13 +180,13 @@ pub fn defineComplete(
163180
164 ty.assertHasLayout(zcu);181 ty.assertHasLayout(zcu);
165182
166 switch (ty.zigTypeTag(zcu)) {183 const check_cty = check_cty: switch (ty.zigTypeTag(zcu)) {
167 .@"fn" => if (!ty.fnHasRuntimeBits(zcu)) {184 .@"fn" => if (!ty.fnHasRuntimeBits(zcu)) {
168 const name_cty: CType = .{ .@"fn" = ty };185 const name_cty: CType = .{ .@"fn" = ty };
169 try w.print("typedef void {f}; /* {f} */\n", .{186 try w.print("typedef void {f};", .{
170 name_cty.fmtTypeName(zcu),187 name_cty.fmtTypeName(zcu),
171 ty.fmt(pt),
172 });188 });
189 break :check_cty null;
173 } else {190 } else {
174 const ip = &zcu.intern_pool;191 const ip = &zcu.intern_pool;
175 const func_type = ip.indexToKey(ty.toIntern()).func_type;192 const func_type = ip.indexToKey(ty.toIntern()).func_type;
...@@ -186,10 +203,12 @@ pub fn defineComplete(...@@ -186,10 +203,12 @@ pub fn defineComplete(
186 const name_cty: CType = .{ .@"fn" = ty };203 const name_cty: CType = .{ .@"fn" = ty };
187 const ret_cty: CType = try .lower(effective_ret_ty, deps, arena, zcu);204 const ret_cty: CType = try .lower(effective_ret_ty, deps, arena, zcu);
188205
189 try w.print("typedef {f}{f}(", .{206 try w.print("typedef {f}", .{ret_cty.fmtDeclaratorPrefix(zcu)});
190 ret_cty.fmtDeclaratorPrefix(zcu),207 switch (CType.CallingConvention.fromLang(func_type.cc, zcu.getTarget())) {
191 name_cty.fmtTypeName(zcu),208 .c => {},
192 });209 else => |cc| try w.print("zig_callconv({t}) ", .{cc}),
210 }
211 try w.print("{f}(", .{name_cty.fmtTypeName(zcu)});
193 var any_params = false;212 var any_params = false;
194 for (func_type.param_types.get(ip)) |param_ty_ip| {213 for (func_type.param_types.get(ip)) |param_ty_ip| {
195 const param_ty: Type = .fromInterned(param_ty_ip);214 const param_ty: Type = .fromInterned(param_ty_ip);
...@@ -205,88 +224,85 @@ pub fn defineComplete(...@@ -205,88 +224,85 @@ pub fn defineComplete(
205 } else if (!any_params) {224 } else if (!any_params) {
206 try w.writeAll("void");225 try w.writeAll("void");
207 }226 }
208 try w.print("){f}; /* {f} */\n", .{227 try w.print("){f};", .{ret_cty.fmtDeclaratorSuffixIgnoreNonstring(zcu)});
209 ret_cty.fmtDeclaratorSuffixIgnoreNonstring(zcu),228 break :check_cty null;
210 ty.fmt(pt),
211 });
212 },229 },
213 .@"enum" => {230 .@"enum" => {
214 const name_cty: CType = .{ .@"enum" = ty };231 const name_cty: CType = .{ .@"enum" = ty };
215 const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu);232 const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu);
216 try w.print("typedef {f}{f}{f}; /* {f} */\n", .{233 try w.print("typedef {f}{f}{f};", .{
217 cty.fmtDeclaratorPrefix(zcu),234 cty.fmtDeclaratorPrefix(zcu),
218 name_cty.fmtTypeName(zcu),235 name_cty.fmtTypeName(zcu),
219 cty.fmtDeclaratorSuffix(zcu),236 cty.fmtDeclaratorSuffix(zcu),
220 ty.fmt(pt),
221 });237 });
238 break :check_cty null;
222 },239 },
223 .@"struct" => if (ty.isTuple(zcu)) {240 .@"struct" => if (ty.isTuple(zcu))
224 try defineTuple(ty, deps, arena, w, pt);241 if (ty.hasRuntimeBits(zcu)) try defineTuple(ty, deps, arena, w, pt) else return
225 } else switch (ty.containerLayout(zcu)) {242 else switch (ty.containerLayout(zcu)) {
226 .auto, .@"extern" => try defineStruct(ty, deps, arena, w, pt),243 .auto, .@"extern" => if (ty.hasRuntimeBits(zcu)) try defineStruct(ty, deps, arena, w, pt) else return,
227 .@"packed" => try defineBitpack(ty, deps, arena, w, pt),244 .@"packed" => try defineBitpack(ty, deps, arena, w, pt),
228 },245 },
229 .@"union" => switch (ty.containerLayout(zcu)) {246 .@"union" => switch (ty.containerLayout(zcu)) {
230 .auto => try defineUnionAuto(ty, deps, arena, w, pt),247 .auto => if (ty.hasRuntimeBits(zcu)) try defineUnionAuto(ty, deps, arena, w, pt) else return,
231 .@"extern" => try defineUnionExtern(ty, deps, arena, w, pt),248 .@"extern" => if (ty.hasRuntimeBits(zcu)) try defineUnionExtern(ty, deps, arena, w, pt) else return,
232 .@"packed" => try defineBitpack(ty, deps, arena, w, pt),249 .@"packed" => try defineBitpack(ty, deps, arena, w, pt),
233 },250 },
234 .pointer => if (ty.isSlice(zcu)) {251 .pointer => if (ty.isSlice(zcu)) {
235 const name_cty: CType = .{ .slice = ty };252 const name_cty: CType = .{ .slice = ty };
236 const ptr_cty: CType = try .lower(ty.slicePtrFieldType(zcu), deps, arena, zcu);253 const ptr_cty: CType = try .lower(ty.slicePtrFieldType(zcu), deps, arena, zcu);
237 try w.print(254 try w.print(
238 \\{f} {{ /* {f} */255 \\{f} {{
239 \\ {f}ptr{f};256 \\ {f}ptr{f};
240 \\ size_t len;257 \\ uintptr_t len;
241 \\}};258 \\}};
242 \\
243 , .{259 , .{
244 name_cty.fmtTypeName(zcu),260 name_cty.fmtTypeName(zcu),
245 ty.fmt(pt),
246 ptr_cty.fmtDeclaratorPrefix(zcu),261 ptr_cty.fmtDeclaratorPrefix(zcu),
247 ptr_cty.fmtDeclaratorSuffix(zcu),262 ptr_cty.fmtDeclaratorSuffix(zcu),
248 });263 });
249 // Don't bother with `writeStaticAssertLayout`---there's not really any way we could mess264 break :check_cty switch (ty.toIntern()) {
250 // slices up, and they're all obviously the same layout.265 .slice_const_u8_sentinel_0_type => name_cty,
251 },266 else => null,
267 };
268 } else return,
252 .optional => switch (CType.classifyOptional(ty, zcu)) {269 .optional => switch (CType.classifyOptional(ty, zcu)) {
253 .error_set,270 .error_set,
254 .ptr_like,271 .ptr_like,
255 .slice_like,272 .slice_like,
256 .npv_payload,273 .npv_payload,
257 => {},274 => return,
258275
259 .opv_payload => {276 .opv_payload => {
260 const name_cty: CType = .{ .opt = ty };277 const name_cty: CType = .{ .opt = ty };
261 try w.print("{f} {{ bool is_null; }}; /* {f} */\n", .{278 try w.print("{f} {{ bool is_null; }};", .{
262 name_cty.fmtTypeName(zcu),279 name_cty.fmtTypeName(zcu),
263 ty.fmt(pt),
264 });280 });
265 try writeStaticAssertLayout(ty, name_cty, w, zcu);281 break :check_cty switch (ty.toIntern()) {
282 .optional_noreturn_type => name_cty,
283 else => null,
284 };
266 },285 },
267286
268 .@"struct" => {287 .@"struct" => {
269 const name_cty: CType = .{ .opt = ty };288 const name_cty: CType = .{ .opt = ty };
270 const payload_cty: CType = try .lower(ty.optionalChild(zcu), deps, arena, zcu);289 const payload_cty: CType = try .lower(ty.optionalChild(zcu), deps, arena, zcu);
271 try w.print(290 try w.print(
272 \\{f} {{ /* {f} */291 \\{f} {{
273 \\ {f}payload{f};292 \\ {f}payload{f};
274 \\ bool is_null;293 \\ bool is_null;
275 \\}};294 \\}};
276 \\
277 , .{295 , .{
278 name_cty.fmtTypeName(zcu),296 name_cty.fmtTypeName(zcu),
279 ty.fmt(pt),
280 payload_cty.fmtDeclaratorPrefix(zcu),297 payload_cty.fmtDeclaratorPrefix(zcu),
281 payload_cty.fmtDeclaratorSuffix(zcu),298 payload_cty.fmtDeclaratorSuffix(zcu),
282 });299 });
283 try writeStaticAssertLayout(ty, name_cty, w, zcu);300 break :check_cty name_cty;
284 },301 },
285 },302 },
286 .array => if (ty.hasRuntimeBits(zcu)) {303 .array => if (ty.hasRuntimeBits(zcu)) {
287 const elem_ty = ty.childType(zcu);
288 const name_cty: CType = .{ .arr = ty };304 const name_cty: CType = .{ .arr = ty };
289 const elem_cty: CType = try .lower(elem_ty, deps, arena, zcu);305 const elem_cty: CType = try .lower(ty.childType(zcu), deps, arena, zcu);
290 const array_cty: CType = .{ .array = .{306 const array_cty: CType = .{ .array = .{
291 .len = ty.arrayLenIncludingSentinel(zcu),307 .len = ty.arrayLenIncludingSentinel(zcu),
292 .elem_ty = &elem_cty,308 .elem_ty = &elem_cty,
...@@ -296,43 +312,35 @@ pub fn defineComplete(...@@ -296,43 +312,35 @@ pub fn defineComplete(
296 break :nonstring Value.compareHetero(s, .neq, .zero_comptime_int, zcu);312 break :nonstring Value.compareHetero(s, .neq, .zero_comptime_int, zcu);
297 },313 },
298 } };314 } };
299 if (elem_ty.defaultStructFieldAlignment(.auto, zcu) == elem_ty.abiAlignment(zcu)) {315 try w.print("{f} {{ {f}array{f}; }};", .{
300 try w.print("{f} {{ {f}array{f}; }}; /* {f} */\n", .{316 name_cty.fmtTypeName(zcu),
301 name_cty.fmtTypeName(zcu),317 array_cty.fmtDeclaratorPrefix(zcu),
302 array_cty.fmtDeclaratorPrefix(zcu),318 array_cty.fmtDeclaratorSuffix(zcu),
303 array_cty.fmtDeclaratorSuffix(zcu),319 });
304 ty.fmt(pt),320 break :check_cty name_cty;
305 });321 } else return,
306 } else {
307 try w.print("zig_packed({f} {{ zig_under_align({d}) {f}array{f}; }}); /* {f} */\n", .{
308 name_cty.fmtTypeName(zcu),
309 elem_ty.abiAlignment(zcu).toByteUnits().?,
310 array_cty.fmtDeclaratorPrefix(zcu),
311 array_cty.fmtDeclaratorSuffix(zcu),
312 ty.fmt(pt),
313 });
314 }
315 try writeStaticAssertLayout(ty, name_cty, w, zcu);
316 },
317 .vector => if (ty.hasRuntimeBits(zcu)) {322 .vector => if (ty.hasRuntimeBits(zcu)) {
318 const elem_ty = ty.childType(zcu);
319 const name_cty: CType = .{ .vec = ty };323 const name_cty: CType = .{ .vec = ty };
320 const elem_cty: CType = try .lower(elem_ty, deps, arena, zcu);324 const elem_cty: CType = try .lower(ty.childType(zcu), deps, arena, zcu);
321 const array_cty: CType = .{ .array = .{325 const array_cty: CType = .{ .array = .{
322 .len = ty.arrayLenIncludingSentinel(zcu),326 .len = ty.arrayLenIncludingSentinel(zcu),
323 .elem_ty = &elem_cty,327 .elem_ty = &elem_cty,
324 .nonstring = elem_cty.isStringElem(),328 .nonstring = elem_cty.isStringElem(),
325 } };329 } };
326 try w.print("{f} {{ {f}array{f}; }}; /* {f} */\n", .{330 try w.print("{f} {{ {f}array{f}; }};", .{
327 name_cty.fmtTypeName(zcu),331 name_cty.fmtTypeName(zcu),
328 array_cty.fmtDeclaratorPrefix(zcu),332 array_cty.fmtDeclaratorPrefix(zcu),
329 array_cty.fmtDeclaratorSuffix(zcu),333 array_cty.fmtDeclaratorSuffix(zcu),
330 ty.fmt(pt),
331 });334 });
332 try writeStaticAssertLayout(ty, name_cty, w, zcu);335 break :check_cty name_cty;
333 },336 } else return,
334 else => {},337 else => return,
335 }338 };
339 if (!zcu.comp.config.root_strip) try w.print(" /* {f} */", .{
340 ty.fmt(pt),
341 });
342 try w.writeByte('\n');
343 if (check_cty) |cty| try writeStaticAssertTypeLayout(ty, cty, w, zcu);
336}344}
337fn defineBitpack(345fn defineBitpack(
338 ty: Type,346 ty: Type,
...@@ -340,16 +348,16 @@ fn defineBitpack(...@@ -340,16 +348,16 @@ fn defineBitpack(
340 arena: Allocator,348 arena: Allocator,
341 w: *Writer,349 w: *Writer,
342 pt: Zcu.PerThread,350 pt: Zcu.PerThread,
343) (Allocator.Error || Writer.Error)!void {351) (Allocator.Error || Writer.Error)!?CType {
344 const zcu = pt.zcu;352 const zcu = pt.zcu;
345 const name_cty: CType = .{ .bitpack = ty };353 const name_cty: CType = .{ .bitpack = ty };
346 const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu);354 const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu);
347 try w.print("typedef {f}{f}{f}; /* {f} */\n", .{355 try w.print("typedef {f}{f}{f};", .{
348 cty.fmtDeclaratorPrefix(zcu),356 cty.fmtDeclaratorPrefix(zcu),
349 name_cty.fmtTypeName(zcu),357 name_cty.fmtTypeName(zcu),
350 cty.fmtDeclaratorSuffix(zcu),358 cty.fmtDeclaratorSuffix(zcu),
351 ty.fmt(pt),
352 });359 });
360 return null;
353}361}
354fn defineTuple(362fn defineTuple(
355 ty: Type,363 ty: Type,
...@@ -357,72 +365,54 @@ fn defineTuple(...@@ -357,72 +365,54 @@ fn defineTuple(
357 arena: Allocator,365 arena: Allocator,
358 w: *Writer,366 w: *Writer,
359 pt: Zcu.PerThread,367 pt: Zcu.PerThread,
360) (Allocator.Error || Writer.Error)!void {368) (Allocator.Error || Writer.Error)!CType {
361 const zcu = pt.zcu;369 const zcu = pt.zcu;
362 if (!ty.hasRuntimeBits(zcu)) return;
363 const ip = &zcu.intern_pool;370 const ip = &zcu.intern_pool;
364 const tuple = ip.indexToKey(ty.toIntern()).tuple_type;371 const tuple = ip.indexToKey(ty.toIntern()).tuple_type;
365372
366 const tuple_align = ty.abiAlignment(zcu);373 // Fields cannot be underaligned, because tuple fields cannot have specified alignments.
374 // However, overaligned fields are possible thanks to intermediate zero-bit fields.
367375
368 // If there are any underaligned fields, we need to byte-pack the tuple.376 const tuple_align = ty.abiAlignment(zcu);
369 const pack: bool = pack: {
370 var offset: u64 = 0;
371 for (tuple.types.get(ip)) |field_ty_ip| {
372 const field_ty: Type = .fromInterned(field_ty_ip);
373 if (!field_ty.hasRuntimeBits(zcu)) continue;
374 const natural_align = field_ty.defaultStructFieldAlignment(.auto, zcu);
375 const natural_offset = natural_align.forward(offset);
376 offset = field_ty.abiAlignment(zcu).forward(offset);
377 if (offset < natural_offset) break :pack true;
378 // Also pack if any field is more aligned than the tuple should be.
379 if (natural_align.compareStrict(.gt, tuple_align)) break :pack true;
380 offset += field_ty.abiSize(zcu);
381 }
382 break :pack false;
383 };
384377
385 // If the alignment of other fields would not give the tuple sufficient alignment, we378 // If the alignment of other fields would not give the tuple sufficient alignment, we
386 // need to align the first field (which does not affect its offset, because 0 is always379 // need to align the first field (which does not affect its offset, because 0 is always
387 // well-aligned) to indirectly specify the tuple alignment.380 // well-aligned) to indirectly specify the tuple alignment.
388 const overalign: bool = switch (pack) {381 const overalign: bool = for (tuple.types.get(ip)) |field_ty_ip| {
389 true => tuple_align.compareStrict(.gt, .@"1"),382 const field_ty: Type = .fromInterned(field_ty_ip);
390 false => for (tuple.types.get(ip)) |field_ty_ip| {383 if (!field_ty.hasRuntimeBits(zcu)) continue;
391 const field_ty: Type = .fromInterned(field_ty_ip);384 const natural_align = field_ty.abiAlignment(zcu);
392 if (!field_ty.hasRuntimeBits(zcu)) continue;385 if (natural_align.compareStrict(.gte, tuple_align)) break false;
393 const natural_align = field_ty.defaultStructFieldAlignment(.auto, zcu);386 } else true;
394 if (natural_align.compareStrict(.gte, tuple_align)) break false;
395 } else true,
396 };
397387
398 if (pack) try w.writeAll("zig_packed(");
399 const name_cty: CType = .{ .@"struct" = ty };388 const name_cty: CType = .{ .@"struct" = ty };
400 try w.print("{f} {{ /* {f} */\n", .{389 try w.print("{f} {{\n", .{
401 name_cty.fmtTypeName(zcu),390 name_cty.fmtTypeName(zcu),
402 ty.fmt(pt),
403 });391 });
404 var zig_offset: u64 = 0;392 var zig_offset: u64 = 0;
405 var c_offset: u64 = 0;393 var c_offset: u64 = 0;
406 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty_ip, field_val_ip, field_index| {394 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty_ip, field_val_ip, field_index| {
407 if (field_val_ip != .none) continue; // `comptime` field395 if (field_val_ip != .none) continue; // `comptime` field
408 const field_ty: Type = .fromInterned(field_ty_ip);396 const field_ty: Type = .fromInterned(field_ty_ip);
409 zig_offset = field_ty.abiAlignment(zcu).forward(zig_offset);397 const field_align = field_ty.abiAlignment(zcu);
398 zig_offset = field_align.forward(zig_offset);
410 if (!field_ty.hasRuntimeBits(zcu)) continue;399 if (!field_ty.hasRuntimeBits(zcu)) continue;
411 if (!pack) c_offset = field_ty.defaultStructFieldAlignment(.auto, zcu).forward(c_offset);400 c_offset = field_align.forward(c_offset);
412 try w.writeByte(' ');401 try w.writeByte(' ');
413 if (zig_offset == 0 and overalign) {402 if (zig_offset == 0 and overalign) {
414 // This is the first field; specify its alignment to align the tuple.403 // This is the first field; specify its alignment to align the tuple.
415 try writeFieldAlign(field_ty, tuple_align, w, zcu);404 try writeFieldAlign(field_ty, tuple_align, w, zcu);
416 } else if (zig_offset > c_offset) {405 } else switch (zig_offset - c_offset) {
417 // This field needs to be underaligned or overaligned compared to what its406 0 => {},
418 // offset would otherwise be.407 else => |need_bytes| {
419 const need_align: Alignment = .minStrict(408 // This field needs to be overaligned compared to what its offset would otherwise be.
420 tuple_align, // don't make the tuple more aligned than it should be409 const need_align: Alignment = .fromLog2Units(std.math.log2_int(u64, need_bytes) + 1);
421 .fromLog2Units(@ctz(zig_offset)),410 assert(need_align.compareStrict(.lte, tuple_align));
422 );411 try writeFieldAlign(field_ty, need_align, w, zcu);
423 try writeFieldAlign(field_ty, need_align, w, zcu);412 c_offset = need_align.forward(c_offset);
424 c_offset = need_align.forward(c_offset);413 },
425 }414 }
415 assert(c_offset == zig_offset);
426 const field_cty: CType = try .lower(field_ty, deps, arena, zcu);416 const field_cty: CType = try .lower(field_ty, deps, arena, zcu);
427 try w.print("{f}f{d}{f};\n", .{417 try w.print("{f}f{d}{f};\n", .{
428 field_cty.fmtDeclaratorPrefix(zcu),418 field_cty.fmtDeclaratorPrefix(zcu),
...@@ -433,11 +423,8 @@ fn defineTuple(...@@ -433,11 +423,8 @@ fn defineTuple(
433 zig_offset += field_size;423 zig_offset += field_size;
434 c_offset += field_size;424 c_offset += field_size;
435 }425 }
436 try w.writeByte('}');426 try w.writeAll("};");
437 if (pack) try w.writeByte(')');427 return name_cty;
438 try w.writeAll(";\n");
439
440 try writeStaticAssertLayout(ty, name_cty, w, zcu);
441}428}
442fn defineStruct(429fn defineStruct(
443 ty: Type,430 ty: Type,
...@@ -445,9 +432,8 @@ fn defineStruct(...@@ -445,9 +432,8 @@ fn defineStruct(
445 arena: Allocator,432 arena: Allocator,
446 w: *Writer,433 w: *Writer,
447 pt: Zcu.PerThread,434 pt: Zcu.PerThread,
448) (Allocator.Error || Writer.Error)!void {435) (Allocator.Error || Writer.Error)!CType {
449 const zcu = pt.zcu;436 const zcu = pt.zcu;
450 if (!ty.hasRuntimeBits(zcu)) return;
451 const ip = &zcu.intern_pool;437 const ip = &zcu.intern_pool;
452438
453 const struct_type = ip.loadStructType(ty.toIntern());439 const struct_type = ip.loadStructType(ty.toIntern());
...@@ -459,7 +445,7 @@ fn defineStruct(...@@ -459,7 +445,7 @@ fn defineStruct(
459 while (it.next()) |field_index| {445 while (it.next()) |field_index| {
460 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);446 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
461 if (!field_ty.hasRuntimeBits(zcu)) continue;447 if (!field_ty.hasRuntimeBits(zcu)) continue;
462 const natural_align = field_ty.defaultStructFieldAlignment(struct_type.layout, zcu);448 const natural_align = field_ty.abiAlignment(zcu);
463 const natural_offset = natural_align.forward(offset);449 const natural_offset = natural_align.forward(offset);
464 const actual_offset = struct_type.field_offsets.get(ip)[field_index];450 const actual_offset = struct_type.field_offsets.get(ip)[field_index];
465 if (actual_offset < natural_offset) break :pack true;451 if (actual_offset < natural_offset) break :pack true;
...@@ -480,7 +466,7 @@ fn defineStruct(...@@ -480,7 +466,7 @@ fn defineStruct(
480 while (it.next()) |field_index| {466 while (it.next()) |field_index| {
481 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);467 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
482 if (!field_ty.hasRuntimeBits(zcu)) continue;468 if (!field_ty.hasRuntimeBits(zcu)) continue;
483 const natural_align = field_ty.defaultStructFieldAlignment(struct_type.layout, zcu);469 const natural_align = field_ty.abiAlignment(zcu);
484 if (natural_align.compareStrict(.gte, struct_type.alignment)) break :overalign false;470 if (natural_align.compareStrict(.gte, struct_type.alignment)) break :overalign false;
485 }471 }
486 break :overalign true;472 break :overalign true;
...@@ -489,16 +475,15 @@ fn defineStruct(...@@ -489,16 +475,15 @@ fn defineStruct(
489475
490 if (pack) try w.writeAll("zig_packed(");476 if (pack) try w.writeAll("zig_packed(");
491 const name_cty: CType = .{ .@"struct" = ty };477 const name_cty: CType = .{ .@"struct" = ty };
492 try w.print("{f} {{ /* {f} */\n", .{478 try w.print("{f} {{\n", .{
493 name_cty.fmtTypeName(zcu),479 name_cty.fmtTypeName(zcu),
494 ty.fmt(pt),
495 });480 });
496 var it = struct_type.iterateRuntimeOrder(ip);481 var it = struct_type.iterateRuntimeOrder(ip);
497 var offset: u64 = 0;482 var offset: u64 = 0;
498 while (it.next()) |field_index| {483 while (it.next()) |field_index| {
499 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);484 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
500 if (!field_ty.hasRuntimeBits(zcu)) continue;485 if (!field_ty.hasRuntimeBits(zcu)) continue;
501 const natural_align = field_ty.defaultStructFieldAlignment(struct_type.layout, zcu);486 const natural_align = field_ty.abiAlignment(zcu);
502 const natural_offset = switch (pack) {487 const natural_offset = switch (pack) {
503 true => offset,488 true => offset,
504 false => natural_align.forward(offset),489 false => natural_align.forward(offset),
...@@ -529,9 +514,8 @@ fn defineStruct(...@@ -529,9 +514,8 @@ fn defineStruct(
529 assert(struct_type.alignment.forward(offset) == struct_type.size);514 assert(struct_type.alignment.forward(offset) == struct_type.size);
530 try w.writeByte('}');515 try w.writeByte('}');
531 if (pack) try w.writeByte(')');516 if (pack) try w.writeByte(')');
532 try w.writeAll(";\n");517 try w.writeByte(';');
533518 return name_cty;
534 try writeStaticAssertLayout(ty, name_cty, w, zcu);
535}519}
536fn defineUnionAuto(520fn defineUnionAuto(
537 ty: Type,521 ty: Type,
...@@ -539,9 +523,8 @@ fn defineUnionAuto(...@@ -539,9 +523,8 @@ fn defineUnionAuto(
539 arena: Allocator,523 arena: Allocator,
540 w: *Writer,524 w: *Writer,
541 pt: Zcu.PerThread,525 pt: Zcu.PerThread,
542) (Allocator.Error || Writer.Error)!void {526) (Allocator.Error || Writer.Error)!CType {
543 const zcu = pt.zcu;527 const zcu = pt.zcu;
544 if (!ty.hasRuntimeBits(zcu)) return;
545 const ip = &zcu.intern_pool;528 const ip = &zcu.intern_pool;
546529
547 const union_type = ip.loadUnionType(ty.toIntern());530 const union_type = ip.loadUnionType(ty.toIntern());
...@@ -553,7 +536,7 @@ fn defineUnionAuto(...@@ -553,7 +536,7 @@ fn defineUnionAuto(
553 const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| {536 const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| {
554 const field_ty: Type = .fromInterned(field_ty_ip);537 const field_ty: Type = .fromInterned(field_ty_ip);
555 if (!field_ty.hasRuntimeBits(zcu)) continue;538 if (!field_ty.hasRuntimeBits(zcu)) continue;
556 const natural_align = field_ty.defaultStructFieldAlignment(.auto, zcu);539 const natural_align = field_ty.abiAlignment(zcu);
557 if (natural_align.compareStrict(.gt, union_type.alignment)) break true;540 if (natural_align.compareStrict(.gt, union_type.alignment)) break true;
558 // The tag will immediately follow the payload. This layout may put the tag in what would541 // The tag will immediately follow the payload. This layout may put the tag in what would
559 // otherwise be padding on the payload union, because if the most-aligned union field is not542 // otherwise be padding on the payload union, because if the most-aligned union field is not
...@@ -571,7 +554,7 @@ fn defineUnionAuto(...@@ -571,7 +554,7 @@ fn defineUnionAuto(
571 false => for (union_type.field_types.get(ip)) |field_ty_ip| {554 false => for (union_type.field_types.get(ip)) |field_ty_ip| {
572 const field_ty: Type = .fromInterned(field_ty_ip);555 const field_ty: Type = .fromInterned(field_ty_ip);
573 if (!field_ty.hasRuntimeBits(zcu)) continue;556 if (!field_ty.hasRuntimeBits(zcu)) continue;
574 const natural_align = field_ty.defaultStructFieldAlignment(.auto, zcu);557 const natural_align = field_ty.abiAlignment(zcu);
575 if (natural_align.compareStrict(.gte, union_type.alignment)) break false;558 if (natural_align.compareStrict(.gte, union_type.alignment)) break false;
576 } else overalign: {559 } else overalign: {
577 if (union_type.has_runtime_tag) {560 if (union_type.has_runtime_tag) {
...@@ -585,9 +568,8 @@ fn defineUnionAuto(...@@ -585,9 +568,8 @@ fn defineUnionAuto(
585 const payload_has_bits = !union_type.has_runtime_tag or union_type.size > enum_tag_ty.abiSize(zcu);568 const payload_has_bits = !union_type.has_runtime_tag or union_type.size > enum_tag_ty.abiSize(zcu);
586569
587 const name_cty: CType = .{ .union_auto = ty };570 const name_cty: CType = .{ .union_auto = ty };
588 try w.print("{f} {{ /* {f} */\n", .{571 try w.print("{f} {{\n", .{
589 name_cty.fmtTypeName(zcu),572 name_cty.fmtTypeName(zcu),
590 ty.fmt(pt),
591 });573 });
592 if (payload_has_bits) {574 if (payload_has_bits) {
593 try w.writeByte(' ');575 try w.writeByte(' ');
...@@ -619,9 +601,8 @@ fn defineUnionAuto(...@@ -619,9 +601,8 @@ fn defineUnionAuto(
619 tag_cty.fmtDeclaratorSuffix(zcu),601 tag_cty.fmtDeclaratorSuffix(zcu),
620 });602 });
621 }603 }
622 try w.writeAll("};\n");604 try w.writeAll("};");
623605 return name_cty;
624 try writeStaticAssertLayout(ty, name_cty, w, zcu);
625}606}
626fn defineUnionExtern(607fn defineUnionExtern(
627 ty: Type,608 ty: Type,
...@@ -629,9 +610,8 @@ fn defineUnionExtern(...@@ -629,9 +610,8 @@ fn defineUnionExtern(
629 arena: Allocator,610 arena: Allocator,
630 w: *Writer,611 w: *Writer,
631 pt: Zcu.PerThread,612 pt: Zcu.PerThread,
632) (Allocator.Error || Writer.Error)!void {613) (Allocator.Error || Writer.Error)!CType {
633 const zcu = pt.zcu;614 const zcu = pt.zcu;
634 if (!ty.hasRuntimeBits(zcu)) return;
635 const ip = &zcu.intern_pool;615 const ip = &zcu.intern_pool;
636616
637 const union_type = ip.loadUnionType(ty.toIntern());617 const union_type = ip.loadUnionType(ty.toIntern());
...@@ -642,7 +622,7 @@ fn defineUnionExtern(...@@ -642,7 +622,7 @@ fn defineUnionExtern(
642 const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| {622 const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| {
643 const field_ty: Type = .fromInterned(field_ty_ip);623 const field_ty: Type = .fromInterned(field_ty_ip);
644 if (!field_ty.hasRuntimeBits(zcu)) continue;624 if (!field_ty.hasRuntimeBits(zcu)) continue;
645 const natural_align = field_ty.defaultStructFieldAlignment(.@"extern", zcu);625 const natural_align = field_ty.abiAlignment(zcu);
646 if (natural_align.compareStrict(.gt, union_type.alignment)) break true;626 if (natural_align.compareStrict(.gt, union_type.alignment)) break true;
647 } else false;627 } else false;
648628
...@@ -654,7 +634,7 @@ fn defineUnionExtern(...@@ -654,7 +634,7 @@ fn defineUnionExtern(
654 false => for (union_type.field_types.get(ip)) |field_ty_ip| {634 false => for (union_type.field_types.get(ip)) |field_ty_ip| {
655 const field_ty: Type = .fromInterned(field_ty_ip);635 const field_ty: Type = .fromInterned(field_ty_ip);
656 if (!field_ty.hasRuntimeBits(zcu)) continue;636 if (!field_ty.hasRuntimeBits(zcu)) continue;
657 const natural_align = field_ty.defaultStructFieldAlignment(.@"extern", zcu);637 const natural_align = field_ty.abiAlignment(zcu);
658 if (natural_align.compareStrict(.gte, union_type.alignment)) break false;638 if (natural_align.compareStrict(.gte, union_type.alignment)) break false;
659 } else overalign: {639 } else overalign: {
660 if (union_type.has_runtime_tag) {640 if (union_type.has_runtime_tag) {
...@@ -668,9 +648,8 @@ fn defineUnionExtern(...@@ -668,9 +648,8 @@ fn defineUnionExtern(
668 if (pack) try w.writeAll("zig_packed(");648 if (pack) try w.writeAll("zig_packed(");
669649
670 const name_cty: CType = .{ .union_extern = ty };650 const name_cty: CType = .{ .union_extern = ty };
671 try w.print("{f} {{ /* {f} */\n", .{651 try w.print("{f} {{\n", .{
672 name_cty.fmtTypeName(zcu),652 name_cty.fmtTypeName(zcu),
673 ty.fmt(pt),
674 });653 });
675654
676 for (0..enum_tag_ty.enumFieldCount(zcu)) |field_index| {655 for (0..enum_tag_ty.enumFieldCount(zcu)) |field_index| {
...@@ -691,9 +670,8 @@ fn defineUnionExtern(...@@ -691,9 +670,8 @@ fn defineUnionExtern(
691 }670 }
692 try w.writeByte('}');671 try w.writeByte('}');
693 if (pack) try w.writeByte(')');672 if (pack) try w.writeByte(')');
694 try w.writeAll(";\n");673 try w.writeByte(';');
695674 return name_cty;
696 try writeStaticAssertLayout(ty, name_cty, w, zcu);
697}675}
698676
699/// Writes an annotation which, placed before a struct/union field declaration with field type `ty`,677/// Writes an annotation which, placed before a struct/union field declaration with field type `ty`,
...@@ -704,7 +682,7 @@ fn writeFieldAlign(...@@ -704,7 +682,7 @@ fn writeFieldAlign(
704 w: *Writer,682 w: *Writer,
705 zcu: *const Zcu,683 zcu: *const Zcu,
706) Writer.Error!void {684) Writer.Error!void {
707 if (alignment.compareStrict(.lt, ty.defaultStructFieldAlignment(.auto, zcu))) {685 if (alignment.compareStrict(.lt, ty.abiAlignment(zcu))) {
708 try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?});686 try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?});
709 } else {687 } else {
710 try w.print("zig_align({d}) ", .{alignment.toByteUnits().?});688 try w.print("zig_align({d}) ", .{alignment.toByteUnits().?});
...@@ -712,19 +690,29 @@ fn writeFieldAlign(...@@ -712,19 +690,29 @@ fn writeFieldAlign(
712}690}
713691
714/// Emits static assertions that the size and alignment of `cty` match those of the Zig type `ty`.692/// Emits static assertions that the size and alignment of `cty` match those of the Zig type `ty`.
715fn writeStaticAssertLayout(693pub fn writeStaticAssertTypeLayout(
716 ty: Type,694 ty: Type,
717 cty: CType,695 cty: CType,
718 w: *Writer,696 w: *Writer,
719 zcu: *const Zcu,697 zcu: *const Zcu,
698) Writer.Error!void {
699 try writeStaticAssertCTypeLayout(cty, ty.abiSize(zcu), ty.abiAlignment(zcu), w, zcu);
700}
701
702/// Emits static assertions that the size and alignment of `cty` match the provided values.
703pub fn writeStaticAssertCTypeLayout(
704 cty: CType,
705 expected_size: u64,
706 expected_alignment: Alignment,
707 w: *Writer,
708 zcu: *const Zcu,
720) Writer.Error!void {709) Writer.Error!void {
721 try w.print(710 try w.print(
722 \\zig_static_assert(sizeof ({f}) == {d}, "incorrect size");711 \\zig_static_assert(sizeof({f}) == {d} && zig_alignOf({f}) == {d}, "abi mismatch");
723 \\zig_static_assert(_Alignof ({f}) == {d}, "incorrect alignment");
724 \\712 \\
725 , .{713 , .{
726 cty.fmtTypeName(zcu), ty.abiSize(zcu),714 cty.fmtTypeName(zcu), expected_size,
727 cty.fmtTypeName(zcu), ty.abiAlignment(zcu).toByteUnits().?,715 cty.fmtTypeName(zcu), expected_alignment.toByteUnits().?,
728 });716 });
729}717}
730718
src/codegen/llvm.zig+693-539
...@@ -345,160 +345,6 @@ pub fn supportsTailCall(target: *const std.Target) bool {...@@ -345,160 +345,6 @@ pub fn supportsTailCall(target: *const std.Target) bool {
345 };345 };
346}346}
347347
348pub fn dataLayout(target: *const std.Target) []const u8 {
349 // These data layouts should match Clang.
350 return switch (target.cpu.arch) {
351 .arc => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32",
352 .xcore => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64:32-a:0:32-n32",
353 .hexagon => "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048",
354 .lanai => "E-m:e-p:32:32-i64:64-a:0:32-n32-S64",
355 .aarch64 => if (target.ofmt == .macho)
356 if (target.os.tag == .windows or target.os.tag == .uefi)
357 "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
358 else if (target.abi == .ilp32)
359 "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
360 else
361 "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
362 else if (target.os.tag == .windows or target.os.tag == .uefi)
363 "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
364 else
365 "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
366 .aarch64_be => "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
367 .arm => if (target.ofmt == .macho)
368 "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
369 else
370 "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
371 .armeb, .thumbeb => if (target.ofmt == .macho)
372 "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
373 else
374 "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
375 .thumb => if (target.ofmt == .macho)
376 "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
377 else if (target.os.tag == .windows or target.os.tag == .uefi)
378 "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
379 else
380 "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
381 .avr => "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8",
382 .bpfeb => "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
383 .bpfel => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
384 .msp430 => "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16",
385 .mips => "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64",
386 .mipsel => "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64",
387 .mips64 => switch (target.abi) {
388 .gnuabin32, .muslabin32, .abin32 => "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
389 else => "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
390 },
391 .mips64el => switch (target.abi) {
392 .gnuabin32, .muslabin32, .abin32 => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
393 else => "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
394 },
395 .m68k => "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16",
396 .powerpc => "E-m:e-p:32:32-Fn32-i64:64-n32",
397 .powerpcle => "e-m:e-p:32:32-Fn32-i64:64-n32",
398 .powerpc64 => switch (target.os.tag) {
399 .linux => "E-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512",
400 .ps3 => "E-m:e-p:32:32-Fi64-i64:64-i128:128-n32:64",
401 else => "E-m:e-Fn32-i64:64-i128:128-n32:64",
402 },
403 .powerpc64le => if (target.os.tag == .linux)
404 "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512"
405 else
406 "e-m:e-Fn32-i64:64-i128:128-n32:64",
407 .nvptx => "e-p:32:32-p6:32:32-p7:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64",
408 .nvptx64 => "e-p6:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64",
409 .amdgcn => "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9",
410 .riscv32 => if (target.cpu.has(.riscv, .e))
411 "e-m:e-p:32:32-i64:64-n32-S32"
412 else
413 "e-m:e-p:32:32-i64:64-n32-S128",
414 .riscv32be => if (target.cpu.has(.riscv, .e))
415 "E-m:e-p:32:32-i64:64-n32-S32"
416 else
417 "E-m:e-p:32:32-i64:64-n32-S128",
418 .riscv64 => if (target.cpu.has(.riscv, .e))
419 "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64"
420 else
421 "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
422 .riscv64be => if (target.cpu.has(.riscv, .e))
423 "E-m:e-p:64:64-i64:64-i128:128-n32:64-S64"
424 else
425 "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
426 .sparc => "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64",
427 .sparc64 => "E-m:e-i64:64-i128:128-n32:64-S128",
428 .s390x => "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64",
429 .x86 => if (target.os.tag == .windows or target.os.tag == .uefi) switch (target.abi) {
430 .gnu => if (target.ofmt == .coff)
431 "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"
432 else
433 "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32",
434 else => blk: {
435 const msvc = switch (target.abi) {
436 .none, .msvc => true,
437 else => false,
438 };
439
440 break :blk if (target.ofmt == .coff)
441 if (msvc)
442 "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
443 else
444 "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"
445 else if (msvc)
446 "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
447 else
448 "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32";
449 },
450 } else if (target.ofmt == .macho)
451 "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
452 else
453 "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128",
454 .x86_64 => if (target.os.tag.isDarwin() or target.ofmt == .macho)
455 "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
456 else switch (target.abi) {
457 .gnux32, .muslx32, .x32 => "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
458 else => if ((target.os.tag == .windows or target.os.tag == .uefi) and target.ofmt == .coff)
459 "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
460 else
461 "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
462 },
463 .spirv32 => switch (target.os.tag) {
464 .vulkan, .opengl => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
465 else => "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
466 },
467 .spirv64 => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
468 .wasm32 => if (target.os.tag == .emscripten)
469 "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-S128-ni:1:10:20"
470 else
471 "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20",
472 .wasm64 => if (target.os.tag == .emscripten)
473 "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-S128-ni:1:10:20"
474 else
475 "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20",
476 .ve => "e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64",
477 .csky => "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32",
478 .loongarch32 => "e-m:e-p:32:32-i64:64-n32-S128",
479 .loongarch64 => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
480 .xtensa => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32",
481
482 .alpha,
483 .arceb,
484 .ez80,
485 .hppa,
486 .hppa64,
487 .kalimba,
488 .kvx,
489 .m88k,
490 .microblaze,
491 .microblazeel,
492 .or1k,
493 .propeller,
494 .sh,
495 .sheb,
496 .x86_16,
497 .xtensaeb,
498 => unreachable, // Gated by hasLlvmSupport().
499 };
500}
501
502// Avoid depending on `bindings.CodeModel` in the bitcode-only case.348// Avoid depending on `bindings.CodeModel` in the bitcode-only case.
503const CodeModel = enum {349const CodeModel = enum {
504 default,350 default,
...@@ -573,6 +419,8 @@ pub const Object = struct {...@@ -573,6 +419,8 @@ pub const Object = struct {
573 val: InternPool.Index,419 val: InternPool.Index,
574 @"addrspace": std.lang.AddressSpace,420 @"addrspace": std.lang.AddressSpace,
575 }, Builder.Variable.Index),421 }, Builder.Variable.Index),
422 /// Same as `uav_map` but for llvm values not originating from the frontend.
423 const_map: std.AutoHashMapUnmanaged(Builder.Constant, Builder.Variable.Index),
576 /// Maps enum types to their corresponding LLVM functions for implementing the `tag_name` instruction.424 /// Maps enum types to their corresponding LLVM functions for implementing the `tag_name` instruction.
577 enum_tag_name_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Function.Index),425 enum_tag_name_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Function.Index),
578 /// Serves the same purpose as `enum_tag_name_map` but for the `is_named_enum_value` instruction.426 /// Serves the same purpose as `enum_tag_name_map` but for the `is_named_enum_value` instruction.
...@@ -616,8 +464,6 @@ pub const Object = struct {...@@ -616,8 +464,6 @@ pub const Object = struct {
616 });464 });
617 errdefer builder.deinit();465 errdefer builder.deinit();
618466
619 builder.data_layout = try builder.string(dataLayout(target));
620
621 const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref =467 const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref =
622 if (!builder.strip) debug_info: {468 if (!builder.strip) debug_info: {
623 // We fully resolve all paths at this point to avoid lack of469 // We fully resolve all paths at this point to avoid lack of
...@@ -693,6 +539,7 @@ pub const Object = struct {...@@ -693,6 +539,7 @@ pub const Object = struct {
693 .zcu = zcu,539 .zcu = zcu,
694 .nav_map = .empty,540 .nav_map = .empty,
695 .uav_map = .empty,541 .uav_map = .empty,
542 .const_map = .empty,
696 .enum_tag_name_map = .empty,543 .enum_tag_name_map = .empty,
697 .named_enum_map = .empty,544 .named_enum_map = .empty,
698 .type_map = .empty,545 .type_map = .empty,
...@@ -703,21 +550,22 @@ pub const Object = struct {...@@ -703,21 +550,22 @@ pub const Object = struct {
703 return obj;550 return obj;
704 }551 }
705552
706 pub fn deinit(self: *Object) void {553 pub fn deinit(o: *Object) void {
707 const gpa = self.gpa;554 const gpa = o.gpa;
708 self.type_pool.deinit(gpa);555 o.type_pool.deinit(gpa);
709 self.lazy_abi_aligns.deinit(gpa);556 o.lazy_abi_aligns.deinit(gpa);
710 self.debug_enums.deinit(gpa);557 o.debug_enums.deinit(gpa);
711 self.debug_globals.deinit(gpa);558 o.debug_globals.deinit(gpa);
712 self.debug_file_map.deinit(gpa);559 o.debug_file_map.deinit(gpa);
713 self.debug_types.deinit(gpa);560 o.debug_types.deinit(gpa);
714 self.nav_map.deinit(gpa);561 o.nav_map.deinit(gpa);
715 self.uav_map.deinit(gpa);562 o.uav_map.deinit(gpa);
716 self.enum_tag_name_map.deinit(gpa);563 o.const_map.deinit(gpa);
717 self.named_enum_map.deinit(gpa);564 o.enum_tag_name_map.deinit(gpa);
718 self.type_map.deinit(gpa);565 o.named_enum_map.deinit(gpa);
719 self.builder.deinit();566 o.type_map.deinit(gpa);
720 self.* = undefined;567 o.builder.deinit();
568 o.* = undefined;
721 }569 }
722570
723 fn genErrorNameTable(o: *Object) Allocator.Error!void {571 fn genErrorNameTable(o: *Object) Allocator.Error!void {
...@@ -741,16 +589,16 @@ pub const Object = struct {...@@ -741,16 +589,16 @@ pub const Object = struct {
741 for (llvm_errors[1..], error_name_list) |*llvm_error, name| {589 for (llvm_errors[1..], error_name_list) |*llvm_error, name| {
742 const name_string = try o.builder.stringNull(name.toSlice(ip));590 const name_string = try o.builder.stringNull(name.toSlice(ip));
743 const name_init = try o.builder.stringConst(name_string);591 const name_init = try o.builder.stringConst(name_string);
744 const name_variable_index = try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);592 const name_llvm_variable = try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
745 try name_variable_index.setInitializer(name_init, &o.builder);593 try name_llvm_variable.setInitializer(name_init, &o.builder);
746 name_variable_index.setMutability(.constant, &o.builder);594 name_llvm_variable.setMutability(.constant, &o.builder);
747 name_variable_index.setAlignment(comptime .fromByteUnits(1), &o.builder);595 name_llvm_variable.setAlignment(comptime .fromByteUnits(1), &o.builder);
748 const global_index = name_variable_index.ptrConst(&o.builder).global;596 const llvm_global = name_llvm_variable.ptrConst(&o.builder).global;
749 global_index.setLinkage(.private, &o.builder);597 llvm_global.setLinkage(.private, &o.builder);
750 global_index.setUnnamedAddr(.unnamed_addr, &o.builder);598 llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder);
751599
752 llvm_error.* = try o.builder.structConst(llvm_slice_ty, &.{600 llvm_error.* = try o.builder.structConst(llvm_slice_ty, &.{
753 name_variable_index.toConst(&o.builder),601 name_llvm_variable.toConst(&o.builder),
754 try o.builder.intConst(llvm_usize_ty, name_string.slice(&o.builder).?.len - 1),602 try o.builder.intConst(llvm_usize_ty, name_string.slice(&o.builder).?.len - 1),
755 });603 });
756 }604 }
...@@ -1199,19 +1047,33 @@ pub const Object = struct {...@@ -1199,19 +1047,33 @@ pub const Object = struct {
1199 global.dll_storage_class = .default;1047 global.dll_storage_class = .default;
1200 global.unnamed_addr = .unnamed_addr;1048 global.unnamed_addr = .unnamed_addr;
1201 }1049 }
1202 llvm_function.setAlignment(switch (nav.resolved.?.@"align") {1050 llvm_function.setAlignment(nav.resolved.?.@"align".toLlvm(), &o.builder);
1203 .none => fn_ty.abiAlignment(zcu).toLlvm(),
1204 else => |a| a.toLlvm(),
1205 }, &o.builder);
1206 llvm_function.setSection(s: {1051 llvm_function.setSection(s: {
1207 const section = nav.resolved.?.@"linksection".toSlice(ip) orelse break :s .none;1052 const section = nav.resolved.?.@"linksection".toSlice(ip) orelse break :s .none;
1208 break :s try o.builder.string(section);1053 break :s try o.builder.string(section);
1209 }, &o.builder);1054 }, &o.builder);
1210 try o.addLlvmFunctionAttributes(pt, func.owner_nav, llvm_function);
12111055
1212 var attributes = try llvm_function.ptrConst(&o.builder).attributes.toWip(&o.builder);1056 var attributes: Builder.FunctionAttributes.Wip = .{};
1213 defer attributes.deinit(&o.builder);1057 defer attributes.deinit(&o.builder);
12141058
1059 // Function attributes that are independent of analysis results of the function body.
1060 try o.addCommonFnAttributes(
1061 &attributes,
1062 owner_mod,
1063 // Some backends don't respect the `naked` attribute in `TargetFrameLowering::hasFP()`,
1064 // so for these backends, LLVM will happily emit code that accesses the stack through
1065 // the frame pointer. This is nonsensical since what the `naked` attribute does is
1066 // suppress generation of the prologue and epilogue, and the prologue is where the
1067 // frame pointer normally gets set up. At time of writing, this is the case for at
1068 // least x86 and RISC-V.
1069 owner_mod.omit_frame_pointer or fn_info.cc == .naked,
1070 );
1071
1072 try o.addCallingConventionFnAttributes(pt, llvm_function, &attributes, if (nav.getExtern(ip)) |@"extern"| .{
1073 .name = nav.name.toSlice(ip),
1074 .lib_name = @"extern".lib_name.toSlice(ip),
1075 } else null, .fromIntern(fn_info, ip));
1076
1215 const func_analysis = func.analysisUnordered(ip);1077 const func_analysis = func.analysisUnordered(ip);
1216 if (func_analysis.is_noinline) {1078 if (func_analysis.is_noinline) {
1217 try attributes.addFnAttr(.@"noinline", &o.builder);1079 try attributes.addFnAttr(.@"noinline", &o.builder);
...@@ -1324,7 +1186,7 @@ pub const Object = struct {...@@ -1324,7 +1186,7 @@ pub const Object = struct {
1324 const counters_variable = try o.builder.addVariable(anon_name, .void, .default);1186 const counters_variable = try o.builder.addVariable(anon_name, .void, .default);
1325 try o.used.append(gpa, counters_variable.toConst(&o.builder));1187 try o.used.append(gpa, counters_variable.toConst(&o.builder));
1326 counters_variable.ptrConst(&o.builder).global.setLinkage(.private, &o.builder);1188 counters_variable.ptrConst(&o.builder).global.setLinkage(.private, &o.builder);
1327 counters_variable.setAlignment(comptime Builder.Alignment.fromByteUnits(1), &o.builder);1189 counters_variable.setAlignment(comptime .fromByteUnits(1), &o.builder);
13281190
1329 if (target.ofmt == .macho) {1191 if (target.ofmt == .macho) {
1330 counters_variable.setSection(try o.builder.string("__DATA,__sancov_cntrs"), &o.builder);1192 counters_variable.setSection(try o.builder.string("__DATA,__sancov_cntrs"), &o.builder);
...@@ -1507,10 +1369,6 @@ pub const Object = struct {...@@ -1507,10 +1369,6 @@ pub const Object = struct {
1507 llvm_global.ptr(&o.builder).unnamed_addr = .unnamed_addr;1369 llvm_global.ptr(&o.builder).unnamed_addr = .unnamed_addr;
1508 }1370 }
15091371
1510 const llvm_align = switch (resolved.@"align") {
1511 .none => nav_ty.abiAlignment(zcu).toLlvm(),
1512 else => |a| a.toLlvm(),
1513 };
1514 const llvm_section: Builder.String = if (resolved.@"linksection".toSlice(ip)) |section| s: {1372 const llvm_section: Builder.String = if (resolved.@"linksection".toSlice(ip)) |section| s: {
1515 break :s try o.builder.string(section);1373 break :s try o.builder.string(section);
1516 } else .none;1374 } else .none;
...@@ -1519,13 +1377,20 @@ pub const Object = struct {...@@ -1519,13 +1377,20 @@ pub const Object = struct {
1519 // can see are extern functions or other comptime function body values (e.g. undefined). Of1377 // can see are extern functions or other comptime function body values (e.g. undefined). Of
1520 // these, only extern functions need to be lowered to LLVM functions.1378 // these, only extern functions need to be lowered to LLVM functions.
1521 if (opt_extern != null and nav_ty.zigTypeTag(zcu) == .@"fn" and nav_ty.fnHasRuntimeBits(zcu)) {1379 if (opt_extern != null and nav_ty.zigTypeTag(zcu) == .@"fn" and nav_ty.fnHasRuntimeBits(zcu)) {
1380 const fn_info = zcu.typeToFunc(nav_ty).?;
1522 const llvm_function: Builder.Function.Index = switch (llvm_global.ptrConst(&o.builder).kind) {1381 const llvm_function: Builder.Function.Index = switch (llvm_global.ptrConst(&o.builder).kind) {
1523 .function => |function| function, // re-use existing `Builder.Function`1382 .function => |function| function, // re-use existing `Builder.Function`
1524 .replaced, .alias, .variable => try llvm_global.toNewFunction(&o.builder),1383 .replaced, .alias, .variable => try llvm_global.toNewFunction(&o.builder),
1525 };1384 };
1526 llvm_function.setAlignment(llvm_align, &o.builder);1385 llvm_function.setAlignment(resolved.@"align".toLlvm(), &o.builder);
1527 llvm_function.setSection(llvm_section, &o.builder);1386 llvm_function.setSection(llvm_section, &o.builder);
1528 try o.addLlvmFunctionAttributes(pt, nav_id, llvm_function);1387 var attributes: Builder.FunctionAttributes.Wip = .{};
1388 defer attributes.deinit(&o.builder);
1389 try o.addCallingConventionFnAttributes(pt, llvm_function, &attributes, .{
1390 .name = nav.name.toSlice(ip),
1391 .lib_name = opt_extern.?.lib_name.toSlice(ip),
1392 }, .fromIntern(fn_info, ip));
1393 llvm_function.setAttributes(try attributes.finish(&o.builder), &o.builder);
1529 } else {1394 } else {
1530 const file_scope = nav.srcInst(ip).resolveFile(ip);1395 const file_scope = nav.srcInst(ip).resolveFile(ip);
1531 const mod = zcu.fileByIndex(file_scope).mod.?;1396 const mod = zcu.fileByIndex(file_scope).mod.?;
...@@ -1534,7 +1399,10 @@ pub const Object = struct {...@@ -1534,7 +1399,10 @@ pub const Object = struct {
1534 .variable => |variable| variable, // re-use existing `Builder.Variable`1399 .variable => |variable| variable, // re-use existing `Builder.Variable`
1535 .replaced, .alias, .function => try llvm_global.toNewVariable(&o.builder),1400 .replaced, .alias, .function => try llvm_global.toNewVariable(&o.builder),
1536 };1401 };
1537 llvm_variable.setAlignment(llvm_align, &o.builder);1402 llvm_variable.setAlignment(switch (resolved.@"align") {
1403 .none => nav_ty.abiAlignment(zcu).toLlvm(),
1404 else => |a| a.toLlvm(),
1405 }, &o.builder);
1538 llvm_variable.setSection(llvm_section, &o.builder);1406 llvm_variable.setSection(llvm_section, &o.builder);
1539 llvm_variable.setMutability(if (resolved.@"const") .constant else .global, &o.builder);1407 llvm_variable.setMutability(if (resolved.@"const") .constant else .global, &o.builder);
1540 try llvm_variable.setInitializer(if (opt_extern != null) .no_init else try o.lowerValue(resolved.value, .in_memory), &o.builder);1408 try llvm_variable.setInitializer(if (opt_extern != null) .no_init else try o.lowerValue(resolved.value, .in_memory), &o.builder);
...@@ -1585,7 +1453,7 @@ pub const Object = struct {...@@ -1585,7 +1453,7 @@ pub const Object = struct {
1585 const uav_ty = Value.fromInterned(uav).typeOf(zcu);1453 const uav_ty = Value.fromInterned(uav).typeOf(zcu);
1586 const uav_ref = try o.lowerUavRef(1454 const uav_ref = try o.lowerUavRef(
1587 uav,1455 uav,
1588 uav_ty.abiAlignment(zcu),1456 uav_ty.abiAlignment(zcu).toLlvm(),
1589 target_util.defaultAddressSpace(zcu.getTarget(), .global_constant),1457 target_util.defaultAddressSpace(zcu.getTarget(), .global_constant),
1590 );1458 );
1591 break :exp .{ uav_ty, uav_ref };1459 break :exp .{ uav_ty, uav_ref };
...@@ -1599,7 +1467,7 @@ pub const Object = struct {...@@ -1599,7 +1467,7 @@ pub const Object = struct {
15991467
1600 fn updateExportedGlobal(1468 fn updateExportedGlobal(
1601 o: *Object,1469 o: *Object,
1602 global_index: Builder.Global.Index,1470 llvm_global: Builder.Global.Index,
1603 ty: Type,1471 ty: Type,
1604 export_indices: []const Zcu.Export.Index,1472 export_indices: []const Zcu.Export.Index,
1605 ) link.Error!void {1473 ) link.Error!void {
...@@ -1634,11 +1502,11 @@ pub const Object = struct {...@@ -1634,11 +1502,11 @@ pub const Object = struct {
1634 // make much sense: the linksection should be associated with the declaration itself rather1502 // make much sense: the linksection should be associated with the declaration itself rather
1635 // than some particular symbol it is exported as!1503 // than some particular symbol it is exported as!
1636 if (export_indices[0].ptr(zcu).opts.section.toSlice(ip)) |section_slice| {1504 if (export_indices[0].ptr(zcu).opts.section.toSlice(ip)) |section_slice| {
1637 const variable = &global_index.ptrConst(&o.builder).kind.variable;1505 const variable = &llvm_global.ptrConst(&o.builder).kind.variable;
1638 variable.setSection(try o.builder.string(section_slice), &o.builder);1506 variable.setSection(try o.builder.string(section_slice), &o.builder);
1639 }1507 }
16401508
1641 const llvm_global_ty = global_index.typeOf(&o.builder);1509 const llvm_global_ty = llvm_global.typeOf(&o.builder);
16421510
1643 // All exports are represented as aliases to the original global.1511 // All exports are represented as aliases to the original global.
16441512
...@@ -1661,8 +1529,8 @@ pub const Object = struct {...@@ -1661,8 +1529,8 @@ pub const Object = struct {
1661 const alias = try o.builder.addAlias(1529 const alias = try o.builder.addAlias(
1662 exp_name,1530 exp_name,
1663 llvm_global_ty,1531 llvm_global_ty,
1664 global_index.ptrConst(&o.builder).addr_space,1532 llvm_global.ptrConst(&o.builder).addr_space,
1665 global_index.toConst(),1533 llvm_global.toConst(),
1666 );1534 );
1667 break :global alias.ptrConst(&o.builder).global;1535 break :global alias.ptrConst(&o.builder).global;
1668 };1536 };
...@@ -1671,12 +1539,9 @@ pub const Object = struct {...@@ -1671,12 +1539,9 @@ pub const Object = struct {
1671 switch (existing_global.ptrConst(&o.builder).kind) {1539 switch (existing_global.ptrConst(&o.builder).kind) {
1672 .alias => |alias| {1540 .alias => |alias| {
1673 // We can just repurpose the existing alias.1541 // We can just repurpose the existing alias.
1674 alias.setAliasee(global_index.toConst(), &o.builder);1542 alias.setAliasee(llvm_global.toConst(), &o.builder);
1675 alias.ptrConst(&o.builder).global.ptr(&o.builder).type = global_index.typeOf(&o.builder);1543 alias.ptrConst(&o.builder).global.ptr(&o.builder).type = llvm_global.typeOf(&o.builder);
1676 // If the type the alias is pointing to can change, then1544 alias.ptrConst(&o.builder).global.ptr(&o.builder).addr_space = llvm_global.ptrConst(&o.builder).addr_space;
1677 // it makes sense that we should update the address
1678 // space too.
1679 alias.ptrConst(&o.builder).global.ptr(&o.builder).addr_space = global_index.ptrConst(&o.builder).addr_space;
1680 break :global existing_global;1545 break :global existing_global;
1681 },1546 },
1682 .variable, .function => {1547 .variable, .function => {
...@@ -1686,13 +1551,13 @@ pub const Object = struct {...@@ -1686,13 +1551,13 @@ pub const Object = struct {
1686 // We need to make a new global which is an alias. Replace this existing one1551 // We need to make a new global which is an alias. Replace this existing one
1687 // with the target global, making the name available and fixing references1552 // with the target global, making the name available and fixing references
1688 // to this global to point to the target.1553 // to this global to point to the target.
1689 try existing_global.replace(global_index, &o.builder);1554 try existing_global.replace(llvm_global, &o.builder);
1690 // The name is now free, so create an alias.1555 // The name is now free, so create an alias.
1691 const alias = try o.builder.addAlias(1556 const alias = try o.builder.addAlias(
1692 exp_name,1557 exp_name,
1693 llvm_global_ty,1558 llvm_global_ty,
1694 global_index.ptrConst(&o.builder).addr_space,1559 llvm_global.ptrConst(&o.builder).addr_space,
1695 global_index.toConst(),1560 llvm_global.toConst(),
1696 );1561 );
1697 break :global alias.ptrConst(&o.builder).global;1562 break :global alias.ptrConst(&o.builder).global;
1698 },1563 },
...@@ -1725,11 +1590,11 @@ pub const Object = struct {...@@ -1725,11 +1590,11 @@ pub const Object = struct {
1725 pub fn updateContainerType(o: *Object, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Allocator.Error!void {1590 pub fn updateContainerType(o: *Object, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Allocator.Error!void {
1726 _ = o.type_map.remove(ty);1591 _ = o.type_map.remove(ty);
1727 try o.type_pool.updateContainerType(pt, .{ .llvm = o }, ty, success);1592 try o.type_pool.updateContainerType(pt, .{ .llvm = o }, ty, success);
1728 if (o.named_enum_map.get(ty)) |function_index| {1593 if (o.named_enum_map.get(ty)) |llvm_function| {
1729 try o.updateIsNamedEnumValueFunction(.fromInterned(ty), function_index);1594 try o.updateIsNamedEnumValueFunction(.fromInterned(ty), llvm_function);
1730 }1595 }
1731 if (o.enum_tag_name_map.get(ty)) |function_index| {1596 if (o.enum_tag_name_map.get(ty)) |llvm_function| {
1732 try o.updateEnumTagNameFunction(.fromInterned(ty), function_index);1597 try o.updateEnumTagNameFunction(.fromInterned(ty), llvm_function);
1733 }1598 }
1734 }1599 }
17351600
...@@ -2102,7 +1967,7 @@ pub const Object = struct {...@@ -2102,7 +1967,7 @@ pub const Object = struct {
2102 payload_offset * 8,1967 payload_offset * 8,
2103 );1968 );
21041969
2105 return try o.builder.debugStructType(1970 return o.builder.debugStructType(
2106 name,1971 name,
2107 null, // File1972 null, // File
2108 o.debug_compile_unit.unwrap().?, // Scope1973 o.debug_compile_unit.unwrap().?, // Scope
...@@ -2140,7 +2005,7 @@ pub const Object = struct {...@@ -2140,7 +2005,7 @@ pub const Object = struct {
2140 defer debug_param_types.deinit(gpa);2005 defer debug_param_types.deinit(gpa);
21412006
2142 // Return type goes first.2007 // Return type goes first.
2143 if (try fnReturnStrat(o, fn_info) == .sret) {2008 if (try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type)) == .sret) {
2144 // Actual return type is void, then first arg is the sret pointer.2009 // Actual return type is void, then first arg is the sret pointer.
2145 const ptr_ty = try pt.singleMutPtrType(.fromInterned(fn_info.return_type));2010 const ptr_ty = try pt.singleMutPtrType(.fromInterned(fn_info.return_type));
2146 debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, .void));2011 debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, .void));
...@@ -2575,53 +2440,117 @@ pub const Object = struct {...@@ -2575,53 +2440,117 @@ pub const Object = struct {
2575 fn namespaceToDebugScope(o: *Object, pt: Zcu.PerThread, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {2440 fn namespaceToDebugScope(o: *Object, pt: Zcu.PerThread, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {
2576 const zcu = o.zcu;2441 const zcu = o.zcu;
2577 const namespace = zcu.namespacePtr(namespace_index);2442 const namespace = zcu.namespacePtr(namespace_index);
2578 if (namespace.parent == .none) return try o.getDebugFile(namespace.file_scope);2443 if (namespace.parent == .none) return o.getDebugFile(namespace.file_scope);
2579 return o.getDebugType(pt, .fromInterned(namespace.owner_type));2444 return o.getDebugType(pt, .fromInterned(namespace.owner_type));
2580 }2445 }
25812446
2582 /// Sets the attributes and callconv of the given `Builder.Function`, which corresponds to the2447 fn addCommonFnAttributes(
2583 /// given `Nav` (which is a function).2448 o: *Object,
2584 fn addLlvmFunctionAttributes(2449 attributes: *Builder.FunctionAttributes.Wip,
2450 owner_mod: *Module,
2451 omit_frame_pointer: bool,
2452 ) Allocator.Error!void {
2453 if (!owner_mod.red_zone) {
2454 try attributes.addFnAttr(.noredzone, &o.builder);
2455 }
2456 if (omit_frame_pointer) {
2457 try attributes.addFnAttr(.{ .string = .{
2458 .kind = try o.builder.string("frame-pointer"),
2459 .value = try o.builder.string("none"),
2460 } }, &o.builder);
2461 } else {
2462 try attributes.addFnAttr(.{ .string = .{
2463 .kind = try o.builder.string("frame-pointer"),
2464 .value = try o.builder.string("all"),
2465 } }, &o.builder);
2466 }
2467 try attributes.addFnAttr(.nounwind, &o.builder);
2468 if (owner_mod.unwind_tables != .none) {
2469 try attributes.addFnAttr(
2470 .{ .uwtable = if (owner_mod.unwind_tables == .async) .async else .sync },
2471 &o.builder,
2472 );
2473 }
2474 if (owner_mod.optimize_mode == .small) {
2475 try attributes.addFnAttr(.minsize, &o.builder);
2476 try attributes.addFnAttr(.optsize, &o.builder);
2477 }
2478 const target = &owner_mod.resolved_target.result;
2479 if (target.cpu.model.llvm_name) |s| {
2480 try attributes.addFnAttr(.{ .string = .{
2481 .kind = try o.builder.string("target-cpu"),
2482 .value = try o.builder.string(s),
2483 } }, &o.builder);
2484 }
2485 if (owner_mod.resolved_target.llvm_cpu_features) |s| {
2486 try attributes.addFnAttr(.{ .string = .{
2487 .kind = try o.builder.string("target-features"),
2488 .value = try o.builder.string(std.mem.span(s)),
2489 } }, &o.builder);
2490 }
2491 if (target.abi.float() == .soft) {
2492 // `use-soft-float` means "use software routines for floating point computations". In
2493 // other words, it configures how LLVM lowers basic float instructions like `fcmp`,
2494 // `fadd`, etc. The float calling convention is configured on `TargetMachine` and is
2495 // mostly an orthogonal concept, although obviously we do need hardware float operations
2496 // to actually be able to pass float values in float registers.
2497 //
2498 // Ideally, we would support something akin to the `-mfloat-abi=softfp` option that GCC
2499 // and Clang support for Arm32 and CSKY. We don't currently expose such an option in
2500 // Zig, and using CPU features as the source of truth for this makes for a miserable
2501 // user experience since people expect e.g. `arm-linux-gnueabi` to mean full soft float
2502 // unless the compiler has explicitly been told otherwise. (And note that our baseline
2503 // CPU models almost all include FPU features!)
2504 //
2505 // Revisit this at some point.
2506 try attributes.addFnAttr(.{ .string = .{
2507 .kind = try o.builder.string("use-soft-float"),
2508 .value = try o.builder.string("true"),
2509 } }, &o.builder);
2510
2511 // This prevents LLVM from using FPU/SIMD code for things like `memcpy`. As for the
2512 // above, this should be revisited if `softfp` support is added.
2513 try attributes.addFnAttr(.noimplicitfloat, &o.builder);
2514 }
2515 }
2516
2517 pub fn addCallingConventionFnAttributes(
2585 o: *Object,2518 o: *Object,
2586 pt: Zcu.PerThread,2519 pt: Zcu.PerThread,
2587 nav_id: InternPool.Nav.Index,2520 llvm_function: Builder.Function.Index,
2588 function_index: Builder.Function.Index,2521 attributes: *Builder.FunctionAttributes.Wip,
2522 opt_extern: ?struct {
2523 name: []const u8,
2524 lib_name: ?[]const u8 = null,
2525 },
2526 fn_info: FuncInfo,
2589 ) Allocator.Error!void {2527 ) Allocator.Error!void {
2590 const zcu = o.zcu;2528 const zcu = o.zcu;
2591 const ip = &zcu.intern_pool;2529 const target = zcu.getTarget();
2592 const nav = ip.getNav(nav_id);
2593 const owner_mod = zcu.navFileScope(nav_id).mod.?;
2594 const ty: Type = .fromInterned(nav.resolved.?.type);
2595
2596 const fn_info = zcu.typeToFunc(ty).?;
2597 const target = &owner_mod.resolved_target.result;
25982530
2599 var attributes: Builder.FunctionAttributes.Wip = .{};2531 if (fn_info.cc == .async) {
2600 defer attributes.deinit(&o.builder);2532 @panic("TODO: LLVM backend lower async function");
2533 }
26012534
2602 if (target.cpu.arch.isWasm()) if (nav.getExtern(ip)) |@"extern"| {2535 if (target.cpu.arch.isWasm()) if (opt_extern) |@"extern"| {
2603 try attributes.addFnAttr(.{ .string = .{2536 try attributes.addFnAttr(.{ .string = .{
2604 .kind = try o.builder.string("wasm-import-name"),2537 .kind = try o.builder.string("wasm-import-name"),
2605 .value = try o.builder.string(nav.name.toSlice(ip)),2538 .value = try o.builder.string(@"extern".name),
2606 } }, &o.builder);2539 } }, &o.builder);
2607 if (@"extern".lib_name.toSlice(ip)) |lib_name_slice| {2540 if (@"extern".lib_name) |lib_name| {
2608 if (!std.mem.eql(u8, lib_name_slice, "c")) try attributes.addFnAttr(.{ .string = .{2541 if (!std.mem.eql(u8, lib_name, "c")) try attributes.addFnAttr(.{ .string = .{
2609 .kind = try o.builder.string("wasm-import-module"),2542 .kind = try o.builder.string("wasm-import-module"),
2610 .value = try o.builder.string(lib_name_slice),2543 .value = try o.builder.string(lib_name),
2611 } }, &o.builder);2544 } }, &o.builder);
2612 }2545 }
2613 };2546 };
26142547
2615 if (fn_info.cc == .async) {
2616 @panic("TODO: LLVM backend lower async function");
2617 }
2618
2619 const cc_info = toLlvmCallConv(fn_info.cc, target).?;2548 const cc_info = toLlvmCallConv(fn_info.cc, target).?;
26202549
2621 function_index.setCallConv(cc_info.llvm_cc, &o.builder);2550 llvm_function.setCallConv(cc_info.llvm_cc, &o.builder);
26222551
2623 if (cc_info.align_stack) {2552 if (cc_info.align_stack) {
2624 try attributes.addFnAttr(.{ .alignstack = .wrap(.fromByteUnits(target.stackAlignment())) }, &o.builder);2553 try attributes.addFnAttr(.{ .string = .{ .kind = try o.builder.string("stackrealign"), .value = .empty } }, &o.builder);
2625 }2554 }
26262555
2627 if (cc_info.naked) {2556 if (cc_info.naked) {
...@@ -2672,29 +2601,16 @@ pub const Object = struct {...@@ -2672,29 +2601,16 @@ pub const Object = struct {
2672 else => {},2601 else => {},
2673 }2602 }
26742603
2675 // Function attributes that are independent of analysis results of the function body.
2676 try o.addCommonFnAttributes(
2677 &attributes,
2678 owner_mod,
2679 // Some backends don't respect the `naked` attribute in `TargetFrameLowering::hasFP()`,
2680 // so for these backends, LLVM will happily emit code that accesses the stack through
2681 // the frame pointer. This is nonsensical since what the `naked` attribute does is
2682 // suppress generation of the prologue and epilogue, and the prologue is where the
2683 // frame pointer normally gets set up. At time of writing, this is the case for at
2684 // least x86 and RISC-V.
2685 owner_mod.omit_frame_pointer or fn_info.cc == .naked,
2686 );
2687
2688 if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder);2604 if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder);
26892605
2690 var it = iterateParamTypes(o, fn_info);2606 var it = iterateParamTypes(o, fn_info.cc, fn_info.param_types);
2691 if (try fnReturnStrat(o, fn_info) == .sret) {2607 if (try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type)) == .sret) {
2692 // Sret pointers must not be address 02608 try o.addSRetFnAttributes(
2693 try attributes.addParamAttr(it.llvm_index, .nonnull, &o.builder);2609 attributes,
2694 try attributes.addParamAttr(it.llvm_index, .@"noalias", &o.builder);2610 try o.lowerType(.fromInterned(fn_info.return_type), .in_memory),
26952611 Type.fromInterned(fn_info.return_type).abiAlignment(zcu).toLlvm(),
2696 const raw_llvm_ret_ty = try o.lowerType(.fromInterned(fn_info.return_type), .in_memory);2612 .declaration,
2697 try attributes.addParamAttr(it.llvm_index, .{ .sret = raw_llvm_ret_ty }, &o.builder);2613 );
2698 it.llvm_index += 1;2614 it.llvm_index += 1;
2699 } else if (ccAbiPromoteInt(fn_info.cc, zcu, Type.fromInterned(fn_info.return_type))) |s| switch (s) {2615 } else if (ccAbiPromoteInt(fn_info.cc, zcu, Type.fromInterned(fn_info.return_type))) |s| switch (s) {
2700 .signed => try attributes.addRetAttr(.signext, &o.builder),2616 .signed => try attributes.addRetAttr(.signext, &o.builder),
...@@ -2713,9 +2629,9 @@ pub const Object = struct {...@@ -2713,9 +2629,9 @@ pub const Object = struct {
2713 while (try it.next()) |lowering| switch (lowering) {2629 while (try it.next()) |lowering| switch (lowering) {
2714 .byval => {2630 .byval => {
2715 const param_index = it.zig_index - 1;2631 const param_index = it.zig_index - 1;
2716 const param_ty: Type = .fromInterned(fn_info.param_types.get(ip)[param_index]);2632 const param_ty: Type = .fromInterned(fn_info.param_types[param_index]);
2717 if (!isByRef(param_ty, zcu)) {2633 if (!isByRef(param_ty, zcu)) {
2718 try o.addByValParamAttrs(pt, &attributes, param_ty, param_index, fn_info, it.llvm_index - 1);2634 try o.addByValParamAttrs(pt, attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
2719 }2635 }
27202636
2721 if (remaining_inreg_int > 0 and2637 if (remaining_inreg_int > 0 and
...@@ -2734,12 +2650,12 @@ pub const Object = struct {...@@ -2734,12 +2650,12 @@ pub const Object = struct {
2734 }2650 }
2735 },2651 },
2736 .byref => {2652 .byref => {
2737 const param_ty: Type = .fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);2653 const param_ty: Type = .fromInterned(fn_info.param_types[it.zig_index - 1]);
2738 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, it.byval_attr, param_ty);2654 try o.addByRefParamAttrs(attributes, it.llvm_index - 1, it.byval_attr, param_ty);
2739 },2655 },
2740 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),2656 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
2741 .slice => {2657 .slice => {
2742 const param_ty: Type = .fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);2658 const param_ty: Type = .fromInterned(fn_info.param_types[it.zig_index - 1]);
2743 const ptr_info = param_ty.ptrInfo(zcu);2659 const ptr_info = param_ty.ptrInfo(zcu);
2744 const llvm_ptr_index = it.llvm_index - 2;2660 const llvm_ptr_index = it.llvm_index - 2;
2745 if (std.math.cast(u5, it.zig_index - 1)) |i| {2661 if (std.math.cast(u5, it.zig_index - 1)) |i| {
...@@ -2771,94 +2687,205 @@ pub const Object = struct {...@@ -2771,94 +2687,205 @@ pub const Object = struct {
2771 .i64_array,2687 .i64_array,
2772 => continue,2688 => continue,
2773 };2689 };
2774
2775 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
2776 }2690 }
27772691
2778 fn addCommonFnAttributes(2692 pub fn addSRetFnAttributes(
2779 o: *Object,2693 o: *Object,
2780 attributes: *Builder.FunctionAttributes.Wip,2694 attributes: *Builder.FunctionAttributes.Wip,
2781 owner_mod: *Module,2695 ret_ty: Builder.Type,
2782 omit_frame_pointer: bool,2696 ret_align: Builder.Alignment,
2697 location: enum { declaration, callsite },
2783 ) Allocator.Error!void {2698 ) Allocator.Error!void {
2784 if (!owner_mod.red_zone) {2699 try attributes.addParamAttr(0, .dead_on_unwind, &o.builder);
2785 try attributes.addFnAttr(.noredzone, &o.builder);2700 switch (location) {
2786 }2701 .declaration => try attributes.addParamAttr(0, .@"noalias", &o.builder),
2787 if (omit_frame_pointer) {2702 .callsite => {},
2788 try attributes.addFnAttr(.{ .string = .{
2789 .kind = try o.builder.string("frame-pointer"),
2790 .value = try o.builder.string("none"),
2791 } }, &o.builder);
2792 } else {
2793 try attributes.addFnAttr(.{ .string = .{
2794 .kind = try o.builder.string("frame-pointer"),
2795 .value = try o.builder.string("all"),
2796 } }, &o.builder);
2797 }
2798 try attributes.addFnAttr(.nounwind, &o.builder);
2799 if (owner_mod.unwind_tables != .none) {
2800 try attributes.addFnAttr(
2801 .{ .uwtable = if (owner_mod.unwind_tables == .async) .async else .sync },
2802 &o.builder,
2803 );
2804 }
2805 if (owner_mod.optimize_mode == .small) {
2806 try attributes.addFnAttr(.minsize, &o.builder);
2807 try attributes.addFnAttr(.optsize, &o.builder);
2808 }
2809 const target = &owner_mod.resolved_target.result;
2810 if (target.cpu.model.llvm_name) |s| {
2811 try attributes.addFnAttr(.{ .string = .{
2812 .kind = try o.builder.string("target-cpu"),
2813 .value = try o.builder.string(s),
2814 } }, &o.builder);
2815 }
2816 if (owner_mod.resolved_target.llvm_cpu_features) |s| {
2817 try attributes.addFnAttr(.{ .string = .{
2818 .kind = try o.builder.string("target-features"),
2819 .value = try o.builder.string(std.mem.span(s)),
2820 } }, &o.builder);
2821 }
2822 if (target.abi.float() == .soft) {
2823 // `use-soft-float` means "use software routines for floating point computations". In
2824 // other words, it configures how LLVM lowers basic float instructions like `fcmp`,
2825 // `fadd`, etc. The float calling convention is configured on `TargetMachine` and is
2826 // mostly an orthogonal concept, although obviously we do need hardware float operations
2827 // to actually be able to pass float values in float registers.
2828 //
2829 // Ideally, we would support something akin to the `-mfloat-abi=softfp` option that GCC
2830 // and Clang support for Arm32 and CSKY. We don't currently expose such an option in
2831 // Zig, and using CPU features as the source of truth for this makes for a miserable
2832 // user experience since people expect e.g. `arm-linux-gnueabi` to mean full soft float
2833 // unless the compiler has explicitly been told otherwise. (And note that our baseline
2834 // CPU models almost all include FPU features!)
2835 //
2836 // Revisit this at some point.
2837 try attributes.addFnAttr(.{ .string = .{
2838 .kind = try o.builder.string("use-soft-float"),
2839 .value = try o.builder.string("true"),
2840 } }, &o.builder);
2841
2842 // This prevents LLVM from using FPU/SIMD code for things like `memcpy`. As for the
2843 // above, this should be revisited if `softfp` support is added.
2844 try attributes.addFnAttr(.noimplicitfloat, &o.builder);
2845 }2703 }
2704 try attributes.addParamAttr(0, .writeonly, &o.builder);
2705 try attributes.addParamAttr(0, .{ .captures = .none }, &o.builder);
2706 try attributes.addParamAttr(0, .{ .sret = ret_ty }, &o.builder);
2707 try attributes.addParamAttr(0, .{ .@"align" = .wrap(ret_align) }, &o.builder);
2846 }2708 }
28472709
2848 pub const TypeRepr = enum {2710 pub const TypeRepr = enum {
2849 /// The representation of the type when it is being manipulated as a value in a function.2711 /// The representation of the type when it is being manipulated as a value in a function.
2850 /// e.g. Zig `u5` -> LLVM `i5`2712 /// e.g. Zig `u90` -> LLVM `i90`
2851 by_value,2713 as_value,
2852 /// The representation of the type when it is stored in memory.2714 /// The representation of the type when it is loaded from or stored to memory.
2853 /// e.g. Zig `u5` -> LLVM `i8`2715 /// e.g. Zig `u90` -> LLVM `i96`
2716 memory_access,
2717 /// The representation of the type when it is in memory.
2718 /// e.g. Zig `u90` -> LLVM `[12 x i8]`
2854 in_memory,2719 in_memory,
2855 };2720 };
28562721
2722 pub fn intType(o: *Object, bits: u16, repr: TypeRepr) Allocator.Error!Builder.Type {
2723 switch (repr) {
2724 .as_value => return o.builder.intType(bits),
2725 .memory_access, .in_memory => {},
2726 }
2727 const target = o.zcu.getTarget();
2728 const abi_size = std.zig.target.intByteSize(target, bits);
2729 const llvm_bit_width = @as(u20, 8) * abi_size;
2730 switch (repr) {
2731 .as_value => unreachable,
2732 .memory_access => {},
2733 .in_memory => {
2734 const zig_align = std.zig.target.intAlignment(target, bits);
2735 const llvm_align = o.builder.data_layout.getIntegerSpec(llvm_bit_width).abi_align;
2736 if (zig_align < llvm_align.toByteUnits().?) return o.builder.arrayType(abi_size, .i8);
2737 },
2738 }
2739 return o.builder.intType(llvm_bit_width);
2740 }
2741
2857 pub fn errorIntType(o: *Object, repr: TypeRepr) Allocator.Error!Builder.Type {2742 pub fn errorIntType(o: *Object, repr: TypeRepr) Allocator.Error!Builder.Type {
2858 return o.builder.intType(switch (repr) {2743 return o.intType(o.zcu.errorSetBits(), repr);
2859 .by_value => o.zcu.errorSetBits(),2744 }
2860 .in_memory => @intCast(Type.anyerror.abiSize(o.zcu) * 8),2745
2861 });2746 pub const SoftF80Layout = struct {
2747 alignment: InternPool.Alignment,
2748 /// byte offset of u64 field
2749 mantissa_offset: u64,
2750 /// byte offset of u16 field
2751 exponent_offset: u64,
2752 llvm_fields_len: u32,
2753
2754 pub const LlvmFieldTag = enum { mantissa, exponent, padding };
2755 };
2756 pub fn softF80Layout(o: *Object, opts: struct {
2757 llvm_field_tags_buf: []SoftF80Layout.LlvmFieldTag = &.{},
2758 llvm_field_types_buf: []Builder.Type = &.{},
2759 }) Allocator.Error!SoftF80Layout {
2760 const zcu = o.zcu;
2761 const target = zcu.getTarget();
2762 assert(std.zig.target.compilerRtFloatAbi(target, 80) == .soft);
2763 // Current compiler rt soft abi, which is not yet affected by endianness for simplicity:
2764 //
2765 // typedef struct { uint64_t mantissa; uint16_t exponent; } f80;
2766 //
2767 var layout: SoftF80Layout = .{
2768 .alignment = Type.f80.abiAlignment(zcu),
2769 .mantissa_offset = undefined,
2770 .exponent_offset = undefined,
2771 .llvm_fields_len = 0,
2772 };
2773 var offset: u64 = 0;
2774 for ([2]SoftF80Layout.LlvmFieldTag{ .mantissa, .exponent }, [2]Type{ .u64, .u16 }) |field_tag, field_type| {
2775 const field_align = field_type.abiAlignment(zcu);
2776 assert(field_align.compareStrict(.lte, layout.alignment));
2777 const field_offset = field_align.forward(offset);
2778 switch (field_offset - offset) {
2779 0 => {},
2780 else => |padding| {
2781 if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len)
2782 opts.llvm_field_tags_buf[layout.llvm_fields_len] = .padding;
2783 if (layout.llvm_fields_len < opts.llvm_field_types_buf.len)
2784 opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.builder.arrayType(padding, .i8);
2785 layout.llvm_fields_len += 1;
2786 },
2787 }
2788 switch (field_tag) {
2789 .mantissa => layout.mantissa_offset = field_offset,
2790 .exponent => layout.exponent_offset = field_offset,
2791 .padding => unreachable,
2792 }
2793 if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len)
2794 opts.llvm_field_tags_buf[layout.llvm_fields_len] = field_tag;
2795 if (layout.llvm_fields_len < opts.llvm_field_types_buf.len)
2796 opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.lowerType(field_type, .in_memory);
2797 layout.llvm_fields_len += 1;
2798 offset = field_offset + field_type.abiSize(zcu);
2799 }
2800 const end = layout.alignment.forward(offset);
2801 assert(end == Type.f80.abiSize(zcu));
2802 switch (end - offset) {
2803 0 => {},
2804 else => |padding| {
2805 if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len)
2806 opts.llvm_field_tags_buf[layout.llvm_fields_len] = .padding;
2807 if (layout.llvm_fields_len < opts.llvm_field_types_buf.len)
2808 opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.builder.arrayType(padding, .i8);
2809 layout.llvm_fields_len += 1;
2810 },
2811 }
2812 return layout;
2813 }
2814
2815 pub const SoftF128Layout = struct {
2816 alignment: InternPool.Alignment,
2817 /// byte offset of u64 field
2818 lo_offset: u64,
2819 /// byte offset of u64 field
2820 hi_offset: u64,
2821 llvm_fields_len: u32,
2822
2823 pub const LlvmFieldTag = enum { lo, hi, padding };
2824 };
2825 pub fn softF128Layout(o: *Object, opts: struct {
2826 llvm_field_tags_buf: []SoftF128Layout.LlvmFieldTag = &.{},
2827 llvm_field_types_buf: []Builder.Type = &.{},
2828 }) Allocator.Error!SoftF128Layout {
2829 const zcu = o.zcu;
2830 const target = zcu.getTarget();
2831 assert(std.zig.target.compilerRtFloatAbi(target, 128) == .soft);
2832 // Current compiler rt soft abi:
2833 //
2834 // #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
2835 // typedef struct { uint64_t hi, lo; } f128;
2836 // #else
2837 // typedef struct { uint64_t lo, hi; } f128;
2838 // #endif
2839 //
2840 var layout: SoftF128Layout = .{
2841 .alignment = Type.f128.abiAlignment(zcu),
2842 .lo_offset = undefined,
2843 .hi_offset = undefined,
2844 .llvm_fields_len = 0,
2845 };
2846 var offset: u64 = 0;
2847 for (@as([2]SoftF128Layout.LlvmFieldTag, switch (target.cpu.arch.endian()) {
2848 .big => .{ .hi, .lo },
2849 .little => .{ .lo, .hi },
2850 }), [2]Type{ .u64, .u64 }) |field_tag, field_type| {
2851 const field_align = field_type.abiAlignment(zcu);
2852 assert(field_align.compareStrict(.lte, layout.alignment));
2853 const field_offset = field_align.forward(offset);
2854 switch (field_offset - offset) {
2855 0 => {},
2856 else => |padding| {
2857 if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len)
2858 opts.llvm_field_tags_buf[layout.llvm_fields_len] = .padding;
2859 if (layout.llvm_fields_len < opts.llvm_field_types_buf.len)
2860 opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.builder.arrayType(padding, .i8);
2861 layout.llvm_fields_len += 1;
2862 },
2863 }
2864 switch (field_tag) {
2865 .lo => layout.lo_offset = field_offset,
2866 .hi => layout.hi_offset = field_offset,
2867 .padding => unreachable,
2868 }
2869 if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len)
2870 opts.llvm_field_tags_buf[layout.llvm_fields_len] = field_tag;
2871 if (layout.llvm_fields_len < opts.llvm_field_types_buf.len)
2872 opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.lowerType(field_type, .in_memory);
2873 layout.llvm_fields_len += 1;
2874 offset = field_offset + field_type.abiSize(zcu);
2875 }
2876 const end = layout.alignment.forward(offset);
2877 assert(end == Type.f128.abiSize(zcu));
2878 switch (end - offset) {
2879 0 => {},
2880 else => |padding| {
2881 if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len)
2882 opts.llvm_field_tags_buf[layout.llvm_fields_len] = .padding;
2883 if (layout.llvm_fields_len < opts.llvm_field_types_buf.len)
2884 opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.builder.arrayType(padding, .i8);
2885 layout.llvm_fields_len += 1;
2886 },
2887 }
2888 return layout;
2862 }2889 }
28632890
2864 pub fn lowerType(o: *Object, t: Type, repr: TypeRepr) Allocator.Error!Builder.Type {2891 pub fn lowerType(o: *Object, t: Type, repr: TypeRepr) Allocator.Error!Builder.Type {
...@@ -2866,42 +2893,31 @@ pub const Object = struct {...@@ -2866,42 +2893,31 @@ pub const Object = struct {
2866 const target = zcu.getTarget();2893 const target = zcu.getTarget();
2867 const ip = &zcu.intern_pool;2894 const ip = &zcu.intern_pool;
28682895
2869 if (repr == .by_value) {2896 switch (repr) {
2870 assert(!isByRef(t, zcu)); // by-ref types must only be manipulated in memory2897 .as_value => assert(!isByRef(t, zcu)), // by-ref types must only be manipulated in memory
2898 .memory_access, .in_memory => {},
2871 }2899 }
28722900
2873 return switch (t.toIntern()) {2901 return switch (t.toIntern()) {
2874 .u0_type => unreachable, // no runtime bits2902 .u0_type => unreachable, // no runtime bits
2875 inline .u1_type,2903 .u1_type => try o.intType(1, repr),
2876 .u8_type,2904 .u8_type, .i8_type => try o.intType(8, repr),
2877 .i8_type,2905 .u16_type, .i16_type => try o.intType(16, repr),
2878 .u16_type,2906 .u29_type => try o.intType(29, repr),
2879 .i16_type,2907 .u32_type, .i32_type => try o.intType(32, repr),
2880 .u29_type,2908 .u64_type, .i64_type => try o.intType(64, repr),
2881 .u32_type,2909 .u80_type => try o.intType(80, repr),
2882 .i32_type,2910 .u128_type, .i128_type => try o.intType(128, repr),
2883 .u64_type,2911 .usize_type, .isize_type => try o.intType(target.ptrBitWidth(), repr),
2884 .i64_type,2912 .c_char_type => try o.intType(target.cTypeBitSize(.char).?, repr),
2885 .u80_type,2913 .c_short_type => try o.intType(target.cTypeBitSize(.short).?, repr),
2886 .u128_type,2914 .c_ushort_type => try o.intType(target.cTypeBitSize(.ushort).?, repr),
2887 .i128_type,2915 .c_int_type => try o.intType(target.cTypeBitSize(.int).?, repr),
2888 => |tag| switch (repr) {2916 .c_uint_type => try o.intType(target.cTypeBitSize(.uint).?, repr),
2889 .by_value => @field(Builder.Type, "i" ++ @tagName(tag)[1 .. @tagName(tag).len - "_type".len]),2917 .c_long_type => try o.intType(target.cTypeBitSize(.long).?, repr),
2890 .in_memory => try o.builder.intType(@intCast(t.abiSize(zcu) * 8)),2918 .c_ulong_type => try o.intType(target.cTypeBitSize(.ulong).?, repr),
2891 },2919 .c_longlong_type => try o.intType(target.cTypeBitSize(.longlong).?, repr),
2892 .usize_type, .isize_type => try o.builder.intType(target.ptrBitWidth()),2920 .c_ulonglong_type => try o.intType(target.cTypeBitSize(.ulonglong).?, repr),
2893 inline .c_char_type,
2894 .c_short_type,
2895 .c_ushort_type,
2896 .c_int_type,
2897 .c_uint_type,
2898 .c_long_type,
2899 .c_ulong_type,
2900 .c_longlong_type,
2901 .c_ulonglong_type,
2902 => |tag| try o.builder.intType(target.cTypeBitSize(
2903 @field(std.Target.CType, @tagName(tag)["c_".len .. @tagName(tag).len - "_type".len]),
2904 )),
2905 .c_longdouble_type,2921 .c_longdouble_type,
2906 .f16_type,2922 .f16_type,
2907 .f32_type,2923 .f32_type,
...@@ -2909,11 +2925,44 @@ pub const Object = struct {...@@ -2909,11 +2925,44 @@ pub const Object = struct {
2909 .f80_type,2925 .f80_type,
2910 .f128_type,2926 .f128_type,
2911 => switch (t.floatBits(target)) {2927 => switch (t.floatBits(target)) {
2912 16 => if (backendSupportsF16(target)) .half else .i16,2928 16 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
2913 32 => .float,2929 .hard => .half,
2914 64 => .double,2930 .soft => .i16,
2915 80 => if (backendSupportsF80(target)) .x86_fp80 else .i80,2931 },
2916 128 => .fp128,2932 32 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
2933 .hard => .float,
2934 .soft => .i32,
2935 },
2936 64 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
2937 .hard => .double,
2938 .soft => .i64,
2939 },
2940 80 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
2941 .hard => .x86_fp80,
2942 .soft => {
2943 var llvm_field_types_buf: [5]Builder.Type = undefined;
2944 const f80_layout = try o.softF80Layout(.{
2945 .llvm_field_types_buf = &llvm_field_types_buf,
2946 });
2947 return o.builder.structType(
2948 .normal,
2949 llvm_field_types_buf[0..f80_layout.llvm_fields_len],
2950 );
2951 },
2952 },
2953 128 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
2954 .hard => .fp128,
2955 .soft => {
2956 var llvm_field_types_buf: [5]Builder.Type = undefined;
2957 const f128_layout = try o.softF128Layout(.{
2958 .llvm_field_types_buf = &llvm_field_types_buf,
2959 });
2960 return o.builder.structType(
2961 .normal,
2962 llvm_field_types_buf[0..f128_layout.llvm_fields_len],
2963 );
2964 },
2965 },
2917 else => unreachable,2966 else => unreachable,
2918 },2967 },
2919 .anyopaque_type => {2968 .anyopaque_type => {
...@@ -2972,10 +3021,7 @@ pub const Object = struct {...@@ -2972,10 +3021,7 @@ pub const Object = struct {
2972 .none,3021 .none,
2973 => unreachable,3022 => unreachable,
2974 else => switch (ip.indexToKey(t.toIntern())) {3023 else => switch (ip.indexToKey(t.toIntern())) {
2975 .int_type => |int_type| switch (repr) {3024 .int_type => |int_type| o.intType(int_type.bits, repr),
2976 .by_value => try o.builder.intType(int_type.bits),
2977 .in_memory => try o.builder.intType(@intCast(t.abiSize(zcu) * 8)),
2978 },
2979 .ptr_type => |ptr_type| type: {3025 .ptr_type => |ptr_type| type: {
2980 const ptr_ty = try o.builder.ptrType(3026 const ptr_ty = try o.builder.ptrType(
2981 toLlvmAddressSpace(ptr_type.flags.address_space, target),3027 toLlvmAddressSpace(ptr_type.flags.address_space, target),
...@@ -2992,11 +3038,13 @@ pub const Object = struct {...@@ -2992,11 +3038,13 @@ pub const Object = struct {
2992 array_type.lenIncludingSentinel(),3038 array_type.lenIncludingSentinel(),
2993 try o.lowerType(.fromInterned(array_type.child), repr),3039 try o.lowerType(.fromInterned(array_type.child), repr),
2994 ),3040 ),
2995 .vector_type => |vector_type| o.builder.vectorType(3041 .vector_type => |vector_type| if (isByRef(t, zcu)) {
2996 .normal,3042 const child_llvm_ty = try o.lowerType(.fromInterned(vector_type.child), repr);
2997 vector_type.len,3043 return o.builder.arrayType(vector_type.len, child_llvm_ty);
2998 try o.lowerType(.fromInterned(vector_type.child), .by_value),3044 } else {
2999 ),3045 const child_llvm_ty = try o.lowerType(.fromInterned(vector_type.child), .as_value);
3046 return o.builder.vectorType(.normal, vector_type.len, child_llvm_ty);
3047 },
3000 .opt_type => |child_ty| {3048 .opt_type => |child_ty| {
3001 // Must stay in sync with `opt_payload` logic in `lowerPtr`.3049 // Must stay in sync with `opt_payload` logic in `lowerPtr`.
3002 switch (Type.fromInterned(child_ty).classify(zcu)) {3050 switch (Type.fromInterned(child_ty).classify(zcu)) {
...@@ -3256,8 +3304,11 @@ pub const Object = struct {...@@ -3256,8 +3304,11 @@ pub const Object = struct {
3256 return ty;3304 return ty;
3257 },3305 },
3258 .opaque_type, .spirv_type => unreachable, // no runtime bits3306 .opaque_type, .spirv_type => unreachable, // no runtime bits
3259 .enum_type => try o.lowerType(t.backingIntType(zcu), repr),3307 .enum_type => try o.intType(t.backingIntType(zcu).intInfo(zcu).bits, repr),
3260 .func_type => |func_type| try o.lowerFnType(t, func_type),3308 .func_type => |func_type| {
3309 assert(t.fnHasRuntimeBits(zcu));
3310 return o.lowerFnType(.fromIntern(func_type, ip));
3311 },
3261 .error_set_type, .inferred_error_set_type => try o.errorIntType(repr),3312 .error_set_type, .inferred_error_set_type => try o.errorIntType(repr),
3262 // values, not types3313 // values, not types
3263 .undef,3314 .undef,
...@@ -3283,14 +3334,28 @@ pub const Object = struct {...@@ -3283,14 +3334,28 @@ pub const Object = struct {
3283 };3334 };
3284 }3335 }
32853336
3286 fn lowerFnType(o: *Object, fn_ty: Type, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {3337 pub const FuncInfo = struct {
3338 cc: std.lang.CallingConvention,
3339 noalias_bits: u32 = 0,
3340 param_types: []const InternPool.Index,
3341 return_type: InternPool.Index = .void_type,
3342 is_var_args: bool = false,
3343
3344 pub fn fromIntern(fn_info: InternPool.Key.FuncType, ip: *InternPool) FuncInfo {
3345 return .{
3346 .cc = fn_info.cc,
3347 .noalias_bits = fn_info.noalias_bits,
3348 .param_types = fn_info.param_types.get(ip),
3349 .return_type = fn_info.return_type,
3350 .is_var_args = fn_info.is_var_args,
3351 };
3352 }
3353 };
3354 pub fn lowerFnType(o: *Object, fn_info: FuncInfo) Allocator.Error!Builder.Type {
3287 const zcu = o.zcu;3355 const zcu = o.zcu;
3288 const ip = &zcu.intern_pool;
3289 const target = zcu.getTarget();3356 const target = zcu.getTarget();
32903357
3291 assert(fn_ty.fnHasRuntimeBits(zcu));3358 const ret_strat = try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type));
3292
3293 const ret_strat = try fnReturnStrat(o, fn_info);
32943359
3295 var llvm_params: std.ArrayList(Builder.Type) = .empty;3360 var llvm_params: std.ArrayList(Builder.Type) = .empty;
3296 defer llvm_params.deinit(o.gpa);3361 defer llvm_params.deinit(o.gpa);
...@@ -3305,35 +3370,35 @@ pub const Object = struct {...@@ -3305,35 +3370,35 @@ pub const Object = struct {
3305 try llvm_params.append(o.gpa, llvm_ptr_ty);3370 try llvm_params.append(o.gpa, llvm_ptr_ty);
3306 }3371 }
33073372
3308 var it = iterateParamTypes(o, fn_info);3373 var it = iterateParamTypes(o, fn_info.cc, fn_info.param_types);
3309 while (try it.next()) |lowering| switch (lowering) {3374 while (try it.next()) |lowering| switch (lowering) {
3310 .no_bits => continue,3375 .no_bits => continue,
3311 .byval => {3376 .byval => {
3312 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);3377 const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]);
3313 try llvm_params.append(o.gpa, try o.lowerType(param_ty, if (isByRef(param_ty, zcu)) .in_memory else .by_value));3378 try llvm_params.append(o.gpa, try o.lowerType(param_ty, if (isByRef(param_ty, zcu)) .memory_access else .as_value));
3314 },3379 },
3315 .byref, .byref_mut => {3380 .byref, .byref_mut => {
3316 try llvm_params.append(o.gpa, .ptr);3381 try llvm_params.append(o.gpa, .ptr);
3317 },3382 },
3318 .abi_sized_int => {3383 .abi_sized_int => {
3319 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);3384 const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]);
3320 try llvm_params.append(o.gpa, try o.builder.intType(3385 try llvm_params.append(o.gpa, try o.builder.intType(
3321 @intCast(param_ty.abiSize(zcu) * 8),3386 @intCast(param_ty.abiSize(zcu) * 8),
3322 ));3387 ));
3323 },3388 },
3324 .slice => {3389 .slice => {
3325 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);3390 const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]);
3326 try llvm_params.appendSlice(o.gpa, &.{3391 try llvm_params.appendSlice(o.gpa, &.{
3327 try o.builder.ptrType(toLlvmAddressSpace(param_ty.ptrAddressSpace(zcu), target)),3392 try o.builder.ptrType(toLlvmAddressSpace(param_ty.ptrAddressSpace(zcu), target)),
3328 try o.lowerType(.usize, .by_value),3393 try o.lowerType(.usize, .as_value),
3329 });3394 });
3330 },3395 },
3331 .multiple_llvm_types => {3396 .multiple_llvm_types => {
3332 try llvm_params.appendSlice(o.gpa, it.types_buffer[0..it.types_len]);3397 try llvm_params.appendSlice(o.gpa, it.types_buffer[0..it.types_len]);
3333 },3398 },
3334 .float_array => |count| {3399 .float_array => |count| {
3335 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);3400 const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]);
3336 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, zcu).?, .in_memory);3401 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, zcu).?, .memory_access);
3337 try llvm_params.append(o.gpa, try o.builder.arrayType(count, float_ty));3402 try llvm_params.append(o.gpa, try o.builder.arrayType(count, float_ty));
3338 },3403 },
3339 .i32_array, .i64_array => |arr_len| {3404 .i32_array, .i64_array => |arr_len| {
...@@ -3347,7 +3412,7 @@ pub const Object = struct {...@@ -3347,7 +3412,7 @@ pub const Object = struct {
33473412
3348 const llvm_ret_ty: Builder.Type = switch (ret_strat) {3413 const llvm_ret_ty: Builder.Type = switch (ret_strat) {
3349 .void, .sret => .void,3414 .void, .sret => .void,
3350 .by_val => try o.lowerType(.fromInterned(fn_info.return_type), .by_value),3415 .by_val => try o.lowerType(.fromInterned(fn_info.return_type), .as_value),
3351 .mem_cast => |llvm_ret_ty| llvm_ret_ty,3416 .mem_cast => |llvm_ret_ty| llvm_ret_ty,
3352 };3417 };
3353 const llvm_fn_kind: Builder.Type.Function.Kind = switch (fn_info.is_var_args) {3418 const llvm_fn_kind: Builder.Type.Function.Kind = switch (fn_info.is_var_args) {
...@@ -3405,7 +3470,12 @@ pub const Object = struct {...@@ -3405,7 +3470,12 @@ pub const Object = struct {
3405 var bigint_space: Value.BigIntSpace = undefined;3470 var bigint_space: Value.BigIntSpace = undefined;
3406 const bigint = val.toBigInt(&bigint_space, zcu);3471 const bigint = val.toBigInt(&bigint_space, zcu);
3407 const llvm_int_ty = try o.lowerType(ty, repr);3472 const llvm_int_ty = try o.lowerType(ty, repr);
3408 return o.builder.bigIntConst(llvm_int_ty, bigint);3473 if (llvm_int_ty.isInteger(&o.builder))
3474 return o.builder.bigIntConst(llvm_int_ty, bigint);
3475 const buffer = try o.gpa.alloc(u8, llvm_int_ty.aggregateLen(&o.builder));
3476 defer o.gpa.free(buffer);
3477 bigint.writeTwosComplement(buffer, target.cpu.arch.endian());
3478 return o.builder.stringConst(try o.builder.string(buffer));
3409 },3479 },
3410 .err => |err| {3480 .err => |err| {
3411 const int = zcu.intern_pool.getErrorValueIfExists(err.name).?;3481 const int = zcu.intern_pool.getErrorValueIfExists(err.name).?;
...@@ -3460,18 +3530,12 @@ pub const Object = struct {...@@ -3460,18 +3530,12 @@ pub const Object = struct {
3460 },3530 },
3461 .enum_tag => |enum_tag| o.lowerValue(enum_tag.int, repr),3531 .enum_tag => |enum_tag| o.lowerValue(enum_tag.int, repr),
3462 .float => switch (ty.floatBits(target)) {3532 .float => switch (ty.floatBits(target)) {
3463 16 => if (backendSupportsF16(target))
3464 try o.builder.halfConst(val.toFloat(f16, zcu))
3465 else
3466 try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, zcu)))),
3467 32 => try o.builder.floatConst(val.toFloat(f32, zcu)),
3468 64 => try o.builder.doubleConst(val.toFloat(f64, zcu)),
3469 80 => if (backendSupportsF80(target))
3470 try o.builder.x86_fp80Const(val.toFloat(f80, zcu))
3471 else
3472 try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, zcu)))),
3473 128 => try o.builder.fp128Const(val.toFloat(f128, zcu)),
3474 else => unreachable,3533 else => unreachable,
3534 16 => try o.f16Const(val.toFloat(f16, zcu)),
3535 32 => try o.f32Const(val.toFloat(f32, zcu)),
3536 64 => try o.f64Const(val.toFloat(f64, zcu)),
3537 80 => try o.f80Const(val.toFloat(f80, zcu)),
3538 128 => try o.f128Const(val.toFloat(f128, zcu)),
3475 },3539 },
3476 .ptr => try o.lowerPtr(arg_val, 0),3540 .ptr => try o.lowerPtr(arg_val, 0),
3477 .slice => |slice| return o.builder.structConst(try o.lowerType(ty, repr), &.{3541 .slice => |slice| return o.builder.structConst(try o.lowerType(ty, repr), &.{
...@@ -3590,12 +3654,13 @@ pub const Object = struct {...@@ -3590,12 +3654,13 @@ pub const Object = struct {
3590 },3654 },
3591 .vector_type => |vector_type| {3655 .vector_type => |vector_type| {
3592 const vector_ty = try o.lowerType(ty, repr);3656 const vector_ty = try o.lowerType(ty, repr);
3657 const ExpectedContents = [Builder.expected_fields_len]Builder.Constant;
3658 var bfa_buf: ExpectedContents = undefined;
3659 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), o.gpa);
3660 const allocator = bfa.allocator();
3661 const is_by_ref = isByRef(ty, zcu);
3593 switch (aggregate.storage) {3662 switch (aggregate.storage) {
3594 .bytes, .elems => {3663 .bytes, .elems => {
3595 const ExpectedContents = [Builder.expected_fields_len]Builder.Constant;
3596 var bfa_buf: ExpectedContents = undefined;
3597 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), o.gpa);
3598 const allocator = bfa.allocator();
3599 const vals = try allocator.alloc(Builder.Constant, vector_type.len);3664 const vals = try allocator.alloc(Builder.Constant, vector_type.len);
3600 defer allocator.free(vals);3665 defer allocator.free(vals);
36013666
...@@ -3604,16 +3669,21 @@ pub const Object = struct {...@@ -3604,16 +3669,21 @@ pub const Object = struct {
3604 result_val.* = try o.builder.intConst(.i8, byte);3669 result_val.* = try o.builder.intConst(.i8, byte);
3605 },3670 },
3606 .elems => |elems| for (vals, elems) |*result_val, elem| {3671 .elems => |elems| for (vals, elems) |*result_val, elem| {
3607 result_val.* = try o.lowerValue(elem, .by_value);3672 result_val.* = try o.lowerValue(elem, if (is_by_ref) repr else .as_value);
3608 },3673 },
3609 .repeated_elem => unreachable,3674 .repeated_elem => unreachable,
3610 }3675 }
3611 return o.builder.vectorConst(vector_ty, vals);3676 return if (is_by_ref)
3677 o.builder.arrayConst(vector_ty, vals)
3678 else
3679 o.builder.vectorConst(vector_ty, vals);
3612 },3680 },
3613 .repeated_elem => |elem| return o.builder.splatConst(3681 .repeated_elem => |elem| if (is_by_ref) {
3614 vector_ty,3682 const vals = try allocator.alloc(Builder.Constant, vector_type.len);
3615 try o.lowerValue(elem, .by_value),3683 defer allocator.free(vals);
3616 ),3684 @memset(vals, try o.lowerValue(elem, repr));
3685 return o.builder.arrayConst(vector_ty, vals);
3686 } else return o.builder.splatConst(vector_ty, try o.lowerValue(elem, .as_value)),
3617 }3687 }
3618 },3688 },
3619 .tuple_type => |tuple| {3689 .tuple_type => |tuple| {
...@@ -3841,6 +3911,117 @@ pub const Object = struct {...@@ -3841,6 +3911,117 @@ pub const Object = struct {
3841 };3911 };
3842 }3912 }
38433913
3914 pub fn f16Const(o: *Object, val: f16) Allocator.Error!Builder.Constant {
3915 return switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 16)) {
3916 .hard => o.builder.halfConst(val),
3917 .soft => o.builder.intConst(.i16, @as(u16, @bitCast(val))),
3918 };
3919 }
3920
3921 pub fn f32Const(o: *Object, val: f32) Allocator.Error!Builder.Constant {
3922 return switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 32)) {
3923 .hard => o.builder.floatConst(val),
3924 .soft => o.builder.intConst(.i32, @as(u32, @bitCast(val))),
3925 };
3926 }
3927
3928 pub fn f64Const(o: *Object, val: f64) Allocator.Error!Builder.Constant {
3929 return switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 64)) {
3930 .hard => o.builder.doubleConst(val),
3931 .soft => o.builder.intConst(.i64, @as(u64, @bitCast(val))),
3932 };
3933 }
3934
3935 pub fn f80Const(o: *Object, val: f80) Allocator.Error!Builder.Constant {
3936 switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 80)) {
3937 .hard => return o.builder.x86_fp80Const(val),
3938 .soft => {},
3939 }
3940 var llvm_field_tags_buf: [5]SoftF80Layout.LlvmFieldTag = undefined;
3941 var llvm_field_types_buf: [5]Builder.Type = undefined;
3942 const f80_layout = try o.softF80Layout(.{
3943 .llvm_field_tags_buf = &llvm_field_tags_buf,
3944 .llvm_field_types_buf = &llvm_field_types_buf,
3945 });
3946 const llvm_field_types = llvm_field_types_buf[0..f80_layout.llvm_fields_len];
3947 const f80_llvm_ty = try o.builder.structType(.normal, llvm_field_types);
3948 const f80_repr: packed struct { mantissa: u64, exponent: u16 } = @bitCast(val);
3949 var llvm_field_vals_buf: [5]Builder.Constant = undefined;
3950 const llvm_field_vals = llvm_field_vals_buf[0..f80_layout.llvm_fields_len];
3951 for (
3952 llvm_field_vals,
3953 llvm_field_tags_buf[0..f80_layout.llvm_fields_len],
3954 llvm_field_types,
3955 ) |*llvm_field_val, llvm_field_tag, llvm_field_type|
3956 llvm_field_val.* = switch (llvm_field_tag) {
3957 .mantissa => try o.builder.intConst(llvm_field_type, f80_repr.mantissa),
3958 .exponent => try o.builder.intConst(llvm_field_type, f80_repr.exponent),
3959 .padding => try o.builder.undefConst(llvm_field_type),
3960 };
3961 return o.builder.structConst(f80_llvm_ty, llvm_field_vals);
3962 }
3963
3964 pub fn f128Const(o: *Object, val: f128) Allocator.Error!Builder.Constant {
3965 switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 128)) {
3966 .hard => return o.builder.fp128Const(val),
3967 .soft => {},
3968 }
3969 var llvm_field_tags_buf: [5]SoftF128Layout.LlvmFieldTag = undefined;
3970 var llvm_field_types_buf: [5]Builder.Type = undefined;
3971 const f128_layout = try o.softF128Layout(.{
3972 .llvm_field_tags_buf = &llvm_field_tags_buf,
3973 .llvm_field_types_buf = &llvm_field_types_buf,
3974 });
3975 const llvm_field_types = llvm_field_types_buf[0..f128_layout.llvm_fields_len];
3976 const f128_llvm_ty = try o.builder.structType(.normal, llvm_field_types);
3977 const f128_repr: packed struct { lo: u64, hi: u64 } = @bitCast(val);
3978 var llvm_field_vals_buf: [5]Builder.Constant = undefined;
3979 const llvm_field_vals = llvm_field_vals_buf[0..f128_layout.llvm_fields_len];
3980 for (
3981 llvm_field_vals,
3982 llvm_field_tags_buf[0..f128_layout.llvm_fields_len],
3983 llvm_field_types,
3984 ) |*llvm_field_val, llvm_field_tag, llvm_field_type|
3985 llvm_field_val.* = switch (llvm_field_tag) {
3986 .lo => try o.builder.intConst(llvm_field_type, f128_repr.lo),
3987 .hi => try o.builder.intConst(llvm_field_type, f128_repr.hi),
3988 .padding => try o.builder.undefConst(llvm_field_type),
3989 };
3990 return o.builder.structConst(f128_llvm_ty, llvm_field_vals);
3991 }
3992
3993 pub fn lowerConstRef(
3994 o: *Object,
3995 constant: Builder.Constant,
3996 @"align": Builder.Alignment,
3997 ) Allocator.Error!Builder.Constant {
3998 assert(@"align" != .default);
3999 const zcu = o.zcu;
4000 const gpa = zcu.comp.gpa;
4001 const gop = try o.const_map.getOrPut(gpa, constant);
4002 if (gop.found_existing) {
4003 // Keep the greater of the two alignments.
4004 const llvm_variable = gop.value_ptr.*;
4005 const llvm_old_align = llvm_variable.getAlignment(&o.builder);
4006 const llvm_new_align = llvm_old_align.max(@"align");
4007 llvm_variable.setAlignment(llvm_new_align, &o.builder);
4008 return llvm_variable.ptrConst(&o.builder).global.toConst();
4009 }
4010 errdefer assert(o.const_map.remove(constant));
4011
4012 const llvm_ty = constant.typeOf(&o.builder);
4013 const llvm_addrspace = toLlvmAddressSpace(.generic, zcu.getTarget());
4014 const llvm_variable = try o.builder.addVariable(.empty, llvm_ty, llvm_addrspace);
4015 gop.value_ptr.* = llvm_variable;
4016 try llvm_variable.setInitializer(constant, &o.builder);
4017 llvm_variable.setMutability(.constant, &o.builder);
4018 llvm_variable.setAlignment(@"align", &o.builder);
4019 const llvm_global = llvm_variable.ptrConst(&o.builder).global;
4020 llvm_global.setLinkage(.private, &o.builder);
4021 llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder);
4022 return llvm_global.toConst();
4023 }
4024
3844 fn lowerPtr(4025 fn lowerPtr(
3845 o: *Object,4026 o: *Object,
3846 ptr_val: InternPool.Index,4027 ptr_val: InternPool.Index,
...@@ -3860,7 +4041,7 @@ pub const Object = struct {...@@ -3860,7 +4041,7 @@ pub const Object = struct {
3860 const orig_ptr_ty: Type = .fromInterned(uav.orig_ty);4041 const orig_ptr_ty: Type = .fromInterned(uav.orig_ty);
3861 const base_ptr = try o.lowerUavRef(4042 const base_ptr = try o.lowerUavRef(
3862 uav.val,4043 uav.val,
3863 orig_ptr_ty.ptrAlignment(zcu),4044 orig_ptr_ty.ptrAlignment(zcu).toLlvm(),
3864 orig_ptr_ty.ptrAddressSpace(zcu),4045 orig_ptr_ty.ptrAddressSpace(zcu),
3865 );4046 );
3866 return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{4047 return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{
...@@ -3869,8 +4050,8 @@ pub const Object = struct {...@@ -3869,8 +4050,8 @@ pub const Object = struct {
3869 },4050 },
3870 .int => try o.builder.castConst(4051 .int => try o.builder.castConst(
3871 .inttoptr,4052 .inttoptr,
3872 try o.builder.intConst(try o.lowerType(.usize, .by_value), offset),4053 try o.builder.intConst(try o.lowerType(.usize, .as_value), offset),
3873 try o.lowerType(.fromInterned(ptr.ty), .by_value),4054 try o.lowerType(.fromInterned(ptr.ty), .as_value),
3874 ),4055 ),
3875 .eu_payload => |eu_ptr| try o.lowerPtr(4056 .eu_payload => |eu_ptr| try o.lowerPtr(
3876 eu_ptr,4057 eu_ptr,
...@@ -3912,12 +4093,12 @@ pub const Object = struct {...@@ -3912,12 +4093,12 @@ pub const Object = struct {
39124093
3913 pub fn lowerPtrToVoid(4094 pub fn lowerPtrToVoid(
3914 o: *Object,4095 o: *Object,
3915 /// Must not be `.none`.4096 /// Must not be `.default`.
3916 @"align": InternPool.Alignment,4097 @"align": Builder.Alignment,
3917 @"addrspace": std.lang.AddressSpace,4098 @"addrspace": std.lang.AddressSpace,
3918 ) Allocator.Error!Builder.Constant {4099 ) Allocator.Error!Builder.Constant {
3919 const addr: u64 = @"align".toByteUnits().?;4100 const addr: u64 = @"align".toByteUnits().?;
3920 const llvm_usize = try o.lowerType(.usize, .by_value);4101 const llvm_usize = try o.lowerType(.usize, .as_value);
3921 const llvm_addr = try o.builder.intConst(llvm_usize, addr);4102 const llvm_addr = try o.builder.intConst(llvm_usize, addr);
3922 const llvm_ptr_ty = try o.builder.ptrType(toLlvmAddressSpace(@"addrspace", o.zcu.getTarget()));4103 const llvm_ptr_ty = try o.builder.ptrType(toLlvmAddressSpace(@"addrspace", o.zcu.getTarget()));
3923 return o.builder.castConst(.inttoptr, llvm_addr, llvm_ptr_ty);4104 return o.builder.castConst(.inttoptr, llvm_addr, llvm_ptr_ty);
...@@ -3926,11 +4107,11 @@ pub const Object = struct {...@@ -3926,11 +4107,11 @@ pub const Object = struct {
3926 pub fn lowerUavRef(4107 pub fn lowerUavRef(
3927 o: *Object,4108 o: *Object,
3928 uav_val: InternPool.Index,4109 uav_val: InternPool.Index,
3929 /// Must not be `.none`.4110 /// Must not be `.default`.
3930 @"align": InternPool.Alignment,4111 @"align": Builder.Alignment,
3931 @"addrspace": std.lang.AddressSpace,4112 @"addrspace": std.lang.AddressSpace,
3932 ) Allocator.Error!Builder.Constant {4113 ) Allocator.Error!Builder.Constant {
3933 assert(@"align" != .none);4114 assert(@"align" != .default);
39344115
3935 const zcu = o.zcu;4116 const zcu = o.zcu;
3936 const ip = &zcu.intern_pool;4117 const ip = &zcu.intern_pool;
...@@ -3955,19 +4136,18 @@ pub const Object = struct {...@@ -3955,19 +4136,18 @@ pub const Object = struct {
3955 // Keep the greater of the two alignments.4136 // Keep the greater of the two alignments.
3956 const llvm_variable = gop.value_ptr.*;4137 const llvm_variable = gop.value_ptr.*;
3957 const llvm_old_align = llvm_variable.getAlignment(&o.builder);4138 const llvm_old_align = llvm_variable.getAlignment(&o.builder);
3958 const llvm_new_align = llvm_old_align.max(@"align".toLlvm());4139 const llvm_new_align = llvm_old_align.max(@"align");
3959 llvm_variable.setAlignment(llvm_new_align, &o.builder);4140 llvm_variable.setAlignment(llvm_new_align, &o.builder);
3960 return llvm_variable.ptrConst(&o.builder).global.toConst();4141 return llvm_variable.ptrConst(&o.builder).global.toConst();
3961 }4142 }
3962 errdefer assert(o.uav_map.remove(.{ .val = uav_val, .@"addrspace" = @"addrspace" }));4143 errdefer assert(o.uav_map.remove(.{ .val = uav_val, .@"addrspace" = @"addrspace" }));
39634144
3964 const llvm_ty = try o.lowerType(uav_ty, .in_memory);
3965 const llvm_name = try o.builder.strtabStringFmt("__anon_{d}", .{@backingInt(uav_val)});4145 const llvm_name = try o.builder.strtabStringFmt("__anon_{d}", .{@backingInt(uav_val)});
3966 const llvm_variable = try o.builder.addVariable(llvm_name, llvm_ty, llvm_addrspace);4146 const llvm_variable = try o.builder.addVariable(llvm_name, .void, llvm_addrspace);
3967 gop.value_ptr.* = llvm_variable;4147 gop.value_ptr.* = llvm_variable;
3968 try llvm_variable.setInitializer(try o.lowerValue(uav_val, .in_memory), &o.builder);4148 try llvm_variable.setInitializer(try o.lowerValue(uav_val, .in_memory), &o.builder);
3969 llvm_variable.setMutability(.constant, &o.builder);4149 llvm_variable.setMutability(.constant, &o.builder);
3970 llvm_variable.setAlignment(@"align".toLlvm(), &o.builder);4150 llvm_variable.setAlignment(@"align", &o.builder);
3971 const llvm_global = llvm_variable.ptrConst(&o.builder).global;4151 const llvm_global = llvm_variable.ptrConst(&o.builder).global;
3972 llvm_global.setLinkage(if (o.builder.strip) .private else .internal, &o.builder);4152 llvm_global.setLinkage(if (o.builder.strip) .private else .internal, &o.builder);
3973 llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder);4153 llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder);
...@@ -3986,7 +4166,7 @@ pub const Object = struct {...@@ -3986,7 +4166,7 @@ pub const Object = struct {
3986 .none => nav_ty.abiAlignment(zcu),4166 .none => nav_ty.abiAlignment(zcu),
3987 else => |a| a,4167 else => |a| a,
3988 };4168 };
3989 return o.lowerPtrToVoid(nav_align, nav.resolved.?.@"addrspace");4169 return o.lowerPtrToVoid(nav_align.toLlvm(), nav.resolved.?.@"addrspace");
3990 }4170 }
39914171
3992 const gop = try o.nav_map.getOrPut(gpa, nav_id);4172 const gop = try o.nav_map.getOrPut(gpa, nav_id);
...@@ -4015,7 +4195,7 @@ pub const Object = struct {...@@ -4015,7 +4195,7 @@ pub const Object = struct {
4015 attributes: *Builder.FunctionAttributes.Wip,4195 attributes: *Builder.FunctionAttributes.Wip,
4016 param_ty: Type,4196 param_ty: Type,
4017 param_index: u32,4197 param_index: u32,
4018 fn_info: InternPool.Key.FuncType,4198 fn_info: FuncInfo,
4019 llvm_arg_i: u32,4199 llvm_arg_i: u32,
4020 ) Allocator.Error!void {4200 ) Allocator.Error!void {
4021 const zcu = o.zcu;4201 const zcu = o.zcu;
...@@ -4055,19 +4235,26 @@ pub const Object = struct {...@@ -4055,19 +4235,26 @@ pub const Object = struct {
4055 };4235 };
4056 }4236 }
40574237
4238 pub const Byval = struct { alignment: InternPool.Alignment = .none };
4058 pub fn addByRefParamAttrs(4239 pub fn addByRefParamAttrs(
4059 o: *Object,4240 o: *Object,
4060 attributes: *Builder.FunctionAttributes.Wip,4241 attributes: *Builder.FunctionAttributes.Wip,
4061 llvm_arg_i: u32,4242 llvm_arg_i: u32,
4062 byval: bool,4243 maybe_byval: ?Byval,
4063 param_ty: Type,4244 param_ty: Type,
4064 ) Allocator.Error!void {4245 ) Allocator.Error!void {
4065 const llvm_param_ty = try o.lowerType(param_ty, .in_memory);4246 const llvm_param_ty = try o.lowerType(param_ty, .in_memory);
4066 const alignment = param_ty.abiAlignment(o.zcu).toLlvm();
4067 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
4068 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);4247 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
4069 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = .wrap(alignment) }, &o.builder);4248 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
4070 if (byval) try attributes.addParamAttr(llvm_arg_i, .{ .byval = llvm_param_ty }, &o.builder);4249 try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder);
4250 const alignment = if (maybe_byval) |byval| alignment: {
4251 try attributes.addParamAttr(llvm_arg_i, .{ .byval = llvm_param_ty }, &o.builder);
4252 break :alignment byval.alignment;
4253 } else .none;
4254 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = .wrap(switch (alignment) {
4255 .none => param_ty.abiAlignment(o.zcu),
4256 else => alignment,
4257 }.toLlvm()) }, &o.builder);
4071 }4258 }
40724259
4073 pub fn getErrorNameTable(o: *Object) Allocator.Error!Builder.Variable.Index {4260 pub fn getErrorNameTable(o: *Object) Allocator.Error!Builder.Variable.Index {
...@@ -4075,18 +4262,18 @@ pub const Object = struct {...@@ -4075,18 +4262,18 @@ pub const Object = struct {
40754262
4076 const name = try o.builder.strtabString("__zig_error_name_table");4263 const name = try o.builder.strtabString("__zig_error_name_table");
4077 // TODO: Address space4264 // TODO: Address space
4078 const variable_index = try o.builder.addVariable(name, .ptr, .default);4265 const llvm_variable = try o.builder.addVariable(name, .ptr, .default);
4079 variable_index.setMutability(.constant, &o.builder);4266 llvm_variable.setMutability(.constant, &o.builder);
4080 variable_index.setAlignment(4267 llvm_variable.setAlignment(
4081 Type.slice_const_u8_sentinel_0.abiAlignment(o.zcu).toLlvm(),4268 Type.slice_const_u8_sentinel_0.abiAlignment(o.zcu).toLlvm(),
4082 &o.builder,4269 &o.builder,
4083 );4270 );
4084 const global_index = variable_index.ptrConst(&o.builder).global;4271 const llvm_global = llvm_variable.ptrConst(&o.builder).global;
4085 global_index.setLinkage(.private, &o.builder);4272 llvm_global.setLinkage(.private, &o.builder);
4086 global_index.setUnnamedAddr(.unnamed_addr, &o.builder);4273 llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder);
40874274
4088 o.error_name_table = variable_index;4275 o.error_name_table = llvm_variable;
4089 return variable_index;4276 return llvm_variable;
4090 }4277 }
40914278
4092 pub fn getErrorsLen(o: *Object) Allocator.Error!Builder.Variable.Index {4279 pub fn getErrorsLen(o: *Object) Allocator.Error!Builder.Variable.Index {
...@@ -4094,13 +4281,13 @@ pub const Object = struct {...@@ -4094,13 +4281,13 @@ pub const Object = struct {
4094 if (o.errors_len_variable == .none) {4281 if (o.errors_len_variable == .none) {
4095 const llvm_err_int_ty = try o.errorIntType(.in_memory);4282 const llvm_err_int_ty = try o.errorIntType(.in_memory);
4096 const name = try builder.strtabString("__zig_errors_len");4283 const name = try builder.strtabString("__zig_errors_len");
4097 const variable_index = try builder.addVariable(name, llvm_err_int_ty, .default);4284 const llvm_variable = try builder.addVariable(name, llvm_err_int_ty, .default);
4098 variable_index.setMutability(.constant, builder);4285 llvm_variable.setMutability(.constant, builder);
4099 variable_index.setAlignment(Type.errorAbiAlignment(o.zcu).toLlvm(), builder);4286 llvm_variable.setAlignment(Type.errorAbiAlignment(o.zcu).toLlvm(), builder);
4100 const global_index = variable_index.ptrConst(&o.builder).global;4287 const llvm_global = llvm_variable.ptrConst(&o.builder).global;
4101 global_index.setLinkage(.private, builder);4288 llvm_global.setLinkage(.private, builder);
4102 global_index.setUnnamedAddr(.unnamed_addr, builder);4289 llvm_global.setUnnamedAddr(.unnamed_addr, builder);
4103 o.errors_len_variable = variable_index;4290 o.errors_len_variable = llvm_variable;
4104 }4291 }
4105 return o.errors_len_variable;4292 return o.errors_len_variable;
4106 }4293 }
...@@ -4112,43 +4299,43 @@ pub const Object = struct {...@@ -4112,43 +4299,43 @@ pub const Object = struct {
4112 const gop = try o.enum_tag_name_map.getOrPut(o.gpa, enum_ty.toIntern());4299 const gop = try o.enum_tag_name_map.getOrPut(o.gpa, enum_ty.toIntern());
4113 if (gop.found_existing) return gop.value_ptr.*;4300 if (gop.found_existing) return gop.value_ptr.*;
4114 errdefer assert(o.enum_tag_name_map.remove(enum_ty.toIntern()));4301 errdefer assert(o.enum_tag_name_map.remove(enum_ty.toIntern()));
4115 const function_index = try o.builder.addFunction(4302 const llvm_function = try o.builder.addFunction(
4116 // Dummy function type; `updateEnumTagNameFunction` will replace it with the correct type.4303 // Dummy function type; `updateEnumTagNameFunction` will replace it with the correct type.
4117 // TODO: change the builder API so we don't need to do this.4304 // TODO: change the builder API so we don't need to do this.
4118 try o.builder.fnType(.void, &.{}, .normal),4305 try o.builder.fnType(.void, &.{}, .normal),
4119 try o.builder.strtabStringFmt("__zig_tag_name_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}),4306 try o.builder.strtabStringFmt("__zig_tag_name_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}),
4120 toLlvmAddressSpace(.generic, zcu.getTarget()),4307 toLlvmAddressSpace(.generic, zcu.getTarget()),
4121 );4308 );
4122 gop.value_ptr.* = function_index;4309 gop.value_ptr.* = llvm_function;
4123 try o.updateEnumTagNameFunction(enum_ty, function_index);4310 try o.updateEnumTagNameFunction(enum_ty, llvm_function);
4124 return function_index;4311 return llvm_function;
4125 }4312 }
4126 fn updateEnumTagNameFunction(4313 fn updateEnumTagNameFunction(
4127 o: *Object,4314 o: *Object,
4128 enum_ty: Type,4315 enum_ty: Type,
4129 function_index: Builder.Function.Index,4316 llvm_function: Builder.Function.Index,
4130 ) Allocator.Error!void {4317 ) Allocator.Error!void {
4131 const zcu = o.zcu;4318 const zcu = o.zcu;
4132 const ip = &zcu.intern_pool;4319 const ip = &zcu.intern_pool;
4133 const loaded_enum = ip.loadEnumType(enum_ty.toIntern());4320 const loaded_enum = ip.loadEnumType(enum_ty.toIntern());
41344321
4135 const llvm_usize_ty = try o.lowerType(.usize, .by_value);4322 const llvm_usize_ty = try o.lowerType(.usize, .as_value);
4136 const llvm_ret_ty = try o.lowerType(.slice_const_u8_sentinel_0, .by_value);4323 const llvm_ret_ty = try o.lowerType(.slice_const_u8_sentinel_0, .as_value);
4137 const llvm_int_ty = try o.lowerType(.fromInterned(loaded_enum.int_tag_type), .by_value);4324 const llvm_int_ty = try o.lowerType(.fromInterned(loaded_enum.int_tag_type), .as_value);
41384325
4139 function_index.ptrConst(&o.builder).global.ptr(&o.builder).type =4326 llvm_function.ptrConst(&o.builder).global.ptr(&o.builder).type =
4140 try o.builder.fnType(llvm_ret_ty, &.{llvm_int_ty}, .normal);4327 try o.builder.fnType(llvm_ret_ty, &.{llvm_int_ty}, .normal);
41414328
4142 var attributes: Builder.FunctionAttributes.Wip = .{};4329 var attributes: Builder.FunctionAttributes.Wip = .{};
4143 defer attributes.deinit(&o.builder);4330 defer attributes.deinit(&o.builder);
4144 try o.addCommonFnAttributes(&attributes, zcu.root_mod, zcu.root_mod.omit_frame_pointer);4331 try o.addCommonFnAttributes(&attributes, zcu.root_mod, zcu.root_mod.omit_frame_pointer);
41454332
4146 function_index.setLinkage(if (o.builder.strip) .private else .internal, &o.builder);4333 llvm_function.setLinkage(if (o.builder.strip) .private else .internal, &o.builder);
4147 function_index.setCallConv(.fastcc, &o.builder);4334 llvm_function.setCallConv(.fastcc, &o.builder);
4148 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);4335 llvm_function.setAttributes(try attributes.finish(&o.builder), &o.builder);
41494336
4150 var wip = try Builder.WipFunction.init(&o.builder, .{4337 var wip = try Builder.WipFunction.init(&o.builder, .{
4151 .function = function_index,4338 .function = llvm_function,
4152 .strip = true,4339 .strip = true,
4153 });4340 });
4154 defer wip.deinit();4341 defer wip.deinit();
...@@ -4167,23 +4354,23 @@ pub const Object = struct {...@@ -4167,23 +4354,23 @@ pub const Object = struct {
4167 for (0..loaded_enum.field_names.len) |field_index| {4354 for (0..loaded_enum.field_names.len) |field_index| {
4168 const name = try o.builder.stringNull(loaded_enum.field_names.get(ip)[field_index].toSlice(ip));4355 const name = try o.builder.stringNull(loaded_enum.field_names.get(ip)[field_index].toSlice(ip));
4169 const name_init = try o.builder.stringConst(name);4356 const name_init = try o.builder.stringConst(name);
4170 const name_variable_index = try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);4357 const name_llvm_variable = try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
4171 try name_variable_index.setInitializer(name_init, &o.builder);4358 try name_llvm_variable.setInitializer(name_init, &o.builder);
4172 name_variable_index.setMutability(.constant, &o.builder);4359 name_llvm_variable.setMutability(.constant, &o.builder);
4173 name_variable_index.setAlignment(comptime Builder.Alignment.fromByteUnits(1), &o.builder);4360 name_llvm_variable.setAlignment(comptime .fromByteUnits(1), &o.builder);
4174 const name_global_index = name_variable_index.ptrConst(&o.builder).global;4361 const name_llvm_global = name_llvm_variable.ptrConst(&o.builder).global;
4175 name_global_index.setLinkage(.private, &o.builder);4362 name_llvm_global.setLinkage(.private, &o.builder);
4176 name_global_index.setUnnamedAddr(.unnamed_addr, &o.builder);4363 name_llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder);
41774364
4178 const name_val = try o.builder.structValue(llvm_ret_ty, &.{4365 const name_val = try o.builder.structValue(llvm_ret_ty, &.{
4179 name_global_index.toConst(),4366 name_llvm_global.toConst(),
4180 try o.builder.intConst(llvm_usize_ty, name.slice(&o.builder).?.len - 1),4367 try o.builder.intConst(llvm_usize_ty, name.slice(&o.builder).?.len - 1),
4181 });4368 });
41824369
4183 const return_block = try wip.block(1, "Name");4370 const return_block = try wip.block(1, "Name");
4184 const llvm_tag_val = switch (loaded_enum.field_values.getOrNone(ip, field_index)) {4371 const llvm_tag_val = switch (loaded_enum.field_values.getOrNone(ip, field_index)) {
4185 .none => try o.builder.intConst(llvm_int_ty, field_index), // auto-numbered4372 .none => try o.builder.intConst(llvm_int_ty, field_index), // auto-numbered
4186 else => |tag_val_ip| try o.lowerValue(tag_val_ip, .by_value),4373 else => |tag_val_ip| try o.lowerValue(tag_val_ip, .as_value),
4187 };4374 };
4188 try wip_switch.addCase(llvm_tag_val, return_block, &wip);4375 try wip_switch.addCase(llvm_tag_val, return_block, &wip);
41894376
...@@ -4209,40 +4396,40 @@ pub const Object = struct {...@@ -4209,40 +4396,40 @@ pub const Object = struct {
4209 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern());4396 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern());
4210 if (gop.found_existing) return gop.value_ptr.*;4397 if (gop.found_existing) return gop.value_ptr.*;
4211 errdefer assert(o.named_enum_map.remove(enum_ty.toIntern()));4398 errdefer assert(o.named_enum_map.remove(enum_ty.toIntern()));
4212 const function_index = try o.builder.addFunction(4399 const llvm_function = try o.builder.addFunction(
4213 // Dummy function type; `updateIsNamedEnumValue` will replace it with the correct type.4400 // Dummy function type; `updateIsNamedEnumValue` will replace it with the correct type.
4214 // TODO: change the builder API so we don't need to do this.4401 // TODO: change the builder API so we don't need to do this.
4215 try o.builder.fnType(.void, &.{}, .normal),4402 try o.builder.fnType(.void, &.{}, .normal),
4216 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}),4403 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}),
4217 toLlvmAddressSpace(.generic, zcu.getTarget()),4404 toLlvmAddressSpace(.generic, zcu.getTarget()),
4218 );4405 );
4219 gop.value_ptr.* = function_index;4406 gop.value_ptr.* = llvm_function;
4220 try o.updateIsNamedEnumValueFunction(enum_ty, function_index);4407 try o.updateIsNamedEnumValueFunction(enum_ty, llvm_function);
4221 return function_index;4408 return llvm_function;
4222 }4409 }
4223 fn updateIsNamedEnumValueFunction(4410 fn updateIsNamedEnumValueFunction(
4224 o: *Object,4411 o: *Object,
4225 enum_ty: Type,4412 enum_ty: Type,
4226 function_index: Builder.Function.Index,4413 llvm_function: Builder.Function.Index,
4227 ) Allocator.Error!void {4414 ) Allocator.Error!void {
4228 const zcu = o.zcu;4415 const zcu = o.zcu;
4229 const ip = &zcu.intern_pool;4416 const ip = &zcu.intern_pool;
4230 const loaded_enum = ip.loadEnumType(enum_ty.toIntern());4417 const loaded_enum = ip.loadEnumType(enum_ty.toIntern());
42314418
4232 const llvm_int_ty = try o.lowerType(.fromInterned(loaded_enum.int_tag_type), .by_value);4419 const llvm_int_ty = try o.lowerType(.fromInterned(loaded_enum.int_tag_type), .as_value);
4233 function_index.ptrConst(&o.builder).global.ptr(&o.builder).type =4420 llvm_function.ptrConst(&o.builder).global.ptr(&o.builder).type =
4234 try o.builder.fnType(.i1, &.{llvm_int_ty}, .normal);4421 try o.builder.fnType(.i1, &.{llvm_int_ty}, .normal);
42354422
4236 var attributes: Builder.FunctionAttributes.Wip = .{};4423 var attributes: Builder.FunctionAttributes.Wip = .{};
4237 defer attributes.deinit(&o.builder);4424 defer attributes.deinit(&o.builder);
4238 try o.addCommonFnAttributes(&attributes, zcu.root_mod, zcu.root_mod.omit_frame_pointer);4425 try o.addCommonFnAttributes(&attributes, zcu.root_mod, zcu.root_mod.omit_frame_pointer);
42394426
4240 function_index.setLinkage(if (o.builder.strip) .private else .internal, &o.builder);4427 llvm_function.setLinkage(if (o.builder.strip) .private else .internal, &o.builder);
4241 function_index.setCallConv(.fastcc, &o.builder);4428 llvm_function.setCallConv(.fastcc, &o.builder);
4242 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);4429 llvm_function.setAttributes(try attributes.finish(&o.builder), &o.builder);
42434430
4244 var wip: Builder.WipFunction = try .init(&o.builder, .{4431 var wip: Builder.WipFunction = try .init(&o.builder, .{
4245 .function = function_index,4432 .function = llvm_function,
4246 .strip = true,4433 .strip = true,
4247 });4434 });
4248 defer wip.deinit();4435 defer wip.deinit();
...@@ -4256,7 +4443,7 @@ pub const Object = struct {...@@ -4256,7 +4443,7 @@ pub const Object = struct {
42564443
4257 if (loaded_enum.field_values.len > 0) {4444 if (loaded_enum.field_values.len > 0) {
4258 for (loaded_enum.field_values.get(ip)) |tag_val_ip| {4445 for (loaded_enum.field_values.get(ip)) |tag_val_ip| {
4259 const llvm_tag_val = try o.lowerValue(tag_val_ip, .by_value);4446 const llvm_tag_val = try o.lowerValue(tag_val_ip, .as_value);
4260 try wip_switch.addCase(llvm_tag_val, named_block, &wip);4447 try wip_switch.addCase(llvm_tag_val, named_block, &wip);
4261 }4448 }
4262 } else {4449 } else {
...@@ -4278,20 +4465,27 @@ pub const Object = struct {...@@ -4278,20 +4465,27 @@ pub const Object = struct {
42784465
4279 pub fn getLibcFunction(4466 pub fn getLibcFunction(
4280 o: *Object,4467 o: *Object,
4468 pt: Zcu.PerThread,
4281 fn_name: Builder.StrtabString,4469 fn_name: Builder.StrtabString,
4282 param_types: []const Builder.Type,4470 fn_info: FuncInfo,
4283 return_type: Builder.Type,
4284 ) Allocator.Error!Builder.Function.Index {4471 ) Allocator.Error!Builder.Function.Index {
4285 if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {4472 if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {
4286 .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,4473 .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,
4287 .function => |function| function,4474 .function => |function| function,
4288 .variable, .replaced => unreachable,4475 .variable, .replaced => unreachable,
4289 };4476 };
4290 return o.builder.addFunction(4477 const llvm_function = try o.builder.addFunction(
4291 try o.builder.fnType(return_type, param_types, .normal),4478 try o.lowerFnType(fn_info),
4292 fn_name,4479 fn_name,
4293 toLlvmAddressSpace(.generic, o.zcu.getTarget()),4480 toLlvmAddressSpace(.generic, o.zcu.getTarget()),
4294 );4481 );
4482 var attributes: Builder.FunctionAttributes.Wip = .{};
4483 defer attributes.deinit(&o.builder);
4484 try o.addCallingConventionFnAttributes(pt, llvm_function, &attributes, .{
4485 .name = fn_name.slice(&o.builder).?,
4486 }, fn_info);
4487 llvm_function.setAttributes(try attributes.finish(&o.builder), &o.builder);
4488 return llvm_function;
4295 }4489 }
4296};4490};
42974491
...@@ -4328,7 +4522,7 @@ pub fn toLlvmCallConv(cc: std.lang.CallingConvention, target: *const std.Target)...@@ -4328,7 +4522,7 @@ pub fn toLlvmCallConv(cc: std.lang.CallingConvention, target: *const std.Target)
4328 std.lang.CallingConvention.SpirvFragmentOptions,4522 std.lang.CallingConvention.SpirvFragmentOptions,
4329 std.lang.CallingConvention.SpirvMeshOptions,4523 std.lang.CallingConvention.SpirvMeshOptions,
4330 => .{ null, 0, 0 },4524 => .{ null, 0, 0 },
4331 else => @compileError("TODO: toLlvmCallConv" ++ @tagName(pl)),4525 else => @compileError("TODO: toLlvmCallConv(." ++ @tagName(pl) ++ ")"),
4332 },4526 },
4333 };4527 };
4334 return .{4528 return .{
...@@ -4411,6 +4605,7 @@ pub fn toLlvmCallConvTag(cc_tag: std.lang.CallingConvention.Tag, target: *const...@@ -4411,6 +4605,7 @@ pub fn toLlvmCallConvTag(cc_tag: std.lang.CallingConvention.Tag, target: *const
4411 .x86_16_interrupt,4605 .x86_16_interrupt,
4412 .x86_sysv,4606 .x86_sysv,
4413 .x86_win,4607 .x86_win,
4608 .x86_mingw,
4414 .x86_thiscall_mingw,4609 .x86_thiscall_mingw,
4415 .x86_64_x32,4610 .x86_64_x32,
4416 .aarch64_aapcs,4611 .aarch64_aapcs,
...@@ -4585,47 +4780,6 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.lang.AddressSpace, target:...@@ -4585,47 +4780,6 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.lang.AddressSpace, target:
4585 };4780 };
4586}4781}
45874782
4588/// This function returns true if we expect LLVM to lower f16 correctly
4589/// and false if we expect LLVM to crash if it encounters an f16 type,
4590/// or if it produces miscompilations.
4591pub fn backendSupportsF16(target: *const std.Target) bool {
4592 return switch (target.cpu.arch) {
4593 .arm,
4594 .armeb,
4595 .thumb,
4596 .thumbeb,
4597 => target.abi.float() == .soft or target.cpu.has(.arm, .fullfp16),
4598 else => true,
4599 };
4600}
4601
4602/// This function returns true if we expect LLVM to lower x86_fp80 correctly
4603/// and false if we expect LLVM to crash if it encounters an x86_fp80 type,
4604/// or if it produces miscompilations.
4605pub fn backendSupportsF80(target: *const std.Target) bool {
4606 return switch (target.cpu.arch) {
4607 .x86, .x86_64 => !target.cpu.has(.x86, .soft_float),
4608 else => false,
4609 };
4610}
4611
4612/// This function returns true if we expect LLVM to lower f128 correctly,
4613/// and false if we expect LLVM to crash if it encounters an f128 type,
4614/// or if it produces miscompilations.
4615pub fn backendSupportsF128(target: *const std.Target) bool {
4616 return switch (target.cpu.arch) {
4617 // https://github.com/llvm/llvm-project/issues/121122
4618 .amdgcn,
4619 => false,
4620 .arm,
4621 .armeb,
4622 .thumb,
4623 .thumbeb,
4624 => target.abi.float() == .soft or target.cpu.has(.arm, .fp_armv8),
4625 else => true,
4626 };
4627}
4628
4629/// We need to insert extra padding if LLVM's isn't enough.4783/// We need to insert extra padding if LLVM's isn't enough.
4630/// However we don't want to ever call LLVMABIAlignmentOfType or4784/// However we don't want to ever call LLVMABIAlignmentOfType or
4631/// LLVMABISizeOfType because these functions will trip assertions4785/// LLVMABISizeOfType because these functions will trip assertions
src/codegen/llvm/FuncGen.zig+1509-1028
...@@ -164,12 +164,12 @@ fn resolveValue(self: *FuncGen, val: Value) Allocator.Error!Builder.Constant {...@@ -164,12 +164,12 @@ fn resolveValue(self: *FuncGen, val: Value) Allocator.Error!Builder.Constant {
164 const zcu = o.zcu;164 const zcu = o.zcu;
165 const ty = val.typeOf(zcu);165 const ty = val.typeOf(zcu);
166 if (!isByRef(ty, zcu)) {166 if (!isByRef(ty, zcu)) {
167 return o.lowerValue(val.toIntern(), .by_value);167 return o.lowerValue(val.toIntern(), .as_value);
168 } else {168 } else {
169 // We need a pointer to a global constant, i.e. a UAV.169 // We need a pointer to a global constant, i.e. a UAV.
170 return o.lowerUavRef(170 return o.lowerUavRef(
171 val.toIntern(),171 val.toIntern(),
172 ty.abiAlignment(zcu),172 ty.abiAlignment(zcu).toLlvm(),
173 target_util.defaultAddressSpace(zcu.getTarget(), .global_constant),173 target_util.defaultAddressSpace(zcu.getTarget(), .global_constant),
174 );174 );
175 }175 }
...@@ -190,10 +190,10 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {...@@ -190,10 +190,10 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {
190 const fn_info = zcu.typeToFunc(fn_ty).?;190 const fn_info = zcu.typeToFunc(fn_ty).?;
191 const param_types = fn_info.param_types.get(ip);191 const param_types = fn_info.param_types.get(ip);
192192
193 var it = iterateParamTypes(o, fn_info);193 var it = iterateParamTypes(o, fn_info.cc, fn_info.param_types.get(ip));
194194
195 // Populate `fg.ret_ptr`...195 // Populate `fg.ret_ptr`...
196 fg.ret_ptr = switch (try fnReturnStrat(o, fn_info)) {196 fg.ret_ptr = switch (try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type))) {
197 .sret => rp: {197 .sret => rp: {
198 defer it.llvm_index += 1;198 defer it.llvm_index += 1;
199 break :rp fg.wip.arg(it.llvm_index);199 break :rp fg.wip.arg(it.llvm_index);
...@@ -218,7 +218,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {...@@ -218,7 +218,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {
218 switch (lowering) {218 switch (lowering) {
219 .no_bits => continue,219 .no_bits => continue,
220 .byval => {220 .byval => {
221 assert(!it.byval_attr);221 assert(it.byval_attr == null);
222 const param_index = it.zig_index - 1;222 const param_index = it.zig_index - 1;
223 const param_ty: Type = .fromInterned(param_types[param_index]);223 const param_ty: Type = .fromInterned(param_types[param_index]);
224 const param = fg.wip.arg(it.llvm_index - 1);224 const param = fg.wip.arg(it.llvm_index - 1);
...@@ -237,15 +237,16 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {...@@ -237,15 +237,16 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {
237 .byref, .byref_mut => {237 .byref, .byref_mut => {
238 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);238 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);
239 const param = fg.wip.arg(it.llvm_index - 1);239 const param = fg.wip.arg(it.llvm_index - 1);
240 const alignment = if (it.byval_attr) |byval_attr| byval_attr.alignment else .none;
240241
241 if (isByRef(param_ty, zcu)) {242 if (alignment == .none and isByRef(param_ty, zcu)) {
242 args.appendAssumeCapacity(param);243 args.appendAssumeCapacity(param);
243 } else {244 } else {
244 args.appendAssumeCapacity(try fg.load(param, .none, param_ty, .normal));245 args.appendAssumeCapacity(try fg.load(param, alignment, param_ty, .normal));
245 }246 }
246 },247 },
247 .abi_sized_int => {248 .abi_sized_int => {
248 assert(!it.byval_attr);249 assert(it.byval_attr == null);
249 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);250 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);
250 const param = fg.wip.arg(it.llvm_index - 1);251 const param = fg.wip.arg(it.llvm_index - 1);
251252
...@@ -260,18 +261,18 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {...@@ -260,18 +261,18 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {
260 }261 }
261 },262 },
262 .slice => {263 .slice => {
263 assert(!it.byval_attr);264 assert(it.byval_attr == null);
264 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);265 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);
265 assert(!isByRef(param_ty, zcu));266 assert(!isByRef(param_ty, zcu));
266 const slice_val = try fg.wip.buildAggregate(267 const slice_val = try fg.wip.buildAggregate(
267 try o.lowerType(param_ty, .by_value),268 try o.lowerType(param_ty, .as_value),
268 &.{ fg.wip.arg(it.llvm_index - 2), fg.wip.arg(it.llvm_index - 1) },269 &.{ fg.wip.arg(it.llvm_index - 2), fg.wip.arg(it.llvm_index - 1) },
269 "",270 "",
270 );271 );
271 args.appendAssumeCapacity(slice_val);272 args.appendAssumeCapacity(slice_val);
272 },273 },
273 .multiple_llvm_types => {274 .multiple_llvm_types => {
274 assert(!it.byval_attr);275 assert(it.byval_attr == null);
275 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);276 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);
276 const param_alignment = param_ty.abiAlignment(zcu);277 const param_alignment = param_ty.abiAlignment(zcu);
277 const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8);278 const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8);
...@@ -721,29 +722,19 @@ fn genBodyDebugScope(...@@ -721,29 +722,19 @@ fn genBodyDebugScope(
721 try self.genBody(body, coverage_point);722 try self.genBody(body, coverage_point);
722}723}
723724
724const CallAttr = enum {725fn airCall(fg: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier) Allocator.Error!Builder.Value {
725 Auto,726 const o = fg.object;
726 NeverTail,
727 NeverInline,
728 AlwaysTail,
729 AlwaysInline,
730};
731
732fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier) Allocator.Error!Builder.Value {
733 const air_call = self.air.unwrapCall(inst);
734 const args = air_call.args;
735 const o = self.object;
736 const pt = self.pt;
737 const zcu = o.zcu;727 const zcu = o.zcu;
728 const air_call = fg.air.unwrapCall(inst);
729 const args = air_call.args;
738 const ip = &zcu.intern_pool;730 const ip = &zcu.intern_pool;
739 const callee_ty = self.typeOf(air_call.callee);731 const callee_ty = fg.typeOf(air_call.callee);
740 const zig_fn_ty = switch (callee_ty.zigTypeTag(zcu)) {732 const zig_fn_ty = switch (callee_ty.zigTypeTag(zcu)) {
741 .@"fn" => callee_ty,733 .@"fn" => callee_ty,
742 .pointer => callee_ty.childType(zcu),734 .pointer => callee_ty.childType(zcu),
743 else => unreachable,735 else => unreachable,
744 };736 };
745 const fn_info = zcu.typeToFunc(zig_fn_ty).?;737 const fn_info = zcu.typeToFunc(zig_fn_ty).?;
746 const return_type: Type = .fromInterned(fn_info.return_type);
747 const llvm_fn = llvm_fn: {738 const llvm_fn = llvm_fn: {
748 // If the callee is a function *body*, we need to use a pointer to the global.739 // If the callee is a function *body*, we need to use a pointer to the global.
749 if (air_call.callee.toInterned()) |ip_index| switch (ip.indexToKey(ip_index)) {740 if (air_call.callee.toInterned()) |ip_index| switch (ip.indexToKey(ip_index)) {
...@@ -752,22 +743,54 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier...@@ -752,22 +743,54 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier
752 else => {},743 else => {},
753 };744 };
754 // Otherwise, the operand is already a function pointer (possibly runtime-known).745 // Otherwise, the operand is already a function pointer (possibly runtime-known).
755 break :llvm_fn try self.resolveInst(air_call.callee);746 break :llvm_fn try fg.resolveInst(air_call.callee);
756 };747 };
748
749 const arg_types = try fg.gpa.alloc(InternPool.Index, args.len);
750 defer fg.gpa.free(arg_types);
751 const arg_values = try fg.gpa.alloc(Builder.Value, args.len);
752 defer fg.gpa.free(arg_values);
753 for (arg_types, arg_values, args) |*arg_type, *arg_value, arg| {
754 const arg_ty = fg.typeOf(arg);
755 arg_type.* = arg_ty.toIntern();
756 arg_value.* = if (arg_ty.hasRuntimeBits(zcu)) try fg.resolveInst(arg) else .none;
757 }
758 return fg.buildCall(.{
759 .is_unused = fg.liveness.isUnused(inst),
760 .modifier = modifier,
761 }, try o.lowerType(zig_fn_ty, .as_value), llvm_fn, .fromIntern(fn_info, ip), arg_types, arg_values);
762}
763
764fn buildCall(
765 fg: *FuncGen,
766 opts: struct {
767 is_unused: bool = false,
768 modifier: std.lang.CallModifier = .auto,
769 },
770 llvm_fn_ty: Builder.Type,
771 llvm_fn: Builder.Value,
772 fn_info: Object.FuncInfo,
773 arg_types: []const InternPool.Index,
774 arg_values: []const Builder.Value,
775) Allocator.Error!Builder.Value {
776 const o = fg.object;
777 const pt = fg.pt;
778 const zcu = o.zcu;
779 const return_type: Type = .fromInterned(fn_info.return_type);
757 const target = zcu.getTarget();780 const target = zcu.getTarget();
758 const ret_strat = try fnReturnStrat(o, fn_info);781 const ret_strat = try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type));
759782
760 var llvm_args = std.array_list.Managed(Builder.Value).init(self.gpa);783 var llvm_args: std.ArrayList(Builder.Value) = .empty;
761 defer llvm_args.deinit();784 defer llvm_args.deinit(fg.gpa);
762785
763 var attributes: Builder.FunctionAttributes.Wip = .{};786 var attributes: Builder.FunctionAttributes.Wip = .{};
764 defer attributes.deinit(&o.builder);787 defer attributes.deinit(&o.builder);
765788
766 if (self.disable_intrinsics) {789 if (fg.disable_intrinsics) {
767 try attributes.addFnAttr(.nobuiltin, &o.builder);790 try attributes.addFnAttr(.nobuiltin, &o.builder);
768 }791 }
769792
770 switch (modifier) {793 switch (opts.modifier) {
771 .auto, .always_tail => {},794 .auto, .always_tail => {},
772 .never_tail, .never_inline => try attributes.addFnAttr(.@"noinline", &o.builder),795 .never_tail, .never_inline => try attributes.addFnAttr(.@"noinline", &o.builder),
773 .no_suspend, .always_inline, .compile_time => unreachable,796 .no_suspend, .always_inline, .compile_time => unreachable,
...@@ -775,10 +798,11 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier...@@ -775,10 +798,11 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier
775798
776 const sret_alloc: ?Builder.Value = switch (ret_strat) {799 const sret_alloc: ?Builder.Value = switch (ret_strat) {
777 .sret => sret_alloc: {800 .sret => sret_alloc: {
778 try attributes.addParamAttr(0, .{ .sret = try o.lowerType(return_type, .in_memory) }, &o.builder);801 const alignment = return_type.abiAlignment(zcu).toLlvm();
802 try o.addSRetFnAttributes(&attributes, try o.lowerType(return_type, .in_memory), alignment, .callsite);
779803
780 const ptr = try self.buildZigAlloca(return_type, .none);804 const ptr = try fg.buildZigAlloca(return_type, .none);
781 try llvm_args.append(ptr);805 try llvm_args.append(fg.gpa, ptr);
782 break :sret_alloc ptr;806 break :sret_alloc ptr;
783 },807 },
784 else => sret_alloc: {808 else => sret_alloc: {
...@@ -792,132 +816,111 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier...@@ -792,132 +816,111 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier
792816
793 const err_return_tracing = fn_info.cc == .auto and zcu.comp.config.any_error_tracing;817 const err_return_tracing = fn_info.cc == .auto and zcu.comp.config.any_error_tracing;
794 if (err_return_tracing) {818 if (err_return_tracing) {
795 assert(self.err_ret_trace != .none);819 assert(fg.err_ret_trace != .none);
796 try llvm_args.append(self.err_ret_trace);820 try llvm_args.append(fg.gpa, fg.err_ret_trace);
797 }821 }
798
799 var it = iterateParamTypes(o, fn_info);
800 while (try it.nextCall(self, args)) |lowering| switch (lowering) {
801 .no_bits => continue,
802 .byval => {
803 const arg = args[it.zig_index - 1];
804 const param_ty = self.typeOf(arg);
805 const llvm_arg = try self.resolveInst(arg);
806 if (isByRef(param_ty, zcu)) {
807 const alignment = param_ty.abiAlignment(zcu).toLlvm();
808 // We don't need to handle non-ABI-sized integer types in memory here since they are
809 // never by-ref.
810 const llvm_param_ty = try o.lowerType(param_ty, .in_memory);
811 const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, "");
812 try llvm_args.append(loaded);
813 } else {
814 try llvm_args.append(llvm_arg);
815 }
816 },
817 .byref => {
818 const arg = args[it.zig_index - 1];
819 const param_ty = self.typeOf(arg);
820 const llvm_arg = try self.resolveInst(arg);
821 if (isByRef(param_ty, zcu)) {
822 try llvm_args.append(llvm_arg);
823 } else {
824 const arg_ptr = try self.buildZigAlloca(param_ty, .none);
825 try self.store(arg_ptr, .none, llvm_arg, param_ty, .normal);
826 try llvm_args.append(arg_ptr);
827 }
828 },
829 .byref_mut => {
830 const arg = args[it.zig_index - 1];
831 const param_ty = self.typeOf(arg);
832 const llvm_arg = try self.resolveInst(arg);
833
834 const arg_ptr = try self.buildZigAlloca(param_ty, .none);
835 try self.store(arg_ptr, .none, llvm_arg, param_ty, .normal);
836 try llvm_args.append(arg_ptr);
837 },
838 .abi_sized_int => {
839 const arg = args[it.zig_index - 1];
840 const param_ty = self.typeOf(arg);
841 const llvm_arg = try self.resolveInst(arg);
842 const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(zcu) * 8));
843
844 if (isByRef(param_ty, zcu)) {
845 const alignment = param_ty.abiAlignment(zcu).toLlvm();
846 const loaded = try self.wip.load(.normal, int_llvm_ty, llvm_arg, alignment, "");
847 try llvm_args.append(loaded);
848 } else {
849 // LLVM does not allow bitcasting structs so we must allocate
850 // a local, store as one type, and then load as another type.
851 const alignment = param_ty.abiAlignment(zcu).toLlvm();
852 const ptr = try self.buildAlloca(int_llvm_ty, alignment);
853 try self.store(ptr, .none, llvm_arg, param_ty, .normal);
854 const loaded = try self.wip.load(.normal, int_llvm_ty, ptr, alignment, "");
855 try llvm_args.append(loaded);
856 }
857 },
858 .slice => {
859 const arg = args[it.zig_index - 1];
860 const llvm_arg = try self.resolveInst(arg);
861 const ptr = try self.wip.extractValue(llvm_arg, &.{0}, "");
862 const len = try self.wip.extractValue(llvm_arg, &.{1}, "");
863 try llvm_args.appendSlice(&.{ ptr, len });
864 },
865 .multiple_llvm_types => {
866 const arg = args[it.zig_index - 1];
867 const param_ty = self.typeOf(arg);
868 const llvm_arg = try self.resolveInst(arg);
869 const param_alignment = param_ty.abiAlignment(zcu);
870 const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8);
871 const arg_ptr = try self.buildAlloca(llvm_ty, param_alignment.toLlvm());
872 try self.store(arg_ptr, .none, llvm_arg, param_ty, .normal);
873
874 try llvm_args.ensureUnusedCapacity(it.types_len);
875 for (it.types_buffer[0..it.types_len], it.offsets_buffer[0..it.types_len]) |field_ty, offset| {
876 const field_ptr = try self.ptraddConst(arg_ptr, offset);
877 const loaded = try self.wip.load(.normal, field_ty, field_ptr, param_alignment.offset(offset).toLlvm(), "");
878 llvm_args.appendAssumeCapacity(loaded);
879 }
880 },
881 .float_array => |count| {
882 const arg = args[it.zig_index - 1];
883 const arg_ty = self.typeOf(arg);
884 const arg_val = try self.resolveInst(arg);
885
886 const arg_ptr: Builder.Value = if (!isByRef(arg_ty, zcu)) ptr: {
887 const ptr = try self.buildZigAlloca(arg_ty, .none);
888 try self.store(ptr, .none, arg_val, arg_ty, .normal);
889 break :ptr ptr;
890 } else arg_val;
891
892 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, zcu).?, .in_memory);
893 const array_ty = try o.builder.arrayType(count, float_ty);
894822
895 const loaded = try self.wip.load(.normal, array_ty, arg_ptr, arg_ty.abiAlignment(zcu).toLlvm(), "");823 var it = iterateParamTypes(o, fn_info.cc, fn_info.param_types);
896 try llvm_args.append(loaded);824 while (try it.nextCall(arg_types)) |lowering| {
897 },825 const arg_ty: Type = .fromInterned(arg_types[it.zig_index - 1]);
898 .i32_array, .i64_array => |arr_len| {826 const arg_val = arg_values[it.zig_index - 1];
899 const elem_size: u8 = if (lowering == .i32_array) 32 else 64;827 switch (lowering) {
900 const arg = args[it.zig_index - 1];828 .no_bits => continue,
901 const arg_ty = self.typeOf(arg);829 .byval => {
902 const arg_val = try self.resolveInst(arg);830 if (isByRef(arg_ty, zcu)) {
903831 const alignment = arg_ty.abiAlignment(zcu).toLlvm();
904 const arg_ptr: Builder.Value = if (!isByRef(arg_ty, zcu)) ptr: {832 // We don't need to handle non-ABI-sized integer types in memory here since they are
905 const ptr = try self.buildZigAlloca(arg_ty, .none);833 // never by-ref.
906 try self.store(ptr, .none, arg_val, arg_ty, .normal);834 const llvm_arg_ty = try o.lowerType(arg_ty, .memory_access);
907 break :ptr ptr;835 const loaded = try fg.wip.load(.normal, llvm_arg_ty, arg_val, alignment, "");
908 } else arg_val;836 try llvm_args.append(fg.gpa, loaded);
837 } else {
838 try llvm_args.append(fg.gpa, arg_val);
839 }
840 },
841 .byref => {
842 if (isByRef(arg_ty, zcu)) {
843 try llvm_args.append(fg.gpa, arg_val);
844 } else {
845 const arg_ptr = try fg.buildZigAlloca(arg_ty, .none);
846 try fg.store(arg_ptr, .none, arg_val, arg_ty, .normal);
847 try llvm_args.append(fg.gpa, arg_ptr);
848 }
849 },
850 .byref_mut => {
851 const arg_ptr = try fg.buildZigAlloca(arg_ty, .none);
852 try fg.store(arg_ptr, .none, arg_val, arg_ty, .normal);
853 try llvm_args.append(fg.gpa, arg_ptr);
854 },
855 .abi_sized_int => {
856 const int_llvm_ty = try o.builder.intType(@intCast(arg_ty.abiSize(zcu) * 8));
909857
910 const array_ty = try o.builder.arrayType(arr_len, try o.builder.intType(@intCast(elem_size)));858 if (isByRef(arg_ty, zcu)) {
911 const loaded = try self.wip.load(.normal, array_ty, arg_ptr, arg_ty.abiAlignment(zcu).toLlvm(), "");859 const alignment = arg_ty.abiAlignment(zcu).toLlvm();
912 try llvm_args.append(loaded);860 const loaded = try fg.wip.load(.normal, int_llvm_ty, arg_val, alignment, "");
913 },861 try llvm_args.append(fg.gpa, loaded);
914 };862 } else {
863 // LLVM does not allow bitcasting structs so we must allocate
864 // a local, store as one type, and then load as another type.
865 const alignment = arg_ty.abiAlignment(zcu).toLlvm();
866 const ptr = try fg.buildAlloca(int_llvm_ty, alignment);
867 try fg.store(ptr, .none, arg_val, arg_ty, .normal);
868 const loaded = try fg.wip.load(.normal, int_llvm_ty, ptr, alignment, "");
869 try llvm_args.append(fg.gpa, loaded);
870 }
871 },
872 .slice => {
873 const ptr = try fg.wip.extractValue(arg_val, &.{0}, "");
874 const len = try fg.wip.extractValue(arg_val, &.{1}, "");
875 try llvm_args.appendSlice(fg.gpa, &.{ ptr, len });
876 },
877 .multiple_llvm_types => {
878 const arg_alignment = arg_ty.abiAlignment(zcu);
879 const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8);
880 const arg_ptr = try fg.buildAlloca(llvm_ty, arg_alignment.toLlvm());
881 try fg.store(arg_ptr, .none, arg_val, arg_ty, .normal);
882
883 try llvm_args.ensureUnusedCapacity(fg.gpa, it.types_len);
884 for (it.types_buffer[0..it.types_len], it.offsets_buffer[0..it.types_len]) |field_ty, offset| {
885 const field_ptr = try fg.ptraddConst(arg_ptr, offset);
886 const loaded = try fg.wip.load(.normal, field_ty, field_ptr, arg_alignment.offset(offset).toLlvm(), "");
887 llvm_args.appendAssumeCapacity(loaded);
888 }
889 },
890 .float_array => |count| {
891 const arg_ptr: Builder.Value = if (!isByRef(arg_ty, zcu)) ptr: {
892 const ptr = try fg.buildZigAlloca(arg_ty, .none);
893 try fg.store(ptr, .none, arg_val, arg_ty, .normal);
894 break :ptr ptr;
895 } else arg_val;
896
897 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, zcu).?, .memory_access);
898 const array_ty = try o.builder.arrayType(count, float_ty);
899
900 const loaded = try fg.wip.load(.normal, array_ty, arg_ptr, arg_ty.abiAlignment(zcu).toLlvm(), "");
901 try llvm_args.append(fg.gpa, loaded);
902 },
903 .i32_array, .i64_array => |arr_len| {
904 const elem_size: u8 = if (lowering == .i32_array) 32 else 64;
905
906 const arg_ptr: Builder.Value = if (!isByRef(arg_ty, zcu)) ptr: {
907 const ptr = try fg.buildZigAlloca(arg_ty, .none);
908 try fg.store(ptr, .none, arg_val, arg_ty, .normal);
909 break :ptr ptr;
910 } else arg_val;
911
912 const array_ty = try o.builder.arrayType(arr_len, try o.builder.intType(@intCast(elem_size)));
913 const loaded = try fg.wip.load(.normal, array_ty, arg_ptr, arg_ty.abiAlignment(zcu).toLlvm(), "");
914 try llvm_args.append(fg.gpa, loaded);
915 },
916 }
917 }
915918
916 const cc_info = llvm.toLlvmCallConv(fn_info.cc, target).?;919 const cc_info = llvm.toLlvmCallConv(fn_info.cc, target).?;
917920
918 {921 {
919 // Add argument attributes.922 // Add argument attributes.
920 it = iterateParamTypes(o, fn_info);923 it = iterateParamTypes(o, fn_info.cc, fn_info.param_types);
921 it.llvm_index += @intFromBool(ret_strat == .sret);924 it.llvm_index += @intFromBool(ret_strat == .sret);
922 it.llvm_index += @intFromBool(err_return_tracing);925 it.llvm_index += @intFromBool(err_return_tracing);
923 var remaining_inreg_int = cc_info.inreg_int_params;926 var remaining_inreg_int = cc_info.inreg_int_params;
...@@ -925,7 +928,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier...@@ -925,7 +928,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier
925 while (try it.next()) |lowering| switch (lowering) {928 while (try it.next()) |lowering| switch (lowering) {
926 .byval => {929 .byval => {
927 const param_index = it.zig_index - 1;930 const param_index = it.zig_index - 1;
928 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);931 const param_ty = Type.fromInterned(fn_info.param_types[param_index]);
929 if (!isByRef(param_ty, zcu)) {932 if (!isByRef(param_ty, zcu)) {
930 try o.addByValParamAttrs(pt, &attributes, param_ty, param_index, fn_info, it.llvm_index - 1);933 try o.addByValParamAttrs(pt, &attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
931 }934 }
...@@ -947,7 +950,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier...@@ -947,7 +950,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier
947 },950 },
948 .byref => {951 .byref => {
949 const param_index = it.zig_index - 1;952 const param_index = it.zig_index - 1;
950 const param_ty: Type = .fromInterned(fn_info.param_types.get(ip)[param_index]);953 const param_ty: Type = .fromInterned(fn_info.param_types[param_index]);
951 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, it.byval_attr, param_ty);954 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, it.byval_attr, param_ty);
952 },955 },
953 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),956 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
...@@ -961,8 +964,8 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier...@@ -961,8 +964,8 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier
961 => continue,964 => continue,
962965
963 .slice => {966 .slice => {
964 assert(!it.byval_attr);967 assert(it.byval_attr == null);
965 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);968 const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]);
966 const ptr_info = param_ty.ptrInfo(zcu);969 const ptr_info = param_ty.ptrInfo(zcu);
967 const llvm_arg_i = it.llvm_index - 2;970 const llvm_arg_i = it.llvm_index - 2;
968971
...@@ -989,8 +992,8 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier...@@ -989,8 +992,8 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier
989 };992 };
990 }993 }
991994
992 const call = try self.wip.call(995 const call = try fg.wip.call(
993 switch (modifier) {996 switch (opts.modifier) {
994 .auto, .never_inline => .normal,997 .auto, .never_inline => .normal,
995 .never_tail => .notail,998 .never_tail => .notail,
996 .always_tail => .musttail,999 .always_tail => .musttail,
...@@ -998,19 +1001,14 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier...@@ -998,19 +1001,14 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier
998 },1001 },
999 cc_info.llvm_cc,1002 cc_info.llvm_cc,
1000 try attributes.finish(&o.builder),1003 try attributes.finish(&o.builder),
1001 try o.lowerType(zig_fn_ty, .by_value),1004 llvm_fn_ty,
1002 llvm_fn,1005 llvm_fn,
1003 llvm_args.items,1006 llvm_args.items,
1004 "",1007 "",
1005 );1008 );
10061009
1007 if (fn_info.return_type == .noreturn_type and modifier != .always_tail) {1010 if (opts.is_unused) return .none;
1008 return .none;1011 if (fn_info.return_type == .noreturn_type and opts.modifier != .always_tail) return .none;
1009 }
1010
1011 if (self.liveness.isUnused(inst)) {
1012 return .none;
1013 }
10141012
1015 // We exit this `switch` if we have a pointer to the return value.1013 // We exit this `switch` if we have a pointer to the return value.
1016 const ret_val_ptr: Builder.Value = switch (ret_strat) {1014 const ret_val_ptr: Builder.Value = switch (ret_strat) {
...@@ -1020,15 +1018,15 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier...@@ -1020,15 +1018,15 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier
1020 .sret => sret_alloc.?,1018 .sret => sret_alloc.?,
1021 .mem_cast => |llvm_ret_ty| ret_val_ptr: {1019 .mem_cast => |llvm_ret_ty| ret_val_ptr: {
1022 const alignment = return_type.abiAlignment(zcu).toLlvm();1020 const alignment = return_type.abiAlignment(zcu).toLlvm();
1023 const ptr = try self.buildAlloca(llvm_ret_ty, alignment);1021 const ptr = try fg.buildAlloca(llvm_ret_ty, alignment);
1024 _ = try self.wip.store(.normal, call, ptr, alignment);1022 _ = try fg.wip.store(.normal, call, ptr, alignment);
1025 break :ret_val_ptr ptr;1023 break :ret_val_ptr ptr;
1026 },1024 },
1027 };1025 };
1028 if (isByRef(return_type, zcu)) {1026 if (isByRef(return_type, zcu)) {
1029 return ret_val_ptr;1027 return ret_val_ptr;
1030 } else {1028 } else {
1031 return self.load(ret_val_ptr, .none, return_type, .normal);1029 return fg.load(ret_val_ptr, .none, return_type, .normal);
1032 }1030 }
1033}1031}
10341032
...@@ -1038,7 +1036,7 @@ fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) Allocator.Error!v...@@ -1038,7 +1036,7 @@ fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) Allocator.Error!v
1038 const target = zcu.getTarget();1036 const target = zcu.getTarget();
1039 const panic_func = zcu.funcInfo(zcu.std_lang_decl_values.get(panic_id.toStdLangDecl()));1037 const panic_func = zcu.funcInfo(zcu.std_lang_decl_values.get(panic_id.toStdLangDecl()));
1040 const fn_info = zcu.typeToFunc(.fromInterned(panic_func.ty)).?;1038 const fn_info = zcu.typeToFunc(.fromInterned(panic_func.ty)).?;
1041 const llvm_panic_fn_ty = try o.lowerType(.fromInterned(panic_func.ty), .by_value);1039 const llvm_panic_fn_ty = try o.lowerType(.fromInterned(panic_func.ty), .as_value);
10421040
1043 const llvm_panic_fn_ref = try o.lowerNavRef(panic_func.owner_nav);1041 const llvm_panic_fn_ref = try o.lowerNavRef(panic_func.owner_nav);
10441042
...@@ -1067,7 +1065,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!vo...@@ -1067,7 +1065,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!vo
10671065
1068 const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.nav_index).resolved.?.type)).?;1066 const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.nav_index).resolved.?.type)).?;
10691067
1070 const ret_strat = try fnReturnStrat(o, fn_info);1068 const ret_strat = try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type));
1071 const val_is_undef = if (un_op.toInterned()) |i| Value.fromInterned(i).isUndef(zcu) else false;1069 const val_is_undef = if (un_op.toInterned()) |i| Value.fromInterned(i).isUndef(zcu) else false;
1072 const ret_ty_align = ret_ty.abiAlignment(zcu);1070 const ret_ty_align = ret_ty.abiAlignment(zcu);
10731071
...@@ -1076,7 +1074,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!vo...@@ -1076,7 +1074,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!vo
1076 .none => try self.buildZigAlloca(ret_ty, .none),1074 .none => try self.buildZigAlloca(ret_ty, .none),
1077 else => |rp| rp,1075 else => |rp| rp,
1078 };1076 };
1079 const len = try o.builder.intValue(try o.lowerType(.usize, .by_value), ret_ty.abiSize(zcu));1077 const len = try o.builder.intValue(try o.lowerType(.usize, .as_value), ret_ty.abiSize(zcu));
1080 _ = try self.wip.callMemSet(1078 _ = try self.wip.callMemSet(
1081 rp,1079 rp,
1082 ret_ty_align.toLlvm(),1080 ret_ty_align.toLlvm(),
...@@ -1141,7 +1139,7 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void {...@@ -1141,7 +1139,7 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void {
1141 const ret_ty = ptr_ty.childType(zcu);1139 const ret_ty = ptr_ty.childType(zcu);
1142 const fn_info = zcu.typeToFunc(.fromInterned(ip.getNav(self.nav_index).resolved.?.type)).?;1140 const fn_info = zcu.typeToFunc(.fromInterned(ip.getNav(self.nav_index).resolved.?.type)).?;
1143 const ptr = try self.resolveInst(un_op);1141 const ptr = try self.resolveInst(un_op);
1144 switch (try fnReturnStrat(o, fn_info)) {1142 switch (try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type))) {
1145 .void => _ = try self.wip.retVoid(),1143 .void => _ = try self.wip.retVoid(),
1146 .sret => {1144 .sret => {
1147 assert(self.ret_ptr != .none);1145 assert(self.ret_ptr != .none);
...@@ -1165,7 +1163,7 @@ fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -1165,7 +1163,7 @@ fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
1165 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;1163 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;
1166 const list = try self.resolveInst(ty_op.operand);1164 const list = try self.resolveInst(ty_op.operand);
1167 const arg_ty = ty_op.ty.toType();1165 const arg_ty = ty_op.ty.toType();
1168 const llvm_arg_ty = try self.object.lowerType(arg_ty, .by_value);1166 const llvm_arg_ty = try self.object.lowerType(arg_ty, .as_value);
11691167
1170 return self.wip.vaArg(list, llvm_arg_ty, "");1168 return self.wip.vaArg(list, llvm_arg_ty, "");
1171}1169}
...@@ -1378,7 +1376,7 @@ fn lowerBlock(...@@ -1378,7 +1376,7 @@ fn lowerBlock(
1378 if (have_block_result) {1376 if (have_block_result) {
1379 const llvm_ty: Builder.Type = switch (isByRef(inst_ty, zcu)) {1377 const llvm_ty: Builder.Type = switch (isByRef(inst_ty, zcu)) {
1380 true => .ptr,1378 true => .ptr,
1381 false => try o.lowerType(inst_ty, .by_value),1379 false => try o.lowerType(inst_ty, .as_value),
1382 };1380 };
1383 parent_bb.ptr(&self.wip).incoming = @intCast(breaks.list.len);1381 parent_bb.ptr(&self.wip).incoming = @intCast(breaks.list.len);
1384 const phi = try self.wip.phi(llvm_ty, "");1382 const phi = try self.wip.phi(llvm_ty, "");
...@@ -1485,7 +1483,7 @@ fn lowerSwitchDispatch(...@@ -1485,7 +1483,7 @@ fn lowerSwitchDispatch(
1485 const table_index = try self.wip.conv(1483 const table_index = try self.wip.conv(
1486 .unsigned,1484 .unsigned,
1487 try self.wip.bin(.@"sub nuw", cond, jmp_table.min.toValue(), ""),1485 try self.wip.bin(.@"sub nuw", cond, jmp_table.min.toValue(), ""),
1488 try o.lowerType(.usize, .by_value),1486 try o.lowerType(.usize, .as_value),
1489 "",1487 "",
1490 );1488 );
1491 const target_ptr_ptr = try self.ptraddScaled(1489 const target_ptr_ptr = try self.ptraddScaled(
...@@ -1510,7 +1508,7 @@ fn lowerSwitchDispatch(...@@ -1510,7 +1508,7 @@ fn lowerSwitchDispatch(
1510 // The switch prongs will correspond to our scalar cases. Ranges will1508 // The switch prongs will correspond to our scalar cases. Ranges will
1511 // be handled by conditional branches in the `else` prong.1509 // be handled by conditional branches in the `else` prong.
15121510
1513 const llvm_usize = try o.lowerType(.usize, .by_value);1511 const llvm_usize = try o.lowerType(.usize, .as_value);
1514 const cond_int = if (cond_ty.zigTypeTag(zcu) == .pointer)1512 const cond_int = if (cond_ty.zigTypeTag(zcu) == .pointer)
1515 try self.wip.cast(.ptrtoint, cond, llvm_usize, "")1513 try self.wip.cast(.ptrtoint, cond, llvm_usize, "")
1516 else1514 else
...@@ -1725,7 +1723,7 @@ fn lowerTry(...@@ -1725,7 +1723,7 @@ fn lowerTry(
1725 if (err_union_ty.isVolatilePtr(zcu)) .@"volatile" else .normal,1723 if (err_union_ty.isVolatilePtr(zcu)) .@"volatile" else .normal,
1726 );1724 );
1727 };1725 };
1728 const zero = try o.builder.intValue(try o.errorIntType(.by_value), 0);1726 const zero = try o.builder.intValue(try o.errorIntType(.as_value), 0);
1729 const is_err = try fg.wip.icmp(.ne, loaded, zero, "");1727 const is_err = try fg.wip.icmp(.ne, loaded, zero, "");
17301728
1731 const return_block = try fg.wip.block(1, "TryRet");1729 const return_block = try fg.wip.block(1, "TryRet");
...@@ -1862,8 +1860,8 @@ fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Tod...@@ -1862,8 +1860,8 @@ fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Tod
1862 const table_includes_else = item_count != table_len;1860 const table_includes_else = item_count != table_len;
18631861
1864 break :jmp_table .{1862 break :jmp_table .{
1865 .min = try o.lowerValue(min.toIntern(), .by_value),1863 .min = try o.lowerValue(min.toIntern(), .as_value),
1866 .max = try o.lowerValue(max.toIntern(), .by_value),1864 .max = try o.lowerValue(max.toIntern(), .as_value),
1867 .in_bounds_hint = if (table_includes_else) .none else switch (switch_br.getElseHint()) {1865 .in_bounds_hint = if (table_includes_else) .none else switch (switch_br.getElseHint()) {
1868 .none, .cold => .none,1866 .none, .cold => .none,
1869 .unpredictable => .unpredictable,1867 .unpredictable => .unpredictable,
...@@ -2021,142 +2019,102 @@ fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder...@@ -2021,142 +2019,102 @@ fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder
2021 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;2019 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;
2022 const operand_ty = self.typeOf(ty_op.operand);2020 const operand_ty = self.typeOf(ty_op.operand);
2023 const array_ty = operand_ty.childType(zcu);2021 const array_ty = operand_ty.childType(zcu);
2024 const llvm_usize = try o.lowerType(.usize, .by_value);2022 const llvm_usize = try o.lowerType(.usize, .as_value);
2025 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu));2023 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu));
2026 const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst), .by_value);2024 const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst), .as_value);
2027 const operand = try self.resolveInst(ty_op.operand);2025 const operand = try self.resolveInst(ty_op.operand);
2028 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");2026 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");
2029}2027}
20302028
2031fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {2029fn airFloatFromInt(fg: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {
2032 const o = self.object;2030 const o = fg.object;
2033 const zcu = o.zcu;2031 const zcu = o.zcu;
2034 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;2032 const ty_op = fg.air.instructions.items(.data)[@backingInt(inst)].ty_op;
20352033
2036 const operand = try self.resolveInst(ty_op.operand);2034 const operand = try fg.resolveInst(ty_op.operand);
2037 const operand_ty = self.typeOf(ty_op.operand);2035 const operand_ty = fg.typeOf(ty_op.operand);
2038 const operand_scalar_ty = operand_ty.scalarType(zcu);2036 const operand_scalar_ty = operand_ty.scalarType(zcu);
2039 const is_signed_int = operand_scalar_ty.isSignedInt(zcu);2037 const operand_scalar_info = operand_scalar_ty.intInfo(zcu);
20402038
2041 const dest_ty = self.typeOfIndex(inst);2039 const dest_ty = fg.typeOfIndex(inst);
2042 const dest_scalar_ty = dest_ty.scalarType(zcu);2040 const dest_scalar_ty = dest_ty.scalarType(zcu);
2043 const dest_llvm_ty = try o.lowerType(dest_ty, .by_value);
2044 const target = zcu.getTarget();2041 const target = zcu.getTarget();
20452042
2046 if (intrinsicsAllowed(dest_scalar_ty, target)) return self.wip.conv(2043 if (intrinsicsAllowed(.compiler_rt, dest_scalar_ty, target))
2047 if (is_signed_int) .signed else .unsigned,2044 return fg.wip.conv(.fromStdLang(operand_scalar_info.signedness), operand, try o.lowerType(dest_ty, .as_value), "");
2048 operand,
2049 dest_llvm_ty,
2050 "",
2051 );
20522045
2053 const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(zcu))) orelse {2046 const rt_int_ty = compilerRtPromoteInt(operand_scalar_info) orelse {
2054 return self.todo("float_from_int on {d} bit integer", .{operand_scalar_ty.bitSize(zcu)});2047 return fg.todo("float_from_int on {d} bit integer", .{operand_scalar_info.bits});
2055 };2048 };
2056 const rt_int_ty = try o.builder.intType(rt_int_bits);2049 const vector_len = if (operand_ty.isVector(zcu)) operand_ty.vectorLen(zcu) else null;
2057 var extended = try self.wip.conv(2050 const rt_llvm_int_ty = try o.lowerType(rt_int_ty, .as_value);
2058 if (is_signed_int) .signed else .unsigned,2051 const extended = try fg.wip.conv(
2052 .fromStdLang(operand_scalar_info.signedness),
2059 operand,2053 operand,
2060 rt_int_ty,2054 if (vector_len) |len|
2055 try o.builder.vectorType(.normal, len, rt_llvm_int_ty)
2056 else
2057 rt_llvm_int_ty,
2061 "",2058 "",
2062 );2059 );
2063 const dest_bits = dest_scalar_ty.floatBits(target);
2064 const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits);
2065 const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits);
2066 const sign_prefix = if (is_signed_int) "" else "un";
2067 const fn_name = try o.builder.strtabStringFmt("__float{s}{s}i{s}f", .{2060 const fn_name = try o.builder.strtabStringFmt("__float{s}{s}i{s}f", .{
2068 sign_prefix,2061 switch (operand_scalar_info.signedness) {
2069 compiler_rt_operand_abbrev,2062 .signed => "",
2070 compiler_rt_dest_abbrev,2063 .unsigned => "un",
2064 },
2065 compilerRtIntAbbrev(rt_int_ty.intInfo(zcu).bits),
2066 compilerRtFloatAbbrev(target, dest_scalar_ty.floatBits(target)),
2071 });2067 });
20722068 return fg.buildElementwiseCall(fn_name, .{
2073 var param_type = rt_int_ty;2069 .cc = target.cCallingConvention().?,
2074 if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) {2070 .param_types = &.{rt_int_ty.toIntern()},
2075 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard2071 .return_type = dest_scalar_ty.toIntern(),
2076 // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have.2072 }, &.{extended}, vector_len);
2077 param_type = try o.builder.vectorType(.normal, 2, .i64);
2078 extended = try self.wip.cast(.bitcast, extended, param_type, "");
2079 }
2080
2081 const libc_fn = try o.getLibcFunction(fn_name, &.{param_type}, dest_llvm_ty);
2082 return self.wip.call(
2083 .normal,
2084 .ccc,
2085 .none,
2086 libc_fn.typeOf(&o.builder),
2087 libc_fn.toValue(&o.builder),
2088 &.{extended},
2089 "",
2090 );
2091}2073}
20922074
2093fn airIntFromFloat(2075fn airIntFromFloat(
2094 self: *FuncGen,2076 fg: *FuncGen,
2095 inst: Air.Inst.Index,2077 inst: Air.Inst.Index,
2096 fast: Builder.FastMathKind,2078 fast: Builder.FastMathKind,
2097) TodoError!Builder.Value {2079) TodoError!Builder.Value {
2098 _ = fast;2080 _ = fast;
20992081
2100 const o = self.object;2082 const o = fg.object;
2101 const zcu = o.zcu;2083 const zcu = o.zcu;
2102 const target = zcu.getTarget();2084 const target = zcu.getTarget();
2103 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;2085 const ty_op = fg.air.instructions.items(.data)[@backingInt(inst)].ty_op;
21042086
2105 const operand = try self.resolveInst(ty_op.operand);2087 const operand = try fg.resolveInst(ty_op.operand);
2106 const operand_ty = self.typeOf(ty_op.operand);2088 const operand_ty = fg.typeOf(ty_op.operand);
2107 const operand_scalar_ty = operand_ty.scalarType(zcu);2089 const operand_scalar_ty = operand_ty.scalarType(zcu);
21082090
2109 const dest_ty = self.typeOfIndex(inst);2091 const dest_ty = fg.typeOfIndex(inst);
2110 const dest_scalar_ty = dest_ty.scalarType(zcu);2092 const dest_scalar_ty = dest_ty.scalarType(zcu);
2111 const dest_llvm_ty = try o.lowerType(dest_ty, .by_value);2093 const dest_llvm_ty = try o.lowerType(dest_ty, .as_value);
2094 const dest_scalar_info = dest_scalar_ty.intInfo(zcu);
21122095
2113 if (intrinsicsAllowed(operand_scalar_ty, target)) {2096 if (intrinsicsAllowed(.compiler_rt, operand_scalar_ty, target)) {
2114 // TODO set fast math flag2097 // TODO set fast math flag
2115 return self.wip.conv(2098 return fg.wip.conv(.fromStdLang(dest_scalar_info.signedness), operand, dest_llvm_ty, "");
2116 if (dest_scalar_ty.isSignedInt(zcu)) .signed else .unsigned,
2117 operand,
2118 dest_llvm_ty,
2119 "",
2120 );
2121 }2099 }
21222100
2123 const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(zcu))) orelse {2101 const rt_int_ty = compilerRtPromoteInt(dest_scalar_info) orelse {
2124 return self.todo("int_from_float to {d} bit integer", .{dest_scalar_ty.bitSize(zcu)});2102 return fg.todo("int_from_float to {d} bit integer", .{dest_scalar_info.bits});
2125 };2103 };
2126 const ret_ty = try o.builder.intType(rt_int_bits);
2127 const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: {
2128 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
2129 // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have.
2130 break :b try o.builder.vectorType(.normal, 2, .i64);
2131 } else ret_ty;
2132
2133 const operand_bits = operand_scalar_ty.floatBits(target);
2134 const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits);
2135
2136 const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);
2137 const sign_prefix = if (dest_scalar_ty.isSignedInt(zcu)) "" else "uns";
2138
2139 const fn_name = try o.builder.strtabStringFmt("__fix{s}{s}f{s}i", .{2104 const fn_name = try o.builder.strtabStringFmt("__fix{s}{s}f{s}i", .{
2140 sign_prefix,2105 switch (dest_scalar_info.signedness) {
2141 compiler_rt_operand_abbrev,2106 .signed => "",
2142 compiler_rt_dest_abbrev,2107 .unsigned => "uns",
2108 },
2109 compilerRtFloatAbbrev(target, operand_scalar_ty.floatBits(target)),
2110 compilerRtIntAbbrev(rt_int_ty.intInfo(zcu).bits),
2143 });2111 });
21442112 const result = try fg.buildElementwiseCall(fn_name, .{
2145 const operand_llvm_ty = try o.lowerType(operand_ty, .by_value);2113 .cc = target.cCallingConvention().?,
2146 const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty);2114 .param_types = &.{operand_scalar_ty.toIntern()},
2147 var result = try self.wip.call(2115 .return_type = rt_int_ty.toIntern(),
2148 .normal,2116 }, &.{operand}, if (operand_ty.isVector(zcu)) operand_ty.vectorLen(zcu) else null);
2149 .ccc,2117 return fg.wip.cast(.trunc, result, try o.lowerType(dest_ty, .as_value), "");
2150 .none,
2151 libc_fn.typeOf(&o.builder),
2152 libc_fn.toValue(&o.builder),
2153 &.{operand},
2154 "",
2155 );
2156
2157 if (libc_ret_ty != ret_ty) result = try self.wip.cast(.bitcast, result, ret_ty, "");
2158 if (ret_ty != dest_llvm_ty) result = try self.wip.cast(.trunc, result, dest_llvm_ty, "");
2159 return result;
2160}2118}
21612119
2162fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {2120fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {
...@@ -2167,7 +2125,7 @@ fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!B...@@ -2167,7 +2125,7 @@ fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!B
2167fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {2125fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {
2168 const o = fg.object;2126 const o = fg.object;
2169 const zcu = o.zcu;2127 const zcu = o.zcu;
2170 const llvm_usize = try o.lowerType(.usize, .by_value);2128 const llvm_usize = try o.lowerType(.usize, .as_value);
2171 switch (ty.ptrSize(zcu)) {2129 switch (ty.ptrSize(zcu)) {
2172 .slice => {2130 .slice => {
2173 const len = try fg.wip.extractValue(ptr, &.{1}, "");2131 const len = try fg.wip.extractValue(ptr, &.{1}, "");
...@@ -2365,7 +2323,7 @@ fn airAggFieldVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder....@@ -2365,7 +2323,7 @@ fn airAggFieldVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.
2365 },2323 },
2366 .float => {2324 .float => {
2367 // bitcast int->float2325 // bitcast int->float
2368 return self.wip.cast(.bitcast, field_int_val, try o.lowerType(field_ty, .by_value), "");2326 return self.wip.cast(.bitcast, field_int_val, try o.lowerType(field_ty, .as_value), "");
2369 },2327 },
2370 }2328 }
2371 }2329 }
...@@ -2395,8 +2353,8 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build...@@ -2395,8 +2353,8 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build
2395 const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu);2353 const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu);
2396 if (field_offset == 0) return field_ptr;2354 if (field_offset == 0) return field_ptr;
23972355
2398 const res_ty = try o.lowerType(ty_pl.ty.toType(), .by_value);2356 const res_ty = try o.lowerType(ty_pl.ty.toType(), .as_value);
2399 const llvm_usize = try o.lowerType(.usize, .by_value);2357 const llvm_usize = try o.lowerType(.usize, .as_value);
24002358
2401 const field_ptr_int = try self.wip.cast(.ptrtoint, field_ptr, llvm_usize, "");2359 const field_ptr_int = try self.wip.cast(.ptrtoint, field_ptr, llvm_usize, "");
2402 const base_ptr_int = try self.wip.bin(2360 const base_ptr_int = try self.wip.bin(
...@@ -2612,7 +2570,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {...@@ -2612,7 +2570,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {
2612 const output_inst = try self.resolveInst(output.operand);2570 const output_inst = try self.resolveInst(output.operand);
2613 const output_ty = self.typeOf(output.operand);2571 const output_ty = self.typeOf(output.operand);
2614 assert(output_ty.zigTypeTag(zcu) == .pointer);2572 assert(output_ty.zigTypeTag(zcu) == .pointer);
2615 const elem_llvm_ty = try o.lowerType(output_ty.childType(zcu), .by_value);2573 const elem_llvm_ty = try o.lowerType(output_ty.childType(zcu), .as_value);
26162574
2617 switch (constraint[0]) {2575 switch (constraint[0]) {
2618 '=' => {},2576 '=' => {},
...@@ -2650,7 +2608,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {...@@ -2650,7 +2608,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {
2650 llvm_ret_indirect[output.index] = false;2608 llvm_ret_indirect[output.index] = false;
26512609
2652 const ret_ty = self.typeOfIndex(inst);2610 const ret_ty = self.typeOfIndex(inst);
2653 llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty, .by_value);2611 llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty, .as_value);
2654 llvm_ret_i += 1;2612 llvm_ret_i += 1;
2655 }2613 }
26562614
...@@ -2689,7 +2647,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {...@@ -2689,7 +2647,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {
2689 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);2647 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);
2690 } else {2648 } else {
2691 const alignment = arg_ty.abiAlignment(zcu).toLlvm();2649 const alignment = arg_ty.abiAlignment(zcu).toLlvm();
2692 const arg_llvm_ty = try o.lowerType(arg_ty, .by_value);2650 const arg_llvm_ty = try o.lowerType(arg_ty, .as_value);
2693 const load_inst = try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, "");2651 const load_inst = try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, "");
2694 llvm_param_values[llvm_param_i] = load_inst;2652 llvm_param_values[llvm_param_i] = load_inst;
2695 llvm_param_types[llvm_param_i] = arg_llvm_ty;2653 llvm_param_types[llvm_param_i] = arg_llvm_ty;
...@@ -2729,7 +2687,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {...@@ -2729,7 +2687,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {
2729 llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: {2687 llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: {
2730 if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu));2688 if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu));
27312689
2732 break :blk try o.lowerType(if (is_by_ref) arg_ty else arg_ty.childType(zcu), .by_value);2690 break :blk try o.lowerType(if (is_by_ref) arg_ty else arg_ty.childType(zcu), .as_value);
2733 } else .none;2691 } else .none;
27342692
2735 llvm_param_i += 1;2693 llvm_param_i += 1;
...@@ -2743,7 +2701,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {...@@ -2743,7 +2701,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {
2743 if (constraint[0] != '+') continue;2701 if (constraint[0] != '+') continue;
27442702
2745 const rw_ty = self.typeOf(output.operand);2703 const rw_ty = self.typeOf(output.operand);
2746 const llvm_elem_ty = try o.lowerType(rw_ty.childType(zcu), .by_value);2704 const llvm_elem_ty = try o.lowerType(rw_ty.childType(zcu), .as_value);
2747 if (llvm_ret_indirect[output.index]) {2705 if (llvm_ret_indirect[output.index]) {
2748 llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index];2706 llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index];
2749 llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip);2707 llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip);
...@@ -2957,7 +2915,7 @@ fn airIsNonNull(...@@ -2957,7 +2915,7 @@ fn airIsNonNull(
2957 ));2915 ));
2958 return self.wip.icmp(cond, slice_ptr, try o.builder.nullValue(ptr_ty), "");2916 return self.wip.icmp(cond, slice_ptr, try o.builder.nullValue(ptr_ty), "");
2959 }2917 }
2960 return self.wip.icmp(cond, loaded, try o.builder.zeroInitValue(try o.lowerType(optional_ty, .by_value)), "");2918 return self.wip.icmp(cond, loaded, try o.builder.zeroInitValue(try o.lowerType(optional_ty, .as_value)), "");
2961 }2919 }
29622920
2963 comptime assert(optional_layout_version == 3);2921 comptime assert(optional_layout_version == 3);
...@@ -2986,7 +2944,7 @@ fn airIsErr(...@@ -2986,7 +2944,7 @@ fn airIsErr(
2986 const operand_ty = self.typeOf(un_op);2944 const operand_ty = self.typeOf(un_op);
2987 const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;2945 const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;
2988 const payload_ty = err_union_ty.errorUnionPayload(zcu);2946 const payload_ty = err_union_ty.errorUnionPayload(zcu);
2989 const zero_err = try o.builder.intValue(try o.errorIntType(.by_value), 0);2947 const zero_err = try o.builder.intValue(try o.errorIntType(.as_value), 0);
29902948
2991 const access_kind: Builder.MemoryAccessKind =2949 const access_kind: Builder.MemoryAccessKind =
2992 if (operand_is_ptr and operand_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;2950 if (operand_is_ptr and operand_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
...@@ -3156,7 +3114,7 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) Allocator.Erro...@@ -3156,7 +3114,7 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) Allocator.Erro
3156 const err_union_ptr_align = err_union_ptr_ty.ptrAlignment(zcu);3114 const err_union_ptr_align = err_union_ptr_ty.ptrAlignment(zcu);
31573115
3158 const payload_ty = err_union_ty.errorUnionPayload(zcu);3116 const payload_ty = err_union_ty.errorUnionPayload(zcu);
3159 const non_error_val = try o.builder.intValue(try o.errorIntType(.by_value), 0);3117 const non_error_val = try o.builder.intValue(try o.errorIntType(.as_value), 0);
31603118
3161 const access_kind: Builder.MemoryAccessKind =3119 const access_kind: Builder.MemoryAccessKind =
3162 if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;3120 if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
...@@ -3234,7 +3192,7 @@ fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!...@@ -3234,7 +3192,7 @@ fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!
3234 const payload_ty = self.typeOf(ty_op.operand);3192 const payload_ty = self.typeOf(ty_op.operand);
3235 assert(payload_ty.hasRuntimeBits(zcu));3193 assert(payload_ty.hasRuntimeBits(zcu));
3236 assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref3194 assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref
3237 const ok_err_code = try o.builder.intValue(try o.errorIntType(.by_value), 0);3195 const ok_err_code = try o.builder.intValue(try o.errorIntType(.as_value), 0);
32383196
3239 const result_ptr = try self.buildZigAlloca(err_un_ty, .none);3197 const result_ptr = try self.buildZigAlloca(err_un_ty, .none);
32403198
...@@ -3273,7 +3231,7 @@ fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build...@@ -3273,7 +3231,7 @@ fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build
3273 const o = self.object;3231 const o = self.object;
3274 const pl_op = self.air.instructions.items(.data)[@backingInt(inst)].pl_op;3232 const pl_op = self.air.instructions.items(.data)[@backingInt(inst)].pl_op;
3275 const index = pl_op.payload;3233 const index = pl_op.payload;
3276 const llvm_usize = try o.lowerType(.usize, .by_value);3234 const llvm_usize = try o.lowerType(.usize, .as_value);
3277 return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.size", &.{llvm_usize}, &.{3235 return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.size", &.{llvm_usize}, &.{
3278 try o.builder.intValue(.i32, index),3236 try o.builder.intValue(.i32, index),
3279 }, "");3237 }, "");
...@@ -3283,7 +3241,7 @@ fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build...@@ -3283,7 +3241,7 @@ fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build
3283 const o = self.object;3241 const o = self.object;
3284 const pl_op = self.air.instructions.items(.data)[@backingInt(inst)].pl_op;3242 const pl_op = self.air.instructions.items(.data)[@backingInt(inst)].pl_op;
3285 const index = pl_op.payload;3243 const index = pl_op.payload;
3286 const llvm_isize = try o.lowerType(.isize, .by_value);3244 const llvm_isize = try o.lowerType(.isize, .as_value);
3287 return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.grow", &.{llvm_isize}, &.{3245 return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.grow", &.{llvm_isize}, &.{
3288 try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand),3246 try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand),
3289 }, "");3247 }, "");
...@@ -3310,7 +3268,7 @@ fn airMin(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {...@@ -3310,7 +3268,7 @@ fn airMin(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3310 .normal,3268 .normal,
3311 .none,3269 .none,
3312 if (scalar_ty.isSignedInt(zcu)) .smin else .umin,3270 if (scalar_ty.isSignedInt(zcu)) .smin else .umin,
3313 &.{try o.lowerType(inst_ty, .by_value)},3271 &.{try o.lowerType(inst_ty, .as_value)},
3314 &.{ lhs, rhs },3272 &.{ lhs, rhs },
3315 "",3273 "",
3316 );3274 );
...@@ -3330,7 +3288,7 @@ fn airMax(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {...@@ -3330,7 +3288,7 @@ fn airMax(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3330 .normal,3288 .normal,
3331 .none,3289 .none,
3332 if (scalar_ty.isSignedInt(zcu)) .smax else .umax,3290 if (scalar_ty.isSignedInt(zcu)) .smax else .umax,
3333 &.{try o.lowerType(inst_ty, .by_value)},3291 &.{try o.lowerType(inst_ty, .as_value)},
3334 &.{ lhs, rhs },3292 &.{ lhs, rhs },
3335 "",3293 "",
3336 );3294 );
...@@ -3342,7 +3300,7 @@ fn airSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -3342,7 +3300,7 @@ fn airSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
3342 const ptr = try self.resolveInst(bin_op.lhs);3300 const ptr = try self.resolveInst(bin_op.lhs);
3343 const len = try self.resolveInst(bin_op.rhs);3301 const len = try self.resolveInst(bin_op.rhs);
3344 const inst_ty = self.typeOfIndex(inst);3302 const inst_ty = self.typeOfIndex(inst);
3345 return self.wip.buildAggregate(try self.object.lowerType(inst_ty, .by_value), &.{ ptr, len }, "");3303 return self.wip.buildAggregate(try self.object.lowerType(inst_ty, .as_value), &.{ ptr, len }, "");
3346}3304}
33473305
3348fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {3306fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
...@@ -3373,7 +3331,7 @@ fn airSafeArithmetic(...@@ -3373,7 +3331,7 @@ fn airSafeArithmetic(
3373 const scalar_ty = inst_ty.scalarType(zcu);3331 const scalar_ty = inst_ty.scalarType(zcu);
33743332
3375 const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic;3333 const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic;
3376 const llvm_inst_ty = try o.lowerType(inst_ty, .by_value);3334 const llvm_inst_ty = try o.lowerType(inst_ty, .as_value);
3377 const results =3335 const results =
3378 try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, "");3336 try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, "");
33793337
...@@ -3423,7 +3381,7 @@ fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -3423,7 +3381,7 @@ fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
3423 .normal,3381 .normal,
3424 .none,3382 .none,
3425 if (scalar_ty.isSignedInt(zcu)) .@"sadd.sat" else .@"uadd.sat",3383 if (scalar_ty.isSignedInt(zcu)) .@"sadd.sat" else .@"uadd.sat",
3426 &.{try o.lowerType(inst_ty, .by_value)},3384 &.{try o.lowerType(inst_ty, .as_value)},
3427 &.{ lhs, rhs },3385 &.{ lhs, rhs },
3428 "",3386 "",
3429 );3387 );
...@@ -3462,7 +3420,7 @@ fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -3462,7 +3420,7 @@ fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
3462 .normal,3420 .normal,
3463 .none,3421 .none,
3464 if (scalar_ty.isSignedInt(zcu)) .@"ssub.sat" else .@"usub.sat",3422 if (scalar_ty.isSignedInt(zcu)) .@"ssub.sat" else .@"usub.sat",
3465 &.{try o.lowerType(inst_ty, .by_value)},3423 &.{try o.lowerType(inst_ty, .as_value)},
3466 &.{ lhs, rhs },3424 &.{ lhs, rhs },
3467 "",3425 "",
3468 );3426 );
...@@ -3501,7 +3459,7 @@ fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -3501,7 +3459,7 @@ fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
3501 .normal,3459 .normal,
3502 .none,3460 .none,
3503 if (scalar_ty.isSignedInt(zcu)) .@"smul.fix.sat" else .@"umul.fix.sat",3461 if (scalar_ty.isSignedInt(zcu)) .@"smul.fix.sat" else .@"umul.fix.sat",
3504 &.{try o.lowerType(inst_ty, .by_value)},3462 &.{try o.lowerType(inst_ty, .as_value)},
3505 &.{ lhs, rhs, .@"0" },3463 &.{ lhs, rhs, .@"0" },
3506 "",3464 "",
3507 );3465 );
...@@ -3545,8 +3503,8 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)...@@ -3545,8 +3503,8 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)
3545 return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result});3503 return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result});
3546 }3504 }
3547 if (scalar_ty.isSignedInt(zcu)) {3505 if (scalar_ty.isSignedInt(zcu)) {
3548 const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value);3506 const scalar_llvm_ty = try o.lowerType(scalar_ty, .as_value);
3549 const inst_llvm_ty = try o.lowerType(inst_ty, .by_value);3507 const inst_llvm_ty = try o.lowerType(inst_ty, .as_value);
35503508
3551 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;3509 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;
3552 var bfa_buf: ExpectedContents = undefined;3510 var bfa_buf: ExpectedContents = undefined;
...@@ -3594,8 +3552,8 @@ fn airDivCeil(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)...@@ -3594,8 +3552,8 @@ fn airDivCeil(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)
3594 return self.buildFloatOp(.ceil, fast, inst_ty, 1, .{result});3552 return self.buildFloatOp(.ceil, fast, inst_ty, 1, .{result});
3595 }3553 }
3596 if (scalar_ty.isSignedInt(zcu)) {3554 if (scalar_ty.isSignedInt(zcu)) {
3597 const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value);3555 const scalar_llvm_ty = try o.lowerType(scalar_ty, .as_value);
3598 const inst_llvm_ty = try o.lowerType(inst_ty, .by_value);3556 const inst_llvm_ty = try o.lowerType(inst_ty, .as_value);
35993557
3600 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;3558 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;
3601 var bfa_buf: ExpectedContents = undefined;3559 var bfa_buf: ExpectedContents = undefined;
...@@ -3634,8 +3592,8 @@ fn airDivCeil(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)...@@ -3634,8 +3592,8 @@ fn airDivCeil(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)
3634 const correction = try self.wip.cast(.zext, need_correction, inst_llvm_ty, "divCeil.correction");3592 const correction = try self.wip.cast(.zext, need_correction, inst_llvm_ty, "divCeil.correction");
3635 return self.wip.bin(.@"add nsw", div, correction, "divCeil");3593 return self.wip.bin(.@"add nsw", div, correction, "divCeil");
3636 } else {3594 } else {
3637 const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value);3595 const scalar_llvm_ty = try o.lowerType(scalar_ty, .as_value);
3638 const inst_llvm_ty = try o.lowerType(inst_ty, .by_value);3596 const inst_llvm_ty = try o.lowerType(inst_ty, .as_value);
36393597
3640 const zero = try o.builder.splatValue(3598 const zero = try o.builder.splatValue(
3641 inst_llvm_ty,3599 inst_llvm_ty,
...@@ -3692,15 +3650,17 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo...@@ -3692,15 +3650,17 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo
3692 const lhs = try self.resolveInst(bin_op.lhs);3650 const lhs = try self.resolveInst(bin_op.lhs);
3693 const rhs = try self.resolveInst(bin_op.rhs);3651 const rhs = try self.resolveInst(bin_op.rhs);
3694 const inst_ty = self.typeOfIndex(inst);3652 const inst_ty = self.typeOfIndex(inst);
3695 const inst_llvm_ty = try o.lowerType(inst_ty, .by_value);
3696 const scalar_ty = inst_ty.scalarType(zcu);3653 const scalar_ty = inst_ty.scalarType(zcu);
36973654
3698 if (scalar_ty.isRuntimeFloat()) {3655 if (scalar_ty.isRuntimeFloat()) {
3699 const a = try self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ lhs, rhs });3656 const a = try self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ lhs, rhs });
3700 const b = try self.buildFloatOp(.add, fast, inst_ty, 2, .{ a, rhs });3657 const b = try self.buildFloatOp(.add, fast, inst_ty, 2, .{ a, rhs });
3701 const c = try self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ b, rhs });3658 const c = try self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ b, rhs });
3702 const zero = try o.builder.zeroInitValue(inst_llvm_ty);3659 const zero = if (isByRef(inst_ty, zcu)) zero: {
3703 const ltz = try self.buildFloatCmp(fast, .lt, inst_ty, .{ lhs, zero });3660 const zero = try o.builder.zeroInitConst(try o.lowerType(inst_ty, .in_memory));
3661 break :zero try o.lowerConstRef(zero, inst_ty.abiAlignment(zcu).toLlvm());
3662 } else try o.builder.zeroInitConst(try o.lowerType(inst_ty, .as_value));
3663 const ltz = try self.buildFloatCmp(fast, .lt, inst_ty, .{ lhs, zero.toValue() });
3704 return self.wip.select(fast, ltz, c, a, "");3664 return self.wip.select(fast, ltz, c, a, "");
3705 }3665 }
3706 if (scalar_ty.isSignedInt(zcu)) {3666 if (scalar_ty.isSignedInt(zcu)) {
...@@ -3709,6 +3669,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo...@@ -3709,6 +3669,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo
3709 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa);3669 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa);
3710 const allocator = bfa.allocator();3670 const allocator = bfa.allocator();
37113671
3672 const inst_llvm_ty = try o.lowerType(inst_ty, .as_value);
3712 const scalar_bits = scalar_ty.intInfo(zcu).bits;3673 const scalar_bits = scalar_ty.intInfo(zcu).bits;
3713 var smin_big_int: std.math.big.int.Mutable = .{3674 var smin_big_int: std.math.big.int.Mutable = .{
3714 .limbs = try allocator.alloc(3675 .limbs = try allocator.alloc(
...@@ -3721,7 +3682,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo...@@ -3721,7 +3682,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo
3721 defer allocator.free(smin_big_int.limbs);3682 defer allocator.free(smin_big_int.limbs);
3722 smin_big_int.setTwosCompIntLimit(.min, .signed, scalar_bits);3683 smin_big_int.setTwosCompIntLimit(.min, .signed, scalar_bits);
3723 const smin = try o.builder.splatValue(inst_llvm_ty, try o.builder.bigIntConst(3684 const smin = try o.builder.splatValue(inst_llvm_ty, try o.builder.bigIntConst(
3724 try o.lowerType(scalar_ty, .by_value),3685 try o.lowerType(scalar_ty, .as_value),
3725 smin_big_int.toConst(),3686 smin_big_int.toConst(),
3726 ));3687 ));
37273688
...@@ -3757,7 +3718,7 @@ fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -3757,7 +3718,7 @@ fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
3757 const ty_pl = self.air.instructions.items(.data)[@backingInt(inst)].ty_pl;3718 const ty_pl = self.air.instructions.items(.data)[@backingInt(inst)].ty_pl;
3758 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3719 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
3759 const ptr_or_slice = try self.resolveInst(bin_op.lhs);3720 const ptr_or_slice = try self.resolveInst(bin_op.lhs);
3760 const llvm_usize_ty = try o.lowerType(.usize, .by_value);3721 const llvm_usize_ty = try o.lowerType(.usize, .as_value);
3761 const ptr_ty = self.typeOf(bin_op.lhs);3722 const ptr_ty = self.typeOf(bin_op.lhs);
3762 const elem_ty = ptr_ty.indexableElem(zcu);3723 const elem_ty = ptr_ty.indexableElem(zcu);
3763 const ptr = switch (ptr_ty.ptrSize(zcu)) {3724 const ptr = switch (ptr_ty.ptrSize(zcu)) {
...@@ -3790,7 +3751,7 @@ fn airOverflow(...@@ -3790,7 +3751,7 @@ fn airOverflow(
3790 assert(isByRef(inst_ty, zcu)); // auto structs are by-ref3751 assert(isByRef(inst_ty, zcu)); // auto structs are by-ref
37913752
3792 const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic;3753 const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic;
3793 const llvm_lhs_ty = try o.lowerType(lhs_ty, .by_value);3754 const llvm_lhs_ty = try o.lowerType(lhs_ty, .as_value);
3794 const results =3755 const results =
3795 try self.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, "");3756 try self.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, "");
37963757
...@@ -3818,34 +3779,97 @@ fn airOverflow(...@@ -3818,34 +3779,97 @@ fn airOverflow(
3818}3779}
38193780
3820fn buildElementwiseCall(3781fn buildElementwiseCall(
3821 self: *FuncGen,3782 fg: *FuncGen,
3822 llvm_fn: Builder.Function.Index,3783 fn_name: Builder.StrtabString,
3823 args_vectors: []const Builder.Value,3784 fn_info: Object.FuncInfo,
3824 result_vector: Builder.Value,3785 arg_values: []const Builder.Value,
3825 vector_len: usize,3786 vector_len: ?u32,
3826) Allocator.Error!Builder.Value {3787) Allocator.Error!Builder.Value {
3827 const o = self.object;3788 const o = fg.object;
3828 assert(args_vectors.len <= 3);3789 const zcu = o.zcu;
3790 const llvm_fn = try fg.object.getLibcFunction(fg.pt, fn_name, fn_info);
3791
3792 const iterations = vector_len orelse 1;
3793 const ret_ty: Type = .fromInterned(fn_info.return_type);
3794 const ret_is_by_ref = isByRef(ret_ty, zcu);
3795 if (iterations > 1 and (fn_info.return_type == .void_type or ret_is_by_ref) and
3796 for (fn_info.param_types) |param_type| {
3797 if (!isByRef(.fromInterned(param_type), zcu)) break false;
3798 } else true)
3799 {
3800 const entry_block = fg.wip.cursor.block;
3801 const loop_block = try fg.wip.block(2, "elementwise.loop");
3802 const done_block = try fg.wip.block(1, "elementwise.done");
3803
3804 const result_ptr = if (fn_info.return_type == .void_type) .none else result_ptr: {
3805 const ret_llvm_ty = try o.lowerType(ret_ty, .in_memory);
3806 break :result_ptr try fg.buildAlloca(
3807 if (vector_len) |len| try o.builder.arrayType(len, ret_llvm_ty) else ret_llvm_ty,
3808 ret_ty.abiAlignment(zcu).toLlvm(),
3809 );
3810 };
3811 _ = try fg.wip.br(loop_block);
38293812
3830 var i: usize = 0;3813 fg.wip.cursor = .{ .block = loop_block };
3831 var result = result_vector;3814 const index = try fg.wip.phi(.i32, "elementwise.index");
3832 while (i < vector_len) : (i += 1) {
3833 const index_i32 = try o.builder.intValue(.i32, i);
38343815
3835 var args: [3]Builder.Value = undefined;3816 var arg_elems_buf: [3]Builder.Value = undefined;
3836 for (args[0..args_vectors.len], args_vectors) |*arg_elem, arg_vector| {3817 const arg_elems = arg_elems_buf[0..arg_values.len];
3837 arg_elem.* = try self.wip.extractElement(arg_vector, index_i32, "");3818 for (arg_elems, fn_info.param_types, arg_values) |*arg_elem, param_type, arg_value| {
3819 const arg_elem_ptr = try fg.ptraddScaled(arg_value, index.toValue(), Type.fromInterned(param_type).abiSize(zcu));
3820 arg_elem.* = try fg.load(arg_elem_ptr, .none, .fromInterned(param_type), .normal);
3838 }3821 }
3839 const result_elem = try self.wip.call(3822 const result_elem = try fg.buildCall(.{}, llvm_fn.typeOf(&o.builder), llvm_fn.toValue(&o.builder), fn_info, fn_info.param_types, arg_elems);
3840 .normal,3823 if (fn_info.return_type == .void_type) {
3841 .ccc,3824 assert(result_elem == .none);
3842 .none,3825 } else if (result_elem != .none) {
3843 llvm_fn.typeOf(&o.builder),3826 const result_elem_ptr = try fg.ptraddScaled(result_ptr, index.toValue(), ret_ty.abiSize(zcu));
3844 llvm_fn.toValue(&o.builder),3827 try fg.store(result_elem_ptr, .none, result_elem, ret_ty, .normal);
3845 args[0..args_vectors.len],3828 }
3846 "",3829
3830 const next_index = try fg.wip.bin(.@"add nuw", index.toValue(), try o.builder.intValue(.i32, 1), "elementwise.next_index");
3831 index.finish(&.{ try o.builder.intValue(.i32, 0), next_index }, &.{ entry_block, loop_block }, &fg.wip);
3832 const is_done = try fg.wip.icmp(.eq, next_index, try o.builder.intValue(.i32, iterations), "elementwise.is_done");
3833 _ = try fg.wip.brCond(is_done, done_block, loop_block, .none);
3834
3835 fg.wip.cursor = .{ .block = done_block };
3836 return result_ptr;
3837 }
3838
3839 var result = if (fn_info.return_type == .void_type) .none else if (ret_is_by_ref) result: {
3840 const ret_llvm_ty = try o.lowerType(ret_ty, .in_memory);
3841 break :result try fg.buildAlloca(
3842 if (vector_len) |len| try o.builder.arrayType(len, ret_llvm_ty) else ret_llvm_ty,
3843 ret_ty.abiAlignment(zcu).toLlvm(),
3847 );3844 );
3848 result = try self.wip.insertElement(result, result_elem, index_i32, "");3845 } else if (vector_len) |len| try o.builder.poisonValue(
3846 try o.builder.vectorType(.normal, len, try o.lowerType(ret_ty, .as_value)),
3847 ) else .none;
3848 for (0..iterations) |index| {
3849 const index_value = try o.builder.intValue(.i32, index);
3850 var arg_elems_buf: [3]Builder.Value = undefined;
3851 const arg_elems = arg_elems_buf[0..arg_values.len];
3852 for (arg_elems, fn_info.param_types, arg_values) |*arg_elem_value, param_type, arg_value| {
3853 const arg_ty: Type = .fromInterned(param_type);
3854 if (isByRef(arg_ty, zcu)) {
3855 const arg_elem_ptr = try fg.ptraddConst(arg_value, index * arg_ty.abiSize(zcu));
3856 arg_elem_value.* = try fg.load(arg_elem_ptr, .none, .fromInterned(param_type), .normal);
3857 } else if (vector_len) |_| {
3858 arg_elem_value.* = try fg.wip.extractElement(arg_value, index_value, "elementwise.arg_elem");
3859 } else arg_elem_value.* = arg_value;
3860 }
3861 const result_elem = try fg.buildCall(.{}, llvm_fn.typeOf(&o.builder), llvm_fn.toValue(&o.builder), fn_info, fn_info.param_types, arg_elems);
3862 if (fn_info.return_type == .void_type) {
3863 assert(result_elem == .none);
3864 } else if (ret_is_by_ref) {
3865 const result_elem_ptr = try fg.ptraddConst(result, index * ret_ty.abiSize(zcu));
3866 try fg.store(result_elem_ptr, .none, result_elem, ret_ty, .normal);
3867 } else if (vector_len) |_| {
3868 result = try fg.wip.insertElement(result, result_elem, index_value, "elementwise.result");
3869 } else {
3870 assert(result == .none);
3871 result = result_elem;
3872 }
3849 }3873 }
3850 return result;3874 return result;
3851}3875}
...@@ -3853,19 +3877,18 @@ fn buildElementwiseCall(...@@ -3853,19 +3877,18 @@ fn buildElementwiseCall(
3853/// Creates a floating point comparison by lowering to the appropriate3877/// Creates a floating point comparison by lowering to the appropriate
3854/// hardware instruction or softfloat routine for the target3878/// hardware instruction or softfloat routine for the target
3855fn buildFloatCmp(3879fn buildFloatCmp(
3856 self: *FuncGen,3880 fg: *FuncGen,
3857 fast: Builder.FastMathKind,3881 fast: Builder.FastMathKind,
3858 pred: math.CompareOperator,3882 pred: math.CompareOperator,
3859 ty: Type,3883 ty: Type,
3860 params: [2]Builder.Value,3884 params: [2]Builder.Value,
3861) Allocator.Error!Builder.Value {3885) Allocator.Error!Builder.Value {
3862 const o = self.object;3886 const o = fg.object;
3863 const zcu = o.zcu;3887 const zcu = o.zcu;
3864 const target = zcu.getTarget();3888 const target = zcu.getTarget();
3865 const scalar_ty = ty.scalarType(zcu);3889 const scalar_ty = ty.scalarType(zcu);
3866 const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value);
38673890
3868 if (intrinsicsAllowed(scalar_ty, target)) {3891 if (intrinsicsAllowed(.compiler_rt, scalar_ty, target)) {
3869 const cond: Builder.FloatCondition = switch (pred) {3892 const cond: Builder.FloatCondition = switch (pred) {
3870 .eq => .oeq,3893 .eq => .oeq,
3871 .neq => .une,3894 .neq => .une,
...@@ -3874,53 +3897,33 @@ fn buildFloatCmp(...@@ -3874,53 +3897,33 @@ fn buildFloatCmp(
3874 .gt => .ogt,3897 .gt => .ogt,
3875 .gte => .oge,3898 .gte => .oge,
3876 };3899 };
3877 return self.wip.fcmp(fast, cond, params[0], params[1], "");3900 return fg.wip.fcmp(fast, cond, params[0], params[1], "");
3878 }3901 }
38793902
3880 const float_bits = scalar_ty.floatBits(target);3903 const fn_name = try o.builder.strtabStringFmt("__{s}{s}f2", .{
3881 const compiler_rt_float_abbrev = compilerRtFloatAbbrev(float_bits);3904 switch (pred) {
3882 const fn_base_name = switch (pred) {3905 .neq => "ne",
3883 .neq => "ne",3906 .eq => "eq",
3884 .eq => "eq",3907 .lt => "lt",
3885 .lt => "lt",3908 .lte => "le",
3886 .lte => "le",3909 .gt => "gt",
3887 .gt => "gt",3910 .gte => "ge",
3888 .gte => "ge",3911 },
3889 };3912 compilerRtFloatAbbrev(target, scalar_ty.floatBits(target)),
3890 const fn_name = try o.builder.strtabStringFmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev });3913 });
38913914 const result = try fg.buildElementwiseCall(fn_name, .{
3892 const libc_fn = try o.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32);3915 .cc = target.cCallingConvention().?,
38933916 .param_types = &.{ scalar_ty.toIntern(), scalar_ty.toIntern() },
3894 const int_cond: Builder.IntegerCondition = switch (pred) {3917 .return_type = .i32_type,
3918 }, &params, if (ty.isVector(zcu)) ty.vectorLen(zcu) else null);
3919 return fg.wip.icmp(switch (pred) {
3895 .eq => .eq,3920 .eq => .eq,
3896 .neq => .ne,3921 .neq => .ne,
3897 .lt => .slt,3922 .lt => .slt,
3898 .lte => .sle,3923 .lte => .sle,
3899 .gt => .sgt,3924 .gt => .sgt,
3900 .gte => .sge,3925 .gte => .sge,
3901 };3926 }, result, try o.builder.splatValue(result.typeOfWip(&fg.wip), .@"0"), "");
3902
3903 if (ty.zigTypeTag(zcu) == .vector) {
3904 const vec_len = ty.vectorLen(zcu);
3905 const vector_result_ty = try o.builder.vectorType(.normal, vec_len, .i32);
3906
3907 const init = try o.builder.poisonValue(vector_result_ty);
3908 const result = try self.buildElementwiseCall(libc_fn, &params, init, vec_len);
3909
3910 const zero_vector = try o.builder.splatValue(vector_result_ty, .@"0");
3911 return self.wip.icmp(int_cond, result, zero_vector, "");
3912 }
3913
3914 const result = try self.wip.call(
3915 .normal,
3916 .ccc,
3917 .none,
3918 libc_fn.typeOf(&o.builder),
3919 libc_fn.toValue(&o.builder),
3920 &params,
3921 "",
3922 );
3923 return self.wip.icmp(int_cond, result, .@"0", "");
3924}3927}
39253928
3926const FloatOp = enum {3929const FloatOp = enum {
...@@ -3949,32 +3952,30 @@ const FloatOp = enum {...@@ -3949,32 +3952,30 @@ const FloatOp = enum {
3949 trunc,3952 trunc,
3950};3953};
39513954
3952const FloatOpStrat = union(enum) {
3953 intrinsic: []const u8,
3954 libc: Builder.String,
3955};
3956
3957/// Creates a floating point operation (add, sub, fma, sqrt, exp, etc.)3955/// Creates a floating point operation (add, sub, fma, sqrt, exp, etc.)
3958/// by lowering to the appropriate hardware instruction or softfloat3956/// by lowering to the appropriate hardware instruction or softfloat
3959/// routine for the target3957/// routine for the target
3960fn buildFloatOp(3958fn buildFloatOp(
3961 self: *FuncGen,3959 fg: *FuncGen,
3962 comptime op: FloatOp,3960 comptime op: FloatOp,
3963 fast: Builder.FastMathKind,3961 fast: Builder.FastMathKind,
3964 ty: Type,3962 ty: Type,
3965 comptime params_len: usize,3963 comptime params_len: usize,
3966 params: [params_len]Builder.Value,3964 params: [params_len]Builder.Value,
3967) Allocator.Error!Builder.Value {3965) Allocator.Error!Builder.Value {
3968 const o = self.object;3966 const o = fg.object;
3969 const zcu = o.zcu;3967 const zcu = o.zcu;
3970 const target = zcu.getTarget();3968 const target = zcu.getTarget();
3971 const scalar_ty = ty.scalarType(zcu);3969 const scalar_ty = ty.scalarType(zcu);
3972 const llvm_ty = try o.lowerType(ty, .by_value);
39733970
3974 if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) {3971 switch (op) {
3975 // Some operations are dedicated LLVM instructions, not available as intrinsics3972 // Some operations are dedicated LLVM instructions, not available as intrinsics
3976 .neg => return self.wip.un(.fneg, params[0], ""),3973 .neg => if (intrinsicsAllowed(.compiler_rt, scalar_ty, target)) return fg.wip.un(.fneg, params[0], ""),
3977 .add, .sub, .mul, .div, .fmod => return self.wip.bin(switch (fast) {3974 .add, .sub, .mul, .div, .fmod => if (intrinsicsAllowed(switch (op) {
3975 else => unreachable,
3976 .add, .sub, .mul, .div => .compiler_rt,
3977 .fmod => .libc,
3978 }, scalar_ty, target)) return fg.wip.bin(switch (fast) {
3978 .normal => switch (op) {3979 .normal => switch (op) {
3979 .add => .fadd,3980 .add => .fadd,
3980 .sub => .fsub,3981 .sub => .fsub,
...@@ -3992,6 +3993,7 @@ fn buildFloatOp(...@@ -3992,6 +3993,7 @@ fn buildFloatOp(
3992 else => unreachable,3993 else => unreachable,
3993 },3994 },
3994 }, params[0], params[1], ""),3995 }, params[0], params[1], ""),
3996 .fma,
3995 .fmax,3997 .fmax,
3996 .fmin,3998 .fmin,
3997 .ceil,3999 .ceil,
...@@ -4006,9 +4008,10 @@ fn buildFloatOp(...@@ -4006,9 +4008,10 @@ fn buildFloatOp(
4006 .round,4008 .round,
4007 .sin,4009 .sin,
4008 .sqrt,4010 .sqrt,
4011 .tan,
4009 .trunc,4012 .trunc,
4010 .fma,4013 => if (intrinsicsAllowed(.libc, scalar_ty, target)) return fg.wip.callIntrinsic(fast, .none, switch (op) {
4011 => return self.wip.callIntrinsic(fast, .none, switch (op) {4014 .fma => .fma,
4012 .fmax => .maxnum,4015 .fmax => .maxnum,
4013 .fmin => .minnum,4016 .fmin => .minnum,
4014 .ceil => .ceil,4017 .ceil => .ceil,
...@@ -4023,39 +4026,154 @@ fn buildFloatOp(...@@ -4023,39 +4026,154 @@ fn buildFloatOp(
4023 .round => .round,4026 .round => .round,
4024 .sin => .sin,4027 .sin => .sin,
4025 .sqrt => .sqrt,4028 .sqrt => .sqrt,
4029 .tan => .tan,
4026 .trunc => .trunc,4030 .trunc => .trunc,
4027 .fma => .fma,
4028 else => unreachable,4031 else => unreachable,
4029 }, &.{llvm_ty}, &params, ""),4032 }, &.{try o.lowerType(ty, .as_value)}, &params, ""),
4030 .tan => unreachable,4033 }
4031 };
40324034
4033 const float_bits = scalar_ty.floatBits(target);4035 const float_bits = scalar_ty.floatBits(target);
4034 const fn_name = switch (op) {4036 const fn_name = switch (op) {
4035 .neg => {4037 // In these cases we can generate a softfloat operation by modifying the sign bit using a bitwise operation.
4036 // In this case we can generate a softfloat negation by XORing the4038 .neg, .fabs => if (isByRef(scalar_ty, zcu)) {
4037 // bits with a constant.4039 const is_vector = ty.toIntern() != scalar_ty.toIntern();
4040 const result_ptr = try fg.buildZigAlloca(ty, .none);
4041 const entry_block = fg.wip.cursor.block;
4042 const loop_block, const done_block, const llvm_usize_ty, const offset, const elem, const result_elem = if (is_vector) loop: {
4043 const loop_block = try fg.wip.block(2, "neg_fabs.loop");
4044 const done_block = try fg.wip.block(1, "neg_fabs.done");
4045 _ = try fg.wip.br(loop_block);
4046
4047 fg.wip.cursor = .{ .block = loop_block };
4048 const llvm_usize_ty = try o.lowerType(.usize, .as_value);
4049 const offset = try fg.wip.phi(llvm_usize_ty, "neg_fabs.offset");
4050 break :loop .{
4051 loop_block,
4052 done_block,
4053 llvm_usize_ty,
4054 offset,
4055 try fg.ptraddScaled(params[0], offset.toValue(), 1),
4056 try fg.ptraddScaled(result_ptr, offset.toValue(), 1),
4057 };
4058 } else .{ undefined, undefined, undefined, undefined, params[0], result_ptr };
4059 switch (scalar_ty.floatBits(target)) {
4060 else => unreachable,
4061 80 => {
4062 const f80_layout = o.softF80Layout(.{}) catch unreachable;
4063 const mantissa = try fg.load(
4064 try fg.ptraddConst(elem, f80_layout.mantissa_offset),
4065 f80_layout.alignment.offset(f80_layout.mantissa_offset),
4066 .u64,
4067 .normal,
4068 );
4069 const exponent = try fg.load(
4070 try fg.ptraddConst(elem, f80_layout.exponent_offset),
4071 f80_layout.alignment.offset(f80_layout.exponent_offset),
4072 .u16,
4073 .normal,
4074 );
4075 const exponent_sign_bit: u16 = 1 << (16 - 1);
4076 const updated_exponent = try fg.wip.bin(switch (op) {
4077 else => unreachable,
4078 .neg => .xor,
4079 .fabs => .@"and",
4080 }, exponent, try o.builder.intValue(.i16, switch (op) {
4081 else => unreachable,
4082 .neg => exponent_sign_bit,
4083 .fabs => exponent_sign_bit - 1,
4084 }), "neg_fabs.updated_exponent");
4085 try fg.store(
4086 try fg.ptraddConst(result_elem, f80_layout.mantissa_offset),
4087 f80_layout.alignment.offset(f80_layout.mantissa_offset),
4088 mantissa,
4089 .u64,
4090 .normal,
4091 );
4092 try fg.store(
4093 try fg.ptraddConst(result_elem, f80_layout.exponent_offset),
4094 f80_layout.alignment.offset(f80_layout.exponent_offset),
4095 updated_exponent,
4096 .u16,
4097 .normal,
4098 );
4099 },
4100 128 => {
4101 const f128_layout = o.softF128Layout(.{}) catch unreachable;
4102 const lo = try fg.load(
4103 try fg.ptraddConst(elem, f128_layout.lo_offset),
4104 f128_layout.alignment.offset(f128_layout.lo_offset),
4105 .u64,
4106 .normal,
4107 );
4108 const hi = try fg.load(
4109 try fg.ptraddConst(elem, f128_layout.hi_offset),
4110 f128_layout.alignment.offset(f128_layout.hi_offset),
4111 .u64,
4112 .normal,
4113 );
4114 const hi_sign_bit: u64 = 1 << (64 - 1);
4115 const updated_hi = try fg.wip.bin(switch (op) {
4116 else => unreachable,
4117 .neg => .xor,
4118 .fabs => .@"and",
4119 }, hi, try o.builder.intValue(.i64, switch (op) {
4120 else => unreachable,
4121 .neg => hi_sign_bit,
4122 .fabs => hi_sign_bit - 1,
4123 }), "neg_fabs.updated_hi");
4124 try fg.store(
4125 try fg.ptraddConst(result_elem, f128_layout.lo_offset),
4126 f128_layout.alignment.offset(f128_layout.lo_offset),
4127 lo,
4128 .u64,
4129 .normal,
4130 );
4131 try fg.store(
4132 try fg.ptraddConst(result_elem, f128_layout.hi_offset),
4133 f128_layout.alignment.offset(f128_layout.hi_offset),
4134 updated_hi,
4135 .u64,
4136 .normal,
4137 );
4138 },
4139 }
4140 if (is_vector) {
4141 const next_offset = try fg.wip.bin(.@"add nuw", offset.toValue(), try o.builder.intValue(llvm_usize_ty, scalar_ty.abiSize(zcu)), "neg_fabs.next_offset");
4142 offset.finish(&.{ try o.builder.intValue(llvm_usize_ty, 0), next_offset }, &.{ entry_block, loop_block }, &fg.wip);
4143 const is_done = try fg.wip.icmp(.eq, next_offset, try o.builder.intValue(llvm_usize_ty, ty.abiSize(zcu)), "neg_fabs.is_done");
4144 _ = try fg.wip.brCond(is_done, done_block, loop_block, .none);
4145
4146 fg.wip.cursor = .{ .block = done_block };
4147 }
4148 return result_ptr;
4149 } else {
4038 const int_ty = try o.builder.intType(@intCast(float_bits));4150 const int_ty = try o.builder.intType(@intCast(float_bits));
4039 const cast_ty = switch (ty.zigTypeTag(zcu)) {4151 const cast_ty = switch (ty.zigTypeTag(zcu)) {
4040 .vector => try o.builder.vectorType(.normal, ty.vectorLen(zcu), int_ty),4152 .vector => try o.builder.vectorType(.normal, ty.vectorLen(zcu), int_ty),
4041 else => int_ty,4153 else => int_ty,
4042 };4154 };
4043 const sign_mask = try o.builder.splatValue(4155 const sign_bit = @as(u128, 1) << @intCast(float_bits - 1);
4044 cast_ty,4156 const bitwise_rhs = try o.builder.splatValue(cast_ty, try o.builder.intConst(int_ty, switch (op) {
4045 try o.builder.intConst(int_ty, @as(u128, 1) << @intCast(float_bits - 1)),4157 else => unreachable,
4046 );4158 .neg => sign_bit,
4047 const bitcasted_operand = try self.wip.cast(.bitcast, params[0], cast_ty, "");4159 .fabs => sign_bit - 1,
4048 const result = try self.wip.bin(.xor, bitcasted_operand, sign_mask, "");4160 }));
4049 return self.wip.cast(.bitcast, result, llvm_ty, "");4161 const bitcasted_operand = try fg.wip.cast(.bitcast, params[0], cast_ty, "");
4162 const result = try fg.wip.bin(switch (op) {
4163 else => unreachable,
4164 .neg => .xor,
4165 .fabs => .@"and",
4166 }, bitcasted_operand, bitwise_rhs, "");
4167 const llvm_ty = try o.lowerType(ty, .as_value);
4168 return fg.wip.cast(.bitcast, result, llvm_ty, "");
4050 },4169 },
4051 .add, .sub, .div, .mul => try o.builder.strtabStringFmt("__{s}{s}f3", .{4170 .add, .sub, .div, .mul => try o.builder.strtabStringFmt("__{s}{s}f3", .{
4052 @tagName(op), compilerRtFloatAbbrev(float_bits),4171 @tagName(op), compilerRtFloatAbbrev(target, float_bits),
4053 }),4172 }),
4054 .ceil,4173 .ceil,
4055 .cos,4174 .cos,
4056 .exp,4175 .exp,
4057 .exp2,4176 .exp2,
4058 .fabs,
4059 .floor,4177 .floor,
4060 .fma,4178 .fma,
4061 .fmax,4179 .fmax,
...@@ -4073,27 +4191,27 @@ fn buildFloatOp(...@@ -4073,27 +4191,27 @@ fn buildFloatOp(
4073 libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits),4191 libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits),
4074 }),4192 }),
4075 };4193 };
4194 return fg.buildElementwiseCall(fn_name, .{
4195 .cc = target.cCallingConvention().?,
4196 .param_types = &@as([params_len]InternPool.Index, @splat(scalar_ty.toIntern())),
4197 .return_type = scalar_ty.toIntern(),
4198 }, &params, if (ty.isVector(zcu)) ty.vectorLen(zcu) else null);
4199}
40764200
4077 const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value);4201/// Creates a floating point cast operation by lowering to the specified softfloat routine.
4078 const libc_fn = try o.getLibcFunction(4202fn buildFloatCastCall(
4079 fn_name,4203 fg: *FuncGen,
4080 @as([3]Builder.Type, @splat(scalar_llvm_ty))[0..params.len],4204 dest_ty: Type,
4081 scalar_llvm_ty,4205 fn_name: Builder.StrtabString,
4082 );4206 operand_ty: Type,
4083 if (ty.zigTypeTag(zcu) == .vector) {4207 operand: Builder.Value,
4084 const result = try o.builder.poisonValue(llvm_ty);4208) Allocator.Error!Builder.Value {
4085 return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(zcu));4209 const zcu = fg.object.zcu;
4086 }4210 return fg.buildElementwiseCall(fn_name, .{
40874211 .cc = zcu.getTarget().cCallingConvention().?,
4088 return self.wip.call(4212 .param_types = &.{operand_ty.scalarType(zcu).toIntern()},
4089 fast.toCallKind(),4213 .return_type = dest_ty.scalarType(zcu).toIntern(),
4090 .ccc,4214 }, &.{operand}, if (operand_ty.isVector(zcu)) operand_ty.vectorLen(zcu) else null);
4091 .none,
4092 libc_fn.typeOf(&o.builder),
4093 libc_fn.toValue(&o.builder),
4094 &params,
4095 "",
4096 );
4097}4215}
40984216
4099fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {4217fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
...@@ -4129,7 +4247,7 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Buil...@@ -4129,7 +4247,7 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Buil
4129 const dest_ty = self.typeOfIndex(inst);4247 const dest_ty = self.typeOfIndex(inst);
4130 assert(isByRef(dest_ty, zcu)); // auto structs are by-ref4248 assert(isByRef(dest_ty, zcu)); // auto structs are by-ref
41314249
4132 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .by_value), "");4250 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .as_value), "");
41334251
4134 const result = try self.wip.bin(.shl, lhs, casted_rhs, "");4252 const result = try self.wip.bin(.shl, lhs, casted_rhs, "");
4135 const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu))4253 const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu))
...@@ -4196,7 +4314,7 @@ fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val...@@ -4196,7 +4314,7 @@ fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val
4196 }4314 }
4197 const lhs_scalar_ty = lhs_ty.scalarType(zcu);4315 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
41984316
4199 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .by_value), "");4317 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .as_value), "");
4200 return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu))4318 return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu))
4201 .@"shl nsw"4319 .@"shl nsw"
4202 else4320 else
...@@ -4217,7 +4335,7 @@ fn airShl(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {...@@ -4217,7 +4335,7 @@ fn airShl(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4217 // features which we do not use. Therefore this branch is currently impossible.4335 // features which we do not use. Therefore this branch is currently impossible.
4218 unreachable;4336 unreachable;
4219 }4337 }
4220 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .by_value), "");4338 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .as_value), "");
4221 return self.wip.bin(.shl, lhs, casted_rhs, "");4339 return self.wip.bin(.shl, lhs, casted_rhs, "");
4222}4340}
42234341
...@@ -4231,8 +4349,8 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -4231,8 +4349,8 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
42314349
4232 const lhs_ty = self.typeOf(bin_op.lhs);4350 const lhs_ty = self.typeOf(bin_op.lhs);
4233 const lhs_info = lhs_ty.intInfo(zcu);4351 const lhs_info = lhs_ty.intInfo(zcu);
4234 const llvm_lhs_ty = try o.lowerType(lhs_ty, .by_value);4352 const llvm_lhs_ty = try o.lowerType(lhs_ty, .as_value);
4235 const llvm_lhs_scalar_ty = try o.lowerType(lhs_ty.scalarType(zcu), .by_value);4353 const llvm_lhs_scalar_ty = try o.lowerType(lhs_ty.scalarType(zcu), .as_value);
42364354
4237 const rhs_ty = self.typeOf(bin_op.rhs);4355 const rhs_ty = self.typeOf(bin_op.rhs);
4238 if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) {4356 if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) {
...@@ -4242,8 +4360,8 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -4242,8 +4360,8 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
4242 }4360 }
4243 const rhs_info = rhs_ty.intInfo(zcu);4361 const rhs_info = rhs_ty.intInfo(zcu);
4244 assert(rhs_info.signedness == .unsigned);4362 assert(rhs_info.signedness == .unsigned);
4245 const llvm_rhs_ty = try o.lowerType(rhs_ty, .by_value);4363 const llvm_rhs_ty = try o.lowerType(rhs_ty, .as_value);
4246 const llvm_rhs_scalar_ty = try o.lowerType(rhs_ty.scalarType(zcu), .by_value);4364 const llvm_rhs_scalar_ty = try o.lowerType(rhs_ty.scalarType(zcu), .as_value);
42474365
4248 const result = try self.wip.callIntrinsic(4366 const result = try self.wip.callIntrinsic(
4249 .normal,4367 .normal,
...@@ -4319,7 +4437,7 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) Allocator.Error!...@@ -4319,7 +4437,7 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) Allocator.Error!
4319 }4437 }
4320 const lhs_scalar_ty = lhs_ty.scalarType(zcu);4438 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
43214439
4322 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .by_value), "");4440 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .as_value), "");
4323 const is_signed_int = lhs_scalar_ty.isSignedInt(zcu);4441 const is_signed_int = lhs_scalar_ty.isSignedInt(zcu);
43244442
4325 return self.wip.bin(if (is_exact)4443 return self.wip.bin(if (is_exact)
...@@ -4340,7 +4458,7 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {...@@ -4340,7 +4458,7 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4340 .normal,4458 .normal,
4341 .none,4459 .none,
4342 .abs,4460 .abs,
4343 &.{try o.lowerType(operand_ty, .by_value)},4461 &.{try o.lowerType(operand_ty, .as_value)},
4344 &.{ operand, .false },4462 &.{ operand, .false },
4345 "",4463 "",
4346 ),4464 ),
...@@ -4354,7 +4472,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!...@@ -4354,7 +4472,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!
4354 const zcu = o.zcu;4472 const zcu = o.zcu;
4355 const ty_op = fg.air.instructions.items(.data)[@backingInt(inst)].ty_op;4473 const ty_op = fg.air.instructions.items(.data)[@backingInt(inst)].ty_op;
4356 const dest_ty = fg.typeOfIndex(inst);4474 const dest_ty = fg.typeOfIndex(inst);
4357 const dest_llvm_ty = try o.lowerType(dest_ty, .by_value);4475 const dest_llvm_ty = try o.lowerType(dest_ty, .as_value);
4358 const operand = try fg.resolveInst(ty_op.operand);4476 const operand = try fg.resolveInst(ty_op.operand);
4359 const operand_ty = fg.typeOf(ty_op.operand);4477 const operand_ty = fg.typeOf(ty_op.operand);
4360 const operand_info = operand_ty.intInfo(zcu);4478 const operand_info = operand_ty.intInfo(zcu);
...@@ -4382,8 +4500,8 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!...@@ -4382,8 +4500,8 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!
43824500
4383 if (!have_min_check and !have_max_check) break :bounds_check;4501 if (!have_min_check and !have_max_check) break :bounds_check;
43844502
4385 const operand_llvm_ty = try o.lowerType(operand_ty, .by_value);4503 const operand_llvm_ty = try o.lowerType(operand_ty, .as_value);
4386 const operand_scalar_llvm_ty = try o.lowerType(operand_scalar, .by_value);4504 const operand_scalar_llvm_ty = try o.lowerType(operand_scalar, .as_value);
43874505
4388 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;4506 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;
4389 assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector));4507 assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector));
...@@ -4461,7 +4579,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!...@@ -4461,7 +4579,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!
4461fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {4579fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4462 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;4580 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;
4463 const operand = try self.resolveInst(ty_op.operand);4581 const operand = try self.resolveInst(ty_op.operand);
4464 const dest_llvm_ty = try self.object.lowerType(self.typeOfIndex(inst), .by_value);4582 const dest_llvm_ty = try self.object.lowerType(self.typeOfIndex(inst), .as_value);
4465 return self.wip.cast(.trunc, operand, dest_llvm_ty, "");4583 return self.wip.cast(.trunc, operand, dest_llvm_ty, "");
4466}4584}
44674585
...@@ -4471,32 +4589,20 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Valu...@@ -4471,32 +4589,20 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Valu
4471 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;4589 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;
4472 const operand = try self.resolveInst(ty_op.operand);4590 const operand = try self.resolveInst(ty_op.operand);
4473 const operand_ty = self.typeOf(ty_op.operand);4591 const operand_ty = self.typeOf(ty_op.operand);
4592 const operand_scalar_ty = operand_ty.scalarType(zcu);
4474 const dest_ty = self.typeOfIndex(inst);4593 const dest_ty = self.typeOfIndex(inst);
4594 const dest_scalar_ty = dest_ty.scalarType(zcu);
4475 const target = zcu.getTarget();4595 const target = zcu.getTarget();
44764596
4477 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {4597 if (intrinsicsAllowed(.compiler_rt, dest_scalar_ty, target) and
4478 return self.wip.cast(.fptrunc, operand, try o.lowerType(dest_ty, .by_value), "");4598 intrinsicsAllowed(.compiler_rt, operand_scalar_ty, target))
4479 } else {4599 return self.wip.cast(.fptrunc, operand, try o.lowerType(dest_ty, .as_value), "");
4480 const operand_llvm_ty = try o.lowerType(operand_ty, .by_value);4600 const dest_bits = dest_scalar_ty.floatBits(target);
4481 const dest_llvm_ty = try o.lowerType(dest_ty, .by_value);4601 const src_bits = operand_scalar_ty.floatBits(target);
44824602 const fn_name = try o.builder.strtabStringFmt("__trunc{s}f{s}f2", .{
4483 const dest_bits = dest_ty.floatBits(target);4603 compilerRtFloatAbbrev(target, src_bits), compilerRtFloatAbbrev(target, dest_bits),
4484 const src_bits = operand_ty.floatBits(target);4604 });
4485 const fn_name = try o.builder.strtabStringFmt("__trunc{s}f{s}f2", .{4605 return self.buildFloatCastCall(dest_ty, fn_name, operand_ty, operand);
4486 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),
4487 });
4488
4489 const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);
4490 return self.wip.call(
4491 .normal,
4492 .ccc,
4493 .none,
4494 libc_fn.typeOf(&o.builder),
4495 libc_fn.toValue(&o.builder),
4496 &.{operand},
4497 "",
4498 );
4499 }
4500}4606}
45014607
4502fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {4608fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
...@@ -4505,38 +4611,20 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -4505,38 +4611,20 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
4505 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;4611 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;
4506 const operand = try self.resolveInst(ty_op.operand);4612 const operand = try self.resolveInst(ty_op.operand);
4507 const operand_ty = self.typeOf(ty_op.operand);4613 const operand_ty = self.typeOf(ty_op.operand);
4614 const operand_scalar_ty = operand_ty.scalarType(zcu);
4508 const dest_ty = self.typeOfIndex(inst);4615 const dest_ty = self.typeOfIndex(inst);
4616 const dest_scalar_ty = dest_ty.scalarType(zcu);
4509 const target = zcu.getTarget();4617 const target = zcu.getTarget();
45104618
4511 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {4619 if (intrinsicsAllowed(.compiler_rt, dest_scalar_ty, target) and
4512 return self.wip.cast(.fpext, operand, try o.lowerType(dest_ty, .by_value), "");4620 intrinsicsAllowed(.compiler_rt, operand_scalar_ty, target))
4513 } else {4621 return self.wip.cast(.fpext, operand, try o.lowerType(dest_ty, .as_value), "");
4514 const operand_llvm_ty = try o.lowerType(operand_ty, .by_value);4622 const dest_bits = dest_scalar_ty.floatBits(target);
4515 const dest_llvm_ty = try o.lowerType(dest_ty, .by_value);4623 const src_bits = operand_scalar_ty.floatBits(target);
45164624 const fn_name = try o.builder.strtabStringFmt("__extend{s}f{s}f2", .{
4517 const dest_bits = dest_ty.scalarType(zcu).floatBits(target);4625 compilerRtFloatAbbrev(target, src_bits), compilerRtFloatAbbrev(target, dest_bits),
4518 const src_bits = operand_ty.scalarType(zcu).floatBits(target);4626 });
4519 const fn_name = try o.builder.strtabStringFmt("__extend{s}f{s}f2", .{4627 return self.buildFloatCastCall(dest_ty, fn_name, operand_ty, operand);
4520 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),
4521 });
4522
4523 const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);
4524 if (dest_ty.isVector(zcu)) return self.buildElementwiseCall(
4525 libc_fn,
4526 &.{operand},
4527 try o.builder.poisonValue(dest_llvm_ty),
4528 dest_ty.vectorLen(zcu),
4529 );
4530 return self.wip.call(
4531 .normal,
4532 .ccc,
4533 .none,
4534 libc_fn.typeOf(&o.builder),
4535 libc_fn.toValue(&o.builder),
4536 &.{operand},
4537 "",
4538 );
4539 }
4540}4628}
45414629
4542fn airBitCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value {4630fn airBitCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value {
...@@ -4558,28 +4646,161 @@ fn airBitCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!...@@ -4558,28 +4646,161 @@ fn airBitCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!
4558 // * bool/int/float <-> bool/int/float4646 // * bool/int/float <-> bool/int/float
4559 // * `@Vector(n, A)` <-> `@Vector(n, B)`4647 // * `@Vector(n, A)` <-> `@Vector(n, B)`
4560 //4648 //
4561 // All of these cases can be handled by LLVM's `bitcast` instruction.4649 // Most of these cases can be handled by LLVM's `bitcast` instruction, except when
4650 // a non-native type like `f80` is used.
45624651
4563 assert(!isByRef(operand_ty, zcu));4652 if (isByRef(operand_ty, zcu)) {
4564 assert(!isByRef(dest_ty, zcu));4653 const operand_scalar_ty = operand_ty.scalarType(zcu);
4654 const target = zcu.getTarget();
4655 const bits = operand_scalar_ty.floatBits(target);
4656 const dest_scalar_ty = dest_ty.scalarType(zcu);
4657 if (isByRef(dest_ty, zcu)) {
4658 assert(dest_scalar_ty.floatBits(target) == bits);
4659 return operand;
4660 }
4661 assert(dest_scalar_ty.intInfo(zcu).bits == bits);
45654662
4566 const llvm_dest_ty = try o.lowerType(dest_ty, .by_value);4663 const len = if (operand_ty.toIntern() != operand_scalar_ty.toIntern())
4567 const result = try fg.wip.cast(.bitcast, operand, llvm_dest_ty, "");4664 operand_ty.vectorLen(zcu)
4568 if (safety and dest_ty.zigTypeTag(zcu) == .@"enum" and !dest_ty.isNonexhaustiveEnum(zcu)) {4665 else
4569 const llvm_fn = try o.getIsNamedEnumValueFunction(dest_ty);4666 null;
4570 const is_valid_enum_val = try fg.wip.call(4667 const operand_scalar_size = operand_scalar_ty.abiSize(zcu);
4571 .normal,4668 var result = if (len) |_|
4572 .fastcc,4669 try o.builder.poisonValue(try o.lowerType(dest_ty, .as_value))
4573 .none,4670 else
4574 llvm_fn.typeOf(&o.builder),4671 undefined;
4575 llvm_fn.toValue(&o.builder),4672 for (0..len orelse 1) |index| {
4576 &.{result},4673 const result_elem = result_elem: switch (bits) {
4577 "",4674 else => unreachable,
4578 );4675 80 => {
4579 const fail_block = try fg.wip.block(1, "ValidEnumFail");4676 const f80_layout = o.softF80Layout(.{}) catch unreachable;
4580 const ok_block = try fg.wip.block(1, "ValidEnumOk");4677 const mantissa = try fg.load(
4581 _ = try fg.wip.brCond(is_valid_enum_val, ok_block, fail_block, .none);4678 try fg.ptraddConst(operand, operand_scalar_size * index + f80_layout.mantissa_offset),
4582 fg.wip.cursor = .{ .block = fail_block };4679 f80_layout.alignment.offset(f80_layout.mantissa_offset),
4680 .u64,
4681 .normal,
4682 );
4683 const exponent = try fg.load(
4684 try fg.ptraddConst(operand, operand_scalar_size * index + f80_layout.exponent_offset),
4685 f80_layout.alignment.offset(f80_layout.exponent_offset),
4686 .u16,
4687 .normal,
4688 );
4689 const casted_mantissa = try fg.wip.cast(.zext, mantissa, .i80, "bitCast.casted_mantissa");
4690 const casted_exponent = try fg.wip.cast(.zext, exponent, .i80, "bitCast.casted_exponent");
4691 const shifted_exponent = try fg.wip.bin(.@"shl nuw", casted_exponent, try o.builder.intValue(.i80, 64), "bitCast.shifted_exponent");
4692 break :result_elem try fg.wip.bin(.@"or", casted_mantissa, shifted_exponent, "bitCast.result_elem");
4693 },
4694 128 => {
4695 const f128_layout = o.softF128Layout(.{}) catch unreachable;
4696 const lo = try fg.load(
4697 try fg.ptraddConst(operand, operand_scalar_size * index + f128_layout.lo_offset),
4698 f128_layout.alignment.offset(f128_layout.lo_offset),
4699 .u64,
4700 .normal,
4701 );
4702 const hi = try fg.load(
4703 try fg.ptraddConst(operand, operand_scalar_size * index + f128_layout.hi_offset),
4704 f128_layout.alignment.offset(f128_layout.hi_offset),
4705 .u64,
4706 .normal,
4707 );
4708 const casted_lo = try fg.wip.cast(.zext, lo, .i128, "bitCast.casted_lo");
4709 const casted_hi = try fg.wip.cast(.zext, hi, .i128, "bitCast.casted_hi");
4710 const shifted_hi = try fg.wip.bin(.@"shl nuw", casted_hi, try o.builder.intValue(.i128, 64), "bitCast.shifted_hi");
4711 break :result_elem try fg.wip.bin(.@"or", casted_lo, shifted_hi, "bitCast.result_elem");
4712 },
4713 };
4714 result = if (len) |_|
4715 try fg.wip.insertElement(result, result_elem, try o.builder.intValue(.i32, index), "elementwise.result")
4716 else
4717 result_elem;
4718 }
4719 return result;
4720 }
4721
4722 if (isByRef(dest_ty, zcu)) {
4723 const dest_scalar_ty = dest_ty.scalarType(zcu);
4724 const bits = dest_scalar_ty.floatBits(zcu.getTarget());
4725 assert(dest_scalar_ty.isRuntimeFloat());
4726 const operand_scalar_ty = operand_ty.scalarType(zcu);
4727 assert(operand_scalar_ty.intInfo(zcu).bits == bits);
4728
4729 const len = if (operand_ty.toIntern() != operand_scalar_ty.toIntern())
4730 operand_ty.vectorLen(zcu)
4731 else
4732 null;
4733 const operand_scalar_size = operand_scalar_ty.abiSize(zcu);
4734 const result_ptr = try fg.buildZigAlloca(dest_ty, .none);
4735 for (0..len orelse 1) |index| {
4736 const operand_elem = if (len) |_|
4737 try fg.wip.extractElement(operand, try o.builder.intValue(.i32, index), "elementwise.operand_elem")
4738 else
4739 operand;
4740 switch (bits) {
4741 else => unreachable,
4742 80 => {
4743 const f80_layout = o.softF80Layout(.{}) catch unreachable;
4744 const mantissa = try fg.wip.cast(.trunc, operand_elem, .i64, "bitCast.mantissa");
4745 const shifted_exponent = try fg.wip.bin(.lshr, operand_elem, try o.builder.intValue(.i80, 64), "bitCast.shifted_exponent");
4746 const exponent = try fg.wip.cast(.@"trunc nuw", shifted_exponent, .i16, "bitCast.exponent");
4747 try fg.store(
4748 try fg.ptraddConst(result_ptr, operand_scalar_size * index + f80_layout.mantissa_offset),
4749 f80_layout.alignment.offset(f80_layout.mantissa_offset),
4750 mantissa,
4751 .u64,
4752 .normal,
4753 );
4754 try fg.store(
4755 try fg.ptraddConst(result_ptr, operand_scalar_size * index + f80_layout.exponent_offset),
4756 f80_layout.alignment.offset(f80_layout.exponent_offset),
4757 exponent,
4758 .u16,
4759 .normal,
4760 );
4761 },
4762 128 => {
4763 const f128_layout = o.softF128Layout(.{}) catch unreachable;
4764 const lo = try fg.wip.cast(.trunc, operand_elem, .i64, "bitCast.lo");
4765 const shifted_hi = try fg.wip.bin(.lshr, operand_elem, try o.builder.intValue(.i128, 64), "bitCast.shifted_hi");
4766 const hi = try fg.wip.cast(.@"trunc nuw", shifted_hi, .i64, "bitCast.hi");
4767 try fg.store(
4768 try fg.ptraddConst(result_ptr, operand_scalar_size * index + f128_layout.lo_offset),
4769 f128_layout.alignment.offset(f128_layout.lo_offset),
4770 lo,
4771 .u64,
4772 .normal,
4773 );
4774 try fg.store(
4775 try fg.ptraddConst(result_ptr, operand_scalar_size * index + f128_layout.hi_offset),
4776 f128_layout.alignment.offset(f128_layout.hi_offset),
4777 hi,
4778 .u64,
4779 .normal,
4780 );
4781 },
4782 }
4783 }
4784 return result_ptr;
4785 }
4786
4787 const llvm_dest_ty = try o.lowerType(dest_ty, .as_value);
4788 const result = try fg.wip.cast(.bitcast, operand, llvm_dest_ty, "");
4789 if (safety and dest_ty.zigTypeTag(zcu) == .@"enum" and !dest_ty.isNonexhaustiveEnum(zcu)) {
4790 const llvm_fn = try o.getIsNamedEnumValueFunction(dest_ty);
4791 const is_valid_enum_val = try fg.wip.call(
4792 .normal,
4793 .fastcc,
4794 .none,
4795 llvm_fn.typeOf(&o.builder),
4796 llvm_fn.toValue(&o.builder),
4797 &.{result},
4798 "",
4799 );
4800 const fail_block = try fg.wip.block(1, "ValidEnumFail");
4801 const ok_block = try fg.wip.block(1, "ValidEnumOk");
4802 _ = try fg.wip.brCond(is_valid_enum_val, ok_block, fail_block, .none);
4803 fg.wip.cursor = .{ .block = fail_block };
4583 try fg.buildSimplePanic(.invalid_enum_value);4804 try fg.buildSimplePanic(.invalid_enum_value);
4584 fg.wip.cursor = .{ .block = ok_block };4805 fg.wip.cursor = .{ .block = ok_block };
4585 }4806 }
...@@ -4606,7 +4827,7 @@ fn airPtrFromInt(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val...@@ -4606,7 +4827,7 @@ fn airPtrFromInt(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val
4606 assert(dest_ty.scalarType(zcu).isPtrAtRuntime(zcu));4827 assert(dest_ty.scalarType(zcu).isPtrAtRuntime(zcu));
46074828
4608 const operand = try fg.resolveInst(ty_op.operand);4829 const operand = try fg.resolveInst(ty_op.operand);
4609 const llvm_dest_ty = try o.lowerType(dest_ty, .by_value);4830 const llvm_dest_ty = try o.lowerType(dest_ty, .as_value);
4610 return fg.wip.cast(.inttoptr, operand, llvm_dest_ty, "");4831 return fg.wip.cast(.inttoptr, operand, llvm_dest_ty, "");
4611}4832}
46124833
...@@ -4620,7 +4841,7 @@ fn airIntFromPtr(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val...@@ -4620,7 +4841,7 @@ fn airIntFromPtr(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val
4620 assert(dest_ty.scalarType(zcu).toIntern() == .usize_type);4841 assert(dest_ty.scalarType(zcu).toIntern() == .usize_type);
46214842
4622 const operand = try fg.resolveInst(ty_op.operand);4843 const operand = try fg.resolveInst(ty_op.operand);
4623 const llvm_dest_ty = try o.lowerType(dest_ty, .by_value);4844 const llvm_dest_ty = try o.lowerType(dest_ty, .as_value);
4624 return fg.wip.cast(.ptrtoint, operand, llvm_dest_ty, "");4845 return fg.wip.cast(.ptrtoint, operand, llvm_dest_ty, "");
4625}4846}
46264847
...@@ -4730,7 +4951,7 @@ fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -4730,7 +4951,7 @@ fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
4730 const ptr_align = ptr_ty.ptrAlignment(zcu);4951 const ptr_align = ptr_ty.ptrAlignment(zcu);
4731 const elem_ty = ptr_ty.childType(zcu);4952 const elem_ty = ptr_ty.childType(zcu);
4732 if (!elem_ty.hasRuntimeBits(zcu)) {4953 if (!elem_ty.hasRuntimeBits(zcu)) {
4733 return (try o.lowerPtrToVoid(ptr_align, ptr_ty.ptrAddressSpace(zcu))).toValue();4954 return (try o.lowerPtrToVoid(ptr_align.toLlvm(), ptr_ty.ptrAddressSpace(zcu))).toValue();
4734 }4955 }
4735 return self.buildZigAlloca(elem_ty, ptr_align);4956 return self.buildZigAlloca(elem_ty, ptr_align);
4736}4957}
...@@ -4743,7 +4964,7 @@ fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -4743,7 +4964,7 @@ fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
4743 const ptr_align = ptr_ty.ptrAlignment(zcu);4964 const ptr_align = ptr_ty.ptrAlignment(zcu);
4744 const elem_ty = ptr_ty.childType(zcu);4965 const elem_ty = ptr_ty.childType(zcu);
4745 if (!elem_ty.hasRuntimeBits(zcu)) {4966 if (!elem_ty.hasRuntimeBits(zcu)) {
4746 return (try o.lowerPtrToVoid(ptr_align, ptr_ty.ptrAddressSpace(zcu))).toValue();4967 return (try o.lowerPtrToVoid(ptr_align.toLlvm(), ptr_ty.ptrAddressSpace(zcu))).toValue();
4747 }4968 }
4748 return self.buildZigAlloca(elem_ty, ptr_align);4969 return self.buildZigAlloca(elem_ty, ptr_align);
4749}4970}
...@@ -4754,10 +4975,7 @@ fn buildZigAlloca(fg: *FuncGen, ty: Type, @"align": InternPool.Alignment) Alloca...@@ -4754,10 +4975,7 @@ fn buildZigAlloca(fg: *FuncGen, ty: Type, @"align": InternPool.Alignment) Alloca
4754 .none => ty.abiAlignment(o.zcu),4975 .none => ty.abiAlignment(o.zcu),
4755 else => |a| a,4976 else => |a| a,
4756 };4977 };
4757 return fg.buildAlloca(4978 return fg.buildAlloca(try o.lowerType(ty, .in_memory), resolved_align.toLlvm());
4758 try o.lowerType(ty, .in_memory),
4759 resolved_align.toLlvm(),
4760 );
4761}4979}
47624980
4763/// Unlike `WipFunction.alloca`, this puts the alloca instruction at the top of the function.4981/// Unlike `WipFunction.alloca`, this puts the alloca instruction at the top of the function.
...@@ -4832,7 +5050,7 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu...@@ -4832,7 +5050,7 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu
4832 return .none;5050 return .none;
4833 }5051 }
48345052
4835 const len = try o.builder.intValue(try o.lowerType(.usize, .by_value), elem_ty.abiSize(zcu));5053 const len = try o.builder.intValue(try o.lowerType(.usize, .as_value), elem_ty.abiSize(zcu));
4836 _ = try fg.wip.callMemSet(5054 _ = try fg.wip.callMemSet(
4837 ptr,5055 ptr,
4838 ptr_alignment.toLlvm(),5056 ptr_alignment.toLlvm(),
...@@ -4850,24 +5068,31 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu...@@ -4850,24 +5068,31 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu
4850 const elem = try fg.resolveInst(bin_op.rhs);5068 const elem = try fg.resolveInst(bin_op.rhs);
48515069
4852 if (ptr_info.flags.vector_index != .none) {5070 if (ptr_info.flags.vector_index != .none) {
4853 // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`.5071 if (isByRef(elem_ty, zcu)) {
4854 const vec_ty = try fg.pt.vectorType(.{5072 const offset = @backingInt(ptr_info.flags.vector_index) * elem_ty.abiSize(zcu);
4855 .len = ptr_info.packed_offset.host_size,5073 const elem_ptr = try fg.ptraddConst(ptr, offset);
4856 .child = elem_ty.toIntern(),5074 try fg.store(elem_ptr, ptr_alignment.offset(offset), elem, elem_ty, access_kind);
4857 });5075 } else {
5076 // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`.
5077 const vec_ty = try fg.pt.vectorType(.{
5078 .len = ptr_info.packed_offset.host_size,
5079 .child = elem_ty.toIntern(),
5080 });
5081
5082 const loaded_vector = try fg.load(ptr, ptr_alignment, vec_ty, access_kind);
5083 const index_val = try o.builder.intValue(.i32, ptr_info.flags.vector_index);
5084 const modified_vector = try fg.wip.insertElement(loaded_vector, elem, index_val, "");
48585085
4859 const loaded_vector = try fg.load(ptr, ptr_alignment, vec_ty, access_kind);5086 try fg.store(ptr, ptr_alignment, modified_vector, vec_ty, access_kind);
4860 const index_val = try o.builder.intValue(.i32, ptr_info.flags.vector_index);5087 }
4861 const modified_vector = try fg.wip.insertElement(loaded_vector, elem, index_val, "");
48625088
4863 try fg.store(ptr, ptr_alignment, modified_vector, vec_ty, access_kind);
4864 return .none;5089 return .none;
4865 }5090 }
48665091
4867 if (ptr_info.packed_offset.host_size != 0) {5092 if (ptr_info.packed_offset.host_size != 0) {
4868 // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`.5093 // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`.
4869 const backing_int_ty = try fg.pt.intType(.unsigned, @intCast(ptr_info.packed_offset.host_size * 8));5094 const backing_int_ty = try fg.pt.intType(.unsigned, @intCast(ptr_info.packed_offset.host_size * 8));
4870 const llvm_backing_int_ty = try o.lowerType(backing_int_ty, .by_value);5095 const llvm_backing_int_ty = try o.lowerType(backing_int_ty, .as_value);
48715096
4872 const backing_int_val = try fg.load(ptr, ptr_alignment, backing_int_ty, access_kind);5097 const backing_int_val = try fg.load(ptr, ptr_alignment, backing_int_ty, access_kind);
48735098
...@@ -4927,32 +5152,98 @@ fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {...@@ -4927,32 +5152,98 @@ fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4927 if (ptr_info.flags.is_volatile) .@"volatile" else .normal;5152 if (ptr_info.flags.is_volatile) .@"volatile" else .normal;
49285153
4929 if (ptr_info.flags.vector_index != .none) {5154 if (ptr_info.flags.vector_index != .none) {
4930 // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`.5155 if (isByRef(elem_ty, zcu)) {
4931 const vec_ty = try fg.pt.vectorType(.{5156 const elem_size = elem_ty.abiSize(zcu);
4932 .len = ptr_info.packed_offset.host_size,5157 const offset = @backingInt(ptr_info.flags.vector_index) * elem_size;
4933 .child = elem_ty.toIntern(),5158 const elem_ptr = try fg.ptraddConst(ptr, offset);
4934 });5159 return fg.load(elem_ptr, ptr_align.offset(offset), elem_ty, access_kind);
4935 const vector_val = try fg.load(ptr, ptr_align, vec_ty, access_kind);5160 } else {
4936 const index_val = try o.builder.intValue(.i32, ptr_info.flags.vector_index);5161 // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`.
4937 return fg.wip.extractElement(vector_val, index_val, "");5162 const vec_ty = try fg.pt.vectorType(.{
5163 .len = ptr_info.packed_offset.host_size,
5164 .child = elem_ty.toIntern(),
5165 });
5166 const vector_val = try fg.load(ptr, ptr_align, vec_ty, access_kind);
5167 const index_val = try o.builder.intValue(.i32, ptr_info.flags.vector_index);
5168 return fg.wip.extractElement(vector_val, index_val, "");
5169 }
4938 }5170 }
49395171
4940 if (ptr_info.packed_offset.host_size == 0) {5172 if (ptr_info.packed_offset.host_size == 0) {
4941 return fg.load(ptr, ptr_align, elem_ty, access_kind);5173 return fg.load(ptr, ptr_align, elem_ty, access_kind);
4942 }5174 }
49435175
4944 assert(!isByRef(elem_ty, zcu)); // all packable types are by-val
4945
4946 // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`.5176 // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`.
4947 const backing_int_ty = try fg.pt.intType(.unsigned, @intCast(ptr_info.packed_offset.host_size * 8));5177 const backing_int_ty = try fg.pt.intType(.unsigned, @intCast(ptr_info.packed_offset.host_size * 8));
4948 const llvm_backing_int_ty = try o.lowerType(backing_int_ty, .by_value);5178 const llvm_backing_int_ty = try o.lowerType(backing_int_ty, .as_value);
49495179
4950 const backing_int_val = try fg.load(ptr, ptr_align, backing_int_ty, .normal);5180 const backing_int_val = try fg.load(ptr, ptr_align, backing_int_ty, .normal);
49515181
4952 const elem_bits = ptr_ty.childType(zcu).bitSize(zcu);5182 const elem_bits = ptr_ty.childType(zcu).bitSize(zcu);
4953 const shift_amt = try o.builder.intValue(llvm_backing_int_ty, ptr_info.packed_offset.bit_offset);5183 const shift_amt = try o.builder.intValue(llvm_backing_int_ty, ptr_info.packed_offset.bit_offset);
4954 const shifted_value = try fg.wip.bin(.lshr, backing_int_val, shift_amt, "");5184 const shifted_value = try fg.wip.bin(.lshr, backing_int_val, shift_amt, "");
4955 const elem_llvm_ty = try o.lowerType(elem_ty, .by_value);5185
5186 if (isByRef(elem_ty, zcu)) {
5187 const result_ptr = try fg.buildZigAlloca(elem_ty, .none);
5188 switch (elem_ty.floatBits(zcu.getTarget())) {
5189 else => unreachable,
5190 80 => {
5191 const f80_layout = o.softF80Layout(.{}) catch unreachable;
5192 const mantissa = try fg.wip.cast(.trunc, shifted_value, .i64, "load.mantissa");
5193 const shifted_exponent = try fg.wip.bin(
5194 .lshr,
5195 backing_int_val,
5196 try o.builder.intValue(llvm_backing_int_ty, ptr_info.packed_offset.bit_offset + 64),
5197 "load.shifted_exponent",
5198 );
5199 const exponent = try fg.wip.cast(.trunc, shifted_exponent, .i16, "load.exponent");
5200
5201 try fg.store(
5202 try fg.ptraddConst(result_ptr, f80_layout.mantissa_offset),
5203 f80_layout.alignment.offset(f80_layout.mantissa_offset),
5204 mantissa,
5205 .u64,
5206 .normal,
5207 );
5208 try fg.store(
5209 try fg.ptraddConst(result_ptr, f80_layout.exponent_offset),
5210 f80_layout.alignment.offset(f80_layout.exponent_offset),
5211 exponent,
5212 .u16,
5213 .normal,
5214 );
5215 },
5216 128 => {
5217 const f128_layout = o.softF128Layout(.{}) catch unreachable;
5218 const lo = try fg.wip.cast(.trunc, shifted_value, .i64, "load.lo");
5219 const shifted_hi = try fg.wip.bin(
5220 .lshr,
5221 backing_int_val,
5222 try o.builder.intValue(llvm_backing_int_ty, ptr_info.packed_offset.bit_offset + 64),
5223 "load.shifted_hi",
5224 );
5225 const hi = try fg.wip.cast(.trunc, shifted_hi, .i64, "load.hi");
5226
5227 try fg.store(
5228 try fg.ptraddConst(result_ptr, f128_layout.lo_offset),
5229 f128_layout.alignment.offset(f128_layout.lo_offset),
5230 lo,
5231 .u64,
5232 .normal,
5233 );
5234 try fg.store(
5235 try fg.ptraddConst(result_ptr, f128_layout.hi_offset),
5236 f128_layout.alignment.offset(f128_layout.hi_offset),
5237 hi,
5238 .u64,
5239 .normal,
5240 );
5241 },
5242 }
5243 return result_ptr;
5244 }
5245
5246 const elem_llvm_ty = try o.lowerType(elem_ty, .as_value);
49565247
4957 if (elem_ty.zigTypeTag(zcu) == .float or elem_ty.zigTypeTag(zcu) == .vector) {5248 if (elem_ty.zigTypeTag(zcu) == .float or elem_ty.zigTypeTag(zcu) == .vector) {
4958 const same_size_int = try o.builder.intType(@intCast(elem_bits));5249 const same_size_int = try o.builder.intType(@intCast(elem_bits));
...@@ -5002,7 +5293,7 @@ fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.V...@@ -5002,7 +5293,7 @@ fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.V
5002fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {5293fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5003 _ = inst;5294 _ = inst;
5004 const o = self.object;5295 const o = self.object;
5005 const llvm_usize = try o.lowerType(.usize, .by_value);5296 const llvm_usize = try o.lowerType(.usize, .as_value);
5006 if (!target_util.supportsReturnAddress(self.object.zcu.getTarget(), self.ownerModule().optimize_mode)) {5297 if (!target_util.supportsReturnAddress(self.object.zcu.getTarget(), self.ownerModule().optimize_mode)) {
5007 // https://github.com/ziglang/zig/issues/119465298 // https://github.com/ziglang/zig/issues/11946
5008 return o.builder.intValue(llvm_usize, 0);5299 return o.builder.intValue(llvm_usize, 0);
...@@ -5014,7 +5305,7 @@ fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Valu...@@ -5014,7 +5305,7 @@ fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Valu
5014fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {5305fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5015 _ = inst;5306 _ = inst;
5016 const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, "");5307 const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, "");
5017 return self.wip.cast(.ptrtoint, result, try self.object.lowerType(.usize, .by_value), "");5308 return self.wip.cast(.ptrtoint, result, try self.object.lowerType(.usize, .as_value), "");
5018}5309}
50195310
5020fn airCmpxchg(5311fn airCmpxchg(
...@@ -5031,7 +5322,7 @@ fn airCmpxchg(...@@ -5031,7 +5322,7 @@ fn airCmpxchg(
5031 var expected_value = try self.resolveInst(extra.expected_value);5322 var expected_value = try self.resolveInst(extra.expected_value);
5032 var new_value = try self.resolveInst(extra.new_value);5323 var new_value = try self.resolveInst(extra.new_value);
5033 const operand_ty = ptr_ty.childType(zcu);5324 const operand_ty = ptr_ty.childType(zcu);
5034 const llvm_operand_ty = try o.lowerType(operand_ty, .by_value);5325 const llvm_operand_ty = try o.lowerType(operand_ty, .as_value);
5035 const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, false);5326 const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, false);
5036 if (llvm_abi_ty != .none) {5327 if (llvm_abi_ty != .none) {
5037 // operand needs widening and truncating5328 // operand needs widening and truncating
...@@ -5101,7 +5392,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va...@@ -5101,7 +5392,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va
5101 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);5392 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);
5102 const ordering = toLlvmAtomicOrdering(extra.ordering());5393 const ordering = toLlvmAtomicOrdering(extra.ordering());
5103 const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, op == .xchg);5394 const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, op == .xchg);
5104 const llvm_operand_ty = try o.lowerType(operand_ty, .by_value);5395 const llvm_operand_ty = try o.lowerType(operand_ty, .as_value);
51055396
5106 const access_kind: Builder.MemoryAccessKind =5397 const access_kind: Builder.MemoryAccessKind =
5107 if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;5398 if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
...@@ -5130,7 +5421,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va...@@ -5130,7 +5421,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va
51305421
5131 // If we are storing a pointer we need to convert to and from a plain old integer.5422 // If we are storing a pointer we need to convert to and from a plain old integer.
5132 const non_ptr_operand = switch (operand_ty.zigTypeTag(zcu)) {5423 const non_ptr_operand = switch (operand_ty.zigTypeTag(zcu)) {
5133 .pointer => try self.wip.cast(.ptrtoint, operand, try o.lowerType(.usize, .by_value), ""),5424 .pointer => try self.wip.cast(.ptrtoint, operand, try o.lowerType(.usize, .as_value), ""),
5134 else => operand,5425 else => operand,
5135 };5426 };
51365427
...@@ -5169,7 +5460,7 @@ fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.V...@@ -5169,7 +5460,7 @@ fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.V
5169 Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm();5460 Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm();
5170 const access_kind: Builder.MemoryAccessKind =5461 const access_kind: Builder.MemoryAccessKind =
5171 if (info.flags.is_volatile) .@"volatile" else .normal;5462 if (info.flags.is_volatile) .@"volatile" else .normal;
5172 const elem_llvm_ty = try o.lowerType(elem_ty, .by_value);5463 const elem_llvm_ty = try o.lowerType(elem_ty, .as_value);
51735464
5174 self.maybeMarkAllowZeroAccess(info);5465 self.maybeMarkAllowZeroAccess(info);
51755466
...@@ -5503,11 +5794,11 @@ fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic)...@@ -5503,11 +5794,11 @@ fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic)
5503 .normal,5794 .normal,
5504 .none,5795 .none,
5505 intrinsic,5796 intrinsic,
5506 &.{try o.lowerType(operand_ty, .by_value)},5797 &.{try o.lowerType(operand_ty, .as_value)},
5507 &.{ operand, .false },5798 &.{ operand, .false },
5508 "",5799 "",
5509 );5800 );
5510 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .by_value), "");5801 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .as_value), "");
5511}5802}
55125803
5513fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value {5804fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value {
...@@ -5521,11 +5812,11 @@ fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic)...@@ -5521,11 +5812,11 @@ fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic)
5521 .normal,5812 .normal,
5522 .none,5813 .none,
5523 intrinsic,5814 intrinsic,
5524 &.{try o.lowerType(operand_ty, .by_value)},5815 &.{try o.lowerType(operand_ty, .as_value)},
5525 &.{operand},5816 &.{operand},
5526 "",5817 "",
5527 );5818 );
5528 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .by_value), "");5819 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .as_value), "");
5529}5820}
55305821
5531fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {5822fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
...@@ -5538,7 +5829,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val...@@ -5538,7 +5829,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val
55385829
5539 const inst_ty = self.typeOfIndex(inst);5830 const inst_ty = self.typeOfIndex(inst);
5540 var operand = try self.resolveInst(ty_op.operand);5831 var operand = try self.resolveInst(ty_op.operand);
5541 var llvm_operand_ty = try o.lowerType(operand_ty, .by_value);5832 var llvm_operand_ty = try o.lowerType(operand_ty, .as_value);
55425833
5543 if (bits % 16 == 8) {5834 if (bits % 16 == 8) {
5544 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte5835 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
...@@ -5559,7 +5850,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val...@@ -5559,7 +5850,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val
55595850
5560 const result =5851 const result =
5561 try self.wip.callIntrinsic(.normal, .none, .bswap, &.{llvm_operand_ty}, &.{operand}, "");5852 try self.wip.callIntrinsic(.normal, .none, .bswap, &.{llvm_operand_ty}, &.{operand}, "");
5562 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .by_value), "");5853 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .as_value), "");
5563}5854}
55645855
5565fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {5856fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
...@@ -5579,7 +5870,7 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Bui...@@ -5579,7 +5870,7 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Bui
55795870
5580 for (0..names.len) |name_index| {5871 for (0..names.len) |name_index| {
5581 const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;5872 const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;
5582 const this_tag_int_value = try o.builder.intConst(try o.errorIntType(.by_value), err_int);5873 const this_tag_int_value = try o.builder.intConst(try o.errorIntType(.as_value), err_int);
5583 try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);5874 try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
5584 }5875 }
5585 self.wip.cursor = .{ .block = valid_block };5876 self.wip.cursor = .{ .block = valid_block };
...@@ -5638,7 +5929,7 @@ fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va...@@ -5638,7 +5929,7 @@ fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va
5638 const slice_ty = self.typeOfIndex(inst);5929 const slice_ty = self.typeOfIndex(inst);
56395930
5640 // If operand is small (e.g. `u8`), then signedness becomes a problem -- GEP always treats the index as signed.5931 // If operand is small (e.g. `u8`), then signedness becomes a problem -- GEP always treats the index as signed.
5641 const operand_usize = try self.wip.conv(.unsigned, operand, try o.lowerType(.usize, .by_value), "");5932 const operand_usize = try self.wip.conv(.unsigned, operand, try o.lowerType(.usize, .as_value), "");
56425933
5643 const error_name_table_ptr = try o.getErrorNameTable();5934 const error_name_table_ptr = try o.getErrorNameTable();
5644 const error_name_ptr = try self.ptraddScaled(error_name_table_ptr.toValue(&o.builder), operand_usize, slice_ty.abiSize(zcu));5935 const error_name_ptr = try self.ptraddScaled(error_name_table_ptr.toValue(&o.builder), operand_usize, slice_ty.abiSize(zcu));
...@@ -5649,7 +5940,7 @@ fn airSplat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value...@@ -5649,7 +5940,7 @@ fn airSplat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value
5649 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;5940 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;
5650 const scalar = try self.resolveInst(ty_op.operand);5941 const scalar = try self.resolveInst(ty_op.operand);
5651 const vector_ty = self.typeOfIndex(inst);5942 const vector_ty = self.typeOfIndex(inst);
5652 return self.wip.splatVector(try self.object.lowerType(vector_ty, .by_value), scalar, "");5943 return self.wip.splatVector(try self.object.lowerType(vector_ty, .as_value), scalar, "");
5653}5944}
56545945
5655fn airSelect(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {5946fn airSelect(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
...@@ -5672,9 +5963,9 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val...@@ -5672,9 +5963,9 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val
5672 const operand = try fg.resolveInst(unwrapped.operand);5963 const operand = try fg.resolveInst(unwrapped.operand);
5673 const mask = unwrapped.mask;5964 const mask = unwrapped.mask;
5674 const operand_ty = fg.typeOf(unwrapped.operand);5965 const operand_ty = fg.typeOf(unwrapped.operand);
5675 const llvm_operand_ty = try o.lowerType(operand_ty, .by_value);5966 const llvm_operand_ty = try o.lowerType(operand_ty, .as_value);
5676 const llvm_result_ty = try o.lowerType(unwrapped.result_ty, .by_value);5967 const llvm_result_ty = try o.lowerType(unwrapped.result_ty, .as_value);
5677 const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu), .by_value);5968 const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu), .as_value);
5678 const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty);5969 const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty);
5679 const llvm_poison_mask_elem = try o.builder.poisonConst(.i32);5970 const llvm_poison_mask_elem = try o.builder.poisonConst(.i32);
5680 const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32);5971 const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32);
...@@ -5704,7 +5995,7 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val...@@ -5704,7 +5995,7 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val
5704 .elem => llvm_poison_elem,5995 .elem => llvm_poison_elem,
5705 .value => |val| if (!Value.fromInterned(val).isUndef(zcu)) elem: {5996 .value => |val| if (!Value.fromInterned(val).isUndef(zcu)) elem: {
5706 any_defined_comptime_value = true;5997 any_defined_comptime_value = true;
5707 break :elem try o.lowerValue(val, .by_value);5998 break :elem try o.lowerValue(val, .as_value);
5708 } else llvm_poison_elem,5999 } else llvm_poison_elem,
5709 };6000 };
5710 }6001 }
...@@ -5776,7 +6067,7 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val...@@ -5776,7 +6067,7 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val
5776 const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst);6067 const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst);
57776068
5778 const mask = unwrapped.mask;6069 const mask = unwrapped.mask;
5779 const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu), .by_value);6070 const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu), .as_value);
5780 const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32);6071 const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32);
5781 const llvm_poison_mask_elem = try o.builder.poisonConst(.i32);6072 const llvm_poison_mask_elem = try o.builder.poisonConst(.i32);
57826073
...@@ -5848,95 +6139,25 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val...@@ -5848,95 +6139,25 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val
5848 );6139 );
5849}6140}
58506141
5851/// Reduce a vector by repeatedly applying `llvm_fn` to produce an accumulated result.6142fn airReduce(fg: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
5852///6143 const o = fg.object;
5853/// Equivalent to:
5854/// ```
5855/// var accum: T = init;
5856/// for (0..i) |i| {
5857/// accum = llvm_fn(accum, vec[i]);
5858/// }
5859/// // result is 'accum'
5860/// ```
5861fn buildReducedCall(
5862 self: *FuncGen,
5863 llvm_fn: Builder.Function.Index,
5864 operand_vector: Builder.Value,
5865 vector_len: usize,
5866 accum_init: Builder.Value,
5867) Allocator.Error!Builder.Value {
5868 const o = self.object;
5869 const llvm_usize_ty = try o.lowerType(.usize, .by_value);
5870 const llvm_vector_len = try o.builder.intValue(llvm_usize_ty, vector_len);
5871 const llvm_result_ty = accum_init.typeOfWip(&self.wip);
5872
5873 const entry_block = self.wip.cursor.block;
5874
5875 const cond_block = try self.wip.block(2, "ReduceLoopCond");
5876 const body_block = try self.wip.block(1, "ReduceLoopBody");
5877 const exit_block = try self.wip.block(1, "ReduceLoopExit");
5878
5879 _ = try self.wip.br(cond_block);
5880
5881 // ReduceLoopCond:
5882 // %index = phi iN [0, %Entry], [%new_index, %ReduceLoopBody]
5883 // %accum = phi T [%accum_init, %Entry], [%new_accum, %ReduceLoopBody]
5884 // %cond = icmp ult iN %index, %vector_len
5885 // br i1 %cond, label %ReduceLoopBody, label %ReduceLoopExit
5886 self.wip.cursor = .{ .block = cond_block };
5887 const index = try self.wip.phi(llvm_usize_ty, "");
5888 const accum = try self.wip.phi(llvm_result_ty, "");
5889 const cond = try self.wip.icmp(.ult, index.toValue(), llvm_vector_len, "");
5890 _ = try self.wip.brCond(cond, body_block, exit_block, .none);
5891
5892 // ReduceLoopBody:
5893 // %elem = extractelement <n x T> %operand_vec, iN %index
5894 // %new_accum = call T @llvm_fn(T %accum, T %elem)
5895 // %new_index = add nuw iN %index, 1
5896 // br label %ReduceLoopCond
5897 self.wip.cursor = .{ .block = body_block };
5898 const elem = try self.wip.extractElement(operand_vector, index.toValue(), "");
5899 const new_accum = try self.wip.call(
5900 .normal,
5901 .ccc,
5902 .none,
5903 llvm_fn.typeOf(&o.builder),
5904 llvm_fn.toValue(&o.builder),
5905 &.{ accum.toValue(), elem },
5906 "",
5907 );
5908 const new_index = try self.wip.bin(.@"add nuw", index.toValue(), try o.builder.intValue(llvm_usize_ty, 1), "");
5909 _ = try self.wip.br(cond_block);
5910
5911 const index_init = try o.builder.intValue(llvm_usize_ty, 0);
5912 index.finish(&.{ index_init, new_index }, &.{ entry_block, body_block }, &self.wip);
5913 accum.finish(&.{ accum_init, new_accum }, &.{ entry_block, body_block }, &self.wip);
5914
5915 self.wip.cursor = .{ .block = exit_block };
5916 return accum.toValue();
5917}
5918
5919fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
5920 const o = self.object;
5921 const zcu = o.zcu;6144 const zcu = o.zcu;
5922 const target = zcu.getTarget();6145 const target = zcu.getTarget();
59236146
5924 const reduce = self.air.instructions.items(.data)[@backingInt(inst)].reduce;6147 const reduce = fg.air.instructions.items(.data)[@backingInt(inst)].reduce;
5925 const operand = try self.resolveInst(reduce.operand);6148 const operand = try fg.resolveInst(reduce.operand);
5926 const operand_ty = self.typeOf(reduce.operand);6149 const operand_ty = fg.typeOf(reduce.operand);
5927 const llvm_operand_ty = try o.lowerType(operand_ty, .by_value);6150 const scalar_ty = fg.typeOfIndex(inst);
5928 const scalar_ty = self.typeOfIndex(inst);
5929 const llvm_scalar_ty = try o.lowerType(scalar_ty, .by_value);
59306151
5931 switch (reduce.operation) {6152 switch (reduce.operation) {
5932 .And, .Or, .Xor => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) {6153 .And, .Or, .Xor => return fg.wip.callIntrinsic(.normal, .none, switch (reduce.operation) {
5933 .And => .@"vector.reduce.and",6154 .And => .@"vector.reduce.and",
5934 .Or => .@"vector.reduce.or",6155 .Or => .@"vector.reduce.or",
5935 .Xor => .@"vector.reduce.xor",6156 .Xor => .@"vector.reduce.xor",
5936 else => unreachable,6157 else => unreachable,
5937 }, &.{llvm_operand_ty}, &.{operand}, ""),6158 }, &.{try o.lowerType(operand_ty, .as_value)}, &.{operand}, ""),
5938 .Min, .Max => switch (scalar_ty.zigTypeTag(zcu)) {6159 .Min, .Max => switch (scalar_ty.zigTypeTag(zcu)) {
5939 .int => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) {6160 .int => return fg.wip.callIntrinsic(.normal, .none, switch (reduce.operation) {
5940 .Min => if (scalar_ty.isSignedInt(zcu))6161 .Min => if (scalar_ty.isSignedInt(zcu))
5941 .@"vector.reduce.smin"6162 .@"vector.reduce.smin"
5942 else6163 else
...@@ -5946,29 +6167,29 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) A...@@ -5946,29 +6167,29 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) A
5946 else6167 else
5947 .@"vector.reduce.umax",6168 .@"vector.reduce.umax",
5948 else => unreachable,6169 else => unreachable,
5949 }, &.{llvm_operand_ty}, &.{operand}, ""),6170 }, &.{try o.lowerType(operand_ty, .as_value)}, &.{operand}, ""),
5950 .float => if (intrinsicsAllowed(scalar_ty, target))6171 .float => if (intrinsicsAllowed(.libc, scalar_ty, target))
5951 return self.wip.callIntrinsic(fast, .none, switch (reduce.operation) {6172 return fg.wip.callIntrinsic(fast, .none, switch (reduce.operation) {
5952 .Min => .@"vector.reduce.fmin",6173 .Min => .@"vector.reduce.fmin",
5953 .Max => .@"vector.reduce.fmax",6174 .Max => .@"vector.reduce.fmax",
5954 else => unreachable,6175 else => unreachable,
5955 }, &.{llvm_operand_ty}, &.{operand}, ""),6176 }, &.{try o.lowerType(operand_ty, .as_value)}, &.{operand}, ""),
5956 else => unreachable,6177 else => unreachable,
5957 },6178 },
5958 .Add, .Mul => switch (scalar_ty.zigTypeTag(zcu)) {6179 .Add, .Mul => switch (scalar_ty.zigTypeTag(zcu)) {
5959 .int => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) {6180 .int => return fg.wip.callIntrinsic(.normal, .none, switch (reduce.operation) {
5960 .Add => .@"vector.reduce.add",6181 .Add => .@"vector.reduce.add",
5961 .Mul => .@"vector.reduce.mul",6182 .Mul => .@"vector.reduce.mul",
5962 else => unreachable,6183 else => unreachable,
5963 }, &.{llvm_operand_ty}, &.{operand}, ""),6184 }, &.{try o.lowerType(operand_ty, .as_value)}, &.{operand}, ""),
5964 .float => if (intrinsicsAllowed(scalar_ty, target))6185 .float => if (intrinsicsAllowed(.compiler_rt, scalar_ty, target))
5965 return self.wip.callIntrinsic(fast, .none, switch (reduce.operation) {6186 return fg.wip.callIntrinsic(fast, .none, switch (reduce.operation) {
5966 .Add => .@"vector.reduce.fadd",6187 .Add => .@"vector.reduce.fadd",
5967 .Mul => .@"vector.reduce.fmul",6188 .Mul => .@"vector.reduce.fmul",
5968 else => unreachable,6189 else => unreachable,
5969 }, &.{llvm_operand_ty}, &.{ switch (reduce.operation) {6190 }, &.{try o.lowerType(operand_ty, .as_value)}, &.{ switch (reduce.operation) {
5970 .Add => try o.builder.fpValue(llvm_scalar_ty, -0.0),6191 .Add => try o.builder.fpValue(try o.lowerType(scalar_ty, .as_value), -0.0),
5971 .Mul => try o.builder.fpValue(llvm_scalar_ty, 1.0),6192 .Mul => try o.builder.fpValue(try o.lowerType(scalar_ty, .as_value), 1.0),
5972 else => unreachable,6193 else => unreachable,
5973 }, operand }, ""),6194 }, operand }, ""),
5974 else => unreachable,6195 else => unreachable,
...@@ -5986,62 +6207,119 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) A...@@ -5986,62 +6207,119 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) A
5986 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),6207 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),
5987 }),6208 }),
5988 .Add => try o.builder.strtabStringFmt("__add{s}f3", .{6209 .Add => try o.builder.strtabStringFmt("__add{s}f3", .{
5989 compilerRtFloatAbbrev(float_bits),6210 compilerRtFloatAbbrev(target, float_bits),
5990 }),6211 }),
5991 .Mul => try o.builder.strtabStringFmt("__mul{s}f3", .{6212 .Mul => try o.builder.strtabStringFmt("__mul{s}f3", .{
5992 compilerRtFloatAbbrev(float_bits),6213 compilerRtFloatAbbrev(target, float_bits),
5993 }),6214 }),
5994 else => unreachable,6215 else => unreachable,
5995 };6216 };
59966217 const fn_info: Object.FuncInfo = .{
5997 const libc_fn = try o.getLibcFunction(fn_name, &.{ llvm_scalar_ty, llvm_scalar_ty }, llvm_scalar_ty);6218 .cc = target.cCallingConvention().?,
5998 const init_val = switch (llvm_scalar_ty) {6219 .param_types = &.{ scalar_ty.toIntern(), scalar_ty.toIntern() },
5999 .i16 => try o.builder.intValue(.i16, @as(i16, @bitCast(6220 .return_type = scalar_ty.toIntern(),
6000 @as(f16, switch (reduce.operation) {6221 };
6001 .Min, .Max => std.math.nan(f16),6222 const llvm_fn = try fg.object.getLibcFunction(fg.pt, fn_name, fn_info);
6002 .Add => -0.0,6223 const init = switch (float_bits) {
6003 .Mul => 1.0,
6004 else => unreachable,
6005 }),
6006 ))),
6007 .i80 => try o.builder.intValue(.i80, @as(i80, @bitCast(
6008 @as(f80, switch (reduce.operation) {
6009 .Min, .Max => std.math.nan(f80),
6010 .Add => -0.0,
6011 .Mul => 1.0,
6012 else => unreachable,
6013 }),
6014 ))),
6015 .i128 => try o.builder.intValue(.i128, @as(i128, @bitCast(
6016 @as(f128, switch (reduce.operation) {
6017 .Min, .Max => std.math.nan(f128),
6018 .Add => -0.0,
6019 .Mul => 1.0,
6020 else => unreachable,
6021 }),
6022 ))),
6023 else => unreachable,6224 else => unreachable,
6225 16 => try o.f16Const(switch (reduce.operation) {
6226 else => unreachable,
6227 .Min, .Max => std.math.nan(f16),
6228 .Add => -0.0,
6229 .Mul => 1.0,
6230 }),
6231 32 => try o.f32Const(switch (reduce.operation) {
6232 else => unreachable,
6233 .Min, .Max => std.math.nan(f32),
6234 .Add => -0.0,
6235 .Mul => 1.0,
6236 }),
6237 64 => try o.f64Const(switch (reduce.operation) {
6238 else => unreachable,
6239 .Min, .Max => std.math.nan(f64),
6240 .Add => -0.0,
6241 .Mul => 1.0,
6242 }),
6243 80 => try o.f80Const(switch (reduce.operation) {
6244 else => unreachable,
6245 .Min, .Max => std.math.nan(f80),
6246 .Add => -0.0,
6247 .Mul => 1.0,
6248 }),
6249 128 => try o.f128Const(switch (reduce.operation) {
6250 else => unreachable,
6251 .Min, .Max => std.math.nan(f128),
6252 .Add => -0.0,
6253 .Mul => 1.0,
6254 }),
6024 };6255 };
6025 return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(zcu), init_val);6256 const iterations = operand_ty.vectorLen(zcu);
6257 const is_by_ref = isByRef(operand_ty, zcu);
6258 if (iterations > 1 and is_by_ref) {
6259 const init_ref = try o.lowerConstRef(init, scalar_ty.abiAlignment(zcu).toLlvm());
6260
6261 const entry_block = fg.wip.cursor.block;
6262 const loop_block = try fg.wip.block(2, "reduce.loop");
6263 const done_block = try fg.wip.block(1, "reduce.loop");
6264
6265 _ = try fg.wip.br(loop_block);
6266
6267 fg.wip.cursor = .{ .block = loop_block };
6268 const index = try fg.wip.phi(.i32, "reduce.index");
6269 const result = try fg.wip.phi(.ptr, "reduce.result");
6270
6271 const rhs_elem_ptr = try fg.ptraddScaled(operand, index.toValue(), scalar_ty.abiSize(zcu));
6272 const rhs_elem = try fg.load(rhs_elem_ptr, .none, scalar_ty, .normal);
6273 const next_result = try fg.buildCall(.{}, llvm_fn.typeOf(&o.builder), llvm_fn.toValue(&o.builder), fn_info, fn_info.param_types, &.{ result.toValue(), rhs_elem });
6274
6275 const next_index = try fg.wip.bin(.@"add nuw", index.toValue(), try o.builder.intValue(.i32, 1), "reduce.next_index");
6276 index.finish(&.{ try o.builder.intValue(.i32, 0), next_index }, &.{ entry_block, loop_block }, &fg.wip);
6277 result.finish(&.{ init_ref.toValue(), next_result }, &.{ entry_block, loop_block }, &fg.wip);
6278 const is_done = try fg.wip.icmp(.eq, next_index, try o.builder.intValue(.i32, iterations), "reduce.is_done");
6279 _ = try fg.wip.brCond(is_done, done_block, loop_block, .none);
6280
6281 fg.wip.cursor = .{ .block = done_block };
6282 return next_result;
6283 }
6284 var result = init.toValue();
6285 for (0..iterations) |index| {
6286 const index_value = try o.builder.intValue(.i32, index);
6287 const rhs_elem = if (is_by_ref) rhs_elem: {
6288 const rhs_elem_ptr = try fg.ptraddConst(operand, index * scalar_ty.abiSize(zcu));
6289 break :rhs_elem try fg.load(rhs_elem_ptr, .none, scalar_ty, .normal);
6290 } else try fg.wip.extractElement(operand, index_value, "reduce.rhs_elem");
6291 result = try fg.buildCall(.{}, llvm_fn.typeOf(&o.builder), llvm_fn.toValue(&o.builder), fn_info, fn_info.param_types, &.{ result, rhs_elem });
6292 }
6293 return result;
6026}6294}
60276295
6028fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {6296fn airAggregateInit(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
6029 const o = self.object;6297 const o = fg.object;
6030 const zcu = o.zcu;6298 const zcu = o.zcu;
6031 const ip = &zcu.intern_pool;6299 const ip = &zcu.intern_pool;
6032 const ty_pl = self.air.instructions.items(.data)[@backingInt(inst)].ty_pl;6300 const ty_pl = fg.air.instructions.items(.data)[@backingInt(inst)].ty_pl;
6033 const result_ty = self.typeOfIndex(inst);6301 const result_ty = fg.typeOfIndex(inst);
6034 const len: usize = @intCast(result_ty.arrayLen(zcu));6302 const len: usize = @intCast(result_ty.arrayLen(zcu));
6035 const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[ty_pl.payload..][0..len]);6303 const elements: []const Air.Inst.Ref = @ptrCast(fg.air.extra.items[ty_pl.payload..][0..len]);
60366304
6037 switch (result_ty.zigTypeTag(zcu)) {6305 switch (result_ty.zigTypeTag(zcu)) {
6038 .vector => {6306 .vector => if (isByRef(result_ty, zcu)) {
6039 const llvm_result_ty = try o.lowerType(result_ty, .by_value);6307 const elem_ty = result_ty.childType(zcu);
6308 const elem_size = elem_ty.abiSize(zcu);
6309 const result_ptr = try fg.buildZigAlloca(result_ty, .none);
6310 for (elements, 0..) |elem, elem_index| {
6311 const elem_ptr = try fg.ptraddConst(result_ptr, elem_index * elem_size);
6312 const llvm_elem = try fg.resolveInst(elem);
6313 try fg.store(elem_ptr, .none, llvm_elem, elem_ty, .normal);
6314 }
6315 return result_ptr;
6316 } else {
6317 const llvm_result_ty = try o.lowerType(result_ty, .as_value);
6040 var vector = try o.builder.poisonValue(llvm_result_ty);6318 var vector = try o.builder.poisonValue(llvm_result_ty);
6041 for (elements, 0..) |elem, i| {6319 for (elements, 0..) |elem, elem_index| {
6042 const index_u32 = try o.builder.intValue(.i32, i);6320 const elem_index_val = try o.builder.intValue(.i32, elem_index);
6043 const llvm_elem = try self.resolveInst(elem);6321 const llvm_elem = try fg.resolveInst(elem);
6044 vector = try self.wip.insertElement(vector, llvm_elem, index_u32, "");6322 vector = try fg.wip.insertElement(vector, llvm_elem, elem_index_val, "");
6045 }6323 }
6046 return vector;6324 return vector;
6047 },6325 },
...@@ -6057,18 +6335,18 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde...@@ -6057,18 +6335,18 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde
6057 for (elements, struct_type.field_types.get(ip)) |elem, field_ty| {6335 for (elements, struct_type.field_types.get(ip)) |elem, field_ty| {
6058 if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;6336 if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
60596337
6060 const non_int_val = try self.resolveInst(elem);6338 const non_int_val = try fg.resolveInst(elem);
6061 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(zcu));6339 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(zcu));
6062 const small_int_ty = try o.builder.intType(ty_bit_size);6340 const small_int_ty = try o.builder.intType(ty_bit_size);
6063 const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(zcu))6341 const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(zcu))
6064 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")6342 try fg.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")
6065 else6343 else
6066 try self.wip.cast(.bitcast, non_int_val, small_int_ty, "");6344 try fg.wip.cast(.bitcast, non_int_val, small_int_ty, "");
6067 const shift_rhs = try o.builder.intValue(int_ty, running_bits);6345 const shift_rhs = try o.builder.intValue(int_ty, running_bits);
6068 const extended_int_val =6346 const extended_int_val =
6069 try self.wip.conv(.unsigned, small_int_val, int_ty, "");6347 try fg.wip.conv(.unsigned, small_int_val, int_ty, "");
6070 const shifted = try self.wip.bin(.shl, extended_int_val, shift_rhs, "");6348 const shifted = try fg.wip.bin(.shl, extended_int_val, shift_rhs, "");
6071 running_int = try self.wip.bin(.@"or", running_int, shifted, "");6349 running_int = try fg.wip.bin(.@"or", running_int, shifted, "");
6072 running_bits += ty_bit_size;6350 running_bits += ty_bit_size;
6073 }6351 }
6074 return running_int;6352 return running_int;
...@@ -6078,19 +6356,19 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde...@@ -6078,19 +6356,19 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde
6078 // TODO in debug builds init to undef so that the padding will be 0xaa6356 // TODO in debug builds init to undef so that the padding will be 0xaa
6079 // even if we fully populate the fields.6357 // even if we fully populate the fields.
6080 const struct_align = result_ty.abiAlignment(zcu);6358 const struct_align = result_ty.abiAlignment(zcu);
6081 const alloca_inst = try self.buildZigAlloca(result_ty, .none);6359 const alloca_inst = try fg.buildZigAlloca(result_ty, .none);
60826360
6083 for (elements, 0..) |elem, field_index| {6361 for (elements, 0..) |elem, field_index| {
6084 if (result_ty.structFieldIsComptime(field_index, zcu)) continue;6362 if (result_ty.structFieldIsComptime(field_index, zcu)) continue;
6085 const field_ty = result_ty.fieldType(field_index, zcu);6363 const field_ty = result_ty.fieldType(field_index, zcu);
6086 if (!field_ty.hasRuntimeBits(zcu)) continue;6364 if (!field_ty.hasRuntimeBits(zcu)) continue;
6087 const offset = result_ty.structFieldOffset(field_index, zcu);6365 const offset = result_ty.structFieldOffset(field_index, zcu);
6088 const field_ptr = try self.ptraddConst(alloca_inst, offset);6366 const field_ptr = try fg.ptraddConst(alloca_inst, offset);
6089 const field_ptr_align = struct_align.offset(offset);6367 const field_ptr_align = struct_align.offset(offset);
60906368
6091 const llvm_field_val = try self.resolveInst(elem);6369 const llvm_field_val = try fg.resolveInst(elem);
60926370
6093 try self.store(field_ptr, field_ptr_align, llvm_field_val, field_ty, .normal);6371 try fg.store(field_ptr, field_ptr_align, llvm_field_val, field_ty, .normal);
6094 }6372 }
60956373
6096 return alloca_inst;6374 return alloca_inst;
...@@ -6099,21 +6377,21 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde...@@ -6099,21 +6377,21 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde
6099 .array => {6377 .array => {
6100 assert(isByRef(result_ty, zcu));6378 assert(isByRef(result_ty, zcu));
61016379
6102 const alloca_inst = try self.buildZigAlloca(result_ty, .none);6380 const alloca_inst = try fg.buildZigAlloca(result_ty, .none);
61036381
6104 const array_info = result_ty.arrayInfo(zcu);6382 const array_info = result_ty.arrayInfo(zcu);
61056383
6106 const elem_size = array_info.elem_type.abiSize(zcu);6384 const elem_size = array_info.elem_type.abiSize(zcu);
61076385
6108 for (elements, 0..) |elem, i| {6386 for (elements, 0..) |elem, i| {
6109 const elem_ptr = try self.ptraddConst(alloca_inst, elem_size * i);6387 const elem_ptr = try fg.ptraddConst(alloca_inst, elem_size * i);
6110 const llvm_elem = try self.resolveInst(elem);6388 const llvm_elem = try fg.resolveInst(elem);
6111 try self.store(elem_ptr, .none, llvm_elem, array_info.elem_type, .normal);6389 try fg.store(elem_ptr, .none, llvm_elem, array_info.elem_type, .normal);
6112 }6390 }
6113 if (array_info.sentinel) |sent_val| {6391 if (array_info.sentinel) |sent_val| {
6114 const elem_ptr = try self.ptraddConst(alloca_inst, elem_size * array_info.len);6392 const elem_ptr = try fg.ptraddConst(alloca_inst, elem_size * array_info.len);
6115 const llvm_elem = try self.resolveValue(sent_val);6393 const llvm_elem = try fg.resolveValue(sent_val);
6116 try self.store(elem_ptr, .none, llvm_elem.toValue(), array_info.elem_type, .normal);6394 try fg.store(elem_ptr, .none, llvm_elem.toValue(), array_info.elem_type, .normal);
6117 }6395 }
61186396
6119 return alloca_inst;6397 return alloca_inst;
...@@ -6153,10 +6431,10 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va...@@ -6153,10 +6431,10 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va
6153 const loaded_enum = ip.loadEnumType(tag_ty.toIntern());6431 const loaded_enum = ip.loadEnumType(tag_ty.toIntern());
6154 const llvm_tag_val = switch (loaded_enum.field_values.getOrNone(ip, extra.field_index)) {6432 const llvm_tag_val = switch (loaded_enum.field_values.getOrNone(ip, extra.field_index)) {
6155 .none => try o.builder.intConst(6433 .none => try o.builder.intConst(
6156 try o.lowerType(.fromInterned(union_obj.enum_tag_type), .by_value),6434 try o.lowerType(.fromInterned(union_obj.enum_tag_type), .as_value),
6157 extra.field_index, // auto-numbered6435 extra.field_index, // auto-numbered
6158 ),6436 ),
6159 else => |tag_val_ip| try o.lowerValue(tag_val_ip, .by_value),6437 else => |tag_val_ip| try o.lowerValue(tag_val_ip, .as_value),
6160 };6438 };
6161 const tag_ptr = try self.ptraddConst(result_ptr, layout.tagOffset());6439 const tag_ptr = try self.ptraddConst(result_ptr, layout.tagOffset());
6162 try self.store(tag_ptr, layout.tag_align, llvm_tag_val.toValue(), tag_ty, .normal);6440 try self.store(tag_ptr, layout.tag_align, llvm_tag_val.toValue(), tag_ty, .normal);
...@@ -6218,7 +6496,7 @@ fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde...@@ -6218,7 +6496,7 @@ fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde
6218 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;6496 const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op;
6219 const inst_ty = self.typeOfIndex(inst);6497 const inst_ty = self.typeOfIndex(inst);
6220 const operand = try self.resolveInst(ty_op.operand);6498 const operand = try self.resolveInst(ty_op.operand);
6221 return self.wip.cast(.addrspacecast, operand, try self.object.lowerType(inst_ty, .by_value), "");6499 return self.wip.cast(.addrspacecast, operand, try self.object.lowerType(inst_ty, .as_value), "");
6222}6500}
62236501
6224fn workIntrinsic(6502fn workIntrinsic(
...@@ -6370,7 +6648,7 @@ fn load(...@@ -6370,7 +6648,7 @@ fn load(
6370 };6648 };
63716649
6372 if (isByRef(load_ty, zcu)) {6650 if (isByRef(load_ty, zcu)) {
6373 const llvm_usize_ty = try o.lowerType(.usize, .by_value);6651 const llvm_usize_ty = try o.lowerType(.usize, .as_value);
6374 const result_ptr = try fg.buildZigAlloca(load_ty, .none);6652 const result_ptr = try fg.buildZigAlloca(load_ty, .none);
6375 _ = try fg.wip.callMemCpy(6653 _ = try fg.wip.callMemCpy(
6376 result_ptr,6654 result_ptr,
...@@ -6384,10 +6662,10 @@ fn load(...@@ -6384,10 +6662,10 @@ fn load(
6384 return result_ptr;6662 return result_ptr;
6385 }6663 }
63866664
6387 const llvm_memory_ty = try o.lowerType(load_ty, .in_memory);6665 const llvm_access_ty = try o.lowerType(load_ty, .memory_access);
6388 const llvm_value_ty = try o.lowerType(load_ty, .by_value);6666 const llvm_value_ty = try o.lowerType(load_ty, .as_value);
63896667
6390 if (llvm_memory_ty != llvm_value_ty) {6668 if (llvm_access_ty != llvm_value_ty) {
6391 assert(load_ty.isAbiInt(zcu));6669 assert(load_ty.isAbiInt(zcu));
6392 // `load_ty` is an integer type with padding bits. In theory, we shouldn't need any special6670 // `load_ty` is an integer type with padding bits. In theory, we shouldn't need any special
6393 // handling for these, as LLVM's documented semantics are a valid implementation of Zig's6671 // handling for these, as LLVM's documented semantics are a valid implementation of Zig's
...@@ -6401,7 +6679,7 @@ fn load(...@@ -6401,7 +6679,7 @@ fn load(
6401 //6679 //
6402 // Therefore, we handle these memory accesses specially: in this case we will actually load6680 // Therefore, we handle these memory accesses specially: in this case we will actually load
6403 // the next-largest "natural" integer type and then truncate to `load_ty`.6681 // the next-largest "natural" integer type and then truncate to `load_ty`.
6404 const loaded = try fg.wip.load(access_kind, llvm_memory_ty, ptr, llvm_ptr_align, "");6682 const loaded = try fg.wip.load(access_kind, llvm_access_ty, ptr, llvm_ptr_align, "");
6405 // For packed structs, current Zig semantics don't really allow us to make the padding bits6683 // For packed structs, current Zig semantics don't really allow us to make the padding bits
6406 // well-defined. This should be solved once https://github.com/ziglang/zig/issues/24061 is6684 // well-defined. This should be solved once https://github.com/ziglang/zig/issues/24061 is
6407 // implemented, but until then, do a normal trunc for packed types.6685 // implemented, but until then, do a normal trunc for packed types.
...@@ -6443,7 +6721,7 @@ fn store(...@@ -6443,7 +6721,7 @@ fn store(
6443 };6721 };
64446722
6445 if (isByRef(elem_ty, zcu)) {6723 if (isByRef(elem_ty, zcu)) {
6446 const llvm_usize_ty = try o.lowerType(.usize, .by_value);6724 const llvm_usize_ty = try o.lowerType(.usize, .as_value);
6447 _ = try fg.wip.callMemCpy(6725 _ = try fg.wip.callMemCpy(
6448 ptr,6726 ptr,
6449 llvm_ptr_align,6727 llvm_ptr_align,
...@@ -6456,45 +6734,31 @@ fn store(...@@ -6456,45 +6734,31 @@ fn store(
6456 return;6734 return;
6457 }6735 }
64586736
6459 assert(elem.typeOfWip(&fg.wip) == try o.lowerType(elem_ty, .by_value));6737 assert(elem.typeOfWip(&fg.wip) == try o.lowerType(elem_ty, .as_value));
64606738
6461 const llvm_memory_ty = try o.lowerType(elem_ty, .in_memory);6739 const llvm_access_ty = try o.lowerType(elem_ty, .memory_access);
6462 const llvm_value_ty = try o.lowerType(elem_ty, .by_value);6740 const llvm_value_ty = try o.lowerType(elem_ty, .as_value);
64636741
6464 if (llvm_memory_ty != llvm_value_ty) {6742 if (llvm_access_ty != llvm_value_ty) {
6465 assert(elem_ty.isAbiInt(zcu));6743 assert(elem_ty.isAbiInt(zcu));
6466 // `elem_ty` is an integer type with padding bits, so we need to handle it specially---see6744 // `elem_ty` is an integer type with padding bits, so we need to handle it specially---see
6467 // the corresponding comment in `FuncGen.load` for more details.6745 // the corresponding comment in `FuncGen.load` for more details.
6468 const extended = try fg.wip.cast(switch (elem_ty.intInfo(zcu).signedness) {6746 const extended = try fg.wip.cast(switch (elem_ty.intInfo(zcu).signedness) {
6469 .unsigned => .zext,6747 .unsigned => .zext,
6470 .signed => .sext,6748 .signed => .sext,
6471 }, elem, llvm_memory_ty, "");6749 }, elem, llvm_access_ty, "");
6472 _ = try fg.wip.storeAtomic(6750 _ = try fg.wip.store(access_kind, extended, ptr, llvm_ptr_align);
6473 access_kind,
6474 extended,
6475 ptr,
6476 fg.sync_scope,
6477 .none,
6478 llvm_ptr_align,
6479 );
6480 return;6751 return;
6481 }6752 }
64826753
6483 // `elem_ty` is a simple by-val type which requires no special handling.6754 // `elem_ty` is a simple by-val type which requires no special handling.
6484 _ = try fg.wip.storeAtomic(6755 _ = try fg.wip.store(access_kind, elem, ptr, llvm_ptr_align);
6485 access_kind,
6486 elem,
6487 ptr,
6488 fg.sync_scope,
6489 .none,
6490 llvm_ptr_align,
6491 );
6492}6756}
64936757
6494fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void {6758fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void {
6495 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;6759 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
6496 const o = fg.object;6760 const o = fg.object;
6497 const usize_ty = try o.lowerType(.usize, .by_value);6761 const usize_ty = try o.lowerType(.usize, .as_value);
6498 const zero = try o.builder.intValue(usize_ty, 0);6762 const zero = try o.builder.intValue(usize_ty, 0);
6499 const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED);6763 const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED);
6500 const ptr_as_usize = try fg.wip.cast(.ptrtoint, ptr, usize_ty, "");6764 const ptr_as_usize = try fg.wip.cast(.ptrtoint, ptr, usize_ty, "");
...@@ -6516,7 +6780,7 @@ fn valgrindClientRequest(...@@ -6516,7 +6780,7 @@ fn valgrindClientRequest(
6516 const target = zcu.getTarget();6780 const target = zcu.getTarget();
6517 if (!target_util.hasValgrindSupport(target, .stage2_llvm)) return default_value;6781 if (!target_util.hasValgrindSupport(target, .stage2_llvm)) return default_value;
65186782
6519 const llvm_usize = try o.lowerType(.usize, .by_value);6783 const llvm_usize = try o.lowerType(.usize, .as_value);
6520 const usize_align = Type.usize.abiAlignment(zcu).toLlvm();6784 const usize_align = Type.usize.abiAlignment(zcu).toLlvm();
65216785
6522 const array_llvm_ty = try o.builder.arrayType(6, llvm_usize);6786 const array_llvm_ty = try o.builder.arrayType(6, llvm_usize);
...@@ -6650,13 +6914,14 @@ fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {...@@ -6650,13 +6914,14 @@ fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {
66506914
6651const ParamTypeIterator = struct {6915const ParamTypeIterator = struct {
6652 object: *Object,6916 object: *Object,
6653 fn_info: InternPool.Key.FuncType,6917 cc: std.lang.CallingConvention,
6918 param_types: []const InternPool.Index,
6654 zig_index: u32,6919 zig_index: u32,
6655 llvm_index: u32,6920 llvm_index: u32,
6656 types_len: u32,6921 types_len: u32,
6657 types_buffer: [8]Builder.Type,6922 types_buffer: [8]Builder.Type,
6658 offsets_buffer: [9]u64,6923 offsets_buffer: [9]u64,
6659 byval_attr: bool,6924 byval_attr: ?Object.Byval,
66606925
6661 const Lowering = union(enum) {6926 const Lowering = union(enum) {
6662 no_bits,6927 no_bits,
...@@ -6672,88 +6937,78 @@ const ParamTypeIterator = struct {...@@ -6672,88 +6937,78 @@ const ParamTypeIterator = struct {
6672 };6937 };
66736938
6674 pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {6939 pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {
6675 if (it.zig_index >= it.fn_info.param_types.len) return null;6940 if (it.zig_index >= it.param_types.len) return null;
6676 const ip = &it.object.zcu.intern_pool;6941 const ty = it.param_types[it.zig_index];
6677 const ty = it.fn_info.param_types.get(ip)[it.zig_index];6942 it.byval_attr = null;
6678 it.byval_attr = false;
6679 return nextInner(it, Type.fromInterned(ty));6943 return nextInner(it, Type.fromInterned(ty));
6680 }6944 }
66816945
6682 /// `airCall` uses this instead of `next` so that it can take into account variadic functions.6946 /// `airCall` uses this instead of `next` so that it can take into account variadic functions.
6683 fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering {6947 fn nextCall(it: *ParamTypeIterator, arg_types: []const InternPool.Index) Allocator.Error!?Lowering {
6684 const ip = &it.object.zcu.intern_pool;6948 if (it.zig_index >= it.param_types.len) {
6685 if (it.zig_index >= it.fn_info.param_types.len) {6949 if (it.zig_index >= arg_types.len) {
6686 if (it.zig_index >= args.len) {
6687 return null;6950 return null;
6688 } else {6951 } else {
6689 return nextInner(it, fg.typeOf(args[it.zig_index]));6952 return nextInner(it, .fromInterned(arg_types[it.zig_index]));
6690 }6953 }
6691 } else {6954 } else {
6692 return nextInner(it, Type.fromInterned(it.fn_info.param_types.get(ip)[it.zig_index]));6955 return nextInner(it, .fromInterned(it.param_types[it.zig_index]));
6693 }6956 }
6694 }6957 }
66956958
6696 fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {6959 fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {
6697 const zcu = it.object.zcu;6960 const zcu = it.object.zcu;
6698 const target = zcu.getTarget();6961 ty.assertHasLayout(zcu);
6699
6700 if (!ty.hasRuntimeBits(zcu)) {6962 if (!ty.hasRuntimeBits(zcu)) {
6701 it.zig_index += 1;6963 it.zig_index += 1;
6702 return .no_bits;6964 return .no_bits;
6703 }6965 }
6704 switch (it.fn_info.cc) {6966 switch (it.cc) {
6705 .@"inline" => unreachable,6967 .@"inline" => unreachable,
6706 .auto => {6968 .auto => {
6707 it.zig_index += 1;6969 it.zig_index += 1;
6708 it.llvm_index += 1;6970 it.llvm_index += 1;
6971
6972 // Match the c calling convention in some cases to avoid llvm bugs.
6973 const target = zcu.getTarget();
6974 if (target.cpu.arch == .x86_64 and ty.isVector(zcu) and ty.childType(zcu).toIntern() == .bool_type) return switch (ty.vectorLen(zcu)) {
6975 0 => .no_bits,
6976 1...32 => .abi_sized_int,
6977 33...64 => {
6978 it.types_buffer[0..1].* = .{.double};
6979 it.offsets_buffer[0..2].* = .{ 0, 8 };
6980 it.types_len = 1;
6981 return .multiple_llvm_types;
6982 },
6983 else => .byval,
6984 };
6985
6709 if (ty.isSlice(zcu) or6986 if (ty.isSlice(zcu) or
6710 (ty.zigTypeTag(zcu) == .optional and ty.optionalChild(zcu).isSlice(zcu) and !ty.ptrAllowsZero(zcu)))6987 (ty.zigTypeTag(zcu) == .optional and ty.optionalChild(zcu).isSlice(zcu) and !ty.ptrAllowsZero(zcu)))
6711 {6988 {
6712 it.llvm_index += 1;6989 it.llvm_index += 1;
6713 return .slice;6990 return .slice;
6714 } else if (isByRef(ty, zcu)) {
6715 return .byref;
6716 } else if (target.cpu.arch.isX86() and
6717 !target.cpu.has(.x86, .avx512f) and
6718 ty.totalVectorBits(zcu) >= 512)
6719 {
6720 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns
6721 // "512-bit vector arguments require 'avx512f' for AVX512"
6722 return .byref;
6723 } else {
6724 return .byval;
6725 }6991 }
6992 if (isByRef(ty, zcu)) return .byref;
6993 return .byval;
6726 },6994 },
6727 .async => {6995 .async => {
6728 @panic("TODO implement async function lowering in the LLVM backend");6996 @panic("TODO implement async function lowering in the LLVM backend");
6729 },6997 },
6730 .x86_64_sysv, .x86_64_x32 => return it.nextSystemV(ty),
6731 .x86_64_win => return it.nextWin64(ty),
6732 .x86_stdcall => {
6733 it.zig_index += 1;
6734 it.llvm_index += 1;
6735
6736 if (isScalar(zcu, ty)) {
6737 return .byval;
6738 } else {
6739 it.byval_attr = true;
6740 return .byref;
6741 }
6742 },
6743 .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => {6998 .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => {
6744 it.zig_index += 1;6999 it.zig_index += 1;
6745 it.llvm_index += 1;7000 it.llvm_index += 1;
6746 switch (aarch64_c_abi.classifyType(ty, zcu)) {7001 switch (aarch64_c_abi.classifyType(ty, zcu)) {
6747 .memory => return .byref_mut,7002 .memory => return .byref_mut,
6748 .float_array => |len| return Lowering{ .float_array = len },7003 .float_array => |len| return .{ .float_array = len },
6749 .byval => return .byval,7004 .byval => return .byval,
6750 .integer => {7005 .integer => {
6751 it.types_len = 1;
6752 it.types_buffer[0..1].* = .{.i64};7006 it.types_buffer[0..1].* = .{.i64};
6753 it.offsets_buffer[0..2].* = .{ 0, 8 };7007 it.offsets_buffer[0..2].* = .{ 0, 8 };
7008 it.types_len = 1;
6754 return .multiple_llvm_types;7009 return .multiple_llvm_types;
6755 },7010 },
6756 .double_integer => return Lowering{ .i64_array = 2 },7011 .double_integer => return .{ .i64_array = 2 },
6757 }7012 }
6758 },7013 },
6759 .arm_aapcs, .arm_aapcs_vfp => {7014 .arm_aapcs, .arm_aapcs_vfp => {
...@@ -6761,26 +7016,101 @@ const ParamTypeIterator = struct {...@@ -6761,26 +7016,101 @@ const ParamTypeIterator = struct {
6761 it.llvm_index += 1;7016 it.llvm_index += 1;
6762 switch (arm_c_abi.classifyType(ty, zcu, .arg)) {7017 switch (arm_c_abi.classifyType(ty, zcu, .arg)) {
6763 .memory => {7018 .memory => {
6764 it.byval_attr = true;7019 it.byval_attr = .{};
6765 return .byref;7020 return .byref;
6766 },7021 },
6767 .byval => return .byval,7022 .byval => return .byval,
6768 .i32_array => |size| return Lowering{ .i32_array = size },7023 .i32_array => |size| return .{ .i32_array = size },
6769 .i64_array => |size| return Lowering{ .i64_array = size },7024 .i64_array => |size| return .{ .i64_array = size },
6770 }7025 }
6771 },7026 },
7027 .loongarch32_ilp32, .loongarch64_lp64 => switch (loongarch_c_abi.classifyType(ty, zcu)) {
7028 .ignored => {
7029 it.zig_index += 1;
7030 return .no_bits;
7031 },
7032 .gar, .far => {
7033 it.zig_index += 1;
7034 it.llvm_index += 1;
7035 return .byval;
7036 },
7037 .member => |member_ty| {
7038 it.types_buffer[0..1].* = .{
7039 try it.object.lowerType(member_ty, .as_value),
7040 };
7041 it.offsets_buffer[0..2].* = .{ 0, member_ty.abiSize(zcu) };
7042 it.types_len = 1;
7043 it.zig_index += 1;
7044 it.llvm_index += 1;
7045 return .multiple_llvm_types;
7046 },
7047 .member_pair => |member_tys| {
7048 it.types_buffer[0..2].* = .{
7049 try it.object.lowerType(member_tys[0], .as_value),
7050 try it.object.lowerType(member_tys[1], .as_value),
7051 };
7052 const first_size = member_tys[0].abiSize(zcu);
7053 const second_size = member_tys[0].abiSize(zcu);
7054 it.offsets_buffer[0..3].* = .{ 0, first_size, first_size + second_size };
7055 it.types_len = 2;
7056 it.zig_index += 1;
7057 it.llvm_index += 2;
7058 return .multiple_llvm_types;
7059 },
7060 .memory_gar => {
7061 switch (it.cc) {
7062 else => unreachable,
7063 .loongarch32_ilp32 => {
7064 it.types_buffer[0..1].* = .{.i32};
7065 it.offsets_buffer[0..2].* = .{ 0, 4 };
7066 },
7067 .loongarch64_lp64 => {
7068 it.types_buffer[0..1].* = .{.i64};
7069 it.offsets_buffer[0..2].* = .{ 0, 8 };
7070 },
7071 }
7072 it.types_len = 1;
7073 it.zig_index += 1;
7074 it.llvm_index += 1;
7075 return .multiple_llvm_types;
7076 },
7077 .memory_gar_pair => {
7078 it.zig_index += 1;
7079 it.llvm_index += 1;
7080 return switch (it.cc) {
7081 else => unreachable,
7082 .loongarch32_ilp32 => .{ .i32_array = 2 },
7083 .loongarch64_lp64 => .{ .i64_array = 2 },
7084 };
7085 },
7086 .address => {
7087 it.zig_index += 1;
7088 it.llvm_index += 1;
7089 return .byref;
7090 },
7091 },
6772 .mips_o32 => {7092 .mips_o32 => {
6773 it.zig_index += 1;7093 it.zig_index += 1;
6774 it.llvm_index += 1;7094 it.llvm_index += 1;
6775 switch (mips_c_abi.classifyType(ty, zcu, .arg)) {7095 switch (mips_c_abi.classifyType(ty, zcu, .arg)) {
6776 .memory => {7096 .memory => {
6777 it.byval_attr = true;7097 it.byval_attr = .{};
6778 return .byref;7098 return .byref;
6779 },7099 },
6780 .byval => return .byval,7100 .byval => return .byval,
6781 .i32_array => |size| return Lowering{ .i32_array = size },7101 .i32_array => |size| return .{ .i32_array = size },
6782 }7102 }
6783 },7103 },
7104 .powerpc64_elf_v2 => {
7105 it.zig_index += 1;
7106 it.llvm_index += 1;
7107 if (isByRef(ty, zcu)) return switch (ty.abiSize(zcu)) {
7108 1...8 => .abi_sized_int,
7109 9...64 => |abi_size| .{ .i64_array = @intCast(@divCeil(abi_size, 8)) },
7110 else => .byref,
7111 };
7112 return .byval; // TODO
7113 },
6784 .riscv64_lp64, .riscv32_ilp32 => {7114 .riscv64_lp64, .riscv32_ilp32 => {
6785 it.zig_index += 1;7115 it.zig_index += 1;
6786 it.llvm_index += 1;7116 it.llvm_index += 1;
...@@ -6788,7 +7118,7 @@ const ParamTypeIterator = struct {...@@ -6788,7 +7118,7 @@ const ParamTypeIterator = struct {
6788 .memory => return .byref_mut,7118 .memory => return .byref_mut,
6789 .byval => return .byval,7119 .byval => return .byval,
6790 .integer => return .abi_sized_int,7120 .integer => return .abi_sized_int,
6791 .double_integer => return Lowering{ .i64_array = 2 },7121 .double_integer => return .{ .i64_array = 2 },
6792 .fields => {7122 .fields => {
6793 it.types_len = 0;7123 it.types_len = 0;
6794 var field_it: InternPool.LoadedStructType.RuntimeOrderIterator = if (zcu.typeToStruct(ty)) |loaded_struct|7124 var field_it: InternPool.LoadedStructType.RuntimeOrderIterator = if (zcu.typeToStruct(ty)) |loaded_struct|
...@@ -6798,7 +7128,7 @@ const ParamTypeIterator = struct {...@@ -6798,7 +7128,7 @@ const ParamTypeIterator = struct {
6798 while (field_it.next()) |field_index| {7128 while (field_it.next()) |field_index| {
6799 const field_ty = ty.fieldType(field_index, zcu);7129 const field_ty = ty.fieldType(field_index, zcu);
6800 if (!field_ty.hasRuntimeBits(zcu)) continue;7130 if (!field_ty.hasRuntimeBits(zcu)) continue;
6801 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty, .by_value);7131 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty, .as_value);
6802 it.offsets_buffer[it.types_len] = ty.structFieldOffset(field_index, zcu);7132 it.offsets_buffer[it.types_len] = ty.structFieldOffset(field_index, zcu);
6803 it.types_len += 1;7133 it.types_len += 1;
6804 }7134 }
...@@ -6808,6 +7138,24 @@ const ParamTypeIterator = struct {...@@ -6808,6 +7138,24 @@ const ParamTypeIterator = struct {
6808 },7138 },
6809 }7139 }
6810 },7140 },
7141 .s390x_sysv, .s390x_sysv_vx => {
7142 it.zig_index += 1;
7143 switch (s390x_c_abi.classifyType(ty, .arg, zcu)) {
7144 .none => return .no_bits,
7145 .double_or_float, .vector, .simple => {
7146 it.llvm_index += 1;
7147 return .byval;
7148 },
7149 .simple_aggregate => {
7150 it.llvm_index += 1;
7151 return .abi_sized_int;
7152 },
7153 .pointer => {
7154 it.llvm_index += 1;
7155 return .byref_mut;
7156 },
7157 }
7158 },
6811 .wasm_mvp => switch (wasm_c_abi.classifyType(ty, zcu)) {7159 .wasm_mvp => switch (wasm_c_abi.classifyType(ty, zcu)) {
6812 .direct => |scalar_ty| {7160 .direct => |scalar_ty| {
6813 if (isScalar(zcu, ty)) {7161 if (isScalar(zcu, ty)) {
...@@ -6815,21 +7163,80 @@ const ParamTypeIterator = struct {...@@ -6815,21 +7163,80 @@ const ParamTypeIterator = struct {
6815 it.llvm_index += 1;7163 it.llvm_index += 1;
6816 return .byval;7164 return .byval;
6817 } else {7165 } else {
6818 it.types_buffer[0..1].* = .{try it.object.lowerType(scalar_ty, .by_value)};7166 it.types_buffer[0..1].* = .{try it.object.lowerType(scalar_ty, .as_value)};
6819 it.offsets_buffer[0..2].* = .{ 0, scalar_ty.abiSize(zcu) };7167 it.offsets_buffer[0..2].* = .{ 0, scalar_ty.abiSize(zcu) };
6820 it.types_len = 1;7168 it.types_len = 1;
6821 it.llvm_index += 1;
6822 it.zig_index += 1;7169 it.zig_index += 1;
7170 it.llvm_index += 1;
6823 return .multiple_llvm_types;7171 return .multiple_llvm_types;
6824 }7172 }
6825 },7173 },
6826 .indirect => {7174 .indirect => {
6827 it.zig_index += 1;7175 it.zig_index += 1;
6828 it.llvm_index += 1;7176 it.llvm_index += 1;
6829 it.byval_attr = true;7177 it.byval_attr = .{};
6830 return .byref;7178 return .byref;
6831 },7179 },
6832 },7180 },
7181 .x86_stdcall => {
7182 it.zig_index += 1;
7183 it.llvm_index += 1;
7184
7185 if (isScalar(zcu, ty)) {
7186 return .byval;
7187 } else {
7188 it.byval_attr = .{};
7189 return .byref;
7190 }
7191 },
7192 .x86_sysv, .x86_win, .x86_mingw => {
7193 if (isByRef(ty, zcu)) {
7194 var items_buf: [1]codegen.FlattenedItem = undefined;
7195 if (codegen.flattenType(&items_buf, ty, zcu, .{
7196 .allow_arrays = false,
7197 })) |items| one_float: {
7198 if (items.len != 1 or items[0].offset != 0) break :one_float;
7199 const item_ty = items[0].type orelse break :one_float;
7200 if (!item_ty.isRuntimeFloat()) break :one_float;
7201 it.types_buffer[0..1].*, it.offsets_buffer[0..2].* =
7202 switch (item_ty.floatBits(zcu.getTarget())) {
7203 else => unreachable,
7204 32 => .{ .{.float}, .{ 0, 4 } },
7205 64 => .{ .{.double}, .{ 0, 8 } },
7206 16, 80, 128 => break :one_float,
7207 };
7208 it.types_len = 1;
7209 it.zig_index += 1;
7210 it.llvm_index += 1;
7211 return .multiple_llvm_types;
7212 }
7213 it.zig_index += 1;
7214 it.llvm_index += 1;
7215 it.byval_attr = .{ .alignment = .@"4" };
7216 return .byref;
7217 }
7218 if (ty.isAbiInt(zcu)) switch (ty.intInfo(zcu).bits) {
7219 else => unreachable,
7220 8, 16, 32, 64 => {
7221 it.zig_index += 1;
7222 it.llvm_index += 1;
7223 return .byval;
7224 },
7225 128 => {
7226 it.types_buffer[0..2].* = .{ .i64, .i64 };
7227 it.offsets_buffer[0..3].* = .{ 0, 8, 16 };
7228 it.types_len = 2;
7229 it.zig_index += 1;
7230 it.llvm_index += 2;
7231 return .multiple_llvm_types;
7232 },
7233 };
7234 it.zig_index += 1;
7235 it.llvm_index += 1;
7236 return .byval;
7237 },
7238 .x86_64_sysv, .x86_64_x32 => return try it.next_x86_64_sysv(ty),
7239 .x86_64_win => return it.next_x86_64_win(ty),
6833 // TODO investigate other callconvs7240 // TODO investigate other callconvs
6834 else => {7241 else => {
6835 it.zig_index += 1;7242 it.zig_index += 1;
...@@ -6839,7 +7246,7 @@ const ParamTypeIterator = struct {...@@ -6839,7 +7246,7 @@ const ParamTypeIterator = struct {
6839 }7246 }
6840 }7247 }
68417248
6842 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {7249 fn next_x86_64_win(it: *ParamTypeIterator, ty: Type) Lowering {
6843 const zcu = it.object.zcu;7250 const zcu = it.object.zcu;
6844 switch (x86_64_abi.classifyWindows(ty, zcu, zcu.getTarget(), .arg)) {7251 switch (x86_64_abi.classifyWindows(ty, zcu, zcu.getTarget(), .arg)) {
6845 .integer => {7252 .integer => {
...@@ -6880,119 +7287,114 @@ const ParamTypeIterator = struct {...@@ -6880,119 +7287,114 @@ const ParamTypeIterator = struct {
6880 }7287 }
6881 }7288 }
68827289
6883 fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {7290 fn next_x86_64_sysv(it: *ParamTypeIterator, ty: Type) Allocator.Error!Lowering {
6884 const zcu = it.object.zcu;7291 const o = it.object;
6885 const ip = &zcu.intern_pool;7292 const zcu = o.zcu;
6886 ty.assertHasLayout(zcu);7293 const target = zcu.getTarget();
6887 const classes = x86_64_abi.classifySystemV(ty, zcu, zcu.getTarget(), .arg);7294 const classes = x86_64_abi.classifySystemV(ty, zcu, target, .arg);
6888 if (classes[0] == .memory) {7295 var types_len: u32 = 0;
6889 it.zig_index += 1;7296 const classes_len = for (classes, 0..) |class, class_index| switch (class) {
6890 it.llvm_index += 1;7297 .integer => {
6891 it.byval_attr = true;7298 it.types_buffer[types_len] = try o.builder.intType(@min(8 * ty.abiSize(zcu) - 64 * class_index, 64));
6892 return .byref;7299 it.offsets_buffer[types_len] = 8 * class_index;
6893 }7300 types_len += 1;
6894 if (isScalar(zcu, ty)) {7301 },
6895 it.zig_index += 1;7302 .sse => {
6896 it.llvm_index += 1;7303 it.types_buffer[types_len] = .double;
6897 return .byval;7304 it.offsets_buffer[types_len] = 8 * class_index;
6898 }7305 types_len += 1;
6899 var types_index: u32 = 0;7306 },
6900 var offset: u64 = 0;7307 .sseup => {
6901 for (classes) |class| {7308 if (it.types_buffer[types_len - 1] == .double) {
6902 switch (class) {7309 if (ty.isVector(zcu)) {
6903 .integer => {7310 it.zig_index += 1;
6904 it.types_buffer[types_index] = .i64;7311 it.llvm_index += 1;
6905 it.offsets_buffer[types_index] = offset;7312 return .byval;
6906 types_index += 1;
6907 },
6908 .sse => {
6909 it.types_buffer[types_index] = .double;
6910 it.offsets_buffer[types_index] = offset;
6911 types_index += 1;
6912 },
6913 .sseup => {
6914 if (it.types_buffer[types_index - 1] == .double) {
6915 it.types_buffer[types_index - 1] = .fp128;
6916 } else {
6917 it.types_buffer[types_index] = .double;
6918 it.offsets_buffer[types_index] = offset;
6919 types_index += 1;
6920 }7313 }
6921 },7314 it.types_buffer[types_len - 1] = .fp128;
6922 .float => {7315 } else {
6923 it.types_buffer[types_index] = .float;7316 it.types_buffer[types_len] = .double;
6924 it.offsets_buffer[types_index] = offset;7317 it.offsets_buffer[types_len] = 8 * class_index;
6925 types_index += 1;7318 types_len += 1;
6926 },7319 }
6927 .float_combine => {7320 },
6928 it.types_buffer[types_index] = try it.object.builder.vectorType(.normal, 2, .float);7321 .float => {
6929 it.offsets_buffer[types_index] = offset;7322 it.types_buffer[types_len] = .float;
6930 types_index += 1;7323 it.offsets_buffer[types_len] = 8 * class_index;
6931 },7324 types_len += 1;
6932 .x87 => {7325 },
6933 it.zig_index += 1;7326 .float_combine => {
6934 it.llvm_index += 1;7327 it.types_buffer[types_len] = try it.object.builder.vectorType(.normal, 2, .float);
6935 it.byval_attr = true;7328 it.offsets_buffer[types_len] = 8 * class_index;
6936 return .byref;7329 types_len += 1;
6937 },7330 },
6938 .x87up => unreachable,7331 .x87 => {
6939 .none => break,
6940 .memory => unreachable, // handled above
6941 .win_i128 => unreachable, // windows only
6942 .bool_vector_mask,
6943 .integer_per_element,
6944 .sse_per_element,
6945 .sse_sse_x87_per_qword,
6946 .sse_per_xword,
6947 .sse_per_yword,
6948 .sse_per_zword,
6949 => unreachable, // vectors already handled by `isScalar` above
6950 }
6951 offset += 8;
6952 }
6953 const first_non_integer = std.mem.indexOfNone(x86_64_abi.Class, &classes, &.{.integer});
6954 if (first_non_integer == null or classes[first_non_integer.?] == .none) {
6955 assert(first_non_integer orelse classes.len == types_index);
6956 if (types_index == 1) {
6957 it.zig_index += 1;7332 it.zig_index += 1;
6958 it.llvm_index += 1;7333 it.llvm_index += 1;
6959 return .abi_sized_int;7334 it.byval_attr = .{};
6960 }7335 return .byref;
6961 if (it.llvm_index + types_index > 6) {7336 },
7337 .x87up => unreachable,
7338 .none => break class_index,
7339 .memory => {
7340 it.zig_index += 1;
7341 it.llvm_index += 1;
7342 it.byval_attr = .{};
7343 return .byref;
7344 },
7345 .win_i128 => unreachable, // windows only
7346 .bool_vector_mask,
7347 .integer_per_element,
7348 .sse_per_element,
7349 .sse_sse_x87_per_qword,
7350 .sse_per_xword,
7351 .sse_per_yword,
7352 .sse_per_zword,
7353 => {
7354 it.zig_index += 1;
7355 it.llvm_index += 1;
7356 return .byval;
7357 },
7358 } else classes.len;
7359 if (types_len > 1) {
7360 if (it.llvm_index + classes_len > 6) {
6962 it.zig_index += 1;7361 it.zig_index += 1;
6963 it.llvm_index += 1;7362 it.llvm_index += 1;
6964 it.byval_attr = true;7363 it.byval_attr = .{};
6965 return .byref;7364 return .byref;
6966 }7365 }
6967 switch (ip.indexToKey(ty.toIntern())) {7366 } else if (!isByRef(ty, zcu)) {
6968 .struct_type => {7367 const llvm_ty = try o.lowerType(ty, .as_value);
6969 const size = ty.abiSize(zcu);7368 if (it.types_buffer[0] == llvm_ty or
6970 assert(@divCeil(size, 8) == types_index);7369 (it.types_buffer[0] == .i64 and llvm_ty.isPointer(&o.builder)))
6971 if (size % 8 > 0) {7370 {
6972 it.types_buffer[types_index - 1] =7371 it.zig_index += 1;
6973 try it.object.builder.intType(@intCast(size % 8 * 8));7372 it.llvm_index += 1;
6974 }7373 return .byval;
6975 },
6976 else => {},
6977 }7374 }
6978 }7375 }
6979 it.offsets_buffer[types_index] = offset;7376 it.offsets_buffer[types_len] = 8 * classes_len;
6980 it.types_len = types_index;7377 it.types_len = types_len;
6981 it.llvm_index += types_index;7378 it.llvm_index += types_len;
6982 it.zig_index += 1;7379 it.zig_index += 1;
6983 return .multiple_llvm_types;7380 return .multiple_llvm_types;
6984 }7381 }
6985};7382};
6986pub fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTypeIterator {7383pub fn iterateParamTypes(
7384 object: *Object,
7385 cc: std.lang.CallingConvention,
7386 param_types: []const InternPool.Index,
7387) ParamTypeIterator {
6987 return .{7388 return .{
6988 .object = object,7389 .object = object,
6989 .fn_info = fn_info,7390 .cc = cc,
7391 .param_types = param_types,
6990 .zig_index = 0,7392 .zig_index = 0,
6991 .llvm_index = 0,7393 .llvm_index = 0,
6992 .types_len = undefined,7394 .types_len = undefined,
6993 .types_buffer = undefined,7395 .types_buffer = undefined,
6994 .offsets_buffer = undefined,7396 .offsets_buffer = undefined,
6995 .byval_attr = false,7397 .byval_attr = null,
6996 };7398 };
6997}7399}
69987400
...@@ -7017,54 +7419,68 @@ pub const FnReturnStrat = union(enum) {...@@ -7017,54 +7419,68 @@ pub const FnReturnStrat = union(enum) {
7017/// In order to support the C calling convention, some return types need to be lowered7419/// In order to support the C calling convention, some return types need to be lowered
7018/// completely differently in the function prototype to honor the C ABI, and then7420/// completely differently in the function prototype to honor the C ABI, and then
7019/// be effectively bitcasted to the actual return type.7421/// be effectively bitcasted to the actual return type.
7020pub fn fnReturnStrat(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!FnReturnStrat {7422pub fn fnReturnStrat(o: *Object, cc: std.lang.CallingConvention, ret_ty: Type) Allocator.Error!FnReturnStrat {
7021 const zcu = o.zcu;7423 const zcu = o.zcu;
7022 const ret_ty: Type = .fromInterned(fn_info.return_type);
7023 ret_ty.assertHasLayout(zcu);7424 ret_ty.assertHasLayout(zcu);
7024 if (!ret_ty.hasRuntimeBits(zcu)) return .void;7425 if (!ret_ty.hasRuntimeBits(zcu)) return .void;
7025 switch (fn_info.cc) {7426 return switch (cc) {
7026 .@"inline" => unreachable,7427 .@"inline" => unreachable,
7027 .auto => {7428 .auto => {
7028 if (isByRef(ret_ty, zcu)) return .sret;7429 // Match the c calling convention in some cases to avoid llvm bugs.
7029
7030 const target = zcu.getTarget();7430 const target = zcu.getTarget();
7031 if (target.cpu.arch.isX86() and7431 if (target.cpu.arch == .x86_64 and ret_ty.isVector(zcu) and ret_ty.childType(zcu).toIntern() == .bool_type) return switch (ret_ty.vectorLen(zcu)) {
7032 !target.cpu.has(.x86, .avx512f) and7432 0 => .void,
7033 ret_ty.totalVectorBits(zcu) >= 512)7433 1...8 => .{ .mem_cast = .i8 },
7034 {7434 9...16 => .{ .mem_cast = .i16 },
7035 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns7435 17...32 => .{ .mem_cast = .i32 },
7036 // "512-bit vector arguments require 'avx512f' for AVX512"7436 33...64 => .{ .mem_cast = .double },
7037 return .sret;7437 else => .by_val,
7038 }7438 };
70397439 return if (isByRef(ret_ty, zcu)) .sret else .by_val;
7040 return .by_val;
7041 },7440 },
7042 .x86_64_sysv, .x86_64_x32 => return lowerSystemVFnRetTy(o, fn_info),
7043 .x86_64_win => return lowerWin64FnRetTy(o, fn_info),
7044 .x86_stdcall => if (isScalar(zcu, ret_ty)) {
7045 assert(!isByRef(ret_ty, zcu));
7046 return .by_val;
7047 } else return .sret,
7048 .x86_fastcall => return lowerX86FastcallFnRetTy(o, zcu, ret_ty),
7049 .x86_sysv, .x86_win => return if (isByRef(ret_ty, zcu)) .sret else .by_val,
7050 .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => switch (aarch64_c_abi.classifyType(ret_ty, zcu)) {7441 .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => switch (aarch64_c_abi.classifyType(ret_ty, zcu)) {
7051 .memory => return .sret,7442 .memory => .sret,
7052 .float_array, .byval => return .forceByVal(o, ret_ty),7443 .float_array, .byval => .forceByVal(o, ret_ty),
7053 .integer => return .{ .mem_cast = .i64 },7444 .integer => .{ .mem_cast = .i64 },
7054 .double_integer => return .{ .mem_cast = try o.builder.arrayType(2, .i64) },7445 .double_integer => .{ .mem_cast = try o.builder.arrayType(2, .i64) },
7055 },7446 },
7056 .arm_aapcs, .arm_aapcs_vfp => switch (arm_c_abi.classifyType(ret_ty, zcu, .ret)) {7447 .arm_aapcs, .arm_aapcs_vfp => switch (arm_c_abi.classifyType(ret_ty, zcu, .ret)) {
7057 .memory, .i64_array => return .sret,7448 .memory, .i64_array => .sret,
7058 .i32_array => |len| return if (len == 1) .{ .mem_cast = .i32 } else .sret,7449 .i32_array => |len| if (len == 1) .{ .mem_cast = .i32 } else .sret,
7059 .byval => return .forceByVal(o, ret_ty),7450 .byval => .forceByVal(o, ret_ty),
7451 },
7452 .loongarch32_ilp32, .loongarch64_lp64 => switch (loongarch_c_abi.classifyType(ret_ty, zcu)) {
7453 .ignored => .void,
7454 .gar, .far => .by_val,
7455 .member => |member_ty| .{ .mem_cast = try o.lowerType(member_ty, .as_value) },
7456 .member_pair => |member_tys| .{ .mem_cast = try o.builder.structType(.normal, &.{
7457 try o.lowerType(member_tys[0], .as_value),
7458 try o.lowerType(member_tys[1], .as_value),
7459 }) },
7460 .memory_gar => .{ .mem_cast = switch (cc) {
7461 else => unreachable,
7462 .loongarch32_ilp32 => .i32,
7463 .loongarch64_lp64 => .i64,
7464 } },
7465 .memory_gar_pair => .{ .mem_cast = try o.builder.arrayType(2, switch (cc) {
7466 else => unreachable,
7467 .loongarch32_ilp32 => .i32,
7468 .loongarch64_lp64 => .i64,
7469 }) },
7470 .address => .sret,
7060 },7471 },
7061 .mips_o32 => switch (mips_c_abi.classifyType(ret_ty, zcu, .ret)) {7472 .mips_o32 => switch (mips_c_abi.classifyType(ret_ty, zcu, .ret)) {
7062 .memory, .i32_array => return .sret,7473 .memory, .i32_array => .sret,
7063 .byval => return .forceByVal(o, ret_ty),7474 .byval => .forceByVal(o, ret_ty),
7064 },7475 },
7476 .powerpc64_elf_v2 => if (isByRef(ret_ty, zcu)) switch (ret_ty.abiSize(zcu)) {
7477 1...8 => .{ .mem_cast = try o.builder.intType(@intCast(ret_ty.abiSize(zcu) * 8)) },
7478 9...16 => .{ .mem_cast = try o.builder.structType(.normal, &.{ .i64, .i64 }) },
7479 else => .sret,
7480 } else .by_val, // TODO
7065 .riscv64_lp64, .riscv32_ilp32 => switch (riscv_c_abi.classifyType(ret_ty, zcu)) {7481 .riscv64_lp64, .riscv32_ilp32 => switch (riscv_c_abi.classifyType(ret_ty, zcu)) {
7066 .memory => return .sret,7482 .memory => .sret,
7067 .integer => return .{ .mem_cast = try o.builder.intType(@intCast(ret_ty.abiSize(zcu) * 8)) },7483 .integer => .{ .mem_cast = try o.builder.intType(@intCast(ret_ty.abiSize(zcu) * 8)) },
7068 .double_integer => {7484 .double_integer => {
7069 const integer: Builder.Type = switch (zcu.getTarget().cpu.arch) {7485 const integer: Builder.Type = switch (zcu.getTarget().cpu.arch) {
7070 .riscv64, .riscv64be => .i64,7486 .riscv64, .riscv64be => .i64,
...@@ -7073,34 +7489,78 @@ pub fn fnReturnStrat(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err...@@ -7073,34 +7489,78 @@ pub fn fnReturnStrat(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err
7073 };7489 };
7074 return .{ .mem_cast = try o.builder.structType(.normal, &.{ integer, integer }) };7490 return .{ .mem_cast = try o.builder.structType(.normal, &.{ integer, integer }) };
7075 },7491 },
7076 .byval => return .forceByVal(o, ret_ty),7492 .byval => .forceByVal(o, ret_ty),
7077 .fields => {7493 .fields => {
7078 var types_len: usize = 0;7494 var types_len: usize = 0;
7079 var types: [8]Builder.Type = undefined;7495 var types: [8]Builder.Type = undefined;
7080 for (0..ret_ty.structFieldCount(zcu)) |field_index| {7496 for (0..ret_ty.structFieldCount(zcu)) |field_index| {
7081 const field_ty = ret_ty.fieldType(field_index, zcu);7497 const field_ty = ret_ty.fieldType(field_index, zcu);
7082 if (!field_ty.hasRuntimeBits(zcu)) continue;7498 if (!field_ty.hasRuntimeBits(zcu)) continue;
7083 types[types_len] = try o.lowerType(field_ty, .by_value);7499 types[types_len] = try o.lowerType(field_ty, .as_value);
7084 types_len += 1;7500 types_len += 1;
7085 }7501 }
7086 return .{ .mem_cast = try o.builder.structType(.normal, types[0..types_len]) };7502 return .{ .mem_cast = try o.builder.structType(.normal, types[0..types_len]) };
7087 },7503 },
7088 },7504 },
7505 .s390x_sysv, .s390x_sysv_vx => switch (s390x_c_abi.classifyType(ret_ty, .ret, zcu)) {
7506 .none => .void,
7507 .double_or_float, .vector, .simple => .by_val,
7508 .simple_aggregate => unreachable,
7509 .pointer => .sret,
7510 },
7089 .wasm_mvp => switch (wasm_c_abi.classifyType(ret_ty, zcu)) {7511 .wasm_mvp => switch (wasm_c_abi.classifyType(ret_ty, zcu)) {
7090 .direct => |scalar_ty| if (scalar_ty.toIntern() == ret_ty.toIntern()) {7512 .direct => |scalar_ty| if (scalar_ty.toIntern() == ret_ty.toIntern()) {
7091 assert(!isByRef(ret_ty, zcu));7513 assert(!isByRef(ret_ty, zcu));
7092 return .by_val;7514 return .by_val;
7093 } else {7515 } else .{ .mem_cast = try o.lowerType(scalar_ty, .as_value) },
7094 return .{ .mem_cast = try o.lowerType(scalar_ty, .by_value) };7516 .indirect => .sret,
7095 },
7096 .indirect => return .sret,
7097 },7517 },
7518 .x86_stdcall => if (isScalar(zcu, ret_ty)) {
7519 assert(!isByRef(ret_ty, zcu));
7520 return .by_val;
7521 } else .sret,
7522 .x86_fastcall => fnReturnStrat_x86_fastcall(o, zcu, ret_ty),
7523 .x86_sysv, .x86_win, .x86_mingw => if (isByRef(ret_ty, zcu)) {
7524 switch (cc) {
7525 else => unreachable,
7526 .x86_sysv => return .sret,
7527 .x86_win => {},
7528 .x86_mingw => {
7529 var items_buf: [1]codegen.FlattenedItem = undefined;
7530 if (codegen.flattenType(&items_buf, ret_ty, zcu, .{})) |items| one_float: {
7531 if (items.len != 1 or items[0].offset != 0) break :one_float;
7532 const item_ty = items[0].type orelse break :one_float;
7533 if (!item_ty.isRuntimeFloat()) break :one_float;
7534 return .{ .mem_cast = switch (item_ty.floatBits(zcu.getTarget())) {
7535 else => unreachable,
7536 16 => .half,
7537 32 => .float,
7538 64 => .double,
7539 80, 128 => break :one_float,
7540 } };
7541 }
7542 },
7543 }
7544 return switch (ret_ty.abiSize(zcu)) {
7545 0 => .void,
7546 1 => .{ .mem_cast = .i8 },
7547 2 => .{ .mem_cast = .i16 },
7548 4 => .{ .mem_cast = .i32 },
7549 8 => .{ .mem_cast = .i64 },
7550 else => .sret,
7551 };
7552 } else if (ret_ty.isAbiInt(zcu) and ret_ty.intInfo(zcu).bits > 64)
7553 .sret
7554 else
7555 .by_val,
7556 .x86_64_sysv, .x86_64_x32 => fnReturnStrat_x86_64_sysv(o, ret_ty),
7557 .x86_64_win => fnReturnStrat_x86_64_win(o, ret_ty),
7098 // TODO investigate other callconvs7558 // TODO investigate other callconvs
7099 else => return .forceByVal(o, ret_ty),7559 else => .forceByVal(o, ret_ty),
7100 }7560 };
7101}7561}
71027562
7103fn lowerX86FastcallFnRetTy(o: *Object, zcu: *Zcu, ty: Type) Allocator.Error!FnReturnStrat {7563fn fnReturnStrat_x86_fastcall(o: *Object, zcu: *Zcu, ty: Type) Allocator.Error!FnReturnStrat {
7104 if (isScalar(zcu, ty)) {7564 if (isScalar(zcu, ty)) {
7105 assert(!isByRef(ty, zcu));7565 assert(!isByRef(ty, zcu));
7106 return .by_val;7566 return .by_val;
...@@ -7115,9 +7575,8 @@ fn lowerX86FastcallFnRetTy(o: *Object, zcu: *Zcu, ty: Type) Allocator.Error!FnRe...@@ -7115,9 +7575,8 @@ fn lowerX86FastcallFnRetTy(o: *Object, zcu: *Zcu, ty: Type) Allocator.Error!FnRe
7115 return .sret;7575 return .sret;
7116}7576}
71177577
7118fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!FnReturnStrat {7578fn fnReturnStrat_x86_64_win(o: *Object, ret_ty: Type) Allocator.Error!FnReturnStrat {
7119 const zcu = o.zcu;7579 const zcu = o.zcu;
7120 const ret_ty = Type.fromInterned(fn_info.return_type);
7121 switch (x86_64_abi.classifyWindows(ret_ty, zcu, zcu.getTarget(), .ret)) {7580 switch (x86_64_abi.classifyWindows(ret_ty, zcu, zcu.getTarget(), .ret)) {
7122 .integer => if (isScalar(zcu, ret_ty)) {7581 .integer => if (isScalar(zcu, ret_ty)) {
7123 assert(!isByRef(ret_ty, zcu));7582 assert(!isByRef(ret_ty, zcu));
...@@ -7150,78 +7609,65 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err...@@ -7150,78 +7609,65 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err
7150 }7609 }
7151}7610}
71527611
7153fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!FnReturnStrat {7612fn fnReturnStrat_x86_64_sysv(o: *Object, ret_ty: Type) Allocator.Error!FnReturnStrat {
7154 const zcu = o.zcu;7613 const zcu = o.zcu;
7155 const ip = &zcu.intern_pool;
7156 const ret_ty = Type.fromInterned(fn_info.return_type);
7157 if (isScalar(zcu, ret_ty)) {
7158 assert(!isByRef(ret_ty, zcu));
7159 return .by_val;
7160 }
7161 const classes = x86_64_abi.classifySystemV(ret_ty, zcu, zcu.getTarget(), .ret);7614 const classes = x86_64_abi.classifySystemV(ret_ty, zcu, zcu.getTarget(), .ret);
7162 var types_index: u32 = 0;
7163 var types_buffer: [8]Builder.Type = undefined;7615 var types_buffer: [8]Builder.Type = undefined;
7164 for (classes) |class| {7616 var types_len: u32 = 0;
7165 switch (class) {7617 for (classes, 0..) |class, class_index| switch (class) {
7166 .integer => {7618 .integer => {
7167 types_buffer[types_index] = .i64;7619 types_buffer[types_len] = try o.builder.intType(@min(8 * ret_ty.abiSize(zcu) - 64 * class_index, 64));
7168 types_index += 1;7620 types_len += 1;
7169 },7621 },
7170 .sse => {7622 .sse => {
7171 types_buffer[types_index] = .double;7623 types_buffer[types_len] = .double;
7172 types_index += 1;7624 types_len += 1;
7173 },7625 },
7174 .sseup => {7626 .sseup => {
7175 if (types_buffer[types_index - 1] == .double) {7627 if (types_buffer[types_len - 1] == .double) {
7176 types_buffer[types_index - 1] = .fp128;7628 if (ret_ty.isVector(zcu)) return .by_val;
7177 } else {7629 types_buffer[types_len - 1] = .fp128;
7178 types_buffer[types_index] = .double;7630 } else {
7179 types_index += 1;7631 types_buffer[types_len] = .double;
7180 }7632 types_len += 1;
7181 },7633 }
7182 .float => {7634 },
7183 types_buffer[types_index] = .float;7635 .float => {
7184 types_index += 1;7636 types_buffer[types_len] = .float;
7185 },7637 types_len += 1;
7186 .float_combine => {7638 },
7187 types_buffer[types_index] = try o.builder.vectorType(.normal, 2, .float);7639 .float_combine => {
7188 types_index += 1;7640 types_buffer[types_len] = try o.builder.vectorType(.normal, 2, .float);
7189 },7641 types_len += 1;
7190 .x87 => {7642 },
7191 if (types_index != 0 or classes[2] != .none) return .sret;7643 .x87 => {
7192 types_buffer[types_index] = .x86_fp80;7644 if (types_len > 0 or classes[2] != .none) return .sret;
7193 types_index += 1;7645 types_buffer[types_len] = .x86_fp80;
7194 },7646 types_len += 1;
7195 .x87up => continue,7647 },
7196 .none => break,7648 .x87up => continue,
7197 .memory => return .sret,7649 .none => break,
7198 .win_i128 => unreachable, // windows only7650 .memory => return if (ret_ty.isVector(zcu)) .by_val else .sret,
7199 .bool_vector_mask,7651 .win_i128 => unreachable, // windows only
7200 .integer_per_element,7652 .bool_vector_mask,
7201 .sse_per_element,7653 .integer_per_element,
7202 .sse_sse_x87_per_qword,7654 .sse_per_element,
7203 .sse_per_xword,7655 .sse_sse_x87_per_qword,
7204 .sse_per_yword,7656 .sse_per_xword,
7205 .sse_per_zword,7657 .sse_per_yword,
7206 => unreachable, // vectors already handled by `isScalar` above7658 .sse_per_zword,
7207 }7659 => return .by_val,
7208 }7660 };
7209 const first_non_integer = std.mem.indexOfNone(x86_64_abi.Class, &classes, &.{.integer});7661 if (types_len > 1) return .{ .mem_cast = try o.builder.structType(.normal, types_buffer[0..types_len]) };
7210 if (first_non_integer == null or classes[first_non_integer.?] == .none) {7662 if (!isByRef(ret_ty, zcu)) {
7211 assert(first_non_integer orelse classes.len == types_index);7663 const llvm_ty = try o.lowerType(ret_ty, .as_value);
7212 switch (ip.indexToKey(ret_ty.toIntern())) {7664 if (types_buffer[0] == llvm_ty) return .by_val;
7213 .struct_type => {7665 if (types_buffer[0] == .i64 and llvm_ty.isPointer(&o.builder)) return .by_val;
7214 const size = ret_ty.abiSize(zcu);7666 if (types_buffer[0] == .double and llvm_ty.isVector(&o.builder) and
7215 assert(@divCeil(size, 8) == types_index);7667 llvm_ty.vectorLen(&o.builder) == 1 and
7216 if (size % 8 > 0) {7668 llvm_ty.scalarType(&o.builder) == .double) return .by_val;
7217 types_buffer[types_index - 1] = try o.builder.intType(@intCast(size % 8 * 8));
7218 }
7219 },
7220 else => {},
7221 }
7222 if (types_index == 1) return .{ .mem_cast = types_buffer[0] };
7223 }7669 }
7224 return .{ .mem_cast = try o.builder.structType(.normal, types_buffer[0..types_index]) };7670 return .{ .mem_cast = types_buffer[0] };
7225}7671}
72267672
7227/// This function deliberately does not handle `_BitInt` because it typically7673/// This function deliberately does not handle `_BitInt` because it typically
...@@ -7234,15 +7680,22 @@ pub fn ccAbiPromoteInt(cc: std.lang.CallingConvention, zcu: *Zcu, ty: Type) ?std...@@ -7234,15 +7680,22 @@ pub fn ccAbiPromoteInt(cc: std.lang.CallingConvention, zcu: *Zcu, ty: Type) ?std
7234 else => {},7680 else => {},
7235 }7681 }
72367682
7237 const ty_tag = ty.zigTypeTag(zcu);7683 const target = zcu.getTarget();
7238 const int_info = switch (ty_tag) {7684 const int_info: std.lang.Type.Int = if (ty.toIntern() == .bool_type)
7239 .bool => Type.u1.intInfo(zcu),7685 .{ .signedness = .unsigned, .bits = 1 }
7240 else => if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else return null,7686 else if (ty.isAbiInt(zcu))
7241 };7687 ty.intInfo(zcu)
7688 else if (ty.isRuntimeFloat()) switch (ty.floatBits(target)) {
7689 else => unreachable,
7690 16, 32, 64 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
7691 .hard => return null,
7692 .soft => .{ .signedness = .unsigned, .bits = bits },
7693 },
7694 80, 128 => return null,
7695 } else return null;
72427696
7243 assert(int_info.bits == 0 or (int_info.bits == 1 and ty_tag == .bool) or std.math.isPowerOfTwo(int_info.bits));7697 assert(int_info.bits == 0 or (int_info.bits == 1 and ty.toIntern() == .bool_type) or std.math.isPowerOfTwo(int_info.bits));
72447698
7245 const target = zcu.getTarget();
7246 return switch (target.cpu.arch) {7699 return switch (target.cpu.arch) {
7247 .aarch64,7700 .aarch64,
7248 .aarch64_be,7701 .aarch64_be,
...@@ -7338,15 +7791,26 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool {...@@ -7338,15 +7791,26 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool {
7338 .void,7791 .void,
7339 .bool,7792 .bool,
7340 .int,7793 .int,
7341 .float,
7342 .pointer,7794 .pointer,
7343 .error_set,7795 .error_set,
7344 .@"fn",7796 .@"fn",
7345 .@"enum",7797 .@"enum",
7346 .vector,
7347 .@"anyframe",7798 .@"anyframe",
7348 => false,7799 => false,
73497800
7801 .float, .vector => {
7802 const target = zcu.getTarget();
7803 const scalar_ty = ty.scalarType(zcu);
7804 return if (scalar_ty.isRuntimeFloat()) switch (scalar_ty.floatBits(target)) {
7805 else => unreachable,
7806 16, 32, 64 => false,
7807 80, 128 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
7808 .hard => false,
7809 .soft => true,
7810 },
7811 } else false;
7812 },
7813
7350 .array,7814 .array,
7351 .frame,7815 .frame,
7352 => ty.hasRuntimeBits(zcu),7816 => ty.hasRuntimeBits(zcu),
...@@ -7392,7 +7856,7 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E...@@ -7392,7 +7856,7 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E
7392fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value {7856fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value {
7393 if (offset == 0) return ptr;7857 if (offset == 0) return ptr;
7394 const o = fg.object;7858 const o = fg.object;
7395 const llvm_usize_ty = try o.lowerType(.usize, .by_value);7859 const llvm_usize_ty = try o.lowerType(.usize, .as_value);
7396 const offset_val = try o.builder.intValue(llvm_usize_ty, offset);7860 const offset_val = try o.builder.intValue(llvm_usize_ty, offset);
7397 return fg.wip.gep(.inbounds, .i8, ptr, &.{offset_val}, "");7861 return fg.wip.gep(.inbounds, .i8, ptr, &.{offset_val}, "");
7398}7862}
...@@ -7407,12 +7871,19 @@ fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u...@@ -7407,12 +7871,19 @@ fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u
7407 return fg.wip.gep(.inbounds, llvm_scale_ty, ptr, &.{index}, "");7871 return fg.wip.gep(.inbounds, llvm_scale_ty, ptr, &.{index}, "");
7408}7872}
74097873
7410fn compilerRtIntBits(bits: u16) ?u16 {7874fn compilerRtPromoteInt(int_info: InternPool.Key.IntType) ?Type {
7411 inline for (.{ 32, 64, 128 }) |b| {7875 if (int_info.bits <= 32) return switch (int_info.signedness) {
7412 if (bits <= b) {7876 .signed => .i32,
7413 return b;7877 .unsigned => .u32,
7414 }7878 };
7415 }7879 if (int_info.bits <= 64) return switch (int_info.signedness) {
7880 .signed => .i64,
7881 .unsigned => .u64,
7882 };
7883 if (int_info.bits <= 128) return switch (int_info.signedness) {
7884 .signed => .i128,
7885 .unsigned => .u128,
7886 };
7416 return null;7887 return null;
7417}7888}
74187889
...@@ -7471,13 +7942,21 @@ fn appendConstraints(...@@ -7471,13 +7942,21 @@ fn appendConstraints(
7471}7942}
74727943
7473/// LLVM does not support all relevant intrinsics for all targets, so we7944/// LLVM does not support all relevant intrinsics for all targets, so we
7474/// may need to manually generate a compiler-rt call.7945/// may need to manually generate a compiler-rt call using a soft type.
7475fn intrinsicsAllowed(scalar_ty: Type, target: *const std.Target) bool {7946fn intrinsicsAllowed(kind: enum { compiler_rt, libc }, scalar_ty: Type, target: *const std.Target) bool {
7476 return switch (scalar_ty.toIntern()) {7947 if (!scalar_ty.isRuntimeFloat()) return true;
7477 .f16_type => llvm.backendSupportsF16(target),7948 const bits = scalar_ty.floatBits(target);
7478 .f80_type => (target.cTypeBitSize(.longdouble) == 80) and llvm.backendSupportsF80(target),7949 // Since upstream musl/msvc do not actually define the *f128 functions, llvm decides
7479 .f128_type => (target.cTypeBitSize(.longdouble) == 128) and llvm.backendSupportsF128(target),7950 // that it is a much better idea to just emit a call to the entirely wrong function as
7480 else => true,7951 // a fallback. We wouldn't want any linker errors when trying to perform an operation
7952 // that isn't actually implemented anywhere, now would we!
7953 if (bits == 128 and target.cpu.arch.isX86() and !target.abi.isGnu()) return switch (kind) {
7954 .compiler_rt => true,
7955 .libc => false,
7956 };
7957 return switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
7958 .hard => true,
7959 .soft => false,
7481 };7960 };
7482}7961}
74837962
...@@ -7823,12 +8302,14 @@ const Builder = std.zig.llvm.Builder;...@@ -7823,12 +8302,14 @@ const Builder = std.zig.llvm.Builder;
7823const assert = std.debug.assert;8302const assert = std.debug.assert;
7824const math = std.math;8303const math = std.math;
78258304
7826const x86_64_abi = @import("../x86_64/abi.zig");
7827const wasm_c_abi = @import("../wasm/abi.zig");
7828const aarch64_c_abi = @import("../aarch64/abi.zig");8305const aarch64_c_abi = @import("../aarch64/abi.zig");
7829const arm_c_abi = @import("../arm/abi.zig");8306const arm_c_abi = @import("../arm/abi.zig");
7830const riscv_c_abi = @import("../riscv64/abi.zig");8307const loongarch_c_abi = @import("../loongarch/abi.zig");
7831const mips_c_abi = @import("../mips/abi.zig");8308const mips_c_abi = @import("../mips/abi.zig");
8309const riscv_c_abi = @import("../riscv64/abi.zig");
8310const s390x_c_abi = @import("../s390x/abi.zig");
8311const wasm_c_abi = @import("../wasm/abi.zig");
8312const x86_64_abi = @import("../x86_64/abi.zig");
78328313
7833const Zcu = @import("../../Zcu.zig");8314const Zcu = @import("../../Zcu.zig");
7834const Air = @import("../../Air.zig");8315const Air = @import("../../Air.zig");
src/codegen/loongarch/abi.zig created+133
...@@ -0,0 +1,133 @@
1const std = @import("std");
2const InternPool = @import("../../InternPool.zig");
3const Type = @import("../../Type.zig");
4const Zcu = @import("../../Zcu.zig");
5
6pub const Class = union(enum) {
7 ignored,
8 gar,
9 far,
10 member: Type,
11 member_pair: [2]Type,
12 memory_gar,
13 memory_gar_pair,
14 address,
15
16 fn combineMember(container_class: Class, member_class: Class, member_ty: Type) Class {
17 const second_member_ty = switch (member_class) {
18 .ignored => return container_class,
19 .gar, .far => member_ty,
20 .member => |second_member_ty| second_member_ty,
21 .member_pair, .memory_gar, .memory_gar_pair, .address => return .address,
22 };
23 return switch (container_class) {
24 .ignored => .{ .member = second_member_ty },
25 .gar, .far, .memory_gar, .memory_gar_pair => unreachable,
26 .member => |first_member_ty| .{ .member_pair = .{ first_member_ty, second_member_ty } },
27 .member_pair, .address => .address,
28 };
29 }
30};
31
32pub fn classifyType(ty: Type, zcu: *Zcu) Class {
33 return Classifier.init(zcu).classifyType(ty);
34}
35
36const Classifier = struct {
37 zcu: *Zcu,
38 target: *const std.Target,
39 grlen: u8,
40 frlen: u8,
41
42 fn init(zcu: *Zcu) Classifier {
43 const target = zcu.getTarget();
44 return .{
45 .zcu = zcu,
46 .target = target,
47 .grlen = switch (target.cpu.arch) {
48 else => unreachable,
49 .loongarch32 => 32,
50 .loongarch64 => 64,
51 },
52 .frlen = if (target.cpu.has(.loongarch, .d))
53 64
54 else if (target.cpu.has(.loongarch, .f))
55 32
56 else
57 0,
58 };
59 }
60
61 fn classifyType(c: Classifier, ty: Type) Class {
62 switch (ty.zigTypeTag(c.zcu)) {
63 .type,
64 .comptime_float,
65 .comptime_int,
66 .undefined,
67 .null,
68 .error_union,
69 .error_set,
70 .@"fn",
71 .@"opaque",
72 .frame,
73 .@"anyframe",
74 .enum_literal,
75 .spirv,
76 => unreachable,
77 .void, .noreturn => return .ignored,
78 .bool => return .gar,
79 .int, .@"enum" => {
80 const bits = ty.intInfo(c.zcu).bits;
81 if (bits == 0) return .ignored;
82 if (bits <= c.grlen) return .gar;
83 if (bits <= 2 * c.grlen) return .memory_gar_pair;
84 return .address;
85 },
86 .float => {
87 const bits = ty.floatBits(c.target);
88 if (bits <= c.frlen) return .far;
89 if (bits <= c.grlen) return .gar;
90 if (bits <= 2 * c.grlen) return .memory_gar_pair;
91 return .address;
92 },
93 .pointer, .optional => return .gar,
94 .array => {
95 var class: Class = .ignored;
96 const elem_ty = ty.childType(c.zcu);
97 const elem_class = c.classifyType(elem_ty);
98 for (0..std.math.lossyCast(usize, ty.arrayLen(c.zcu))) |_| {
99 class = class.combineMember(elem_class, elem_ty);
100 if (class == .address) break;
101 }
102 if (class != .address) return class;
103 },
104 .@"struct" => switch (ty.containerLayout(c.zcu)) {
105 .auto => unreachable,
106 .@"extern" => {
107 var class: Class = .ignored;
108 var field_it: InternPool.LoadedStructType.RuntimeOrderIterator = if (c.zcu.typeToStruct(ty)) |loaded_struct|
109 loaded_struct.iterateRuntimeOrder(&c.zcu.intern_pool)
110 else
111 .{ .runtime_order = null, .fields_len = ty.structFieldCount(c.zcu), .next_index = 0 };
112 while (field_it.next()) |field_index| {
113 const field_ty = ty.fieldType(field_index, c.zcu);
114 class = class.combineMember(c.classifyType(field_ty), field_ty);
115 if (class == .address) break;
116 }
117 if (class != .address) return class;
118 },
119 .@"packed" => return c.classifyType(ty.backingIntType(c.zcu)),
120 },
121 .@"union" => switch (ty.containerLayout(c.zcu)) {
122 .auto => unreachable,
123 .@"extern" => {},
124 .@"packed" => return c.classifyType(ty.backingIntType(c.zcu)),
125 },
126 .vector => {},
127 }
128 const size = ty.abiSize(c.zcu);
129 if (size <= @divExact(c.grlen, 8)) return .memory_gar;
130 if (size <= @divExact(2 * c.grlen, 8)) return .memory_gar_pair;
131 return .address;
132 }
133};
src/codegen/mips/abi.zig+8-1
...@@ -38,7 +38,14 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {...@@ -38,7 +38,14 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
38 return .byval;38 return .byval;
39 },39 },
40 .bool => return .byval,40 .bool => return .byval,
41 .float => return .byval,41 .float => return switch (ty.floatBits(target)) {
42 else => unreachable,
43 16, 32, 64 => .byval,
44 80, 128 => switch (max_direct_size) {
45 else => unreachable,
46 64 => .memory,
47 },
48 },
42 .int, .@"enum", .error_set => {49 .int, .@"enum", .error_set => {
43 return .byval;50 return .byval;
44 },51 },
src/codegen/riscv64/CodeGen.zig+2-2
...@@ -5036,7 +5036,7 @@ fn airRet(func: *Func, inst: Air.Inst.Index, safety: bool) !void {...@@ -5036,7 +5036,7 @@ fn airRet(func: *Func, inst: Air.Inst.Index, safety: bool) !void {
5036 .register_pair,5036 .register_pair,
5037 => {5037 => {
5038 if (ret_ty.isVector(zcu)) {5038 if (ret_ty.isVector(zcu)) {
5039 const bit_size = ret_ty.totalVectorBits(zcu);5039 const bit_size = ret_ty.bitSize(zcu);
50405040
5041 // set the vtype to hold the entire vector's contents in a single element5041 // set the vtype to hold the entire vector's contents in a single element
5042 try func.setVl(.zero, 0, .{5042 try func.setVl(.zero, 0, .{
...@@ -6871,7 +6871,7 @@ fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError!...@@ -6871,7 +6871,7 @@ fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError!
6871 // size to the total size of the vector, and vmv.x.s will work then6871 // size to the total size of the vector, and vmv.x.s will work then
6872 if (src_reg.class() == .vector) {6872 if (src_reg.class() == .vector) {
6873 try func.setVl(.zero, 0, .{6873 try func.setVl(.zero, 0, .{
6874 .vsew = switch (ty.totalVectorBits(zcu)) {6874 .vsew = switch (ty.bitSize(zcu)) {
6875 8 => .@"8",6875 8 => .@"8",
6876 16 => .@"16",6876 16 => .@"16",
6877 32 => .@"32",6877 32 => .@"32",
src/codegen/riscv64/abi.zig+10-2
...@@ -56,12 +56,20 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {...@@ -56,12 +56,20 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {
56 return .integer;56 return .integer;
57 },57 },
58 .bool => return .integer,58 .bool => return .integer,
59 .float => return .byval,
60 .int, .@"enum", .error_set => {59 .int, .@"enum", .error_set => {
61 const bit_size = ty.bitSize(zcu);60 const bit_size = ty.bitSize(zcu);
62 if (bit_size > max_byval_size) return .memory;61 if (bit_size > max_byval_size) return .memory;
63 return .byval;62 return .byval;
64 },63 },
64 .float => return switch (ty.floatBits(target)) {
65 else => unreachable,
66 16, 32, 64, 128 => .byval,
67 80 => switch (max_byval_size) {
68 else => unreachable,
69 64 => .memory,
70 128 => .double_integer,
71 },
72 },
65 .vector => {73 .vector => {
66 const bit_size = ty.bitSize(zcu);74 const bit_size = ty.bitSize(zcu);
67 if (bit_size > max_byval_size) return .memory;75 if (bit_size > max_byval_size) return .memory;
...@@ -190,7 +198,7 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {...@@ -190,7 +198,7 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {
190 },198 },
191 .vector => {199 .vector => {
192 // we pass vectors through integer registers if they are small enough to fit.200 // we pass vectors through integer registers if they are small enough to fit.
193 const vec_bits = ty.totalVectorBits(zcu);201 const vec_bits = ty.bitSize(zcu);
194 if (vec_bits <= 64) {202 if (vec_bits <= 64) {
195 result[0] = .integer;203 result[0] = .integer;
196 return result;204 return result;
src/codegen/s390x/abi.zig created+92
...@@ -0,0 +1,92 @@
1const assert = std.debug.assert;
2const std = @import("std");
3const InternPool = @import("../../InternPool.zig");
4const Type = @import("../../Type.zig");
5const Zcu = @import("../../Zcu.zig");
6
7pub const Context = enum { ret, arg };
8
9pub const Class = enum {
10 none,
11 double_or_float,
12 vector,
13 simple,
14 simple_aggregate,
15 pointer,
16};
17
18pub fn classifyType(ty: Type, context: Context, zcu: *Zcu) Class {
19 tag: switch (ty.zigTypeTag(zcu)) {
20 .type,
21 .comptime_float,
22 .comptime_int,
23 .undefined,
24 .null,
25 .error_union,
26 .error_set,
27 .@"fn",
28 .@"opaque",
29 .frame,
30 .@"anyframe",
31 .enum_literal,
32 .spirv,
33 => unreachable,
34 .void, .noreturn => return .none,
35 .bool => return .simple,
36 .int, .@"enum" => return switch (ty.intInfo(zcu).bits) {
37 0 => .none,
38 1...64 => .simple,
39 else => .pointer,
40 },
41 .float => switch (ty.floatBits(zcu.getTarget())) {
42 else => unreachable,
43 16, 32, 64 => return .double_or_float,
44 80 => {},
45 128 => return .pointer,
46 },
47 .pointer, .optional => return .simple,
48 .array => switch (ty.arrayLen(zcu)) {
49 0 => return .none,
50 1 => switch (context) {
51 .ret => {},
52 .arg => return classifyType(ty.childType(zcu), context, zcu),
53 },
54 else => {},
55 },
56 .@"struct", .@"union" => |tag| switch (ty.containerLayout(zcu)) {
57 .auto => unreachable,
58 .@"extern" => switch (context) {
59 .ret => {},
60 .arg => {
61 var class: Class = .none;
62 for (0..switch (tag) {
63 else => unreachable,
64 .@"struct" => ty.structFieldCount(zcu),
65 .@"union" => ty.unionTagTypeHypothetical(zcu).enumFieldCount(zcu),
66 }) |field_index| {
67 switch (tag) {
68 else => unreachable,
69 .@"struct" => if (ty.structFieldIsComptime(field_index, zcu)) continue,
70 .@"union" => {},
71 }
72 const field_class = classifyType(ty.fieldType(field_index, zcu), context, zcu);
73 if (field_class == .none) continue;
74 if (class != .none) break :tag;
75 class = field_class;
76 }
77 return class;
78 },
79 },
80 .@"packed" => return classifyType(ty.backingIntType(zcu), context, zcu),
81 },
82 .vector => return if (ty.abiSize(zcu) <= 16) .vector else .pointer,
83 }
84 return switch (ty.abiSize(zcu)) {
85 0 => .none,
86 1, 2, 4, 8 => switch (context) {
87 .ret => .pointer,
88 .arg => .simple_aggregate,
89 },
90 else => .pointer,
91 };
92}
src/codegen/wasm/CodeGen.zig+25-31
...@@ -24,12 +24,6 @@ const Alignment = InternPool.Alignment;...@@ -24,12 +24,6 @@ const Alignment = InternPool.Alignment;
24const errUnionPayloadOffset = codegen.errUnionPayloadOffset;24const errUnionPayloadOffset = codegen.errUnionPayloadOffset;
25const errUnionErrorOffset = codegen.errUnionErrorOffset;25const errUnionErrorOffset = codegen.errUnionErrorOffset;
2626
27const target_util = @import("../../target.zig");
28const libcFloatPrefix = target_util.libcFloatPrefix;
29const libcFloatSuffix = target_util.libcFloatSuffix;
30const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev;
31const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;
32
33pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features {27pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features {
34 return comptime &.initMany(&.{28 return comptime &.initMany(&.{
35 .expand_bit_cast_safe,29 .expand_bit_cast_safe,
...@@ -2515,15 +2509,15 @@ const IntType = struct {...@@ -2515,15 +2509,15 @@ const IntType = struct {
2515 .anyerror, .adhoc_inferred_error_set => .{ .is_signed = false, .bits = zcu.errorSetBits() },2509 .anyerror, .adhoc_inferred_error_set => .{ .is_signed = false, .bits = zcu.errorSetBits() },
2516 .isize => .{ .is_signed = true, .bits = cg.target.ptrBitWidth() },2510 .isize => .{ .is_signed = true, .bits = cg.target.ptrBitWidth() },
2517 .usize => .{ .is_signed = false, .bits = cg.target.ptrBitWidth() },2511 .usize => .{ .is_signed = false, .bits = cg.target.ptrBitWidth() },
2518 .c_char => .{ .is_signed = cg.target.cCharSignedness() == .signed, .bits = cg.target.cTypeBitSize(.char) },2512 .c_char => .{ .is_signed = cg.target.cCharSignedness().? == .signed, .bits = cg.target.cTypeBitSize(.char).? },
2519 .c_short => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.short) },2513 .c_short => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.short).? },
2520 .c_ushort => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.short) },2514 .c_ushort => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.short).? },
2521 .c_int => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.int) },2515 .c_int => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.int).? },
2522 .c_uint => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.int) },2516 .c_uint => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.int).? },
2523 .c_long => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.long) },2517 .c_long => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.long).? },
2524 .c_ulong => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.long) },2518 .c_ulong => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.long).? },
2525 .c_longlong => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.longlong) },2519 .c_longlong => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.longlong).? },
2526 .c_ulonglong => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.longlong) },2520 .c_ulonglong => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.longlong).? },
2527 .f16, .f32, .f64, .f80, .f128, .c_longdouble => unreachable,2521 .f16, .f32, .f64, .f80, .f128, .c_longdouble => unreachable,
2528 .anyopaque, .void, .type, .comptime_int, .comptime_float, .noreturn, .null, .undefined, .enum_literal, .generic_poison => unreachable,2522 .anyopaque, .void, .type, .comptime_int, .comptime_float, .noreturn, .null, .undefined, .enum_literal, .generic_poison => unreachable,
2529 },2523 },
...@@ -4340,7 +4334,7 @@ fn floatRem(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV...@@ -4340,7 +4334,7 @@ fn floatRem(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV
4340 .f32 => return cg.callIntrinsic(.fmodf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }),4334 .f32 => return cg.callIntrinsic(.fmodf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }),
4341 .f64 => return cg.callIntrinsic(.fmod, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }),4335 .f64 => return cg.callIntrinsic(.fmod, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }),
4342 .f80 => return cg.callIntrinsic(.__fmodx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }),4336 .f80 => return cg.callIntrinsic(.__fmodx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }),
4343 .f128 => return cg.callIntrinsic(.fmodq, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }),4337 .f128 => return cg.callIntrinsic(.fmodf128, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }),
4344 }4338 }
4345}4339}
43464340
...@@ -4376,7 +4370,7 @@ fn floatMax(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV...@@ -4376,7 +4370,7 @@ fn floatMax(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV
4376 .f32 => return cg.callIntrinsic(.fmaxf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }),4370 .f32 => return cg.callIntrinsic(.fmaxf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }),
4377 .f64 => return cg.callIntrinsic(.fmax, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }),4371 .f64 => return cg.callIntrinsic(.fmax, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }),
4378 .f80 => return cg.callIntrinsic(.__fmaxx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }),4372 .f80 => return cg.callIntrinsic(.__fmaxx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }),
4379 .f128 => return cg.callIntrinsic(.fmaxq, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }),4373 .f128 => return cg.callIntrinsic(.fmaxf128, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }),
4380 }4374 }
4381}4375}
43824376
...@@ -4387,7 +4381,7 @@ fn floatMin(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV...@@ -4387,7 +4381,7 @@ fn floatMin(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV
4387 .f32 => return cg.callIntrinsic(.fminf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }),4381 .f32 => return cg.callIntrinsic(.fminf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }),
4388 .f64 => return cg.callIntrinsic(.fmin, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }),4382 .f64 => return cg.callIntrinsic(.fmin, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }),
4389 .f80 => return cg.callIntrinsic(.__fminx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }),4383 .f80 => return cg.callIntrinsic(.__fminx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }),
4390 .f128 => return cg.callIntrinsic(.fminq, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }),4384 .f128 => return cg.callIntrinsic(.fminf128, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }),
4391 }4385 }
4392}4386}
43934387
...@@ -4405,7 +4399,7 @@ fn floatSqrt(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4405,7 +4399,7 @@ fn floatSqrt(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4405 return .stack;4399 return .stack;
4406 },4400 },
4407 .f80 => return cg.callIntrinsic(.__sqrtx, &.{.f80_type}, Type.f80, &.{arg}),4401 .f80 => return cg.callIntrinsic(.__sqrtx, &.{.f80_type}, Type.f80, &.{arg}),
4408 .f128 => return cg.callIntrinsic(.sqrtq, &.{.f128_type}, Type.f128, &.{arg}),4402 .f128 => return cg.callIntrinsic(.sqrtf128, &.{.f128_type}, Type.f128, &.{arg}),
4409 }4403 }
4410}4404}
44114405
...@@ -4415,7 +4409,7 @@ fn floatSin(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4415,7 +4409,7 @@ fn floatSin(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4415 .f32 => return cg.callIntrinsic(.sinf, &.{.f32_type}, Type.f32, &.{arg}),4409 .f32 => return cg.callIntrinsic(.sinf, &.{.f32_type}, Type.f32, &.{arg}),
4416 .f64 => return cg.callIntrinsic(.sin, &.{.f64_type}, Type.f64, &.{arg}),4410 .f64 => return cg.callIntrinsic(.sin, &.{.f64_type}, Type.f64, &.{arg}),
4417 .f80 => return cg.callIntrinsic(.__sinx, &.{.f80_type}, Type.f80, &.{arg}),4411 .f80 => return cg.callIntrinsic(.__sinx, &.{.f80_type}, Type.f80, &.{arg}),
4418 .f128 => return cg.callIntrinsic(.sinq, &.{.f128_type}, Type.f128, &.{arg}),4412 .f128 => return cg.callIntrinsic(.sinf128, &.{.f128_type}, Type.f128, &.{arg}),
4419 }4413 }
4420}4414}
44214415
...@@ -4425,7 +4419,7 @@ fn floatCos(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4425,7 +4419,7 @@ fn floatCos(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4425 .f32 => return cg.callIntrinsic(.cosf, &.{.f32_type}, Type.f32, &.{arg}),4419 .f32 => return cg.callIntrinsic(.cosf, &.{.f32_type}, Type.f32, &.{arg}),
4426 .f64 => return cg.callIntrinsic(.cos, &.{.f64_type}, Type.f64, &.{arg}),4420 .f64 => return cg.callIntrinsic(.cos, &.{.f64_type}, Type.f64, &.{arg}),
4427 .f80 => return cg.callIntrinsic(.__cosx, &.{.f80_type}, Type.f80, &.{arg}),4421 .f80 => return cg.callIntrinsic(.__cosx, &.{.f80_type}, Type.f80, &.{arg}),
4428 .f128 => return cg.callIntrinsic(.cosq, &.{.f128_type}, Type.f128, &.{arg}),4422 .f128 => return cg.callIntrinsic(.cosf128, &.{.f128_type}, Type.f128, &.{arg}),
4429 }4423 }
4430}4424}
44314425
...@@ -4435,7 +4429,7 @@ fn floatTan(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4435,7 +4429,7 @@ fn floatTan(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4435 .f32 => return cg.callIntrinsic(.tanf, &.{.f32_type}, Type.f32, &.{arg}),4429 .f32 => return cg.callIntrinsic(.tanf, &.{.f32_type}, Type.f32, &.{arg}),
4436 .f64 => return cg.callIntrinsic(.tan, &.{.f64_type}, Type.f64, &.{arg}),4430 .f64 => return cg.callIntrinsic(.tan, &.{.f64_type}, Type.f64, &.{arg}),
4437 .f80 => return cg.callIntrinsic(.__tanx, &.{.f80_type}, Type.f80, &.{arg}),4431 .f80 => return cg.callIntrinsic(.__tanx, &.{.f80_type}, Type.f80, &.{arg}),
4438 .f128 => return cg.callIntrinsic(.tanq, &.{.f128_type}, Type.f128, &.{arg}),4432 .f128 => return cg.callIntrinsic(.tanf128, &.{.f128_type}, Type.f128, &.{arg}),
4439 }4433 }
4440}4434}
44414435
...@@ -4445,7 +4439,7 @@ fn floatExp(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4445,7 +4439,7 @@ fn floatExp(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4445 .f32 => return cg.callIntrinsic(.expf, &.{.f32_type}, Type.f32, &.{arg}),4439 .f32 => return cg.callIntrinsic(.expf, &.{.f32_type}, Type.f32, &.{arg}),
4446 .f64 => return cg.callIntrinsic(.exp, &.{.f64_type}, Type.f64, &.{arg}),4440 .f64 => return cg.callIntrinsic(.exp, &.{.f64_type}, Type.f64, &.{arg}),
4447 .f80 => return cg.callIntrinsic(.__expx, &.{.f80_type}, Type.f80, &.{arg}),4441 .f80 => return cg.callIntrinsic(.__expx, &.{.f80_type}, Type.f80, &.{arg}),
4448 .f128 => return cg.callIntrinsic(.expq, &.{.f128_type}, Type.f128, &.{arg}),4442 .f128 => return cg.callIntrinsic(.expf128, &.{.f128_type}, Type.f128, &.{arg}),
4449 }4443 }
4450}4444}
44514445
...@@ -4455,7 +4449,7 @@ fn floatExp2(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4455,7 +4449,7 @@ fn floatExp2(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4455 .f32 => return cg.callIntrinsic(.exp2f, &.{.f32_type}, Type.f32, &.{arg}),4449 .f32 => return cg.callIntrinsic(.exp2f, &.{.f32_type}, Type.f32, &.{arg}),
4456 .f64 => return cg.callIntrinsic(.exp2, &.{.f64_type}, Type.f64, &.{arg}),4450 .f64 => return cg.callIntrinsic(.exp2, &.{.f64_type}, Type.f64, &.{arg}),
4457 .f80 => return cg.callIntrinsic(.__exp2x, &.{.f80_type}, Type.f80, &.{arg}),4451 .f80 => return cg.callIntrinsic(.__exp2x, &.{.f80_type}, Type.f80, &.{arg}),
4458 .f128 => return cg.callIntrinsic(.exp2q, &.{.f128_type}, Type.f128, &.{arg}),4452 .f128 => return cg.callIntrinsic(.exp2f128, &.{.f128_type}, Type.f128, &.{arg}),
4459 }4453 }
4460}4454}
44614455
...@@ -4465,7 +4459,7 @@ fn floatLog(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4465,7 +4459,7 @@ fn floatLog(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4465 .f32 => return cg.callIntrinsic(.logf, &.{.f32_type}, Type.f32, &.{arg}),4459 .f32 => return cg.callIntrinsic(.logf, &.{.f32_type}, Type.f32, &.{arg}),
4466 .f64 => return cg.callIntrinsic(.log, &.{.f64_type}, Type.f64, &.{arg}),4460 .f64 => return cg.callIntrinsic(.log, &.{.f64_type}, Type.f64, &.{arg}),
4467 .f80 => return cg.callIntrinsic(.__logx, &.{.f80_type}, Type.f80, &.{arg}),4461 .f80 => return cg.callIntrinsic(.__logx, &.{.f80_type}, Type.f80, &.{arg}),
4468 .f128 => return cg.callIntrinsic(.logq, &.{.f128_type}, Type.f128, &.{arg}),4462 .f128 => return cg.callIntrinsic(.logf128, &.{.f128_type}, Type.f128, &.{arg}),
4469 }4463 }
4470}4464}
44714465
...@@ -4475,7 +4469,7 @@ fn floatLog2(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4475,7 +4469,7 @@ fn floatLog2(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4475 .f32 => return cg.callIntrinsic(.log2f, &.{.f32_type}, Type.f32, &.{arg}),4469 .f32 => return cg.callIntrinsic(.log2f, &.{.f32_type}, Type.f32, &.{arg}),
4476 .f64 => return cg.callIntrinsic(.log2, &.{.f64_type}, Type.f64, &.{arg}),4470 .f64 => return cg.callIntrinsic(.log2, &.{.f64_type}, Type.f64, &.{arg}),
4477 .f80 => return cg.callIntrinsic(.__log2x, &.{.f80_type}, Type.f80, &.{arg}),4471 .f80 => return cg.callIntrinsic(.__log2x, &.{.f80_type}, Type.f80, &.{arg}),
4478 .f128 => return cg.callIntrinsic(.log2q, &.{.f128_type}, Type.f128, &.{arg}),4472 .f128 => return cg.callIntrinsic(.log2f128, &.{.f128_type}, Type.f128, &.{arg}),
4479 }4473 }
4480}4474}
44814475
...@@ -4485,7 +4479,7 @@ fn floatLog10(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4485,7 +4479,7 @@ fn floatLog10(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4485 .f32 => return cg.callIntrinsic(.log10f, &.{.f32_type}, Type.f32, &.{arg}),4479 .f32 => return cg.callIntrinsic(.log10f, &.{.f32_type}, Type.f32, &.{arg}),
4486 .f64 => return cg.callIntrinsic(.log10, &.{.f64_type}, Type.f64, &.{arg}),4480 .f64 => return cg.callIntrinsic(.log10, &.{.f64_type}, Type.f64, &.{arg}),
4487 .f80 => return cg.callIntrinsic(.__log10x, &.{.f80_type}, Type.f80, &.{arg}),4481 .f80 => return cg.callIntrinsic(.__log10x, &.{.f80_type}, Type.f80, &.{arg}),
4488 .f128 => return cg.callIntrinsic(.log10q, &.{.f128_type}, Type.f128, &.{arg}),4482 .f128 => return cg.callIntrinsic(.log10f128, &.{.f128_type}, Type.f128, &.{arg}),
4489 }4483 }
4490}4484}
44914485
...@@ -4503,7 +4497,7 @@ fn floatFloor(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4503,7 +4497,7 @@ fn floatFloor(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4503 return .stack;4497 return .stack;
4504 },4498 },
4505 .f80 => return cg.callIntrinsic(.__floorx, &.{.f80_type}, Type.f80, &.{arg}),4499 .f80 => return cg.callIntrinsic(.__floorx, &.{.f80_type}, Type.f80, &.{arg}),
4506 .f128 => return cg.callIntrinsic(.floorq, &.{.f128_type}, Type.f128, &.{arg}),4500 .f128 => return cg.callIntrinsic(.floorf128, &.{.f128_type}, Type.f128, &.{arg}),
4507 }4501 }
4508}4502}
45094503
...@@ -4521,7 +4515,7 @@ fn floatCeil(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4521,7 +4515,7 @@ fn floatCeil(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4521 return .stack;4515 return .stack;
4522 },4516 },
4523 .f80 => return cg.callIntrinsic(.__ceilx, &.{.f80_type}, Type.f80, &.{arg}),4517 .f80 => return cg.callIntrinsic(.__ceilx, &.{.f80_type}, Type.f80, &.{arg}),
4524 .f128 => return cg.callIntrinsic(.ceilq, &.{.f128_type}, Type.f128, &.{arg}),4518 .f128 => return cg.callIntrinsic(.ceilf128, &.{.f128_type}, Type.f128, &.{arg}),
4525 }4519 }
4526}4520}
45274521
...@@ -4539,7 +4533,7 @@ fn floatRound(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4539,7 +4533,7 @@ fn floatRound(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4539 return .stack;4533 return .stack;
4540 },4534 },
4541 .f80 => return cg.callIntrinsic(.__roundx, &.{.f80_type}, Type.f80, &.{arg}),4535 .f80 => return cg.callIntrinsic(.__roundx, &.{.f80_type}, Type.f80, &.{arg}),
4542 .f128 => return cg.callIntrinsic(.roundq, &.{.f128_type}, Type.f128, &.{arg}),4536 .f128 => return cg.callIntrinsic(.roundf128, &.{.f128_type}, Type.f128, &.{arg}),
4543 }4537 }
4544}4538}
45454539
...@@ -4557,7 +4551,7 @@ fn floatTrunc(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {...@@ -4557,7 +4551,7 @@ fn floatTrunc(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue {
4557 return .stack;4551 return .stack;
4558 },4552 },
4559 .f80 => return cg.callIntrinsic(.__truncx, &.{.f80_type}, Type.f80, &.{arg}),4553 .f80 => return cg.callIntrinsic(.__truncx, &.{.f80_type}, Type.f80, &.{arg}),
4560 .f128 => return cg.callIntrinsic(.truncq, &.{.f128_type}, Type.f128, &.{arg}),4554 .f128 => return cg.callIntrinsic(.truncf128, &.{.f128_type}, Type.f128, &.{arg}),
4561 }4555 }
4562}4556}
45634557
src/codegen/wasm/Mir.zig+18-18
...@@ -991,48 +991,48 @@ pub const Intrinsic = enum(u32) {...@@ -991,48 +991,48 @@ pub const Intrinsic = enum(u32) {
991 __udivti3,991 __udivti3,
992 __umodei5,992 __umodei5,
993 __umodti3,993 __umodti3,
994 ceilq,994 ceilf128,
995 cos,995 cos,
996 cosf,996 cosf,
997 cosq,997 cosf128,
998 exp,998 exp,
999 exp2,999 exp2,
1000 exp2f,1000 exp2f,
1001 exp2q,1001 exp2f128,
1002 expf,1002 expf,
1003 expq,1003 expf128,
1004 fabsq,1004 fabsf128,
1005 floorq,1005 floorf128,
1006 fma,1006 fma,
1007 fmaf,1007 fmaf,
1008 fmaq,1008 fmaf128,
1009 fmax,1009 fmax,
1010 fmaxf,1010 fmaxf,
1011 fmaxq,1011 fmaxf128,
1012 fmin,1012 fmin,
1013 fminf,1013 fminf,
1014 fminq,1014 fminf128,
1015 fmod,1015 fmod,
1016 fmodf,1016 fmodf,
1017 fmodq,1017 fmodf128,
1018 log,1018 log,
1019 log10,1019 log10,
1020 log10f,1020 log10f,
1021 log10q,1021 log10f128,
1022 log2,1022 log2,
1023 log2f,1023 log2f,
1024 log2q,1024 log2f128,
1025 logf,1025 logf,
1026 logq,1026 logf128,
1027 roundq,1027 roundf128,
1028 sin,1028 sin,
1029 sinf,1029 sinf,
1030 sinq,1030 sinf128,
1031 sqrtq,1031 sqrtf128,
1032 tan,1032 tan,
1033 tanf,1033 tanf,
1034 tanq,1034 tanf128,
1035 truncq,1035 truncf128,
1036 memcpy,1036 memcpy,
1037 memmove,1037 memmove,
1038 memset,1038 memset,
src/codegen/wasm/abi.zig+5-1
...@@ -25,7 +25,11 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class {...@@ -25,7 +25,11 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class {
25 assert(ty.hasRuntimeBits(zcu));25 assert(ty.hasRuntimeBits(zcu));
26 switch (ty.zigTypeTag(zcu)) {26 switch (ty.zigTypeTag(zcu)) {
27 .int, .@"enum", .error_set => return .{ .direct = ty },27 .int, .@"enum", .error_set => return .{ .direct = ty },
28 .float => return .{ .direct = ty },28 .float => return switch (ty.floatBits(zcu.getTarget())) {
29 else => unreachable,
30 16, 32, 64, 128 => .{ .direct = ty },
31 80 => .indirect,
32 },
29 .bool => return .{ .direct = ty },33 .bool => return .{ .direct = ty },
30 .vector => return .{ .direct = ty },34 .vector => return .{ .direct = ty },
31 .array => return .indirect,35 .array => return .indirect,
src/codegen/x86_64/CodeGen.zig+157-285
...@@ -34436,7 +34436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34436,7 +34436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34436 .call_frame = .{ .alignment = .@"16" },34436 .call_frame = .{ .alignment = .@"16" },
34437 .extra_temps = .{34437 .extra_temps = .{
34438 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34438 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34439 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34439 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34440 .unused,34440 .unused,
34441 .unused,34441 .unused,
34442 .unused,34442 .unused,
...@@ -34470,7 +34470,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34470,7 +34470,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34470 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },34470 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34471 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34471 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34472 .{ .type = .f128, .kind = .mem },34472 .{ .type = .f128, .kind = .mem },
34473 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34473 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34474 .unused,34474 .unused,
34475 .unused,34475 .unused,
34476 .unused,34476 .unused,
...@@ -34505,7 +34505,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34505,7 +34505,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34505 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },34505 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34506 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34506 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34507 .{ .type = .f128, .kind = .mem },34507 .{ .type = .f128, .kind = .mem },
34508 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34508 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34509 .unused,34509 .unused,
34510 .unused,34510 .unused,
34511 .unused,34511 .unused,
...@@ -34540,7 +34540,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34540,7 +34540,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34540 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },34540 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34541 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34541 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34542 .{ .type = .f128, .kind = .mem },34542 .{ .type = .f128, .kind = .mem },
34543 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34543 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34544 .unused,34544 .unused,
34545 .unused,34545 .unused,
34546 .unused,34546 .unused,
...@@ -34575,7 +34575,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34575,7 +34575,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34575 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },34575 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34576 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },34576 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34577 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34577 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34578 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34578 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34579 .unused,34579 .unused,
34580 .unused,34580 .unused,
34581 .unused,34581 .unused,
...@@ -34612,7 +34612,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34612,7 +34612,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34612 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },34612 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34613 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },34613 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34614 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34614 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34615 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34615 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34616 .unused,34616 .unused,
34617 .unused,34617 .unused,
34618 .unused,34618 .unused,
...@@ -34649,7 +34649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34649,7 +34649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34649 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },34649 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34650 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },34650 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34651 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34651 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34652 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34652 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34653 .unused,34653 .unused,
34654 .unused,34654 .unused,
34655 .unused,34655 .unused,
...@@ -34688,7 +34688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34688,7 +34688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34688 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34688 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34689 .{ .type = .f128, .kind = .mem },34689 .{ .type = .f128, .kind = .mem },
34690 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },34690 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34691 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34691 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34692 .unused,34692 .unused,
34693 .unused,34693 .unused,
34694 .unused,34694 .unused,
...@@ -34727,7 +34727,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34727,7 +34727,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34727 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34727 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34728 .{ .type = .f128, .kind = .mem },34728 .{ .type = .f128, .kind = .mem },
34729 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },34729 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34730 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34730 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34731 .unused,34731 .unused,
34732 .unused,34732 .unused,
34733 .unused,34733 .unused,
...@@ -34766,7 +34766,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34766,7 +34766,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34766 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },34766 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34767 .{ .type = .f128, .kind = .mem },34767 .{ .type = .f128, .kind = .mem },
34768 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },34768 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34769 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },34769 .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } },
34770 .unused,34770 .unused,
34771 .unused,34771 .unused,
34772 .unused,34772 .unused,
...@@ -35960,8 +35960,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35960,8 +35960,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35960 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },35960 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
35961 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {35961 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35962 else => unreachable,35962 else => unreachable,
35963 .zero => "truncq",35963 .zero => "truncf128",
35964 .down => "floorq",35964 .down => "floorf128",
35965 } } },35965 } } },
35966 .unused,35966 .unused,
35967 .unused,35967 .unused,
...@@ -35998,8 +35998,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35998,8 +35998,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35998 .{ .type = .f128, .kind = .mem },35998 .{ .type = .f128, .kind = .mem },
35999 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {35999 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36000 else => unreachable,36000 else => unreachable,
36001 .zero => "truncq",36001 .zero => "truncf128",
36002 .down => "floorq",36002 .down => "floorf128",
36003 } } },36003 } } },
36004 .unused,36004 .unused,
36005 .unused,36005 .unused,
...@@ -36037,8 +36037,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36037,8 +36037,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36037 .{ .type = .f128, .kind = .mem },36037 .{ .type = .f128, .kind = .mem },
36038 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {36038 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36039 else => unreachable,36039 else => unreachable,
36040 .zero => "truncq",36040 .zero => "truncf128",
36041 .down => "floorq",36041 .down => "floorf128",
36042 } } },36042 } } },
36043 .unused,36043 .unused,
36044 .unused,36044 .unused,
...@@ -36076,8 +36076,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36076,8 +36076,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36076 .{ .type = .f128, .kind = .mem },36076 .{ .type = .f128, .kind = .mem },
36077 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {36077 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36078 else => unreachable,36078 else => unreachable,
36079 .zero => "truncq",36079 .zero => "truncf128",
36080 .down => "floorq",36080 .down => "floorf128",
36081 } } },36081 } } },
36082 .unused,36082 .unused,
36083 .unused,36083 .unused,
...@@ -36115,8 +36115,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36115,8 +36115,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36115 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },36115 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36116 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {36116 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36117 else => unreachable,36117 else => unreachable,
36118 .zero => "truncq",36118 .zero => "truncf128",
36119 .down => "floorq",36119 .down => "floorf128",
36120 } } },36120 } } },
36121 .unused,36121 .unused,
36122 .unused,36122 .unused,
...@@ -36156,8 +36156,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36156,8 +36156,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36156 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },36156 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36157 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {36157 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36158 else => unreachable,36158 else => unreachable,
36159 .zero => "truncq",36159 .zero => "truncf128",
36160 .down => "floorq",36160 .down => "floorf128",
36161 } } },36161 } } },
36162 .unused,36162 .unused,
36163 .unused,36163 .unused,
...@@ -36197,8 +36197,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36197,8 +36197,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36197 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },36197 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36198 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {36198 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36199 else => unreachable,36199 else => unreachable,
36200 .zero => "truncq",36200 .zero => "truncf128",
36201 .down => "floorq",36201 .down => "floorf128",
36202 } } },36202 } } },
36203 .unused,36203 .unused,
36204 .unused,36204 .unused,
...@@ -36240,8 +36240,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36240,8 +36240,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36240 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },36240 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
36241 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {36241 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36242 else => unreachable,36242 else => unreachable,
36243 .zero => "truncq",36243 .zero => "truncf128",
36244 .down => "floorq",36244 .down => "floorf128",
36245 } } },36245 } } },
36246 .unused,36246 .unused,
36247 .unused,36247 .unused,
...@@ -36283,8 +36283,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36283,8 +36283,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36283 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },36283 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
36284 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {36284 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36285 else => unreachable,36285 else => unreachable,
36286 .zero => "truncq",36286 .zero => "truncf128",
36287 .down => "floorq",36287 .down => "floorf128",
36288 } } },36288 } } },
36289 .unused,36289 .unused,
36290 .unused,36290 .unused,
...@@ -36326,8 +36326,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36326,8 +36326,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36326 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },36326 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
36327 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {36327 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36328 else => unreachable,36328 else => unreachable,
36329 .zero => "truncq",36329 .zero => "truncf128",
36330 .down => "floorq",36330 .down => "floorf128",
36331 } } },36331 } } },
36332 .unused,36332 .unused,
36333 .unused,36333 .unused,
...@@ -37691,7 +37691,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37691,7 +37691,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37691 .call_frame = .{ .alignment = .@"16" },37691 .call_frame = .{ .alignment = .@"16" },
37692 .extra_temps = .{37692 .extra_temps = .{
37693 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },37693 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37694 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },37694 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
37695 .unused,37695 .unused,
37696 .unused,37696 .unused,
37697 .unused,37697 .unused,
...@@ -37725,7 +37725,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37725,7 +37725,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37725 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },37725 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37726 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },37726 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37727 .{ .type = .f128, .kind = .mem },37727 .{ .type = .f128, .kind = .mem },
37728 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },37728 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
37729 .unused,37729 .unused,
37730 .unused,37730 .unused,
37731 .unused,37731 .unused,
...@@ -37760,7 +37760,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37760,7 +37760,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37760 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },37760 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37761 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },37761 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37762 .{ .type = .f128, .kind = .mem },37762 .{ .type = .f128, .kind = .mem },
37763 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },37763 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
37764 .unused,37764 .unused,
37765 .unused,37765 .unused,
37766 .unused,37766 .unused,
...@@ -37795,7 +37795,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37795,7 +37795,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37795 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },37795 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37796 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },37796 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37797 .{ .type = .f128, .kind = .mem },37797 .{ .type = .f128, .kind = .mem },
37798 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },37798 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
37799 .unused,37799 .unused,
37800 .unused,37800 .unused,
37801 .unused,37801 .unused,
...@@ -37830,7 +37830,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37830,7 +37830,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37830 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },37830 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37831 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },37831 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37832 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },37832 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37833 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },37833 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
37834 .unused,37834 .unused,
37835 .unused,37835 .unused,
37836 .unused,37836 .unused,
...@@ -37867,7 +37867,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37867,7 +37867,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37867 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },37867 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37868 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },37868 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37869 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },37869 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37870 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },37870 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
37871 .unused,37871 .unused,
37872 .unused,37872 .unused,
37873 .unused,37873 .unused,
...@@ -37904,7 +37904,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37904,7 +37904,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37904 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },37904 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37905 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },37905 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37906 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },37906 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37907 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },37907 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
37908 .unused,37908 .unused,
37909 .unused,37909 .unused,
37910 .unused,37910 .unused,
...@@ -37943,7 +37943,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37943,7 +37943,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37943 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },37943 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37944 .{ .type = .f128, .kind = .mem },37944 .{ .type = .f128, .kind = .mem },
37945 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },37945 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37946 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },37946 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
37947 .unused,37947 .unused,
37948 .unused,37948 .unused,
37949 .unused,37949 .unused,
...@@ -37982,7 +37982,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37982,7 +37982,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37982 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },37982 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37983 .{ .type = .f128, .kind = .mem },37983 .{ .type = .f128, .kind = .mem },
37984 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },37984 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37985 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },37985 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
37986 .unused,37986 .unused,
37987 .unused,37987 .unused,
37988 .unused,37988 .unused,
...@@ -38021,7 +38021,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38021,7 +38021,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38021 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },38021 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
38022 .{ .type = .f128, .kind = .mem },38022 .{ .type = .f128, .kind = .mem },
38023 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },38023 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
38024 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },38024 .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } },
38025 .unused,38025 .unused,
38026 .unused,38026 .unused,
38027 .unused,38027 .unused,
...@@ -39558,7 +39558,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39558,7 +39558,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39558 },39558 },
39559 .call_frame = .{ .alignment = .@"16" },39559 .call_frame = .{ .alignment = .@"16" },
39560 .extra_temps = .{39560 .extra_temps = .{
39561 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },39561 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
39562 .unused,39562 .unused,
39563 .unused,39563 .unused,
39564 .unused,39564 .unused,
...@@ -39590,7 +39590,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39590,7 +39590,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39590 .extra_temps = .{39590 .extra_temps = .{
39591 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },39591 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39592 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },39592 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39593 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },39593 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
39594 .unused,39594 .unused,
39595 .unused,39595 .unused,
39596 .unused,39596 .unused,
...@@ -39623,7 +39623,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39623,7 +39623,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39623 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },39623 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
39624 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },39624 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39625 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },39625 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39626 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },39626 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
39627 .unused,39627 .unused,
39628 .unused,39628 .unused,
39629 .unused,39629 .unused,
...@@ -39659,7 +39659,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39659,7 +39659,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39659 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },39659 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
39660 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },39660 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39661 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },39661 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39662 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },39662 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
39663 .unused,39663 .unused,
39664 .unused,39664 .unused,
39665 .unused,39665 .unused,
...@@ -39695,7 +39695,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39695,7 +39695,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39695 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },39695 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
39696 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },39696 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39697 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },39697 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39698 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },39698 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
39699 .unused,39699 .unused,
39700 .unused,39700 .unused,
39701 .unused,39701 .unused,
...@@ -39731,7 +39731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39731,7 +39731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39731 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },39731 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
39732 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },39732 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39733 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },39733 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39734 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },39734 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
39735 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },39735 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39736 .unused,39736 .unused,
39737 .unused,39737 .unused,
...@@ -39767,7 +39767,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39767,7 +39767,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39767 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },39767 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
39768 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },39768 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39769 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },39769 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39770 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },39770 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
39771 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },39771 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39772 .unused,39772 .unused,
39773 .unused,39773 .unused,
...@@ -39803,7 +39803,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39803,7 +39803,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39803 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },39803 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
39804 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },39804 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39805 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },39805 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39806 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },39806 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
39807 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },39807 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39808 .unused,39808 .unused,
39809 .unused,39809 .unused,
...@@ -42803,7 +42803,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -42803,7 +42803,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42803 .call_frame = .{ .alignment = .@"16" },42803 .call_frame = .{ .alignment = .@"16" },
42804 .extra_temps = .{42804 .extra_temps = .{
42805 .{ .type = .f128, .kind = .mem },42805 .{ .type = .f128, .kind = .mem },
42806 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },42806 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
42807 .{ .type = .u64, .kind = .{ .reg = .rcx } },42807 .{ .type = .u64, .kind = .{ .reg = .rcx } },
42808 .{ .type = .u64, .kind = .{ .reg = .rdx } },42808 .{ .type = .u64, .kind = .{ .reg = .rdx } },
42809 .{ .type = .u64, .kind = .{ .reg = .rax } },42809 .{ .type = .u64, .kind = .{ .reg = .rax } },
...@@ -42849,7 +42849,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -42849,7 +42849,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42849 .call_frame = .{ .alignment = .@"16" },42849 .call_frame = .{ .alignment = .@"16" },
42850 .extra_temps = .{42850 .extra_temps = .{
42851 .{ .type = .f128, .kind = .mem },42851 .{ .type = .f128, .kind = .mem },
42852 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },42852 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
42853 .{ .type = .u64, .kind = .{ .reg = .rcx } },42853 .{ .type = .u64, .kind = .{ .reg = .rcx } },
42854 .{ .type = .u64, .kind = .{ .reg = .rdx } },42854 .{ .type = .u64, .kind = .{ .reg = .rdx } },
42855 .{ .type = .u64, .kind = .{ .reg = .rax } },42855 .{ .type = .u64, .kind = .{ .reg = .rax } },
...@@ -42895,7 +42895,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -42895,7 +42895,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42895 .call_frame = .{ .alignment = .@"16" },42895 .call_frame = .{ .alignment = .@"16" },
42896 .extra_temps = .{42896 .extra_temps = .{
42897 .{ .type = .f128, .kind = .mem },42897 .{ .type = .f128, .kind = .mem },
42898 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },42898 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
42899 .{ .type = .u64, .kind = .{ .reg = .rcx } },42899 .{ .type = .u64, .kind = .{ .reg = .rcx } },
42900 .{ .type = .u64, .kind = .{ .reg = .rdx } },42900 .{ .type = .u64, .kind = .{ .reg = .rdx } },
42901 .{ .type = .u64, .kind = .{ .reg = .rax } },42901 .{ .type = .u64, .kind = .{ .reg = .rax } },
...@@ -42942,7 +42942,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -42942,7 +42942,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42942 .call_frame = .{ .alignment = .@"16" },42942 .call_frame = .{ .alignment = .@"16" },
42943 .extra_temps = .{42943 .extra_temps = .{
42944 .{ .type = .f128, .kind = .mem },42944 .{ .type = .f128, .kind = .mem },
42945 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },42945 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
42946 .{ .type = .u64, .kind = .{ .reg = .rdx } },42946 .{ .type = .u64, .kind = .{ .reg = .rdx } },
42947 .{ .type = .f128, .kind = .mem },42947 .{ .type = .f128, .kind = .mem },
42948 .{ .type = .u64, .kind = .{ .reg = .rax } },42948 .{ .type = .u64, .kind = .{ .reg = .rax } },
...@@ -42984,7 +42984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -42984,7 +42984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42984 .extra_temps = .{42984 .extra_temps = .{
42985 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },42985 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42986 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },42986 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42987 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },42987 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
42988 .{ .type = .f128, .kind = .mem },42988 .{ .type = .f128, .kind = .mem },
42989 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },42989 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
42990 .{ .type = .u64, .kind = .{ .reg = .rax } },42990 .{ .type = .u64, .kind = .{ .reg = .rax } },
...@@ -43029,7 +43029,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43029,7 +43029,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43029 .extra_temps = .{43029 .extra_temps = .{
43030 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },43030 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
43031 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },43031 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
43032 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },43032 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
43033 .{ .type = .f128, .kind = .mem },43033 .{ .type = .f128, .kind = .mem },
43034 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },43034 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
43035 .{ .type = .u64, .kind = .{ .reg = .rax } },43035 .{ .type = .u64, .kind = .{ .reg = .rax } },
...@@ -43074,7 +43074,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43074,7 +43074,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43074 .extra_temps = .{43074 .extra_temps = .{
43075 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },43075 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
43076 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },43076 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
43077 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },43077 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
43078 .{ .type = .f128, .kind = .mem },43078 .{ .type = .f128, .kind = .mem },
43079 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },43079 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
43080 .{ .type = .u64, .kind = .{ .reg = .rax } },43080 .{ .type = .u64, .kind = .{ .reg = .rax } },
...@@ -43120,7 +43120,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43120,7 +43120,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43120 .extra_temps = .{43120 .extra_temps = .{
43121 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },43121 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
43122 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },43122 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
43123 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },43123 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
43124 .{ .type = .f128, .kind = .mem },43124 .{ .type = .f128, .kind = .mem },
43125 .{ .type = .usize, .kind = .{ .reg = .rax } },43125 .{ .type = .usize, .kind = .{ .reg = .rax } },
43126 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },43126 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
...@@ -43164,7 +43164,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43164,7 +43164,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43164 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },43164 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
43165 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },43165 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
43166 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },43166 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
43167 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },43167 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
43168 .{ .type = .f128, .kind = .{ .reg = .rcx } },43168 .{ .type = .f128, .kind = .{ .reg = .rcx } },
43169 .{ .type = .f128, .kind = .{ .reg = .rdx } },43169 .{ .type = .f128, .kind = .{ .reg = .rdx } },
43170 .{ .type = .f128, .kind = .{ .reg = .rax } },43170 .{ .type = .f128, .kind = .{ .reg = .rax } },
...@@ -43211,7 +43211,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43211,7 +43211,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43211 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },43211 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
43212 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },43212 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
43213 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },43213 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
43214 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },43214 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
43215 .{ .type = .f128, .kind = .{ .reg = .rcx } },43215 .{ .type = .f128, .kind = .{ .reg = .rcx } },
43216 .{ .type = .f128, .kind = .{ .reg = .rdx } },43216 .{ .type = .f128, .kind = .{ .reg = .rdx } },
43217 .{ .type = .f128, .kind = .{ .reg = .rax } },43217 .{ .type = .f128, .kind = .{ .reg = .rax } },
...@@ -43258,7 +43258,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43258,7 +43258,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43258 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },43258 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
43259 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },43259 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
43260 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },43260 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
43261 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },43261 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
43262 .{ .type = .f128, .kind = .{ .reg = .rcx } },43262 .{ .type = .f128, .kind = .{ .reg = .rcx } },
43263 .{ .type = .f128, .kind = .{ .reg = .rdx } },43263 .{ .type = .f128, .kind = .{ .reg = .rdx } },
43264 .{ .type = .f128, .kind = .{ .reg = .rax } },43264 .{ .type = .f128, .kind = .{ .reg = .rax } },
...@@ -43306,7 +43306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43306,7 +43306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43306 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },43306 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
43307 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },43307 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
43308 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },43308 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
43309 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },43309 .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } },
43310 .{ .type = .f128, .kind = .{ .reg = .rdx } },43310 .{ .type = .f128, .kind = .{ .reg = .rdx } },
43311 .{ .type = .f128, .kind = .mem },43311 .{ .type = .f128, .kind = .mem },
43312 .{ .type = .f128, .kind = .{ .reg = .rax } },43312 .{ .type = .f128, .kind = .{ .reg = .rax } },
...@@ -47623,7 +47623,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -47623,7 +47623,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
47623 },47623 },
47624 .call_frame = .{ .alignment = .@"16" },47624 .call_frame = .{ .alignment = .@"16" },
47625 .extra_temps = .{47625 .extra_temps = .{
47626 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },47626 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
47627 .unused,47627 .unused,
47628 .unused,47628 .unused,
47629 .unused,47629 .unused,
...@@ -47655,7 +47655,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -47655,7 +47655,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
47655 .extra_temps = .{47655 .extra_temps = .{
47656 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },47656 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47657 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },47657 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47658 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },47658 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
47659 .unused,47659 .unused,
47660 .unused,47660 .unused,
47661 .unused,47661 .unused,
...@@ -47688,7 +47688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -47688,7 +47688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
47688 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },47688 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
47689 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },47689 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47690 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },47690 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47691 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },47691 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
47692 .unused,47692 .unused,
47693 .unused,47693 .unused,
47694 .unused,47694 .unused,
...@@ -47724,7 +47724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -47724,7 +47724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
47724 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },47724 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
47725 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },47725 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47726 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },47726 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47727 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },47727 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
47728 .unused,47728 .unused,
47729 .unused,47729 .unused,
47730 .unused,47730 .unused,
...@@ -47760,7 +47760,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -47760,7 +47760,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
47760 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },47760 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
47761 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },47761 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47762 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },47762 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47763 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },47763 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
47764 .unused,47764 .unused,
47765 .unused,47765 .unused,
47766 .unused,47766 .unused,
...@@ -47796,7 +47796,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -47796,7 +47796,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
47796 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },47796 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
47797 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },47797 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47798 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },47798 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47799 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },47799 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
47800 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },47800 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47801 .unused,47801 .unused,
47802 .unused,47802 .unused,
...@@ -47832,7 +47832,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -47832,7 +47832,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
47832 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },47832 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
47833 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },47833 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47834 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },47834 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47835 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },47835 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
47836 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },47836 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47837 .unused,47837 .unused,
47838 .unused,47838 .unused,
...@@ -47868,7 +47868,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -47868,7 +47868,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
47868 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },47868 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
47869 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },47869 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47870 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },47870 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47871 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },47871 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
47872 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },47872 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47873 .unused,47873 .unused,
47874 .unused,47874 .unused,
...@@ -51926,7 +51926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -51926,7 +51926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
51926 },51926 },
51927 .call_frame = .{ .alignment = .@"16" },51927 .call_frame = .{ .alignment = .@"16" },
51928 .extra_temps = .{51928 .extra_temps = .{
51929 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },51929 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
51930 .unused,51930 .unused,
51931 .unused,51931 .unused,
51932 .unused,51932 .unused,
...@@ -51958,7 +51958,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -51958,7 +51958,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
51958 .extra_temps = .{51958 .extra_temps = .{
51959 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },51959 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
51960 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },51960 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
51961 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },51961 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
51962 .unused,51962 .unused,
51963 .unused,51963 .unused,
51964 .unused,51964 .unused,
...@@ -51991,7 +51991,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -51991,7 +51991,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
51991 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },51991 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
51992 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },51992 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
51993 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },51993 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
51994 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },51994 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
51995 .unused,51995 .unused,
51996 .unused,51996 .unused,
51997 .unused,51997 .unused,
...@@ -52027,7 +52027,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -52027,7 +52027,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52027 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },52027 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
52028 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },52028 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52029 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },52029 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
52030 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },52030 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
52031 .unused,52031 .unused,
52032 .unused,52032 .unused,
52033 .unused,52033 .unused,
...@@ -52063,7 +52063,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -52063,7 +52063,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52063 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },52063 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
52064 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },52064 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52065 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },52065 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
52066 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },52066 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
52067 .unused,52067 .unused,
52068 .unused,52068 .unused,
52069 .unused,52069 .unused,
...@@ -52099,7 +52099,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -52099,7 +52099,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52099 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },52099 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
52100 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },52100 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52101 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },52101 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
52102 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },52102 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
52103 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },52103 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52104 .unused,52104 .unused,
52105 .unused,52105 .unused,
...@@ -52135,7 +52135,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -52135,7 +52135,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52135 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },52135 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
52136 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },52136 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52137 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },52137 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
52138 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },52138 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
52139 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },52139 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52140 .unused,52140 .unused,
52141 .unused,52141 .unused,
...@@ -52171,7 +52171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -52171,7 +52171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52171 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },52171 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
52172 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },52172 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52173 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },52173 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
52174 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },52174 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
52175 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },52175 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52176 .unused,52176 .unused,
52177 .unused,52177 .unused,
...@@ -76457,7 +76457,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76457,7 +76457,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76457 },76457 },
76458 .call_frame = .{ .alignment = .@"16" },76458 .call_frame = .{ .alignment = .@"16" },
76459 .extra_temps = .{76459 .extra_temps = .{
76460 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },76460 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } },
76461 .unused,76461 .unused,
76462 .unused,76462 .unused,
76463 .unused,76463 .unused,
...@@ -76484,7 +76484,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76484,7 +76484,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76484 .call_frame = .{ .alignment = .@"16" },76484 .call_frame = .{ .alignment = .@"16" },
76485 .extra_temps = .{76485 .extra_temps = .{
76486 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },76486 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76487 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },76487 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } },
76488 .unused,76488 .unused,
76489 .unused,76489 .unused,
76490 .unused,76490 .unused,
...@@ -76512,7 +76512,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76512,7 +76512,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76512 .extra_temps = .{76512 .extra_temps = .{
76513 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },76513 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
76514 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },76514 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76515 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },76515 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } },
76516 .unused,76516 .unused,
76517 .unused,76517 .unused,
76518 .unused,76518 .unused,
...@@ -76543,7 +76543,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76543,7 +76543,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76543 .extra_temps = .{76543 .extra_temps = .{
76544 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },76544 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
76545 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },76545 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76546 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },76546 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } },
76547 .unused,76547 .unused,
76548 .unused,76548 .unused,
76549 .unused,76549 .unused,
...@@ -76574,7 +76574,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76574,7 +76574,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76574 .extra_temps = .{76574 .extra_temps = .{
76575 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },76575 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
76576 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },76576 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76577 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },76577 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } },
76578 .unused,76578 .unused,
76579 .unused,76579 .unused,
76580 .unused,76580 .unused,
...@@ -76605,7 +76605,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76605,7 +76605,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76605 .extra_temps = .{76605 .extra_temps = .{
76606 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },76606 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
76607 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },76607 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76608 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },76608 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } },
76609 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },76609 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76610 .unused,76610 .unused,
76611 .unused,76611 .unused,
...@@ -76636,7 +76636,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76636,7 +76636,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76636 .extra_temps = .{76636 .extra_temps = .{
76637 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },76637 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
76638 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },76638 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76639 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },76639 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } },
76640 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },76640 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76641 .unused,76641 .unused,
76642 .unused,76642 .unused,
...@@ -76667,7 +76667,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76667,7 +76667,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76667 .extra_temps = .{76667 .extra_temps = .{
76668 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },76668 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
76669 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },76669 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76670 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },76670 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } },
76671 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },76671 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76672 .unused,76672 .unused,
76673 .unused,76673 .unused,
...@@ -77306,7 +77306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77306,7 +77306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77306 },77306 },
77307 .call_frame = .{ .alignment = .@"16" },77307 .call_frame = .{ .alignment = .@"16" },
77308 .extra_temps = .{77308 .extra_temps = .{
77309 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },77309 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } },
77310 .unused,77310 .unused,
77311 .unused,77311 .unused,
77312 .unused,77312 .unused,
...@@ -77333,7 +77333,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77333,7 +77333,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77333 .call_frame = .{ .alignment = .@"16" },77333 .call_frame = .{ .alignment = .@"16" },
77334 .extra_temps = .{77334 .extra_temps = .{
77335 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },77335 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77336 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },77336 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } },
77337 .unused,77337 .unused,
77338 .unused,77338 .unused,
77339 .unused,77339 .unused,
...@@ -77361,7 +77361,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77361,7 +77361,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77361 .extra_temps = .{77361 .extra_temps = .{
77362 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },77362 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
77363 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },77363 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77364 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },77364 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } },
77365 .unused,77365 .unused,
77366 .unused,77366 .unused,
77367 .unused,77367 .unused,
...@@ -77392,7 +77392,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77392,7 +77392,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77392 .extra_temps = .{77392 .extra_temps = .{
77393 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },77393 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
77394 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },77394 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77395 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },77395 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } },
77396 .unused,77396 .unused,
77397 .unused,77397 .unused,
77398 .unused,77398 .unused,
...@@ -77423,7 +77423,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77423,7 +77423,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77423 .extra_temps = .{77423 .extra_temps = .{
77424 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },77424 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
77425 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },77425 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77426 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },77426 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } },
77427 .unused,77427 .unused,
77428 .unused,77428 .unused,
77429 .unused,77429 .unused,
...@@ -77454,7 +77454,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77454,7 +77454,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77454 .extra_temps = .{77454 .extra_temps = .{
77455 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },77455 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
77456 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },77456 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77457 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },77457 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } },
77458 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },77458 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77459 .unused,77459 .unused,
77460 .unused,77460 .unused,
...@@ -77485,7 +77485,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77485,7 +77485,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77485 .extra_temps = .{77485 .extra_temps = .{
77486 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },77486 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
77487 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },77487 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77488 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },77488 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } },
77489 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },77489 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77490 .unused,77490 .unused,
77491 .unused,77491 .unused,
...@@ -77516,7 +77516,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77516,7 +77516,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77516 .extra_temps = .{77516 .extra_temps = .{
77517 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },77517 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
77518 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },77518 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77519 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },77519 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } },
77520 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },77520 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77521 .unused,77521 .unused,
77522 .unused,77522 .unused,
...@@ -80155,9 +80155,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80155,9 +80155,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80155 .extra_temps = .{80155 .extra_temps = .{
80156 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {80156 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80157 else => unreachable,80157 else => unreachable,
80158 .down => "floorq",80158 .down => "floorf128",
80159 .up => "ceilq",80159 .up => "ceilf128",
80160 .zero => "truncq",80160 .zero => "truncf128",
80161 } } },80161 } } },
80162 .unused,80162 .unused,
80163 .unused,80163 .unused,
...@@ -80187,9 +80187,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80187,9 +80187,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80187 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },80187 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80188 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {80188 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80189 else => unreachable,80189 else => unreachable,
80190 .down => "floorq",80190 .down => "floorf128",
80191 .up => "ceilq",80191 .up => "ceilf128",
80192 .zero => "truncq",80192 .zero => "truncf128",
80193 } } },80193 } } },
80194 .unused,80194 .unused,
80195 .unused,80195 .unused,
...@@ -80220,9 +80220,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80220,9 +80220,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80220 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },80220 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80221 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {80221 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80222 else => unreachable,80222 else => unreachable,
80223 .down => "floorq",80223 .down => "floorf128",
80224 .up => "ceilq",80224 .up => "ceilf128",
80225 .zero => "truncq",80225 .zero => "truncf128",
80226 } } },80226 } } },
80227 .unused,80227 .unused,
80228 .unused,80228 .unused,
...@@ -80256,9 +80256,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80256,9 +80256,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80256 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },80256 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80257 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {80257 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80258 else => unreachable,80258 else => unreachable,
80259 .down => "floorq",80259 .down => "floorf128",
80260 .up => "ceilq",80260 .up => "ceilf128",
80261 .zero => "truncq",80261 .zero => "truncf128",
80262 } } },80262 } } },
80263 .unused,80263 .unused,
80264 .unused,80264 .unused,
...@@ -80292,9 +80292,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80292,9 +80292,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80292 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },80292 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80293 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {80293 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80294 else => unreachable,80294 else => unreachable,
80295 .down => "floorq",80295 .down => "floorf128",
80296 .up => "ceilq",80296 .up => "ceilf128",
80297 .zero => "truncq",80297 .zero => "truncf128",
80298 } } },80298 } } },
80299 .unused,80299 .unused,
80300 .unused,80300 .unused,
...@@ -80328,9 +80328,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80328,9 +80328,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80328 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },80328 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80329 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {80329 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80330 else => unreachable,80330 else => unreachable,
80331 .down => "floorq",80331 .down => "floorf128",
80332 .up => "ceilq",80332 .up => "ceilf128",
80333 .zero => "truncq",80333 .zero => "truncf128",
80334 } } },80334 } } },
80335 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },80335 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80336 .unused,80336 .unused,
...@@ -80364,9 +80364,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80364,9 +80364,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80364 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },80364 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80365 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {80365 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80366 else => unreachable,80366 else => unreachable,
80367 .down => "floorq",80367 .down => "floorf128",
80368 .up => "ceilq",80368 .up => "ceilf128",
80369 .zero => "truncq",80369 .zero => "truncf128",
80370 } } },80370 } } },
80371 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },80371 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80372 .unused,80372 .unused,
...@@ -80400,9 +80400,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80400,9 +80400,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80400 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },80400 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80401 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {80401 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80402 else => unreachable,80402 else => unreachable,
80403 .down => "floorq",80403 .down => "floorf128",
80404 .up => "ceilq",80404 .up => "ceilf128",
80405 .zero => "truncq",80405 .zero => "truncf128",
80406 } } },80406 } } },
80407 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },80407 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80408 .unused,80408 .unused,
...@@ -125531,7 +125531,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -125531,7 +125531,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
125531 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },125531 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
125532 } },125532 } },
125533 }, .{125533 }, .{
125534 .required_cc_abi = .sysv64,
125535 .required_features = .{ .sse, null, null, null },125534 .required_features = .{ .sse, null, null, null },
125536 .src_constraints = .{ .{ .unsigned_int = .xword }, .any, .any },125535 .src_constraints = .{ .{ .unsigned_int = .xword }, .any, .any },
125537 .dst_constraints = .{ .{ .float = .xword }, .any },125536 .dst_constraints = .{ .{ .float = .xword }, .any },
...@@ -125557,34 +125556,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -125557,34 +125556,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
125557 .each = .{ .once = &.{125556 .each = .{ .once = &.{
125558 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },125557 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
125559 } },125558 } },
125560 }, .{
125561 .required_cc_abi = .win64,
125562 .required_features = .{ .sse, null, null, null },
125563 .src_constraints = .{ .{ .unsigned_int = .xword }, .any, .any },
125564 .dst_constraints = .{ .{ .float = .xword }, .any },
125565 .patterns = &.{
125566 .{ .src = .{ .to_mem, .none, .none } },
125567 },
125568 .call_frame = .{ .alignment = .@"16" },
125569 .extra_temps = .{
125570 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
125571 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } },
125572 .unused,
125573 .unused,
125574 .unused,
125575 .unused,
125576 .unused,
125577 .unused,
125578 .unused,
125579 .unused,
125580 .unused,
125581 },
125582 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
125583 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
125584 .each = .{ .once = &.{
125585 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
125586 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
125587 } },
125588 }, .{125559 }, .{
125589 .required_features = .{ .@"64bit", .sse, null, null },125560 .required_features = .{ .@"64bit", .sse, null, null },
125590 .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any, .any },125561 .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any, .any },
...@@ -126791,7 +126762,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -126791,7 +126762,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
126791 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },126762 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
126792 } },126763 } },
126793 }, .{126764 }, .{
126794 .required_cc_abi = .sysv64,
126795 .required_features = .{ .avx, null, null, null },126765 .required_features = .{ .avx, null, null, null },
126796 .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },126766 .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },
126797 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any },126767 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any },
...@@ -126824,39 +126794,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -126824,39 +126794,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
126824 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },126794 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
126825 } },126795 } },
126826 }, .{126796 }, .{
126827 .required_cc_abi = .win64,
126828 .required_features = .{ .avx, null, null, null },
126829 .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },
126830 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any },
126831 .patterns = &.{
126832 .{ .src = .{ .to_mem, .none, .none } },
126833 },
126834 .call_frame = .{ .alignment = .@"16" },
126835 .extra_temps = .{
126836 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
126837 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
126838 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } },
126839 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
126840 .unused,
126841 .unused,
126842 .unused,
126843 .unused,
126844 .unused,
126845 .unused,
126846 .unused,
126847 },
126848 .dst_temps = .{ .mem, .unused },
126849 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
126850 .each = .{ .once = &.{
126851 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
126852 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
126853 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
126854 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
126855 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
126856 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
126857 } },
126858 }, .{
126859 .required_cc_abi = .sysv64,
126860 .required_features = .{ .sse2, null, null, null },126797 .required_features = .{ .sse2, null, null, null },
126861 .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },126798 .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },
126862 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any },126799 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any },
...@@ -126889,39 +126826,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -126889,39 +126826,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
126889 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },126826 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
126890 } },126827 } },
126891 }, .{126828 }, .{
126892 .required_cc_abi = .win64,
126893 .required_features = .{ .sse2, null, null, null },
126894 .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },
126895 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any },
126896 .patterns = &.{
126897 .{ .src = .{ .to_mem, .none, .none } },
126898 },
126899 .call_frame = .{ .alignment = .@"16" },
126900 .extra_temps = .{
126901 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
126902 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
126903 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } },
126904 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
126905 .unused,
126906 .unused,
126907 .unused,
126908 .unused,
126909 .unused,
126910 .unused,
126911 .unused,
126912 },
126913 .dst_temps = .{ .mem, .unused },
126914 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
126915 .each = .{ .once = &.{
126916 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
126917 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
126918 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
126919 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
126920 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
126921 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
126922 } },
126923 }, .{
126924 .required_cc_abi = .sysv64,
126925 .required_features = .{ .sse, null, null, null },126829 .required_features = .{ .sse, null, null, null },
126926 .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },126830 .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },
126927 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any },126831 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any },
...@@ -126953,38 +126857,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -126953,38 +126857,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
126953 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },126857 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
126954 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },126858 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
126955 } },126859 } },
126956 }, .{
126957 .required_cc_abi = .win64,
126958 .required_features = .{ .sse, null, null, null },
126959 .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },
126960 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any },
126961 .patterns = &.{
126962 .{ .src = .{ .to_mem, .none, .none } },
126963 },
126964 .call_frame = .{ .alignment = .@"16" },
126965 .extra_temps = .{
126966 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
126967 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
126968 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } },
126969 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
126970 .unused,
126971 .unused,
126972 .unused,
126973 .unused,
126974 .unused,
126975 .unused,
126976 .unused,
126977 },
126978 .dst_temps = .{ .mem, .unused },
126979 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
126980 .each = .{ .once = &.{
126981 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
126982 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
126983 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
126984 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
126985 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
126986 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
126987 } },
126988 }, .{126860 }, .{
126989 .required_features = .{ .@"64bit", .avx, null, null },126861 .required_features = .{ .@"64bit", .avx, null, null },
126990 .src_constraints = .{ .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any, .any },126862 .src_constraints = .{ .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any, .any },
...@@ -142552,7 +142424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -142552,7 +142424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
142552 .extra_temps = .{142424 .extra_temps = .{
142553 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },142425 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142554 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },142426 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
142555 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },142427 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
142556 .unused,142428 .unused,
142557 .unused,142429 .unused,
142558 .unused,142430 .unused,
...@@ -142584,7 +142456,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -142584,7 +142456,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
142584 .extra_temps = .{142456 .extra_temps = .{
142585 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },142457 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142586 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },142458 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
142587 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },142459 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
142588 .unused,142460 .unused,
142589 .unused,142461 .unused,
142590 .unused,142462 .unused,
...@@ -142616,7 +142488,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -142616,7 +142488,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
142616 .extra_temps = .{142488 .extra_temps = .{
142617 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },142489 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142618 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },142490 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
142619 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },142491 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
142620 .unused,142492 .unused,
142621 .unused,142493 .unused,
142622 .unused,142494 .unused,
...@@ -142649,7 +142521,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -142649,7 +142521,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
142649 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },142521 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142650 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },142522 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
142651 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },142523 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
142652 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },142524 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
142653 .{ .type = .f128, .kind = .mem },142525 .{ .type = .f128, .kind = .mem },
142654 .unused,142526 .unused,
142655 .unused,142527 .unused,
...@@ -142683,7 +142555,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -142683,7 +142555,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
142683 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },142555 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142684 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },142556 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
142685 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },142557 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
142686 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },142558 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
142687 .{ .type = .f128, .kind = .mem },142559 .{ .type = .f128, .kind = .mem },
142688 .unused,142560 .unused,
142689 .unused,142561 .unused,
...@@ -142717,7 +142589,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -142717,7 +142589,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
142717 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },142589 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142718 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },142590 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
142719 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },142591 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
142720 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },142592 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
142721 .{ .type = .f128, .kind = .mem },142593 .{ .type = .f128, .kind = .mem },
142722 .unused,142594 .unused,
142723 .unused,142595 .unused,
...@@ -152785,7 +152657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -152785,7 +152657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
152785 .extra_temps = .{152657 .extra_temps = .{
152786 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },152658 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152787 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },152659 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
152788 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },152660 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
152789 .unused,152661 .unused,
152790 .unused,152662 .unused,
152791 .unused,152663 .unused,
...@@ -152817,7 +152689,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -152817,7 +152689,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
152817 .extra_temps = .{152689 .extra_temps = .{
152818 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },152690 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152819 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },152691 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
152820 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },152692 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
152821 .unused,152693 .unused,
152822 .unused,152694 .unused,
152823 .unused,152695 .unused,
...@@ -152849,7 +152721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -152849,7 +152721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
152849 .extra_temps = .{152721 .extra_temps = .{
152850 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },152722 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152851 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },152723 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
152852 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },152724 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
152853 .unused,152725 .unused,
152854 .unused,152726 .unused,
152855 .unused,152727 .unused,
...@@ -152882,7 +152754,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -152882,7 +152754,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
152882 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },152754 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152883 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },152755 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
152884 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },152756 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
152885 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },152757 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
152886 .{ .type = .f128, .kind = .mem },152758 .{ .type = .f128, .kind = .mem },
152887 .unused,152759 .unused,
152888 .unused,152760 .unused,
...@@ -152916,7 +152788,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -152916,7 +152788,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
152916 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },152788 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152917 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },152789 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
152918 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },152790 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
152919 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },152791 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
152920 .{ .type = .f128, .kind = .mem },152792 .{ .type = .f128, .kind = .mem },
152921 .unused,152793 .unused,
152922 .unused,152794 .unused,
...@@ -152950,7 +152822,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -152950,7 +152822,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
152950 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },152822 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152951 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },152823 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
152952 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },152824 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
152953 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },152825 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
152954 .{ .type = .f128, .kind = .mem },152826 .{ .type = .f128, .kind = .mem },
152955 .unused,152827 .unused,
152956 .unused,152828 .unused,
...@@ -163019,7 +162891,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -163019,7 +162891,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163019 .extra_temps = .{162891 .extra_temps = .{
163020 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },162892 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
163021 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },162893 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
163022 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },162894 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
163023 .unused,162895 .unused,
163024 .unused,162896 .unused,
163025 .unused,162897 .unused,
...@@ -163051,7 +162923,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -163051,7 +162923,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163051 .extra_temps = .{162923 .extra_temps = .{
163052 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },162924 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
163053 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },162925 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
163054 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },162926 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
163055 .unused,162927 .unused,
163056 .unused,162928 .unused,
163057 .unused,162929 .unused,
...@@ -163083,7 +162955,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -163083,7 +162955,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163083 .extra_temps = .{162955 .extra_temps = .{
163084 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },162956 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
163085 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },162957 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
163086 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },162958 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
163087 .unused,162959 .unused,
163088 .unused,162960 .unused,
163089 .unused,162961 .unused,
...@@ -163116,7 +162988,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -163116,7 +162988,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163116 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },162988 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
163117 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },162989 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
163118 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },162990 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
163119 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },162991 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
163120 .{ .type = .f128, .kind = .mem },162992 .{ .type = .f128, .kind = .mem },
163121 .unused,162993 .unused,
163122 .unused,162994 .unused,
...@@ -163150,7 +163022,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -163150,7 +163022,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163150 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },163022 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
163151 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },163023 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
163152 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },163024 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
163153 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },163025 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
163154 .{ .type = .f128, .kind = .mem },163026 .{ .type = .f128, .kind = .mem },
163155 .unused,163027 .unused,
163156 .unused,163028 .unused,
...@@ -163184,7 +163056,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -163184,7 +163056,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163184 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },163056 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
163185 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },163057 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
163186 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },163058 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
163187 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },163059 .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } },
163188 .{ .type = .f128, .kind = .mem },163060 .{ .type = .f128, .kind = .mem },
163189 .unused,163061 .unused,
163190 .unused,163062 .unused,
...@@ -164816,7 +164688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -164816,7 +164688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
164816 .extra_temps = .{164688 .extra_temps = .{
164817 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },164689 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
164818 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },164690 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
164819 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },164691 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
164820 .unused,164692 .unused,
164821 .unused,164693 .unused,
164822 .unused,164694 .unused,
...@@ -164848,7 +164720,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -164848,7 +164720,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
164848 .extra_temps = .{164720 .extra_temps = .{
164849 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },164721 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
164850 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },164722 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
164851 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },164723 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
164852 .unused,164724 .unused,
164853 .unused,164725 .unused,
164854 .unused,164726 .unused,
...@@ -164880,7 +164752,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -164880,7 +164752,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
164880 .extra_temps = .{164752 .extra_temps = .{
164881 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },164753 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
164882 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },164754 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
164883 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },164755 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
164884 .unused,164756 .unused,
164885 .unused,164757 .unused,
164886 .unused,164758 .unused,
...@@ -164913,7 +164785,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -164913,7 +164785,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
164913 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },164785 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
164914 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },164786 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
164915 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },164787 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
164916 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },164788 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
164917 .{ .type = .f128, .kind = .mem },164789 .{ .type = .f128, .kind = .mem },
164918 .unused,164790 .unused,
164919 .unused,164791 .unused,
...@@ -164947,7 +164819,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -164947,7 +164819,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
164947 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },164819 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
164948 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },164820 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
164949 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },164821 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
164950 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },164822 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
164951 .{ .type = .f128, .kind = .mem },164823 .{ .type = .f128, .kind = .mem },
164952 .unused,164824 .unused,
164953 .unused,164825 .unused,
...@@ -164981,7 +164853,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -164981,7 +164853,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
164981 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },164853 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
164982 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },164854 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
164983 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },164855 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
164984 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },164856 .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } },
164985 .{ .type = .f128, .kind = .mem },164857 .{ .type = .f128, .kind = .mem },
164986 .unused,164858 .unused,
164987 .unused,164859 .unused,
...@@ -172785,7 +172657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -172785,7 +172657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
172785 },172657 },
172786 .call_frame = .{ .alignment = .@"16" },172658 .call_frame = .{ .alignment = .@"16" },
172787 .extra_temps = .{172659 .extra_temps = .{
172788 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },172660 .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } },
172789 .unused,172661 .unused,
172790 .unused,172662 .unused,
172791 .unused,172663 .unused,
...@@ -172818,7 +172690,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -172818,7 +172690,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
172818 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },172690 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172819 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },172691 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
172820 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },172692 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
172821 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },172693 .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } },
172822 .unused,172694 .unused,
172823 .unused,172695 .unused,
172824 .unused,172696 .unused,
...@@ -172852,7 +172724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -172852,7 +172724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
172852 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },172724 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172853 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },172725 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
172854 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } },172726 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } },
172855 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },172727 .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } },
172856 .unused,172728 .unused,
172857 .unused,172729 .unused,
172858 .unused,172730 .unused,
...@@ -172889,7 +172761,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -172889,7 +172761,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
172889 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },172761 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172890 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },172762 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
172891 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } },172763 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } },
172892 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },172764 .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } },
172893 .unused,172765 .unused,
172894 .unused,172766 .unused,
172895 .unused,172767 .unused,
...@@ -172926,7 +172798,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -172926,7 +172798,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
172926 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },172798 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172927 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },172799 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
172928 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } },172800 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } },
172929 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },172801 .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } },
172930 .unused,172802 .unused,
172931 .unused,172803 .unused,
172932 .unused,172804 .unused,
...@@ -172963,7 +172835,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -172963,7 +172835,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
172963 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },172835 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172964 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },172836 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
172965 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },172837 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
172966 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },172838 .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } },
172967 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },172839 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172968 .unused,172840 .unused,
172969 .unused,172841 .unused,
...@@ -173000,7 +172872,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -173000,7 +172872,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173000 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },172872 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
173001 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },172873 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
173002 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },172874 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
173003 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },172875 .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } },
173004 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },172876 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
173005 .unused,172877 .unused,
173006 .unused,172878 .unused,
...@@ -173037,7 +172909,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -173037,7 +172909,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173037 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },172909 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
173038 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },172910 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
173039 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },172911 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
173040 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },172912 .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } },
173041 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },172913 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
173042 .unused,172914 .unused,
173043 .unused,172915 .unused,
...@@ -182636,15 +182508,15 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.lang.Type.Int {...@@ -182636,15 +182508,15 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.lang.Type.Int {
182636 .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },182508 .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },
182637 .isize => .{ .signedness = .signed, .bits = cg.target.ptrBitWidth() },182509 .isize => .{ .signedness = .signed, .bits = cg.target.ptrBitWidth() },
182638 .usize => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() },182510 .usize => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() },
182639 .c_char => .{ .signedness = cg.target.cCharSignedness(), .bits = cg.target.cTypeBitSize(.char) },182511 .c_char => .{ .signedness = cg.target.cCharSignedness().?, .bits = cg.target.cTypeBitSize(.char).? },
182640 .c_short => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.short) },182512 .c_short => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.short).? },
182641 .c_ushort => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.short) },182513 .c_ushort => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.short).? },
182642 .c_int => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.int) },182514 .c_int => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.int).? },
182643 .c_uint => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.int) },182515 .c_uint => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.int).? },
182644 .c_long => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.long) },182516 .c_long => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.long).? },
182645 .c_ulong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.long) },182517 .c_ulong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.long).? },
182646 .c_longlong => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.longlong) },182518 .c_longlong => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.longlong).? },
182647 .c_ulonglong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.longlong) },182519 .c_ulonglong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.longlong).? },
182648 .f16, .f32, .f64, .f80, .f128, .c_longdouble => null,182520 .f16, .f32, .f64, .f80, .f128, .c_longdouble => null,
182649 .anyopaque,182521 .anyopaque,
182650 .void,182522 .void,
src/codegen/x86_64/abi.zig+38-15
...@@ -133,7 +133,7 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx:...@@ -133,7 +133,7 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx:
133 .float => switch (ty.floatBits(target)) {133 .float => switch (ty.floatBits(target)) {
134 16, 32, 64 => .sse,134 16, 32, 64 => .sse,
135 80 => .memory,135 80 => .memory,
136 128 => if (ctx == .arg) .memory else .sse,136 128 => .win_i128,
137 else => unreachable,137 else => unreachable,
138 },138 },
139 .vector => {139 .vector => {
...@@ -238,16 +238,18 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont...@@ -238,16 +238,18 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont
238 };238 };
239 const unaligned_size = elem_ty.abiSize(zcu) * len;239 const unaligned_size = elem_ty.abiSize(zcu) * len;
240 if (unaligned_size <= 4) return Class.one_integer;240 if (unaligned_size <= 4) return Class.one_integer;
241 if (ctx == .arg and unaligned_size == 8 * 1 * 1 and len == 1 and241 if (unaligned_size == 8 * 1 * 1 and len == 1) {
242 elem_ty.isRuntimeFloat()) return Class.stack; // what242 if (ctx == .arg and elem_ty.isRuntimeFloat()) return Class.stack; // what?
243 if (ctx != .other and !elem_ty.isRuntimeFloat() and target.os.tag == .freebsd) return Class.one_integer; // who?
244 }
243 if (unaligned_size <= 8 * 1) return .{ .sse, .none, .none, .none, .none, .none, .none, .none };245 if (unaligned_size <= 8 * 1) return .{ .sse, .none, .none, .none, .none, .none, .none, .none };
244 if (unaligned_size <= 8 * 2) return .{ .sse, .sseup, .none, .none, .none, .none, .none, .none };246 if (unaligned_size <= 8 * 2) return .{ .sse, .sseup, .none, .none, .none, .none, .none, .none };
245 if (!target.cpu.has(.x86, .avx)) {247 if (!target.cpu.has(.x86, .avx)) {
246 if (ctx == .ret) switch (unaligned_size) {248 if (ctx == .ret) switch (unaligned_size) {
247 else => {},249 else => {},
248 8 * 3 => if (len == 3) return if (elem_ty.isRuntimeFloat()) .{250 8 * 3 => if (len == 3) return if (elem_ty.isRuntimeFloat()) .{
249 .sse_sse_x87_per_qword, .none, .none, .none, .none, .none, .none, .none, // how251 .sse_sse_x87_per_qword, .none, .none, .none, .none, .none, .none, .none, // how?
250 } else Class.len_integers, // why252 } else Class.len_integers, // why?
251 8 * 2 * 2, 8 * 2 * 4 => return .{ .sse_per_xword, .none, .none, .none, .none, .none, .none, .none },253 8 * 2 * 2, 8 * 2 * 4 => return .{ .sse_per_xword, .none, .none, .none, .none, .none, .none, .none },
252 };254 };
253 return Class.stack;255 return Class.stack;
...@@ -356,11 +358,10 @@ fn classifySystemVStruct(...@@ -356,11 +358,10 @@ fn classifySystemVStruct(
356 while (field_it.next()) |field_index| {358 while (field_it.next()) |field_index| {
357 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);359 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
358 const field_align = loaded_struct.field_aligns.getOrNone(ip, field_index);360 const field_align = loaded_struct.field_aligns.getOrNone(ip, field_index);
359 byte_offset = std.mem.alignForward(361 byte_offset = switch (field_align) {
360 u64,362 .none => field_ty.abiAlignment(zcu),
361 byte_offset,363 else => field_align,
362 field_align.toByteUnits() orelse field_ty.abiAlignment(zcu).toByteUnits().?,364 }.forward(byte_offset);
363 );
364 if (zcu.typeToStruct(field_ty)) |field_loaded_struct| {365 if (zcu.typeToStruct(field_ty)) |field_loaded_struct| {
365 switch (field_loaded_struct.layout) {366 switch (field_loaded_struct.layout) {
366 .auto => unreachable,367 .auto => unreachable,
...@@ -379,6 +380,9 @@ fn classifySystemVStruct(...@@ -379,6 +380,9 @@ fn classifySystemVStruct(
379 },380 },
380 .@"packed" => {},381 .@"packed" => {},
381 }382 }
383 } else if (field_ty.zigTypeTag(zcu) == .array) {
384 byte_offset = classifySystemVArray(result, byte_offset, field_ty, zcu, target);
385 continue;
382 }386 }
383 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none);387 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none);
384 for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|388 for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
...@@ -386,11 +390,7 @@ fn classifySystemVStruct(...@@ -386,11 +390,7 @@ fn classifySystemVStruct(
386 byte_offset += field_ty.abiSize(zcu);390 byte_offset += field_ty.abiSize(zcu);
387 }391 }
388 const final_byte_offset = starting_byte_offset + loaded_struct.size;392 const final_byte_offset = starting_byte_offset + loaded_struct.size;
389 std.debug.assert(final_byte_offset == std.mem.alignForward(393 std.debug.assert(final_byte_offset == loaded_struct.alignment.forward(byte_offset));
390 u64,
391 byte_offset,
392 loaded_struct.alignment.toByteUnits().?,
393 ));
394 return final_byte_offset;394 return final_byte_offset;
395}395}
396396
...@@ -422,6 +422,9 @@ fn classifySystemVUnion(...@@ -422,6 +422,9 @@ fn classifySystemVUnion(
422 },422 },
423 .@"packed" => {},423 .@"packed" => {},
424 }424 }
425 } else if (field_ty.zigTypeTag(zcu) == .array) {
426 _ = classifySystemVArray(result, starting_byte_offset, field_ty, zcu, target);
427 continue;
425 }428 }
426 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none);429 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none);
427 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|430 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
...@@ -430,6 +433,26 @@ fn classifySystemVUnion(...@@ -430,6 +433,26 @@ fn classifySystemVUnion(
430 return starting_byte_offset + loaded_union.size;433 return starting_byte_offset + loaded_union.size;
431}434}
432435
436fn classifySystemVArray(
437 result: *[8]Class,
438 starting_byte_offset: u64,
439 array_ty: Type,
440 zcu: *Zcu,
441 target: *const std.Target,
442) u64 {
443 const field_classes = std.mem.sliceTo(&classifySystemV(array_ty.childType(zcu), zcu, target, .other), .none);
444 var byte_offset = starting_byte_offset;
445 const elem_size = array_ty.childType(zcu).abiSize(zcu);
446 for (0..@intCast(array_ty.arrayLen(zcu))) |_| {
447 for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
448 result_class.* = result_class.combineSystemV(field_class);
449 byte_offset += elem_size;
450 }
451 const final_byte_offset = starting_byte_offset + array_ty.abiSize(zcu);
452 assert(final_byte_offset == byte_offset);
453 return final_byte_offset;
454}
455
433pub const zigcc = struct {456pub const zigcc = struct {
434 pub const stack_align: ?InternPool.Alignment = null;457 pub const stack_align: ?InternPool.Alignment = null;
435 pub const return_in_regs = true;458 pub const return_in_regs = true;
src/libs/mingw/Preprocessor.zig+2-2
...@@ -91,9 +91,9 @@ fn addTokenAssumeCapacity(pp: *Preprocessor, tok: Token) void {...@@ -91,9 +91,9 @@ fn addTokenAssumeCapacity(pp: *Preprocessor, tok: Token) void {
9191
92fn defineBuiltins(pp: *Preprocessor) !void {92fn defineBuiltins(pp: *Preprocessor) !void {
93 var buf: [5]u8 = undefined;93 var buf: [5]u8 = undefined;
94 var val = std.fmt.bufPrint(&buf, "{d}", .{pp.target.cTypeBitSize(.longdouble)}) catch unreachable;94 var val = std.fmt.bufPrint(&buf, "{d}", .{pp.target.cTypeByteSize(.longdouble).?}) catch unreachable;
95 try pp.defineBuiltinValue("__SIZEOF_LONG_DOUBLE__", val, .pp_num);95 try pp.defineBuiltinValue("__SIZEOF_LONG_DOUBLE__", val, .pp_num);
96 val = std.fmt.bufPrint(&buf, "{d}", .{pp.target.cTypeBitSize(.double)}) catch unreachable;96 val = std.fmt.bufPrint(&buf, "{d}", .{pp.target.cTypeByteSize(.double).?}) catch unreachable;
97 try pp.defineBuiltinValue("__SIZEOF_DOUBLE__", val, .pp_num);97 try pp.defineBuiltinValue("__SIZEOF_DOUBLE__", val, .pp_num);
9898
99 if (pp.target.abi.isGnu()) {99 if (pp.target.abi.isGnu()) {
src/link.zig+2-2
...@@ -1238,7 +1238,7 @@ pub const File = struct {...@@ -1238,7 +1238,7 @@ pub const File = struct {
1238 }1238 }
12391239
1240 switch (base.tag) {1240 switch (base.tag) {
1241 inline .elf2, .coff2, .wasm => |tag| {1241 inline .elf2, .coff2, .wasm, .c => |tag| {
1242 dev.check(tag.devFeature());1242 dev.check(tag.devFeature());
1243 try @as(*tag.Type(), @fieldParentPtr("base", base)).prelink(base.comp.link_prog_node);1243 try @as(*tag.Type(), @fieldParentPtr("base", base)).prelink(base.comp.link_prog_node);
1244 },1244 },
...@@ -2127,7 +2127,7 @@ pub fn resolveInputs(...@@ -2127,7 +2127,7 @@ pub fn resolveInputs(
2127 continue;2127 continue;
2128 },2128 },
2129 }2129 }
2130 @compileError("unreachable");2130 comptime unreachable;
2131 }2131 }
21322132
2133 if (failed_libs.items.len > 0) {2133 if (failed_libs.items.len > 0) {
src/link/C.zig+25-24
...@@ -43,6 +43,8 @@ type_dependencies: std.ArrayList(link.ConstPool.Index),...@@ -43,6 +43,8 @@ type_dependencies: std.ArrayList(link.ConstPool.Index),
43/// one array.43/// one array.
44align_dependency_masks: std.ArrayList(u64),44align_dependency_masks: std.ArrayList(u64),
4545
46/// Emitted at the top of the file. This can be cached since it only depends on the target.
47header: String,
46/// All NAVs, regardless of whether they are functions or simple constants, are put in this map.48/// All NAVs, regardless of whether they are functions or simple constants, are put in this map.
47navs: std.array_hash_map.Auto(InternPool.Nav.Index, RenderedDecl),49navs: std.array_hash_map.Auto(InternPool.Nav.Index, RenderedDecl),
48/// All UAVs which may be referenced are in this map. The UAV alignment is not included in the50/// All UAVs which may be referenced are in this map. The UAV alignment is not included in the
...@@ -404,9 +406,8 @@ pub fn createEmpty(...@@ -404,9 +406,8 @@ pub fn createEmpty(
404 emit: Path,406 emit: Path,
405 options: link.File.OpenOptions,407 options: link.File.OpenOptions,
406) !*C {408) !*C {
409 assert(comp.root_mod.resolved_target.result.ofmt == .c);
407 const io = comp.io;410 const io = comp.io;
408 const target = &comp.root_mod.resolved_target.result;
409 assert(target.ofmt == .c);
410 const optimize_mode = comp.root_mod.optimize_mode;411 const optimize_mode = comp.root_mod.optimize_mode;
411 const use_lld = build_options.have_llvm and comp.config.use_lld;412 const use_lld = build_options.have_llvm and comp.config.use_lld;
412 const use_llvm = comp.config.use_llvm;413 const use_llvm = comp.config.use_llvm;
...@@ -422,9 +423,8 @@ pub fn createEmpty(...@@ -422,9 +423,8 @@ pub fn createEmpty(
422 });423 });
423 errdefer file.close(io);424 errdefer file.close(io);
424425
425 const c_file = try arena.create(C);426 const c = try arena.create(C);
426427 c.* = .{
427 c_file.* = .{
428 .base = .{428 .base = .{
429 .tag = .c,429 .tag = .c,
430 .comp = comp,430 .comp = comp,
...@@ -439,6 +439,7 @@ pub fn createEmpty(...@@ -439,6 +439,7 @@ pub fn createEmpty(
439 .string_bytes = .empty,439 .string_bytes = .empty,
440 .type_dependencies = .empty,440 .type_dependencies = .empty,
441 .align_dependency_masks = .empty,441 .align_dependency_masks = .empty,
442 .header = .empty,
442 .navs = .empty,443 .navs = .empty,
443 .uavs = .empty,444 .uavs = .empty,
444 .type_pool = .empty,445 .type_pool = .empty,
...@@ -447,8 +448,7 @@ pub fn createEmpty(...@@ -447,8 +448,7 @@ pub fn createEmpty(
447 .exported_navs = .empty,448 .exported_navs = .empty,
448 .exported_uavs = .empty,449 .exported_uavs = .empty,
449 };450 };
450451 return c;
451 return c_file;
452}452}
453453
454pub fn deinit(c: *C) void {454pub fn deinit(c: *C) void {
...@@ -469,6 +469,21 @@ pub fn deinit(c: *C) void {...@@ -469,6 +469,21 @@ pub fn deinit(c: *C) void {
469 c.exported_uavs.deinit(gpa);469 c.exported_uavs.deinit(gpa);
470}470}
471471
472pub fn prelink(c: *C, prog_node: std.Progress.Node) !void {
473 const comp = c.base.comp;
474
475 const sub_prog_node = prog_node.start("Generate Header", 0);
476 defer sub_prog_node.end();
477
478 var header_aw: std.Io.Writer.Allocating = .init(comp.gpa);
479 defer header_aw.deinit();
480 codegen.genHeader(comp.zcu.?, &header_aw.writer) catch |err| switch (err) {
481 error.WriteFailed => return error.OutOfMemory,
482 else => |e| return e,
483 };
484 c.header = try c.addString(&.{header_aw.written()});
485}
486
472pub fn updateContainerType(487pub fn updateContainerType(
473 c: *C,488 c: *C,
474 pt: Zcu.PerThread,489 pt: Zcu.PerThread,
...@@ -727,7 +742,6 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog...@@ -727,7 +742,6 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
727 const io = comp.io;742 const io = comp.io;
728 const zcu = c.base.comp.zcu.?;743 const zcu = c.base.comp.zcu.?;
729 const ip = &zcu.intern_pool;744 const ip = &zcu.intern_pool;
730 const target = zcu.getTarget();
731 const active = zcu.activate(tid);745 const active = zcu.activate(tid);
732 defer active.deactivate();746 defer active.deactivate();
733 const pt = active.pt;747 const pt = active.pt;
...@@ -943,7 +957,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog...@@ -943,7 +957,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
943 // We have discovered the full set of NAVs, UAVs, and types we need to emit, and will now begin957 // We have discovered the full set of NAVs, UAVs, and types we need to emit, and will now begin
944 // to build the output buffer. Our strategy is to emit the C source in this order:958 // to build the output buffer. Our strategy is to emit the C source in this order:
945 //959 //
946 // * ABI defines and `#include "zig.h"`960 // * Header
947 // * Big-int type definitions961 // * Big-int type definitions
948 // * Other CType definitions (traversing the dependency graph to sort topologically)962 // * Other CType definitions (traversing the dependency graph to sort topologically)
949 // * Global assembly963 // * Global assembly
...@@ -968,7 +982,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog...@@ -968,7 +982,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
968982
969 // We know exactly what we'll be emitting, so can reserve capacity for all of our buffers!983 // We know exactly what we'll be emitting, so can reserve capacity for all of our buffers!
970984
971 try f.all_buffers.ensureUnusedCapacity(gpa, 3 + // ABI defines and `#include "zig.h"`985 try f.all_buffers.ensureUnusedCapacity(gpa, 1 + // Header
972 1 + // Big-int type definitions986 1 + // Big-int type definitions
973 need_types.count() + // `RenderedType.fwd_decl` (worst-case)987 need_types.count() + // `RenderedType.fwd_decl` (worst-case)
974 need_types.count() + // `RenderedType.definition`988 need_types.count() + // `RenderedType.definition`
...@@ -984,20 +998,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog...@@ -984,20 +998,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
984 need_uavs.count() * 3 + // UAV definitions ("static ", "zig_align(4)", "<definition body>")998 need_uavs.count() * 3 + // UAV definitions ("static ", "zig_align(4)", "<definition body>")
985 need_navs.count() * 2); // NAV definitions ("static ", "<definition body>")999 need_navs.count() * 2); // NAV definitions ("static ", "<definition body>")
9861000
987 // ABI defines and `#include "zig.h"`1001 f.appendBufAssumeCapacity(c.header.get(c));
988 switch (target.abi) {
989 .msvc, .itanium => f.appendBufAssumeCapacity("#define ZIG_TARGET_ABI_MSVC\n"),
990 else => {},
991 }
992 f.appendBufAssumeCapacity(try std.fmt.allocPrint(
993 arena,
994 "#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}\n",
995 .{target.cMaxIntAlignment()},
996 ));
997 f.appendBufAssumeCapacity(
998 \\#include "zig.h"
999 \\
1000 );
10011002
1002 // Big-int type definitions1003 // Big-int type definitions
1003 var bigint_aw: std.Io.Writer.Allocating = .init(gpa);1004 var bigint_aw: std.Io.Writer.Allocating = .init(gpa);
src/link/Dwarf.zig+1-2
...@@ -4151,8 +4151,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -4151,8 +4151,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
4151 .x86_64_regcall_v3_sysv => .LLVM_X86RegCall,4151 .x86_64_regcall_v3_sysv => .LLVM_X86RegCall,
4152 .x86_64_regcall_v4_win => .LLVM_X86RegCall,4152 .x86_64_regcall_v4_win => .LLVM_X86RegCall,
4153 .x86_64_vectorcall => .LLVM_vectorcall,4153 .x86_64_vectorcall => .LLVM_vectorcall,
4154 .x86_sysv => .normal,4154 .x86_sysv, .x86_win, .x86_mingw => .normal,
4155 .x86_win => .normal,
4156 .x86_stdcall => .BORLAND_stdcall,4155 .x86_stdcall => .BORLAND_stdcall,
4157 .x86_fastcall => .BORLAND_msfastcall,4156 .x86_fastcall => .BORLAND_msfastcall,
4158 .x86_thiscall => .BORLAND_thiscall,4157 .x86_thiscall => .BORLAND_thiscall,
src/main.zig+10-4
...@@ -3835,11 +3835,17 @@ fn buildOutputType(...@@ -3835,11 +3835,17 @@ fn buildOutputType(
38353835
3836 var prev_has_cflags = false;3836 var prev_has_cflags = false;
3837 var prev_has_rcflags = false;3837 var prev_has_rcflags = false;
3838 if (dirs.zig_lib.path) |zig_lib_path| {3838 {
3839 try test_exec_args.appendSlice(arena, &.{ "-cflags", "-I", zig_lib_path, "--" });3839 if (dirs.zig_lib.path) |zig_lib_path| {
3840 prev_has_cflags = true;3840 try test_exec_args.appendSlice(arena, &.{ "-cflags", "-I", zig_lib_path, "--" });
3841 prev_has_cflags = true;
3842 }
3843 const emit_ext: Compilation.FileExt = .c;
3844 const need_lang = if (comp.emit_bin) |comp_emit_bin| Compilation.classifyFileExt(comp_emit_bin) != emit_ext else true;
3845 if (need_lang) try test_exec_args.appendSlice(arena, &.{ "-x", emit_ext.toLang() });
3846 try test_exec_args.append(arena, null);
3847 if (need_lang) try test_exec_args.appendSlice(arena, &.{ "-x", "none" });
3841 }3848 }
3842 try test_exec_args.append(arena, null);
3843 for (create_module.modules.keys(), create_module.modules.values()) |mod_name, mod| {3849 for (create_module.modules.keys(), create_module.modules.values()) |mod_name, mod| {
3844 for (create_module.c_source_files.items[mod.c_source_files_start..mod.c_source_files_end]) |c_source_file| {3850 for (create_module.c_source_files.items[mod.c_source_files_start..mod.c_source_files_end]) |c_source_file| {
3845 const cflags_len = c_source_file.extra_flags.len + c_source_file.cache_exempt_flags.len;3851 const cflags_len = c_source_file.extra_flags.len + c_source_file.cache_exempt_flags.len;
src/target.zig+3-3
...@@ -876,18 +876,18 @@ pub fn libcFloatSuffix(float_bits: u16) []const u8 {...@@ -876,18 +876,18 @@ pub fn libcFloatSuffix(float_bits: u16) []const u8 {
876 32 => "f",876 32 => "f",
877 64 => "",877 64 => "",
878 80 => "x", // Non-standard878 80 => "x", // Non-standard
879 128 => "q", // Non-standard (mimics convention in GCC libquadmath)879 128 => "f128",
880 else => unreachable,880 else => unreachable,
881 };881 };
882}882}
883883
884pub fn compilerRtFloatAbbrev(float_bits: u16) []const u8 {884pub fn compilerRtFloatAbbrev(target: *const std.Target, float_bits: u16) []const u8 {
885 return switch (float_bits) {885 return switch (float_bits) {
886 16 => "h",886 16 => "h",
887 32 => "s",887 32 => "s",
888 64 => "d",888 64 => "d",
889 80 => "x",889 80 => "x",
890 128 => "t",890 128 => if (target.cpu.arch.isPowerPC()) "k" else "t",
891 else => unreachable,891 else => unreachable,
892 };892 };
893}893}
stage1/zig.h+3079-991
...@@ -166,6 +166,12 @@...@@ -166,6 +166,12 @@
166#endif166#endif
167#define zig_expand_has_builtin(b) zig_has_builtin(b)167#define zig_expand_has_builtin(b) zig_has_builtin(b)
168168
169#if defined(__has_feature)
170#define zig_has_feature(feature) __has_feature(feature)
171#else
172#define zig_has_feature(feature) 0
173#endif
174
169#if defined(__has_attribute)175#if defined(__has_attribute)
170#define zig_has_attribute(attribute) __has_attribute(attribute)176#define zig_has_attribute(attribute) __has_attribute(attribute)
171#else177#else
...@@ -175,9 +181,9 @@...@@ -175,9 +181,9 @@
175#if __STDC_VERSION__ >= 201112L181#if __STDC_VERSION__ >= 201112L
176#define zig_static_assert(cond, msg) _Static_assert(cond, msg)182#define zig_static_assert(cond, msg) _Static_assert(cond, msg)
177#elif zig_has_attribute(unused)183#elif zig_has_attribute(unused)
178#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)] __attribute__((unused))184#define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1] __attribute__((unused))
179#else185#else
180#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)]186#define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1]
181#endif187#endif
182188
183#if __STDC_VERSION__ >= 202311L189#if __STDC_VERSION__ >= 202311L
...@@ -193,10 +199,8 @@...@@ -193,10 +199,8 @@
193#endif199#endif
194200
195#if defined(zig_msvc)201#if defined(zig_msvc)
196#define zig_const_arr
197#define zig_callconv(c) __##c202#define zig_callconv(c) __##c
198#else203#else
199#define zig_const_arr static const
200#define zig_callconv(c) __attribute__((c))204#define zig_callconv(c) __attribute__((c))
201#endif205#endif
202206
...@@ -267,12 +271,20 @@...@@ -267,12 +271,20 @@
267271
268#if __STDC_VERSION__ >= 202311L272#if __STDC_VERSION__ >= 202311L
269#define zig_align(alignment) alignas(alignment)273#define zig_align(alignment) alignas(alignment)
270#elif __STDC_VERSION__ >= 201112L274#elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignas)
271#define zig_align(alignment) _Alignas(alignment)275#define zig_align(alignment) _Alignas(alignment)
272#else276#else
273#define zig_align(alignment) zig_under_align(alignment)277#define zig_align(alignment) zig_under_align(alignment)
274#endif278#endif
275279
280#if __STDC_VERSION__ >= 202311L
281#define zig_alignOf(Type) alignof(Type)
282#elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignof)
283#define zig_alignOf(Type) _Alignof(Type)
284#else
285#define zig_alignOf(Type) (sizeof(struct { char c; Type t; }) - sizeof(Type))
286#endif
287
276#if zig_has_attribute(aligned) || defined(zig_tinyc)288#if zig_has_attribute(aligned) || defined(zig_tinyc)
277#define zig_align_fn(alignment) __attribute__((aligned(alignment)))289#define zig_align_fn(alignment) __attribute__((aligned(alignment)))
278#elif defined(zig_msvc)290#elif defined(zig_msvc)
...@@ -350,11 +362,9 @@...@@ -350,11 +362,9 @@
350#define zig_export(symbol, name) __attribute__((alias(symbol)))362#define zig_export(symbol, name) __attribute__((alias(symbol)))
351#else363#else
352#define zig_export(symbol, name) ; \364#define zig_export(symbol, name) ; \
353 __asm(zig_mangle_c(name) " = " zig_mangle_c(symbol))365 __asm("\t.globl\t" zig_mangle_c(name) "\n" zig_mangle_c(name) " = " zig_mangle_c(symbol))
354#endif366#endif
355367
356#define zig_mangled_tentative zig_mangled
357#define zig_mangled_final zig_mangled
358#if defined(zig_msvc)368#if defined(zig_msvc)
359#define zig_mangled(mangled, unmangled) ; \369#define zig_mangled(mangled, unmangled) ; \
360 zig_export(#mangled, unmangled)370 zig_export(#mangled, unmangled)
...@@ -364,7 +374,7 @@...@@ -364,7 +374,7 @@
364#else /* zig_msvc */374#else /* zig_msvc */
365#define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled))375#define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled))
366#define zig_mangled_export(mangled, unmangled, symbol) \376#define zig_mangled_export(mangled, unmangled, symbol) \
367 zig_mangled_final(mangled, unmangled) \377 zig_mangled(mangled, unmangled) \
368 zig_export(symbol, unmangled)378 zig_export(symbol, unmangled)
369#endif /* zig_msvc */379#endif /* zig_msvc */
370380
...@@ -550,6 +560,9 @@...@@ -550,6 +560,9 @@
550#define zig_noreturn560#define zig_noreturn
551#endif561#endif
552562
563#define zig_has_always 1
564#define zig_has_never 0
565
553#define zig_compiler_rt_abbrev_uint32_t si566#define zig_compiler_rt_abbrev_uint32_t si
554#define zig_compiler_rt_abbrev_int32_t si567#define zig_compiler_rt_abbrev_int32_t si
555#define zig_compiler_rt_abbrev_uint64_t di568#define zig_compiler_rt_abbrev_uint64_t di
...@@ -560,7 +573,11 @@...@@ -560,7 +573,11 @@
560#define zig_compiler_rt_abbrev_zig_f32 sf573#define zig_compiler_rt_abbrev_zig_f32 sf
561#define zig_compiler_rt_abbrev_zig_f64 df574#define zig_compiler_rt_abbrev_zig_f64 df
562#define zig_compiler_rt_abbrev_zig_f80 xf575#define zig_compiler_rt_abbrev_zig_f80 xf
576#ifdef zig_powerpc
577#define zig_compiler_rt_abbrev_zig_f128 kf
578#else
563#define zig_compiler_rt_abbrev_zig_f128 tf579#define zig_compiler_rt_abbrev_zig_f128 tf
580#endif
564581
565zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);582zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);
566zig_extern void *memset (void *, int, size_t);583zig_extern void *memset (void *, int, size_t);
...@@ -645,16 +662,6 @@ typedef signed long long int16_t;...@@ -645,16 +662,6 @@ typedef signed long long int16_t;
645#define INT16_MAX ( INT16_C(0x7FFF))662#define INT16_MAX ( INT16_C(0x7FFF))
646#define UINT16_MAX ( INT16_C(0xFFFF))663#define UINT16_MAX ( INT16_C(0xFFFF))
647664
648#if defined(zig_ez80)
649typedef unsigned int uint24_t;
650typedef signed int int24_t;
651#define INT24_C(c) c
652#define UINT24_C(c) c##U
653#endif
654#define INT24_MIN (~INT24_C(0x7FFF))
655#define INT24_MAX ( INT24_C(0x7FFF))
656#define UINT24_MAX ( INT24_C(0xFFFF))
657
658#if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF665#if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF
659typedef unsigned char uint32_t;666typedef unsigned char uint32_t;
660typedef signed char int32_t;667typedef signed char int32_t;
...@@ -685,17 +692,6 @@ typedef signed long long int32_t;...@@ -685,17 +692,6 @@ typedef signed long long int32_t;
685#define INT32_MAX ( INT32_C(0x7FFFFFFF))692#define INT32_MAX ( INT32_C(0x7FFFFFFF))
686#define UINT32_MAX ( INT32_C(0xFFFFFFFF))693#define UINT32_MAX ( INT32_C(0xFFFFFFFF))
687694
688#if defined(zig_ez80)
689typedef unsigned __int48 uint48_t;
690typedef signed __int48 int48_t;
691#define INT48_C(c) c
692/* no suffix */
693#define UINT48_C(c) ((uint48_t)(c))
694#endif
695#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF))
696#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF))
697#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF))
698
699#if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF695#if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF
700typedef unsigned char uint64_t;696typedef unsigned char uint64_t;
701typedef signed char int64_t;697typedef signed char int64_t;
...@@ -726,6 +722,27 @@ typedef signed long long int64_t;...@@ -726,6 +722,27 @@ typedef signed long long int64_t;
726#define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF))722#define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF))
727#define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF))723#define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF))
728724
725#if defined(zig_ez80)
726
727typedef unsigned int uint24_t;
728typedef signed int int24_t;
729#define INT24_C(c) c
730#define UINT24_C(c) c##U
731#define INT24_MIN (~INT24_C(0x7FFF))
732#define INT24_MAX ( INT24_C(0x7FFF))
733#define UINT24_MAX ( INT24_C(0xFFFF))
734
735typedef unsigned __int48 uint48_t;
736typedef signed __int48 int48_t;
737#define INT48_C(c) c
738/* no suffix */
739#define UINT48_C(c) ((uint48_t)(c))
740#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF))
741#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF))
742#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF))
743
744#endif
745
729typedef size_t uintptr_t;746typedef size_t uintptr_t;
730typedef ptrdiff_t intptr_t;747typedef ptrdiff_t intptr_t;
731748
...@@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t;...@@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t;
739#define zig_maxInt_i16 INT16_MAX756#define zig_maxInt_i16 INT16_MAX
740#define zig_minInt_u16 UINT16_C(0)757#define zig_minInt_u16 UINT16_C(0)
741#define zig_maxInt_u16 UINT16_MAX758#define zig_maxInt_u16 UINT16_MAX
742#define zig_minInt_i24 INT24_MIN
743#define zig_maxInt_i24 INT24_MAX
744#define zig_minInt_u24 UINT24_C(0)
745#define zig_maxInt_u24 UINT24_MAX
746#define zig_minInt_i32 INT32_MIN759#define zig_minInt_i32 INT32_MIN
747#define zig_maxInt_i32 INT32_MAX760#define zig_maxInt_i32 INT32_MAX
748#define zig_minInt_u32 UINT32_C(0)761#define zig_minInt_u32 UINT32_C(0)
749#define zig_maxInt_u32 UINT32_MAX762#define zig_maxInt_u32 UINT32_MAX
750#define zig_minInt_i48 INT48_MIN
751#define zig_maxInt_i48 INT48_MAX
752#define zig_minInt_u48 UINT48_C(0)
753#define zig_maxInt_u48 UINT48_MAX
754#define zig_minInt_i64 INT64_MIN763#define zig_minInt_i64 INT64_MIN
755#define zig_maxInt_i64 INT64_MAX764#define zig_maxInt_i64 INT64_MAX
756#define zig_minInt_u64 UINT64_C(0)765#define zig_minInt_u64 UINT64_C(0)
757#define zig_maxInt_u64 UINT64_MAX766#define zig_maxInt_u64 UINT64_MAX
758767
768// zig_promoted_T implements C integral promotions except with signedness preserved, which
769// allows wrapping operations to avoid the ub that would be caused by the normal promotion.
770
771#if INT8_MAX <= INT_MAX
772typedef unsigned int zig_promoted_i8;
773#elif INT8_MAX <= LONG_MAX
774typedef unsigned long zig_promoted_i8;
775#elif INT8_MAX <= LLONG_MAX
776typedef unsigned long long zig_promoted_i8;
777#else
778typedef int8_t zig_promoted_i8;
779#endif
780#if UINT8_MAX <= UINT_MAX
781typedef unsigned int zig_promoted_u8;
782#elif UINT8_MAX <= ULONG_MAX
783typedef unsigned long zig_promoted_u8;
784#elif UINT8_MAX <= ULLONG_MAX
785typedef unsigned long long zig_promoted_u8;
786#else
787typedef uint8_t zig_promoted_u8;
788#endif
789
790#if INT16_MAX <= INT_MAX
791typedef unsigned int zig_promoted_i16;
792#elif INT16_MAX <= LONG_MAX
793typedef unsigned long zig_promoted_i16;
794#elif INT16_MAX <= LLONG_MAX
795typedef unsigned long long zig_promoted_i16;
796#else
797typedef int16_t zig_promoted_i16;
798#endif
799#if UINT16_MAX <= UINT_MAX
800typedef unsigned int zig_promoted_u16;
801#elif UINT16_MAX <= ULONG_MAX
802typedef unsigned long zig_promoted_u16;
803#elif UINT16_MAX <= ULLONG_MAX
804typedef unsigned long long zig_promoted_u16;
805#else
806typedef uint16_t zig_promoted_u16;
807#endif
808
809#if INT32_MAX <= INT_MAX
810typedef unsigned int zig_promoted_i32;
811#elif INT32_MAX <= LONG_MAX
812typedef unsigned long zig_promoted_i32;
813#elif INT32_MAX <= LLONG_MAX
814typedef unsigned long long zig_promoted_i32;
815#else
816typedef int32_t zig_promoted_i32;
817#endif
818#if UINT32_MAX <= UINT_MAX
819typedef unsigned int zig_promoted_u32;
820#elif UINT32_MAX <= ULONG_MAX
821typedef unsigned long zig_promoted_u32;
822#elif UINT32_MAX <= ULLONG_MAX
823typedef unsigned long long zig_promoted_u32;
824#else
825typedef uint32_t zig_promoted_u32;
826#endif
827
828#if INT64_MAX <= INT_MAX
829typedef unsigned int zig_promoted_i64;
830#elif INT64_MAX <= LONG_MAX
831typedef unsigned long zig_promoted_i64;
832#elif INT64_MAX <= LLONG_MAX
833typedef unsigned long long zig_promoted_i64;
834#else
835typedef int64_t zig_promoted_i64;
836#endif
837#if UINT64_MAX <= UINT_MAX
838typedef unsigned int zig_promoted_u64;
839#elif UINT64_MAX <= ULONG_MAX
840typedef unsigned long zig_promoted_u64;
841#elif UINT64_MAX <= ULLONG_MAX
842typedef unsigned long long zig_promoted_u64;
843#else
844typedef uint64_t zig_promoted_u64;
845#endif
846
847#ifdef zig_ez80
848
849#define zig_minInt_i24 INT24_MIN
850#define zig_maxInt_i24 INT24_MAX
851#define zig_minInt_u24 UINT24_C(0)
852#define zig_maxInt_u24 UINT24_MAX
853#define zig_minInt_i48 INT48_MIN
854#define zig_maxInt_i48 INT48_MAX
855#define zig_minInt_u48 UINT48_C(0)
856#define zig_maxInt_u48 UINT48_MAX
857
858#if INT24_MAX <= INT_MAX
859typedef unsigned int zig_promoted_i24;
860#elif INT24_MAX <= LONG_MAX
861typedef unsigned long zig_promoted_i24;
862#elif INT24_MAX <= LLONG_MAX
863typedef unsigned long long zig_promoted_i24;
864#else
865typedef int24_t zig_promoted_i24;
866#endif
867#if UINT24_MAX <= UINT_MAX
868typedef unsigned int zig_promoted_u24;
869#elif UINT24_MAX <= ULONG_MAX
870typedef unsigned long zig_promoted_u24;
871#elif UINT24_MAX <= ULLONG_MAX
872typedef unsigned long long zig_promoted_u24;
873#else
874typedef uint24_t zig_promoted_u24;
875#endif
876
877#if INT48_MAX <= INT_MAX
878typedef unsigned int zig_promoted_i48;
879#elif INT48_MAX <= LONG_MAX
880typedef unsigned long zig_promoted_i48;
881#elif INT48_MAX <= LLONG_MAX
882typedef unsigned long long zig_promoted_i48;
883#else
884typedef int48_t zig_promoted_i48;
885#endif
886#if UINT48_MAX <= UINT_MAX
887typedef unsigned int zig_promoted_u48;
888#elif UINT48_MAX <= ULONG_MAX
889typedef unsigned long zig_promoted_u48;
890#elif UINT48_MAX <= ULLONG_MAX
891typedef unsigned long long zig_promoted_u48;
892#else
893typedef uint48_t zig_promoted_u48;
894#endif
895
896#endif
897
759#define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits))898#define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits))
760#define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits)899#define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits)
761#define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits)900#define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits)
...@@ -770,7 +909,33 @@ typedef ptrdiff_t intptr_t;...@@ -770,7 +909,33 @@ typedef ptrdiff_t intptr_t;
770 zig_operator(Type, Type, operation, operator)909 zig_operator(Type, Type, operation, operator)
771#define zig_shift_operator(Type, operation, operator) \910#define zig_shift_operator(Type, operation, operator) \
772 zig_operator(Type, uint8_t, operation, operator)911 zig_operator(Type, uint8_t, operation, operator)
773#define zig_int_helpers(w, PromotedUnsigned) \912
913#define zig_int_casts_common(bw, sw) \
914 static inline uint##bw##_t zig_u##bw##_intCast_u##sw(uint##sw##_t arg) { \
915 return arg; \
916 } \
917\
918 static inline uint##bw##_t zig_u##bw##_intCast_i##sw(int##sw##_t arg) { \
919 return (uint##bw##_t)arg; \
920 } \
921\
922 static inline int##bw##_t zig_i##bw##_intCast_u##sw(uint##sw##_t arg) { \
923 return arg; \
924 } \
925\
926 static inline int##bw##_t zig_i##bw##_intCast_i##sw(int##sw##_t arg) { \
927 return arg; \
928 } \
929\
930 static inline uint##sw##_t zig_u##sw##_truncate_u##bw(uint##bw##_t arg, uint8_t bits) { \
931 return (uint##sw##_t)arg & zig_maxInt_u(sw, bits); \
932 } \
933\
934 static inline int##sw##_t zig_i##sw##_truncate_i##bw(int##bw##_t arg, uint8_t bits) { \
935 return ((uint##sw##_t)arg & UINT##sw##_C(1) << (bits - UINT8_C(1))) != UINT##sw##_C(0) \
936 ? (int##sw##_t)arg | zig_minInt_i(sw, bits) : (int##sw##_t)arg & zig_maxInt_i(sw, bits); \
937 }
938#define zig_int_operators(w) \
774 zig_basic_operator(uint##w##_t, and_u##w, &) \939 zig_basic_operator(uint##w##_t, and_u##w, &) \
775 zig_basic_operator( int##w##_t, and_i##w, &) \940 zig_basic_operator( int##w##_t, and_i##w, &) \
776 zig_basic_operator(uint##w##_t, or_u##w, |) \941 zig_basic_operator(uint##w##_t, or_u##w, |) \
...@@ -786,44 +951,48 @@ typedef ptrdiff_t intptr_t;...@@ -786,44 +951,48 @@ typedef ptrdiff_t intptr_t;
786 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \951 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \
787 } \952 } \
788\953\
789 static inline uint##w##_t zig_not_u##w(uint##w##_t val, uint8_t bits) { \954 static inline uint##w##_t zig_not_u##w(uint##w##_t arg, uint8_t bits) { \
790 return val ^ zig_maxInt_u(w, bits); \955 return arg ^ zig_maxInt_u(w, bits); \
791 } \956 } \
792\957\
793 static inline int##w##_t zig_not_i##w(int##w##_t val, uint8_t bits) { \958 static inline int##w##_t zig_not_i##w(int##w##_t arg, uint8_t bits) { \
794 (void)bits; \959 (void)bits; \
795 return ~val; \960 return ~arg; \
796 } \961 } \
797\962\
798 static inline uint##w##_t zig_wrap_u##w(uint##w##_t val, uint8_t bits) { \963 zig_basic_operator(uint##w##_t, divFloor_u##w, /) \
799 return val & zig_maxInt_u(w, bits); \964\
965 static inline int##w##_t zig_divFloor_i##w(int##w##_t lhs, int##w##_t rhs) { \
966 return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \
800 } \967 } \
801\968\
802 static inline int##w##_t zig_wrap_i##w(int##w##_t val, uint8_t bits) { \969 static inline uint##w##_t zig_divCeil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
803 return (val & UINT##w##_C(1) << (bits - UINT8_C(1))) != 0 \970 return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \
804 ? val | zig_minInt_i(w, bits) : val & zig_maxInt_i(w, bits); \
805 } \971 } \
806\972\
807 static inline uint##w##_t zig_abs_i##w(int##w##_t val) { \973 static inline int##w##_t zig_divCeil_i##w(int##w##_t lhs, int##w##_t rhs) { \
808 return (val < 0) ? -(uint##w##_t)val : (uint##w##_t)val; \974 return lhs / rhs + (lhs % rhs != INT##w##_C(0) \
975 ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \
809 } \976 } \
810\977\
811 zig_basic_operator(uint##w##_t, div_floor_u##w, /) \978 zig_basic_operator(uint##w##_t, mod_u##w, %) \
979 zig_int_casts_common(w, w) \
812\980\
813 static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \981 static inline uint##w##_t zig_u##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \
814 return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \982 return zig_u##w##_truncate_u##w(arg, bits); \
815 } \983 } \
816\984\
817 static inline uint##w##_t zig_div_ceil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \985 static inline uint##w##_t zig_u##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \
818 return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \986 return zig_u##w##_bitCast_u##w((uint##w##_t)arg, bits); \
819 } \987 } \
820\988\
821 static inline int##w##_t zig_div_ceil_i##w(int##w##_t lhs, int##w##_t rhs) { \989 static inline int##w##_t zig_i##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \
822 return lhs / rhs + (lhs % rhs != INT##w##_C(0) \990 return zig_i##w##_truncate_i##w(arg, bits); \
823 ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \
824 } \991 } \
825\992\
826 zig_basic_operator(uint##w##_t, mod_u##w, %) \993 static inline int##w##_t zig_i##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \
994 return zig_i##w##_bitCast_i##w((int##w##_t)arg, bits); \
995 } \
827\996\
828 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \997 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \
829 int##w##_t rem = lhs % rhs; \998 int##w##_t rem = lhs % rhs; \
...@@ -831,100 +1000,102 @@ typedef ptrdiff_t intptr_t;...@@ -831,100 +1000,102 @@ typedef ptrdiff_t intptr_t;
831 } \1000 } \
832\1001\
833 static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \1002 static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
834 return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \1003 return zig_u##w##_truncate_u##w(zig_shl_u##w(lhs, rhs), bits); \
835 } \1004 } \
836\1005\
837 static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \1006 static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \
838 return zig_wrap_i##w((int##w##_t)zig_shl_u##w((uint##w##_t)lhs, rhs), bits); \1007 return zig_i##w##_bitCast_u##w(zig_shl_u##w(zig_u##w##_bitCast_i##w(lhs, bits), rhs), bits); \
839 } \1008 } \
840\1009\
841 static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1010 static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
842 return zig_wrap_u##w(lhs + rhs, bits); \1011 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs + rhs, bits); \
843 } \1012 } \
844\1013\
845 static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \1014 static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
846 return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs + (uint##w##_t)rhs), bits); \1015 return zig_i##w##_bitCast_u##w(zig_addw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
847 } \1016 } \
848\1017\
849 static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1018 static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
850 return zig_wrap_u##w(lhs - rhs, bits); \1019 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs - rhs, bits); \
851 } \1020 } \
852\1021\
853 static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \1022 static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
854 return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs - (uint##w##_t)rhs), bits); \1023 return zig_i##w##_bitCast_u##w(zig_subw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
855 } \1024 } \
856\1025\
857 static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1026 static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
858 return zig_wrap_u##w((PromotedUnsigned)lhs * rhs, bits); \1027 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs * rhs, bits); \
859 } \1028 } \
860\1029\
861 static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \1030 static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
862 return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs * (uint##w##_t)rhs), bits); \1031 return zig_i##w##_bitCast_u##w(zig_mulw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
1032 } \
1033\
1034 static inline uint##w##_t zig_abs_i##w(int##w##_t arg) { \
1035 int##w##_t tmp = zig_shr_i##w(arg, UINT8_C(w) - UINT8_C(1)); \
1036 return zig_u##w##_bitCast_i##w(zig_subw_i##w(zig_xor_i##w(arg, tmp), tmp, UINT8_C(w)), UINT8_C(w)); \
1037 } \
1038\
1039 static inline uint##w##_t zig_min_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
1040 return lhs < rhs ? lhs : rhs; \
1041 } \
1042\
1043 static inline int##w##_t zig_min_i##w(int##w##_t lhs, int##w##_t rhs) { \
1044 return lhs < rhs ? lhs : rhs; \
1045 } \
1046\
1047 static inline uint##w##_t zig_max_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
1048 return lhs >= rhs ? lhs : rhs; \
1049 } \
1050\
1051 static inline int##w##_t zig_max_i##w(int##w##_t lhs, int##w##_t rhs) { \
1052 return lhs >= rhs ? lhs : rhs; \
863 }1053 }
864#if UINT8_MAX <= UINT_MAX1054zig_int_operators(8)
865zig_int_helpers(8, unsigned int)1055zig_int_operators(16)
866#elif UINT8_MAX <= ULONG_MAX1056zig_int_operators(32)
867zig_int_helpers(8, unsigned long)1057zig_int_operators(64)
868#elif UINT8_MAX <= ULLONG_MAX1058#ifdef zig_ez80
869zig_int_helpers(8, unsigned long long)1059zig_int_operators(24)
870#else1060zig_int_operators(48)
871zig_int_helpers(8, uint8_t)1061#endif
872#endif1062
873#if UINT16_MAX <= UINT_MAX1063#define zig_int_casts(bw, sw) \
874zig_int_helpers(16, unsigned int)1064 static inline uint##sw##_t zig_u##sw##_intCast_u##bw(uint##bw##_t arg) { \
875#elif UINT16_MAX <= ULONG_MAX1065 return (uint##sw##_t)arg; \
876zig_int_helpers(16, unsigned long)1066 } \
877#elif UINT16_MAX <= ULLONG_MAX1067\
878zig_int_helpers(16, unsigned long long)1068 static inline uint##sw##_t zig_u##sw##_intCast_i##bw(int##bw##_t arg) { \
879#else1069 return (uint##sw##_t)arg; \
880zig_int_helpers(16, uint16_t)1070 } \
881#endif1071\
882#if defined(zig_ez80)1072 static inline int##sw##_t zig_i##sw##_intCast_u##bw(uint##bw##_t arg) { \
883#if UINT24_MAX <= UINT_MAX1073 return (int##sw##_t)arg; \
884zig_int_helpers(24, unsigned int)1074 } \
885#elif UINT24_MAX <= ULONG_MAX1075\
886zig_int_helpers(24, unsigned long)1076 static inline int##sw##_t zig_i##sw##_intCast_i##bw(int##bw##_t arg) { \
887#elif UINT24_MAX <= ULLONG_MAX1077 return (int##sw##_t)arg; \
888zig_int_helpers(24, unsigned long long)1078 } \
889#else1079\
890zig_int_helpers(24, uint24_t)1080 zig_int_casts_common(bw, sw)
891#endif1081zig_int_casts(16, 8)
892#endif1082zig_int_casts(32, 8)
893#if UINT32_MAX <= UINT_MAX1083zig_int_casts(64, 8)
894zig_int_helpers(32, unsigned int)1084zig_int_casts(32, 16)
895#elif UINT32_MAX <= ULONG_MAX1085zig_int_casts(64, 16)
896zig_int_helpers(32, unsigned long)1086zig_int_casts(64, 32)
897#elif UINT32_MAX <= ULLONG_MAX1087#ifdef zig_ez80
898zig_int_helpers(32, unsigned long long)1088zig_int_casts(32, 24)
899#else1089zig_int_casts(48, 24)
900zig_int_helpers(32, uint32_t)1090zig_int_casts(64, 24)
901#endif1091zig_int_casts(64, 48)
902#if defined(zig_ez80)
903#if UINT24_MAX <= UINT_MAX
904zig_int_helpers(48, unsigned int)
905#elif UINT24_MAX <= ULONG_MAX
906zig_int_helpers(48, unsigned long)
907#elif UINT24_MAX <= ULLONG_MAX
908zig_int_helpers(48, unsigned long long)
909#else
910zig_int_helpers(48, uint48_t)
911#endif
912#endif
913#if UINT64_MAX <= UINT_MAX
914zig_int_helpers(64, unsigned int)
915#elif UINT64_MAX <= ULONG_MAX
916zig_int_helpers(64, unsigned long)
917#elif UINT64_MAX <= ULLONG_MAX
918zig_int_helpers(64, unsigned long long)
919#else
920zig_int_helpers(64, uint64_t)
921#endif1092#endif
9221093
923static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {1094static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
924#if zig_has_builtin(add_overflow) || defined(zig_gcc)1095#if zig_has_builtin(add_overflow) || defined(zig_gcc)
925 uint32_t full_res;1096 uint32_t full_res;
926 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1097 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
927 *res = zig_wrap_u32(full_res, bits);1098 *res = zig_u32_truncate_u32(full_res, bits);
928 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);1099 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
929#else1100#else
930 *res = zig_addw_u32(lhs, rhs, bits);1101 *res = zig_addw_u32(lhs, rhs, bits);
...@@ -936,19 +1107,19 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t...@@ -936,19 +1107,19 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
936#if zig_has_builtin(add_overflow) || defined(zig_gcc)1107#if zig_has_builtin(add_overflow) || defined(zig_gcc)
937 int32_t full_res;1108 int32_t full_res;
938 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1109 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1110 *res = zig_i32_truncate_i32(full_res, bits);
1111 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
939#else1112#else
940 int32_t full_res = (int32_t)((uint32_t)lhs + (uint32_t)rhs);1113 *res = zig_addw_i32(lhs, rhs, bits);
941 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;1114 return ((*res ^ lhs) & (*res ^ rhs)) < INT32_C(0);
942#endif1115#endif
943 *res = zig_wrap_i32(full_res, bits);
944 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
945}1116}
9461117
947static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {1118static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
948#if zig_has_builtin(add_overflow) || defined(zig_gcc)1119#if zig_has_builtin(add_overflow) || defined(zig_gcc)
949 uint64_t full_res;1120 uint64_t full_res;
950 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1121 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
951 *res = zig_wrap_u64(full_res, bits);1122 *res = zig_u64_truncate_u64(full_res, bits);
952 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);1123 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
953#else1124#else
954 *res = zig_addw_u64(lhs, rhs, bits);1125 *res = zig_addw_u64(lhs, rhs, bits);
...@@ -960,24 +1131,24 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t...@@ -960,24 +1131,24 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
960#if zig_has_builtin(add_overflow) || defined(zig_gcc)1131#if zig_has_builtin(add_overflow) || defined(zig_gcc)
961 int64_t full_res;1132 int64_t full_res;
962 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1133 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1134 *res = zig_i64_truncate_i64(full_res, bits);
1135 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
963#else1136#else
964 int64_t full_res = (int64_t)((uint64_t)lhs + (uint64_t)rhs);1137 *res = zig_addw_i64(lhs, rhs, bits);
965 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;1138 return ((*res ^ lhs) & (*res ^ rhs)) < INT64_C(0);
966#endif1139#endif
967 *res = zig_wrap_i64(full_res, bits);
968 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
969}1140}
9701141
971static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {1142static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
972#if zig_has_builtin(add_overflow) || defined(zig_gcc)1143#if zig_has_builtin(add_overflow) || defined(zig_gcc)
973 uint8_t full_res;1144 uint8_t full_res;
974 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1145 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
975 *res = zig_wrap_u8(full_res, bits);1146 *res = zig_u8_truncate_u8(full_res, bits);
976 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);1147 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
977#else1148#else
978 uint32_t full_res;1149 uint32_t full_res;
979 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);1150 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
980 *res = (uint8_t)full_res;1151 *res = zig_u8_intCast_u32(full_res);
981 return overflow;1152 return overflow;
982#endif1153#endif
983}1154}
...@@ -986,12 +1157,12 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits...@@ -986,12 +1157,12 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
986#if zig_has_builtin(add_overflow) || defined(zig_gcc)1157#if zig_has_builtin(add_overflow) || defined(zig_gcc)
987 int8_t full_res;1158 int8_t full_res;
988 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1159 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
989 *res = zig_wrap_i8(full_res, bits);1160 *res = zig_i8_truncate_i8(full_res, bits);
990 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);1161 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
991#else1162#else
992 int32_t full_res;1163 int32_t full_res;
993 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);1164 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
994 *res = (int8_t)full_res;1165 *res = zig_i8_intCast_i32(full_res);
995 return overflow;1166 return overflow;
996#endif1167#endif
997}1168}
...@@ -1000,12 +1171,12 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8...@@ -1000,12 +1171,12 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
1000#if zig_has_builtin(add_overflow) || defined(zig_gcc)1171#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1001 uint16_t full_res;1172 uint16_t full_res;
1002 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1173 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1003 *res = zig_wrap_u16(full_res, bits);1174 *res = zig_u16_truncate_u16(full_res, bits);
1004 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);1175 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
1005#else1176#else
1006 uint32_t full_res;1177 uint32_t full_res;
1007 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);1178 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
1008 *res = (uint16_t)full_res;1179 *res = zig_u16_intCast_u32(full_res);
1009 return overflow;1180 return overflow;
1010#endif1181#endif
1011}1182}
...@@ -1014,27 +1185,28 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t...@@ -1014,27 +1185,28 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
1014#if zig_has_builtin(add_overflow) || defined(zig_gcc)1185#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1015 int16_t full_res;1186 int16_t full_res;
1016 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1187 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1017 *res = zig_wrap_i16(full_res, bits);1188 *res = zig_i16_truncate_i16(full_res, bits);
1018 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);1189 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
1019#else1190#else
1020 int32_t full_res;1191 int32_t full_res;
1021 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);1192 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
1022 *res = (int16_t)full_res;1193 *res = zig_i16_intCast_i32(full_res);
1023 return overflow;1194 return overflow;
1024#endif1195#endif
1025}1196}
10261197
1027#if defined(zig_ez80)1198#if defined(zig_ez80)
1199
1028static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {1200static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1029#if zig_has_builtin(add_overflow) || defined(zig_gcc)1201#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1030 uint24_t full_res;1202 uint24_t full_res;
1031 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1203 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1032 *res = zig_wrap_u24(full_res, bits);1204 *res = zig_u24_truncate_u24(full_res, bits);
1033 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);1205 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1034#else1206#else
1035 uint32_t full_res;1207 uint32_t full_res;
1036 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);1208 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
1037 *res = (uint24_t)full_res;1209 *res = zig_u24_intCast_u32(full_res);
1038 return overflow;1210 return overflow;
1039#endif1211#endif
1040}1212}
...@@ -1043,28 +1215,26 @@ static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t...@@ -1043,28 +1215,26 @@ static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t
1043#if zig_has_builtin(add_overflow) || defined(zig_gcc)1215#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1044 int24_t full_res;1216 int24_t full_res;
1045 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1217 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1046 *res = zig_wrap_i24(full_res, bits);1218 *res = zig_i24_truncate_i24(full_res, bits);
1047 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);1219 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1048#else1220#else
1049 int32_t full_res;1221 int32_t full_res;
1050 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);1222 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
1051 *res = (int24_t)full_res;1223 *res = zig_i24_intCast_i32(full_res);
1052 return overflow;1224 return overflow;
1053#endif1225#endif
1054}1226}
1055#endif
10561227
1057#if defined(zig_ez80)
1058static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {1228static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1059#if zig_has_builtin(add_overflow) || defined(zig_gcc)1229#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1060 uint48_t full_res;1230 uint48_t full_res;
1061 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1231 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1062 *res = zig_wrap_u48(full_res, bits);1232 *res = zig_u48_truncate_u48(full_res, bits);
1063 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);1233 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1064#else1234#else
1065 uint64_t full_res;1235 uint64_t full_res;
1066 bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits);1236 bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits);
1067 *res = (uint48_t)full_res;1237 *res = zig_u48_intCast_u64(full_res);
1068 return overflow;1238 return overflow;
1069#endif1239#endif
1070}1240}
...@@ -1073,22 +1243,23 @@ static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1073,22 +1243,23 @@ static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1073#if zig_has_builtin(add_overflow) || defined(zig_gcc)1243#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1074 int48_t full_res;1244 int48_t full_res;
1075 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);1245 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1076 *res = zig_wrap_i48(full_res, bits);1246 *res = zig_i48_truncate_i48(full_res, bits);
1077 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);1247 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1078#else1248#else
1079 int64_t full_res;1249 int64_t full_res;
1080 bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits);1250 bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits);
1081 *res = (int48_t)full_res;1251 *res = zig_i48_intCast_i64(full_res);
1082 return overflow;1252 return overflow;
1083#endif1253#endif
1084}1254}
1255
1085#endif1256#endif
10861257
1087static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {1258static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
1088#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1259#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1089 uint32_t full_res;1260 uint32_t full_res;
1090 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1261 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1091 *res = zig_wrap_u32(full_res, bits);1262 *res = zig_u32_truncate_u32(full_res, bits);
1092 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);1263 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
1093#else1264#else
1094 *res = zig_subw_u32(lhs, rhs, bits);1265 *res = zig_subw_u32(lhs, rhs, bits);
...@@ -1100,20 +1271,19 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t...@@ -1100,20 +1271,19 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
1100#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1271#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1101 int32_t full_res;1272 int32_t full_res;
1102 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1273 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1274 *res = zig_i32_truncate_i32(full_res, bits);
1275 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
1103#else1276#else
1104 int32_t full_res = (int32_t)((uint32_t)lhs - (uint32_t)rhs);1277 *res = zig_subw_i32(lhs, rhs, bits);
1105 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;1278 return ((lhs ^ rhs) & (*res ^ lhs)) < INT32_C(0);
1106#endif1279#endif
1107 *res = zig_wrap_i32(full_res, bits);
1108 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
1109}1280}
11101281
1111
1112static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {1282static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
1113#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1283#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1114 uint64_t full_res;1284 uint64_t full_res;
1115 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1285 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1116 *res = zig_wrap_u64(full_res, bits);1286 *res = zig_u64_truncate_u64(full_res, bits);
1117 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);1287 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
1118#else1288#else
1119 *res = zig_subw_u64(lhs, rhs, bits);1289 *res = zig_subw_u64(lhs, rhs, bits);
...@@ -1125,24 +1295,24 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t...@@ -1125,24 +1295,24 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
1125#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1295#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1126 int64_t full_res;1296 int64_t full_res;
1127 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1297 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1298 *res = zig_i64_truncate_i64(full_res, bits);
1299 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
1128#else1300#else
1129 int64_t full_res = (int64_t)((uint64_t)lhs - (uint64_t)rhs);1301 *res = zig_subw_i64(lhs, rhs, bits);
1130 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;1302 return ((lhs ^ rhs) & (*res ^ lhs)) < INT64_C(0);
1131#endif1303#endif
1132 *res = zig_wrap_i64(full_res, bits);
1133 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
1134}1304}
11351305
1136static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {1306static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
1137#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1307#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1138 uint8_t full_res;1308 uint8_t full_res;
1139 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1309 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1140 *res = zig_wrap_u8(full_res, bits);1310 *res = zig_u8_truncate_u8(full_res, bits);
1141 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);1311 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
1142#else1312#else
1143 uint32_t full_res;1313 uint32_t full_res;
1144 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);1314 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1145 *res = (uint8_t)full_res;1315 *res = zig_u8_intCast_u32(full_res);
1146 return overflow;1316 return overflow;
1147#endif1317#endif
1148}1318}
...@@ -1151,12 +1321,12 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits...@@ -1151,12 +1321,12 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
1151#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1321#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1152 int8_t full_res;1322 int8_t full_res;
1153 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1323 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1154 *res = zig_wrap_i8(full_res, bits);1324 *res = zig_i8_truncate_i8(full_res, bits);
1155 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);1325 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
1156#else1326#else
1157 int32_t full_res;1327 int32_t full_res;
1158 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);1328 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1159 *res = (int8_t)full_res;1329 *res = zig_i8_intCast_i32(full_res);
1160 return overflow;1330 return overflow;
1161#endif1331#endif
1162}1332}
...@@ -1165,12 +1335,12 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8...@@ -1165,12 +1335,12 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
1165#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1335#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1166 uint16_t full_res;1336 uint16_t full_res;
1167 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1337 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1168 *res = zig_wrap_u16(full_res, bits);1338 *res = zig_u16_truncate_u16(full_res, bits);
1169 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);1339 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
1170#else1340#else
1171 uint32_t full_res;1341 uint32_t full_res;
1172 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);1342 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1173 *res = (uint16_t)full_res;1343 *res = zig_u16_intCast_u32(full_res);
1174 return overflow;1344 return overflow;
1175#endif1345#endif
1176}1346}
...@@ -1179,27 +1349,28 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t...@@ -1179,27 +1349,28 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
1179#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1349#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1180 int16_t full_res;1350 int16_t full_res;
1181 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1351 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1182 *res = zig_wrap_i16(full_res, bits);1352 *res = zig_i16_truncate_i16(full_res, bits);
1183 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);1353 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
1184#else1354#else
1185 int32_t full_res;1355 int32_t full_res;
1186 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);1356 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1187 *res = (int16_t)full_res;1357 *res = zig_i16_intCast_i32(full_res);
1188 return overflow;1358 return overflow;
1189#endif1359#endif
1190}1360}
11911361
1192#if defined(zig_ez80)1362#if defined(zig_ez80)
1363
1193static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {1364static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1194#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1365#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1195 uint24_t full_res;1366 uint24_t full_res;
1196 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1367 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1197 *res = zig_wrap_u24(full_res, bits);1368 *res = zig_u24_truncate_u24(full_res, bits);
1198 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);1369 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1199#else1370#else
1200 uint32_t full_res;1371 uint32_t full_res;
1201 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);1372 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1202 *res = (uint24_t)full_res;1373 *res = zig_u24_intCast_u32(full_res);
1203 return overflow;1374 return overflow;
1204#endif1375#endif
1205}1376}
...@@ -1208,28 +1379,26 @@ static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t...@@ -1208,28 +1379,26 @@ static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t
1208#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1379#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1209 int24_t full_res;1380 int24_t full_res;
1210 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1381 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1211 *res = zig_wrap_i24(full_res, bits);1382 *res = zig_i24_truncate_i24(full_res, bits);
1212 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);1383 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1213#else1384#else
1214 int32_t full_res;1385 int32_t full_res;
1215 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);1386 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1216 *res = (int24_t)full_res;1387 *res = zig_i24_intCast_i32(full_res);
1217 return overflow;1388 return overflow;
1218#endif1389#endif
1219}1390}
1220#endif
12211391
1222#if defined(zig_ez80)
1223static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {1392static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1224#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1393#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1225 uint48_t full_res;1394 uint48_t full_res;
1226 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1395 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1227 *res = zig_wrap_u48(full_res, bits);1396 *res = zig_u48_truncate_u48(full_res, bits);
1228 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);1397 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1229#else1398#else
1230 uint64_t full_res;1399 uint64_t full_res;
1231 bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits);1400 bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits);
1232 *res = (uint48_t)full_res;1401 *res = zig_u48_intCast_u64(full_res);
1233 return overflow;1402 return overflow;
1234#endif1403#endif
1235}1404}
...@@ -1238,22 +1407,23 @@ static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1238,22 +1407,23 @@ static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1238#if zig_has_builtin(sub_overflow) || defined(zig_gcc)1407#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1239 int48_t full_res;1408 int48_t full_res;
1240 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);1409 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1241 *res = zig_wrap_i48(full_res, bits);1410 *res = zig_i48_truncate_i48(full_res, bits);
1242 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);1411 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1243#else1412#else
1244 int64_t full_res;1413 int64_t full_res;
1245 bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits);1414 bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits);
1246 *res = (int48_t)full_res;1415 *res = zig_i48_intCast_i64(full_res);
1247 return overflow;1416 return overflow;
1248#endif1417#endif
1249}1418}
1419
1250#endif1420#endif
12511421
1252static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {1422static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
1253#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1423#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1254 uint32_t full_res;1424 uint32_t full_res;
1255 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1425 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1256 *res = zig_wrap_u32(full_res, bits);1426 *res = zig_u32_truncate_u32(full_res, bits);
1257 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);1427 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
1258#else1428#else
1259 *res = zig_mulw_u32(lhs, rhs, bits);1429 *res = zig_mulw_u32(lhs, rhs, bits);
...@@ -1261,8 +1431,8 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8...@@ -1261,8 +1431,8 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8
1261#endif1431#endif
1262}1432}
12631433
1264zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow);
1265static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {1434static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {
1435 zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow);
1266#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1436#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1267 int32_t full_res;1437 int32_t full_res;
1268 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1438 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
...@@ -1271,7 +1441,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t...@@ -1271,7 +1441,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
1271 int32_t full_res = __mulosi4(lhs, rhs, &overflow_int);1441 int32_t full_res = __mulosi4(lhs, rhs, &overflow_int);
1272 bool overflow = overflow_int != 0;1442 bool overflow = overflow_int != 0;
1273#endif1443#endif
1274 *res = zig_wrap_i32(full_res, bits);1444 *res = zig_i32_truncate_i32(full_res, bits);
1275 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);1445 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
1276}1446}
12771447
...@@ -1279,7 +1449,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8...@@ -1279,7 +1449,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8
1279#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1449#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1280 uint64_t full_res;1450 uint64_t full_res;
1281 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1451 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1282 *res = zig_wrap_u64(full_res, bits);1452 *res = zig_u64_truncate_u64(full_res, bits);
1283 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);1453 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
1284#else1454#else
1285 *res = zig_mulw_u64(lhs, rhs, bits);1455 *res = zig_mulw_u64(lhs, rhs, bits);
...@@ -1287,8 +1457,8 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8...@@ -1287,8 +1457,8 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8
1287#endif1457#endif
1288}1458}
12891459
1290zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
1291static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {1460static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {
1461 zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
1292#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1462#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1293 int64_t full_res;1463 int64_t full_res;
1294 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1464 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
...@@ -1297,7 +1467,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t...@@ -1297,7 +1467,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
1297 int64_t full_res = __mulodi4(lhs, rhs, &overflow_int);1467 int64_t full_res = __mulodi4(lhs, rhs, &overflow_int);
1298 bool overflow = overflow_int != 0;1468 bool overflow = overflow_int != 0;
1299#endif1469#endif
1300 *res = zig_wrap_i64(full_res, bits);1470 *res = zig_i64_truncate_i64(full_res, bits);
1301 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);1471 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
1302}1472}
13031473
...@@ -1305,12 +1475,12 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b...@@ -1305,12 +1475,12 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b
1305#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1475#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1306 uint8_t full_res;1476 uint8_t full_res;
1307 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1477 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1308 *res = zig_wrap_u8(full_res, bits);1478 *res = zig_u8_truncate_u8(full_res, bits);
1309 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);1479 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
1310#else1480#else
1311 uint32_t full_res;1481 uint32_t full_res;
1312 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);1482 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1313 *res = (uint8_t)full_res;1483 *res = zig_u8_intCast_u32(full_res);
1314 return overflow;1484 return overflow;
1315#endif1485#endif
1316}1486}
...@@ -1319,12 +1489,12 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits...@@ -1319,12 +1489,12 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
1319#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1489#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1320 int8_t full_res;1490 int8_t full_res;
1321 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1491 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1322 *res = zig_wrap_i8(full_res, bits);1492 *res = zig_i8_truncate_i8(full_res, bits);
1323 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);1493 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
1324#else1494#else
1325 int32_t full_res;1495 int32_t full_res;
1326 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);1496 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1327 *res = (int8_t)full_res;1497 *res = zig_i8_intCast_i32(full_res);
1328 return overflow;1498 return overflow;
1329#endif1499#endif
1330}1500}
...@@ -1333,12 +1503,12 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8...@@ -1333,12 +1503,12 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
1333#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1503#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1334 uint16_t full_res;1504 uint16_t full_res;
1335 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1505 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1336 *res = zig_wrap_u16(full_res, bits);1506 *res = zig_u16_truncate_u16(full_res, bits);
1337 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);1507 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
1338#else1508#else
1339 uint32_t full_res;1509 uint32_t full_res;
1340 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);1510 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1341 *res = (uint16_t)full_res;1511 *res = zig_u16_intCast_u32(full_res);
1342 return overflow;1512 return overflow;
1343#endif1513#endif
1344}1514}
...@@ -1347,27 +1517,28 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t...@@ -1347,27 +1517,28 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
1347#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1517#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1348 int16_t full_res;1518 int16_t full_res;
1349 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1519 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1350 *res = zig_wrap_i16(full_res, bits);1520 *res = zig_i16_truncate_i16(full_res, bits);
1351 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);1521 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
1352#else1522#else
1353 int32_t full_res;1523 int32_t full_res;
1354 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);1524 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1355 *res = (int16_t)full_res;1525 *res = zig_i16_intCast_i32(full_res);
1356 return overflow;1526 return overflow;
1357#endif1527#endif
1358}1528}
13591529
1360#if defined(zig_ez80)1530#if defined(zig_ez80)
1531
1361static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {1532static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1362#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1533#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1363 uint24_t full_res;1534 uint24_t full_res;
1364 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1535 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1365 *res = zig_wrap_u24(full_res, bits);1536 *res = zig_u24_truncate_u24(full_res, bits);
1366 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);1537 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1367#else1538#else
1368 uint32_t full_res;1539 uint32_t full_res;
1369 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);1540 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1370 *res = (uint24_t)full_res;1541 *res = zig_u24_intCast_u32(full_res);
1371 return overflow;1542 return overflow;
1372#endif1543#endif
1373}1544}
...@@ -1376,28 +1547,26 @@ static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t...@@ -1376,28 +1547,26 @@ static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t
1376#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1547#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1377 int24_t full_res;1548 int24_t full_res;
1378 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1549 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1379 *res = zig_wrap_i24(full_res, bits);1550 *res = zig_i24_truncate_i24(full_res, bits);
1380 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);1551 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1381#else1552#else
1382 int32_t full_res;1553 int32_t full_res;
1383 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);1554 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1384 *res = (int24_t)full_res;1555 *res = zig_i24_intCast_i32(full_res);
1385 return overflow;1556 return overflow;
1386#endif1557#endif
1387}1558}
1388#endif
13891559
1390#if defined(zig_ez80)
1391static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {1560static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1392#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1561#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1393 uint48_t full_res;1562 uint48_t full_res;
1394 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1563 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1395 *res = zig_wrap_u48(full_res, bits);1564 *res = zig_u48_truncate_u48(full_res, bits);
1396 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);1565 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1397#else1566#else
1398 uint64_t full_res;1567 uint64_t full_res;
1399 bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits);1568 bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits);
1400 *res = (uint48_t)full_res;1569 *res = zig_u48_intCast_u64(full_res);
1401 return overflow;1570 return overflow;
1402#endif1571#endif
1403}1572}
...@@ -1406,18 +1575,32 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1406,18 +1575,32 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1406#if zig_has_builtin(mul_overflow) || defined(zig_gcc)1575#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1407 int48_t full_res;1576 int48_t full_res;
1408 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1577 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1409 *res = zig_wrap_i48(full_res, bits);1578 *res = zig_i48_truncate_i48(full_res, bits);
1410 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);1579 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1411#else1580#else
1412 int64_t full_res;1581 int64_t full_res;
1413 bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits);1582 bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits);
1414 *res = (int48_t)full_res;1583 *res = zig_i48_intCast_i64(full_res);
1415 return overflow;1584 return overflow;
1416#endif1585#endif
1417}1586}
1587
1418#endif1588#endif
14191589
1420#define zig_int_builtins(w) \1590#define zig_shls_builtins(lw, rw) \
1591 static inline uint##lw##_t zig_shls_u##lw##_u##rw(uint##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \
1592 uint##lw##_t res; \
1593 if (rhs < bits && !zig_shlo_u##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
1594 return lhs == INT##lw##_C(0) ? zig_minInt_u(lw, bits) : zig_maxInt_u(lw, bits); \
1595 } \
1596\
1597 static inline int##lw##_t zig_shls_i##lw##_u##rw(int##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \
1598 int##lw##_t res; \
1599 if (rhs < bits && !zig_shlo_i##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
1600 return lhs == INT##lw##_C(0) ? INT##lw##_C(0) : \
1601 lhs < INT##lw##_C(0) ? zig_minInt_i(lw, bits) : zig_maxInt_i(lw, bits); \
1602 }
1603#define zig_int_sat_builtins(w) \
1421 static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \1604 static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
1422 *res = zig_shlw_u##w(lhs, rhs, bits); \1605 *res = zig_shlw_u##w(lhs, rhs, bits); \
1423 return lhs > zig_maxInt_u(w, bits) >> rhs; \1606 return lhs > zig_maxInt_u(w, bits) >> rhs; \
...@@ -1429,18 +1612,10 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1429,18 +1612,10 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1429 return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \1612 return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \
1430 } \1613 } \
1431\1614\
1432 static inline uint##w##_t zig_shls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1615 zig_shls_builtins(w, 8) \
1433 uint##w##_t res; \1616 zig_shls_builtins(w, 16) \
1434 if (rhs < bits && !zig_shlo_u##w(&res, lhs, rhs, bits)) return res; \1617 zig_shls_builtins(w, 32) \
1435 return lhs == INT##w##_C(0) ? INT##w##_C(0) : zig_maxInt_u(w, bits); \1618 zig_shls_builtins(w, 64) \
1436 } \
1437\
1438 static inline int##w##_t zig_shls_i##w(int##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1439 int##w##_t res; \
1440 if (rhs < bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \
1441 return lhs == INT##w##_C(0) ? INT##w##_C(0) : \
1442 lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1443 } \
1444\1619\
1445 static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \1620 static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1446 uint##w##_t res; \1621 uint##w##_t res; \
...@@ -1474,332 +1649,321 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t...@@ -1474,332 +1649,321 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
1474 if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \1649 if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \
1475 return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \1650 return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1476 }1651 }
1477zig_int_builtins(8)1652zig_int_sat_builtins(8)
1478zig_int_builtins(16)1653zig_int_sat_builtins(16)
1479#if defined(zig_ez80)1654zig_int_sat_builtins(32)
1480zig_int_builtins(24)1655zig_int_sat_builtins(64)
1481#endif
1482zig_int_builtins(32)
1483#if defined(zig_ez80)1656#if defined(zig_ez80)
1484zig_int_builtins(48)1657zig_int_sat_builtins(24)
1658zig_int_sat_builtins(48)
1485#endif1659#endif
1486zig_int_builtins(64)
14871660
1488#define zig_builtin8(name, val) __builtin_##name(val)1661#define zig_builtin8(name, arg) __builtin_##name(arg)
1489typedef unsigned int zig_Builtin8;1662typedef unsigned int zig_Builtin8;
14901663
1491#define zig_builtin16(name, val) __builtin_##name(val)1664#define zig_builtin16(name, arg) __builtin_##name(arg)
1492typedef unsigned int zig_Builtin16;1665typedef unsigned int zig_Builtin16;
14931666
1494#if defined(zig_ez80)
1495#define zig_builtin24(name, val) __builtin_##name(val)
1496typedef unsigned int zig_Builtin24;
1497#endif
1498
1499#if INT_MIN <= INT32_MIN1667#if INT_MIN <= INT32_MIN
1500#define zig_builtin32(name, val) __builtin_##name(val)1668#define zig_builtin32(name, arg) __builtin_##name(arg)
1501typedef unsigned int zig_Builtin32;1669typedef unsigned int zig_Builtin32;
1502#elif LONG_MIN <= INT32_MIN1670#elif LONG_MIN <= INT32_MIN
1503#define zig_builtin32(name, val) __builtin_##name##l(val)1671#define zig_builtin32(name, arg) __builtin_##name##l(arg)
1504typedef unsigned long zig_Builtin32;1672typedef unsigned long zig_Builtin32;
1505#endif1673#endif
15061674
1507#if defined(zig_ez80)
1508#define zig_builtin48(name, val) __builtin_##name(val)
1509typedef unsigned long long zig_Builtin48;
1510#endif
1511
1512#if INT_MIN <= INT64_MIN1675#if INT_MIN <= INT64_MIN
1513#define zig_builtin64(name, val) __builtin_##name(val)1676#define zig_builtin64(name, arg) __builtin_##name(arg)
1514typedef unsigned int zig_Builtin64;1677typedef unsigned int zig_Builtin64;
1515#elif LONG_MIN <= INT64_MIN1678#elif LONG_MIN <= INT64_MIN
1516#define zig_builtin64(name, val) __builtin_##name##l(val)1679#define zig_builtin64(name, arg) __builtin_##name##l(arg)
1517typedef unsigned long zig_Builtin64;1680typedef unsigned long zig_Builtin64;
1518#elif LLONG_MIN <= INT64_MIN1681#elif LLONG_MIN <= INT64_MIN
1519#define zig_builtin64(name, val) __builtin_##name##ll(val)1682#define zig_builtin64(name, arg) __builtin_##name##ll(arg)
1520typedef unsigned long long zig_Builtin64;1683typedef unsigned long long zig_Builtin64;
1521#endif1684#endif
15221685
1523static inline uint8_t zig_byte_swap_u8(uint8_t val, uint8_t bits) {1686#if defined(zig_ez80)
1524 return zig_wrap_u8(val >> (8 - bits), bits);1687#define zig_builtin24(name, arg) __builtin_##name(arg)
1688typedef unsigned int zig_Builtin24;
1689#define zig_builtin48(name, arg) __builtin_##name(arg)
1690typedef unsigned long long zig_Builtin48;
1691#endif
1692
1693static inline uint8_t zig_byteSwap_u8(uint8_t arg, uint8_t bits) {
1694 return zig_u8_truncate_u8(arg >> (8 - bits), bits);
1525}1695}
15261696
1527static inline int8_t zig_byte_swap_i8(int8_t val, uint8_t bits) {1697static inline int8_t zig_byteSwap_i8(int8_t arg, uint8_t bits) {
1528 return zig_wrap_i8((int8_t)zig_byte_swap_u8((uint8_t)val, bits), bits);1698 return zig_i8_truncate_i8((int8_t)zig_byteSwap_u8((uint8_t)arg, bits), bits);
1529}1699}
15301700
1531static inline uint16_t zig_byte_swap_u16(uint16_t val, uint8_t bits) {1701static inline uint16_t zig_byteSwap_u16(uint16_t arg, uint8_t bits) {
1532 uint16_t full_res;1702 uint16_t full_res;
1533#if zig_has_builtin(bswap16) || defined(zig_gcc)1703#if zig_has_builtin(bswap16) || defined(zig_gcc)
1534 full_res = __builtin_bswap16(val);1704 full_res = __builtin_bswap16(arg);
1535#else1705#else
1536 full_res = (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 8 |1706 full_res = (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 8 |
1537 (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 8), 8) >> 0;1707 (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 8), 8) >> 0;
1538#endif1708#endif
1539 return zig_wrap_u16(full_res >> (16 - bits), bits);1709 return zig_u16_truncate_u16(full_res >> (16 - bits), bits);
1540}1710}
15411711
1542static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) {1712static inline int16_t zig_byteSwap_i16(int16_t arg, uint8_t bits) {
1543 return zig_wrap_i16((int16_t)zig_byte_swap_u16((uint16_t)val, bits), bits);1713 return zig_i16_truncate_i16((int16_t)zig_byteSwap_u16((uint16_t)arg, bits), bits);
1544}1714}
15451715
1546#if defined(zig_ez80)1716#if defined(zig_ez80)
1547static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) {1717static inline uint16_t zig_byteSwap_u24(uint24_t arg, uint8_t bits) {
1548 uint24_t full_res;1718 uint24_t full_res;
1549#if zig_has_builtin(bswap24) || defined(zig_gcc)1719#if zig_has_builtin(bswap24) || defined(zig_gcc)
1550 full_res = __builtin_bswap24(val);1720 full_res = __builtin_bswap24(arg);
1551#else1721#else
1552 full_res = (uint24_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 16 |1722 full_res = (uint24_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 16 |
1553 (uint24_t)zig_byte_swap_u16((uint16_t)(val >> 8), 16) >> 0;1723 (uint24_t)zig_byteSwap_u16((uint16_t)(arg >> 8), 16) >> 0;
1554#endif1724#endif
1555 return zig_wrap_u24(full_res >> (24 - bits), bits);1725 return zig_u24_truncate_u24(full_res >> (24 - bits), bits);
1556}1726}
15571727
1558static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) {1728static inline int16_t zig_byteSwap_i24(int24_t arg, uint8_t bits) {
1559 return zig_wrap_i24((int24_t)zig_byte_swap_u24((uint24_t)val, bits), bits);1729 return zig_i24_truncate_i24((int24_t)zig_byteSwap_u24((uint24_t)arg, bits), bits);
1560}1730}
1561#endif1731#endif
15621732
1563static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) {1733static inline uint32_t zig_byteSwap_u32(uint32_t arg, uint8_t bits) {
1564 uint32_t full_res;1734 uint32_t full_res;
1565#if zig_has_builtin(bswap32) || defined(zig_gcc)1735#if zig_has_builtin(bswap32) || defined(zig_gcc)
1566 full_res = __builtin_bswap32(val);1736 full_res = __builtin_bswap32(arg);
1567#else1737#else
1568 full_res = (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 0), 16) << 16 |1738 full_res = (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 0), 16) << 16 |
1569 (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 16), 16) >> 0;1739 (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 16), 16) >> 0;
1570#endif1740#endif
1571 return zig_wrap_u32(full_res >> (32 - bits), bits);1741 return zig_u32_truncate_u32(full_res >> (32 - bits), bits);
1572}1742}
15731743
1574static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) {1744static inline int32_t zig_byteSwap_i32(int32_t arg, uint8_t bits) {
1575 return zig_wrap_i32((int32_t)zig_byte_swap_u32((uint32_t)val, bits), bits);1745 return zig_i32_truncate_i32((int32_t)zig_byteSwap_u32((uint32_t)arg, bits), bits);
1576}1746}
15771747
1578#if defined(zig_ez80)1748#if defined(zig_ez80)
1579static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) {1749static inline uint32_t zig_byteSwap_u48(uint48_t arg, uint8_t bits) {
1580 uint48_t full_res;1750 uint48_t full_res;
1581#if zig_has_builtin(bswap48) || defined(zig_gcc)1751#if zig_has_builtin(bswap48) || defined(zig_gcc)
1582 full_res = __builtin_bswap48(val);1752 full_res = __builtin_bswap48(arg);
1583#else1753#else
1584 full_res = (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 0), 24) << 24 |1754 full_res = (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 0), 24) << 24 |
1585 (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 24), 24) >> 0;1755 (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 24), 24) >> 0;
1586#endif1756#endif
1587 return zig_wrap_u48(full_res >> (48 - bits), bits);1757 return zig_u48_truncate_u48(full_res >> (48 - bits), bits);
1588}1758}
15891759
1590static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) {1760static inline int32_t zig_byteSwap_i48(int48_t arg, uint8_t bits) {
1591 return zig_wrap_i48((int48_t)zig_byte_swap_u48((uint48_t)val, bits), bits);1761 return zig_i48_truncate_i48((int48_t)zig_byteSwap_u48((uint48_t)arg, bits), bits);
1592}1762}
1593#endif1763#endif
15941764
1595static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) {1765static inline uint64_t zig_byteSwap_u64(uint64_t arg, uint8_t bits) {
1596 uint64_t full_res;1766 uint64_t full_res;
1597#if zig_has_builtin(bswap64) || defined(zig_gcc)1767#if zig_has_builtin(bswap64) || defined(zig_gcc)
1598 full_res = __builtin_bswap64(val);1768 full_res = __builtin_bswap64(arg);
1599#else1769#else
1600 full_res = (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 0), 32) << 32 |1770 full_res = (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 0), 32) << 32 |
1601 (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 32), 32) >> 0;1771 (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 32), 32) >> 0;
1602#endif1772#endif
1603 return zig_wrap_u64(full_res >> (64 - bits), bits);1773 return zig_u64_truncate_u64(full_res >> (64 - bits), bits);
1604}1774}
16051775
1606static inline int64_t zig_byte_swap_i64(int64_t val, uint8_t bits) {1776static inline int64_t zig_byteSwap_i64(int64_t arg, uint8_t bits) {
1607 return zig_wrap_i64((int64_t)zig_byte_swap_u64((uint64_t)val, bits), bits);1777 return zig_i64_truncate_i64((int64_t)zig_byteSwap_u64((uint64_t)arg, bits), bits);
1608}1778}
16091779
1610static inline uint8_t zig_bit_reverse_u8(uint8_t val, uint8_t bits) {1780static inline uint8_t zig_bitReverse_u8(uint8_t arg, uint8_t bits) {
1611 uint8_t full_res;1781 uint8_t full_res;
1612#if zig_has_builtin(bitreverse8)1782#if zig_has_builtin(bitreverse8)
1613 full_res = __builtin_bitreverse8(val);1783 full_res = __builtin_bitreverse8(arg);
1614#else1784#else
1615 static uint8_t const lut[0x10] = {1785 static uint8_t const lut[0x10] = {
1616 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,1786 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
1617 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf1787 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
1618 };1788 };
1619 full_res = lut[val >> 0 & 0xF] << 4 | lut[val >> 4 & 0xF] << 0;1789 full_res = lut[arg >> 0 & 0xF] << 4 | lut[arg >> 4 & 0xF] << 0;
1620#endif1790#endif
1621 return zig_wrap_u8(full_res >> (8 - bits), bits);1791 return zig_u8_truncate_u8(full_res >> (8 - bits), bits);
1622}1792}
16231793
1624static inline int8_t zig_bit_reverse_i8(int8_t val, uint8_t bits) {1794static inline int8_t zig_bitReverse_i8(int8_t arg, uint8_t bits) {
1625 return zig_wrap_i8((int8_t)zig_bit_reverse_u8((uint8_t)val, bits), bits);1795 return zig_i8_truncate_i8((int8_t)zig_bitReverse_u8((uint8_t)arg, bits), bits);
1626}1796}
16271797
1628static inline uint16_t zig_bit_reverse_u16(uint16_t val, uint8_t bits) {1798static inline uint16_t zig_bitReverse_u16(uint16_t arg, uint8_t bits) {
1629 uint16_t full_res;1799 uint16_t full_res;
1630#if zig_has_builtin(bitreverse16)1800#if zig_has_builtin(bitreverse16)
1631 full_res = __builtin_bitreverse16(val);1801 full_res = __builtin_bitreverse16(arg);
1632#else1802#else
1633 full_res = (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 8 |1803 full_res = (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 8 |
1634 (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 8), 8) >> 0;1804 (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 8), 8) >> 0;
1635#endif1805#endif
1636 return zig_wrap_u16(full_res >> (16 - bits), bits);1806 return zig_u16_truncate_u16(full_res >> (16 - bits), bits);
1637}1807}
16381808
1639static inline int16_t zig_bit_reverse_i16(int16_t val, uint8_t bits) {1809static inline int16_t zig_bitReverse_i16(int16_t arg, uint8_t bits) {
1640 return zig_wrap_i16((int16_t)zig_bit_reverse_u16((uint16_t)val, bits), bits);1810 return zig_i16_truncate_i16((int16_t)zig_bitReverse_u16((uint16_t)arg, bits), bits);
1641}1811}
16421812
1643#if defined(zig_ez80)1813#if defined(zig_ez80)
1644static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) {1814static inline uint24_t zig_bitReverse_u24(uint24_t arg, uint8_t bits) {
1645 uint24_t full_res;1815 uint24_t full_res;
1646#if zig_has_builtin(bitreverse24)1816#if zig_has_builtin(bitreverse24)
1647 full_res = __builtin_bitreverse24(val);1817 full_res = __builtin_bitreverse24(arg);
1648#else1818#else
1649 full_res = (uint24_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 16 |1819 full_res = (uint24_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 16 |
1650 (uint24_t)zig_bit_reverse_u16((uint16_t)(val >> 8), 16) >> 0;1820 (uint24_t)zig_bitReverse_u16((uint16_t)(arg >> 8), 16) >> 0;
1651#endif1821#endif
1652 return zig_wrap_u24(full_res >> (24 - bits), bits);1822 return zig_u24_truncate_u24(full_res >> (24 - bits), bits);
1653}1823}
16541824
1655static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) {1825static inline int24_t zig_bitReverse_i24(int24_t arg, uint8_t bits) {
1656 return zig_wrap_i24((int24_t)zig_bit_reverse_u24((uint24_t)val, bits), bits);1826 return zig_i24_truncate_i24((int24_t)zig_bitReverse_u24((uint24_t)arg, bits), bits);
1657}1827}
1658#endif1828#endif
16591829
1660static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) {1830static inline uint32_t zig_bitReverse_u32(uint32_t arg, uint8_t bits) {
1661 uint32_t full_res;1831 uint32_t full_res;
1662#if zig_has_builtin(bitreverse32)1832#if zig_has_builtin(bitreverse32)
1663 full_res = __builtin_bitreverse32(val);1833 full_res = __builtin_bitreverse32(arg);
1664#else1834#else
1665 full_res = (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 0), 16) << 16 |1835 full_res = (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 0), 16) << 16 |
1666 (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 16), 16) >> 0;1836 (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 16), 16) >> 0;
1667#endif1837#endif
1668 return zig_wrap_u32(full_res >> (32 - bits), bits);1838 return zig_u32_truncate_u32(full_res >> (32 - bits), bits);
1669}1839}
16701840
1671static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) {1841static inline int32_t zig_bitReverse_i32(int32_t arg, uint8_t bits) {
1672 return zig_wrap_i32((int32_t)zig_bit_reverse_u32((uint32_t)val, bits), bits);1842 return zig_i32_truncate_i32((int32_t)zig_bitReverse_u32((uint32_t)arg, bits), bits);
1673}1843}
16741844
1675#if defined(zig_ez80)1845#if defined(zig_ez80)
1676static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) {1846static inline uint32_t zig_bitReverse_u48(uint48_t arg, uint8_t bits) {
1677 uint48_t full_res;1847 uint48_t full_res;
1678#if zig_has_builtin(bitreverse48)1848#if zig_has_builtin(bitreverse48)
1679 full_res = __builtin_bitreverse48(val);1849 full_res = __builtin_bitreverse48(arg);
1680#else1850#else
1681 full_res = (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 0), 24) << 24 |1851 full_res = (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 0), 24) << 24 |
1682 (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 24), 24) >> 0;1852 (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 24), 24) >> 0;
1683#endif1853#endif
1684 return zig_wrap_u32(full_res >> (48 - bits), bits);1854 return zig_u48_truncate_u48(full_res >> (48 - bits), bits);
1685}1855}
16861856
1687static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) {1857static inline int32_t zig_bitReverse_i48(int48_t arg, uint8_t bits) {
1688 return zig_wrap_i48((int48_t)zig_bit_reverse_u48((uint48_t)val, bits), bits);1858 return zig_i48_truncate_i48((int48_t)zig_bitReverse_u48((uint48_t)arg, bits), bits);
1689}1859}
1690#endif1860#endif
16911861
1692static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) {1862static inline uint64_t zig_bitReverse_u64(uint64_t arg, uint8_t bits) {
1693 uint64_t full_res;1863 uint64_t full_res;
1694#if zig_has_builtin(bitreverse64)1864#if zig_has_builtin(bitreverse64)
1695 full_res = __builtin_bitreverse64(val);1865 full_res = __builtin_bitreverse64(arg);
1696#else1866#else
1697 full_res = (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 0), 32) << 32 |1867 full_res = (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 0), 32) << 32 |
1698 (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 32), 32) >> 0;1868 (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 32), 32) >> 0;
1699#endif1869#endif
1700 return zig_wrap_u64(full_res >> (64 - bits), bits);1870 return zig_u64_truncate_u64(full_res >> (64 - bits), bits);
1701}1871}
17021872
1703static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) {1873static inline int64_t zig_bitReverse_i64(int64_t arg, uint8_t bits) {
1704 return zig_wrap_i64((int64_t)zig_bit_reverse_u64((uint64_t)val, bits), bits);1874 return zig_i64_truncate_i64((int64_t)zig_bitReverse_u64((uint64_t)arg, bits), bits);
1705}1875}
17061876
1707#define zig_builtin_popcount_common(w) \1877#define zig_builtin_popCount_common(w) \
1708 static inline uint8_t zig_popcount_i##w(int##w##_t val, uint8_t bits) { \1878 static inline uint8_t zig_popCount_i##w(int##w##_t arg, uint8_t bits) { \
1709 return zig_popcount_u##w((uint##w##_t)val, bits); \1879 return zig_popCount_u##w((uint##w##_t)arg, bits); \
1710 }1880 }
1711#if zig_has_builtin(popcount) || defined(zig_gcc) || defined(zig_tinyc)1881#if zig_has_builtin(popCount) || defined(zig_gcc) || defined(zig_tinyc)
1712#define zig_builtin_popcount(w) \1882#define zig_builtin_popCount(w) \
1713 static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \1883 static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \
1714 (void)bits; \1884 (void)bits; \
1715 return zig_builtin##w(popcount, val); \1885 return zig_builtin##w(popcount, arg); \
1716 } \1886 } \
1717\1887\
1718 zig_builtin_popcount_common(w)1888 zig_builtin_popCount_common(w)
1719#else1889#else
1720#define zig_builtin_popcount(w) \1890#define zig_builtin_popCount(w) \
1721 static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \1891 static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \
1722 (void)bits; \1892 (void)bits; \
1723 uint##w##_t temp = val - ((val >> 1) & (UINT##w##_MAX / 3)); \1893 uint##w##_t temp = arg - ((arg >> 1) & (UINT##w##_MAX / 3)); \
1724 temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \1894 temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \
1725 temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \1895 temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \
1726 return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \1896 return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \
1727 } \1897 } \
1728\1898\
1729 zig_builtin_popcount_common(w)1899 zig_builtin_popCount_common(w)
1730#endif
1731zig_builtin_popcount(8)
1732zig_builtin_popcount(16)
1733#if defined(zig_ez80)
1734zig_builtin_popcount(24)
1735#endif1900#endif
1736zig_builtin_popcount(32)1901zig_builtin_popCount(8)
1902zig_builtin_popCount(16)
1903zig_builtin_popCount(32)
1904zig_builtin_popCount(64)
1737#if defined(zig_ez80)1905#if defined(zig_ez80)
1738zig_builtin_popcount(48)1906zig_builtin_popCount(24)
1907zig_builtin_popCount(48)
1739#endif1908#endif
1740zig_builtin_popcount(64)
17411909
1742#define zig_builtin_ctz_common(w) \1910#define zig_builtin_ctz_common(w) \
1743 static inline uint8_t zig_ctz_i##w(int##w##_t val, uint8_t bits) { \1911 static inline uint8_t zig_ctz_i##w(int##w##_t arg, uint8_t bits) { \
1744 return zig_ctz_u##w((uint##w##_t)val, bits); \1912 return zig_ctz_u##w((uint##w##_t)arg, bits); \
1745 }1913 }
1746#if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc)1914#if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc)
1747#define zig_builtin_ctz(w) \1915#define zig_builtin_ctz(w) \
1748 static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \1916 static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \
1749 if (val == 0) return bits; \1917 if (arg == 0) return bits; \
1750 return zig_builtin##w(ctz, val); \1918 return zig_builtin##w(ctz, arg); \
1751 } \1919 } \
1752\1920\
1753 zig_builtin_ctz_common(w)1921 zig_builtin_ctz_common(w)
1754#else1922#else
1755#define zig_builtin_ctz(w) \1923#define zig_builtin_ctz(w) \
1756 static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \1924 static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \
1757 return zig_popcount_u##w(zig_not_u##w(val, bits) & zig_subw_u##w(val, 1, bits), bits); \1925 return zig_popCount_u##w(zig_not_u##w(arg, bits) & zig_subw_u##w(arg, 1, bits), bits); \
1758 } \1926 } \
1759\1927\
1760 zig_builtin_ctz_common(w)1928 zig_builtin_ctz_common(w)
1761#endif1929#endif
1762zig_builtin_ctz(8)1930zig_builtin_ctz(8)
1763zig_builtin_ctz(16)1931zig_builtin_ctz(16)
1764#if defined(zig_ez80)
1765zig_builtin_ctz(24)
1766#endif
1767zig_builtin_ctz(32)1932zig_builtin_ctz(32)
1933zig_builtin_ctz(64)
1768#if defined(zig_ez80)1934#if defined(zig_ez80)
1935zig_builtin_ctz(24)
1769zig_builtin_ctz(48)1936zig_builtin_ctz(48)
1770#endif1937#endif
1771zig_builtin_ctz(64)
17721938
1773#define zig_builtin_clz_common(w) \1939#define zig_builtin_clz_common(w) \
1774 static inline uint8_t zig_clz_i##w(int##w##_t val, uint8_t bits) { \1940 static inline uint8_t zig_clz_i##w(int##w##_t arg, uint8_t bits) { \
1775 return zig_clz_u##w((uint##w##_t)val, bits); \1941 return zig_clz_u##w((uint##w##_t)arg, bits); \
1776 }1942 }
1777#if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc)1943#if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc)
1778#define zig_builtin_clz(w) \1944#define zig_builtin_clz(w) \
1779 static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \1945 static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \
1780 if (val == 0) return bits; \1946 if (arg == 0) return bits; \
1781 return zig_builtin##w(clz, val) - (zig_bitSizeOf(zig_Builtin##w) - bits); \1947 return zig_builtin##w(clz, arg) - (zig_bitSizeOf(zig_Builtin##w) - bits); \
1782 } \1948 } \
1783\1949\
1784 zig_builtin_clz_common(w)1950 zig_builtin_clz_common(w)
1785#else1951#else
1786#define zig_builtin_clz(w) \1952#define zig_builtin_clz(w) \
1787 static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \1953 static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \
1788 return zig_ctz_u##w(zig_bit_reverse_u##w(val, bits), bits); \1954 return zig_ctz_u##w(zig_bitReverse_u##w(arg, bits), bits); \
1789 } \1955 } \
1790\1956\
1791 zig_builtin_clz_common(w)1957 zig_builtin_clz_common(w)
1792#endif1958#endif
1793zig_builtin_clz(8)1959zig_builtin_clz(8)
1794zig_builtin_clz(16)1960zig_builtin_clz(16)
1795#if defined(zig_ez80)
1796zig_builtin_clz(24)
1797#endif
1798zig_builtin_clz(32)1961zig_builtin_clz(32)
1962zig_builtin_clz(64)
1799#if defined(zig_ez80)1963#if defined(zig_ez80)
1964zig_builtin_clz(24)
1800zig_builtin_clz(48)1965zig_builtin_clz(48)
1801#endif1966#endif
1802zig_builtin_clz(64)
18031967
1804/* ======================== 128-bit Integer Support ========================= */1968/* ======================== 128-bit Integer Support ========================= */
18051969
...@@ -1816,16 +1980,14 @@ zig_builtin_clz(64)...@@ -1816,16 +1980,14 @@ zig_builtin_clz(64)
1816typedef unsigned __int128 zig_u128;1980typedef unsigned __int128 zig_u128;
1817typedef signed __int128 zig_i128;1981typedef signed __int128 zig_i128;
18181982
1819#define zig_make_u128(hi, lo) ((zig_u128)(hi)<<64|(lo))1983#define zig_init_u128(hi, lo) ((zig_u128)(hi)<<64|(lo))
1820#define zig_make_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo))1984#define zig_init_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo))
1821#define zig_init_u128(hi, lo) zig_make_u128(hi, lo)1985#define zig_make_u128(hi, lo) zig_init_u128(hi, lo)
1822#define zig_init_i128(hi, lo) zig_make_i128(hi, lo)1986#define zig_make_i128(hi, lo) zig_init_i128(hi, lo)
1823#define zig_hi_u128(val) ((uint64_t)((val) >> 64))1987#define zig_hi_u128(arg) ((uint64_t)((arg) >> 64))
1824#define zig_lo_u128(val) ((uint64_t)((val) >> 0))1988#define zig_lo_u128(arg) ((uint64_t)((arg) >> 0))
1825#define zig_hi_i128(val) (( int64_t)((val) >> 64))1989#define zig_hi_i128(arg) (( int64_t)((arg) >> 64))
1826#define zig_lo_i128(val) ((uint64_t)((val) >> 0))1990#define zig_lo_i128(arg) ((uint64_t)((arg) >> 0))
1827#define zig_bitCast_u128(val) ((zig_u128)(val))
1828#define zig_bitCast_i128(val) ((zig_i128)(val))
1829#define zig_cmp_int128(Type) \1991#define zig_cmp_int128(Type) \
1830 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \1992 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
1831 return (lhs > rhs) - (lhs < rhs); \1993 return (lhs > rhs) - (lhs < rhs); \
...@@ -1835,32 +1997,49 @@ typedef signed __int128 zig_i128;...@@ -1835,32 +1997,49 @@ typedef signed __int128 zig_i128;
1835 return lhs operator rhs; \1997 return lhs operator rhs; \
1836 }1998 }
18371999
1838#else /* zig_has_int128 */2000static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
2001 return lhs << rhs;
2002}
18392003
1840#if zig_little_endian2004static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
1841typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128;2005 return lhs >> rhs;
1842typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128;2006}
2007
2008static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
2009 return lhs << rhs;
2010}
2011
2012static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
2013 // This works around a GCC miscompilation, but it has the side benefit of
2014 // emitting better code. It is behind the `#if` because it depends on
2015 // arithmetic right shift, which is implementation-defined in C, but should
2016 // be guaranteed on any GCC-compatible compiler.
2017#if defined(zig_gnuc)
2018 return lhs >> rhs;
1843#else2019#else
1844typedef struct { zig_align(16) uint64_t hi; uint64_t lo; } zig_u128;2020 zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);
1845typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;2021 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;
1846#endif2022#endif
2023}
18472024
1848#define zig_make_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) })2025#else /* zig_has_int128 */
1849#define zig_make_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) })
18502026
1851#if defined(zig_msvc) /* MSVC doesn't allow struct literals in constant expressions */2027#if zig_little_endian
1852#define zig_init_u128(hi, lo) { .h##i = (hi), .l##o = (lo) }2028typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; uint64_t hi; } zig_u128;
1853#define zig_init_i128(hi, lo) { .h##i = (hi), .l##o = (lo) }2029typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; int64_t hi; } zig_i128;
1854#else /* But non-MSVC doesn't like the unprotected commas */2030#else
1855#define zig_init_u128(hi, lo) zig_make_u128(hi, lo)2031typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t hi; uint64_t lo; } zig_u128;
1856#define zig_init_i128(hi, lo) zig_make_i128(hi, lo)2032typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) int64_t hi; uint64_t lo; } zig_i128;
1857#endif2033#endif
1858#define zig_hi_u128(val) ((val).hi)2034
1859#define zig_lo_u128(val) ((val).lo)2035#define zig_init_u128(hi, lo) { .h##i = hi, .l##o = lo }
1860#define zig_hi_i128(val) ((val).hi)2036#define zig_init_i128(hi, lo) { .h##i = hi, .l##o = lo }
1861#define zig_lo_i128(val) ((val).lo)2037#define zig_make_u128(hi, lo) (zig_u128)zig_init_u128(hi, lo)
1862#define zig_bitCast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo)2038#define zig_make_i128(hi, lo) (zig_i128)zig_init_i128(hi, lo)
1863#define zig_bitCast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo)2039#define zig_hi_u128(arg) (arg).hi
2040#define zig_lo_u128(arg) (arg).lo
2041#define zig_hi_i128(arg) (arg).hi
2042#define zig_lo_i128(arg) (arg).lo
1864#define zig_cmp_int128(Type) \2043#define zig_cmp_int128(Type) \
1865 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \2044 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
1866 return (lhs.hi == rhs.hi) \2045 return (lhs.hi == rhs.hi) \
...@@ -1872,6 +2051,30 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;...@@ -1872,6 +2051,30 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
1872 return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \2051 return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \
1873 }2052 }
18742053
2054static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
2055 if (rhs == UINT8_C(0)) return lhs;
2056 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
2057 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2058}
2059
2060static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
2061 if (rhs == UINT8_C(0)) return lhs;
2062 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) };
2063 return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs };
2064}
2065
2066static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
2067 if (rhs == UINT8_C(0)) return lhs;
2068 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
2069 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2070}
2071
2072static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
2073 if (rhs == UINT8_C(0)) return lhs;
2074 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) };
2075 return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) };
2076}
2077
1875#endif /* zig_has_int128 */2078#endif /* zig_has_int128 */
18762079
1877#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)2080#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)
...@@ -1891,42 +2094,177 @@ zig_bit_int128(i128, or, |)...@@ -1891,42 +2094,177 @@ zig_bit_int128(i128, or, |)
1891zig_bit_int128(u128, xor, ^)2094zig_bit_int128(u128, xor, ^)
1892zig_bit_int128(i128, xor, ^)2095zig_bit_int128(i128, xor, ^)
18932096
1894static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs);2097static inline uint8_t zig_u8_intCast_u128(zig_u128 arg) {
2098 return (uint8_t)zig_lo_u128(arg);
2099}
2100static inline uint8_t zig_u8_intCast_i128(zig_i128 arg) {
2101 return (uint8_t)zig_lo_i128(arg);
2102}
2103static inline int8_t zig_i8_intCast_i128(zig_i128 arg) {
2104 return (int8_t)zig_lo_i128(arg);
2105}
2106static inline int8_t zig_i8_intCast_u128(zig_u128 arg) {
2107 return (int8_t)zig_lo_u128(arg);
2108}
18952109
1896#if zig_has_int1282110static inline uint16_t zig_u16_intCast_u128(zig_u128 arg) {
2111 return (uint16_t)zig_lo_u128(arg);
2112}
2113static inline uint16_t zig_u16_intCast_i128(zig_i128 arg) {
2114 return (uint16_t)zig_lo_i128(arg);
2115}
2116static inline int16_t zig_i16_intCast_i128(zig_i128 arg) {
2117 return (int16_t)zig_lo_i128(arg);
2118}
2119static inline int16_t zig_i16_intCast_u128(zig_u128 arg) {
2120 return (int16_t)zig_lo_u128(arg);
2121}
18972122
1898static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) {2123static inline uint32_t zig_u32_intCast_u128(zig_u128 arg) {
1899 return val ^ zig_maxInt_u(128, bits);2124 return (uint32_t)zig_lo_u128(arg);
2125}
2126static inline uint32_t zig_u32_intCast_i128(zig_i128 arg) {
2127 return (uint32_t)zig_lo_i128(arg);
2128}
2129static inline int32_t zig_i32_intCast_i128(zig_i128 arg) {
2130 return (int32_t)zig_lo_i128(arg);
2131}
2132static inline int32_t zig_i32_intCast_u128(zig_u128 arg) {
2133 return (int32_t)zig_lo_u128(arg);
1900}2134}
19012135
1902static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) {2136static inline uint64_t zig_u64_intCast_u128(zig_u128 arg) {
1903 (void)bits;2137 return zig_lo_u128(arg);
1904 return ~val;2138}
2139static inline uint64_t zig_u64_intCast_i128(zig_i128 arg) {
2140 return zig_lo_i128(arg);
2141}
2142static inline int64_t zig_i64_intCast_i128(zig_i128 arg) {
2143 return (int64_t)zig_lo_i128(arg);
2144}
2145static inline int64_t zig_i64_intCast_u128(zig_u128 arg) {
2146 return (int64_t)zig_lo_u128(arg);
1905}2147}
19062148
1907static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {2149static inline zig_u128 zig_u128_intCast_u8(uint8_t arg) {
1908 return lhs >> rhs;2150 return zig_make_u128(UINT8_C(0), arg);
2151}
2152static inline zig_u128 zig_u128_intCast_i8(int8_t arg) {
2153 return zig_make_u128(UINT8_C(0), (uint8_t)arg);
2154}
2155static inline zig_i128 zig_i128_intCast_i8(int8_t arg) {
2156 return zig_make_i128(zig_shr_i64(arg, 63), (uint8_t)arg);
2157}
2158static inline zig_i128 zig_i128_intCast_u8(uint8_t arg) {
2159 return zig_make_i128(INT8_C(0), arg);
1909}2160}
19102161
1911static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {2162static inline zig_u128 zig_u128_intCast_u16(uint16_t arg) {
1912 return lhs << rhs;2163 return zig_make_u128(UINT16_C(0), arg);
2164}
2165static inline zig_u128 zig_u128_intCast_i16(int16_t arg) {
2166 return zig_make_u128(UINT16_C(0), (uint16_t)arg);
2167}
2168static inline zig_i128 zig_i128_intCast_i16(int16_t arg) {
2169 return zig_make_i128(zig_shr_i64(arg, 63), (uint16_t)arg);
2170}
2171static inline zig_i128 zig_i128_intCast_u16(uint16_t arg) {
2172 return zig_make_i128(INT16_C(0), arg);
1913}2173}
19142174
1915static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {2175static inline zig_u128 zig_u128_intCast_u32(uint32_t arg) {
1916 // This works around a GCC miscompilation, but it has the side benefit of2176 return zig_make_u128(UINT32_C(0), arg);
1917 // emitting better code. It is behind the `#if` because it depends on2177}
1918 // arithmetic right shift, which is implementation-defined in C, but should2178static inline zig_u128 zig_u128_intCast_i32(int32_t arg) {
1919 // be guaranteed on any GCC-compatible compiler.2179 return zig_make_u128(UINT32_C(0), (uint32_t)arg);
1920#if defined(zig_gnuc)2180}
1921 return lhs >> rhs;2181static inline zig_i128 zig_i128_intCast_i32(int32_t arg) {
2182 return zig_make_i128(zig_shr_i64(arg, 63), (uint32_t)arg);
2183}
2184static inline zig_i128 zig_i128_intCast_u32(uint32_t arg) {
2185 return zig_make_i128(INT32_C(0), arg);
2186}
2187
2188static inline zig_u128 zig_u128_intCast_u64(uint64_t arg) {
2189 return zig_make_u128(UINT64_C(0), arg);
2190}
2191static inline zig_u128 zig_u128_intCast_i64(int64_t arg) {
2192 return zig_make_u128(UINT64_C(0), (uint64_t)arg);
2193}
2194static inline zig_i128 zig_i128_intCast_i64(int64_t arg) {
2195 return zig_make_i128(zig_shr_i64(arg, 63), (uint64_t)arg);
2196}
2197static inline zig_i128 zig_i128_intCast_u64(uint64_t arg) {
2198 return zig_make_i128(INT64_C(0), arg);
2199}
2200
2201static inline zig_u128 zig_u128_intCast_u128(zig_u128 arg) {
2202 return arg;
2203}
2204static inline zig_u128 zig_u128_intCast_i128(zig_i128 arg) {
2205#if zig_has_int128
2206 return (zig_u128)arg;
1922#else2207#else
1923 zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);2208 return zig_make_u128(zig_u64_bitCast_i64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg));
1924 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;2209#endif
2210}
2211static inline zig_i128 zig_i128_intCast_i128(zig_i128 arg) {
2212 return arg;
2213}
2214static inline zig_i128 zig_i128_intCast_u128(zig_u128 arg) {
2215#if zig_has_int128
2216 return (zig_i128)arg;
2217#else
2218 return zig_make_i128(zig_i64_bitCast_u64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg));
1925#endif2219#endif
1926}2220}
19272221
1928static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {2222#define zig_int128_cast_builtins(w) \
1929 return lhs << rhs;2223 static inline uint##w##_t zig_u##w##_truncate_u128(zig_u128 arg, uint8_t bits) { \
2224 return zig_u##w##_truncate_u##w((uint##w##_t)zig_lo_u128(arg), bits); \
2225 } \
2226\
2227 static inline int##w##_t zig_i##w##_truncate_i128(zig_i128 arg, uint8_t bits) { \
2228 return zig_i##w##_truncate_i##w((int##w##_t)zig_lo_i128(arg), bits); \
2229 }
2230zig_int128_cast_builtins(8)
2231zig_int128_cast_builtins(16)
2232zig_int128_cast_builtins(32)
2233zig_int128_cast_builtins(64)
2234
2235static inline zig_u128 zig_u128_truncate_u128(zig_u128 arg, uint8_t bits) {
2236 return zig_and_u128(arg, zig_maxInt_u(128, bits));
2237}
2238static inline zig_i128 zig_i128_truncate_i128(zig_i128 arg, uint8_t bits) {
2239 if (bits > UINT8_C(64)) return zig_make_i128(zig_i64_truncate_i64(zig_hi_i128(arg), bits - UINT8_C(64)), zig_lo_i128(arg));
2240 int64_t lo = zig_i64_truncate_i128(arg, bits);
2241 return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo);
2242}
2243
2244static inline zig_u128 zig_u128_bitCast_u128(zig_u128 arg, uint8_t bits) {
2245 (void)bits;
2246 return arg;
2247}
2248static inline zig_u128 zig_u128_bitCast_i128(zig_i128 arg, uint8_t bits) {
2249 return zig_u128_truncate_u128(zig_u128_intCast_i128(arg), bits);
2250}
2251static inline zig_i128 zig_i128_bitCast_i128(zig_i128 arg, uint8_t bits) {
2252 (void)bits;
2253 return arg;
2254}
2255static inline zig_i128 zig_i128_bitCast_u128(zig_u128 arg, uint8_t bits) {
2256 return zig_i128_truncate_i128(zig_i128_intCast_u128(arg), bits);
2257}
2258
2259#if zig_has_int128
2260
2261static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) {
2262 return arg ^ zig_maxInt_u(128, bits);
2263}
2264
2265static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) {
2266 (void)bits;
2267 return ~arg;
1930}2268}
19312269
1932static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {2270static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
...@@ -1953,11 +2291,11 @@ static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -1953,11 +2291,11 @@ static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
1953 return lhs * rhs;2291 return lhs * rhs;
1954}2292}
19552293
1956static inline zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {2294static inline zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) {
1957 return lhs / rhs;2295 return lhs / rhs;
1958}2296}
19592297
1960static inline zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {2298static inline zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) {
1961 return lhs / rhs;2299 return lhs / rhs;
1962}2300}
19632301
...@@ -1971,36 +2309,14 @@ static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -1971,36 +2309,14 @@ static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
19712309
1972#else /* zig_has_int128 */2310#else /* zig_has_int128 */
19732311
1974static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) {2312static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) {
1975 return (zig_u128){ .hi = zig_not_u64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) };2313 if (bits <= UINT8_C(64)) return (zig_u128){ .hi = UINT64_C(0), .lo = zig_not_u64(arg.lo, bits) };
1976}2314 return (zig_u128){ .hi = zig_not_u64(arg.hi, bits - UINT8_C(64)), .lo = zig_not_u64(arg.lo, UINT8_C(64)) };
1977
1978static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) {
1979 return (zig_i128){ .hi = zig_not_i64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) };
1980}
1981
1982static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
1983 if (rhs == UINT8_C(0)) return lhs;
1984 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) };
1985 return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs };
1986}
1987
1988static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
1989 if (rhs == UINT8_C(0)) return lhs;
1990 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
1991 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
1992}
1993
1994static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
1995 if (rhs == UINT8_C(0)) return lhs;
1996 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) };
1997 return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) };
1998}2315}
19992316
2000static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {2317static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) {
2001 if (rhs == UINT8_C(0)) return lhs;2318 (void)bits;
2002 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };2319 return (zig_i128){ .hi = ~arg.hi, .lo = ~arg.lo };
2003 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2004}2320}
20052321
2006static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {2322static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
...@@ -2027,59 +2343,59 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -2027,59 +2343,59 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
2027 return res;2343 return res;
2028}2344}
20292345
2030zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
2031static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {2346static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
2347 zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
2032 return __multi3(lhs, rhs);2348 return __multi3(lhs, rhs);
2033}2349}
20342350
2035static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {2351static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
2036 return zig_bitCast_u128(zig_mul_i128(zig_bitCast_i128(lhs), zig_bitCast_i128(rhs)));2352 return zig_u128_bitCast_i128(zig_mul_i128(zig_i128_bitCast_u128(lhs, UINT8_C(128)), zig_i128_bitCast_u128(rhs, UINT8_C(128))), UINT8_C(128));
2037}2353}
20382354
2039zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);2355static zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) {
2040static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {2356 zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);
2041 return __udivti3(lhs, rhs);2357 return __udivti3(lhs, rhs);
2042}2358}
20432359
2044zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);2360static zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) {
2045static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {2361 zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);
2046 return __divti3(lhs, rhs);2362 return __divti3(lhs, rhs);
2047}2363}
20482364
2049zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
2050static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {2365static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {
2366 zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
2051 return __umodti3(lhs, rhs);2367 return __umodti3(lhs, rhs);
2052}2368}
20532369
2054zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs);
2055static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {2370static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
2371 zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs);
2056 return __modti3(lhs, rhs);2372 return __modti3(lhs, rhs);
2057}2373}
20582374
2059#endif /* zig_has_int128 */2375#endif /* zig_has_int128 */
20602376
2061#define zig_div_floor_u128 zig_div_trunc_u1282377#define zig_divFloor_u128 zig_divTrunc_u128
20622378
2063static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) {2379static inline zig_i128 zig_divFloor_i128(zig_i128 lhs, zig_i128 rhs) {
2064 zig_i128 rem = zig_rem_i128(lhs, rhs);2380 zig_i128 rem = zig_rem_i128(lhs, rhs);
2065 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)2381 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)
2066 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0);2382 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0);
2067 return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask));2383 return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask));
2068}2384}
20692385
2070static inline zig_u128 zig_div_ceil_u128(zig_u128 lhs, zig_u128 rhs) {2386static inline zig_u128 zig_divCeil_u128(zig_u128 lhs, zig_u128 rhs) {
2071 zig_u128 rem = zig_rem_u128(lhs, rhs);2387 zig_u128 rem = zig_rem_u128(lhs, rhs);
2072 uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0)2388 uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0)
2073 ? UINT64_C(1) : UINT64_C(0);2389 ? UINT64_C(1) : UINT64_C(0);
2074 return zig_add_u128(zig_div_trunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask));2390 return zig_add_u128(zig_divTrunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask));
2075}2391}
20762392
2077static inline zig_i128 zig_div_ceil_i128(zig_i128 lhs, zig_i128 rhs) {2393static inline zig_i128 zig_divCeil_i128(zig_i128 lhs, zig_i128 rhs) {
2078 zig_i128 rem = zig_rem_i128(lhs, rhs);2394 zig_i128 rem = zig_rem_i128(lhs, rhs);
2079 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)2395 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)
2080 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1)2396 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1)
2081 : INT64_C(0);2397 : INT64_C(0);
2082 return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask));2398 return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask));
2083}2399}
20842400
2085#define zig_mod_u128 zig_rem_u1282401#define zig_mod_u128 zig_rem_u128
...@@ -2107,51 +2423,41 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -2107,51 +2423,41 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) {
2107 return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs;2423 return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs;
2108}2424}
21092425
2110static inline zig_u128 zig_wrap_u128(zig_u128 val, uint8_t bits) {
2111 return zig_and_u128(val, zig_maxInt_u(128, bits));
2112}
2113
2114static inline zig_i128 zig_wrap_i128(zig_i128 val, uint8_t bits) {
2115 if (bits > UINT8_C(64)) return zig_make_i128(zig_wrap_i64(zig_hi_i128(val), bits - UINT8_C(64)), zig_lo_i128(val));
2116 int64_t lo = zig_wrap_i64((int64_t)zig_lo_i128(val), bits);
2117 return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo);
2118}
2119
2120static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {2426static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {
2121 return zig_wrap_u128(zig_shl_u128(lhs, rhs), bits);2427 return zig_u128_truncate_u128(zig_shl_u128(lhs, rhs), bits);
2122}2428}
21232429
2124static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) {2430static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) {
2125 return zig_wrap_i128(zig_bitCast_i128(zig_shl_u128(zig_bitCast_u128(lhs), rhs)), bits);2431 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_shl_u128(zig_u128_bitCast_i128(lhs, bits), rhs), bits), bits);
2126}2432}
21272433
2128static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2434static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2129 return zig_wrap_u128(zig_add_u128(lhs, rhs), bits);2435 return zig_u128_truncate_u128(zig_add_u128(lhs, rhs), bits);
2130}2436}
21312437
2132static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2438static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2133 return zig_wrap_i128(zig_bitCast_i128(zig_add_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);2439 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_add_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
2134}2440}
21352441
2136static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2442static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2137 return zig_wrap_u128(zig_sub_u128(lhs, rhs), bits);2443 return zig_u128_truncate_u128(zig_sub_u128(lhs, rhs), bits);
2138}2444}
21392445
2140static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2446static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2141 return zig_wrap_i128(zig_bitCast_i128(zig_sub_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);2447 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_sub_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
2142}2448}
21432449
2144static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2450static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2145 return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits);2451 return zig_u128_truncate_u128(zig_mul_u128(lhs, rhs), bits);
2146}2452}
21472453
2148static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2454static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2149 return zig_wrap_i128(zig_bitCast_i128(zig_mul_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);2455 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_mul_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
2150}2456}
21512457
2152static inline zig_u128 zig_abs_i128(zig_i128 val) {2458static inline zig_u128 zig_abs_i128(zig_i128 arg) {
2153 zig_i128 tmp = zig_shr_i128(val, 127);2459 zig_u128 tmp = zig_u128_bitCast_i128(zig_shr_i128(arg, 127), UINT8_C(128));
2154 return zig_bitCast_u128(zig_sub_i128(zig_xor_i128(val, tmp), tmp));2460 return zig_sub_u128(zig_xor_u128(zig_u128_bitCast_i128(arg, UINT8_C(128)), tmp), tmp);
2155}2461}
21562462
2157#if zig_has_int1282463#if zig_has_int128
...@@ -2160,7 +2466,7 @@ static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint...@@ -2160,7 +2466,7 @@ static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
2160#if zig_has_builtin(add_overflow)2466#if zig_has_builtin(add_overflow)
2161 zig_u128 full_res;2467 zig_u128 full_res;
2162 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);2468 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
2163 *res = zig_wrap_u128(full_res, bits);2469 *res = zig_u128_truncate_u128(full_res, bits);
2164 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);2470 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
2165#else2471#else
2166 *res = zig_addw_u128(lhs, rhs, bits);2472 *res = zig_addw_u128(lhs, rhs, bits);
...@@ -2176,7 +2482,7 @@ static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint...@@ -2176,7 +2482,7 @@ static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
2176 zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs);2482 zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs);
2177 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;2483 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;
2178#endif2484#endif
2179 *res = zig_wrap_i128(full_res, bits);2485 *res = zig_i128_truncate_i128(full_res, bits);
2180 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);2486 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
2181}2487}
21822488
...@@ -2184,7 +2490,7 @@ static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint...@@ -2184,7 +2490,7 @@ static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
2184#if zig_has_builtin(sub_overflow)2490#if zig_has_builtin(sub_overflow)
2185 zig_u128 full_res;2491 zig_u128 full_res;
2186 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);2492 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
2187 *res = zig_wrap_u128(full_res, bits);2493 *res = zig_u128_truncate_u128(full_res, bits);
2188 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);2494 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
2189#else2495#else
2190 *res = zig_subw_u128(lhs, rhs, bits);2496 *res = zig_subw_u128(lhs, rhs, bits);
...@@ -2200,7 +2506,7 @@ static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint...@@ -2200,7 +2506,7 @@ static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
2200 zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs);2506 zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs);
2201 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;2507 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;
2202#endif2508#endif
2203 *res = zig_wrap_i128(full_res, bits);2509 *res = zig_i128_truncate_i128(full_res, bits);
2204 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);2510 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
2205}2511}
22062512
...@@ -2208,7 +2514,7 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint...@@ -2208,7 +2514,7 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
2208#if zig_has_builtin(mul_overflow)2514#if zig_has_builtin(mul_overflow)
2209 zig_u128 full_res;2515 zig_u128 full_res;
2210 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);2516 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
2211 *res = zig_wrap_u128(full_res, bits);2517 *res = zig_u128_truncate_u128(full_res, bits);
2212 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);2518 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
2213#else2519#else
2214 *res = zig_mulw_u128(lhs, rhs, bits);2520 *res = zig_mulw_u128(lhs, rhs, bits);
...@@ -2216,8 +2522,8 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint...@@ -2216,8 +2522,8 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
2216#endif2522#endif
2217}2523}
22182524
2219zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2220static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2525static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2526 zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2221#if zig_has_builtin(mul_overflow)2527#if zig_has_builtin(mul_overflow)
2222 zig_i128 full_res;2528 zig_i128 full_res;
2223 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);2529 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
...@@ -2226,50 +2532,78 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint...@@ -2226,50 +2532,78 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
2226 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);2532 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
2227 bool overflow = overflow_int != 0;2533 bool overflow = overflow_int != 0;
2228#endif2534#endif
2229 *res = zig_wrap_i128(full_res, bits);2535 *res = zig_i128_truncate_i128(full_res, bits);
2230 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);2536 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
2231}2537}
22322538
2233#else /* zig_has_int128 */2539#else /* zig_has_int128 */
22342540
2235static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2541static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2236 uint64_t hi;2542 if (bits <= UINT8_C(64)) {
2237 bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - 64);2543 uint64_t lo;
2238 return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);2544 bool overflow = zig_addo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits);
2545 *res = zig_u128_intCast_u64(lo);
2546 return overflow;
2547 } else {
2548 uint64_t hi;
2549 bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2550 return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2551 }
2239}2552}
22402553
2241static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2554static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2242 int64_t hi;2555 if (bits <= UINT8_C(64)) {
2243 bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - 64);2556 int64_t lo;
2244 return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);2557 bool overflow = zig_addo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits);
2558 *res = zig_i128_intCast_i64(lo);
2559 return overflow;
2560 } else {
2561 int64_t hi;
2562 bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2563 return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2564 }
2245}2565}
22462566
2247static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2567static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2248 uint64_t hi;2568 if (bits <= UINT8_C(64)) {
2249 bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - 64);2569 uint64_t lo;
2250 return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);2570 bool overflow = zig_subo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits);
2571 *res = zig_u128_intCast_u64(lo);
2572 return overflow;
2573 } else {
2574 uint64_t hi;
2575 bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2576 return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2577 }
2251}2578}
22522579
2253static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2580static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2254 int64_t hi;2581 if (bits <= UINT8_C(64)) {
2255 bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - 64);2582 int64_t lo;
2256 return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);2583 bool overflow = zig_subo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits);
2584 *res = zig_i128_intCast_i64(lo);
2585 return overflow;
2586 } else {
2587 int64_t hi;
2588 bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2589 return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2590 }
2257}2591}
22582592
2259static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2593static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2260 *res = zig_mulw_u128(lhs, rhs, bits);2594 *res = zig_mulw_u128(lhs, rhs, bits);
2261 return zig_cmp_u128(*res, zig_make_u128(0, 0)) != INT32_C(0) &&2595 return zig_cmp_u128(rhs, zig_make_u128(0, 0)) != INT32_C(0) &&
2262 zig_cmp_u128(lhs, zig_div_trunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0);2596 zig_cmp_u128(lhs, zig_divTrunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0);
2263}2597}
22642598
2265zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2266static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {2599static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2600 zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2267 int overflow_int;2601 int overflow_int;
2268 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);2602 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
2269 bool overflow = overflow_int != 0 ||2603 bool overflow = overflow_int != 0 ||
2270 zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) ||2604 zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) ||
2271 zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0);2605 zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0);
2272 *res = zig_wrap_i128(full_res, bits);2606 *res = zig_i128_truncate_i128(full_res, bits);
2273 return overflow;2607 return overflow;
2274}2608}
22752609
...@@ -2282,28 +2616,54 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8...@@ -2282,28 +2616,54 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8
22822616
2283static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {2617static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {
2284 *res = zig_shlw_i128(lhs, rhs, bits);2618 *res = zig_shlw_i128(lhs, rhs, bits);
2285 zig_i128 mask = zig_bitCast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)));2619 zig_i128 mask = zig_i128_bitCast_u128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)), bits);
2286 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&2620 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&
2287 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);2621 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);
2288}2622}
22892623
2290static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {2624#define zig_int128_shls_builtins(rw) \
2625 static inline zig_u128 zig_shls_u128_u##rw(zig_u128 lhs, uint##rw##_t rhs, uint8_t bits) { \
2626 zig_u128 res; \
2627 if (rhs < bits && !zig_shlo_u128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
2628 switch (zig_cmp_u128(lhs, zig_make_u128(UINT64_C(0), UINT64_C(0)))) { \
2629 case 0: return zig_minInt_u(128, bits); \
2630 case 1: return zig_maxInt_u(128, bits); \
2631 default: zig_unreachable(); \
2632 } \
2633 } \
2634\
2635 static inline zig_i128 zig_shls_i128_u##rw(zig_i128 lhs, uint##rw##_t rhs, uint8_t bits) { \
2636 zig_i128 res; \
2637 if (rhs < bits && !zig_shlo_i128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
2638 switch (zig_cmp_i128(lhs, zig_make_i128(INT64_C(0), UINT64_C(0)))) { \
2639 case -1: return zig_minInt_i(128, bits); \
2640 case 0: return zig_make_i128(INT64_C(0), UINT64_C(0)); \
2641 case 1: return zig_maxInt_i(128, bits); \
2642 default: zig_unreachable(); \
2643 } \
2644 }
2645zig_int128_shls_builtins(8)
2646zig_int128_shls_builtins(16)
2647zig_int128_shls_builtins(32)
2648zig_int128_shls_builtins(64)
2649
2650static inline zig_u128 zig_shls_u128_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2291 zig_u128 res;2651 zig_u128 res;
2292 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;2652 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
2293 switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) {2653 switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) {
2294 case 0: return zig_make_u128(0, 0);2654 case INT32_C(0): return zig_make_u128(0, 0);
2295 case 1: return zig_maxInt_u(128, bits);2655 case INT32_C(1): return zig_maxInt_u(128, bits);
2296 default: zig_unreachable();2656 default: zig_unreachable();
2297 }2657 }
2298}2658}
22992659
2300static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) {2660static inline zig_i128 zig_shls_i128_u128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) {
2301 zig_i128 res;2661 zig_i128 res;
2302 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;2662 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
2303 switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) {2663 switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) {
2304 case -1: return zig_minInt_i(128, bits);2664 case -INT32_C(1): return zig_minInt_i(128, bits);
2305 case 0: return zig_make_i128(0, 0);2665 case INT32_C(0): return zig_make_i128(0, 0);
2306 case 1: return zig_maxInt_i(128, bits);2666 case INT32_C(1): return zig_maxInt_i(128, bits);
2307 default: zig_unreachable();2667 default: zig_unreachable();
2308 }2668 }
2309}2669}
...@@ -2341,57 +2701,60 @@ static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {...@@ -2341,57 +2701,60 @@ static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2341 return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);2701 return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
2342}2702}
23432703
2344static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) {2704static inline uint8_t zig_clz_u128(zig_u128 arg, uint8_t bits) {
2345 if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(val), bits);2705 if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(arg), bits);
2346 if (zig_hi_u128(val) != 0) return zig_clz_u64(zig_hi_u128(val), bits - UINT8_C(64));2706 if (zig_hi_u128(arg) != 0) return zig_clz_u64(zig_hi_u128(arg), bits - UINT8_C(64));
2347 return zig_clz_u64(zig_lo_u128(val), UINT8_C(64)) + (bits - UINT8_C(64));2707 return zig_clz_u64(zig_lo_u128(arg), UINT8_C(64)) + (bits - UINT8_C(64));
2348}2708}
23492709
2350static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) {2710static inline uint8_t zig_clz_i128(zig_i128 arg, uint8_t bits) {
2351 return zig_clz_u128(zig_bitCast_u128(val), bits);2711 return zig_clz_u128(zig_u128_bitCast_i128(arg, bits), bits);
2352}2712}
23532713
2354static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) {2714static inline uint8_t zig_ctz_u128(zig_u128 arg, uint8_t bits) {
2355 if (zig_lo_u128(val) != 0) return zig_ctz_u64(zig_lo_u128(val), UINT8_C(64));2715 if (zig_lo_u128(arg) != 0) return zig_ctz_u64(zig_lo_u128(arg), UINT8_C(64));
2356 return zig_ctz_u64(zig_hi_u128(val), bits - UINT8_C(64)) + UINT8_C(64);2716 return zig_ctz_u64(zig_hi_u128(arg), bits - UINT8_C(64)) + UINT8_C(64);
2357}2717}
23582718
2359static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) {2719static inline uint8_t zig_ctz_i128(zig_i128 arg, uint8_t bits) {
2360 return zig_ctz_u128(zig_bitCast_u128(val), bits);2720 return zig_ctz_u128(zig_u128_bitCast_i128(arg, bits), bits);
2361}2721}
23622722
2363static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) {2723static inline uint8_t zig_popCount_u128(zig_u128 arg, uint8_t bits) {
2364 return zig_popcount_u64(zig_hi_u128(val), bits - UINT8_C(64)) +2724 return (bits > UINT8_C(64) ? zig_popCount_u64(zig_hi_u128(arg), bits - UINT8_C(64)) : UINT8_C(0)) +
2365 zig_popcount_u64(zig_lo_u128(val), UINT8_C(64));2725 zig_popCount_u64(zig_lo_u128(arg), UINT8_C(64));
2366}2726}
23672727
2368static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) {2728static inline uint8_t zig_popCount_i128(zig_i128 arg, uint8_t bits) {
2369 return zig_popcount_u128(zig_bitCast_u128(val), bits);2729 return zig_popCount_u128(zig_u128_bitCast_i128(arg, bits), bits);
2370}2730}
23712731
2372static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) {2732static inline zig_u128 zig_byteSwap_u128(zig_u128 arg, uint8_t bits) {
2373 zig_u128 full_res;2733 zig_u128 full_res;
2374#if zig_has_builtin(bswap128)2734#if zig_has_builtin(bswap128)
2375 full_res = __builtin_bswap128(val);2735 full_res = __builtin_bswap128(arg);
2376#else2736#else
2377 full_res = zig_make_u128(zig_byte_swap_u64(zig_lo_u128(val), UINT8_C(64)),2737 full_res = zig_make_u128(
2378 zig_byte_swap_u64(zig_hi_u128(val), UINT8_C(64)));2738 zig_byteSwap_u64(zig_lo_u128(arg), UINT8_C(64)),
2739 zig_byteSwap_u64(zig_hi_u128(arg), UINT8_C(64))
2740 );
2379#endif2741#endif
2380 return zig_shr_u128(full_res, UINT8_C(128) - bits);2742 return zig_shr_u128(full_res, UINT8_C(128) - bits);
2381}2743}
23822744
2383static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) {2745static inline zig_i128 zig_byteSwap_i128(zig_i128 arg, uint8_t bits) {
2384 return zig_bitCast_i128(zig_byte_swap_u128(zig_bitCast_u128(val), bits));2746 return zig_i128_bitCast_u128(zig_byteSwap_u128(zig_u128_bitCast_i128(arg, bits), bits), bits);
2385}2747}
23862748
2387static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) {2749static inline zig_u128 zig_bitReverse_u128(zig_u128 arg, uint8_t bits) {
2388 return zig_shr_u128(zig_make_u128(zig_bit_reverse_u64(zig_lo_u128(val), UINT8_C(64)),2750 return zig_shr_u128(zig_make_u128(
2389 zig_bit_reverse_u64(zig_hi_u128(val), UINT8_C(64))),2751 zig_bitReverse_u64(zig_lo_u128(arg), UINT8_C(64)),
2390 UINT8_C(128) - bits);2752 zig_bitReverse_u64(zig_hi_u128(arg), UINT8_C(64))
2753 ), UINT8_C(128) - bits);
2391}2754}
23922755
2393static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {2756static inline zig_i128 zig_bitReverse_i128(zig_i128 arg, uint8_t bits) {
2394 return zig_bitCast_i128(zig_bit_reverse_u128(zig_bitCast_u128(val), bits));2757 return zig_i128_bitCast_u128(zig_bitReverse_u128(zig_u128_bitCast_i128(arg, bits), bits), bits);
2395}2758}
23962759
2397#if zig_has_int1282760#if zig_has_int128
...@@ -2411,15 +2774,218 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {...@@ -2411,15 +2774,218 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {
2411/* ========================== Big Integer Support =========================== */2774/* ========================== Big Integer Support =========================== */
24122775
2413static inline uint16_t zig_int_bytes(uint16_t bits) {2776static inline uint16_t zig_int_bytes(uint16_t bits) {
2414 uint16_t bytes = (bits + CHAR_BIT - 1) / CHAR_BIT;2777 uint16_t bytes = (bits - UINT16_C(1)) / CHAR_BIT + UINT16_C(1);
2415 uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT;2778 uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT;
2779
2416 while (alignment / 2 >= bytes) alignment /= 2;2780 while (alignment / 2 >= bytes) alignment /= 2;
2417 return (bytes + alignment - 1) / alignment * alignment;2781 return (bytes + alignment - 1) / alignment * alignment;
2418}2782}
24192783
2420static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {2784static inline void zig_minInt_big(void *res, bool is_signed, uint16_t bits) {
2785 uint8_t *res_bytes = res;
2786 uint16_t size = zig_int_bytes(bits);
2787 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2788 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2789 uint8_t sign_byte;
2790 uint8_t fill_byte;
2791
2792 if (is_signed) {
2793 int8_t signed_sign_byte = zig_minInt_i(8, remainder_bits);
2794
2795 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2796 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2797 } else {
2798 sign_byte = zig_minInt_u(8, remainder_bits);
2799 fill_byte = UINT8_C(0);
2800 }
2801
2802#if zig_little_endian
2803 memset(&res_bytes[0], zig_minInt_u8, byte_offset);
2804 res_bytes[byte_offset] = sign_byte;
2805 byte_offset += UINT16_C(1);
2806 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2807#else
2808 byte_offset = size - UINT16_C(1) - byte_offset;
2809 memset(&res_bytes[0], fill_byte, byte_offset);
2810 res_bytes[byte_offset] = sign_byte;
2811 byte_offset += UINT16_C(1);
2812 memset(&res_bytes[byte_offset], zig_minInt_u8, size - byte_offset);
2813#endif
2814}
2815
2816static inline void zig_maxInt_big(void *res, bool is_signed, uint16_t bits) {
2817 uint8_t *res_bytes = res;
2818 uint16_t size = zig_int_bytes(bits);
2819 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2820 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2821 uint8_t sign_byte;
2822 uint8_t fill_byte;
2823
2824 if (is_signed) {
2825 int8_t signed_sign_byte = zig_maxInt_i(8, remainder_bits);
2826
2827 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2828 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2829 } else {
2830 sign_byte = zig_maxInt_u(8, remainder_bits);
2831 fill_byte = UINT8_C(0);
2832 }
2833
2834#if zig_little_endian
2835 memset(&res_bytes[0], zig_maxInt_u8, byte_offset);
2836 res_bytes[byte_offset] = sign_byte;
2837 byte_offset += UINT16_C(1);
2838 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2839#else
2840 byte_offset = size - UINT16_C(1) - byte_offset;
2841 memset(&res_bytes[0], fill_byte, byte_offset);
2842 res_bytes[byte_offset] = sign_byte;
2843 byte_offset += UINT16_C(1);
2844 memset(&res_bytes[byte_offset], zig_maxInt_u8, size - byte_offset);
2845#endif
2846}
2847
2848static inline int8_t zig_signFill_big(const void *arg, bool is_signed, uint16_t bits) {
2849 const uint8_t *arg_bytes = arg;
2850 uint16_t byte_offset = 0;
2851
2852 if (!is_signed) return INT8_C(0);
2853#if zig_little_endian
2854 byte_offset = zig_int_bytes(bits) - 1;
2855#endif
2856 return zig_shr_i8(zig_i8_bitCast_u8(arg_bytes[byte_offset], UINT8_C(8)), UINT8_C(7));
2857}
2858
2859static inline void zig_big_intCast_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) {
2860 uint8_t *res_bytes = res;
2861 const uint8_t *arg_bytes = arg;
2862 uint16_t res_size = zig_int_bytes(res_bits);
2863 uint16_t arg_size = zig_int_bytes(arg_bits);
2864 uint16_t copy_size = zig_min_u16(res_size, arg_size);
2865 uint8_t sign_fill = zig_u8_bitCast_i8(zig_signFill_big(arg, arg_is_signed, arg_bits), UINT8_C(8));
2866
2867#if zig_little_endian
2868 memcpy(&res_bytes[0], &arg_bytes[0], copy_size);
2869 memset(&res_bytes[copy_size], sign_fill, res_size - copy_size);
2870#else
2871 memset(&res_bytes[0], sign_fill, res_size - copy_size);
2872 memcpy(&res_bytes[res_size - copy_size], &arg_bytes[arg_size - copy_size], copy_size);
2873#endif
2874}
2875
2876static inline void zig_big_truncate_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) {
2877 uint8_t *res_bytes = res;
2878 const uint8_t *arg_bytes = arg;
2879 uint16_t res_size = zig_int_bytes(res_bits);
2880
2881 if (res_is_signed != arg_is_signed) zig_unreachable();
2882 if (res_bits > arg_bits) zig_unreachable();
2883
2884 if (res_is_signed) {
2885 uint16_t arg_byte_offset = UINT16_C(0);
2886
2887#if zig_big_endian
2888 arg_byte_offset = zig_int_bytes(arg_bits) - res_size;
2889#endif
2890
2891 memcpy(&res_bytes[0], &arg_bytes[arg_byte_offset], res_size);
2892 } else {
2893 uint16_t res_byte_offset = zig_shr_u16(res_bits - UINT16_C(1), UINT8_C(3));
2894 uint16_t arg_byte_offset = res_byte_offset;
2895
2896#if zig_little_endian
2897 memcpy(&res_bytes[0], &arg_bytes[0], res_byte_offset);
2898#else
2899 res_byte_offset = res_size - UINT16_C(1) - res_byte_offset;
2900 arg_byte_offset = zig_int_bytes(arg_bits) - UINT16_C(1) - arg_byte_offset;
2901
2902 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
2903#endif
2904
2905 res_bytes[res_byte_offset] = zig_u8_truncate_u8(
2906 arg_bytes[arg_byte_offset],
2907 zig_u8_truncate_u8(res_bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1)
2908 );
2909 res_byte_offset += UINT16_C(1);
2910 arg_byte_offset += UINT16_C(1);
2911
2912#if zig_little_endian
2913 memset(&res_bytes[res_byte_offset], zig_minInt_u8, res_size - res_byte_offset);
2914#else
2915 memcpy(&res_bytes[res_byte_offset], &arg_bytes[arg_byte_offset], res_size - res_byte_offset);
2916#endif
2917 }
2918}
2919
2920#define zig_big_casts(is, s, w, IntType) \
2921 static inline IntType zig_##s##w##_intCast_big(const void *arg, bool arg_is_signed, uint16_t arg_bits) { \
2922 IntType res; \
2923 zig_big_intCast_big(&res, arg, is, w, arg_is_signed, arg_bits); \
2924 return res; \
2925 } \
2926\
2927 static inline void zig_big_intCast_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \
2928 zig_big_intCast_big(res, &arg, res_is_signed, res_bits, is, w); \
2929 } \
2930\
2931 static inline IntType zig_##s##w##_truncate_big(const void *arg, uint8_t res_bits, bool arg_is_signed, uint16_t arg_bits) { \
2932 IntType res; \
2933 zig_big_truncate_big(&res, arg, is, res_bits, arg_is_signed, arg_bits); \
2934 return res; \
2935 } \
2936\
2937 static inline void zig_big_truncate_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \
2938 zig_big_truncate_big(res, &arg, res_is_signed, res_bits, is, w); \
2939 }
2940zig_big_casts(false, u, 8, uint8_t)
2941zig_big_casts(true , i, 8, int8_t)
2942zig_big_casts(false, u, 16, uint16_t)
2943zig_big_casts(true , i, 16, int16_t)
2944zig_big_casts(false, u, 32, uint32_t)
2945zig_big_casts(true , i, 32, int32_t)
2946zig_big_casts(false, u, 64, uint64_t)
2947zig_big_casts(true , i, 64, int64_t)
2948zig_big_casts(false, u, 128, zig_u128)
2949zig_big_casts(true , i, 128, zig_i128)
2950
2951static inline void zig_big_bitCast_big(void *res, const void *arg, bool res_is_signed, uint16_t bits) {
2952 uint8_t *res_bytes = res;
2953 const uint8_t *arg_bytes = arg;
2954 uint16_t size = zig_int_bytes(bits);
2955 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2956 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2957 uint8_t sign_byte;
2958 uint8_t fill_byte;
2959
2960#if zig_big_endian
2961 byte_offset = size - UINT16_C(1) - byte_offset;
2962#endif
2963
2964 if (res_is_signed) {
2965 int8_t signed_sign_byte = zig_i8_bitCast_u8(arg_bytes[byte_offset], remainder_bits);
2966
2967 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2968 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2969 } else {
2970 sign_byte = zig_u8_bitCast_u8(arg_bytes[byte_offset], remainder_bits);
2971 fill_byte = UINT8_C(0);
2972 }
2973
2974#if zig_little_endian
2975 memcpy(&res_bytes[0], &arg_bytes[0], byte_offset);
2976 res_bytes[byte_offset] = sign_byte;
2977 byte_offset += UINT16_C(1);
2978 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2979#else
2980 memset(&res_bytes[0], fill_byte, byte_offset);
2981 res_bytes[byte_offset] = sign_byte;
2982 byte_offset += UINT16_C(1);
2983 memcpy(&res_bytes[byte_offset], &arg_bytes[byte_offset], size - byte_offset);
2984#endif
2985}
2986
2987static inline int32_t zig_cmp_big_u8(const void *lhs, uint8_t rhs, bool is_signed, uint16_t bits) {
2421 const uint8_t *lhs_bytes = lhs;2988 const uint8_t *lhs_bytes = lhs;
2422 const uint8_t *rhs_bytes = rhs;
2423 uint16_t byte_offset = 0;2989 uint16_t byte_offset = 0;
2424 bool do_signed = is_signed;2990 bool do_signed = is_signed;
2425 uint16_t remaining_bytes = zig_int_bytes(bits);2991 uint16_t remaining_bytes = zig_int_bytes(bits);
...@@ -2429,6 +2995,7 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2429,6 +2995,7 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2429#endif2995#endif
24302996
2431 while (remaining_bytes >= 128 / CHAR_BIT) {2997 while (remaining_bytes >= 128 / CHAR_BIT) {
2998 uint8_t rhs_byte = remaining_bytes == 128 / CHAR_BIT ? rhs : UINT8_C(0);
2432 int32_t limb_cmp;2999 int32_t limb_cmp;
24333000
2434#if zig_little_endian3001#if zig_little_endian
...@@ -2437,18 +3004,16 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2437,18 +3004,16 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
24373004
2438 if (do_signed) {3005 if (do_signed) {
2439 zig_i128 lhs_limb;3006 zig_i128 lhs_limb;
2440 zig_i128 rhs_limb;3007 zig_i128 rhs_limb = zig_i128_intCast_u8(rhs_byte);
24413008
2442 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3009 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2443 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2444 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);3010 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);
2445 do_signed = false;3011 do_signed = false;
2446 } else {3012 } else {
2447 zig_u128 lhs_limb;3013 zig_u128 lhs_limb;
2448 zig_u128 rhs_limb;3014 zig_u128 rhs_limb = zig_u128_intCast_u8(rhs_byte);
24493015
2450 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3016 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2451 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2452 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);3017 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);
2453 }3018 }
24543019
...@@ -2461,24 +3026,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2461,24 +3026,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2461 }3026 }
24623027
2463 while (remaining_bytes >= 64 / CHAR_BIT) {3028 while (remaining_bytes >= 64 / CHAR_BIT) {
3029 uint8_t rhs_byte = remaining_bytes == 64 / CHAR_BIT ? rhs : UINT8_C(0);
3030
2464#if zig_little_endian3031#if zig_little_endian
2465 byte_offset -= 64 / CHAR_BIT;3032 byte_offset -= 64 / CHAR_BIT;
2466#endif3033#endif
24673034
2468 if (do_signed) {3035 if (do_signed) {
2469 int64_t lhs_limb;3036 int64_t lhs_limb;
2470 int64_t rhs_limb;3037 int64_t rhs_limb = zig_i64_intCast_u8(rhs_byte);
24713038
2472 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3039 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2473 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2474 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3040 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2475 do_signed = false;3041 do_signed = false;
2476 } else {3042 } else {
2477 uint64_t lhs_limb;3043 uint64_t lhs_limb;
2478 uint64_t rhs_limb;3044 uint64_t rhs_limb = zig_u64_intCast_u8(rhs_byte);
24793045
2480 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3046 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2481 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2482 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3047 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2483 }3048 }
24843049
...@@ -2490,24 +3055,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2490,24 +3055,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2490 }3055 }
24913056
2492 while (remaining_bytes >= 32 / CHAR_BIT) {3057 while (remaining_bytes >= 32 / CHAR_BIT) {
3058 uint8_t rhs_byte = remaining_bytes == 32 / CHAR_BIT ? rhs : UINT8_C(0);
3059
2493#if zig_little_endian3060#if zig_little_endian
2494 byte_offset -= 32 / CHAR_BIT;3061 byte_offset -= 32 / CHAR_BIT;
2495#endif3062#endif
24963063
2497 if (do_signed) {3064 if (do_signed) {
2498 int32_t lhs_limb;3065 int32_t lhs_limb;
2499 int32_t rhs_limb;3066 int32_t rhs_limb = zig_i32_intCast_u8(rhs_byte);
25003067
2501 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3068 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2502 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2503 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3069 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2504 do_signed = false;3070 do_signed = false;
2505 } else {3071 } else {
2506 uint32_t lhs_limb;3072 uint32_t lhs_limb;
2507 uint32_t rhs_limb;3073 uint32_t rhs_limb = zig_u32_intCast_u8(rhs_byte);
25083074
2509 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3075 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2510 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2511 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3076 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2512 }3077 }
25133078
...@@ -2519,24 +3084,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2519,24 +3084,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2519 }3084 }
25203085
2521 while (remaining_bytes >= 16 / CHAR_BIT) {3086 while (remaining_bytes >= 16 / CHAR_BIT) {
3087 uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0);
3088
2522#if zig_little_endian3089#if zig_little_endian
2523 byte_offset -= 16 / CHAR_BIT;3090 byte_offset -= 16 / CHAR_BIT;
2524#endif3091#endif
25253092
2526 if (do_signed) {3093 if (do_signed) {
2527 int16_t lhs_limb;3094 int16_t lhs_limb;
2528 int16_t rhs_limb;3095 int16_t rhs_limb = zig_i16_intCast_u8(rhs_byte);
25293096
2530 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3097 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2531 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2532 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3098 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2533 do_signed = false;3099 do_signed = false;
2534 } else {3100 } else {
2535 uint16_t lhs_limb;3101 uint16_t lhs_limb;
2536 uint16_t rhs_limb;3102 uint16_t rhs_limb = zig_u16_intCast_u8(rhs_byte);
25373103
2538 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3104 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2539 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2540 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3105 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2541 }3106 }
25423107
...@@ -2548,24 +3113,26 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2548,24 +3113,26 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2548 }3113 }
25493114
2550 while (remaining_bytes >= 8 / CHAR_BIT) {3115 while (remaining_bytes >= 8 / CHAR_BIT) {
3116 uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0);
3117
2551#if zig_little_endian3118#if zig_little_endian
2552 byte_offset -= 8 / CHAR_BIT;3119 byte_offset -= 8 / CHAR_BIT;
2553#endif3120#endif
25543121
2555 if (do_signed) {3122 if (do_signed) {
2556 int8_t lhs_limb;3123 int8_t lhs_limb;
2557 int8_t rhs_limb;3124 int16_t lhs_cmp_limb;
3125 int16_t rhs_cmp_limb = zig_i16_intCast_u8(rhs_byte);
25583126
2559 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3127 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2560 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3128 lhs_cmp_limb = zig_i16_intCast_i8(lhs_limb);
2561 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3129 if (lhs_cmp_limb != rhs_cmp_limb) return (lhs_cmp_limb > rhs_cmp_limb) - (lhs_cmp_limb < rhs_cmp_limb);
2562 do_signed = false;3130 do_signed = false;
2563 } else {3131 } else {
2564 uint8_t lhs_limb;3132 uint8_t lhs_limb;
2565 uint8_t rhs_limb;3133 uint8_t rhs_limb = rhs_byte;
25663134
2567 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3135 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2568 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2569 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);3136 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2570 }3137 }
25713138
...@@ -2579,148 +3146,472 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -2579,148 +3146,472 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
2579 return 0;3146 return 0;
2580}3147}
25813148
2582static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {3149static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2583 uint8_t *res_bytes = res;
2584 const uint8_t *lhs_bytes = lhs;3150 const uint8_t *lhs_bytes = lhs;
2585 const uint8_t *rhs_bytes = rhs;3151 const uint8_t *rhs_bytes = rhs;
2586 uint16_t byte_offset = 0;3152 uint16_t byte_offset = 0;
3153 bool do_signed = is_signed;
2587 uint16_t remaining_bytes = zig_int_bytes(bits);3154 uint16_t remaining_bytes = zig_int_bytes(bits);
2588 (void)is_signed;3155
3156#if zig_little_endian
3157 byte_offset = remaining_bytes;
3158#endif
25893159
2590 while (remaining_bytes >= 128 / CHAR_BIT) {3160 while (remaining_bytes >= 128 / CHAR_BIT) {
2591 zig_u128 res_limb;3161 int32_t limb_cmp;
2592 zig_u128 lhs_limb;
2593 zig_u128 rhs_limb;
25943162
2595 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3163#if zig_little_endian
2596 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3164 byte_offset -= 128 / CHAR_BIT;
2597 res_limb = zig_and_u128(lhs_limb, rhs_limb);3165#endif
2598 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3166
3167 if (do_signed) {
3168 zig_i128 lhs_limb;
3169 zig_i128 rhs_limb;
3170
3171 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3172 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3173 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);
3174 do_signed = false;
3175 } else {
3176 zig_u128 lhs_limb;
3177 zig_u128 rhs_limb;
3178
3179 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3180 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3181 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);
3182 }
25993183
3184 if (limb_cmp != 0) return limb_cmp;
2600 remaining_bytes -= 128 / CHAR_BIT;3185 remaining_bytes -= 128 / CHAR_BIT;
3186
3187#if zig_big_endian
2601 byte_offset += 128 / CHAR_BIT;3188 byte_offset += 128 / CHAR_BIT;
3189#endif
2602 }3190 }
26033191
2604 while (remaining_bytes >= 64 / CHAR_BIT) {3192 while (remaining_bytes >= 64 / CHAR_BIT) {
2605 uint64_t res_limb;3193#if zig_little_endian
2606 uint64_t lhs_limb;3194 byte_offset -= 64 / CHAR_BIT;
2607 uint64_t rhs_limb;3195#endif
26083196
2609 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3197 if (do_signed) {
2610 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3198 int64_t lhs_limb;
2611 res_limb = zig_and_u64(lhs_limb, rhs_limb);3199 int64_t rhs_limb;
2612 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3200
3201 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3202 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3203 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3204 do_signed = false;
3205 } else {
3206 uint64_t lhs_limb;
3207 uint64_t rhs_limb;
3208
3209 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3210 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3211 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3212 }
26133213
2614 remaining_bytes -= 64 / CHAR_BIT;3214 remaining_bytes -= 64 / CHAR_BIT;
3215
3216#if zig_big_endian
2615 byte_offset += 64 / CHAR_BIT;3217 byte_offset += 64 / CHAR_BIT;
3218#endif
2616 }3219 }
26173220
2618 while (remaining_bytes >= 32 / CHAR_BIT) {3221 while (remaining_bytes >= 32 / CHAR_BIT) {
2619 uint32_t res_limb;3222#if zig_little_endian
2620 uint32_t lhs_limb;3223 byte_offset -= 32 / CHAR_BIT;
2621 uint32_t rhs_limb;3224#endif
26223225
2623 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3226 if (do_signed) {
2624 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3227 int32_t lhs_limb;
2625 res_limb = zig_and_u32(lhs_limb, rhs_limb);3228 int32_t rhs_limb;
2626 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3229
3230 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3231 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3232 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3233 do_signed = false;
3234 } else {
3235 uint32_t lhs_limb;
3236 uint32_t rhs_limb;
3237
3238 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3239 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3240 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3241 }
26273242
2628 remaining_bytes -= 32 / CHAR_BIT;3243 remaining_bytes -= 32 / CHAR_BIT;
3244
3245#if zig_big_endian
2629 byte_offset += 32 / CHAR_BIT;3246 byte_offset += 32 / CHAR_BIT;
3247#endif
2630 }3248 }
26313249
2632 while (remaining_bytes >= 16 / CHAR_BIT) {3250 while (remaining_bytes >= 16 / CHAR_BIT) {
2633 uint16_t res_limb;3251#if zig_little_endian
2634 uint16_t lhs_limb;3252 byte_offset -= 16 / CHAR_BIT;
2635 uint16_t rhs_limb;3253#endif
26363254
2637 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3255 if (do_signed) {
2638 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3256 int16_t lhs_limb;
2639 res_limb = zig_and_u16(lhs_limb, rhs_limb);3257 int16_t rhs_limb;
2640 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3258
3259 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3260 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3261 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3262 do_signed = false;
3263 } else {
3264 uint16_t lhs_limb;
3265 uint16_t rhs_limb;
3266
3267 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3268 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3269 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3270 }
26413271
2642 remaining_bytes -= 16 / CHAR_BIT;3272 remaining_bytes -= 16 / CHAR_BIT;
3273
3274#if zig_big_endian
2643 byte_offset += 16 / CHAR_BIT;3275 byte_offset += 16 / CHAR_BIT;
3276#endif
2644 }3277 }
26453278
2646 while (remaining_bytes >= 8 / CHAR_BIT) {3279 while (remaining_bytes >= 8 / CHAR_BIT) {
2647 uint8_t res_limb;3280#if zig_little_endian
2648 uint8_t lhs_limb;3281 byte_offset -= 8 / CHAR_BIT;
2649 uint8_t rhs_limb;3282#endif
26503283
2651 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3284 if (do_signed) {
2652 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3285 int8_t lhs_limb;
2653 res_limb = zig_and_u8(lhs_limb, rhs_limb);3286 int8_t rhs_limb;
2654 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3287
3288 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3289 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3290 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3291 do_signed = false;
3292 } else {
3293 uint8_t lhs_limb;
3294 uint8_t rhs_limb;
3295
3296 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3297 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3298 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3299 }
26553300
2656 remaining_bytes -= 8 / CHAR_BIT;3301 remaining_bytes -= 8 / CHAR_BIT;
3302
3303#if zig_big_endian
2657 byte_offset += 8 / CHAR_BIT;3304 byte_offset += 8 / CHAR_BIT;
3305#endif
2658 }3306 }
3307
3308 return 0;
2659}3309}
26603310
2661static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {3311static inline void zig_not_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
2662 uint8_t *res_bytes = res;3312 uint8_t *res_bytes = res;
2663 const uint8_t *lhs_bytes = lhs;3313 const uint8_t *arg_bytes = arg;
2664 const uint8_t *rhs_bytes = rhs;
2665 uint16_t byte_offset = 0;3314 uint16_t byte_offset = 0;
2666 uint16_t remaining_bytes = zig_int_bytes(bits);3315 uint16_t remaining_bytes = zig_int_bytes(bits);
2667 (void)is_signed;3316 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3317
3318#if zig_big_endian
3319 byte_offset = remaining_bytes;
3320#endif
26683321
2669 while (remaining_bytes >= 128 / CHAR_BIT) {3322 while (remaining_bytes >= 128 / CHAR_BIT) {
2670 zig_u128 res_limb;3323 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
2671 zig_u128 lhs_limb;
2672 zig_u128 rhs_limb;
26733324
2674 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3325#if zig_big_endian
2675 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3326 byte_offset -= 128 / CHAR_BIT;
2676 res_limb = zig_or_u128(lhs_limb, rhs_limb);3327#endif
2677 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3328
3329 if (remaining_bytes != 128 / CHAR_BIT || is_signed) {
3330 zig_i128 res_limb;
3331 zig_i128 arg_limb;
3332
3333 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3334 res_limb = zig_not_i128(arg_limb, limb_bits);
3335 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3336 } else {
3337 zig_u128 res_limb;
3338 zig_u128 arg_limb;
3339
3340 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3341 res_limb = zig_not_u128(arg_limb, limb_bits);
3342 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3343 }
26783344
2679 remaining_bytes -= 128 / CHAR_BIT;3345 remaining_bytes -= 128 / CHAR_BIT;
3346
3347#if zig_little_endian
2680 byte_offset += 128 / CHAR_BIT;3348 byte_offset += 128 / CHAR_BIT;
3349#endif
2681 }3350 }
26823351
2683 while (remaining_bytes >= 64 / CHAR_BIT) {3352 while (remaining_bytes >= 64 / CHAR_BIT) {
2684 uint64_t res_limb;3353 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
2685 uint64_t lhs_limb;
2686 uint64_t rhs_limb;
26873354
2688 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3355#if zig_big_endian
2689 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3356 byte_offset -= 64 / CHAR_BIT;
2690 res_limb = zig_or_u64(lhs_limb, rhs_limb);3357#endif
2691 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3358
3359 if (remaining_bytes != 64 / CHAR_BIT || is_signed) {
3360 int64_t res_limb;
3361 int64_t arg_limb;
3362
3363 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3364 res_limb = zig_not_i64(arg_limb, limb_bits);
3365 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3366 } else {
3367 uint64_t res_limb;
3368 uint64_t arg_limb;
3369
3370 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3371 res_limb = zig_not_u64(arg_limb, limb_bits);
3372 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3373 }
26923374
2693 remaining_bytes -= 64 / CHAR_BIT;3375 remaining_bytes -= 64 / CHAR_BIT;
3376
3377#if zig_little_endian
2694 byte_offset += 64 / CHAR_BIT;3378 byte_offset += 64 / CHAR_BIT;
3379#endif
2695 }3380 }
26963381
2697 while (remaining_bytes >= 32 / CHAR_BIT) {3382 while (remaining_bytes >= 32 / CHAR_BIT) {
2698 uint32_t res_limb;3383 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
2699 uint32_t lhs_limb;
2700 uint32_t rhs_limb;
27013384
2702 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3385#if zig_big_endian
2703 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3386 byte_offset -= 32 / CHAR_BIT;
2704 res_limb = zig_or_u32(lhs_limb, rhs_limb);3387#endif
2705 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));3388
3389 if (remaining_bytes != 32 / CHAR_BIT || is_signed) {
3390 int32_t res_limb;
3391 int32_t arg_limb;
3392
3393 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3394 res_limb = zig_not_i32(arg_limb, limb_bits);
3395 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3396 } else {
3397 uint32_t res_limb;
3398 uint32_t arg_limb;
3399
3400 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3401 res_limb = zig_not_u32(arg_limb, limb_bits);
3402 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3403 }
27063404
2707 remaining_bytes -= 32 / CHAR_BIT;3405 remaining_bytes -= 32 / CHAR_BIT;
3406
3407#if zig_little_endian
2708 byte_offset += 32 / CHAR_BIT;3408 byte_offset += 32 / CHAR_BIT;
3409#endif
2709 }3410 }
27103411
2711 while (remaining_bytes >= 16 / CHAR_BIT) {3412 while (remaining_bytes >= 16 / CHAR_BIT) {
2712 uint16_t res_limb;3413 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
2713 uint16_t lhs_limb;
2714 uint16_t rhs_limb;
27153414
2716 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));3415#if zig_big_endian
2717 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));3416 byte_offset -= 16 / CHAR_BIT;
2718 res_limb = zig_or_u16(lhs_limb, rhs_limb);3417#endif
2719 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
27203418
2721 remaining_bytes -= 16 / CHAR_BIT;3419 if (remaining_bytes != 16 / CHAR_BIT || is_signed) {
2722 byte_offset += 16 / CHAR_BIT;3420 int16_t res_limb;
2723 }3421 int16_t arg_limb;
3422
3423 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3424 res_limb = zig_not_i16(arg_limb, limb_bits);
3425 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3426 } else {
3427 uint16_t res_limb;
3428 uint16_t arg_limb;
3429
3430 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3431 res_limb = zig_not_u16(arg_limb, limb_bits);
3432 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3433 }
3434
3435 remaining_bytes -= 16 / CHAR_BIT;
3436
3437#if zig_little_endian
3438 byte_offset += 16 / CHAR_BIT;
3439#endif
3440 }
3441
3442 while (remaining_bytes >= 8 / CHAR_BIT) {
3443 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3444
3445#if zig_big_endian
3446 byte_offset -= 8 / CHAR_BIT;
3447#endif
3448
3449 if (remaining_bytes != 8 / CHAR_BIT || is_signed) {
3450 int8_t res_limb;
3451 int8_t arg_limb;
3452
3453 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3454 res_limb = zig_not_i8(arg_limb, limb_bits);
3455 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3456 } else {
3457 uint8_t res_limb;
3458 uint8_t arg_limb;
3459
3460 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3461 res_limb = zig_not_u8(arg_limb, limb_bits);
3462 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3463 }
3464
3465 remaining_bytes -= 8 / CHAR_BIT;
3466
3467#if zig_little_endian
3468 byte_offset += 8 / CHAR_BIT;
3469#endif
3470 }
3471}
3472
3473static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3474 uint8_t *res_bytes = res;
3475 const uint8_t *lhs_bytes = lhs;
3476 const uint8_t *rhs_bytes = rhs;
3477 uint16_t byte_offset = 0;
3478 uint16_t remaining_bytes = zig_int_bytes(bits);
3479 (void)is_signed;
3480
3481 while (remaining_bytes >= 128 / CHAR_BIT) {
3482 zig_u128 res_limb;
3483 zig_u128 lhs_limb;
3484 zig_u128 rhs_limb;
3485
3486 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3487 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3488 res_limb = zig_and_u128(lhs_limb, rhs_limb);
3489 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3490
3491 remaining_bytes -= 128 / CHAR_BIT;
3492 byte_offset += 128 / CHAR_BIT;
3493 }
3494
3495 while (remaining_bytes >= 64 / CHAR_BIT) {
3496 uint64_t res_limb;
3497 uint64_t lhs_limb;
3498 uint64_t rhs_limb;
3499
3500 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3501 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3502 res_limb = zig_and_u64(lhs_limb, rhs_limb);
3503 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3504
3505 remaining_bytes -= 64 / CHAR_BIT;
3506 byte_offset += 64 / CHAR_BIT;
3507 }
3508
3509 while (remaining_bytes >= 32 / CHAR_BIT) {
3510 uint32_t res_limb;
3511 uint32_t lhs_limb;
3512 uint32_t rhs_limb;
3513
3514 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3515 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3516 res_limb = zig_and_u32(lhs_limb, rhs_limb);
3517 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3518
3519 remaining_bytes -= 32 / CHAR_BIT;
3520 byte_offset += 32 / CHAR_BIT;
3521 }
3522
3523 while (remaining_bytes >= 16 / CHAR_BIT) {
3524 uint16_t res_limb;
3525 uint16_t lhs_limb;
3526 uint16_t rhs_limb;
3527
3528 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3529 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3530 res_limb = zig_and_u16(lhs_limb, rhs_limb);
3531 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3532
3533 remaining_bytes -= 16 / CHAR_BIT;
3534 byte_offset += 16 / CHAR_BIT;
3535 }
3536
3537 while (remaining_bytes >= 8 / CHAR_BIT) {
3538 uint8_t res_limb;
3539 uint8_t lhs_limb;
3540 uint8_t rhs_limb;
3541
3542 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3543 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3544 res_limb = zig_and_u8(lhs_limb, rhs_limb);
3545 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3546
3547 remaining_bytes -= 8 / CHAR_BIT;
3548 byte_offset += 8 / CHAR_BIT;
3549 }
3550}
3551
3552static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3553 uint8_t *res_bytes = res;
3554 const uint8_t *lhs_bytes = lhs;
3555 const uint8_t *rhs_bytes = rhs;
3556 uint16_t byte_offset = 0;
3557 uint16_t remaining_bytes = zig_int_bytes(bits);
3558 (void)is_signed;
3559
3560 while (remaining_bytes >= 128 / CHAR_BIT) {
3561 zig_u128 res_limb;
3562 zig_u128 lhs_limb;
3563 zig_u128 rhs_limb;
3564
3565 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3566 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3567 res_limb = zig_or_u128(lhs_limb, rhs_limb);
3568 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3569
3570 remaining_bytes -= 128 / CHAR_BIT;
3571 byte_offset += 128 / CHAR_BIT;
3572 }
3573
3574 while (remaining_bytes >= 64 / CHAR_BIT) {
3575 uint64_t res_limb;
3576 uint64_t lhs_limb;
3577 uint64_t rhs_limb;
3578
3579 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3580 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3581 res_limb = zig_or_u64(lhs_limb, rhs_limb);
3582 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3583
3584 remaining_bytes -= 64 / CHAR_BIT;
3585 byte_offset += 64 / CHAR_BIT;
3586 }
3587
3588 while (remaining_bytes >= 32 / CHAR_BIT) {
3589 uint32_t res_limb;
3590 uint32_t lhs_limb;
3591 uint32_t rhs_limb;
3592
3593 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3594 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3595 res_limb = zig_or_u32(lhs_limb, rhs_limb);
3596 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3597
3598 remaining_bytes -= 32 / CHAR_BIT;
3599 byte_offset += 32 / CHAR_BIT;
3600 }
3601
3602 while (remaining_bytes >= 16 / CHAR_BIT) {
3603 uint16_t res_limb;
3604 uint16_t lhs_limb;
3605 uint16_t rhs_limb;
3606
3607 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3608 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3609 res_limb = zig_or_u16(lhs_limb, rhs_limb);
3610 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3611
3612 remaining_bytes -= 16 / CHAR_BIT;
3613 byte_offset += 16 / CHAR_BIT;
3614 }
27243615
2725 while (remaining_bytes >= 8 / CHAR_BIT) {3616 while (remaining_bytes >= 8 / CHAR_BIT) {
2726 uint8_t res_limb;3617 uint8_t res_limb;
...@@ -2816,13 +3707,415 @@ static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool...@@ -2816,13 +3707,415 @@ static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool
2816 }3707 }
2817}3708}
28183709
3710static inline void zig_increment_big(void *res, bool is_signed, uint16_t bits) {
3711 uint8_t *res_bytes = res;
3712 uint16_t byte_offset = 0;
3713 uint16_t remaining_bytes = zig_int_bytes(bits);
3714 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3715
3716#if zig_big_endian
3717 byte_offset = remaining_bytes;
3718#endif
3719
3720 while (remaining_bytes >= 128 / CHAR_BIT) {
3721 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3722
3723#if zig_big_endian
3724 byte_offset -= 128 / CHAR_BIT;
3725#endif
3726
3727 {
3728 zig_u128 res_limb;
3729 bool limb_overflow;
3730
3731 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3732 limb_overflow = zig_addo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits);
3733 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3734 if (!limb_overflow) return;
3735 }
3736
3737 remaining_bytes -= 128 / CHAR_BIT;
3738
3739#if zig_little_endian
3740 byte_offset += 128 / CHAR_BIT;
3741#endif
3742 }
3743
3744 while (remaining_bytes >= 64 / CHAR_BIT) {
3745 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
3746
3747#if zig_big_endian
3748 byte_offset -= 64 / CHAR_BIT;
3749#endif
3750
3751 {
3752 uint64_t res_limb;
3753 bool limb_overflow;
3754
3755 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3756 limb_overflow = zig_addo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits);
3757 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3758 if (!limb_overflow) return;
3759 }
3760
3761 remaining_bytes -= 64 / CHAR_BIT;
3762
3763#if zig_little_endian
3764 byte_offset += 64 / CHAR_BIT;
3765#endif
3766 }
3767
3768 while (remaining_bytes >= 32 / CHAR_BIT) {
3769 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
3770
3771#if zig_big_endian
3772 byte_offset -= 32 / CHAR_BIT;
3773#endif
3774
3775 {
3776 uint32_t res_limb;
3777 bool limb_overflow;
3778
3779 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3780 limb_overflow = zig_addo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits);
3781 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3782 if (!limb_overflow) return;
3783 }
3784
3785 remaining_bytes -= 32 / CHAR_BIT;
3786
3787#if zig_little_endian
3788 byte_offset += 32 / CHAR_BIT;
3789#endif
3790 }
3791
3792 while (remaining_bytes >= 16 / CHAR_BIT) {
3793 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
3794
3795#if zig_big_endian
3796 byte_offset -= 16 / CHAR_BIT;
3797#endif
3798
3799 {
3800 uint16_t res_limb;
3801 bool limb_overflow;
3802
3803 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3804 limb_overflow = zig_addo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits);
3805 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3806 if (!limb_overflow) return;
3807 }
3808
3809 remaining_bytes -= 16 / CHAR_BIT;
3810
3811#if zig_little_endian
3812 byte_offset += 16 / CHAR_BIT;
3813#endif
3814 }
3815
3816 while (remaining_bytes >= 8 / CHAR_BIT) {
3817 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3818
3819#if zig_big_endian
3820 byte_offset -= 8 / CHAR_BIT;
3821#endif
3822
3823 {
3824 uint8_t res_limb;
3825 bool limb_overflow;
3826
3827 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3828 limb_overflow = zig_addo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits);
3829 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3830 if (!limb_overflow) return;
3831 }
3832
3833 remaining_bytes -= 8 / CHAR_BIT;
3834
3835#if zig_little_endian
3836 byte_offset += 8 / CHAR_BIT;
3837#endif
3838 }
3839}
3840
3841static inline void zig_decrement_big(void *res, bool is_signed, uint16_t bits) {
3842 uint8_t *res_bytes = res;
3843 uint16_t byte_offset = 0;
3844 uint16_t remaining_bytes = zig_int_bytes(bits);
3845 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3846
3847#if zig_big_endian
3848 byte_offset = remaining_bytes;
3849#endif
3850
3851 while (remaining_bytes >= 128 / CHAR_BIT) {
3852 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3853
3854#if zig_big_endian
3855 byte_offset -= 128 / CHAR_BIT;
3856#endif
3857
3858 {
3859 zig_u128 res_limb;
3860 bool limb_overflow;
3861
3862 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3863 limb_overflow = zig_subo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits);
3864 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3865 if (!limb_overflow) return;
3866 }
3867
3868 remaining_bytes -= 128 / CHAR_BIT;
3869
3870#if zig_little_endian
3871 byte_offset += 128 / CHAR_BIT;
3872#endif
3873 }
3874
3875 while (remaining_bytes >= 64 / CHAR_BIT) {
3876 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
3877
3878#if zig_big_endian
3879 byte_offset -= 64 / CHAR_BIT;
3880#endif
3881
3882 {
3883 uint64_t res_limb;
3884 bool limb_overflow;
3885
3886 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3887 limb_overflow = zig_subo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits);
3888 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3889 if (!limb_overflow) return;
3890 }
3891
3892 remaining_bytes -= 64 / CHAR_BIT;
3893
3894#if zig_little_endian
3895 byte_offset += 64 / CHAR_BIT;
3896#endif
3897 }
3898
3899 while (remaining_bytes >= 32 / CHAR_BIT) {
3900 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
3901
3902#if zig_big_endian
3903 byte_offset -= 32 / CHAR_BIT;
3904#endif
3905
3906 {
3907 uint32_t res_limb;
3908 bool limb_overflow;
3909
3910 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3911 limb_overflow = zig_subo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits);
3912 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3913 if (!limb_overflow) return;
3914 }
3915
3916 remaining_bytes -= 32 / CHAR_BIT;
3917
3918#if zig_little_endian
3919 byte_offset += 32 / CHAR_BIT;
3920#endif
3921 }
3922
3923 while (remaining_bytes >= 16 / CHAR_BIT) {
3924 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
3925
3926#if zig_big_endian
3927 byte_offset -= 16 / CHAR_BIT;
3928#endif
3929
3930 {
3931 uint16_t res_limb;
3932 bool limb_overflow;
3933
3934 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3935 limb_overflow = zig_subo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits);
3936 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3937 if (!limb_overflow) return;
3938 }
3939
3940 remaining_bytes -= 16 / CHAR_BIT;
3941
3942#if zig_little_endian
3943 byte_offset += 16 / CHAR_BIT;
3944#endif
3945 }
3946
3947 while (remaining_bytes >= 8 / CHAR_BIT) {
3948 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3949
3950#if zig_big_endian
3951 byte_offset -= 8 / CHAR_BIT;
3952#endif
3953
3954 {
3955 uint8_t res_limb;
3956 bool limb_overflow;
3957
3958 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3959 limb_overflow = zig_subo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits);
3960 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3961 if (!limb_overflow) return;
3962 }
3963
3964 remaining_bytes -= 8 / CHAR_BIT;
3965
3966#if zig_little_endian
3967 byte_offset += 8 / CHAR_BIT;
3968#endif
3969 }
3970}
3971
3972static inline void zig_abs_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
3973 uint8_t *res_bytes = res;
3974 const uint8_t *arg_bytes = arg;
3975 uint16_t byte_offset = 0;
3976 uint16_t remaining_bytes = zig_int_bytes(bits);
3977 if (zig_signFill_big(arg, is_signed, bits) >= INT8_C(0)) {
3978 memcpy(res, arg, remaining_bytes);
3979 return;
3980 }
3981 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3982 bool overflow = true;
3983
3984#if zig_big_endian
3985 byte_offset = remaining_bytes;
3986#endif
3987
3988 while (remaining_bytes >= 128 / CHAR_BIT) {
3989 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3990
3991#if zig_big_endian
3992 byte_offset -= 128 / CHAR_BIT;
3993#endif
3994
3995 {
3996 zig_u128 res_limb;
3997 zig_u128 arg_limb;
3998
3999 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4000 overflow = zig_addo_u128(&res_limb, zig_not_u128(arg_limb, UINT8_C(128)), zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits);
4001 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4002 }
4003
4004 remaining_bytes -= 128 / CHAR_BIT;
4005
4006#if zig_little_endian
4007 byte_offset += 128 / CHAR_BIT;
4008#endif
4009 }
4010
4011 while (remaining_bytes >= 64 / CHAR_BIT) {
4012 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
4013
4014#if zig_big_endian
4015 byte_offset -= 64 / CHAR_BIT;
4016#endif
4017
4018 {
4019 uint64_t res_limb;
4020 uint64_t arg_limb;
4021
4022 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4023 overflow = zig_addo_u64(&res_limb, zig_not_u64(arg_limb, UINT8_C(64)), overflow ? UINT64_C(1) : UINT64_C(0), limb_bits);
4024 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4025 }
4026
4027 remaining_bytes -= 64 / CHAR_BIT;
4028
4029#if zig_little_endian
4030 byte_offset += 64 / CHAR_BIT;
4031#endif
4032 }
4033
4034 while (remaining_bytes >= 32 / CHAR_BIT) {
4035 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
4036
4037#if zig_big_endian
4038 byte_offset -= 32 / CHAR_BIT;
4039#endif
4040
4041 {
4042 uint32_t res_limb;
4043 uint32_t arg_limb;
4044
4045 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4046 overflow = zig_addo_u32(&res_limb, zig_not_u32(arg_limb, UINT8_C(32)), overflow ? UINT32_C(1) : UINT32_C(0), limb_bits);
4047 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4048 }
4049
4050 remaining_bytes -= 32 / CHAR_BIT;
4051
4052#if zig_little_endian
4053 byte_offset += 32 / CHAR_BIT;
4054#endif
4055 }
4056
4057 while (remaining_bytes >= 16 / CHAR_BIT) {
4058 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
4059
4060#if zig_big_endian
4061 byte_offset -= 16 / CHAR_BIT;
4062#endif
4063
4064 {
4065 uint16_t res_limb;
4066 uint16_t arg_limb;
4067
4068 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4069 overflow = zig_addo_u16(&res_limb, zig_not_u16(arg_limb, UINT8_C(16)), overflow ? UINT16_C(1) : UINT16_C(0), limb_bits);
4070 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4071 }
4072
4073 remaining_bytes -= 16 / CHAR_BIT;
4074
4075#if zig_little_endian
4076 byte_offset += 16 / CHAR_BIT;
4077#endif
4078 }
4079
4080 while (remaining_bytes >= 8 / CHAR_BIT) {
4081 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
4082
4083#if zig_big_endian
4084 byte_offset -= 8 / CHAR_BIT;
4085#endif
4086
4087 {
4088 uint8_t res_limb;
4089 uint8_t arg_limb;
4090
4091 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4092 overflow = zig_addo_u8(&res_limb, zig_not_u8(arg_limb, UINT8_C(8)), overflow ? UINT8_C(1) : UINT8_C(0), limb_bits);
4093 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4094 }
4095
4096 remaining_bytes -= 8 / CHAR_BIT;
4097
4098#if zig_little_endian
4099 byte_offset += 8 / CHAR_BIT;
4100#endif
4101 }
4102}
4103
4104static inline void zig_min_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4105 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) < INT32_C(0) ? lhs : rhs, zig_int_bytes(bits));
4106}
4107
4108static inline void zig_max_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4109 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) >= INT32_C(0) ? lhs : rhs, zig_int_bytes(bits));
4110}
4111
2819static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {4112static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2820 uint8_t *res_bytes = res;4113 uint8_t *res_bytes = res;
2821 const uint8_t *lhs_bytes = lhs;4114 const uint8_t *lhs_bytes = lhs;
2822 const uint8_t *rhs_bytes = rhs;4115 const uint8_t *rhs_bytes = rhs;
2823 uint16_t byte_offset = 0;4116 uint16_t byte_offset = 0;
2824 uint16_t remaining_bytes = zig_int_bytes(bits);4117 uint16_t remaining_bytes = zig_int_bytes(bits);
2825 uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits);4118 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
2826 bool overflow = false;4119 bool overflow = false;
28274120
2828#if zig_big_endian4121#if zig_big_endian
...@@ -3038,7 +4331,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -3038,7 +4331,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
3038 const uint8_t *rhs_bytes = rhs;4331 const uint8_t *rhs_bytes = rhs;
3039 uint16_t byte_offset = 0;4332 uint16_t byte_offset = 0;
3040 uint16_t remaining_bytes = zig_int_bytes(bits);4333 uint16_t remaining_bytes = zig_int_bytes(bits);
3041 uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits);4334 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3042 bool overflow = false;4335 bool overflow = false;
30434336
3044#if zig_big_endian4337#if zig_big_endian
...@@ -3238,218 +4531,890 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -3238,218 +4531,890 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
3238 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));4531 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3239 }4532 }
32404533
3241 remaining_bytes -= 8 / CHAR_BIT;4534 remaining_bytes -= 8 / CHAR_BIT;
4535
4536#if zig_little_endian
4537 byte_offset += 8 / CHAR_BIT;
4538#endif
4539 }
4540
4541 return overflow;
4542}
4543
4544static inline void zig_add_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4545 if (zig_addo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4546}
4547
4548static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4549 (void)zig_addo_big(res, lhs, rhs, is_signed, bits);
4550}
4551
4552static inline void zig_adds_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4553 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits);
4554
4555 if (!zig_addo_big(res, lhs, rhs, is_signed, bits)) return;
4556 switch (sat_sign) {
4557 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4558 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4559 }
4560}
4561
4562static inline void zig_sub_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4563 if (zig_subo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4564}
4565
4566static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4567 (void)zig_subo_big(res, lhs, rhs, is_signed, bits);
4568}
4569
4570static inline void zig_subs_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4571 int8_t sat_sign = is_signed ? zig_signFill_big(lhs, is_signed, bits) : -INT8_C(1);
4572
4573 if (!zig_subo_big(res, lhs, rhs, is_signed, bits)) return;
4574 switch (sat_sign) {
4575 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4576 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4577 }
4578}
4579
4580static inline bool zig_mulo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4581 uint8_t *res_bytes = res;
4582 const uint8_t *lhs_bytes = lhs;
4583 const uint8_t *rhs_bytes = rhs;
4584 uint16_t size = zig_int_bytes(bits);
4585 uint16_t sign_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4586 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8));
4587 uint8_t rhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(rhs, is_signed, bits), UINT8_C(8));
4588 uint16_t lhs_byte_offset = sign_byte_offset;
4589 uint16_t lhs_end_byte_offset = UINT16_C(0);
4590 bool overflow = false;
4591
4592#if zig_big_endian
4593 lhs_byte_offset = size - lhs_byte_offset;
4594 lhs_end_byte_offset = size - lhs_end_byte_offset;
4595#endif
4596
4597 while (lhs_byte_offset != lhs_end_byte_offset) {
4598 uint16_t rhs_byte_offset = UINT16_C(0);
4599 uint16_t end_byte_offset = sign_byte_offset;
4600 uint16_t res_byte_offset;
4601 uint16_t lhs_byte;
4602 uint8_t res_byte = UINT8_C(0);
4603 uint16_t mul_res = UINT16_C(0);
4604 uint8_t carry = UINT8_C(0);
4605
4606#if zig_little_endian
4607 lhs_byte_offset -= UINT16_C(1);
4608#else
4609 rhs_byte_offset = size - rhs_byte_offset;
4610 end_byte_offset = size - end_byte_offset;
4611#endif
4612
4613 lhs_byte = zig_u16_intCast_u8(lhs_bytes[lhs_byte_offset]) ^ lhs_sign_fill;
4614
4615#if zig_big_endian
4616 lhs_byte_offset += UINT16_C(1);
4617#endif
4618
4619 res_byte_offset = lhs_byte_offset;
4620
4621 while (res_byte_offset != end_byte_offset) {
4622 bool res_byte_initialized = res_byte_offset != lhs_byte_offset;
4623
4624#if zig_big_endian
4625 rhs_byte_offset -= UINT16_C(1);
4626 res_byte_offset -= UINT16_C(1);
4627#endif
4628
4629 if (res_byte_initialized) res_byte = res_bytes[res_byte_offset];
4630 carry = zig_addo_u8(&res_byte, res_byte, carry, UINT8_C(8));
4631 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_intCast_u16(
4632 zig_shr_u16(mul_res, UINT8_C(8))
4633 ), UINT8_C(8));
4634 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill);
4635 carry += zig_addo_u8(&res_bytes[res_byte_offset], res_byte, zig_u8_truncate_u16(
4636 mul_res,
4637 UINT8_C(8)
4638 ), UINT8_C(8));
4639
4640#if zig_little_endian
4641 rhs_byte_offset += UINT16_C(1);
4642 res_byte_offset += UINT16_C(1);
4643#endif
4644 }
4645
4646 while (rhs_byte_offset != end_byte_offset) {
4647#if zig_big_endian
4648 rhs_byte_offset -= UINT16_C(1);
4649#endif
4650
4651 carry = zig_addo_u8(
4652 &res_byte,
4653 zig_u8_intCast_u16(zig_shr_u16(mul_res, UINT8_C(8))),
4654 carry,
4655 UINT8_C(8)
4656 );
4657 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill);
4658 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_truncate_u16(
4659 mul_res,
4660 UINT8_C(8)
4661 ), UINT8_C(8));
4662 overflow |= res_byte != UINT8_C(0);
4663
4664#if zig_little_endian
4665 rhs_byte_offset += UINT16_C(1);
4666#endif
4667 }
4668
4669 overflow |= zig_shr_u16(mul_res, UINT8_C(8)) != UINT16_C(0);
4670 overflow |= carry != UINT8_C(0);
4671 }
4672
4673#if zig_little_endian
4674 sign_byte_offset -= UINT64_C(1);
4675#else
4676 sign_byte_offset = size - sign_byte_offset;
4677#endif
4678
4679 if (lhs_sign_fill != rhs_sign_fill) {
4680 uint16_t byte_offset = UINT16_C(0);
4681 uint16_t end_byte_offset = sign_byte_offset;
4682 uint8_t res_byte;
4683 int8_t signed_res_byte;
4684 uint8_t carry = UINT8_C(0);
4685
4686#if zig_big_endian
4687 byte_offset = size - byte_offset;
4688 end_byte_offset += UINT16_C(1);
4689#endif
4690
4691 while (byte_offset != end_byte_offset) {
4692#if zig_big_endian
4693 byte_offset -= UINT16_C(1);
4694#endif
4695
4696 carry = zig_subo_u8(&res_byte, UINT8_C(0), carry, UINT8_C(8));
4697 carry += zig_subo_u8(&res_byte, res_byte, res_bytes[byte_offset], UINT8_C(8));
4698 carry += zig_subo_u8(
4699 &res_bytes[byte_offset],
4700 res_byte,
4701 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset],
4702 UINT8_C(8)
4703 );
4704
4705#if zig_little_endian
4706 byte_offset += UINT16_C(1);
4707#endif
4708 }
4709
4710#if zig_big_endian
4711 byte_offset -= UINT16_C(1);
4712#endif
4713
4714 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8));
4715 overflow |= signed_res_byte < INT8_C(0);
4716 overflow |= zig_subo_i8(&signed_res_byte, INT8_C(0), signed_res_byte, UINT8_C(8));
4717 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8));
4718 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4719 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset],
4720 UINT8_C(8)
4721 ), UINT8_C(8));
4722 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8));
4723 } else if (lhs_sign_fill != UINT8_C(0)) {
4724 uint16_t byte_offset = UINT16_C(0);
4725 uint16_t end_byte_offset = sign_byte_offset;
4726 uint8_t res_byte;
4727 int8_t signed_res_byte;
4728 uint8_t carry = UINT8_C(1);
4729
4730#if zig_big_endian
4731 byte_offset = size - byte_offset;
4732 end_byte_offset += UINT16_C(1);
4733#endif
4734
4735 while (byte_offset != end_byte_offset) {
4736#if zig_big_endian
4737 byte_offset -= UINT16_C(1);
4738#endif
4739
4740 carry = zig_subo_u8(&res_byte, res_bytes[byte_offset], carry, UINT8_C(8));
4741 carry += zig_subo_u8(&res_byte, res_byte, lhs_bytes[byte_offset], UINT8_C(8));
4742 carry += zig_subo_u8(&res_bytes[byte_offset], res_byte, rhs_bytes[byte_offset], UINT8_C(8));
4743
4744#if zig_little_endian
4745 byte_offset += UINT16_C(1);
4746#endif
4747 }
4748
4749#if zig_big_endian
4750 byte_offset -= UINT16_C(1);
4751#endif
4752
4753 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8));
4754 overflow |= signed_res_byte < INT8_C(0);
4755 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8));
4756 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4757 lhs_bytes[byte_offset],
4758 UINT8_C(8)
4759 ), UINT8_C(8));
4760 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4761 rhs_bytes[byte_offset],
4762 UINT8_C(8)
4763 ), UINT8_C(8));
4764 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8));
4765 } else if (is_signed) {
4766 int8_t signed_res_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8));
4767
4768 overflow |= signed_res_byte < INT8_C(0);
4769 }
4770
4771 {
4772 uint8_t truncate_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4773 uint8_t fill_byte = UINT8_C(0);
4774
4775 if (is_signed) {
4776 int8_t sign_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8));
4777 int8_t truncated = zig_i8_truncate_i8(sign_byte, truncate_bits);
4778
4779 overflow |= sign_byte != truncated;
4780 res_bytes[sign_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8));
4781 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8));
4782 } else {
4783 uint8_t sign_byte = res_bytes[sign_byte_offset];
4784 uint8_t truncated = zig_u8_truncate_u8(sign_byte, truncate_bits);
4785
4786 overflow |= sign_byte != truncated;
4787 res_bytes[sign_byte_offset] = truncated;
4788 }
4789
4790#if zig_little_endian
4791 sign_byte_offset += UINT16_C(1);
4792 memset(&res_bytes[sign_byte_offset], fill_byte, size - sign_byte_offset);
4793#else
4794 memset(&res_bytes[0], fill_byte, sign_byte_offset);
4795#endif
4796 }
4797
4798 return overflow;
4799}
4800
4801static inline void zig_mul_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4802 if (zig_mulo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4803}
4804
4805static inline void zig_mulw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4806 (void)zig_mulo_big(res, lhs, rhs, is_signed, bits);
4807}
4808
4809static inline void zig_muls_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4810 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits) ^ zig_signFill_big(rhs, is_signed, bits);
4811
4812 if (!zig_mulo_big(res, lhs, rhs, is_signed, bits)) return;
4813 switch (sat_sign) {
4814 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4815 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4816 }
4817}
4818
4819static inline void zig_divTrunc_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4820 if (is_signed) {
4821 zig_extern void __divei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4822 __divei5(res, lhs, rhs, temp, bits);
4823 } else {
4824 zig_extern void __udivei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4825 __udivei5(res, lhs, rhs, temp, bits);
4826 }
4827}
4828
4829static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4830 if (is_signed) {
4831 zig_extern void __modei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4832 __modei5(res, lhs, rhs, temp, bits);
4833 } else {
4834 zig_extern void __umodei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4835 __umodei5(res, lhs, rhs, temp, bits);
4836 }
4837}
4838
4839static inline void zig_divFloor_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4840 bool decrement = false;
4841
4842 if (is_signed) {
4843 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4844 decrement = zig_u32_bitCast_i32(zig_xor_i32(
4845 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4846 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4847 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32));
4848 }
4849 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits);
4850 if (decrement) zig_decrement_big(res, is_signed, bits);
4851}
4852
4853static inline void zig_divCeil_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4854 bool increment = false;
4855
4856 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4857 increment = zig_xor_i32(
4858 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4859 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4860 ) > INT32_C(0);
4861 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits);
4862 if (increment) zig_increment_big(res, is_signed, bits);
4863}
4864
4865static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4866 bool fixup = false;
4867
4868 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4869 if (is_signed && zig_u32_bitCast_i32(zig_xor_i32(
4870 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4871 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4872 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32))) zig_add_big(res, res, rhs, is_signed, bits);
4873}
4874
4875static inline void zig_shr_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
4876 uint8_t *res_bytes = res;
4877 const uint8_t *lhs_bytes = lhs;
4878 uint16_t size = zig_int_bytes(bits);
4879 uint16_t res_byte_offset = UINT16_C(0);
4880 uint16_t lhs_byte_offset = zig_shr_u16(rhs, UINT8_C(3));
4881 uint16_t end_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4882 uint8_t lhs_prev_byte;
4883 uint8_t byte_shift = zig_u8_truncate_u16(rhs, UINT8_C(3));
4884
4885#if zig_big_endian
4886 res_byte_offset = size - res_byte_offset;
4887 lhs_byte_offset = size - lhs_byte_offset;
4888 end_byte_offset = size - end_byte_offset;
4889#endif
4890
4891 {
4892#if zig_big_endian
4893 lhs_byte_offset -= UINT16_C(1);
4894#endif
4895
4896 lhs_prev_byte = lhs_bytes[lhs_byte_offset];
4897
4898#if zig_little_endian
4899 lhs_byte_offset += UINT16_C(1);
4900#endif
4901 }
4902
4903 while (lhs_byte_offset != end_byte_offset) {
4904#if zig_big_endian
4905 res_byte_offset -= UINT16_C(1);
4906 lhs_byte_offset -= UINT16_C(1);
4907#endif
4908
4909 {
4910 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset];
4911
4912 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
4913 zig_shl_u16(zig_u16_intCast_u8(lhs_byte), UINT8_C(8)),
4914 zig_u16_intCast_u8(lhs_prev_byte)
4915 ), byte_shift));
4916 lhs_prev_byte = lhs_byte;
4917 }
4918
4919#if zig_little_endian
4920 res_byte_offset += UINT16_C(1);
4921 lhs_byte_offset += UINT16_C(1);
4922#endif
4923 }
4924
4925 {
4926 uint8_t lhs_sign_fill = UINT8_C(0);
4927
4928#if zig_big_endian
4929 res_byte_offset -= UINT16_C(1);
4930#endif
4931
4932 if (is_signed) {
4933 int8_t signed_byte = zig_i8_bitCast_u8(lhs_prev_byte, UINT8_C(8));
4934
4935 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift);
4936 lhs_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8));
4937 } else {
4938 res_bytes[res_byte_offset] = zig_shr_u8(lhs_prev_byte, byte_shift);
4939 }
4940
4941#if zig_little_endian
4942 res_byte_offset += UINT16_C(1);
4943 memset(&res_bytes[res_byte_offset], lhs_sign_fill, size - res_byte_offset);
4944#else
4945 memset(&res_bytes[0], lhs_sign_fill, res_byte_offset);
4946#endif
4947 }
4948}
4949
4950static inline bool zig_shlo_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
4951 uint8_t *res_bytes = res;
4952 const uint8_t *lhs_bytes = lhs;
4953 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8));
4954 uint16_t size = zig_int_bytes(bits);
4955 uint16_t res_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4956 uint16_t lhs_byte_offset = UINT16_C(0);
4957 uint16_t end_byte_offset = res_byte_offset - UINT16_C(1) - zig_shr_u16(rhs, UINT8_C(3));
4958 uint8_t lhs_prev_byte = lhs_sign_fill;
4959 uint8_t byte_shift = UINT8_C(8) - zig_u8_truncate_u16(rhs, UINT8_C(3));
4960 bool overflow = false;
4961
4962#if zig_little_endian
4963 lhs_byte_offset = size - lhs_byte_offset;
4964#else
4965 res_byte_offset = size - res_byte_offset;
4966 end_byte_offset = size - end_byte_offset;
4967#endif
4968
4969 while (lhs_byte_offset != end_byte_offset) {
4970#if zig_little_endian
4971 lhs_byte_offset -= UINT16_C(1);
4972#endif
4973
4974 overflow |= lhs_prev_byte != lhs_sign_fill;
4975 lhs_prev_byte = lhs_bytes[lhs_byte_offset];
4976
4977#if zig_big_endian
4978 lhs_byte_offset += UINT16_C(1);
4979#endif
4980 }
4981
4982#if zig_little_endian
4983 end_byte_offset = UINT16_C(0);
4984#else
4985 end_byte_offset = size;
4986#endif
4987
4988 {
4989 bool lhs_more_bytes = lhs_byte_offset != end_byte_offset;
4990
4991#if zig_little_endian
4992 if (lhs_more_bytes) lhs_byte_offset -= UINT16_C(1);
4993#endif
4994
4995 {
4996 uint8_t lhs_byte = UINT8_C(0);
4997
4998 if (lhs_more_bytes) lhs_byte = lhs_bytes[lhs_byte_offset];
4999
5000 if (is_signed) {
5001 int16_t shifted = zig_shr_i16(zig_or_i16(
5002 zig_shl_i16(zig_i16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5003 zig_i16_intCast_u8(lhs_byte)
5004 ), byte_shift);
5005 int8_t truncated = zig_i8_truncate_i16(
5006 shifted,
5007 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1)
5008 );
5009 uint8_t fill = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8));
5010
5011 overflow |= zig_i16_intCast_i8(truncated) != shifted;
5012#if zig_little_endian
5013 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset);
5014 res_byte_offset -= UINT16_C(1);
5015#else
5016 memset(&res_bytes[0], fill, res_byte_offset);
5017#endif
5018 res_bytes[res_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8));
5019 } else {
5020 uint16_t shifted = zig_shr_u16(zig_or_u16(
5021 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5022 zig_u16_intCast_u8(lhs_byte)
5023 ), byte_shift);
5024 uint8_t truncated = zig_u8_truncate_u16(
5025 shifted,
5026 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1)
5027 );
5028
5029 overflow |= zig_u16_intCast_u8(truncated) != shifted;
5030#if zig_little_endian
5031 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset);
5032 res_byte_offset -= UINT16_C(1);
5033#else
5034 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
5035#endif
5036 res_bytes[res_byte_offset] = truncated;
5037 }
5038
5039 lhs_prev_byte = lhs_byte;
5040 }
5041
5042#if zig_big_endian
5043 res_byte_offset += UINT16_C(1);
5044 if (lhs_more_bytes) lhs_byte_offset += UINT16_C(1);
5045#endif
5046 }
5047
5048 while (lhs_byte_offset != end_byte_offset) {
5049#if zig_little_endian
5050 res_byte_offset -= UINT16_C(1);
5051 lhs_byte_offset -= UINT16_C(1);
5052#endif
5053
5054 {
5055 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset];
5056
5057 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
5058 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5059 zig_u16_intCast_u8(lhs_byte)
5060 ), byte_shift));
5061 lhs_prev_byte = lhs_byte;
5062 }
5063
5064#if zig_big_endian
5065 res_byte_offset += UINT16_C(1);
5066 lhs_byte_offset += UINT16_C(1);
5067#endif
5068 }
5069
5070 {
5071#if zig_little_endian
5072 res_byte_offset -= UINT16_C(1);
5073#endif
5074
5075 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(
5076 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5077 byte_shift
5078 ));
5079
5080#if zig_big_endian
5081 res_byte_offset += UINT16_C(1);
5082#endif
5083 }
5084
5085#if zig_little_endian
5086 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
5087#else
5088 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset);
5089#endif
5090
5091 return overflow;
5092}
5093
5094static inline void zig_shl_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
5095 if (zig_shlo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: left shift overflowed bits
5096}
5097
5098static inline void zig_shlw_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
5099 (void)zig_shlo_big(res, lhs, rhs, is_signed, bits);
5100}
5101
5102#define zig_big_shls_builtin(w) \
5103 static inline uint##w##_t zig_shls_u##w##_big(uint##w##_t lhs, const void *rhs, \
5104 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \
5105 uint##w##_t res; \
5106 const uint8_t *rhs_bytes = rhs; \
5107 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \
5108 !zig_shlo_u##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \
5109 return lhs == INT##w##_C(0) ? zig_minInt_u(w, lhs_bits) : zig_maxInt_u(w, lhs_bits); \
5110 } \
5111\
5112 static inline int##w##_t zig_shls_i##w##_big(int##w##_t lhs, const void *rhs, \
5113 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \
5114 int##w##_t res; \
5115 const uint8_t *rhs_bytes = rhs; \
5116 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \
5117 !zig_shlo_i##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \
5118 return lhs == INT##w##_C(0) ? INT##w##_C(0) : \
5119 lhs < INT##w##_C(0) ? zig_minInt_i(w, lhs_bits) : zig_maxInt_i(w, lhs_bits); \
5120 } \
5121\
5122 static inline void zig_shls_big_u##w(void *res, const void *lhs, uint##w##_t rhs, bool is_signed, uint16_t bits) { \
5123 const uint8_t *lhs_bytes = lhs; \
5124 if (rhs < bits && !zig_shlo_big(res, lhs, zig_u16_intCast_u##w(rhs), is_signed, bits)) return; \
5125 switch (zig_cmp_big_u8(lhs, UINT8_C(0), is_signed, bits)) { \
5126 case -INT32_C(1): return zig_minInt_big(res, is_signed, bits); \
5127 case INT32_C(0): return zig_minInt_big(res, false, bits); \
5128 case INT32_C(1): return zig_maxInt_big(res, is_signed, bits); \
5129 default: zig_unreachable(); \
5130 } \
5131 }
5132zig_big_shls_builtin(8)
5133zig_big_shls_builtin(16)
5134zig_big_shls_builtin(32)
5135zig_big_shls_builtin(64)
5136
5137static inline void zig_byteSwap_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
5138 uint8_t *res_bytes = res;
5139 const uint8_t *arg_bytes = arg;
5140 uint16_t res_byte_offset = UINT16_C(0);
5141 uint16_t arg_byte_offset = bits / CHAR_BIT;
5142 uint16_t end_byte_offset = UINT16_C(1);
5143 uint16_t size = zig_int_bytes(bits);
5144
5145#if zig_big_endian
5146 res_byte_offset = size - res_byte_offset;
5147 arg_byte_offset = size - arg_byte_offset;
5148 end_byte_offset = size - end_byte_offset;
5149#endif
5150
5151 while (arg_byte_offset != end_byte_offset) {
5152#if zig_little_endian
5153 arg_byte_offset -= UINT16_C(1);
5154#else
5155 res_byte_offset -= UINT16_C(1);
5156#endif
5157
5158 res_bytes[res_byte_offset] = arg_bytes[arg_byte_offset];
32425159
3243#if zig_little_endian5160#if zig_little_endian
3244 byte_offset += 8 / CHAR_BIT;5161 res_byte_offset += UINT16_C(1);
5162#else
5163 arg_byte_offset += UINT16_C(1);
3245#endif5164#endif
3246 }5165 }
32475166
3248 return overflow;5167 {
3249}5168#if zig_little_endian
5169 arg_byte_offset -= UINT16_C(1);
5170#else
5171 res_byte_offset -= UINT16_C(1);
5172#endif
32505173
3251static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5174 {
3252 (void)zig_addo_big(res, lhs, rhs, is_signed, bits);5175 uint8_t byte = arg_bytes[arg_byte_offset];
3253}5176 uint8_t fill = is_signed
5177 ? zig_u8_bitCast_i8(zig_shr_i8(zig_i8_bitCast_u8(byte, UINT8_C(8)), UINT8_C(7)), UINT8_C(8))
5178 : UINT8_C(0);
32545179
3255static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5180 res_bytes[res_byte_offset] = byte;
3256 (void)zig_subo_big(res, lhs, rhs, is_signed, bits);
3257}
32585181
3259zig_extern void __udivei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits);5182#if zig_little_endian
3260static inline void zig_div_trunc_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5183 res_byte_offset += UINT16_C(1);
3261 if (!is_signed) {5184 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset);
3262 __udivei4(res, lhs, rhs, bits);5185#else
3263 return;5186 memset(&res_bytes[0], fill, res_byte_offset);
5187#endif
5188 }
3264 }5189 }
3265
3266 zig_trap();
3267}5190}
32685191
3269static inline void zig_div_floor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5192static inline void zig_bitReverse_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
3270 if (!is_signed) {5193 uint8_t *res_bytes = res;
3271 zig_div_trunc_big(res, lhs, rhs, is_signed, bits);5194 const uint8_t *arg_bytes = arg;
3272 return;5195 uint16_t size = zig_int_bytes(bits);
3273 }5196 uint16_t res_byte_offset = UINT16_C(0);
5197 uint16_t arg_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5198 uint16_t end_byte_offset = UINT16_C(0);
5199 uint8_t arg_prev_byte;
5200 uint8_t byte_shift = zig_u8_intCast_u16(zig_subw_u16(UINT16_C(0), bits, UINT8_C(3)));
32745201
3275 zig_trap();5202#if zig_big_endian
3276}5203 res_byte_offset = size - res_byte_offset;
5204 arg_byte_offset = size - arg_byte_offset;
5205 end_byte_offset = size - end_byte_offset;
5206#endif
32775207
3278static inline void zig_div_ceil_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5208 {
3279 zig_trap();5209#if zig_little_endian
3280}5210 arg_byte_offset -= UINT16_C(1);
5211#endif
32815212
3282zig_extern void __umodei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits);5213 arg_prev_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8));
3283static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5214
3284 if (!is_signed) {5215#if zig_big_endian
3285 __umodei4(res, lhs, rhs, bits);5216 arg_byte_offset += UINT16_C(1);
3286 return;5217#endif
3287 }5218 }
32885219
3289 zig_trap();5220 while (arg_byte_offset != end_byte_offset) {
3290}5221#if zig_big_endian
5222 res_byte_offset -= UINT16_C(1);
5223#else
5224 arg_byte_offset -= UINT16_C(1);
5225#endif
32915226
3292static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {5227 {
3293 if (!is_signed) {5228 uint8_t arg_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8));
3294 zig_rem_big(res, lhs, rhs, is_signed, bits);5229
3295 return;5230 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
5231 zig_shl_u16(zig_u16_intCast_u8(arg_byte), UINT8_C(8)),
5232 zig_u16_intCast_u8(arg_prev_byte)
5233 ), byte_shift));
5234 arg_prev_byte = arg_byte;
5235 }
5236
5237#if zig_little_endian
5238 res_byte_offset += UINT16_C(1);
5239#else
5240 arg_byte_offset += UINT16_C(1);
5241#endif
3296 }5242 }
32975243
3298 zig_trap();5244 {
5245 uint8_t arg_sign_fill = UINT8_C(0);
5246
5247#if zig_big_endian
5248 res_byte_offset -= UINT16_C(1);
5249#endif
5250
5251 if (is_signed) {
5252 int8_t signed_byte = zig_i8_bitCast_u8(arg_prev_byte, UINT8_C(8));
5253
5254 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift);
5255 arg_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8));
5256 } else {
5257 res_bytes[res_byte_offset] = zig_shr_u8(arg_prev_byte, byte_shift);
5258 }
5259
5260#if zig_little_endian
5261 res_byte_offset += UINT16_C(1);
5262 memset(&res_bytes[res_byte_offset], arg_sign_fill, size - res_byte_offset);
5263#else
5264 memset(&res_bytes[0], arg_sign_fill, res_byte_offset);
5265#endif
5266 }
3299}5267}
33005268
3301static inline uint16_t zig_clz_big(const void *val, bool is_signed, uint16_t bits) {5269static inline uint16_t zig_popCount_big(const void *arg, bool is_signed, uint16_t bits) {
3302 const uint8_t *val_bytes = val;5270 const uint8_t *arg_bytes = arg;
3303 uint16_t byte_offset = 0;5271 uint16_t byte_offset = 0;
3304 uint16_t remaining_bytes = zig_int_bytes(bits);5272 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
3305 uint16_t skip_bits = remaining_bytes * 8 - bits;5273 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3306 uint16_t total_lz = 0;5274 uint16_t total_pc = 0;
3307 uint16_t limb_lz;
3308 (void)is_signed;5275 (void)is_signed;
33095276
3310#if zig_little_endian5277#if zig_big_endian
3311 byte_offset = remaining_bytes;5278 byte_offset = zig_int_bytes(bits);
3312#endif5279#endif
33135280
3314 while (remaining_bytes >= 128 / CHAR_BIT) {5281 while (remaining_bytes >= 128 / CHAR_BIT) {
3315#if zig_little_endian5282 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
5283
5284#if zig_big_endian
3316 byte_offset -= 128 / CHAR_BIT;5285 byte_offset -= 128 / CHAR_BIT;
3317#endif5286#endif
33185287
3319 {5288 {
3320 zig_u128 val_limb;5289 zig_u128 arg_limb;
33215290
3322 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5291 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3323 limb_lz = zig_clz_u128(val_limb, 128 - skip_bits);5292 total_pc += zig_popCount_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
3324 }5293 }
33255294
3326 total_lz += limb_lz;
3327 if (limb_lz < 128 - skip_bits) return total_lz;
3328 skip_bits = 0;
3329 remaining_bytes -= 128 / CHAR_BIT;5295 remaining_bytes -= 128 / CHAR_BIT;
33305296
3331#if zig_big_endian5297#if zig_little_endian
3332 byte_offset += 128 / CHAR_BIT;5298 byte_offset += 128 / CHAR_BIT;
3333#endif5299#endif
3334 }5300 }
33355301
3336 while (remaining_bytes >= 64 / CHAR_BIT) {5302 while (remaining_bytes >= 64 / CHAR_BIT) {
3337#if zig_little_endian5303 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
5304
5305#if zig_big_endian
3338 byte_offset -= 64 / CHAR_BIT;5306 byte_offset -= 64 / CHAR_BIT;
3339#endif5307#endif
33405308
3341 {5309 {
3342 uint64_t val_limb;5310 uint64_t arg_limb;
33435311
3344 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5312 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3345 limb_lz = zig_clz_u64(val_limb, 64 - skip_bits);5313 total_pc += zig_popCount_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
3346 }5314 }
33475315
3348 total_lz += limb_lz;
3349 if (limb_lz < 64 - skip_bits) return total_lz;
3350 skip_bits = 0;
3351 remaining_bytes -= 64 / CHAR_BIT;5316 remaining_bytes -= 64 / CHAR_BIT;
33525317
3353#if zig_big_endian5318#if zig_little_endian
3354 byte_offset += 64 / CHAR_BIT;5319 byte_offset += 64 / CHAR_BIT;
3355#endif5320#endif
3356 }5321 }
33575322
3358 while (remaining_bytes >= 32 / CHAR_BIT) {5323 while (remaining_bytes >= 32 / CHAR_BIT) {
3359#if zig_little_endian5324 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
5325
5326#if zig_big_endian
3360 byte_offset -= 32 / CHAR_BIT;5327 byte_offset -= 32 / CHAR_BIT;
3361#endif5328#endif
33625329
3363 {5330 {
3364 uint32_t val_limb;5331 uint32_t arg_limb;
33655332
3366 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5333 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3367 limb_lz = zig_clz_u32(val_limb, 32 - skip_bits);5334 total_pc += zig_popCount_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
3368 }5335 }
33695336
3370 total_lz += limb_lz;
3371 if (limb_lz < 32 - skip_bits) return total_lz;
3372 skip_bits = 0;
3373 remaining_bytes -= 32 / CHAR_BIT;5337 remaining_bytes -= 32 / CHAR_BIT;
33745338
3375#if zig_big_endian5339#if zig_little_endian
3376 byte_offset += 32 / CHAR_BIT;5340 byte_offset += 32 / CHAR_BIT;
3377#endif5341#endif
3378 }5342 }
33795343
3380 while (remaining_bytes >= 16 / CHAR_BIT) {5344 while (remaining_bytes >= 16 / CHAR_BIT) {
3381#if zig_little_endian5345 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
5346
5347#if zig_big_endian
3382 byte_offset -= 16 / CHAR_BIT;5348 byte_offset -= 16 / CHAR_BIT;
3383#endif5349#endif
33845350
3385 {5351 {
3386 uint16_t val_limb;5352 uint16_t arg_limb;
33875353
3388 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5354 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3389 limb_lz = zig_clz_u16(val_limb, 16 - skip_bits);5355 total_pc += zig_popCount_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
3390 }5356 }
33915357
3392 total_lz += limb_lz;
3393 if (limb_lz < 16 - skip_bits) return total_lz;
3394 skip_bits = 0;
3395 remaining_bytes -= 16 / CHAR_BIT;5358 remaining_bytes -= 16 / CHAR_BIT;
33965359
3397#if zig_big_endian5360#if zig_little_endian
3398 byte_offset += 16 / CHAR_BIT;5361 byte_offset += 16 / CHAR_BIT;
3399#endif5362#endif
3400 }5363 }
34015364
3402 while (remaining_bytes >= 8 / CHAR_BIT) {5365 while (remaining_bytes >= 8 / CHAR_BIT) {
3403#if zig_little_endian5366 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
5367
5368#if zig_big_endian
3404 byte_offset -= 8 / CHAR_BIT;5369 byte_offset -= 8 / CHAR_BIT;
3405#endif5370#endif
34065371
3407 {5372 {
3408 uint8_t val_limb;5373 uint8_t arg_limb;
34095374
3410 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5375 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3411 limb_lz = zig_clz_u8(val_limb, 8 - skip_bits);5376 total_pc += zig_popCount_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
3412 }5377 }
34135378
3414 total_lz += limb_lz;
3415 if (limb_lz < 8 - skip_bits) return total_lz;
3416 skip_bits = 0;
3417 remaining_bytes -= 8 / CHAR_BIT;5379 remaining_bytes -= 8 / CHAR_BIT;
34185380
3419#if zig_big_endian5381#if zig_little_endian
3420 byte_offset += 8 / CHAR_BIT;5382 byte_offset += 8 / CHAR_BIT;
3421#endif5383#endif
3422 }5384 }
34235385
3424 return total_lz;5386 return total_pc;
3425}5387}
34265388
3427static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bits) {5389static inline uint16_t zig_ctz_big(const void *arg, bool is_signed, uint16_t bits) {
3428 const uint8_t *val_bytes = val;5390 const uint8_t *arg_bytes = arg;
3429 uint16_t byte_offset = 0;5391 uint16_t byte_offset = UINT16_C(0);
3430 uint16_t remaining_bytes = zig_int_bytes(bits);5392 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
3431 uint16_t total_tz = 0;5393 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5394 uint16_t total_tz = UINT16_C(0);
3432 uint16_t limb_tz;5395 uint16_t limb_tz;
3433 (void)is_signed;5396 (void)is_signed;
34345397
3435#if zig_big_endian5398#if zig_big_endian
3436 byte_offset = remaining_bytes;5399 byte_offset = zig_int_bytes(bits);
3437#endif5400#endif
34385401
3439 while (remaining_bytes >= 128 / CHAR_BIT) {5402 while (remaining_bytes >= 128 / CHAR_BIT) {
5403 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
5404
3440#if zig_big_endian5405#if zig_big_endian
3441 byte_offset -= 128 / CHAR_BIT;5406 byte_offset -= 128 / CHAR_BIT;
3442#endif5407#endif
34435408
3444 {5409 {
3445 zig_u128 val_limb;5410 zig_u128 arg_limb;
34465411
3447 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5412 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3448 limb_tz = zig_ctz_u128(val_limb, 128);5413 limb_tz = zig_ctz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
3449 }5414 }
34505415
3451 total_tz += limb_tz;5416 total_tz += limb_tz;
3452 if (limb_tz < 128) return total_tz;5417 if (limb_tz < limb_bits) return total_tz;
3453 remaining_bytes -= 128 / CHAR_BIT;5418 remaining_bytes -= 128 / CHAR_BIT;
34545419
3455#if zig_little_endian5420#if zig_little_endian
...@@ -3458,19 +5423,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3458,19 +5423,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3458 }5423 }
34595424
3460 while (remaining_bytes >= 64 / CHAR_BIT) {5425 while (remaining_bytes >= 64 / CHAR_BIT) {
5426 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
5427
3461#if zig_big_endian5428#if zig_big_endian
3462 byte_offset -= 64 / CHAR_BIT;5429 byte_offset -= 64 / CHAR_BIT;
3463#endif5430#endif
34645431
3465 {5432 {
3466 uint64_t val_limb;5433 uint64_t arg_limb;
34675434
3468 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5435 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3469 limb_tz = zig_ctz_u64(val_limb, 64);5436 limb_tz = zig_ctz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
3470 }5437 }
34715438
3472 total_tz += limb_tz;5439 total_tz += limb_tz;
3473 if (limb_tz < 64) return total_tz;5440 if (limb_tz < limb_bits) return total_tz;
3474 remaining_bytes -= 64 / CHAR_BIT;5441 remaining_bytes -= 64 / CHAR_BIT;
34755442
3476#if zig_little_endian5443#if zig_little_endian
...@@ -3479,19 +5446,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3479,19 +5446,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3479 }5446 }
34805447
3481 while (remaining_bytes >= 32 / CHAR_BIT) {5448 while (remaining_bytes >= 32 / CHAR_BIT) {
5449 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
5450
3482#if zig_big_endian5451#if zig_big_endian
3483 byte_offset -= 32 / CHAR_BIT;5452 byte_offset -= 32 / CHAR_BIT;
3484#endif5453#endif
34855454
3486 {5455 {
3487 uint32_t val_limb;5456 uint32_t arg_limb;
34885457
3489 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5458 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3490 limb_tz = zig_ctz_u32(val_limb, 32);5459 limb_tz = zig_ctz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
3491 }5460 }
34925461
3493 total_tz += limb_tz;5462 total_tz += limb_tz;
3494 if (limb_tz < 32) return total_tz;5463 if (limb_tz < limb_bits) return total_tz;
3495 remaining_bytes -= 32 / CHAR_BIT;5464 remaining_bytes -= 32 / CHAR_BIT;
34965465
3497#if zig_little_endian5466#if zig_little_endian
...@@ -3500,19 +5469,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3500,19 +5469,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3500 }5469 }
35015470
3502 while (remaining_bytes >= 16 / CHAR_BIT) {5471 while (remaining_bytes >= 16 / CHAR_BIT) {
5472 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
5473
3503#if zig_big_endian5474#if zig_big_endian
3504 byte_offset -= 16 / CHAR_BIT;5475 byte_offset -= 16 / CHAR_BIT;
3505#endif5476#endif
35065477
3507 {5478 {
3508 uint16_t val_limb;5479 uint16_t arg_limb;
35095480
3510 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5481 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3511 limb_tz = zig_ctz_u16(val_limb, 16);5482 limb_tz = zig_ctz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
3512 }5483 }
35135484
3514 total_tz += limb_tz;5485 total_tz += limb_tz;
3515 if (limb_tz < 16) return total_tz;5486 if (limb_tz < limb_bits) return total_tz;
3516 remaining_bytes -= 16 / CHAR_BIT;5487 remaining_bytes -= 16 / CHAR_BIT;
35175488
3518#if zig_little_endian5489#if zig_little_endian
...@@ -3521,19 +5492,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3521,19 +5492,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3521 }5492 }
35225493
3523 while (remaining_bytes >= 8 / CHAR_BIT) {5494 while (remaining_bytes >= 8 / CHAR_BIT) {
5495 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
5496
3524#if zig_big_endian5497#if zig_big_endian
3525 byte_offset -= 8 / CHAR_BIT;5498 byte_offset -= 8 / CHAR_BIT;
3526#endif5499#endif
35275500
3528 {5501 {
3529 uint8_t val_limb;5502 uint8_t arg_limb;
35305503
3531 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5504 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3532 limb_tz = zig_ctz_u8(val_limb, 8);5505 limb_tz = zig_ctz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
3533 }5506 }
35345507
3535 total_tz += limb_tz;5508 total_tz += limb_tz;
3536 if (limb_tz < 8) return total_tz;5509 if (limb_tz < limb_bits) return total_tz;
3537 remaining_bytes -= 8 / CHAR_BIT;5510 remaining_bytes -= 8 / CHAR_BIT;
35385511
3539#if zig_little_endian5512#if zig_little_endian
...@@ -3544,113 +5517,141 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit...@@ -3544,113 +5517,141 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
3544 return total_tz;5517 return total_tz;
3545}5518}
35465519
3547static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_t bits) {5520static inline uint16_t zig_clz_big(const void *arg, bool is_signed, uint16_t bits) {
3548 const uint8_t *val_bytes = val;5521 const uint8_t *arg_bytes = arg;
3549 uint16_t byte_offset = 0;5522 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
3550 uint16_t remaining_bytes = zig_int_bytes(bits);5523 uint16_t remaining_bytes = byte_offset;
3551 uint16_t total_pc = 0;5524 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5525 bool sign_limb = true;
5526 uint16_t total_lz = UINT16_C(0);
5527 uint16_t limb_lz;
3552 (void)is_signed;5528 (void)is_signed;
35535529
3554#if zig_big_endian5530#if zig_big_endian
3555 byte_offset = remaining_bytes;5531 byte_offset = zig_int_bytes(bits) - remaining_bytes;
3556#endif5532#endif
35575533
3558 while (remaining_bytes >= 128 / CHAR_BIT) {5534 while (remaining_bytes >= 128 / CHAR_BIT) {
3559#if zig_big_endian5535 uint8_t limb_bits = UINT8_C(128) - (sign_limb ? top_bits : UINT8_C(0));
5536
5537#if zig_little_endian
3560 byte_offset -= 128 / CHAR_BIT;5538 byte_offset -= 128 / CHAR_BIT;
3561#endif5539#endif
35625540
3563 {5541 {
3564 zig_u128 val_limb;5542 zig_u128 arg_limb;
35655543
3566 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5544 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3567 total_pc += zig_popcount_u128(val_limb, 128);5545 limb_lz = zig_clz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
3568 }5546 }
35695547
5548 total_lz += limb_lz;
5549 if (limb_lz < limb_bits) return total_lz;
5550 sign_limb = false;
3570 remaining_bytes -= 128 / CHAR_BIT;5551 remaining_bytes -= 128 / CHAR_BIT;
35715552
3572#if zig_little_endian5553#if zig_big_endian
3573 byte_offset += 128 / CHAR_BIT;5554 byte_offset += 128 / CHAR_BIT;
3574#endif5555#endif
3575 }5556 }
35765557
3577 while (remaining_bytes >= 64 / CHAR_BIT) {5558 while (remaining_bytes >= 64 / CHAR_BIT) {
3578#if zig_big_endian5559 uint8_t limb_bits = UINT8_C(64) - (sign_limb ? top_bits : UINT8_C(0));
5560
5561#if zig_little_endian
3579 byte_offset -= 64 / CHAR_BIT;5562 byte_offset -= 64 / CHAR_BIT;
3580#endif5563#endif
35815564
3582 {5565 {
3583 uint64_t val_limb;5566 uint64_t arg_limb;
35845567
3585 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5568 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3586 total_pc += zig_popcount_u64(val_limb, 64);5569 limb_lz = zig_clz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
3587 }5570 }
35885571
5572 total_lz += limb_lz;
5573 if (limb_lz < limb_bits) return total_lz;
5574 sign_limb = false;
3589 remaining_bytes -= 64 / CHAR_BIT;5575 remaining_bytes -= 64 / CHAR_BIT;
35905576
3591#if zig_little_endian5577#if zig_big_endian
3592 byte_offset += 64 / CHAR_BIT;5578 byte_offset += 64 / CHAR_BIT;
3593#endif5579#endif
3594 }5580 }
35955581
3596 while (remaining_bytes >= 32 / CHAR_BIT) {5582 while (remaining_bytes >= 32 / CHAR_BIT) {
3597#if zig_big_endian5583 uint8_t limb_bits = UINT8_C(32) - (sign_limb ? top_bits : UINT8_C(0));
5584
5585#if zig_little_endian
3598 byte_offset -= 32 / CHAR_BIT;5586 byte_offset -= 32 / CHAR_BIT;
3599#endif5587#endif
36005588
3601 {5589 {
3602 uint32_t val_limb;5590 uint32_t arg_limb;
36035591
3604 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5592 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3605 total_pc += zig_popcount_u32(val_limb, 32);5593 limb_lz = zig_clz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
3606 }5594 }
36075595
5596 total_lz += limb_lz;
5597 if (limb_lz < limb_bits) return total_lz;
5598 sign_limb = false;
3608 remaining_bytes -= 32 / CHAR_BIT;5599 remaining_bytes -= 32 / CHAR_BIT;
36095600
3610#if zig_little_endian5601#if zig_big_endian
3611 byte_offset += 32 / CHAR_BIT;5602 byte_offset += 32 / CHAR_BIT;
3612#endif5603#endif
3613 }5604 }
36145605
3615 while (remaining_bytes >= 16 / CHAR_BIT) {5606 while (remaining_bytes >= 16 / CHAR_BIT) {
3616#if zig_big_endian5607 uint8_t limb_bits = UINT8_C(16) - (sign_limb ? top_bits : UINT8_C(0));
5608
5609#if zig_little_endian
3617 byte_offset -= 16 / CHAR_BIT;5610 byte_offset -= 16 / CHAR_BIT;
3618#endif5611#endif
36195612
3620 {5613 {
3621 uint16_t val_limb;5614 uint16_t arg_limb;
36225615
3623 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5616 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3624 total_pc = zig_popcount_u16(val_limb, 16);5617 limb_lz = zig_clz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
3625 }5618 }
36265619
5620 total_lz += limb_lz;
5621 if (limb_lz < limb_bits) return total_lz;
5622 sign_limb = false;
3627 remaining_bytes -= 16 / CHAR_BIT;5623 remaining_bytes -= 16 / CHAR_BIT;
36285624
3629#if zig_little_endian5625#if zig_big_endian
3630 byte_offset += 16 / CHAR_BIT;5626 byte_offset += 16 / CHAR_BIT;
3631#endif5627#endif
3632 }5628 }
36335629
3634 while (remaining_bytes >= 8 / CHAR_BIT) {5630 while (remaining_bytes >= 8 / CHAR_BIT) {
3635#if zig_big_endian5631 uint8_t limb_bits = UINT8_C(8) - (sign_limb ? top_bits : UINT8_C(0));
5632
5633#if zig_little_endian
3636 byte_offset -= 8 / CHAR_BIT;5634 byte_offset -= 8 / CHAR_BIT;
3637#endif5635#endif
36385636
3639 {5637 {
3640 uint8_t val_limb;5638 uint8_t arg_limb;
36415639
3642 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));5640 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3643 total_pc = zig_popcount_u8(val_limb, 8);5641 limb_lz = zig_clz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
3644 }5642 }
36455643
5644 total_lz += limb_lz;
5645 if (limb_lz < limb_bits) return total_lz;
5646 sign_limb = false;
3646 remaining_bytes -= 8 / CHAR_BIT;5647 remaining_bytes -= 8 / CHAR_BIT;
36475648
3648#if zig_little_endian5649#if zig_big_endian
3649 byte_offset += 8 / CHAR_BIT;5650 byte_offset += 8 / CHAR_BIT;
3650#endif5651#endif
3651 }5652 }
36525653
3653 return total_pc;5654 return total_lz;
3654}5655}
36555656
3656/* ========================= Floating Point Support ========================= */5657/* ========================= Floating Point Support ========================= */
...@@ -3687,29 +5688,29 @@ long double __cdecl nanl(char const* input);...@@ -3687,29 +5688,29 @@ long double __cdecl nanl(char const* input);
3687#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg)5688#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg)
3688#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)5689#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)
3689#else5690#else
3690#define zig_make_special_f16(sign, name, arg, repr) zig_bitCast_f16 (repr)5691#define zig_make_special_f16(sign, name, arg, repr) zig_f16_bitCast_u16 (repr)
3691#define zig_make_special_f32(sign, name, arg, repr) zig_bitCast_f32 (repr)5692#define zig_make_special_f32(sign, name, arg, repr) zig_f32_bitCast_u32 (repr)
3692#define zig_make_special_f64(sign, name, arg, repr) zig_bitCast_f64 (repr)5693#define zig_make_special_f64(sign, name, arg, repr) zig_f64_bitCast_u64 (repr)
3693#define zig_make_special_f80(sign, name, arg, repr) zig_bitCast_f80 (repr)5694#define zig_make_special_f80(sign, name, arg, repr) zig_f80_bitCast_u128(repr)
3694#define zig_make_special_f128(sign, name, arg, repr) zig_bitCast_f128(repr)5695#define zig_make_special_f128(sign, name, arg, repr) zig_f128_bitCast_u128(repr)
3695#endif5696#endif
36965697
3697#define zig_has_f16 15698#define zig_has_f16 1
3698#define zig_libc_name_f16(name) __##name##h5699#define zig_libc_name_f16(name) __##name##h
3699#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)5700#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)
3700#if FLT_MANT_DIG == 115701#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT_MANT_DIG == 11
3701typedef float zig_f16;5702typedef float zig_f16;
3702#define zig_make_f16(fp, repr) fp##f5703#define zig_make_f16(fp, repr) fp##f
3703#elif DBL_MANT_DIG == 115704#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && DBL_MANT_DIG == 11
3704typedef double zig_f16;5705typedef double zig_f16;
3705#define zig_make_f16(fp, repr) fp5706#define zig_make_f16(fp, repr) fp
3706#elif LDBL_MANT_DIG == 115707#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && LDBL_MANT_DIG == 11
3707typedef long double zig_f16;5708typedef long double zig_f16;
3708#define zig_make_f16(fp, repr) fp##l5709#define zig_make_f16(fp, repr) fp##l
3709#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc))5710#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc))
3710typedef _Float16 zig_f16;5711typedef _Float16 zig_f16;
3711#define zig_make_f16(fp, repr) fp##f165712#define zig_make_f16(fp, repr) fp##f16
3712#elif defined(__SIZEOF_FP16__)5713#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && defined(__SIZEOF_FP16__)
3713typedef __fp16 zig_f16;5714typedef __fp16 zig_f16;
3714#define zig_make_f16(fp, repr) fp##f165715#define zig_make_f16(fp, repr) fp##f16
3715#else5716#else
...@@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16;...@@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16;
3723#undef zig_init_special_f165724#undef zig_init_special_f16
3724#define zig_init_special_f16(sign, name, arg, repr) repr5725#define zig_init_special_f16(sign, name, arg, repr) repr
3725#endif5726#endif
3726#if defined(zig_darwin) && defined(zig_x86)
3727typedef uint16_t zig_compiler_rt_f16;
3728#else
3729typedef zig_f16 zig_compiler_rt_f16;
3730#endif
37315727
3732#define zig_has_f32 15728#define zig_has_f32 1
3733#define zig_libc_name_f32(name) name##f5729#define zig_libc_name_f32(name) name##f
...@@ -3736,16 +5732,16 @@ typedef zig_f16 zig_compiler_rt_f16;...@@ -3736,16 +5732,16 @@ typedef zig_f16 zig_compiler_rt_f16;
3736#else5732#else
3737#define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr)5733#define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr)
3738#endif5734#endif
3739#if FLT_MANT_DIG == 245735#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT_MANT_DIG == 24
3740typedef float zig_f32;5736typedef float zig_f32;
3741#define zig_make_f32(fp, repr) fp##f5737#define zig_make_f32(fp, repr) fp##f
3742#elif DBL_MANT_DIG == 245738#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && DBL_MANT_DIG == 24
3743typedef double zig_f32;5739typedef double zig_f32;
3744#define zig_make_f32(fp, repr) fp5740#define zig_make_f32(fp, repr) fp
3745#elif LDBL_MANT_DIG == 245741#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && LDBL_MANT_DIG == 24
3746typedef long double zig_f32;5742typedef long double zig_f32;
3747#define zig_make_f32(fp, repr) fp##l5743#define zig_make_f32(fp, repr) fp##l
3748#elif FLT32_MANT_DIG == 245744#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT32_MANT_DIG == 24
3749typedef _Float32 zig_f32;5745typedef _Float32 zig_f32;
3750#define zig_make_f32(fp, repr) fp##f325746#define zig_make_f32(fp, repr) fp##f32
3751#else5747#else
...@@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32;...@@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32;
3768#else5764#else
3769#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)5765#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)
3770#endif5766#endif
3771#if FLT_MANT_DIG == 535767#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT_MANT_DIG == 53
3772typedef float zig_f64;5768typedef float zig_f64;
3773#define zig_make_f64(fp, repr) fp##f5769#define zig_make_f64(fp, repr) fp##f
3774#elif DBL_MANT_DIG == 535770#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && DBL_MANT_DIG == 53
3775typedef double zig_f64;5771typedef double zig_f64;
3776#define zig_make_f64(fp, repr) fp5772#define zig_make_f64(fp, repr) fp
3777#elif LDBL_MANT_DIG == 535773#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && LDBL_MANT_DIG == 53
3778typedef long double zig_f64;5774typedef long double zig_f64;
3779#define zig_make_f64(fp, repr) fp##l5775#define zig_make_f64(fp, repr) fp##l
3780#elif FLT64_MANT_DIG == 535776#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT64_MANT_DIG == 53
3781typedef _Float64 zig_f64;5777typedef _Float64 zig_f64;
3782#define zig_make_f64(fp, repr) fp##f645778#define zig_make_f64(fp, repr) fp##f64
3783#elif FLT32X_MANT_DIG == 535779#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT32X_MANT_DIG == 53
3784typedef _Float32x zig_f64;5780typedef _Float32x zig_f64;
3785#define zig_make_f64(fp, repr) fp##f32x5781#define zig_make_f64(fp, repr) fp##f32x
3786#else5782#else
...@@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64;...@@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64;
3798#define zig_has_f80 15794#define zig_has_f80 1
3799#define zig_libc_name_f80(name) __##name##x5795#define zig_libc_name_f80(name) __##name##x
3800#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)5796#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)
3801#if FLT_MANT_DIG == 645797#ifdef ZIG_TARGET_SOFT_COMPILER_RT_F80_ABI
5798#undef zig_has_f80
5799typedef struct { uint64_t mantissa; uint16_t exponent; } zig_f80;
5800#define zig_init_repr_f80(mantissa, exponent) { .mant##issa = mantissa, .expo##nent = exponent }
5801#define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent)
5802#define zig_mantissa_repr_f80(arg) (arg).mantissa
5803#define zig_exponent_repr_f80(arg) (arg).exponent
5804#elif FLT_MANT_DIG == 64
3802typedef float zig_f80;5805typedef float zig_f80;
3803#define zig_make_f80(fp, repr) fp##f5806#define zig_make_f80(fp, repr) fp##f
3804#elif DBL_MANT_DIG == 645807#elif DBL_MANT_DIG == 64
...@@ -3818,68 +5821,91 @@ typedef __float80 zig_f80;...@@ -3818,68 +5821,91 @@ typedef __float80 zig_f80;
3818#define zig_make_f80(fp, repr) fp##l5821#define zig_make_f80(fp, repr) fp##l
3819#else5822#else
3820#undef zig_has_f805823#undef zig_has_f80
3821#define zig_has_f80 0
3822#define zig_repr_f80 u128
3823typedef zig_u128 zig_f80;5824typedef zig_u128 zig_f80;
5825#define zig_init_repr_f80(mantissa, exponent) zig_init_u128(exponent, mantissa)
5826#define zig_make_repr_f80(mantissa, exponent) zig_make_u128(exponent, mantissa)
5827#define zig_mantissa_repr_f80(arg) zig_lo_u128(arg)
5828#define zig_exponent_repr_f80(arg) (uint16_t)zig_hi_u128(arg)
5829#endif
5830#ifndef zig_has_f80
5831#define zig_has_f80 0
3824#define zig_make_f80(fp, repr) repr5832#define zig_make_f80(fp, repr) repr
5833#ifndef zig_make_repr_f80
5834#define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent)
5835#endif
3825#undef zig_make_special_f805836#undef zig_make_special_f80
3826#define zig_make_special_f80(sign, name, arg, repr) repr5837#define zig_make_special_f80(sign, name, arg, repr) repr
3827#undef zig_init_special_f805838#undef zig_init_special_f80
3828#define zig_init_special_f80(sign, name, arg, repr) repr5839#define zig_init_special_f80(sign, name, arg, repr) repr
3829#endif5840#endif
38305841
3831#if defined(zig_gcc) && defined(zig_x86)
3832#define zig_f128_has_miscompilations 1
3833#else
3834#define zig_f128_has_miscompilations 0
3835#endif
3836
3837#define zig_has_f128 15842#define zig_has_f128 1
3838#define zig_libc_name_f128(name) name##q5843#define zig_libc_name_f128(name) name##f128
3839#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)5844#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
3840#if !zig_f128_has_miscompilations && FLT_MANT_DIG == 1135845#ifdef ZIG_TARGET_SOFT_COMPILER_RT_F128_ABI
5846#undef zig_has_f128
5847#if zig_little_endian
5848typedef struct { uint64_t lo, hi; } zig_f128;
5849#else
5850typedef struct { uint64_t hi, lo; } zig_f128;
5851#endif
5852#define zig_init_repr_f128(hi, lo) { .h##i = hi, .l##o = lo }
5853#define zig_lo_repr_f128(arg) (arg).lo
5854#define zig_hi_repr_f128(arg) (arg).hi
5855#elif FLT_MANT_DIG == 113
3841typedef float zig_f128;5856typedef float zig_f128;
3842#define zig_make_f128(fp, repr) fp##f5857#define zig_make_f128(fp, repr) fp##f
3843#elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 1135858#elif DBL_MANT_DIG == 113
3844typedef double zig_f128;5859typedef double zig_f128;
3845#define zig_make_f128(fp, repr) fp5860#define zig_make_f128(fp, repr) fp
3846#elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 1135861#elif LDBL_MANT_DIG == 113
3847typedef long double zig_f128;5862typedef long double zig_f128;
3848#define zig_make_f128(fp, repr) fp##l5863#define zig_make_f128(fp, repr) fp##l
3849#elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 1135864#elif FLT128_MANT_DIG == 113
3850typedef _Float128 zig_f128;5865typedef _Float128 zig_f128;
3851#define zig_make_f128(fp, repr) fp##f1285866#define zig_make_f128(fp, repr) fp##f128
3852#elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 1135867#elif FLT64X_MANT_DIG == 113
3853typedef _Float64x zig_f128;5868typedef _Float64x zig_f128;
3854#define zig_make_f128(fp, repr) fp##f64x5869#define zig_make_f128(fp, repr) fp##f64x
3855#elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__)5870#elif defined(__SIZEOF_FLOAT128__)
3856typedef __float128 zig_f128;5871typedef __float128 zig_f128;
3857#define zig_make_f128(fp, repr) fp##q5872#define zig_make_f128(fp, repr) fp##q
3858#undef zig_make_special_f1285873#undef zig_make_special_f128
3859#define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg)5874#define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg)
3860#else5875#else
3861#undef zig_has_f1285876#undef zig_has_f128
3862#define zig_has_f128 05877#if defined(zig_x86_64) && defined(ZIG_TARGET_ABI_MSVC)
3863#undef zig_make_special_f1285878#if defined(zig_msvc) && !defined(__clang__)
3864#undef zig_init_special_f1285879#include <emmintrin.h>
3865#if defined(zig_darwin) || defined(zig_aarch64)5880typedef __m128i zig_f128;
3866typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64;5881#define zig_init_repr_f128(hi, lo) { .m128i_u64 = { lo, hi } }
3867zig_basic_operator(zig_v2u64, xor_v2u64, ^)5882#define zig_lo_repr_f128(arg) (arg).m128i_u64[0]
3868#define zig_repr_f128 v2u645883#define zig_hi_repr_f128(arg) (arg).m128i_u64[1]
3869typedef zig_v2u64 zig_f128;5884#else
3870#define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi }5885typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_f128;
3871#define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u1285886#define zig_init_repr_f128(hi, lo) { lo, hi }
3872#define zig_make_f128(fp, repr) zig_make_f128_##repr5887#define zig_lo_repr_f128(arg) (arg)[0]
3873#define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr5888#define zig_hi_repr_f128(arg) (arg)[1]
3874#define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr5889#endif
3875#else5890#else
3876#define zig_repr_f128 u128
3877typedef zig_u128 zig_f128;5891typedef zig_u128 zig_f128;
5892#define zig_init_repr_f128(hi, lo) zig_init_u128(hi, lo)
5893#define zig_make_repr_f128(hi, lo) zig_make_u128(hi, lo)
5894#define zig_lo_repr_f128(arg) zig_lo_u128(arg)
5895#define zig_hi_repr_f128(arg) zig_hi_u128(arg)
5896#endif
5897#endif
5898#ifndef zig_has_f128
5899#define zig_has_f128 0
3878#define zig_make_f128(fp, repr) repr5900#define zig_make_f128(fp, repr) repr
5901#ifndef zig_make_repr_f128
5902#define zig_make_repr_f128(hi, lo) (zig_f128)zig_init_repr_f128(hi, lo)
5903#endif
5904#undef zig_make_special_f128
3879#define zig_make_special_f128(sign, name, arg, repr) repr5905#define zig_make_special_f128(sign, name, arg, repr) repr
5906#undef zig_init_special_f128
3880#define zig_init_special_f128(sign, name, arg, repr) repr5907#define zig_init_special_f128(sign, name, arg, repr) repr
3881#endif5908#endif
3882#endif
38835909
3884#if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC)5910#if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC)
3885/* Emulate msvc abi on a gnu compiler */5911/* Emulate msvc abi on a gnu compiler */
...@@ -3892,84 +5918,141 @@ typedef zig_f128 zig_c_longdouble;...@@ -3892,84 +5918,141 @@ typedef zig_f128 zig_c_longdouble;
3892typedef long double zig_c_longdouble;5918typedef long double zig_c_longdouble;
3893#endif5919#endif
38945920
3895#define zig_bitCast_float(Type, ReprType) \5921#if __AVR__
3896 static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \5922typedef signed char zig_FloatCompareResult;
3897 zig_##Type result; \5923#elif defined(zig_aarch64)
3898 memcpy(&result, &repr, sizeof(result)); \5924typedef signed int zig_FloatCompareResult;
3899 return result; \5925#elif __SIZEOF_LONG__ >= __SIZEOF_POINTER__
5926typedef signed long zig_FloatCompareResult;
5927#else
5928typedef signed long long zig_FloatCompareResult;
5929#endif
5930
5931#define zig_bitCast_float(w, iw, UnsignedReprType, SignedReprType) \
5932 static inline zig_f##w zig_f##w##_bitCast_u##iw(UnsignedReprType arg) { \
5933 zig_f##w res; \
5934 memcpy(&res, &arg, sizeof(zig_f##w)); \
5935 return res; \
5936 } \
5937 static inline zig_f##w zig_f##w##_bitCast_i##iw(SignedReprType arg) { \
5938 zig_f##w res; \
5939 memcpy(&res, &arg, sizeof(zig_f##w)); \
5940 return res; \
5941 } \
5942 static inline UnsignedReprType zig_u##iw##_bitCast_f##w(zig_f##w arg) { \
5943 UnsignedReprType res; \
5944 memcpy(&res, &arg, sizeof(zig_f##w)); \
5945 return zig_u##iw##_truncate_u##iw(res, w); \
5946 } \
5947 static inline SignedReprType zig_i##iw##_bitCast_f##w(zig_f##w arg) { \
5948 SignedReprType res; \
5949 memcpy(&res, &arg, sizeof(zig_f##w)); \
5950 return zig_i##iw##_truncate_i##iw(res, w); \
3900 }5951 }
3901zig_bitCast_float(f16, uint16_t)5952zig_bitCast_float(16, 16, uint16_t, int16_t)
3902zig_bitCast_float(f32, uint32_t)5953zig_bitCast_float(32, 32, uint32_t, int32_t)
3903zig_bitCast_float(f64, uint64_t)5954zig_bitCast_float(64, 64, uint64_t, int64_t)
3904zig_bitCast_float(f80, zig_u128)5955#if zig_has_f80
3905zig_bitCast_float(f128, zig_u128)5956zig_bitCast_float(80, 128, zig_u128, zig_i128)
5957#else
5958static inline zig_f80 zig_f80_bitCast_u128(zig_u128 arg) {
5959 return zig_make_repr_f80(zig_lo_u128(arg), (uint16_t)zig_hi_u128(arg));
5960}
5961static inline zig_f80 zig_f80_bitCast_i128(zig_i128 arg) {
5962 return zig_make_repr_f80(zig_lo_i128(arg), (uint16_t)zig_hi_i128(arg));
5963}
5964static inline zig_u128 zig_u128_bitCast_f80(zig_f80 arg) {
5965 return zig_make_u128(zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg));
5966}
5967static inline zig_i128 zig_i128_bitCast_f80(zig_f80 arg) {
5968 return zig_make_i128((int16_t)zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg));
5969}
5970#endif
5971static inline zig_f80 zig_f80_bitCast_big(const void *arg) {
5972 return zig_f80_bitCast_u128(zig_u128_truncate_big(arg, UINT8_C(80), false, UINT16_C(80)));
5973}
5974static inline void zig_big_bitCast_f80(void *res, zig_f80 arg, bool res_is_signed, uint16_t res_bits) {
5975 if (res_is_signed) {
5976 zig_big_truncate_i128(res, zig_i128_bitCast_f80(arg), res_is_signed, res_bits);
5977 } else {
5978 zig_big_truncate_u128(res, zig_u128_bitCast_f80(arg), res_is_signed, res_bits);
5979 }
5980}
5981#if zig_has_f128
5982zig_bitCast_float(128, 128, zig_u128, zig_i128)
5983#else
5984static inline zig_f128 zig_f128_bitCast_u128(zig_u128 arg) {
5985 return zig_make_repr_f128(zig_hi_u128(arg), zig_lo_u128(arg));
5986}
5987static inline zig_f128 zig_f128_bitCast_i128(zig_i128 arg) {
5988 return zig_make_repr_f128((uint64_t)zig_hi_i128(arg), zig_lo_i128(arg));
5989}
5990static inline zig_u128 zig_u128_bitCast_f128(zig_f128 arg) {
5991 return zig_make_u128(zig_hi_repr_f128(arg), zig_lo_repr_f128(arg));
5992}
5993static inline zig_i128 zig_i128_bitCast_f128(zig_f128 arg) {
5994 return zig_make_i128((int64_t)zig_hi_repr_f128(arg), zig_lo_repr_f128(arg));
5995}
5996#endif
39065997
3907#define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \5998#define zig_convert_float_00(ResType, operation, ArgType, version) \
3908 zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \5999 zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
3909 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \6000 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType arg); \
6001 return zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
6002 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(arg)
6003#define zig_convert_float_01(ResType, operation, ArgType, version) \
6004 zig_convert_float_00(ResType, operation, ArgType, version)
6005#define zig_convert_float_10(ResType, operation, ArgType, version) \
6006 zig_convert_float_00(ResType, operation, ArgType, version)
6007#define zig_convert_float_11(ResType, operation, ArgType, version) \
6008 return (ResType)arg
6009#define zig_convert_float(res_when, ResType, operation, arg_when, ArgType, version) \
3910 static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \6010 static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \
3911 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \6011 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \
3912 ResType res; \6012 zig_expand_concat(zig_expand_concat(zig_convert_float_, zig_has_##res_when), \
3913 ExternResType extern_res; \6013 zig_has_##arg_when)(ResType, operation, ArgType, version); \
3914 ExternArgType extern_arg; \6014 }
3915 memcpy(&extern_arg, &arg, sizeof(extern_arg)); \6015
3916 extern_res = zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \6016#define zig_convert_floats(SmallType, BigType) \
3917 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(extern_arg); \6017 zig_convert_float(SmallType, zig_##SmallType, trunc, BigType, zig_##BigType, 2) \
3918 memcpy(&res, &extern_res, sizeof(res)); \6018 zig_convert_float(BigType, zig_##BigType, extend, SmallType, zig_##SmallType, 2)
3919 return extern_res; \6019zig_convert_floats(f16, f32)
3920 }6020zig_convert_floats(f16, f64)
3921zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2)6021zig_convert_floats(f16, f80)
3922zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2)6022zig_convert_floats(f16, f128)
3923zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2)6023zig_convert_floats(f32, f64)
3924zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2)6024zig_convert_floats(f32, f80)
3925zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2)6025zig_convert_floats(f32, f128)
3926zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2)6026zig_convert_floats(f64, f80)
3927zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2)6027zig_convert_floats(f64, f128)
3928zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2)6028zig_convert_floats(f80, f128)
3929zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2)6029
3930zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2)6030#define zig_float_negate_builtin_0(w, sb) \
3931zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2)6031 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, sb))
3932zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2)6032#define zig_float_negate_builtin_1(w, sb) -arg
3933zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2)6033#define zig_float_negate_builtin(w, sb) \
3934zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2)
3935zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2)
3936zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2)
3937zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2)
3938zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2)
3939
3940#ifdef __ARM_EABI__
3941
3942zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_d2f(zig_f64);
3943static inline zig_f32 zig_truncdfsf(zig_f64 arg) { return __aeabi_d2f(arg); }
3944
3945zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_f2d(zig_f32);
3946static inline zig_f64 zig_extendsfdf(zig_f32 arg) { return __aeabi_f2d(arg); }
3947
3948#else /* __ARM_EABI__ */
3949
3950zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2)
3951zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2)
3952
3953#endif /* __ARM_EABI__ */
3954
3955#define zig_float_negate_builtin_0(w, c, sb) \
3956 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, c sb))
3957#define zig_float_negate_builtin_1(w, c, sb) -arg
3958#define zig_float_negate_builtin(w, c, sb) \
3959 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \6034 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \
3960 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, c, sb); \6035 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, sb); \
3961 }6036 }
3962zig_float_negate_builtin(16, , UINT16_C(1) << 15 )6037zig_float_negate_builtin(16, UINT16_C(1) << 15)
3963zig_float_negate_builtin(32, , UINT32_C(1) << 31 )6038zig_float_negate_builtin(32, UINT32_C(1) << 31)
3964zig_float_negate_builtin(64, , UINT64_C(1) << 63 )6039zig_float_negate_builtin(64, UINT64_C(1) << 63)
3965zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0)))6040
3966zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))6041#undef zig_float_negate_builtin_0
6042#define zig_float_negate_builtin_0(w, sb) \
6043 zig_make_repr_f##w(zig_mantissa_repr_f##w(arg), zig_xor_u16(zig_exponent_repr_f##w(arg), sb))
6044zig_float_negate_builtin(80, UINT16_C(1) << 15)
6045
6046#undef zig_float_negate_builtin_0
6047#define zig_float_negate_builtin_0(w, sb) \
6048 zig_make_repr_f##w(zig_xor_u64(zig_hi_repr_f##w(arg), sb), zig_lo_repr_f##w(arg))
6049zig_float_negate_builtin(128, UINT64_C(1) << 63)
39676050
3968#define zig_float_less_builtin_0(Type, operation) \6051#define zig_float_less_builtin_0(Type, operation) \
3969 zig_extern int32_t zig_expand_concat(zig_expand_concat(__##operation, \6052 zig_extern zig_FloatCompareResult zig_expand_concat(zig_expand_concat(__##operation, \
3970 zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \6053 zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \
3971 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \6054 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
3972 return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \6055 return (int32_t)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \
3973 }6056 }
3974#define zig_float_less_builtin_1(Type, operation) \6057#define zig_float_less_builtin_1(Type, operation) \
3975 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \6058 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
...@@ -3994,13 +6077,52 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))...@@ -3994,13 +6077,52 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
3994 return lhs operator rhs; \6077 return lhs operator rhs; \
3995 }6078 }
39966079
6080#define zig_float_builtins(w) \
6081 zig_common_float_builtins(w) \
6082 zig_convert_float(f##w, zig_f##w, float, int128, zig_i128, ) \
6083 zig_convert_float(f##w, zig_f##w, floatun, int128, zig_u128, )
3997#define zig_common_float_builtins(w) \6084#define zig_common_float_builtins(w) \
3998 zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \6085 zig_convert_float(always, int32_t, fix, f##w, zig_f##w, ) \
3999 zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \6086 zig_convert_float(always, int64_t, fix, f##w, zig_f##w, ) \
4000 zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \6087 zig_convert_float(int128, zig_i128, fix, f##w, zig_f##w, ) \
4001 zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \6088 zig_convert_float(always, uint32_t, fixuns, f##w, zig_f##w, ) \
4002 zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \6089 zig_convert_float(always, uint64_t, fixuns, f##w, zig_f##w, ) \
4003 zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \6090 zig_convert_float(int128, zig_u128, fixuns, f##w, zig_f##w, ) \
6091 zig_convert_float(f##w, zig_f##w, float, always, int32_t, ) \
6092 zig_convert_float(f##w, zig_f##w, float, always, int64_t, ) \
6093 zig_convert_float(f##w, zig_f##w, floatun, always, uint32_t, ) \
6094 zig_convert_float(f##w, zig_f##w, floatun, always, uint64_t, ) \
6095\
6096 static inline void zig_expand_concat(zig_expand_concat(zig_fix, \
6097 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \
6098 zig_extern void zig_expand_concat(zig_expand_concat(__fix, \
6099 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \
6100 zig_expand_concat(zig_expand_concat(__fix, \
6101 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \
6102 } \
6103\
6104 static inline void zig_expand_concat(zig_expand_concat(zig_fixuns, \
6105 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \
6106 zig_extern void zig_expand_concat(zig_expand_concat(__fixuns, \
6107 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \
6108 zig_expand_concat(zig_expand_concat(__fixuns, \
6109 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \
6110 } \
6111\
6112 static inline zig_f##w zig_expand_concat(zig_floatei, \
6113 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \
6114 zig_extern zig_f##w zig_expand_concat(__floatei, \
6115 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \
6116 return zig_expand_concat(__floatei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \
6117 } \
6118\
6119 static inline zig_f##w zig_expand_concat(zig_floatunei, \
6120 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \
6121 zig_extern zig_f##w zig_expand_concat(__floatunei, \
6122 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \
6123 return zig_expand_concat(__floatunei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \
6124 } \
6125\
4004 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \6126 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \
4005 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \6127 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \
4006 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \6128 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \
...@@ -4031,82 +6153,48 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))...@@ -4031,82 +6153,48 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
4031 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \6153 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \
4032 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \6154 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \
4033\6155\
4034 static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \6156 static inline zig_f##w zig_divTrunc_f##w(zig_f##w lhs, zig_f##w rhs) { \
4035 return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \6157 return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \
4036 } \6158 } \
4037\6159\
4038 static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \6160 static inline zig_f##w zig_divFloor_f##w(zig_f##w lhs, zig_f##w rhs) { \
4039 return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \6161 return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \
4040 } \6162 } \
4041\6163\
4042 static inline zig_f##w zig_div_ceil_f##w(zig_f##w lhs, zig_f##w rhs) { \6164 static inline zig_f##w zig_divCeil_f##w(zig_f##w lhs, zig_f##w rhs) { \
4043 return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \6165 return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \
4044 } \6166 } \
4045\6167\
4046 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \6168 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \
4047 return zig_sub_f##w(lhs, zig_mul_f##w(zig_div_floor_f##w(lhs, rhs), rhs)); \6169 return zig_sub_f##w(lhs, zig_mul_f##w(zig_divFloor_f##w(lhs, rhs), rhs)); \
4048 }6170 }
4049zig_common_float_builtins(16)
4050zig_common_float_builtins(32)
4051zig_common_float_builtins(64)
4052zig_common_float_builtins(80)
4053zig_common_float_builtins(128)
4054
4055#define zig_float_builtins(w) \
4056 zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \
4057 zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \
4058 zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \
4059 zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \
4060 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \
4061 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, )
4062zig_float_builtins(16)6171zig_float_builtins(16)
4063zig_float_builtins(80)
4064zig_float_builtins(128)
4065
4066#ifdef __ARM_EABI__
4067
4068zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_f2iz(zig_f32);
4069static inline int32_t zig_fixsfsi(zig_f32 arg) { return __aeabi_f2iz(arg); }
4070
4071zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_f2uiz(zig_f32);
4072static inline uint32_t zig_fixunssfsi(zig_f32 arg) { return __aeabi_f2uiz(arg); }
4073
4074zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_f2ulz(zig_f32);
4075static inline uint64_t zig_fixunssfdi(zig_f32 arg) { return __aeabi_f2ulz(arg); }
4076
4077zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_i2f(int32_t);
4078static inline zig_f32 zig_floatsisf(int32_t arg) { return __aeabi_i2f(arg); }
4079
4080zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ui2f(uint32_t);
4081static inline zig_f32 zig_floatunsisf(uint32_t arg) { return __aeabi_ui2f(arg); }
4082
4083zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ul2f(uint64_t);
4084static inline zig_f32 zig_floatundisf(uint64_t arg) { return __aeabi_ul2f(arg); }
4085
4086zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_d2iz(zig_f64);
4087static inline int32_t zig_fixdfsi(zig_f64 arg) { return __aeabi_d2iz(arg); }
4088
4089zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_d2uiz(zig_f64);
4090static inline uint32_t zig_fixunsdfsi(zig_f64 arg) { return __aeabi_d2uiz(arg); }
4091
4092zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_d2ulz(zig_f64);
4093static inline uint64_t zig_fixunsdfdi(zig_f64 arg) { return __aeabi_d2ulz(arg); }
4094
4095zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_i2d(int32_t);
4096static inline zig_f64 zig_floatsidf(int32_t arg) { return __aeabi_i2d(arg); }
4097
4098zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ui2d(uint32_t);
4099static inline zig_f64 zig_floatunsidf(uint32_t arg) { return __aeabi_ui2d(arg); }
4100
4101zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ul2d(uint64_t);
4102static inline zig_f64 zig_floatundidf(uint64_t arg) { return __aeabi_ul2d(arg); }
4103
4104#else /* __ARM_EABI__ */
4105
4106zig_float_builtins(32)6172zig_float_builtins(32)
4107zig_float_builtins(64)6173zig_float_builtins(64)
41086174zig_float_builtins(80)
4109#endif /* __ARM_EABI__ */6175#if defined(zig_x86_32)
6176zig_common_float_builtins(128)
6177static inline zig_f128 zig_floattitf(zig_i128 arg) {
6178 extern zig_f128 __floattitf(zig_f128 arg);
6179 return __floattitf(zig_f128_bitCast_i128(arg));
6180}
6181static inline zig_f128 zig_floatuntitf(zig_u128 arg) {
6182 extern zig_f128 __floatuntitf(zig_f128 arg);
6183 return __floatuntitf(zig_f128_bitCast_u128(arg));
6184}
6185#elif defined(zig_x86_64) && defined(zig_windows)
6186zig_common_float_builtins(128)
6187static inline zig_f128 zig_floattitf(zig_i128 arg) {
6188 extern zig_f128 __floattitf(zig_i128 arg);
6189 return __floattitf(arg);
6190}
6191static inline zig_f128 zig_floatuntitf(zig_u128 arg) {
6192 extern zig_f128 __floatuntitf(uint64_t arg_lo, uint64_t arg_hi);
6193 return __floatuntitf(zig_lo_u128(arg), zig_hi_u128(arg));
6194}
6195#else
6196zig_float_builtins(128)
6197#endif
41106198
4111/* ============================ Atomics Support ============================= */6199/* ============================ Atomics Support ============================= */
41126200
...@@ -4410,19 +6498,19 @@ typedef int zig_memory_order;...@@ -4410,19 +6498,19 @@ typedef int zig_memory_order;
4410 } \6498 } \
4411 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \6499 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \
4412 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \6500 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \
4413 } \6501 } \
4414 static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \6502 static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \
4415 return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6503 return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4416 } \6504 } \
4417 static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \6505 static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \
4418 Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6506 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4419 _ReadWriteBarrier(); \6507 _ReadWriteBarrier(); \
4420 return val; \6508 return value; \
4421 } \6509 } \
4422 static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \6510 static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \
4423 Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6511 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4424 _ReadWriteBarrier(); \6512 _ReadWriteBarrier(); \
4425 return val; \6513 return value; \
4426 }6514 }
44276515
4428zig_msvc_atomics( u8, uint8_t, char, 8, 8)6516zig_msvc_atomics( u8, uint8_t, char, 8, 8)
...@@ -4465,14 +6553,14 @@ zig_msvc_atomics(i64, int64_t, __int64, 64, 64)...@@ -4465,14 +6553,14 @@ zig_msvc_atomics(i64, int64_t, __int64, 64, 64)
4465 zig_##Type result; \6553 zig_##Type result; \
4466 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6554 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4467 _ReadWriteBarrier(); \6555 _ReadWriteBarrier(); \
4468 memcpy(&result, &initial, sizeof(result)); \6556 memcpy(&result, &initial, sizeof(result)); \
4469 return result; \6557 return result; \
4470 } \6558 } \
4471 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \6559 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \
4472 zig_##Type result; \6560 zig_##Type result; \
4473 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \6561 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
4474 _ReadWriteBarrier(); \6562 _ReadWriteBarrier(); \
4475 memcpy(&result, &initial, sizeof(result)); \6563 memcpy(&result, &initial, sizeof(result)); \
4476 return result; \6564 return result; \
4477 }6565 }
44786566
...@@ -4502,9 +6590,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volat...@@ -4502,9 +6590,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volat
4502}6590}
45036591
4504static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) {6592static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) {
4505 void* val = (void*)__iso_volatile_load32(obj);6593 void* value = (void*)__iso_volatile_load32(obj);
4506 _ReadWriteBarrier();6594 _ReadWriteBarrier();
4507 return val;6595 return value;
4508}6596}
45096597
4510static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) {6598static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) {
...@@ -4532,9 +6620,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volat...@@ -4532,9 +6620,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volat
4532}6620}
45336621
4534static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) {6622static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) {
4535 void* val = (void*)__iso_volatile_load64(obj);6623 void* value = (void*)__iso_volatile_load64(obj);
4536 _ReadWriteBarrier();6624 _ReadWriteBarrier();
4537 return val;6625 return value;
4538}6626}
45396627
4540static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) {6628static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) {
stage1/zig1.wasm
Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ
test/behavior/abs.zig-2
...@@ -144,7 +144,6 @@ test "@abs big int <= 128 bits" {...@@ -144,7 +144,6 @@ test "@abs big int <= 128 bits" {
144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
145 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO145 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
146 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO146 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
147 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
148147
149 try comptime testAbsSignedBigInt();148 try comptime testAbsSignedBigInt();
150 try testAbsSignedBigInt();149 try testAbsSignedBigInt();
...@@ -256,7 +255,6 @@ fn testAbsFloats(comptime T: type) !void {...@@ -256,7 +255,6 @@ fn testAbsFloats(comptime T: type) !void {
256255
257test "@abs int vectors" {256test "@abs int vectors" {
258 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;257 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
259 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
260 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO258 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
261 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO259 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
262 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;260 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/align.zig+32-13
...@@ -129,8 +129,7 @@ test "alignment and size of structs with 128-bit fields" {...@@ -129,8 +129,7 @@ test "alignment and size of structs with 128-bit fields" {
129 y: u8,129 y: u8,
130 };130 };
131 const expected = switch (builtin.cpu.arch) {131 const expected = switch (builtin.cpu.arch) {
132 .s390x,132 .s390x => .{
133 => .{
134 .a_align = 8,133 .a_align = 8,
135 .a_size = 16,134 .a_size = 16,
136135
...@@ -142,7 +141,32 @@ test "alignment and size of structs with 128-bit fields" {...@@ -142,7 +141,32 @@ test "alignment and size of structs with 128-bit fields" {
142 .u129_align = 8,141 .u129_align = 8,
143 .u129_size = 24,142 .u129_size = 24,
144 },143 },
145144 .x86 => switch (builtin.os.tag) {
145 else => .{
146 .a_align = 4,
147 .a_size = 16,
148
149 .b_align = 4,
150 .b_size = 20,
151
152 .u128_align = 4,
153 .u128_size = 16,
154 .u129_align = 4,
155 .u129_size = 20,
156 },
157 .uefi, .windows => .{
158 .a_align = 8,
159 .a_size = 16,
160
161 .b_align = 8,
162 .b_size = 24,
163
164 .u128_align = 8,
165 .u128_size = 16,
166 .u129_align = 8,
167 .u129_size = 24,
168 },
169 },
146 .amdgcn,170 .amdgcn,
147 .arm,171 .arm,
148 .armeb,172 .armeb,
...@@ -155,12 +179,13 @@ test "alignment and size of structs with 128-bit fields" {...@@ -155,12 +179,13 @@ test "alignment and size of structs with 128-bit fields" {
155 .powerpc,179 .powerpc,
156 .powerpcle,180 .powerpcle,
157 .riscv32,181 .riscv32,
182 .sparc,
158 => .{183 => .{
159 .a_align = 8,184 .a_align = 8,
160 .a_size = 16,185 .a_size = 16,
161186
162 .b_align = 16,187 .b_align = 8,
163 .b_size = 32,188 .b_size = 24,
164189
165 .u128_align = 8,190 .u128_align = 8,
166 .u128_size = 16,191 .u128_size = 16,
...@@ -178,12 +203,10 @@ test "alignment and size of structs with 128-bit fields" {...@@ -178,12 +203,10 @@ test "alignment and size of structs with 128-bit fields" {
178 .nvptx64,203 .nvptx64,
179 .powerpc64,204 .powerpc64,
180 .powerpc64le,205 .powerpc64le,
181 .sparc,
182 .sparc64,206 .sparc64,
183 .riscv64,207 .riscv64,
184 .wasm32,208 .wasm32,
185 .wasm64,209 .wasm64,
186 .x86,
187 .x86_64,210 .x86_64,
188 => .{211 => .{
189 .a_align = 16,212 .a_align = 16,
...@@ -200,12 +223,11 @@ test "alignment and size of structs with 128-bit fields" {...@@ -200,12 +223,11 @@ test "alignment and size of structs with 128-bit fields" {
200223
201 else => return error.SkipZigTest,224 else => return error.SkipZigTest,
202 };225 };
203 const min_struct_align = if (builtin.zig_backend == .stage2_c) if (builtin.cpu.arch == .s390x) 8 else 16 else 0;
204 comptime {226 comptime {
205 assert(@alignOf(A) == @max(expected.a_align, min_struct_align));227 assert(@alignOf(A) == expected.a_align);
206 assert(@sizeOf(A) == expected.a_size);228 assert(@sizeOf(A) == expected.a_size);
207229
208 assert(@alignOf(B) == @max(expected.b_align, min_struct_align));230 assert(@alignOf(B) == expected.b_align);
209 assert(@sizeOf(B) == expected.b_size);231 assert(@sizeOf(B) == expected.b_size);
210232
211 assert(@alignOf(u128) == expected.u128_align);233 assert(@alignOf(u128) == expected.u128_align);
...@@ -547,8 +569,6 @@ test "sub-aligned pointer field access" {...@@ -547,8 +569,6 @@ test "sub-aligned pointer field access" {
547}569}
548570
549test "alignment of zero-bit types is respected" {571test "alignment of zero-bit types is respected" {
550 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
551 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
552 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;572 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
553 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO573 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
554574
...@@ -582,7 +602,6 @@ test "zero-bit fields in extern struct pad fields appropriately" {...@@ -582,7 +602,6 @@ test "zero-bit fields in extern struct pad fields appropriately" {
582 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;602 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
583 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;603 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
584 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;604 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
585 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
586605
587 const S = extern struct {606 const S = extern struct {
588 x: u8,607 x: u8,
test/behavior/basic.zig-2
...@@ -800,7 +800,6 @@ test "extern variable with non-pointer opaque type" {...@@ -800,7 +800,6 @@ test "extern variable with non-pointer opaque type" {
800 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO800 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
801 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO801 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
802 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO802 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
803 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
804 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO803 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
805804
806 @export(&var_to_export, .{ .name = "opaque_extern_var" });805 @export(&var_to_export, .{ .name = "opaque_extern_var" });
...@@ -1398,7 +1397,6 @@ test "allocation and looping over 3-byte integer" {...@@ -1398,7 +1397,6 @@ test "allocation and looping over 3-byte integer" {
1398 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1397 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1399 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1398 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1400 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1399 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1401 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag.isDarwin()) return error.SkipZigTest; // TODO
14021400
1403 try expect(@sizeOf(u24) == 4);1401 try expect(@sizeOf(u24) == 4);
1404 try expect(@sizeOf([1]u24) == 4);1402 try expect(@sizeOf([1]u24) == 4);
test/behavior/bit_shifting.zig-1
...@@ -147,7 +147,6 @@ test "Saturating Shift Left where lhs is of a computed type" {...@@ -147,7 +147,6 @@ test "Saturating Shift Left where lhs is of a computed type" {
147147
148test "Saturating Shift Left" {148test "Saturating Shift Left" {
149 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;149 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
150 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
151 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;150 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
152 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;151 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
153 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;152 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/bitcast.zig+1-6
...@@ -210,7 +210,6 @@ test "triple level result location with bitcast sandwich passed as tuple element...@@ -210,7 +210,6 @@ test "triple level result location with bitcast sandwich passed as tuple element
210210
211test "@bitCast packed struct of floats" {211test "@bitCast packed struct of floats" {
212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
213 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;213 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
215 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO214 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
216 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;215 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -247,7 +246,6 @@ test "@bitCast packed struct of floats" {...@@ -247,7 +246,6 @@ test "@bitCast packed struct of floats" {
247246
248test "comptime @bitCast packed struct to int and back" {247test "comptime @bitCast packed struct to int and back" {
249 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;248 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
250 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
251 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;249 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
252 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO250 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
253 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;251 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -283,7 +281,6 @@ test "comptime @bitCast packed struct to int and back" {...@@ -283,7 +281,6 @@ test "comptime @bitCast packed struct to int and back" {
283test "bitcast vector to integer and back" {281test "bitcast vector to integer and back" {
284 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;282 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
285 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO283 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
286 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
287 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;284 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
288 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;285 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
289286
...@@ -329,10 +326,10 @@ fn bitCastWrapper128(x: f128) u128 {...@@ -329,10 +326,10 @@ fn bitCastWrapper128(x: f128) u128 {
329}326}
330test "bitcast nan float does not modify signaling bit" {327test "bitcast nan float does not modify signaling bit" {
331 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO328 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
332 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
333 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;329 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
334 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;330 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
335 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;331 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
332 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
336333
337 const snan_u16: u16 = 0x7D00;334 const snan_u16: u16 = 0x7D00;
338 const snan_u32: u32 = 0x7FA00000;335 const snan_u32: u32 = 0x7FA00000;
...@@ -383,7 +380,6 @@ test "bitcast nan float does not modify signaling bit" {...@@ -383,7 +380,6 @@ test "bitcast nan float does not modify signaling bit" {
383test "@bitCast of packed struct of bools all true" {380test "@bitCast of packed struct of bools all true" {
384 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;381 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
385 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO382 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
386 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
387 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO383 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
388 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO384 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
389385
...@@ -404,7 +400,6 @@ test "@bitCast of packed struct of bools all true" {...@@ -404,7 +400,6 @@ test "@bitCast of packed struct of bools all true" {
404test "@bitCast of packed struct of bools all false" {400test "@bitCast of packed struct of bools all false" {
405 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;401 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
406 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO402 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
407 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
408 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO403 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
409404
410 const P = packed struct {405 const P = packed struct {
test/behavior/cast.zig+4-18
...@@ -134,7 +134,6 @@ test "@intFromFloat > 128 bits" {...@@ -134,7 +134,6 @@ test "@intFromFloat > 128 bits" {
134 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;134 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
135 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;135 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
136 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;136 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
137 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
138137
139 try testIntFromFloat(f16, 1024, u140, 1024);138 try testIntFromFloat(f16, 1024, u140, 1024);
140 try testIntFromFloat(f16, -1024, i140, -1024);139 try testIntFromFloat(f16, -1024, i140, -1024);
...@@ -160,7 +159,6 @@ test "@floatFromInt > 128 bits" {...@@ -160,7 +159,6 @@ test "@floatFromInt > 128 bits" {
160 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;159 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
161 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
162 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;161 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
163 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
164162
165 try testFloatFromInt(u140, 1024, f16, 1024);163 try testFloatFromInt(u140, 1024, f16, 1024);
166 try testFloatFromInt(i140, -1024, f16, -1024);164 try testFloatFromInt(i140, -1024, f16, -1024);
...@@ -182,8 +180,8 @@ test "@floatFromInt(f80)" {...@@ -182,8 +180,8 @@ test "@floatFromInt(f80)" {
182 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO180 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO181 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
184 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;182 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
185 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
186 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;183 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
184 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
187185
188 const S = struct {186 const S = struct {
189 fn doTheTest(comptime Int: type) !void {187 fn doTheTest(comptime Int: type) !void {
...@@ -207,7 +205,7 @@ test "@floatFromInt(f80)" {...@@ -207,7 +205,7 @@ test "@floatFromInt(f80)" {
207 try S.doTheTest(i64);205 try S.doTheTest(i64);
208 try S.doTheTest(i80);206 try S.doTheTest(i80);
209 try S.doTheTest(i128);207 try S.doTheTest(i128);
210 // try S.doTheTest(i256); // TODO missing compiler_rt symbols208 try S.doTheTest(i256);
211 try comptime S.doTheTest(i31);209 try comptime S.doTheTest(i31);
212 try comptime S.doTheTest(i32);210 try comptime S.doTheTest(i32);
213 try comptime S.doTheTest(i45);211 try comptime S.doTheTest(i45);
...@@ -281,6 +279,7 @@ test "type coercion from int to float" {...@@ -281,6 +279,7 @@ test "type coercion from int to float" {
281test "@intFromFloat" {279test "@intFromFloat" {
282 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO280 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
283 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO281 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
282
284 try testIntFromFloats();283 try testIntFromFloats();
285 try comptime testIntFromFloats();284 try comptime testIntFromFloats();
286}285}
...@@ -1473,11 +1472,6 @@ fn foobar(func: PFN_void) !void {...@@ -1473,11 +1472,6 @@ fn foobar(func: PFN_void) !void {
1473test "cast function with an opaque parameter" {1472test "cast function with an opaque parameter" {
1474 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1473 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
14751474
1476 if (builtin.zig_backend == .stage2_c) {
1477 // https://github.com/ziglang/zig/issues/16845
1478 return error.SkipZigTest;
1479 }
1480
1481 const Container = struct {1475 const Container = struct {
1482 const Ctx = opaque {};1476 const Ctx = opaque {};
1483 ctx: *Ctx,1477 ctx: *Ctx,
...@@ -1724,9 +1718,7 @@ test "cast f16 to wider types" {...@@ -1724,9 +1718,7 @@ test "cast f16 to wider types" {
1724 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1718 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1725 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1719 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1726 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1720 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1727 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1728 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1721 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1729 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
17301722
1731 const S = struct {1723 const S = struct {
1732 fn doTheTest() !void {1724 fn doTheTest() !void {
...@@ -1831,21 +1823,15 @@ test "pointer to empty struct literal to mutable slice" {...@@ -1831,21 +1823,15 @@ test "pointer to empty struct literal to mutable slice" {
18311823
1832test "coerce between pointers of compatible differently-named floats" {1824test "coerce between pointers of compatible differently-named floats" {
1833 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1825 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1834 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows and !builtin.link_libc) return error.SkipZigTest;
1835 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1826 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1836 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1827 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1837 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1828 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18381829
1839 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
1840 // https://github.com/ziglang/zig/issues/12396
1841 return error.SkipZigTest;
1842 }
1843
1844 const F = switch (@typeInfo(c_longdouble).float.bits) {1830 const F = switch (@typeInfo(c_longdouble).float.bits) {
1845 64 => f64,1831 64 => f64,
1846 80 => f80,1832 80 => f80,
1847 128 => f128,1833 128 => f128,
1848 else => @compileError("unreachable"),1834 else => comptime unreachable,
1849 };1835 };
1850 var f1: F = 12.34;1836 var f1: F = 12.34;
1851 const f2: *c_longdouble = &f1;1837 const f2: *c_longdouble = &f1;
test/behavior/cast_int.zig-1
...@@ -168,7 +168,6 @@ test "@intCast <= 64 bits" {...@@ -168,7 +168,6 @@ test "@intCast <= 64 bits" {
168168
169test "@intCast > 128 bits" {169test "@intCast > 128 bits" {
170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
171 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
172 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;171 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
173172
174 try testIntCast(u8, 123, u140, 123);173 try testIntCast(u8, 123, u140, 123);
test/behavior/eval.zig-1
...@@ -513,7 +513,6 @@ test "runtime 128 bit integer division" {...@@ -513,7 +513,6 @@ test "runtime 128 bit integer division" {
513 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO513 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
514 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO514 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
515 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;515 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
516 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
517 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;516 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
518517
519 var a: u128 = 152313999999999991610955792383;518 var a: u128 = 152313999999999991610955792383;
test/behavior/extern.zig-1
...@@ -3,7 +3,6 @@ const std = @import("std");...@@ -3,7 +3,6 @@ const std = @import("std");
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5test "anyopaque extern symbol" {5test "anyopaque extern symbol" {
6 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;6 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;7 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
98
test/behavior/field_parent_ptr.zig-3
...@@ -586,7 +586,6 @@ test "@fieldParentPtr extern struct last zero-bit field" {...@@ -586,7 +586,6 @@ test "@fieldParentPtr extern struct last zero-bit field" {
586}586}
587587
588test "@fieldParentPtr unaligned packed struct" {588test "@fieldParentPtr unaligned packed struct" {
589 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
590 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;589 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
591 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;590 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
592 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;591 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
...@@ -725,7 +724,6 @@ test "@fieldParentPtr unaligned packed struct" {...@@ -725,7 +724,6 @@ test "@fieldParentPtr unaligned packed struct" {
725}724}
726725
727test "@fieldParentPtr aligned packed struct" {726test "@fieldParentPtr aligned packed struct" {
728 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
729 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;727 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
730 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;728 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
731 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;729 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
...@@ -1897,7 +1895,6 @@ test "@fieldParentPtr packed union" {...@@ -1897,7 +1895,6 @@ test "@fieldParentPtr packed union" {
1897}1895}
18981896
1899test "@fieldParentPtr tagged union all zero-bit fields" {1897test "@fieldParentPtr tagged union all zero-bit fields" {
1900 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1901 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1898 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1902 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1899 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
19031900
test/behavior/floatop.zig+6-46
...@@ -118,7 +118,6 @@ fn testMul(comptime T: type) !void {...@@ -118,7 +118,6 @@ fn testMul(comptime T: type) !void {
118test "cmp f16" {118test "cmp f16" {
119 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO119 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
120 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;120 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
121 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
122121
123 try testCmp(f16);122 try testCmp(f16);
124 try comptime testCmp(f16);123 try comptime testCmp(f16);
...@@ -127,7 +126,6 @@ test "cmp f16" {...@@ -127,7 +126,6 @@ test "cmp f16" {
127test "cmp f32" {126test "cmp f32" {
128 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;127 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO128 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
130 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
131129
132 try testCmp(f32);130 try testCmp(f32);
133 try comptime testCmp(f32);131 try comptime testCmp(f32);
...@@ -142,7 +140,6 @@ test "cmp f64" {...@@ -142,7 +140,6 @@ test "cmp f64" {
142140
143test "cmp f128" {141test "cmp f128" {
144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO142 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
145 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
146 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;143 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
147 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;144 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
148145
...@@ -152,7 +149,6 @@ test "cmp f128" {...@@ -152,7 +149,6 @@ test "cmp f128" {
152149
153test "cmp f80/c_longdouble" {150test "cmp f80/c_longdouble" {
154 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO151 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
155 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
156 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;152 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
157 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;153 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
158154
...@@ -220,7 +216,6 @@ test "vector cmp f16" {...@@ -220,7 +216,6 @@ test "vector cmp f16" {
220 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;216 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
221 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO217 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
222 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;218 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
223 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isArm()) return error.SkipZigTest;
224 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;219 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
225220
226 try testCmpVector(f16);221 try testCmpVector(f16);
...@@ -253,7 +248,6 @@ test "vector cmp f64" {...@@ -253,7 +248,6 @@ test "vector cmp f64" {
253test "vector cmp f128" {248test "vector cmp f128" {
254 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;249 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
255 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO250 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
256 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
257 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;251 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
258 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;252 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
259 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .powerpc64le) return error.SkipZigTest;253 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .powerpc64le) return error.SkipZigTest;
...@@ -381,11 +375,7 @@ test "@sqrt f80/f128/c_longdouble" {...@@ -381,11 +375,7 @@ test "@sqrt f80/f128/c_longdouble" {
381 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO375 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
382 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;376 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
383 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;377 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
384378 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
385 if (builtin.os.tag == .freebsd) {
386 // TODO https://github.com/ziglang/zig/issues/10875
387 return error.SkipZigTest;
388 }
389379
390 try testSqrt(f80);380 try testSqrt(f80);
391 try comptime testSqrt(f80);381 try comptime testSqrt(f80);
...@@ -431,9 +421,9 @@ fn testSqrt(comptime T: type) !void {...@@ -431,9 +421,9 @@ fn testSqrt(comptime T: type) !void {
431 var inf: T = math.inf(T);421 var inf: T = math.inf(T);
432 try expect(math.isPositiveInf(@sqrt(inf)));422 try expect(math.isPositiveInf(@sqrt(inf)));
433 var zero: T = 0.0;423 var zero: T = 0.0;
434 try expect(@sqrt(zero) == 0.0);424 try expect(math.isPositiveZero(@sqrt(zero)));
435 var neg_zero: T = -0.0;425 var neg_zero: T = -0.0;
436 try expect(@sqrt(neg_zero) == 0.0);426 try expect(math.isNegativeZero(@sqrt(neg_zero)));
437 var neg_one: T = -1.0;427 var neg_one: T = -1.0;
438 try expect(math.isNan(@sqrt(neg_one)));428 try expect(math.isNan(@sqrt(neg_one)));
439 var nan: T = math.nan(T);429 var nan: T = math.nan(T);
...@@ -947,7 +937,7 @@ test "@log2 with vectors" {...@@ -947,7 +937,7 @@ test "@log2 with vectors" {
947 builtin.cpu.arch == .aarch64 and937 builtin.cpu.arch == .aarch64 and
948 builtin.os.tag == .windows) return error.SkipZigTest;938 builtin.os.tag == .windows) return error.SkipZigTest;
949939
950 if (builtin.os.tag == .windows and builtin.cpu.arch == .x86) {940 if (builtin.os.tag == .windows and builtin.cpu.arch == .x86 and builtin.abi == .msvc) {
951 // https://codeberg.org/ziglang/zig/issues/35518941 // https://codeberg.org/ziglang/zig/issues/35518
952 return error.SkipZigTest;942 return error.SkipZigTest;
953 }943 }
...@@ -1054,7 +1044,6 @@ test "@abs f32/f64" {...@@ -1054,7 +1044,6 @@ test "@abs f32/f64" {
10541044
1055test "@abs f80/f128/c_longdouble" {1045test "@abs f80/f128/c_longdouble" {
1056 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1046 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1057 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1058 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1047 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1059 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1048 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1060 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1049 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
...@@ -1172,16 +1161,10 @@ test "@floor f32/f64" {...@@ -1172,16 +1161,10 @@ test "@floor f32/f64" {
11721161
1173test "@floor f80/f128/c_longdouble" {1162test "@floor f80/f128/c_longdouble" {
1174 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1163 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1175 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1176 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1164 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1177 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1165 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1178 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1166 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11791167
1180 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
1181 // https://github.com/ziglang/zig/issues/12602
1182 return error.SkipZigTest;
1183 }
1184
1185 try testFloor(f80);1168 try testFloor(f80);
1186 try comptime testFloor(f80);1169 try comptime testFloor(f80);
1187 try testFloor(f128);1170 try testFloor(f128);
...@@ -1261,16 +1244,10 @@ test "@ceil f32/f64" {...@@ -1261,16 +1244,10 @@ test "@ceil f32/f64" {
12611244
1262test "@ceil f80/f128/c_longdouble" {1245test "@ceil f80/f128/c_longdouble" {
1263 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1246 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1264 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1265 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1247 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1266 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1248 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1267 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1249 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12681250
1269 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
1270 // https://github.com/ziglang/zig/issues/12602
1271 return error.SkipZigTest;
1272 }
1273
1274 try testCeil(f80);1251 try testCeil(f80);
1275 try comptime testCeil(f80);1252 try comptime testCeil(f80);
1276 try testCeil(f128);1253 try testCeil(f128);
...@@ -1281,16 +1258,10 @@ test "@ceil f80/f128/c_longdouble" {...@@ -1281,16 +1258,10 @@ test "@ceil f80/f128/c_longdouble" {
12811258
1282test "@ceil f80 maxInt(u64)" {1259test "@ceil f80 maxInt(u64)" {
1283 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1260 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1284 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1285 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1261 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1286 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1262 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1287 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1263 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12881264
1289 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
1290 // https://github.com/ziglang/zig/issues/12602
1291 return error.SkipZigTest;
1292 }
1293
1294 var x: u64 = std.math.maxInt(u64);1265 var x: u64 = std.math.maxInt(u64);
1295 x = x;1266 x = x;
1296 const float: f80 = @floatFromInt(x);1267 const float: f80 = @floatFromInt(x);
...@@ -1368,16 +1339,10 @@ test "@trunc f32/f64" {...@@ -1368,16 +1339,10 @@ test "@trunc f32/f64" {
13681339
1369test "@trunc f80/f128/c_longdouble" {1340test "@trunc f80/f128/c_longdouble" {
1370 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1341 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1371 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1372 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1342 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1373 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1343 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1374 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1344 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13751345
1376 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
1377 // https://github.com/ziglang/zig/issues/12602
1378 return error.SkipZigTest;
1379 }
1380
1381 try testTrunc(f80);1346 try testTrunc(f80);
1382 try comptime testTrunc(f80);1347 try comptime testTrunc(f80);
1383 try testTrunc(f128);1348 try testTrunc(f128);
...@@ -1440,11 +1405,6 @@ test "neg f16" {...@@ -1440,11 +1405,6 @@ test "neg f16" {
1440 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1441 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1406 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14421407
1443 if (builtin.os.tag == .freebsd) {
1444 // TODO file issue to track this failure
1445 return error.SkipZigTest;
1446 }
1447
1448 try testNeg(f16);1408 try testNeg(f16);
1449 try comptime testNeg(f16);1409 try comptime testNeg(f16);
1450}1410}
...@@ -1501,9 +1461,9 @@ fn testNeg(comptime T: type) !void {...@@ -1501,9 +1461,9 @@ fn testNeg(comptime T: type) !void {
15011461
1502 // subnormals1462 // subnormals
1503 var zero: T = 0.0;1463 var zero: T = 0.0;
1504 try expect(-zero == -0.0);1464 try expect(math.isNegativeZero(-zero));
1505 var neg_zero: T = -0.0;1465 var neg_zero: T = -0.0;
1506 try expect(-neg_zero == 0.0);1466 try expect(math.isPositiveZero(-neg_zero));
1507 var true_min: T = math.floatTrueMin(T);1467 var true_min: T = math.floatTrueMin(T);
1508 try expect(-true_min == -math.floatTrueMin(T));1468 try expect(-true_min == -math.floatTrueMin(T));
1509 var neg_true_min: T = -math.floatTrueMin(T);1469 var neg_true_min: T = -math.floatTrueMin(T);
test/behavior/fn.zig-1
...@@ -147,7 +147,6 @@ fn fnWithUnreachable() noreturn {...@@ -147,7 +147,6 @@ fn fnWithUnreachable() noreturn {
147147
148test "extern struct with stdcallcc fn pointer" {148test "extern struct with stdcallcc fn pointer" {
149 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;149 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
150 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch == .x86) return error.SkipZigTest;
151 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;150 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
152151
153 const S = extern struct {152 const S = extern struct {
test/behavior/math.zig-35
...@@ -873,7 +873,6 @@ test "umax wrapped squaring" {...@@ -873,7 +873,6 @@ test "umax wrapped squaring" {
873test "128-bit multiplication" {873test "128-bit multiplication" {
874 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO874 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
875 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO875 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
876 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
877 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;876 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
878877
879 {878 {
...@@ -968,7 +967,6 @@ test "@addWithOverflow > 128 bits" {...@@ -968,7 +967,6 @@ test "@addWithOverflow > 128 bits" {
968 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO967 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
969 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;968 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
970 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO969 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
971 if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest;
972970
973 try testAddWithOverflow(u129, 4, 105, 109, 0);971 try testAddWithOverflow(u129, 4, 105, 109, 0);
974 try testAddWithOverflow(u129, 1000, 100, 1100, 0);972 try testAddWithOverflow(u129, 1000, 100, 1100, 0);
...@@ -1136,7 +1134,6 @@ test "Multiply unwrap error * immediate" {...@@ -1136,7 +1134,6 @@ test "Multiply unwrap error * immediate" {
11361134
1137test "@mulWithOverflow bitsize 128 bits" {1135test "@mulWithOverflow bitsize 128 bits" {
1138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1136 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1139 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1140 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1137 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1141 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1138 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1142 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1163,7 +1160,6 @@ test "@mulWithOverflow bitsize 128 bits" {...@@ -1163,7 +1160,6 @@ test "@mulWithOverflow bitsize 128 bits" {
11631160
1164test "@mulWithOverflow > 128 bits" {1161test "@mulWithOverflow > 128 bits" {
1165 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1162 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1166 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1167 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1163 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
11681164
1169 try testMulWithOverflow(u140, 0, maxInt(u140), 0, 0);1165 try testMulWithOverflow(u140, 0, maxInt(u140), 0, 0);
...@@ -1193,7 +1189,6 @@ test "@mulWithOverflow > 128 bits" {...@@ -1193,7 +1189,6 @@ test "@mulWithOverflow > 128 bits" {
11931189
1194test "@mulWithOverflow bitsize 256 bits" {1190test "@mulWithOverflow bitsize 256 bits" {
1195 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1191 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1196 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1197 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1192 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1198 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1193 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11991194
...@@ -1298,7 +1293,6 @@ test "@subWithOverflow > 128 bits" {...@@ -1298,7 +1293,6 @@ test "@subWithOverflow > 128 bits" {
1298 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1293 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1299 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1294 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1300 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO1295 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1301 if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest;
13021296
1303 try testSubWithOverflow(u129, 4, 105, maxInt(u129) - 100, 1);1297 try testSubWithOverflow(u129, 4, 105, maxInt(u129) - 100, 1);
1304 try testSubWithOverflow(u129, 1000, 100, 900, 0);1298 try testSubWithOverflow(u129, 1000, 100, 900, 0);
...@@ -1389,7 +1383,6 @@ test "@shlWithOverflow > 64 bits" {...@@ -1389,7 +1383,6 @@ test "@shlWithOverflow > 64 bits" {
13891383
1390test "@shlWithOverflow > 128 bits" {1384test "@shlWithOverflow > 128 bits" {
1391 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1385 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1392 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1393 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1386 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
13941387
1395 try testShlWithOverflow(u140, 1 << 100, 20, 1 << 120, 0);1388 try testShlWithOverflow(u140, 1 << 100, 20, 1 << 120, 0);
...@@ -1419,7 +1412,6 @@ fn testAnd(comptime T: type, a: T, b: T, expected: T) !void {...@@ -1419,7 +1412,6 @@ fn testAnd(comptime T: type, a: T, b: T, expected: T) !void {
14191412
1420test "and > 128 bits" {1413test "and > 128 bits" {
1421 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1414 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1422 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
14231415
1424 try testAnd(u140, (1 << 139) | (1 << 70) | 0xaa, (1 << 139) | (1 << 69) | 0xcc, (1 << 139) | 0x88);1416 try testAnd(u140, (1 << 139) | (1 << 70) | 0xaa, (1 << 139) | (1 << 69) | 0xcc, (1 << 139) | 0x88);
1425 try testAnd(u140, maxInt(u140), 1 << 100, 1 << 100);1417 try testAnd(u140, maxInt(u140), 1 << 100, 1 << 100);
...@@ -1448,7 +1440,6 @@ fn testOr(comptime T: type, a: T, b: T, expected: T) !void {...@@ -1448,7 +1440,6 @@ fn testOr(comptime T: type, a: T, b: T, expected: T) !void {
14481440
1449test "or > 128 bits" {1441test "or > 128 bits" {
1450 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1442 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1451 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
14521443
1453 try testOr(u140, 0, 1 << 139, 1 << 139);1444 try testOr(u140, 0, 1 << 139, 1 << 139);
1454 try testOr(u140, (1 << 70) | 0xa, (1 << 69) | 0x5, (1 << 70) | (1 << 69) | 0xf);1445 try testOr(u140, (1 << 70) | 0xa, (1 << 69) | 0x5, (1 << 70) | (1 << 69) | 0xf);
...@@ -1477,7 +1468,6 @@ fn testXor(comptime T: type, a: T, b: T, expected: T) !void {...@@ -1477,7 +1468,6 @@ fn testXor(comptime T: type, a: T, b: T, expected: T) !void {
14771468
1478test "xor > 128 bits" {1469test "xor > 128 bits" {
1479 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1470 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1480 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
14811471
1482 try testXor(u140, 0, maxInt(u140), maxInt(u140));1472 try testXor(u140, 0, maxInt(u140), maxInt(u140));
1483 try testXor(u140, 1 << 139, 1 << 139, 0);1473 try testXor(u140, 1 << 139, 1 << 139, 0);
...@@ -1506,7 +1496,6 @@ fn testNot(comptime T: type, a: T, expected: T) !void {...@@ -1506,7 +1496,6 @@ fn testNot(comptime T: type, a: T, expected: T) !void {
15061496
1507test "not > 128 bits" {1497test "not > 128 bits" {
1508 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1498 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1509 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
15101499
1511 try testNot(u140, 0, maxInt(u140));1500 try testNot(u140, 0, maxInt(u140));
1512 try testNot(u140, maxInt(u140), 0);1501 try testNot(u140, maxInt(u140), 0);
...@@ -1535,7 +1524,6 @@ fn testShl(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void {...@@ -1535,7 +1524,6 @@ fn testShl(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void {
15351524
1536test "shl > 128 bits" {1525test "shl > 128 bits" {
1537 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1526 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1538 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
15391527
1540 try testShl(u140, 1 << 5, 10, 1 << 15);1528 try testShl(u140, 1 << 5, 10, 1 << 15);
1541 try testShl(u140, 3, 138, (1 << 139) | (1 << 138));1529 try testShl(u140, 3, 138, (1 << 139) | (1 << 138));
...@@ -1564,7 +1552,6 @@ fn testShr(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void {...@@ -1564,7 +1552,6 @@ fn testShr(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void {
15641552
1565test "shr > 128 bits" {1553test "shr > 128 bits" {
1566 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1554 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1567 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
15681555
1569 try testShr(u140, 1 << 139, 39, 1 << 100);1556 try testShr(u140, 1 << 139, 39, 1 << 100);
1570 try testShr(u140, (1 << 70) | 8, 3, (1 << 67) | 1);1557 try testShr(u140, (1 << 70) | 8, 3, (1 << 67) | 1);
...@@ -1593,7 +1580,6 @@ fn testClz(comptime T: type, a: T, expected: u16) !void {...@@ -1593,7 +1580,6 @@ fn testClz(comptime T: type, a: T, expected: u16) !void {
15931580
1594test "@clz > 128 bits" {1581test "@clz > 128 bits" {
1595 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1582 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1596 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1597 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1583 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
15981584
1599 try testClz(u140, 0, 140);1585 try testClz(u140, 0, 140);
...@@ -1623,7 +1609,6 @@ fn testCtz(comptime T: type, a: T, expected: u16) !void {...@@ -1623,7 +1609,6 @@ fn testCtz(comptime T: type, a: T, expected: u16) !void {
16231609
1624test "@ctz > 128 bits" {1610test "@ctz > 128 bits" {
1625 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1611 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1626 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1627 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1612 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
16281613
1629 try testCtz(u140, 0, 140);1614 try testCtz(u140, 0, 140);
...@@ -1653,7 +1638,6 @@ fn testPopCount(comptime T: type, a: T, expected: u16) !void {...@@ -1653,7 +1638,6 @@ fn testPopCount(comptime T: type, a: T, expected: u16) !void {
16531638
1654test "@popCount > 128 bits" {1639test "@popCount > 128 bits" {
1655 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1640 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1656 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1657 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1641 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
16581642
1659 try testPopCount(u140, 0, 0);1643 try testPopCount(u140, 0, 0);
...@@ -1683,7 +1667,6 @@ fn testBitReverse(comptime T: type, a: T, expected: T) !void {...@@ -1683,7 +1667,6 @@ fn testBitReverse(comptime T: type, a: T, expected: T) !void {
16831667
1684test "@bitReverse > 128 bits" {1668test "@bitReverse > 128 bits" {
1685 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1669 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1686 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1687 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1670 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
16881671
1689 try testBitReverse(u140, 1 << 139, 1);1672 try testBitReverse(u140, 1 << 139, 1);
...@@ -1713,7 +1696,6 @@ fn testByteSwap(comptime T: type, a: T, expected: T) !void {...@@ -1713,7 +1696,6 @@ fn testByteSwap(comptime T: type, a: T, expected: T) !void {
17131696
1714test "@byteSwap > 128 bits" {1697test "@byteSwap > 128 bits" {
1715 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1698 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1716 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1717 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1699 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
17181700
1719 try testByteSwap(u144, 1 << 136, 1);1701 try testByteSwap(u144, 1 << 136, 1);
...@@ -1743,7 +1725,6 @@ fn testMax(comptime T: type, a: T, b: T, expected: T) !void {...@@ -1743,7 +1725,6 @@ fn testMax(comptime T: type, a: T, b: T, expected: T) !void {
17431725
1744test "@max > 128 bits" {1726test "@max > 128 bits" {
1745 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1727 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1746 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1747 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1728 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
17481729
1749 try testMax(u140, 0, maxInt(u140), maxInt(u140));1730 try testMax(u140, 0, maxInt(u140), maxInt(u140));
...@@ -1773,7 +1754,6 @@ fn testMin(comptime T: type, a: T, b: T, expected: T) !void {...@@ -1773,7 +1754,6 @@ fn testMin(comptime T: type, a: T, b: T, expected: T) !void {
17731754
1774test "@min > 128 bits" {1755test "@min > 128 bits" {
1775 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1756 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1776 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1777 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1757 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
17781758
1779 try testMin(u140, 0, maxInt(u140), 0);1759 try testMin(u140, 0, maxInt(u140), 0);
...@@ -1803,7 +1783,6 @@ fn testAbs(comptime T: type, a: T, expected: anytype) !void {...@@ -1803,7 +1783,6 @@ fn testAbs(comptime T: type, a: T, expected: anytype) !void {
18031783
1804test "@abs > 128 bits" {1784test "@abs > 128 bits" {
1805 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1785 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1806 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
18071786
1808 try testAbs(u140, 0, 0);1787 try testAbs(u140, 0, 0);
1809 try testAbs(u140, 1 << 139, 1 << 139);1788 try testAbs(u140, 1 << 139, 1 << 139);
...@@ -1827,7 +1806,6 @@ fn testRem(comptime T: type, numerator: T, denominator: T, expected: T) !void {...@@ -1827,7 +1806,6 @@ fn testRem(comptime T: type, numerator: T, denominator: T, expected: T) !void {
18271806
1828test "@rem > 128 bits" {1807test "@rem > 128 bits" {
1829 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1808 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1830 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1831 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1809 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
18321810
1833 try testRem(u140, 0, maxInt(u140), 0);1811 try testRem(u140, 0, maxInt(u140), 0);
...@@ -1855,7 +1833,6 @@ fn testMod(comptime T: type, numerator: T, denominator: T, expected: T) !void {...@@ -1855,7 +1833,6 @@ fn testMod(comptime T: type, numerator: T, denominator: T, expected: T) !void {
18551833
1856test "@mod > 128 bits" {1834test "@mod > 128 bits" {
1857 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1835 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1858 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1859 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1836 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
18601837
1861 try testMod(u140, 0, maxInt(u140), 0);1838 try testMod(u140, 0, maxInt(u140), 0);
...@@ -1883,7 +1860,6 @@ fn testDivFloor(comptime T: type, numerator: T, denominator: T, expected: T) !vo...@@ -1883,7 +1860,6 @@ fn testDivFloor(comptime T: type, numerator: T, denominator: T, expected: T) !vo
18831860
1884test "@divFloor > 128 bits" {1861test "@divFloor > 128 bits" {
1885 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1862 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1886 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1887 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1863 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
18881864
1889 try testDivFloor(u140, 0, maxInt(u140), 0);1865 try testDivFloor(u140, 0, maxInt(u140), 0);
...@@ -1912,7 +1888,6 @@ fn testDivCeil(comptime T: type, numerator: T, denominator: T, expected: T) !voi...@@ -1912,7 +1888,6 @@ fn testDivCeil(comptime T: type, numerator: T, denominator: T, expected: T) !voi
19121888
1913test "@divCeil > 128 bits" {1889test "@divCeil > 128 bits" {
1914 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1890 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1915 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1916 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1891 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
19171892
1918 try testDivCeil(u140, 0, maxInt(u140), 0);1893 try testDivCeil(u140, 0, maxInt(u140), 0);
...@@ -1941,7 +1916,6 @@ fn testDivTrunc(comptime T: type, numerator: T, denominator: T, expected: T) !vo...@@ -1941,7 +1916,6 @@ fn testDivTrunc(comptime T: type, numerator: T, denominator: T, expected: T) !vo
19411916
1942test "@divTrunc > 128 bits" {1917test "@divTrunc > 128 bits" {
1943 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1918 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1944 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1945 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1919 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
19461920
1947 try testDivTrunc(u140, 0, maxInt(u140), 0);1921 try testDivTrunc(u140, 0, maxInt(u140), 0);
...@@ -2166,14 +2140,8 @@ test "remainder division" {...@@ -2166,14 +2140,8 @@ test "remainder division" {
2166 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO2140 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2167 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2168 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;2142 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2169 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
2170 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;2143 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21712144
2172 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
2173 // https://github.com/ziglang/zig/issues/12602
2174 return error.SkipZigTest;
2175 }
2176
2177 if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;2145 if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;
21782146
2179 try comptime remdiv(f16);2147 try comptime remdiv(f16);
...@@ -2315,7 +2283,6 @@ test "@round f80" {...@@ -2315,7 +2283,6 @@ test "@round f80" {
2315 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO2283 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2316 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2284 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2317 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;2285 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2318 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
2319 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;2286 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
23202287
2321 try testRound(f80, 12.0);2288 try testRound(f80, 12.0);
...@@ -2326,7 +2293,6 @@ test "@round f128" {...@@ -2326,7 +2293,6 @@ test "@round f128" {
2326 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO2293 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2327 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2294 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2328 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;2295 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2329 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
2330 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;2296 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
23312297
2332 try testRound(f128, 12.0);2298 try testRound(f128, 12.0);
...@@ -2366,7 +2332,6 @@ test "NaN comparison" {...@@ -2366,7 +2332,6 @@ test "NaN comparison" {
2366 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2332 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2367 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;2333 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2368 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;2334 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2369 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
23702335
2371 try testNanEqNan(f16);2336 try testNanEqNan(f16);
2372 try testNanEqNan(f32);2337 try testNanEqNan(f32);
test/behavior/maximum_minimum.zig-1
...@@ -115,7 +115,6 @@ test "@min/max for floats" {...@@ -115,7 +115,6 @@ test "@min/max for floats" {
115 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO115 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
116 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO116 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
117 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;117 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
118 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
119 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;118 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
120119
121 const S = struct {120 const S = struct {
test/behavior/muladd.zig-4
...@@ -49,7 +49,6 @@ test "@mulAdd f80" {...@@ -49,7 +49,6 @@ test "@mulAdd f80" {
49 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO49 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO50 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;51 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
52 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
53 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;52 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5453
55 try comptime testMulAdd80();54 try comptime testMulAdd80();
...@@ -68,7 +67,6 @@ test "@mulAdd f128" {...@@ -68,7 +67,6 @@ test "@mulAdd f128" {
68 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO67 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
69 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO68 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;69 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
71 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
72 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;70 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7371
74 try comptime testMulAdd128();72 try comptime testMulAdd128();
...@@ -169,7 +167,6 @@ test "vector f80" {...@@ -169,7 +167,6 @@ test "vector f80" {
169 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO167 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
170 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO168 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
171 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;169 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
172 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
173 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;170 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
174171
175 try comptime vector80();172 try comptime vector80();
...@@ -194,7 +191,6 @@ test "vector f128" {...@@ -194,7 +191,6 @@ test "vector f128" {
194 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO191 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
195 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO192 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
196 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;193 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
197 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
198 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;194 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
199195
200 try comptime vector128();196 try comptime vector128();
test/behavior/packed-struct.zig-4
...@@ -404,7 +404,6 @@ test "nested packed struct field pointers" {...@@ -404,7 +404,6 @@ test "nested packed struct field pointers" {
404 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;404 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
406 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;406 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
407 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // ubsan unaligned pointer access
408 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO407 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
409 const S2 = packed struct {408 const S2 = packed struct {
410 base: u8,409 base: u8,
...@@ -579,7 +578,6 @@ test "packed struct fields modification" {...@@ -579,7 +578,6 @@ test "packed struct fields modification" {
579}578}
580579
581test "nested packed struct field access test" {580test "nested packed struct field access test" {
582 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
583 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO581 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
584 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO582 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
585 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;583 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -733,7 +731,6 @@ test "nested packed struct at non-zero offset 2" {...@@ -733,7 +731,6 @@ test "nested packed struct at non-zero offset 2" {
733 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;731 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
734 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO732 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
735 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;733 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
736 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
737 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;734 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
738735
739 const S = struct {736 const S = struct {
...@@ -1171,7 +1168,6 @@ test "packed struct equality" {...@@ -1171,7 +1168,6 @@ test "packed struct equality" {
11711168
1172test "packed struct equality ignores padding bits" {1169test "packed struct equality ignores padding bits" {
1173 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1174 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1175 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1171 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
11761172
1177 const S = packed struct { b: bool };1173 const S = packed struct { b: bool };
test/behavior/pointers.zig+1-1
...@@ -275,7 +275,7 @@ test "compare equality of optional and non-optional pointer" {...@@ -275,7 +275,7 @@ test "compare equality of optional and non-optional pointer" {
275}275}
276276
277test "allowzero pointer and slice" {277test "allowzero pointer and slice" {
278 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO278 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
279 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;279 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
280 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO280 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
281 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;281 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
test/behavior/saturating_arithmetic.zig-7
...@@ -144,7 +144,6 @@ test "saturating multiplication <= 32 bits" {...@@ -144,7 +144,6 @@ test "saturating multiplication <= 32 bits" {
144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
145 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO145 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
146 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;146 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
147 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
148 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;147 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
149148
150 try testSatMul(u8, 0, maxInt(u8), 0);149 try testSatMul(u8, 0, maxInt(u8), 0);
...@@ -238,7 +237,6 @@ test "saturating multiplication" {...@@ -238,7 +237,6 @@ test "saturating multiplication" {
238 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO237 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
239 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO238 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
240 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;239 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
241 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
242 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;240 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
243241
244 const S = struct {242 const S = struct {
...@@ -313,7 +311,6 @@ test "saturating shift-left" {...@@ -313,7 +311,6 @@ test "saturating shift-left" {
313311
314test "saturating shift-left large rhs" {312test "saturating shift-left large rhs" {
315 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;313 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
316 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
317 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;314 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
318 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;315 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
319 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;316 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
...@@ -361,7 +358,6 @@ test "saturating shl uses the LHS type" {...@@ -361,7 +358,6 @@ test "saturating shl uses the LHS type" {
361358
362test "sat add > 128 bits" {359test "sat add > 128 bits" {
363 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;360 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
364 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
365 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;361 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
366362
367 try testSatAdd(u140, 0, 0, 0);363 try testSatAdd(u140, 0, 0, 0);
...@@ -377,7 +373,6 @@ test "sat add > 128 bits" {...@@ -377,7 +373,6 @@ test "sat add > 128 bits" {
377373
378test "sat sub > 128 bits" {374test "sat sub > 128 bits" {
379 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;375 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
380 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
381 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;376 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
382377
383 try testSatSub(u140, 0, 1, 0);378 try testSatSub(u140, 0, 1, 0);
...@@ -393,7 +388,6 @@ test "sat sub > 128 bits" {...@@ -393,7 +388,6 @@ test "sat sub > 128 bits" {
393388
394test "sat mul > 128 bits" {389test "sat mul > 128 bits" {
395 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;390 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
396 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
397 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;391 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
398392
399 try testSatMul(u140, 0, maxInt(u140), 0);393 try testSatMul(u140, 0, maxInt(u140), 0);
...@@ -409,7 +403,6 @@ test "sat mul > 128 bits" {...@@ -409,7 +403,6 @@ test "sat mul > 128 bits" {
409403
410test "sat shl > 128 bits" {404test "sat shl > 128 bits" {
411 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;405 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
412 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
413 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;406 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
414407
415 try testSatShl(u140, 0, u8, 17, 0);408 try testSatShl(u140, 0, u8, 17, 0);
test/behavior/struct.zig+2-6
...@@ -535,7 +535,6 @@ test "zero-bit field in packed struct" {...@@ -535,7 +535,6 @@ test "zero-bit field in packed struct" {
535test "packed struct with non-ABI-aligned field" {535test "packed struct with non-ABI-aligned field" {
536 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;536 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
537 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO537 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
538 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
539 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO538 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
540 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;539 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
541 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;540 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
...@@ -792,7 +791,6 @@ test "non-packed struct with u128 entry in union" {...@@ -792,7 +791,6 @@ test "non-packed struct with u128 entry in union" {
792 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO791 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
793 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO792 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
794 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;793 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
795 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
796 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;794 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
797795
798 const U = union(enum) {796 const U = union(enum) {
...@@ -1539,7 +1537,6 @@ test "instantiate struct with comptime field" {...@@ -1539,7 +1537,6 @@ test "instantiate struct with comptime field" {
1539}1537}
15401538
1541test "struct field pointer has correct alignment" {1539test "struct field pointer has correct alignment" {
1542 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1543 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1540 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1544 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1541 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1545 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1542 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -1569,7 +1566,6 @@ test "struct field pointer has correct alignment" {...@@ -1569,7 +1566,6 @@ test "struct field pointer has correct alignment" {
1569}1566}
15701567
1571test "extern struct field pointer has correct alignment" {1568test "extern struct field pointer has correct alignment" {
1572 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1573 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1569 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1574 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1570 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1575 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1571 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -2007,7 +2003,6 @@ test "initiate global variable with runtime value" {...@@ -2007,7 +2003,6 @@ test "initiate global variable with runtime value" {
2007}2003}
20082004
2009test "struct containing optional pointer to array of @This()" {2005test "struct containing optional pointer to array of @This()" {
2010 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2011 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;2006 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
20122007
2013 const S = struct {2008 const S = struct {
...@@ -2266,7 +2261,8 @@ test "struct contains aligned pointer to itself through type decl" {...@@ -2266,7 +2261,8 @@ test "struct contains aligned pointer to itself through type decl" {
22662261
2267test "struct contains underaligned field with overaligned pointer to itself" {2262test "struct contains underaligned field with overaligned pointer to itself" {
2268 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;2263 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2269 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO2264 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2265
2270 const S = struct {2266 const S = struct {
2271 ptr: *align(8) @This() align(1),2267 ptr: *align(8) @This() align(1),
2272 };2268 };
test/behavior/switch.zig+1-1
...@@ -1267,7 +1267,7 @@ test "switch with complex item expressions" {...@@ -1267,7 +1267,7 @@ test "switch with complex item expressions" {
1267test "switch evaluation order" {1267test "switch evaluation order" {
1268 const eu: anyerror!u32 = 0;1268 const eu: anyerror!u32 = 0;
1269 _ = eu catch |err| switch (err) {1269 _ = eu catch |err| switch (err) {
1270 if (true) @compileError("unreachable") => unreachable,1270 if (true) comptime unreachable => unreachable,
1271 else => unreachable,1271 else => unreachable,
1272 };1272 };
1273}1273}
test/behavior/switch_loop.zig+1-2
...@@ -223,7 +223,6 @@ test "unanalyzed continue with operand" {...@@ -223,7 +223,6 @@ test "unanalyzed continue with operand" {
223223
224test "switch loop on larger than pointer integer" {224test "switch loop on larger than pointer integer" {
225 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;225 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
226 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
227 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;226 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
228227
229 var entry: @Int(.unsigned, @bitSizeOf(usize) + 1) = undefined;228 var entry: @Int(.unsigned, @bitSizeOf(usize) + 1) = undefined;
...@@ -268,7 +267,7 @@ test "switch loop on non-exhaustive enum" {...@@ -268,7 +267,7 @@ test "switch loop on non-exhaustive enum" {
268267
269test "switch loop with discarded tag capture" {268test "switch loop with discarded tag capture" {
270 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;269 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
271 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;270
272 const S = struct {271 const S = struct {
273 const U = union(enum) {272 const U = union(enum) {
274 a: u32,273 a: u32,
test/behavior/switch_on_captured_error.zig+3-3
...@@ -243,7 +243,7 @@ test "switch on error union catch capture" {...@@ -243,7 +243,7 @@ test "switch on error union catch capture" {
243 var a: error{}!u64 = 0;243 var a: error{}!u64 = 0;
244 _ = &a;244 _ = &a;
245 const b = a catch |err| switch (err) {245 const b = a catch |err| switch (err) {
246 undefined => @compileError("unreachable"),246 undefined => comptime unreachable,
247 };247 };
248 try expectEqual(@as(u64, 0), b);248 try expectEqual(@as(u64, 0), b);
249 }249 }
...@@ -829,7 +829,7 @@ test "switch on error union if else capture" {...@@ -829,7 +829,7 @@ test "switch on error union if else capture" {
829 var a: error{}!u64 = 0;829 var a: error{}!u64 = 0;
830 _ = &a;830 _ = &a;
831 const b = if (a) |x| x else |err| switch (err) {831 const b = if (a) |x| x else |err| switch (err) {
832 undefined => @compileError("unreachable"),832 undefined => comptime unreachable,
833 };833 };
834 try expectEqual(@as(u64, 0), b);834 try expectEqual(@as(u64, 0), b);
835 }835 }
...@@ -840,7 +840,7 @@ test "switch on error union if else capture" {...@@ -840,7 +840,7 @@ test "switch on error union if else capture" {
840 var a: error{}!u64 = 0;840 var a: error{}!u64 = 0;
841 _ = &a;841 _ = &a;
842 const b = if (a) |*x| x.* else |err| switch (err) {842 const b = if (a) |*x| x.* else |err| switch (err) {
843 undefined => @compileError("unreachable"),843 undefined => comptime unreachable,
844 };844 };
845 try expectEqual(@as(u64, 0), b);845 try expectEqual(@as(u64, 0), b);
846 }846 }
test/behavior/threadlocal.zig-5
...@@ -9,11 +9,6 @@ test "thread local variable" {...@@ -9,11 +9,6 @@ test "thread local variable" {
9 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1111
12 if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag.isDarwin()) {
13 // Fails due to register hazards.
14 return error.SkipZigTest;
15 }
16
17 const S = struct {12 const S = struct {
18 threadlocal var t: i32 = 1234;13 threadlocal var t: i32 = 1234;
19 };14 };
test/behavior/truncate.zig-1
...@@ -49,7 +49,6 @@ fn testTruncate(comptime S: type, a: S, comptime D: type, expected: D) !void {...@@ -49,7 +49,6 @@ fn testTruncate(comptime S: type, a: S, comptime D: type, expected: D) !void {
4949
50test "@truncate > 128 bits" {50test "@truncate > 128 bits" {
51 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;51 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
52 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
53 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;52 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
5453
55 try testTruncate(u140, 0, u128, 0);54 try testTruncate(u140, 0, u128, 0);
test/behavior/union.zig+4-8
...@@ -1437,7 +1437,6 @@ test "coerce enum literal to union in result loc" {...@@ -1437,7 +1437,6 @@ test "coerce enum literal to union in result loc" {
1437}1437}
14381438
1439test "defined-layout union field pointer has correct alignment" {1439test "defined-layout union field pointer has correct alignment" {
1440 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1441 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1440 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1442 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1441 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1443 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1442 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -1472,7 +1471,6 @@ test "defined-layout union field pointer has correct alignment" {...@@ -1472,7 +1471,6 @@ test "defined-layout union field pointer has correct alignment" {
1472}1471}
14731472
1474test "undefined-layout union field pointer has correct alignment" {1473test "undefined-layout union field pointer has correct alignment" {
1475 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1476 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1474 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1477 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1475 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1478 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1476 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -1611,6 +1609,10 @@ fn littleToNativeEndian(comptime T: type, v: T) T {...@@ -1611,6 +1609,10 @@ fn littleToNativeEndian(comptime T: type, v: T) T {
1611}1609}
16121610
1613test "reinterpret extern union" {1611test "reinterpret extern union" {
1612 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
1613 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isRiscv32() and builtin.link_libc) return error.SkipZigTest;
1614 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isWasm()) return error.SkipZigTest;
1615
1614 if (true) {1616 if (true) {
1615 // https://github.com/ziglang/zig/issues/193891617 // https://github.com/ziglang/zig/issues/19389
1616 return error.SkipZigTest;1618 return error.SkipZigTest;
...@@ -1678,8 +1680,6 @@ test "reinterpret extern union" {...@@ -1678,8 +1680,6 @@ test "reinterpret extern union" {
1678 };1680 };
16791681
1680 try comptime S.doTheTest();1682 try comptime S.doTheTest();
1681
1682 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
1683 try S.doTheTest();1683 try S.doTheTest();
1684}1684}
16851685
...@@ -1758,8 +1758,6 @@ test "reinterpret packed union" {...@@ -1758,8 +1758,6 @@ test "reinterpret packed union" {
1758 };1758 };
17591759
1760 try comptime S.doTheTest();1760 try comptime S.doTheTest();
1761
1762 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1763 try S.doTheTest();1761 try S.doTheTest();
1764}1762}
17651763
...@@ -1800,8 +1798,6 @@ test "reinterpret packed union inside packed struct" {...@@ -1800,8 +1798,6 @@ test "reinterpret packed union inside packed struct" {
1800 };1798 };
18011799
1802 try comptime S.doTheTest();1800 try comptime S.doTheTest();
1803
1804 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1805 try S.doTheTest();1801 try S.doTheTest();
1806}1802}
18071803
test/behavior/vector.zig+19-18
...@@ -128,13 +128,6 @@ test "vector float operators" {...@@ -128,13 +128,6 @@ test "vector float operators" {
128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
130 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;130 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
131 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
132
133 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
134 // Triggers an assertion with LLVM 18:
135 // https://github.com/ziglang/zig/issues/20680
136 return error.SkipZigTest;
137 }
138131
139 const S = struct {132 const S = struct {
140 fn doTheTest(T: type) !void {133 fn doTheTest(T: type) !void {
...@@ -280,7 +273,6 @@ test "array to vector with element type coercion" {...@@ -280,7 +273,6 @@ test "array to vector with element type coercion" {
280 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO273 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
281 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;274 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
282 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;275 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
283 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
284276
285 const S = struct {277 const S = struct {
286 fn doTheTest() !void {278 fn doTheTest() !void {
...@@ -736,9 +728,7 @@ test "vector reduce operation" {...@@ -736,9 +728,7 @@ test "vector reduce operation" {
736 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO728 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
737 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO729 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
738 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;730 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
739 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
740 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;731 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
741 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/195562
742732
743 const S = struct {733 const S = struct {
744 fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void {734 fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void {
...@@ -776,6 +766,8 @@ test "vector reduce operation" {...@@ -776,6 +766,8 @@ test "vector reduce operation" {
776 try testReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9));766 try testReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9));
777 try testReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9));767 try testReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9));
778 try testReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9));768 try testReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9));
769 try testReduce(.Add, [4]f80{ -1.9, 5.1, -60.3, 100.0 }, @as(f80, 42.9));
770 try testReduce(.Add, [4]f128{ -1.9, 5.1, -60.3, 100.0 }, @as(f128, 42.9));
779771
780 try testReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false));772 try testReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false));
781 try testReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0));773 try testReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0));
...@@ -794,6 +786,8 @@ test "vector reduce operation" {...@@ -794,6 +786,8 @@ test "vector reduce operation" {
794 try testReduce(.Min, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, -100.0));786 try testReduce(.Min, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, -100.0));
795 try testReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0));787 try testReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0));
796 try testReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0));788 try testReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0));
789 try testReduce(.Min, [4]f80{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f80, -100.0));
790 try testReduce(.Min, [4]f128{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f128, -100.0));
797791
798 try testReduce(.Max, [4]i16{ -1, 2, 3, 4 }, @as(i16, 4));792 try testReduce(.Max, [4]i16{ -1, 2, 3, 4 }, @as(i16, 4));
799 try testReduce(.Max, [4]u16{ 1, 2, 3, 4 }, @as(u16, 4));793 try testReduce(.Max, [4]u16{ 1, 2, 3, 4 }, @as(u16, 4));
...@@ -806,6 +800,8 @@ test "vector reduce operation" {...@@ -806,6 +800,8 @@ test "vector reduce operation" {
806 try testReduce(.Max, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, 10.0e9));800 try testReduce(.Max, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, 10.0e9));
807 try testReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9));801 try testReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9));
808 try testReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9));802 try testReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9));
803 try testReduce(.Max, [4]f80{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f80, 10.0e9));
804 try testReduce(.Max, [4]f128{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f128, 10.0e9));
809805
810 try testReduce(.Mul, [4]i16{ -1, 2, 3, 4 }, @as(i16, -24));806 try testReduce(.Mul, [4]i16{ -1, 2, 3, 4 }, @as(i16, -24));
811 try testReduce(.Mul, [4]u16{ 1, 2, 3, 4 }, @as(u16, 24));807 try testReduce(.Mul, [4]u16{ 1, 2, 3, 4 }, @as(u16, 24));
...@@ -818,6 +814,8 @@ test "vector reduce operation" {...@@ -818,6 +814,8 @@ test "vector reduce operation" {
818 try testReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7));814 try testReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7));
819 try testReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7));815 try testReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7));
820 try testReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7));816 try testReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7));
817 try testReduce(.Mul, [4]f80{ -1.9, 5.1, -60.3, 100.0 }, @as(f80, 58430.7));
818 try testReduce(.Mul, [4]f128{ -1.9, 5.1, -60.3, 100.0 }, @as(f128, 58430.7));
821819
822 try testReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true));820 try testReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true));
823 try testReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1));821 try testReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1));
...@@ -825,6 +823,7 @@ test "vector reduce operation" {...@@ -825,6 +823,7 @@ test "vector reduce operation" {
825 try testReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0));823 try testReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0));
826 try testReduce(.Or, [4]u64{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u64, 0xffffffff));824 try testReduce(.Or, [4]u64{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u64, 0xffffffff));
827 try testReduce(.Or, [4]u128{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u128, 0xffffffff));825 try testReduce(.Or, [4]u128{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u128, 0xffffffff));
826 try testReduce(.Or, [4]u80{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u80, 0xffffffff));
828827
829 try testReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true));828 try testReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true));
830 try testReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1));829 try testReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1));
...@@ -837,22 +836,32 @@ test "vector reduce operation" {...@@ -837,22 +836,32 @@ test "vector reduce operation" {
837 const f16_nan = math.nan(f16);836 const f16_nan = math.nan(f16);
838 const f32_nan = math.nan(f32);837 const f32_nan = math.nan(f32);
839 const f64_nan = math.nan(f64);838 const f64_nan = math.nan(f64);
839 const f80_nan = math.nan(f80);
840 const f128_nan = math.nan(f128);
840841
841 try testReduce(.Add, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);842 try testReduce(.Add, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);
842 try testReduce(.Add, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);843 try testReduce(.Add, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);
843 try testReduce(.Add, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);844 try testReduce(.Add, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);
845 try testReduce(.Add, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, f80_nan);
846 try testReduce(.Add, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, f128_nan);
844847
845 try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, -1.9));848 try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, -1.9));
846 try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, -1.9));849 try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, -1.9));
847 try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, -1.9));850 try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, -1.9));
851 try testReduce(.Min, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, @as(f80, -1.9));
852 try testReduce(.Min, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, @as(f128, -1.9));
848853
849 try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, 100.0));854 try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, 100.0));
850 try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, 100.0));855 try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, 100.0));
851 try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, 100.0));856 try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, 100.0));
857 try testReduce(.Max, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, @as(f80, 100.0));
858 try testReduce(.Max, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, @as(f128, 100.0));
852859
853 try testReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);860 try testReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan);
854 try testReduce(.Mul, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);861 try testReduce(.Mul, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan);
855 try testReduce(.Mul, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);862 try testReduce(.Mul, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan);
863 try testReduce(.Mul, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, f80_nan);
864 try testReduce(.Mul, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, f128_nan);
856 }865 }
857 };866 };
858867
...@@ -1321,11 +1330,6 @@ test "byte vector initialized in inline function" {...@@ -1321,11 +1330,6 @@ test "byte vector initialized in inline function" {
1321 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1330 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1322 if (builtin.cpu.arch == .hexagon and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;1331 if (builtin.cpu.arch == .hexagon and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
13231332
1324 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and comptime builtin.cpu.has(.x86, .avx512f)) {
1325 // TODO https://github.com/ziglang/zig/issues/13279
1326 return error.SkipZigTest;
1327 }
1328
1329 const S = struct {1333 const S = struct {
1330 fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {1334 fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {
1331 return .{ e0, e1, e2, e3 };1335 return .{ e0, e1, e2, e3 };
...@@ -1437,7 +1441,6 @@ test "store packed vector element" {...@@ -1437,7 +1441,6 @@ test "store packed vector element" {
1437 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1441 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1438 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1439 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1443 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1440 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1441 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1444 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14421445
1443 var v = @Vector(4, u1){ 1, 1, 1, 1 };1446 var v = @Vector(4, u1){ 1, 1, 1, 1 };
...@@ -1469,7 +1472,6 @@ test "store vector with memset" {...@@ -1469,7 +1472,6 @@ test "store vector with memset" {
1469 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1472 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1470 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1473 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1471 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO1474 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1472 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1473 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1475 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14741476
1475 var a: [5]@Vector(2, i1) = undefined;1477 var a: [5]@Vector(2, i1) = undefined;
...@@ -1610,7 +1612,6 @@ test "bitcast vector to array of smaller vectors" {...@@ -1610,7 +1612,6 @@ test "bitcast vector to array of smaller vectors" {
1610 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1612 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1611 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1613 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1612 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1614 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1613 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
16141615
1615 const u8x32 = @Vector(32, u8);1616 const u8x32 = @Vector(32, u8);
1616 const u8x64 = @Vector(64, u8);1617 const u8x64 = @Vector(64, u8);
test/behavior/widening.zig-1
...@@ -41,7 +41,6 @@ test "float widening" {...@@ -41,7 +41,6 @@ test "float widening" {
41 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO41 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
42 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;42 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
43 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;43 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
44 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
4544
46 var a: f16 = 12.34;45 var a: f16 = 12.34;
47 var b: f32 = a;46 var b: f32 = a;
test/behavior/x86_64/unary.zig+1-1
...@@ -56,7 +56,7 @@ fn unary(comptime op: anytype, comptime opts: struct {...@@ -56,7 +56,7 @@ fn unary(comptime op: anytype, comptime opts: struct {
56 f32 => libc_name ++ "f",56 f32 => libc_name ++ "f",
57 f64 => libc_name,57 f64 => libc_name,
58 f80 => "__" ++ libc_name ++ "x",58 f80 => "__" ++ libc_name ++ "x",
59 f128 => libc_name ++ "q",59 f128 => libc_name ++ "f128",
60 else => break :libc,60 else => break :libc,
61 },61 },
62 .library_name = switch (@import("builtin").object_format) {62 .library_name = switch (@import("builtin").object_format) {
test/c_abi/cfuncs.c+256-20
...@@ -77,7 +77,7 @@ static void assert_or_panic(bool ok) {...@@ -77,7 +77,7 @@ static void assert_or_panic(bool ok) {
77# define ZIG_NO_COMPLEX77# define ZIG_NO_COMPLEX
78#endif78#endif
7979
80#ifdef ZIG_PPC3280#ifdef __powerpc__
81# define ZIG_NO_COMPLEX81# define ZIG_NO_COMPLEX
82#endif82#endif
8383
...@@ -408,7 +408,11 @@ void c_test_longdouble(void) {...@@ -408,7 +408,11 @@ void c_test_longdouble(void) {
408 zig_8_longdouble(0, 1, 2, 3, 4, 5, 6, 7, 10, 9);408 zig_8_longdouble(0, 1, 2, 3, 4, 5, 6, 7, 10, 9);
409}409}
410410
411#if defined(ZIG_BACKEND_STAGE2_X86_64) || defined(ZIG_PPC32) || defined(__wasm__)411#ifndef __hexagon__
412#ifndef __loongarch__
413#ifndef __mips__
414#ifndef ZIG_PPC64
415#if !(defined(__i386__) && defined(_WIN32))
412416
413typedef bool Vector_2_bool __attribute__((ext_vector_type(2)));417typedef bool Vector_2_bool __attribute__((ext_vector_type(2)));
414418
...@@ -4657,6 +4661,10 @@ void c_test_vector_512_bool(void) {...@@ -4657,6 +4661,10 @@ void c_test_vector_512_bool(void) {
4657 });4661 });
4658}4662}
46594663
4664#endif
4665#endif
4666#endif
4667#endif
4660#endif4668#endif
46614669
4662typedef uint8_t Vector_1_u8 __attribute__((vector_size(1 * sizeof(uint8_t))));4670typedef uint8_t Vector_1_u8 __attribute__((vector_size(1 * sizeof(uint8_t))));
...@@ -15186,6 +15194,126 @@ void c_test_struct_f32_f32_f32_f32_f32(void) {...@@ -15186,6 +15194,126 @@ void c_test_struct_f32_f32_f32_f32_f32(void) {
15186 zig_struct_f32_f32_f32_f32_f32((struct Struct_f32_f32_f32_f32_f32){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11);15194 zig_struct_f32_f32_f32_f32_f32((struct Struct_f32_f32_f32_f32_f32){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11);
15187}15195}
1518815196
15197struct Struct_array_1_f32 {
15198 float a[1];
15199};
15200
15201struct Struct_array_1_f32 zig_ret_struct_array_1_f32(void);
15202void zig_struct_array_1_f32(struct Struct_array_1_f32, size_t);
15203
15204struct Struct_array_1_f32 c_ret_struct_array_1_f32(void) {
15205 return (struct Struct_array_1_f32){ .a = { 4 } };
15206}
15207void c_struct_array_1_f32(struct Struct_array_1_f32 s, size_t i) {
15208 assert_or_panic(s.a[0] == 5);
15209 assert_or_panic(i == 6);
15210}
15211void c_test_struct_array_1_f32(void) {
15212 struct Struct_array_1_f32 s = zig_ret_struct_array_1_f32();
15213 assert_or_panic(s.a[0] == 1);
15214 zig_struct_array_1_f32((struct Struct_array_1_f32){ .a = { 2 } }, 3);
15215}
15216
15217struct Struct_array_2_f32 {
15218 float a[2];
15219};
15220
15221struct Struct_array_2_f32 zig_ret_struct_array_2_f32(void);
15222void zig_struct_array_2_f32(struct Struct_array_2_f32, size_t);
15223
15224struct Struct_array_2_f32 c_ret_struct_array_2_f32(void) {
15225 return (struct Struct_array_2_f32){ .a = { 6, 7 } };
15226}
15227void c_struct_array_2_f32(struct Struct_array_2_f32 s, size_t i) {
15228 assert_or_panic(s.a[0] == 8);
15229 assert_or_panic(s.a[1] == 9);
15230 assert_or_panic(i == 10);
15231}
15232void c_test_struct_array_2_f32(void) {
15233 struct Struct_array_2_f32 s = zig_ret_struct_array_2_f32();
15234 assert_or_panic(s.a[0] == 1);
15235 assert_or_panic(s.a[1] == 2);
15236 zig_struct_array_2_f32((struct Struct_array_2_f32){ .a = { 3, 4 } }, 5);
15237}
15238
15239struct Struct_array_3_f32 {
15240 float a[3];
15241};
15242
15243struct Struct_array_3_f32 zig_ret_struct_array_3_f32(void);
15244void zig_struct_array_3_f32(struct Struct_array_3_f32, size_t);
15245
15246struct Struct_array_3_f32 c_ret_struct_array_3_f32(void) {
15247 return (struct Struct_array_3_f32){ .a = { 8, 9, 10 } };
15248}
15249void c_struct_array_3_f32(struct Struct_array_3_f32 s, size_t i) {
15250 assert_or_panic(s.a[0] == 11);
15251 assert_or_panic(s.a[1] == 12);
15252 assert_or_panic(s.a[2] == 13);
15253 assert_or_panic(i == 14);
15254}
15255void c_test_struct_array_3_f32(void) {
15256 struct Struct_array_3_f32 s = zig_ret_struct_array_3_f32();
15257 assert_or_panic(s.a[0] == 1);
15258 assert_or_panic(s.a[1] == 2);
15259 assert_or_panic(s.a[2] == 3);
15260 zig_struct_array_3_f32((struct Struct_array_3_f32){ .a = { 4, 5, 6 } }, 7);
15261}
15262
15263struct Struct_array_4_f32 {
15264 float a[4];
15265};
15266
15267struct Struct_array_4_f32 zig_ret_struct_array_4_f32(void);
15268void zig_struct_array_4_f32(struct Struct_array_4_f32, size_t);
15269
15270struct Struct_array_4_f32 c_ret_struct_array_4_f32(void) {
15271 return (struct Struct_array_4_f32){ .a = { 10, 11, 12, 13 } };
15272}
15273void c_struct_array_4_f32(struct Struct_array_4_f32 s, size_t i) {
15274 assert_or_panic(s.a[0] == 14);
15275 assert_or_panic(s.a[1] == 15);
15276 assert_or_panic(s.a[2] == 16);
15277 assert_or_panic(s.a[3] == 17);
15278 assert_or_panic(i == 18);
15279}
15280void c_test_struct_array_4_f32(void) {
15281 struct Struct_array_4_f32 s = zig_ret_struct_array_4_f32();
15282 assert_or_panic(s.a[0] == 1);
15283 assert_or_panic(s.a[1] == 2);
15284 assert_or_panic(s.a[2] == 3);
15285 assert_or_panic(s.a[3] == 4);
15286 zig_struct_array_4_f32((struct Struct_array_4_f32){ .a = { 5, 6, 7, 8 } }, 9);
15287}
15288
15289struct Struct_array_5_f32 {
15290 float a[5];
15291};
15292
15293struct Struct_array_5_f32 zig_ret_struct_array_5_f32(void);
15294void zig_struct_array_5_f32(struct Struct_array_5_f32, size_t);
15295
15296struct Struct_array_5_f32 c_ret_struct_array_5_f32(void) {
15297 return (struct Struct_array_5_f32){ .a = { 12, 13, 14, 15, 16 } };
15298}
15299void c_struct_array_5_f32(struct Struct_array_5_f32 s, size_t i) {
15300 assert_or_panic(s.a[0] == 17);
15301 assert_or_panic(s.a[1] == 18);
15302 assert_or_panic(s.a[2] == 19);
15303 assert_or_panic(s.a[3] == 20);
15304 assert_or_panic(s.a[4] == 21);
15305 assert_or_panic(i == 22);
15306}
15307void c_test_struct_array_5_f32(void) {
15308 struct Struct_array_5_f32 s = zig_ret_struct_array_5_f32();
15309 assert_or_panic(s.a[0] == 1);
15310 assert_or_panic(s.a[1] == 2);
15311 assert_or_panic(s.a[2] == 3);
15312 assert_or_panic(s.a[3] == 4);
15313 assert_or_panic(s.a[4] == 5);
15314 zig_struct_array_5_f32((struct Struct_array_5_f32){ .a = { 6, 7, 8, 9, 10 } }, 11);
15315}
15316
15189struct Struct_f32a8 {15317struct Struct_f32a8 {
15190 alignas(8) float a;15318 alignas(8) float a;
15191};15319};
...@@ -15401,6 +15529,126 @@ void c_test_struct_f64_f64_f64_f64_f64(void) {...@@ -15401,6 +15529,126 @@ void c_test_struct_f64_f64_f64_f64_f64(void) {
15401 zig_struct_f64_f64_f64_f64_f64((struct Struct_f64_f64_f64_f64_f64){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11);15529 zig_struct_f64_f64_f64_f64_f64((struct Struct_f64_f64_f64_f64_f64){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11);
15402}15530}
1540315531
15532struct Struct_array_1_f64 {
15533 double a[1];
15534};
15535
15536struct Struct_array_1_f64 zig_ret_struct_array_1_f64(void);
15537void zig_struct_array_1_f64(struct Struct_array_1_f64, size_t);
15538
15539struct Struct_array_1_f64 c_ret_struct_array_1_f64(void) {
15540 return (struct Struct_array_1_f64){ .a = { 4 } };
15541}
15542void c_struct_array_1_f64(struct Struct_array_1_f64 s, size_t i) {
15543 assert_or_panic(s.a[0] == 5);
15544 assert_or_panic(i == 6);
15545}
15546void c_test_struct_array_1_f64(void) {
15547 struct Struct_array_1_f64 s = zig_ret_struct_array_1_f64();
15548 assert_or_panic(s.a[0] == 1);
15549 zig_struct_array_1_f64((struct Struct_array_1_f64){ .a = { 2 } }, 3);
15550}
15551
15552struct Struct_array_2_f64 {
15553 double a[2];
15554};
15555
15556struct Struct_array_2_f64 zig_ret_struct_array_2_f64(void);
15557void zig_struct_array_2_f64(struct Struct_array_2_f64, size_t);
15558
15559struct Struct_array_2_f64 c_ret_struct_array_2_f64(void) {
15560 return (struct Struct_array_2_f64){ .a = { 6, 7 } };
15561}
15562void c_struct_array_2_f64(struct Struct_array_2_f64 s, size_t i) {
15563 assert_or_panic(s.a[0] == 8);
15564 assert_or_panic(s.a[1] == 9);
15565 assert_or_panic(i == 10);
15566}
15567void c_test_struct_array_2_f64(void) {
15568 struct Struct_array_2_f64 s = zig_ret_struct_array_2_f64();
15569 assert_or_panic(s.a[0] == 1);
15570 assert_or_panic(s.a[1] == 2);
15571 zig_struct_array_2_f64((struct Struct_array_2_f64){ .a = { 3, 4 } }, 5);
15572}
15573
15574struct Struct_array_3_f64 {
15575 double a[3];
15576};
15577
15578struct Struct_array_3_f64 zig_ret_struct_array_3_f64(void);
15579void zig_struct_array_3_f64(struct Struct_array_3_f64, size_t);
15580
15581struct Struct_array_3_f64 c_ret_struct_array_3_f64(void) {
15582 return (struct Struct_array_3_f64){ .a = { 8, 9, 10 } };
15583}
15584void c_struct_array_3_f64(struct Struct_array_3_f64 s, size_t i) {
15585 assert_or_panic(s.a[0] == 11);
15586 assert_or_panic(s.a[1] == 12);
15587 assert_or_panic(s.a[2] == 13);
15588 assert_or_panic(i == 14);
15589}
15590void c_test_struct_array_3_f64(void) {
15591 struct Struct_array_3_f64 s = zig_ret_struct_array_3_f64();
15592 assert_or_panic(s.a[0] == 1);
15593 assert_or_panic(s.a[1] == 2);
15594 assert_or_panic(s.a[2] == 3);
15595 zig_struct_array_3_f64((struct Struct_array_3_f64){ .a = { 4, 5, 6 } }, 7);
15596}
15597
15598struct Struct_array_4_f64 {
15599 double a[4];
15600};
15601
15602struct Struct_array_4_f64 zig_ret_struct_array_4_f64(void);
15603void zig_struct_array_4_f64(struct Struct_array_4_f64, size_t);
15604
15605struct Struct_array_4_f64 c_ret_struct_array_4_f64(void) {
15606 return (struct Struct_array_4_f64){ .a = { 10, 11, 12, 13 } };
15607}
15608void c_struct_array_4_f64(struct Struct_array_4_f64 s, size_t i) {
15609 assert_or_panic(s.a[0] == 14);
15610 assert_or_panic(s.a[1] == 15);
15611 assert_or_panic(s.a[2] == 16);
15612 assert_or_panic(s.a[3] == 17);
15613 assert_or_panic(i == 18);
15614}
15615void c_test_struct_array_4_f64(void) {
15616 struct Struct_array_4_f64 s = zig_ret_struct_array_4_f64();
15617 assert_or_panic(s.a[0] == 1);
15618 assert_or_panic(s.a[1] == 2);
15619 assert_or_panic(s.a[2] == 3);
15620 assert_or_panic(s.a[3] == 4);
15621 zig_struct_array_4_f64((struct Struct_array_4_f64){ .a = { 5, 6, 7, 8 } }, 9);
15622}
15623
15624struct Struct_array_5_f64 {
15625 double a[5];
15626};
15627
15628struct Struct_array_5_f64 zig_ret_struct_array_5_f64(void);
15629void zig_struct_array_5_f64(struct Struct_array_5_f64, size_t);
15630
15631struct Struct_array_5_f64 c_ret_struct_array_5_f64(void) {
15632 return (struct Struct_array_5_f64){ .a = { 12, 13, 14, 15, 16 } };
15633}
15634void c_struct_array_5_f64(struct Struct_array_5_f64 s, size_t i) {
15635 assert_or_panic(s.a[0] == 17);
15636 assert_or_panic(s.a[1] == 18);
15637 assert_or_panic(s.a[2] == 19);
15638 assert_or_panic(s.a[3] == 20);
15639 assert_or_panic(s.a[4] == 21);
15640 assert_or_panic(i == 22);
15641}
15642void c_test_struct_array_5_f64(void) {
15643 struct Struct_array_5_f64 s = zig_ret_struct_array_5_f64();
15644 assert_or_panic(s.a[0] == 1);
15645 assert_or_panic(s.a[1] == 2);
15646 assert_or_panic(s.a[2] == 3);
15647 assert_or_panic(s.a[3] == 4);
15648 assert_or_panic(s.a[4] == 5);
15649 zig_struct_array_5_f64((struct Struct_array_5_f64){ .a = { 6, 7, 8, 9, 10 } }, 11);
15650}
15651
15404struct Struct_u32_Union_u32_u32u32 {15652struct Struct_u32_Union_u32_u32u32 {
15405 uint32_t a;15653 uint32_t a;
15406 union {15654 union {
...@@ -15563,8 +15811,7 @@ void run_c_tests(void) {...@@ -15563,8 +15811,7 @@ void run_c_tests(void) {
15563#if !(defined(__i386__) && defined(_WIN32))15811#if !(defined(__i386__) && defined(_WIN32))
15564#ifndef __loongarch__15812#ifndef __loongarch__
15565#ifndef ZIG_MIPS6415813#ifndef ZIG_MIPS64
15566#ifndef __powerpc__15814#ifndef ZIG_PPC32
15567#ifndef __s390x__
15568 {15815 {
15569 struct Struct_i32_i32 s = {1, 2};15816 struct Struct_i32_i32 s = {1, 2};
15570 zig_struct_i32_i32(s);15817 zig_struct_i32_i32(s);
...@@ -15573,13 +15820,11 @@ void run_c_tests(void) {...@@ -15573,13 +15820,11 @@ void run_c_tests(void) {
15573#endif15820#endif
15574#endif15821#endif
15575#endif15822#endif
15576#endif
1557715823
15578#ifndef __hexagon__15824#ifndef __hexagon__
15579#ifndef __loongarch__15825#ifndef __loongarch__
15580#ifndef ZIG_MIPS6415826#ifndef ZIG_MIPS64
15581#ifndef __powerpc__15827#ifndef ZIG_PPC32
15582#ifndef __s390x__
15583 {15828 {
15584 struct BigStruct s = {1, 2, 3, 4, 5};15829 struct BigStruct s = {1, 2, 3, 4, 5};
15585 zig_big_struct(s);15830 zig_big_struct(s);
...@@ -15588,7 +15833,6 @@ void run_c_tests(void) {...@@ -15588,7 +15833,6 @@ void run_c_tests(void) {
15588#endif15833#endif
15589#endif15834#endif
15590#endif15835#endif
15591#endif
1559215836
15593#ifndef ZIG_NO_I12815837#ifndef ZIG_NO_I128
15594 {15838 {
...@@ -15612,8 +15856,7 @@ void run_c_tests(void) {...@@ -15612,8 +15856,7 @@ void run_c_tests(void) {
15612#ifndef __i386__15856#ifndef __i386__
15613#ifndef __loongarch__15857#ifndef __loongarch__
15614#ifndef ZIG_MIPS6415858#ifndef ZIG_MIPS64
15615#ifndef __powerpc__15859#ifndef ZIG_PPC32
15616#ifndef __s390x__
15617 {15860 {
15618 struct SplitStructInts s = {1234, 100, 1337};15861 struct SplitStructInts s = {1234, 100, 1337};
15619 zig_split_struct_ints(s);15862 zig_split_struct_ints(s);
...@@ -15623,13 +15866,11 @@ void run_c_tests(void) {...@@ -15623,13 +15866,11 @@ void run_c_tests(void) {
15623#endif15866#endif
15624#endif15867#endif
15625#endif15868#endif
15626#endif
1562715869
15628#ifndef __hexagon__15870#ifndef __hexagon__
15629#ifndef __loongarch__15871#ifndef __loongarch__
15630#ifndef ZIG_MIPS6415872#ifndef ZIG_MIPS64
15631#ifndef __powerpc__15873#ifndef ZIG_PPC32
15632#ifndef __s390x__
15633 {15874 {
15634 struct MedStructMixed s = {1234, 100.0f, 1337.0f};15875 struct MedStructMixed s = {1234, 100.0f, 1337.0f};
15635 zig_med_struct_mixed(s);15876 zig_med_struct_mixed(s);
...@@ -15638,14 +15879,12 @@ void run_c_tests(void) {...@@ -15638,14 +15879,12 @@ void run_c_tests(void) {
15638#endif15879#endif
15639#endif15880#endif
15640#endif15881#endif
15641#endif
1564215882
15643#ifndef __hexagon__15883#ifndef __hexagon__
15644#ifndef __i386__15884#ifndef __i386__
15645#ifndef __loongarch__15885#ifndef __loongarch__
15646#ifndef ZIG_MIPS6415886#ifndef ZIG_MIPS64
15647#ifndef __powerpc__15887#ifndef ZIG_PPC32
15648#ifndef __s390x__
15649 {15888 {
15650 struct SplitStructMixed s = {1234, 100, 1337.0f};15889 struct SplitStructMixed s = {1234, 100, 1337.0f};
15651 zig_split_struct_mixed(s);15890 zig_split_struct_mixed(s);
...@@ -15655,13 +15894,11 @@ void run_c_tests(void) {...@@ -15655,13 +15894,11 @@ void run_c_tests(void) {
15655#endif15894#endif
15656#endif15895#endif
15657#endif15896#endif
15658#endif
1565915897
15660#ifndef __hexagon__15898#ifndef __hexagon__
15661#ifndef __loongarch__15899#ifndef __loongarch__
15662#ifndef ZIG_MIPS6415900#ifndef ZIG_MIPS64
15663#ifndef __powerpc__15901#ifndef ZIG_PPC32
15664#ifndef __s390x__
15665 {15902 {
15666 struct BigStruct s = {30, 31, 32, 33, 34};15903 struct BigStruct s = {30, 31, 32, 33, 34};
15667 struct BigStruct res = zig_big_struct_both(s);15904 struct BigStruct res = zig_big_struct_both(s);
...@@ -15674,7 +15911,6 @@ void run_c_tests(void) {...@@ -15674,7 +15911,6 @@ void run_c_tests(void) {
15674#endif15911#endif
15675#endif15912#endif
15676#endif15913#endif
15677#endif
15678#endif15914#endif
1567915915
15680 {15916 {
test/c_abi/main.zig+558-246
...@@ -13,7 +13,7 @@ const expectEqual = std.testing.expectEqual;...@@ -13,7 +13,7 @@ const expectEqual = std.testing.expectEqual;
13const have_i128 = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isArm() and13const have_i128 = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isArm() and
14 !builtin.cpu.arch.isMIPS() and !builtin.cpu.arch.isPowerPC32() and builtin.cpu.arch != .riscv32 and14 !builtin.cpu.arch.isMIPS() and !builtin.cpu.arch.isPowerPC32() and builtin.cpu.arch != .riscv32 and
15 builtin.cpu.arch != .hexagon and15 builtin.cpu.arch != .hexagon and
16 builtin.cpu.arch != .s390x; // https://github.com/llvm/llvm-project/issues/16846016 builtin.cpu.arch != .s390x;
1717
18const have_f128 = builtin.cpu.arch.isWasm() or (builtin.cpu.arch.isX86() and !builtin.os.tag.isDarwin() and builtin.abi != .msvc);18const have_f128 = builtin.cpu.arch.isWasm() or (builtin.cpu.arch.isX86() and !builtin.os.tag.isDarwin() and builtin.abi != .msvc);
19const have_f80 = builtin.cpu.arch.isX86() and builtin.abi != .msvc;19const have_f80 = builtin.cpu.arch.isX86() and builtin.abi != .msvc;
...@@ -161,7 +161,7 @@ extern fn c_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat;...@@ -161,7 +161,7 @@ extern fn c_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat;
161extern fn c_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble;161extern fn c_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble;
162162
163const complex_abi_compatible = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isMIPS() and163const complex_abi_compatible = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isMIPS() and
164 !builtin.cpu.arch.isArm() and !builtin.cpu.arch.isPowerPC32() and !builtin.cpu.arch.isRISCV() and164 !builtin.cpu.arch.isArm() and !builtin.cpu.arch.isPowerPC() and !builtin.cpu.arch.isRISCV() and
165 builtin.cpu.arch != .hexagon and165 builtin.cpu.arch != .hexagon and
166 builtin.cpu.arch != .s390x and166 builtin.cpu.arch != .s390x and
167 !(builtin.cpu.arch.isLoongArch() and builtin.abi.float() == .soft);167 !(builtin.cpu.arch.isLoongArch() and builtin.abi.float() == .soft);
...@@ -451,8 +451,11 @@ test "long double" {...@@ -451,8 +451,11 @@ test "long double" {
451451
452comptime {452comptime {
453 skip: {453 skip: {
454 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip;454 if (builtin.cpu.arch == .hexagon) break :skip;
455 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip;455 if (builtin.cpu.arch == .loongarch64) break :skip;
456 if (builtin.cpu.arch.isMIPS()) break :skip;
457 if (builtin.cpu.arch.isPowerPC64()) break :skip;
458 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip;
456459
457 _ = struct {460 _ = struct {
458 export fn zig_ret_vector_2_bool() @Vector(2, bool) {461 export fn zig_ret_vector_2_bool() @Vector(2, bool) {
...@@ -474,7 +477,13 @@ extern fn c_vector_2_bool(@Vector(2, bool)) void;...@@ -474,7 +477,13 @@ extern fn c_vector_2_bool(@Vector(2, bool)) void;
474extern fn c_test_vector_2_bool() void;477extern fn c_test_vector_2_bool() void;
475478
476test "@Vector(2, bool)" {479test "@Vector(2, bool)" {
477 if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest;480 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
481 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
482 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
483 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
484 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
485 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
486 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
478487
479 const vec = c_ret_vector_2_bool();488 const vec = c_ret_vector_2_bool();
480 try expect(vec[0] == true);489 try expect(vec[0] == true);
...@@ -488,8 +497,11 @@ test "@Vector(2, bool)" {...@@ -488,8 +497,11 @@ test "@Vector(2, bool)" {
488497
489comptime {498comptime {
490 skip: {499 skip: {
491 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip;500 if (builtin.cpu.arch == .hexagon) break :skip;
492 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip;501 if (builtin.cpu.arch == .loongarch64) break :skip;
502 if (builtin.cpu.arch.isMIPS()) break :skip;
503 if (builtin.cpu.arch.isPowerPC64()) break :skip;
504 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip;
493505
494 _ = struct {506 _ = struct {
495 export fn zig_ret_vector_4_bool() @Vector(4, bool) {507 export fn zig_ret_vector_4_bool() @Vector(4, bool) {
...@@ -515,7 +527,13 @@ extern fn c_vector_4_bool(@Vector(4, bool)) void;...@@ -515,7 +527,13 @@ extern fn c_vector_4_bool(@Vector(4, bool)) void;
515extern fn c_test_vector_4_bool() void;527extern fn c_test_vector_4_bool() void;
516528
517test "@Vector(4, bool)" {529test "@Vector(4, bool)" {
518 if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest;530 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
531 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
532 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
533 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
534 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
535 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
536 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
519537
520 const vec = c_ret_vector_4_bool();538 const vec = c_ret_vector_4_bool();
521 try expect(vec[0] == true);539 try expect(vec[0] == true);
...@@ -533,8 +551,11 @@ test "@Vector(4, bool)" {...@@ -533,8 +551,11 @@ test "@Vector(4, bool)" {
533551
534comptime {552comptime {
535 skip: {553 skip: {
536 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip;554 if (builtin.cpu.arch == .hexagon) break :skip;
537 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip;555 if (builtin.cpu.arch == .loongarch64) break :skip;
556 if (builtin.cpu.arch.isMIPS()) break :skip;
557 if (builtin.cpu.arch.isPowerPC64()) break :skip;
558 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip;
538559
539 _ = struct {560 _ = struct {
540 export fn zig_ret_vector_8_bool() @Vector(8, bool) {561 export fn zig_ret_vector_8_bool() @Vector(8, bool) {
...@@ -568,7 +589,13 @@ extern fn c_vector_8_bool(@Vector(8, bool)) void;...@@ -568,7 +589,13 @@ extern fn c_vector_8_bool(@Vector(8, bool)) void;
568extern fn c_test_vector_8_bool() void;589extern fn c_test_vector_8_bool() void;
569590
570test "@Vector(8, bool)" {591test "@Vector(8, bool)" {
571 if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest;592 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
593 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
594 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
595 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
596 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
597 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
598 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
572599
573 const vec = c_ret_vector_8_bool();600 const vec = c_ret_vector_8_bool();
574 try expect(vec[0] == false);601 try expect(vec[0] == false);
...@@ -594,8 +621,11 @@ test "@Vector(8, bool)" {...@@ -594,8 +621,11 @@ test "@Vector(8, bool)" {
594621
595comptime {622comptime {
596 skip: {623 skip: {
597 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip;624 if (builtin.cpu.arch == .hexagon) break :skip;
598 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip;625 if (builtin.cpu.arch == .loongarch64) break :skip;
626 if (builtin.cpu.arch.isMIPS()) break :skip;
627 if (builtin.cpu.arch.isPowerPC64()) break :skip;
628 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip;
599629
600 _ = struct {630 _ = struct {
601 export fn zig_ret_vector_16_bool() @Vector(16, bool) {631 export fn zig_ret_vector_16_bool() @Vector(16, bool) {
...@@ -645,7 +675,13 @@ extern fn c_vector_16_bool(@Vector(16, bool)) void;...@@ -645,7 +675,13 @@ extern fn c_vector_16_bool(@Vector(16, bool)) void;
645extern fn c_test_vector_16_bool() void;675extern fn c_test_vector_16_bool() void;
646676
647test "@Vector(16, bool)" {677test "@Vector(16, bool)" {
648 if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest;678 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
679 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
680 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
681 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
682 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
683 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
684 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
649685
650 const vec = c_ret_vector_16_bool();686 const vec = c_ret_vector_16_bool();
651 try expect(vec[0] == true);687 try expect(vec[0] == true);
...@@ -687,8 +723,11 @@ test "@Vector(16, bool)" {...@@ -687,8 +723,11 @@ test "@Vector(16, bool)" {
687723
688comptime {724comptime {
689 skip: {725 skip: {
690 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip;726 if (builtin.cpu.arch == .hexagon) break :skip;
691 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip;727 if (builtin.cpu.arch == .loongarch64) break :skip;
728 if (builtin.cpu.arch.isMIPS()) break :skip;
729 if (builtin.cpu.arch.isPowerPC64()) break :skip;
730 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip;
692731
693 _ = struct {732 _ = struct {
694 export fn zig_ret_vector_32_bool() @Vector(32, bool) {733 export fn zig_ret_vector_32_bool() @Vector(32, bool) {
...@@ -770,7 +809,13 @@ extern fn c_vector_32_bool(@Vector(32, bool)) void;...@@ -770,7 +809,13 @@ extern fn c_vector_32_bool(@Vector(32, bool)) void;
770extern fn c_test_vector_32_bool() void;809extern fn c_test_vector_32_bool() void;
771810
772test "@Vector(32, bool)" {811test "@Vector(32, bool)" {
773 if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest;812 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
813 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
814 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
815 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
816 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
817 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
818 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
774819
775 const vec = c_ret_vector_32_bool();820 const vec = c_ret_vector_32_bool();
776 try expect(vec[0] == true);821 try expect(vec[0] == true);
...@@ -844,8 +889,11 @@ test "@Vector(32, bool)" {...@@ -844,8 +889,11 @@ test "@Vector(32, bool)" {
844889
845comptime {890comptime {
846 skip: {891 skip: {
847 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip;892 if (builtin.cpu.arch == .hexagon) break :skip;
848 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip;893 if (builtin.cpu.arch == .loongarch64) break :skip;
894 if (builtin.cpu.arch.isMIPS()) break :skip;
895 if (builtin.cpu.arch.isPowerPC64()) break :skip;
896 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip;
849897
850 _ = struct {898 _ = struct {
851 export fn zig_ret_vector_64_bool() @Vector(64, bool) {899 export fn zig_ret_vector_64_bool() @Vector(64, bool) {
...@@ -991,7 +1039,11 @@ extern fn c_vector_64_bool(@Vector(64, bool)) void;...@@ -991,7 +1039,11 @@ extern fn c_vector_64_bool(@Vector(64, bool)) void;
991extern fn c_test_vector_64_bool() void;1039extern fn c_test_vector_64_bool() void;
9921040
993test "@Vector(64, bool)" {1041test "@Vector(64, bool)" {
994 if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest;1042 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
1043 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
1044 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
1045 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
1046 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
9951047
996 const vec = c_ret_vector_64_bool();1048 const vec = c_ret_vector_64_bool();
997 try expect(vec[0] == false);1049 try expect(vec[0] == false);
...@@ -1129,8 +1181,11 @@ test "@Vector(64, bool)" {...@@ -1129,8 +1181,11 @@ test "@Vector(64, bool)" {
11291181
1130comptime {1182comptime {
1131 skip: {1183 skip: {
1132 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip;1184 if (builtin.cpu.arch == .hexagon) break :skip;
1133 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip;1185 if (builtin.cpu.arch == .loongarch64) break :skip;
1186 if (builtin.cpu.arch.isMIPS()) break :skip;
1187 if (builtin.cpu.arch.isPowerPC64()) break :skip;
1188 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip;
11341189
1135 _ = struct {1190 _ = struct {
1136 export fn zig_ret_vector_128_bool() @Vector(128, bool) {1191 export fn zig_ret_vector_128_bool() @Vector(128, bool) {
...@@ -1404,7 +1459,11 @@ extern fn c_vector_128_bool(@Vector(128, bool)) void;...@@ -1404,7 +1459,11 @@ extern fn c_vector_128_bool(@Vector(128, bool)) void;
1404extern fn c_test_vector_128_bool() void;1459extern fn c_test_vector_128_bool() void;
14051460
1406test "@Vector(128, bool)" {1461test "@Vector(128, bool)" {
1407 if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest;1462 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
1463 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
1464 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
1465 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
1466 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
14081467
1409 const vec = c_ret_vector_128_bool();1468 const vec = c_ret_vector_128_bool();
1410 try expect(vec[0] == false);1469 try expect(vec[0] == false);
...@@ -1670,8 +1729,11 @@ test "@Vector(128, bool)" {...@@ -1670,8 +1729,11 @@ test "@Vector(128, bool)" {
16701729
1671comptime {1730comptime {
1672 skip: {1731 skip: {
1673 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip;1732 if (builtin.cpu.arch == .hexagon) break :skip;
1674 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip;1733 if (builtin.cpu.arch == .loongarch64) break :skip;
1734 if (builtin.cpu.arch.isMIPS()) break :skip;
1735 if (builtin.cpu.arch.isPowerPC64()) break :skip;
1736 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip;
16751737
1676 _ = struct {1738 _ = struct {
1677 export fn zig_ret_vector_256_bool() @Vector(256, bool) {1739 export fn zig_ret_vector_256_bool() @Vector(256, bool) {
...@@ -2201,7 +2263,11 @@ extern fn c_vector_256_bool(@Vector(256, bool)) void;...@@ -2201,7 +2263,11 @@ extern fn c_vector_256_bool(@Vector(256, bool)) void;
2201extern fn c_test_vector_256_bool() void;2263extern fn c_test_vector_256_bool() void;
22022264
2203test "@Vector(256, bool)" {2265test "@Vector(256, bool)" {
2204 if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest;2266 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
2267 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
2268 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
2269 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
2270 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
22052271
2206 const vec = c_ret_vector_256_bool();2272 const vec = c_ret_vector_256_bool();
2207 try expect(vec[0] == true);2273 try expect(vec[0] == true);
...@@ -2723,8 +2789,11 @@ test "@Vector(256, bool)" {...@@ -2723,8 +2789,11 @@ test "@Vector(256, bool)" {
27232789
2724comptime {2790comptime {
2725 skip: {2791 skip: {
2726 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip;2792 if (builtin.cpu.arch == .hexagon) break :skip;
2727 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip;2793 if (builtin.cpu.arch == .loongarch64) break :skip;
2794 if (builtin.cpu.arch.isMIPS()) break :skip;
2795 if (builtin.cpu.arch.isPowerPC64()) break :skip;
2796 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip;
27282797
2729 _ = struct {2798 _ = struct {
2730 export fn zig_ret_vector_512_bool() @Vector(512, bool) {2799 export fn zig_ret_vector_512_bool() @Vector(512, bool) {
...@@ -3766,7 +3835,11 @@ extern fn c_vector_512_bool(@Vector(512, bool)) void;...@@ -3766,7 +3835,11 @@ extern fn c_vector_512_bool(@Vector(512, bool)) void;
3766extern fn c_test_vector_512_bool() void;3835extern fn c_test_vector_512_bool() void;
37673836
3768test "@Vector(512, bool)" {3837test "@Vector(512, bool)" {
3769 if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest;3838 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
3839 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
3840 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
3841 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
3842 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
37703843
3771 const vec = c_ret_vector_512_bool();3844 const vec = c_ret_vector_512_bool();
3772 try expect(vec[0] == false);3845 try expect(vec[0] == false);
...@@ -4840,7 +4913,7 @@ test "@Vector(2, u8)" {...@@ -4840,7 +4913,7 @@ test "@Vector(2, u8)" {
4840 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;4913 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
4841 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;4914 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
4842 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;4915 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
4843 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) return error.SkipZigTest;4916 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest;
48444917
4845 const v = c_ret_vector_2_u8();4918 const v = c_ret_vector_2_u8();
4846 try expect(v[0] == 9);4919 try expect(v[0] == 9);
...@@ -4869,7 +4942,6 @@ test "@Vector(3, u8)" {...@@ -4869,7 +4942,6 @@ test "@Vector(3, u8)" {
4869 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;4942 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
4870 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;4943 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
4871 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;4944 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
4872 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest;
48734945
4874 const v = c_ret_vector_3_u8();4946 const v = c_ret_vector_3_u8();
4875 try expect(v[0] == 19);4947 try expect(v[0] == 19);
...@@ -4912,7 +4984,7 @@ test "@Vector(4, u8)" {...@@ -4912,7 +4984,7 @@ test "@Vector(4, u8)" {
4912 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;4984 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
4913 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;4985 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
4914 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;4986 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
4915 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) return error.SkipZigTest;4987 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest;
49164988
4917 const v = c_ret_vector_4_u8();4989 const v = c_ret_vector_4_u8();
4918 try expect(v[0] == 41);4990 try expect(v[0] == 41);
...@@ -4946,7 +5018,6 @@ test "@Vector(6, u8)" {...@@ -4946,7 +5018,6 @@ test "@Vector(6, u8)" {
4946 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;5018 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
4947 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;5019 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
4948 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;5020 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
4949 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest;
49505021
4951 const v = c_ret_vector_6_u8();5022 const v = c_ret_vector_6_u8();
4952 try expect(v[0] == 53);5023 try expect(v[0] == 53);
...@@ -5136,7 +5207,6 @@ test "@Vector(24, u8)" {...@@ -5136,7 +5207,6 @@ test "@Vector(24, u8)" {
5136 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;5207 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
5137 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;5208 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
5138 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;5209 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
5139 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
51405210
5141 const v = c_ret_vector_24_u8();5211 const v = c_ret_vector_24_u8();
5142 try expect(v[0] == 57);5212 try expect(v[0] == 57);
...@@ -5220,7 +5290,6 @@ test "@Vector(32, u8)" {...@@ -5220,7 +5290,6 @@ test "@Vector(32, u8)" {
5220 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;5290 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
5221 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;5291 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
5222 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;5292 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
5223 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
52245293
5225 const v = c_ret_vector_32_u8();5294 const v = c_ret_vector_32_u8();
5226 try expect(v[0] == 69);5295 try expect(v[0] == 69);
...@@ -5330,7 +5399,6 @@ test "@Vector(48, u8)" {...@@ -5330,7 +5399,6 @@ test "@Vector(48, u8)" {
5330 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;5399 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
5331 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;5400 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
5332 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;5401 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
5333 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
53345402
5335 const v = c_ret_vector_48_u8();5403 const v = c_ret_vector_48_u8();
5336 try expect(v[0] == 29);5404 try expect(v[0] == 29);
...@@ -5473,7 +5541,6 @@ test "@Vector(64, u8)" {...@@ -5473,7 +5541,6 @@ test "@Vector(64, u8)" {
5473 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;5541 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
5474 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;5542 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
5475 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;5543 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
5476 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
54775544
5478 const v = c_ret_vector_64_u8();5545 const v = c_ret_vector_64_u8();
5479 try expect(v[0] == 53);5546 try expect(v[0] == 53);
...@@ -5668,7 +5735,6 @@ test "@Vector(96, u8)" {...@@ -5668,7 +5735,6 @@ test "@Vector(96, u8)" {
5668 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;5735 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
5669 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;5736 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
5670 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;5737 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
5671 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
56725738
5673 const v = c_ret_vector_96_u8();5739 const v = c_ret_vector_96_u8();
5674 try expect(v[0] == 82);5740 try expect(v[0] == 82);
...@@ -5931,7 +5997,6 @@ test "@Vector(128, u8)" {...@@ -5931,7 +5997,6 @@ test "@Vector(128, u8)" {
5931 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;5997 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
5932 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;5998 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
5933 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;5999 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
5934 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
59356000
5936 const v = c_ret_vector_128_u8();6001 const v = c_ret_vector_128_u8();
5937 try expect(v[0] == 30);6002 try expect(v[0] == 30);
...@@ -6296,7 +6361,6 @@ test "@Vector(192, u8)" {...@@ -6296,7 +6361,6 @@ test "@Vector(192, u8)" {
6296 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;6361 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
6297 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;6362 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
6298 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;6363 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
6299 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
63006364
6301 const v = c_ret_vector_192_u8();6365 const v = c_ret_vector_192_u8();
6302 try expect(v[0] == 70);6366 try expect(v[0] == 70);
...@@ -6797,7 +6861,6 @@ test "@Vector(256, u8)" {...@@ -6797,7 +6861,6 @@ test "@Vector(256, u8)" {
6797 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;6861 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
6798 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;6862 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
6799 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;6863 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
6800 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
68016864
6802 const v = c_ret_vector_256_u8();6865 const v = c_ret_vector_256_u8();
6803 try expect(v[0] == 66);6866 try expect(v[0] == 66);
...@@ -7502,7 +7565,6 @@ test "@Vector(384, u8)" {...@@ -7502,7 +7565,6 @@ test "@Vector(384, u8)" {
7502 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;7565 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
7503 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;7566 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
7504 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;7567 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
7505 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
75067568
7507 const v = c_ret_vector_384_u8();7569 const v = c_ret_vector_384_u8();
7508 try expect(v[0] == 46);7570 try expect(v[0] == 46);
...@@ -8479,7 +8541,6 @@ test "@Vector(512, u8)" {...@@ -8479,7 +8541,6 @@ test "@Vector(512, u8)" {
8479 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;8541 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
8480 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;8542 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
8481 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;8543 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
8482 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
84838544
8484 const v = c_ret_vector_512_u8();8545 const v = c_ret_vector_512_u8();
8485 try expect(v[0] == 38);8546 try expect(v[0] == 38);
...@@ -9073,7 +9134,7 @@ test "@Vector(2, u16)" {...@@ -9073,7 +9134,7 @@ test "@Vector(2, u16)" {
9073 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;9134 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
9074 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;9135 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
9075 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;9136 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
9076 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) return error.SkipZigTest;9137 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest;
90779138
9078 const v = c_ret_vector_2_u16();9139 const v = c_ret_vector_2_u16();
9079 try expect(v[0] == 9);9140 try expect(v[0] == 9);
...@@ -9101,7 +9162,6 @@ test "@Vector(3, u16)" {...@@ -9101,7 +9162,6 @@ test "@Vector(3, u16)" {
9101 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;9162 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
9102 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;9163 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
9103 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;9164 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
9104 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest;
91059165
9106 const v = c_ret_vector_3_u16();9166 const v = c_ret_vector_3_u16();
9107 try expect(v[0] == 19);9167 try expect(v[0] == 19);
...@@ -9250,7 +9310,6 @@ test "@Vector(12, u16)" {...@@ -9250,7 +9310,6 @@ test "@Vector(12, u16)" {
9250 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;9310 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
9251 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;9311 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
9252 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;9312 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
9253 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
92549313
9255 const v = c_ret_vector_12_u16();9314 const v = c_ret_vector_12_u16();
9256 try expect(v[0] == 121);9315 try expect(v[0] == 121);
...@@ -9300,7 +9359,6 @@ test "@Vector(16, u16)" {...@@ -9300,7 +9359,6 @@ test "@Vector(16, u16)" {
9300 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;9359 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
9301 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;9360 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
9302 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;9361 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
9303 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
93049362
9305 const v = c_ret_vector_16_u16();9363 const v = c_ret_vector_16_u16();
9306 try expect(v[0] == 177);9364 try expect(v[0] == 177);
...@@ -9366,7 +9424,6 @@ test "@Vector(24, u16)" {...@@ -9366,7 +9424,6 @@ test "@Vector(24, u16)" {
9366 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;9424 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
9367 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;9425 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
9368 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;9426 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
9369 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
93709427
9371 const v = c_ret_vector_24_u16();9428 const v = c_ret_vector_24_u16();
9372 try expect(v[0] == 257);9429 try expect(v[0] == 257);
...@@ -9450,7 +9507,6 @@ test "@Vector(32, u16)" {...@@ -9450,7 +9507,6 @@ test "@Vector(32, u16)" {
9450 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;9507 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
9451 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;9508 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
9452 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;9509 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
9453 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
94549510
9455 const v = c_ret_vector_32_u16();9511 const v = c_ret_vector_32_u16();
9456 try expect(v[0] == 369);9512 try expect(v[0] == 369);
...@@ -9560,7 +9616,6 @@ test "@Vector(48, u16)" {...@@ -9560,7 +9616,6 @@ test "@Vector(48, u16)" {
9560 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;9616 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
9561 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;9617 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
9562 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;9618 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
9563 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
95649619
9565 const v = c_ret_vector_48_u16();9620 const v = c_ret_vector_48_u16();
9566 try expect(v[0] == 529);9621 try expect(v[0] == 529);
...@@ -9704,7 +9759,6 @@ test "@Vector(64, u16)" {...@@ -9704,7 +9759,6 @@ test "@Vector(64, u16)" {
9704 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;9759 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
9705 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;9760 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
9706 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;9761 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
9707 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
97089762
9709 const v = c_ret_vector_64_u16();9763 const v = c_ret_vector_64_u16();
9710 try expect(v[0] == 753);9764 try expect(v[0] == 753);
...@@ -9899,7 +9953,6 @@ test "@Vector(96, u16)" {...@@ -9899,7 +9953,6 @@ test "@Vector(96, u16)" {
9899 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;9953 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
9900 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;9954 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
9901 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;9955 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
9902 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
99039956
9904 const v = c_ret_vector_96_u16();9957 const v = c_ret_vector_96_u16();
9905 try expect(v[0] == 1082);9958 try expect(v[0] == 1082);
...@@ -10162,7 +10215,6 @@ test "@Vector(128, u16)" {...@@ -10162,7 +10215,6 @@ test "@Vector(128, u16)" {
10162 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;10215 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
10163 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;10216 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
10164 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;10217 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
10165 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1016610218
10167 const v = c_ret_vector_128_u16();10219 const v = c_ret_vector_128_u16();
10168 try expect(v[0] == 1530);10220 try expect(v[0] == 1530);
...@@ -10527,7 +10579,6 @@ test "@Vector(192, u16)" {...@@ -10527,7 +10579,6 @@ test "@Vector(192, u16)" {
10527 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;10579 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
10528 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;10580 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
10529 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;10581 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
10530 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1053110582
10532 const v = c_ret_vector_192_u16();10583 const v = c_ret_vector_192_u16();
10533 try expect(v[0] == 2170);10584 try expect(v[0] == 2170);
...@@ -11028,7 +11079,6 @@ test "@Vector(256, u16)" {...@@ -11028,7 +11079,6 @@ test "@Vector(256, u16)" {
11028 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;11079 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
11029 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;11080 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
11030 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;11081 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
11031 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1103211082
11033 const v = c_ret_vector_256_u16();11083 const v = c_ret_vector_256_u16();
11034 try expect(v[0] == 3066);11084 try expect(v[0] == 3066);
...@@ -11445,7 +11495,6 @@ test "@Vector(6, u32)" {...@@ -11445,7 +11495,6 @@ test "@Vector(6, u32)" {
11445 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;11495 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
11446 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;11496 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
11447 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;11497 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
11448 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1144911498
11450 const v = c_ret_vector_6_u32();11499 const v = c_ret_vector_6_u32();
11451 try expect(v[0] == 53);11500 try expect(v[0] == 53);
...@@ -11481,7 +11530,6 @@ test "@Vector(8, u32)" {...@@ -11481,7 +11530,6 @@ test "@Vector(8, u32)" {
11481 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;11530 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
11482 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;11531 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
11483 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;11532 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
11484 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1148511533
11486 const v = c_ret_vector_8_u32();11534 const v = c_ret_vector_8_u32();
11487 try expect(v[0] == 81);11535 try expect(v[0] == 81);
...@@ -11524,7 +11572,6 @@ test "@Vector(12, u32)" {...@@ -11524,7 +11572,6 @@ test "@Vector(12, u32)" {
11524 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;11572 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
11525 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;11573 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
11526 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;11574 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
11527 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1152811575
11529 const v = c_ret_vector_12_u32();11576 const v = c_ret_vector_12_u32();
11530 try expect(v[0] == 121);11577 try expect(v[0] == 121);
...@@ -11574,7 +11621,6 @@ test "@Vector(16, u32)" {...@@ -11574,7 +11621,6 @@ test "@Vector(16, u32)" {
11574 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;11621 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
11575 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;11622 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
11576 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;11623 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
11577 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1157811624
11579 const v = c_ret_vector_16_u32();11625 const v = c_ret_vector_16_u32();
11580 try expect(v[0] == 177);11626 try expect(v[0] == 177);
...@@ -11640,7 +11686,6 @@ test "@Vector(24, u32)" {...@@ -11640,7 +11686,6 @@ test "@Vector(24, u32)" {
11640 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;11686 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
11641 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;11687 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
11642 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;11688 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
11643 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1164411689
11645 const v = c_ret_vector_24_u32();11690 const v = c_ret_vector_24_u32();
11646 try expect(v[0] == 257);11691 try expect(v[0] == 257);
...@@ -11725,7 +11770,6 @@ test "@Vector(32, u32)" {...@@ -11725,7 +11770,6 @@ test "@Vector(32, u32)" {
11725 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;11770 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
11726 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;11771 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
11727 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;11772 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
11728 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1172911773
11730 const v = c_ret_vector_32_u32();11774 const v = c_ret_vector_32_u32();
11731 try expect(v[0] == 369);11775 try expect(v[0] == 369);
...@@ -11835,7 +11879,6 @@ test "@Vector(48, u32)" {...@@ -11835,7 +11879,6 @@ test "@Vector(48, u32)" {
11835 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;11879 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
11836 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;11880 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
11837 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;11881 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
11838 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1183911882
11840 const v = c_ret_vector_48_u32();11883 const v = c_ret_vector_48_u32();
11841 try expect(v[0] == 529);11884 try expect(v[0] == 529);
...@@ -11979,7 +12022,6 @@ test "@Vector(64, u32)" {...@@ -11979,7 +12022,6 @@ test "@Vector(64, u32)" {
11979 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;12022 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
11980 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;12023 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
11981 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;12024 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
11982 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1198312025
11984 const v = c_ret_vector_64_u32();12026 const v = c_ret_vector_64_u32();
11985 try expect(v[0] == 753);12027 try expect(v[0] == 753);
...@@ -12174,7 +12216,6 @@ test "@Vector(96, u32)" {...@@ -12174,7 +12216,6 @@ test "@Vector(96, u32)" {
12174 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;12216 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
12175 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;12217 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
12176 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;12218 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
12177 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1217812219
12179 const v = c_ret_vector_96_u32();12220 const v = c_ret_vector_96_u32();
12180 try expect(v[0] == 1082);12221 try expect(v[0] == 1082);
...@@ -12437,7 +12478,6 @@ test "@Vector(128, u32)" {...@@ -12437,7 +12478,6 @@ test "@Vector(128, u32)" {
12437 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;12478 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
12438 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;12479 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
12439 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;12480 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
12440 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1244112481
12442 const v = c_ret_vector_128_u32();12482 const v = c_ret_vector_128_u32();
12443 try expect(v[0] == 1530);12483 try expect(v[0] == 1530);
...@@ -12594,8 +12634,6 @@ extern fn c_vector_1_u64(@Vector(1, u64), usize) void;...@@ -12594,8 +12634,6 @@ extern fn c_vector_1_u64(@Vector(1, u64), usize) void;
12594extern fn c_test_vector_1_u64() void;12634extern fn c_test_vector_1_u64() void;
1259512635
12596test "@Vector(1, u64)" {12636test "@Vector(1, u64)" {
12597 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest;
12598
12599 const v = c_ret_vector_1_u64();12637 const v = c_ret_vector_1_u64();
12600 try expect(v[0] == 3);12638 try expect(v[0] == 3);
12601 c_vector_1_u64(.{4}, 1);12639 c_vector_1_u64(.{4}, 1);
...@@ -12644,7 +12682,6 @@ test "@Vector(3, u64)" {...@@ -12644,7 +12682,6 @@ test "@Vector(3, u64)" {
12644 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;12682 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
12645 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;12683 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
12646 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;12684 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
12647 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1264812685
12649 const v = c_ret_vector_3_u64();12686 const v = c_ret_vector_3_u64();
12650 try expect(v[0] == 19);12687 try expect(v[0] == 19);
...@@ -12673,7 +12710,6 @@ test "@Vector(4, u64)" {...@@ -12673,7 +12710,6 @@ test "@Vector(4, u64)" {
12673 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;12710 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
12674 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;12711 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
12675 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;12712 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
12676 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1267712713
12678 const v = c_ret_vector_4_u64();12714 const v = c_ret_vector_4_u64();
12679 try expect(v[0] == 33);12715 try expect(v[0] == 33);
...@@ -12740,7 +12776,6 @@ test "@Vector(8, u64)" {...@@ -12740,7 +12776,6 @@ test "@Vector(8, u64)" {
12740 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;12776 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
12741 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;12777 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
12742 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;12778 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
12743 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1274412779
12745 const v = c_ret_vector_8_u64();12780 const v = c_ret_vector_8_u64();
12746 try expect(v[0] == 81);12781 try expect(v[0] == 81);
...@@ -12832,7 +12867,6 @@ test "@Vector(16, u64)" {...@@ -12832,7 +12867,6 @@ test "@Vector(16, u64)" {
12832 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;12867 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
12833 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;12868 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
12834 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;12869 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
12835 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1283612870
12837 const v = c_ret_vector_16_u64();12871 const v = c_ret_vector_16_u64();
12838 try expect(v[0] == 177);12872 try expect(v[0] == 177);
...@@ -12981,7 +13015,6 @@ test "@Vector(32, u64)" {...@@ -12981,7 +13015,6 @@ test "@Vector(32, u64)" {
12981 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13015 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
12982 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;13016 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
12983 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13017 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
12984 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1298513018
12986 const v = c_ret_vector_32_u64();13019 const v = c_ret_vector_32_u64();
12987 try expect(v[0] == 369);13020 try expect(v[0] == 369);
...@@ -13233,7 +13266,6 @@ test "@Vector(64, u64)" {...@@ -13233,7 +13266,6 @@ test "@Vector(64, u64)" {
13233 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13266 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13234 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;13267 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
13235 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13268 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13236 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1323713269
13238 const v = c_ret_vector_64_u64();13270 const v = c_ret_vector_64_u64();
13239 try expect(v[0] == 753);13271 try expect(v[0] == 753);
...@@ -13327,7 +13359,6 @@ test "@Vector(1, f32)" {...@@ -13327,7 +13359,6 @@ test "@Vector(1, f32)" {
13327 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13359 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13328 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;13360 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
13329 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13361 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13330 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest;
1333113362
13332 const v = c_ret_vector_1_f32();13363 const v = c_ret_vector_1_f32();
13333 try expect(v[0] == 3);13364 try expect(v[0] == 3);
...@@ -13449,7 +13480,6 @@ test "@Vector(6, f32)" {...@@ -13449,7 +13480,6 @@ test "@Vector(6, f32)" {
13449 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13480 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13450 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;13481 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
13451 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13482 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13452 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1345313483
13454 const v = c_ret_vector_6_f32();13484 const v = c_ret_vector_6_f32();
13455 try expect(v[0] == 53);13485 try expect(v[0] == 53);
...@@ -13486,7 +13516,6 @@ test "@Vector(8, f32)" {...@@ -13486,7 +13516,6 @@ test "@Vector(8, f32)" {
13486 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13516 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13487 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;13517 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
13488 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13518 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13489 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1349013519
13491 const v = c_ret_vector_8_f32();13520 const v = c_ret_vector_8_f32();
13492 try expect(v[0] == 81);13521 try expect(v[0] == 81);
...@@ -13529,7 +13558,6 @@ test "@Vector(12, f32)" {...@@ -13529,7 +13558,6 @@ test "@Vector(12, f32)" {
13529 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13558 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13530 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;13559 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
13531 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13560 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13532 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1353313561
13534 const v = c_ret_vector_12_f32();13562 const v = c_ret_vector_12_f32();
13535 try expect(v[0] == 121);13563 try expect(v[0] == 121);
...@@ -13580,7 +13608,6 @@ test "@Vector(16, f32)" {...@@ -13580,7 +13608,6 @@ test "@Vector(16, f32)" {
13580 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13608 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13581 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;13609 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
13582 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13610 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13583 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1358413611
13585 const v = c_ret_vector_16_f32();13612 const v = c_ret_vector_16_f32();
13586 try expect(v[0] == 177);13613 try expect(v[0] == 177);
...@@ -13646,7 +13673,6 @@ test "@Vector(24, f32)" {...@@ -13646,7 +13673,6 @@ test "@Vector(24, f32)" {
13646 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13673 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13647 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;13674 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
13648 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13675 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13649 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1365013676
13651 const v = c_ret_vector_24_f32();13677 const v = c_ret_vector_24_f32();
13652 try expect(v[0] == 257);13678 try expect(v[0] == 257);
...@@ -13731,7 +13757,6 @@ test "@Vector(32, f32)" {...@@ -13731,7 +13757,6 @@ test "@Vector(32, f32)" {
13731 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13757 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13732 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;13758 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
13733 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13759 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13734 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1373513760
13736 const v = c_ret_vector_32_f32();13761 const v = c_ret_vector_32_f32();
13737 try expect(v[0] == 369);13762 try expect(v[0] == 369);
...@@ -13841,7 +13866,6 @@ test "@Vector(48, f32)" {...@@ -13841,7 +13866,6 @@ test "@Vector(48, f32)" {
13841 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;13866 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13842 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;13867 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
13843 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;13868 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13844 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1384513869
13846 const v = c_ret_vector_48_f32();13870 const v = c_ret_vector_48_f32();
13847 try expect(v[0] == 529);13871 try expect(v[0] == 529);
...@@ -13985,7 +14009,6 @@ test "@Vector(64, f32)" {...@@ -13985,7 +14009,6 @@ test "@Vector(64, f32)" {
13985 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14009 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
13986 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;14010 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
13987 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14011 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
13988 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1398914012
13990 const v = c_ret_vector_64_f32();14013 const v = c_ret_vector_64_f32();
13991 try expect(v[0] == 753);14014 try expect(v[0] == 753);
...@@ -14180,7 +14203,6 @@ test "@Vector(96, f32)" {...@@ -14180,7 +14203,6 @@ test "@Vector(96, f32)" {
14180 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14203 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14181 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;14204 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
14182 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14205 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14183 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1418414206
14185 const v = c_ret_vector_96_f32();14207 const v = c_ret_vector_96_f32();
14186 try expect(v[0] == 1082);14208 try expect(v[0] == 1082);
...@@ -14443,7 +14465,6 @@ test "@Vector(128, f32)" {...@@ -14443,7 +14465,6 @@ test "@Vector(128, f32)" {
14443 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14465 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14444 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;14466 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
14445 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14467 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14446 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1444714468
14448 const v = c_ret_vector_128_f32();14469 const v = c_ret_vector_128_f32();
14449 try expect(v[0] == 1530);14470 try expect(v[0] == 1530);
...@@ -14651,7 +14672,6 @@ test "@Vector(3, f64)" {...@@ -14651,7 +14672,6 @@ test "@Vector(3, f64)" {
14651 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14672 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14652 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;14673 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
14653 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14674 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14654 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1465514675
14656 const v = c_ret_vector_3_f64();14676 const v = c_ret_vector_3_f64();
14657 try expect(v[0] == 19);14677 try expect(v[0] == 19);
...@@ -14680,8 +14700,6 @@ test "@Vector(4, f64)" {...@@ -14680,8 +14700,6 @@ test "@Vector(4, f64)" {
14680 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14700 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14681 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;14701 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
14682 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14702 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14683 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
14684 if (builtin.cpu.arch.isArm()) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35899
1468514703
14686 const v = c_ret_vector_4_f64();14704 const v = c_ret_vector_4_f64();
14687 try expect(v[0] == 33);14705 try expect(v[0] == 33);
...@@ -14714,7 +14732,6 @@ test "@Vector(6, f64)" {...@@ -14714,7 +14732,6 @@ test "@Vector(6, f64)" {
14714 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14732 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14715 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;14733 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
14716 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14734 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14717 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1471814735
14719 const v = c_ret_vector_6_f64();14736 const v = c_ret_vector_6_f64();
14720 try expect(v[0] == 53);14737 try expect(v[0] == 53);
...@@ -14750,8 +14767,6 @@ test "@Vector(8, f64)" {...@@ -14750,8 +14767,6 @@ test "@Vector(8, f64)" {
14750 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14767 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14751 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;14768 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
14752 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14769 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14753 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
14754 if (builtin.cpu.arch.isArm()) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35899
1475514770
14756 const v = c_ret_vector_8_f64();14771 const v = c_ret_vector_8_f64();
14757 try expect(v[0] == 81);14772 try expect(v[0] == 81);
...@@ -14794,7 +14809,6 @@ test "@Vector(12, f64)" {...@@ -14794,7 +14809,6 @@ test "@Vector(12, f64)" {
14794 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14809 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14795 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;14810 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
14796 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14811 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14797 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1479814812
14799 const v = c_ret_vector_12_f64();14813 const v = c_ret_vector_12_f64();
14800 try expect(v[0] == 121);14814 try expect(v[0] == 121);
...@@ -14845,7 +14859,6 @@ test "@Vector(16, f64)" {...@@ -14845,7 +14859,6 @@ test "@Vector(16, f64)" {
14845 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14859 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14846 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;14860 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
14847 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14861 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14848 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1484914862
14850 const v = c_ret_vector_16_f64();14863 const v = c_ret_vector_16_f64();
14851 try expect(v[0] == 177);14864 try expect(v[0] == 177);
...@@ -14911,7 +14924,6 @@ test "@Vector(24, f64)" {...@@ -14911,7 +14924,6 @@ test "@Vector(24, f64)" {
14911 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;14924 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14912 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;14925 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
14913 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;14926 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14914 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1491514927
14916 const v = c_ret_vector_24_f64();14928 const v = c_ret_vector_24_f64();
14917 try expect(v[0] == 257);14929 try expect(v[0] == 257);
...@@ -14996,7 +15008,6 @@ test "@Vector(32, f64)" {...@@ -14996,7 +15008,6 @@ test "@Vector(32, f64)" {
14996 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15008 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
14997 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;15009 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
14998 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;15010 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
14999 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1500015011
15001 const v = c_ret_vector_32_f64();15012 const v = c_ret_vector_32_f64();
15002 try expect(v[0] == 369);15013 try expect(v[0] == 369);
...@@ -15106,7 +15117,6 @@ test "@Vector(48, f64)" {...@@ -15106,7 +15117,6 @@ test "@Vector(48, f64)" {
15106 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15117 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15107 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;15118 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
15108 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;15119 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
15109 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1511015120
15111 const v = c_ret_vector_48_f64();15121 const v = c_ret_vector_48_f64();
15112 try expect(v[0] == 529);15122 try expect(v[0] == 529);
...@@ -15250,7 +15260,6 @@ test "@Vector(64, f64)" {...@@ -15250,7 +15260,6 @@ test "@Vector(64, f64)" {
15250 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15260 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15251 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;15261 if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest;
15252 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;15262 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
15253 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1525415263
15255 const v = c_ret_vector_64_f64();15264 const v = c_ret_vector_64_f64();
15256 try expect(v[0] == 753);15265 try expect(v[0] == 753);
...@@ -15345,7 +15354,6 @@ extern fn c_test_struct_u8() void;...@@ -15345,7 +15354,6 @@ extern fn c_test_struct_u8() void;
15345test "struct u8" {15354test "struct u8" {
15346 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15355 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15347 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;15356 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15348 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15349 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;15357 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1535015358
15351 const s = c_ret_struct_u8();15359 const s = c_ret_struct_u8();
...@@ -15376,8 +15384,7 @@ test "struct u8, u8" {...@@ -15376,8 +15384,7 @@ test "struct u8, u8" {
15376 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15384 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15377 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15385 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15378 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15386 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15379 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15387 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15380 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15381 if (builtin.cpu.arch == .x86) return error.SkipZigTest;15388 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1538215389
15383 const s = c_ret_struct_u8_u8();15390 const s = c_ret_struct_u8_u8();
...@@ -15411,8 +15418,7 @@ test "struct u8, u8, u8" {...@@ -15411,8 +15418,7 @@ test "struct u8, u8, u8" {
15411 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15418 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15412 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15419 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15413 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15420 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15414 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15421 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15415 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15416 if (builtin.cpu.arch == .x86) return error.SkipZigTest;15422 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1541715423
15418 const s = c_ret_struct_u8_u8_u8();15424 const s = c_ret_struct_u8_u8_u8();
...@@ -15449,8 +15455,7 @@ test "struct u8, u8, u8, u8" {...@@ -15449,8 +15455,7 @@ test "struct u8, u8, u8, u8" {
15449 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15455 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15450 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15456 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15451 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15457 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15452 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15458 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15453 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15454 if (builtin.cpu.arch == .x86) return error.SkipZigTest;15459 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1545515460
15456 const s = c_ret_struct_u8_u8_u8_u8();15461 const s = c_ret_struct_u8_u8_u8_u8();
...@@ -15481,7 +15486,6 @@ extern fn c_test_struct_u16() void;...@@ -15481,7 +15486,6 @@ extern fn c_test_struct_u16() void;
15481test "struct u16" {15486test "struct u16" {
15482 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15487 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15483 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;15488 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15484 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15485 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;15489 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1548615490
15487 const s = c_ret_struct_u16();15491 const s = c_ret_struct_u16();
...@@ -15512,8 +15516,7 @@ test "struct u16, u16" {...@@ -15512,8 +15516,7 @@ test "struct u16, u16" {
15512 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15516 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15513 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15517 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15514 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15518 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15515 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15519 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15516 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15517 if (builtin.cpu.arch == .x86) return error.SkipZigTest;15520 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1551815521
15519 const s = c_ret_struct_u16_u16();15522 const s = c_ret_struct_u16_u16();
...@@ -15547,9 +15550,8 @@ test "struct u16, u16, u16" {...@@ -15547,9 +15550,8 @@ test "struct u16, u16, u16" {
15547 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15550 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15548 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15551 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15549 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15552 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15550 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15553 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15551 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;15554 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;
15552 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15553 if (builtin.cpu.arch == .x86) return error.SkipZigTest;15555 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1555415556
15555 const s = c_ret_struct_u16_u16_u16();15557 const s = c_ret_struct_u16_u16_u16();
...@@ -15586,9 +15588,8 @@ test "struct u16, u16, u16, u16" {...@@ -15586,9 +15588,8 @@ test "struct u16, u16, u16, u16" {
15586 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15588 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15587 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15589 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15588 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15590 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15589 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15591 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15590 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;15592 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;
15591 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15592 if (builtin.cpu.arch == .x86) return error.SkipZigTest;15593 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1559315594
15594 const s = c_ret_struct_u16_u16_u16_u16();15595 const s = c_ret_struct_u16_u16_u16_u16();
...@@ -15619,7 +15620,6 @@ extern fn c_test_struct_u32() void;...@@ -15619,7 +15620,6 @@ extern fn c_test_struct_u32() void;
15619test "struct u32" {15620test "struct u32" {
15620 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15621 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15621 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;15622 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15622 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15623 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;15623 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1562415624
15625 const s = c_ret_struct_u32();15625 const s = c_ret_struct_u32();
...@@ -15649,9 +15649,8 @@ extern fn c_test_struct_u32_u32() void;...@@ -15649,9 +15649,8 @@ extern fn c_test_struct_u32_u32() void;
15649test "struct u32, u32" {15649test "struct u32, u32" {
15650 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15650 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15651 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15651 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15652 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15652 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15653 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;15653 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;
15654 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15655 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;15654 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1565615655
15657 const s = c_ret_struct_u32_u32();15656 const s = c_ret_struct_u32_u32();
...@@ -15685,8 +15684,7 @@ test "struct u32, u32, u32" {...@@ -15685,8 +15684,7 @@ test "struct u32, u32, u32" {
15685 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15684 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15686 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15685 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15687 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15686 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15688 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15687 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15689 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1569015688
15691 const s = c_ret_struct_u32_u32_u32();15689 const s = c_ret_struct_u32_u32_u32();
15692 try expect(s.a == 8);15690 try expect(s.a == 8);
...@@ -15722,8 +15720,7 @@ test "struct u32, u32, u32, u32" {...@@ -15722,8 +15720,7 @@ test "struct u32, u32, u32, u32" {
15722 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15720 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15723 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15721 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15724 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15722 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15725 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15723 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15726 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1572715724
15728 const s = c_ret_struct_u32_u32_u32_u32();15725 const s = c_ret_struct_u32_u32_u32_u32();
15729 try expect(s.a == 10);15726 try expect(s.a == 10);
...@@ -15753,7 +15750,6 @@ extern fn c_test_struct_u64() void;...@@ -15753,7 +15750,6 @@ extern fn c_test_struct_u64() void;
15753test "struct u64" {15750test "struct u64" {
15754 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;15751 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15755 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;15752 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;
15756 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15757 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;15753 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1575815754
15759 const s = c_ret_struct_u64();15755 const s = c_ret_struct_u64();
...@@ -15831,7 +15827,6 @@ extern fn c_test_struct_u64_u64() void;...@@ -15831,7 +15827,6 @@ extern fn c_test_struct_u64_u64() void;
15831test "struct u64, u64" {15827test "struct u64, u64" {
15832 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15828 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15833 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;15829 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15834 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1583515830
15836 const s = c_ret_struct_u64_u64();15831 const s = c_ret_struct_u64_u64();
15837 try expect(s.a == 21);15832 try expect(s.a == 21);
...@@ -15871,8 +15866,7 @@ extern fn c_test_struct_u64_u64_u64() void;...@@ -15871,8 +15866,7 @@ extern fn c_test_struct_u64_u64_u64() void;
15871test "struct u64, u64, u64" {15866test "struct u64, u64, u64" {
15872 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15867 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15873 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15868 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15874 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15869 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15875 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1587615870
15877 const s = c_ret_struct_u64_u64_u64();15871 const s = c_ret_struct_u64_u64_u64();
15878 try expect(s.a == 8);15872 try expect(s.a == 8);
...@@ -15907,8 +15901,7 @@ extern fn c_test_struct_u64_u64_u64_u64() void;...@@ -15907,8 +15901,7 @@ extern fn c_test_struct_u64_u64_u64_u64() void;
15907test "struct u64, u64, u64, u64" {15901test "struct u64, u64, u64, u64" {
15908 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;15902 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
15909 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15903 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
15910 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15904 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
15911 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1591215905
15913 const s = c_ret_struct_u64_u64_u64_u64();15906 const s = c_ret_struct_u64_u64_u64_u64();
15914 try expect(s.a == 10);15907 try expect(s.a == 10);
...@@ -15937,8 +15930,7 @@ extern fn c_test_struct_f32() void;...@@ -15937,8 +15930,7 @@ extern fn c_test_struct_f32() void;
1593715930
15938test "struct f32" {15931test "struct f32" {
15939 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15932 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15940 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;15933 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
15941 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15942 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;15934 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1594315935
15944 const s = c_ret_struct_f32();15936 const s = c_ret_struct_f32();
...@@ -15971,7 +15963,6 @@ test "struct f32, f32" {...@@ -15971,7 +15963,6 @@ test "struct f32, f32" {
15971 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15963 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
15972 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;15964 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
15973 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;15965 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;
15974 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
15975 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;15966 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1597615967
15977 const s = c_ret_struct_f32_f32();15968 const s = c_ret_struct_f32_f32();
...@@ -16007,7 +15998,6 @@ test "struct f32, f32, f32" {...@@ -16007,7 +15998,6 @@ test "struct f32, f32, f32" {
16007 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;15998 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
16008 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;15999 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16009 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;16000 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16010 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1601116001
16012 const s = c_ret_struct_f32_f32_f32();16002 const s = c_ret_struct_f32_f32_f32();
16013 try expect(s.a == 8);16003 try expect(s.a == 8);
...@@ -16045,7 +16035,6 @@ test "struct f32, f32, f32, f32" {...@@ -16045,7 +16035,6 @@ test "struct f32, f32, f32, f32" {
16045 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;16035 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
16046 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;16036 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16047 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;16037 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16048 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1604916038
16050 const s = c_ret_struct_f32_f32_f32_f32();16039 const s = c_ret_struct_f32_f32_f32_f32();
16051 try expect(s.a == 10);16040 try expect(s.a == 10);
...@@ -16085,7 +16074,6 @@ test "struct f32, f32, f32, f32, f32" {...@@ -16085,7 +16074,6 @@ test "struct f32, f32, f32, f32, f32" {
16085 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;16074 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
16086 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;16075 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16087 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;16076 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16088 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1608916077
16090 const s = c_ret_struct_f32_f32_f32_f32_f32();16078 const s = c_ret_struct_f32_f32_f32_f32_f32();
16091 try expect(s.a == 12);16079 try expect(s.a == 12);
...@@ -16097,6 +16085,181 @@ test "struct f32, f32, f32, f32, f32" {...@@ -16097,6 +16085,181 @@ test "struct f32, f32, f32, f32, f32" {
16097 c_test_struct_f32_f32_f32_f32_f32();16085 c_test_struct_f32_f32_f32_f32_f32();
16098}16086}
1609916087
16088const Struct_array_1_f32 = extern struct {
16089 a: [1]f32,
16090};
16091
16092comptime {
16093 skip: {
16094 if (builtin.cpu.arch.isWasm()) break :skip;
16095
16096 _ = struct {
16097 export fn zig_ret_struct_array_1_f32() Struct_array_1_f32 {
16098 return .{ .a = .{1} };
16099 }
16100 export fn zig_struct_array_1_f32(s: Struct_array_1_f32, i: usize) void {
16101 expect(s.a[0] == 2) catch @panic("test failure");
16102 expect(i == 3) catch @panic("test failure");
16103 }
16104 };
16105 }
16106}
16107
16108extern fn c_ret_struct_array_1_f32() Struct_array_1_f32;
16109extern fn c_struct_array_1_f32(Struct_array_1_f32, usize) void;
16110extern fn c_test_struct_array_1_f32() void;
16111
16112test "struct [1]f32" {
16113 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16114 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16115 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16116 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16117 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16118 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16119 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;
16120
16121 const s = c_ret_struct_array_1_f32();
16122 try expect(s.a[0] == 4);
16123 c_struct_array_1_f32(.{ .a = .{5} }, 6);
16124 c_test_struct_array_1_f32();
16125}
16126
16127const Struct_array_2_f32 = extern struct {
16128 a: [2]f32,
16129};
16130
16131export fn zig_ret_struct_array_2_f32() Struct_array_2_f32 {
16132 return .{ .a = .{ 1, 2 } };
16133}
16134export fn zig_struct_array_2_f32(s: Struct_array_2_f32, i: usize) void {
16135 expect(s.a[0] == 3) catch @panic("test failure");
16136 expect(s.a[1] == 4) catch @panic("test failure");
16137 expect(i == 5) catch @panic("test failure");
16138}
16139
16140extern fn c_ret_struct_array_2_f32() Struct_array_2_f32;
16141extern fn c_struct_array_2_f32(Struct_array_2_f32, usize) void;
16142extern fn c_test_struct_array_2_f32() void;
16143
16144test "struct [2]f32" {
16145 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16146 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16147 if (builtin.cpu.arch == .loongarch64 and builtin.abi.float() == .hard) return error.SkipZigTest;
16148 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16149 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16150 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16151
16152 const s = c_ret_struct_array_2_f32();
16153 try expect(s.a[0] == 6);
16154 try expect(s.a[1] == 7);
16155 c_struct_array_2_f32(.{ .a = .{ 8, 9 } }, 10);
16156 c_test_struct_array_2_f32();
16157}
16158
16159const Struct_array_3_f32 = extern struct {
16160 a: [3]f32,
16161};
16162
16163export fn zig_ret_struct_array_3_f32() Struct_array_3_f32 {
16164 return .{ .a = .{ 1, 2, 3 } };
16165}
16166export fn zig_struct_array_3_f32(s: Struct_array_3_f32, i: usize) void {
16167 expect(s.a[0] == 4) catch @panic("test failure");
16168 expect(s.a[1] == 5) catch @panic("test failure");
16169 expect(s.a[2] == 6) catch @panic("test failure");
16170 expect(i == 7) catch @panic("test failure");
16171}
16172
16173extern fn c_ret_struct_array_3_f32() Struct_array_3_f32;
16174extern fn c_struct_array_3_f32(Struct_array_3_f32, usize) void;
16175extern fn c_test_struct_array_3_f32() void;
16176
16177test "struct [3]f32" {
16178 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16179 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16180 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16181 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16182 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16183
16184 const s = c_ret_struct_array_3_f32();
16185 try expect(s.a[0] == 8);
16186 try expect(s.a[1] == 9);
16187 try expect(s.a[2] == 10);
16188 c_struct_array_3_f32(.{ .a = .{ 11, 12, 13 } }, 14);
16189 c_test_struct_array_3_f32();
16190}
16191
16192const Struct_array_4_f32 = extern struct {
16193 a: [4]f32,
16194};
16195
16196export fn zig_ret_struct_array_4_f32() Struct_array_4_f32 {
16197 return .{ .a = .{ 1, 2, 3, 4 } };
16198}
16199export fn zig_struct_array_4_f32(s: Struct_array_4_f32, i: usize) void {
16200 expect(s.a[0] == 5) catch @panic("test failure");
16201 expect(s.a[1] == 6) catch @panic("test failure");
16202 expect(s.a[2] == 7) catch @panic("test failure");
16203 expect(s.a[3] == 8) catch @panic("test failure");
16204 expect(i == 9) catch @panic("test failure");
16205}
16206
16207extern fn c_ret_struct_array_4_f32() Struct_array_4_f32;
16208extern fn c_struct_array_4_f32(Struct_array_4_f32, usize) void;
16209extern fn c_test_struct_array_4_f32() void;
16210
16211test "struct [4]f32" {
16212 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16213 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16214 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16215 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16216 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16217
16218 const s = c_ret_struct_array_4_f32();
16219 try expect(s.a[0] == 10);
16220 try expect(s.a[1] == 11);
16221 try expect(s.a[2] == 12);
16222 try expect(s.a[3] == 13);
16223 c_struct_array_4_f32(.{ .a = .{ 14, 15, 16, 17 } }, 18);
16224 c_test_struct_array_4_f32();
16225}
16226
16227const Struct_array_5_f32 = extern struct {
16228 a: [5]f32,
16229};
16230
16231export fn zig_ret_struct_array_5_f32() Struct_array_5_f32 {
16232 return .{ .a = .{ 1, 2, 3, 4, 5 } };
16233}
16234export fn zig_struct_array_5_f32(s: Struct_array_5_f32, i: usize) void {
16235 expect(s.a[0] == 6) catch @panic("test failure");
16236 expect(s.a[1] == 7) catch @panic("test failure");
16237 expect(s.a[2] == 8) catch @panic("test failure");
16238 expect(s.a[3] == 9) catch @panic("test failure");
16239 expect(s.a[4] == 10) catch @panic("test failure");
16240 expect(i == 11) catch @panic("test failure");
16241}
16242
16243extern fn c_ret_struct_array_5_f32() Struct_array_5_f32;
16244extern fn c_struct_array_5_f32(Struct_array_5_f32, usize) void;
16245extern fn c_test_struct_array_5_f32() void;
16246
16247test "struct [5]f32" {
16248 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16249 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16250 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16251 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16252
16253 const s = c_ret_struct_array_5_f32();
16254 try expect(s.a[0] == 12);
16255 try expect(s.a[1] == 13);
16256 try expect(s.a[2] == 14);
16257 try expect(s.a[3] == 15);
16258 try expect(s.a[4] == 16);
16259 c_struct_array_5_f32(.{ .a = .{ 17, 18, 19, 20, 21 } }, 22);
16260 c_test_struct_array_5_f32();
16261}
16262
16100const Struct_f32a8 = extern struct {16263const Struct_f32a8 = extern struct {
16101 a: f32 align(8),16264 a: f32 align(8),
16102};16265};
...@@ -16120,7 +16283,6 @@ test "struct f32 align(8)" {...@@ -16120,7 +16283,6 @@ test "struct f32 align(8)" {
16120 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;16283 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16121 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;16284 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16122 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;16285 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;
16123 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16124 if (builtin.cpu.arch == .x86) return error.SkipZigTest;16286 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1612516287
16126 const s = c_ret_struct_f32a8();16288 const s = c_ret_struct_f32a8();
...@@ -16154,7 +16316,6 @@ test "struct f32 align(8), f32 align(8)" {...@@ -16154,7 +16316,6 @@ test "struct f32 align(8), f32 align(8)" {
16154 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;16316 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16155 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;16317 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16156 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;16318 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16157 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16158 if (builtin.cpu.arch == .x86) return error.SkipZigTest;16319 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1615916320
16160 const s = c_ret_struct_f32a8_f32a8();16321 const s = c_ret_struct_f32a8_f32a8();
...@@ -16187,8 +16348,7 @@ test "struct {f32, f32}, f32" {...@@ -16187,8 +16348,7 @@ test "struct {f32, f32}, f32" {
16187 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16348 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16188 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;16349 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
16189 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;16350 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16190 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;16351 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16191 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1619216352
16193 const s = c_ret_struct_f32f32_f32();16353 const s = c_ret_struct_f32f32_f32();
16194 try expect(s.a.b == 1.0);16354 try expect(s.a.b == 1.0);
...@@ -16221,8 +16381,7 @@ test "struct f32, {f32, f32}" {...@@ -16221,8 +16381,7 @@ test "struct f32, {f32, f32}" {
16221 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16381 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16222 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;16382 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
16223 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;16383 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16224 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;16384 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16225 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1622616385
16227 const s = c_ret_struct_f32_f32f32();16386 const s = c_ret_struct_f32_f32f32();
16228 try expect(s.a == 1.0);16387 try expect(s.a == 1.0);
...@@ -16250,9 +16409,8 @@ extern fn c_test_struct_f64() void;...@@ -16250,9 +16409,8 @@ extern fn c_test_struct_f64() void;
1625016409
16251test "struct f64" {16410test "struct f64" {
16252 if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest;16411 if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest;
16253 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;16412 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16254 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;16413 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;
16255 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16256 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;16414 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1625716415
16258 const s = c_ret_struct_f64();16416 const s = c_ret_struct_f64();
...@@ -16282,8 +16440,7 @@ extern fn c_test_struct_f64_f64() void;...@@ -16282,8 +16440,7 @@ extern fn c_test_struct_f64_f64() void;
16282test "struct f64, f64" {16440test "struct f64, f64" {
16283 if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest;16441 if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest;
16284 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16442 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16285 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;16443 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16286 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1628716444
16288 const s = c_ret_struct_f64_f64();16445 const s = c_ret_struct_f64_f64();
16289 try expect(s.a == 6);16446 try expect(s.a == 6);
...@@ -16315,8 +16472,7 @@ extern fn c_test_struct_f64_f64_f64() void;...@@ -16315,8 +16472,7 @@ extern fn c_test_struct_f64_f64_f64() void;
16315test "struct f64, f64, f64" {16472test "struct f64, f64, f64" {
16316 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16473 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16317 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;16474 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
16318 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;16475 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16319 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1632016476
16321 const s = c_ret_struct_f64_f64_f64();16477 const s = c_ret_struct_f64_f64_f64();
16322 try expect(s.a == 8);16478 try expect(s.a == 8);
...@@ -16351,8 +16507,7 @@ extern fn c_test_struct_f64_f64_f64_f64() void;...@@ -16351,8 +16507,7 @@ extern fn c_test_struct_f64_f64_f64_f64() void;
16351test "struct f64, f64, f64, f64" {16507test "struct f64, f64, f64, f64" {
16352 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16508 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16353 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;16509 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
16354 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;16510 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16355 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1635616511
16357 const s = c_ret_struct_f64_f64_f64_f64();16512 const s = c_ret_struct_f64_f64_f64_f64();
16358 try expect(s.a == 10);16513 try expect(s.a == 10);
...@@ -16390,8 +16545,7 @@ extern fn c_test_struct_f64_f64_f64_f64_f64() void;...@@ -16390,8 +16545,7 @@ extern fn c_test_struct_f64_f64_f64_f64_f64() void;
16390test "struct f64, f64, f64, f64, f64" {16545test "struct f64, f64, f64, f64, f64" {
16391 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16546 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16392 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;16547 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
16393 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;16548 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16394 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1639516549
16396 const s = c_ret_struct_f64_f64_f64_f64_f64();16550 const s = c_ret_struct_f64_f64_f64_f64_f64();
16397 try expect(s.a == 12);16551 try expect(s.a == 12);
...@@ -16403,6 +16557,181 @@ test "struct f64, f64, f64, f64, f64" {...@@ -16403,6 +16557,181 @@ test "struct f64, f64, f64, f64, f64" {
16403 c_test_struct_f64_f64_f64_f64_f64();16557 c_test_struct_f64_f64_f64_f64_f64();
16404}16558}
1640516559
16560const Struct_array_1_f64 = extern struct {
16561 a: [1]f64,
16562};
16563
16564comptime {
16565 skip: {
16566 if (builtin.cpu.arch.isWasm()) break :skip;
16567
16568 _ = struct {
16569 export fn zig_ret_struct_array_1_f64() Struct_array_1_f64 {
16570 return .{ .a = .{1} };
16571 }
16572 export fn zig_struct_array_1_f64(s: Struct_array_1_f64, i: usize) void {
16573 expect(s.a[0] == 2) catch @panic("test failure");
16574 expect(i == 3) catch @panic("test failure");
16575 }
16576 };
16577 }
16578}
16579
16580extern fn c_ret_struct_array_1_f64() Struct_array_1_f64;
16581extern fn c_struct_array_1_f64(Struct_array_1_f64, usize) void;
16582extern fn c_test_struct_array_1_f64() void;
16583
16584test "struct [1]f64" {
16585 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16586 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16587 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16588 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16589 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16590 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16591 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;
16592
16593 const s = c_ret_struct_array_1_f64();
16594 try expect(s.a[0] == 4);
16595 c_struct_array_1_f64(.{ .a = .{5} }, 6);
16596 c_test_struct_array_1_f64();
16597}
16598
16599const Struct_array_2_f64 = extern struct {
16600 a: [2]f64,
16601};
16602
16603export fn zig_ret_struct_array_2_f64() Struct_array_2_f64 {
16604 return .{ .a = .{ 1, 2 } };
16605}
16606export fn zig_struct_array_2_f64(s: Struct_array_2_f64, i: usize) void {
16607 expect(s.a[0] == 3) catch @panic("test failure");
16608 expect(s.a[1] == 4) catch @panic("test failure");
16609 expect(i == 5) catch @panic("test failure");
16610}
16611
16612extern fn c_ret_struct_array_2_f64() Struct_array_2_f64;
16613extern fn c_struct_array_2_f64(Struct_array_2_f64, usize) void;
16614extern fn c_test_struct_array_2_f64() void;
16615
16616test "struct [2]f64" {
16617 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16618 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16619 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16620 if (builtin.cpu.arch == .loongarch64 and builtin.abi.float() == .hard) return error.SkipZigTest;
16621 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16622 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16623 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16624
16625 const s = c_ret_struct_array_2_f64();
16626 try expect(s.a[0] == 6);
16627 try expect(s.a[1] == 7);
16628 c_struct_array_2_f64(.{ .a = .{ 8, 9 } }, 10);
16629 c_test_struct_array_2_f64();
16630}
16631
16632const Struct_array_3_f64 = extern struct {
16633 a: [3]f64,
16634};
16635
16636export fn zig_ret_struct_array_3_f64() Struct_array_3_f64 {
16637 return .{ .a = .{ 1, 2, 3 } };
16638}
16639export fn zig_struct_array_3_f64(s: Struct_array_3_f64, i: usize) void {
16640 expect(s.a[0] == 4) catch @panic("test failure");
16641 expect(s.a[1] == 5) catch @panic("test failure");
16642 expect(s.a[2] == 6) catch @panic("test failure");
16643 expect(i == 7) catch @panic("test failure");
16644}
16645
16646extern fn c_ret_struct_array_3_f64() Struct_array_3_f64;
16647extern fn c_struct_array_3_f64(Struct_array_3_f64, usize) void;
16648extern fn c_test_struct_array_3_f64() void;
16649
16650test "struct [3]f64" {
16651 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16652 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16653 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16654 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16655 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16656
16657 const s = c_ret_struct_array_3_f64();
16658 try expect(s.a[0] == 8);
16659 try expect(s.a[1] == 9);
16660 try expect(s.a[2] == 10);
16661 c_struct_array_3_f64(.{ .a = .{ 11, 12, 13 } }, 14);
16662 c_test_struct_array_3_f64();
16663}
16664
16665const Struct_array_4_f64 = extern struct {
16666 a: [4]f64,
16667};
16668
16669export fn zig_ret_struct_array_4_f64() Struct_array_4_f64 {
16670 return .{ .a = .{ 1, 2, 3, 4 } };
16671}
16672export fn zig_struct_array_4_f64(s: Struct_array_4_f64, i: usize) void {
16673 expect(s.a[0] == 5) catch @panic("test failure");
16674 expect(s.a[1] == 6) catch @panic("test failure");
16675 expect(s.a[2] == 7) catch @panic("test failure");
16676 expect(s.a[3] == 8) catch @panic("test failure");
16677 expect(i == 9) catch @panic("test failure");
16678}
16679
16680extern fn c_ret_struct_array_4_f64() Struct_array_4_f64;
16681extern fn c_struct_array_4_f64(Struct_array_4_f64, usize) void;
16682extern fn c_test_struct_array_4_f64() void;
16683
16684test "struct [4]f64" {
16685 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16686 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16687 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16688 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16689 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16690
16691 const s = c_ret_struct_array_4_f64();
16692 try expect(s.a[0] == 10);
16693 try expect(s.a[1] == 11);
16694 try expect(s.a[2] == 12);
16695 try expect(s.a[3] == 13);
16696 c_struct_array_4_f64(.{ .a = .{ 14, 15, 16, 17 } }, 18);
16697 c_test_struct_array_4_f64();
16698}
16699
16700const Struct_array_5_f64 = extern struct {
16701 a: [5]f64,
16702};
16703
16704export fn zig_ret_struct_array_5_f64() Struct_array_5_f64 {
16705 return .{ .a = .{ 1, 2, 3, 4, 5 } };
16706}
16707export fn zig_struct_array_5_f64(s: Struct_array_5_f64, i: usize) void {
16708 expect(s.a[0] == 6) catch @panic("test failure");
16709 expect(s.a[1] == 7) catch @panic("test failure");
16710 expect(s.a[2] == 8) catch @panic("test failure");
16711 expect(s.a[3] == 9) catch @panic("test failure");
16712 expect(s.a[4] == 10) catch @panic("test failure");
16713 expect(i == 11) catch @panic("test failure");
16714}
16715
16716extern fn c_ret_struct_array_5_f64() Struct_array_5_f64;
16717extern fn c_struct_array_5_f64(Struct_array_5_f64, usize) void;
16718extern fn c_test_struct_array_5_f64() void;
16719
16720test "struct [5]f64" {
16721 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16722 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16723 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16724
16725 const s = c_ret_struct_array_5_f64();
16726 try expect(s.a[0] == 12);
16727 try expect(s.a[1] == 13);
16728 try expect(s.a[2] == 14);
16729 try expect(s.a[3] == 15);
16730 try expect(s.a[4] == 16);
16731 c_struct_array_5_f64(.{ .a = .{ 17, 18, 19, 20, 21 } }, 22);
16732 c_test_struct_array_5_f64();
16733}
16734
16406const Struct_u32_Union_u32_u32u32 = extern struct {16735const Struct_u32_Union_u32_u32u32 = extern struct {
16407 a: u32,16736 a: u32,
16408 b: extern union {16737 b: extern union {
...@@ -16430,8 +16759,7 @@ test "struct{u32,union{u32,struct{u32,u32}}}" {...@@ -16430,8 +16759,7 @@ test "struct{u32,union{u32,struct{u32,u32}}}" {
16430 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16759 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16431 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;16760 if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest;
16432 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;16761 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16433 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;16762 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16434 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1643516763
16436 const s = c_ret_struct_u32_union_u32_u32u32();16764 const s = c_ret_struct_u32_union_u32_u32u32();
16437 try expect(s.a == 1);16765 try expect(s.a == 1);
...@@ -16449,11 +16777,10 @@ extern fn c_mut_struct_i32_i32(Struct_i32_i32) Struct_i32_i32;...@@ -16449,11 +16777,10 @@ extern fn c_mut_struct_i32_i32(Struct_i32_i32) Struct_i32_i32;
16449extern fn c_struct_i32_i32(Struct_i32_i32) void;16777extern fn c_struct_i32_i32(Struct_i32_i32) void;
1645016778
16451test "struct i32 i32" {16779test "struct i32 i32" {
16780 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16452 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;16781 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16453 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;16782 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16454 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;16783 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;
16455 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16456 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16457 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;16784 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1645816785
16459 const s: Struct_i32_i32 = .{16786 const s: Struct_i32_i32 = .{
...@@ -16483,11 +16810,10 @@ const BigStruct = extern struct {...@@ -16483,11 +16810,10 @@ const BigStruct = extern struct {
16483extern fn c_big_struct(BigStruct) void;16810extern fn c_big_struct(BigStruct) void;
1648416811
16485test "big struct" {16812test "big struct" {
16486 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16487 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16488 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16489 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16813 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16490 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;16814 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16815 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16816 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
1649116817
16492 const s = BigStruct{16818 const s = BigStruct{
16493 .a = 1,16819 .a = 1,
...@@ -16513,10 +16839,9 @@ const BigUnion = extern union {...@@ -16513,10 +16839,9 @@ const BigUnion = extern union {
16513extern fn c_big_union(BigUnion) void;16839extern fn c_big_union(BigUnion) void;
1651416840
16515test "big union" {16841test "big union" {
16516 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16517 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16518 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16842 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16519 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;16843 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16844 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
1652016845
16521 const x = BigUnion{16846 const x = BigUnion{
16522 .a = BigStruct{16847 .a = BigStruct{
...@@ -16548,11 +16873,10 @@ extern fn c_med_struct_mixed(MedStructMixed) void;...@@ -16548,11 +16873,10 @@ extern fn c_med_struct_mixed(MedStructMixed) void;
16548extern fn c_ret_med_struct_mixed() MedStructMixed;16873extern fn c_ret_med_struct_mixed() MedStructMixed;
1654916874
16550test "medium struct of ints and floats" {16875test "medium struct of ints and floats" {
16551 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16552 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16553 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16554 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16876 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16555 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;16877 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16878 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16879 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
1655616880
16557 const s = MedStructMixed{16881 const s = MedStructMixed{
16558 .a = 1234,16882 .a = 1234,
...@@ -16628,12 +16952,11 @@ const SplitStructInt = extern struct {...@@ -16628,12 +16952,11 @@ const SplitStructInt = extern struct {
16628extern fn c_split_struct_ints(SplitStructInt) void;16952extern fn c_split_struct_ints(SplitStructInt) void;
1662916953
16630test "split struct of ints" {16954test "split struct of ints" {
16631 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
16632 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16633 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16634 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16635 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16955 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16636 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;16956 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16957 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16958 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16959 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1663716960
16638 const s = SplitStructInt{16961 const s = SplitStructInt{
16639 .a = 1234,16962 .a = 1234,
...@@ -16658,12 +16981,11 @@ extern fn c_split_struct_mixed(SplitStructMixed) void;...@@ -16658,12 +16981,11 @@ extern fn c_split_struct_mixed(SplitStructMixed) void;
16658extern fn c_ret_split_struct_mixed() SplitStructMixed;16981extern fn c_ret_split_struct_mixed() SplitStructMixed;
1665916982
16660test "split struct of ints and floats" {16983test "split struct of ints and floats" {
16661 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
16662 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16663 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16664 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16665 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;16984 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16666 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;16985 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16986 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16987 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16988 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1666716989
16668 const s = SplitStructMixed{16990 const s = SplitStructMixed{
16669 .a = 1234,16991 .a = 1234,
...@@ -16686,11 +17008,10 @@ export fn zig_split_struct_mixed(x: SplitStructMixed) void {...@@ -16686,11 +17008,10 @@ export fn zig_split_struct_mixed(x: SplitStructMixed) void {
16686extern fn c_big_struct_both(BigStruct) BigStruct;17008extern fn c_big_struct_both(BigStruct) BigStruct;
1668717009
16688test "sret and byval together" {17010test "sret and byval together" {
16689 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16690 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16691 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16692 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17011 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16693 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17012 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17013 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17014 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
1669417015
16695 const s = BigStruct{17016 const s = BigStruct{
16696 .a = 1,17017 .a = 1,
...@@ -16800,12 +17121,11 @@ extern fn c_struct_with_array(StructWithArray) void;...@@ -16800,12 +17121,11 @@ extern fn c_struct_with_array(StructWithArray) void;
16800extern fn c_ret_struct_with_array() StructWithArray;17121extern fn c_ret_struct_with_array() StructWithArray;
1680117122
16802test "Struct with array as padding." {17123test "Struct with array as padding." {
16803 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
16804 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16805 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16806 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16807 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17124 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16808 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17125 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17126 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17127 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17128 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1680917129
16810 c_struct_with_array(.{ .a = 1, .padding = undefined, .b = 2 });17130 c_struct_with_array(.{ .a = 1, .padding = undefined, .b = 2 });
1681117131
...@@ -16829,11 +17149,10 @@ extern fn c_float_array_struct(FloatArrayStruct) void;...@@ -16829,11 +17149,10 @@ extern fn c_float_array_struct(FloatArrayStruct) void;
16829extern fn c_ret_float_array_struct() FloatArrayStruct;17149extern fn c_ret_float_array_struct() FloatArrayStruct;
1683017150
16831test "Float array like struct" {17151test "Float array like struct" {
16832 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16833 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16834 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16835 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17152 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16836 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17153 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17154 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17155 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
1683717156
16838 c_float_array_struct(.{17157 c_float_array_struct(.{
16839 .origin = .{17158 .origin = .{
...@@ -16864,37 +17183,37 @@ pub inline fn expectOk(c_err: c_int) !void {...@@ -16864,37 +17183,37 @@ pub inline fn expectOk(c_err: c_int) !void {
16864/// Tests for Double + Char struct17183/// Tests for Double + Char struct
16865const DC = extern struct { v1: f64, v2: u8 };17184const DC = extern struct { v1: f64, v2: u8 };
16866test "DC: Zig passes to C" {17185test "DC: Zig passes to C" {
17186 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
17187 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16867 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;17188 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17189 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16868 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;17190 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16869 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;17191
16870 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16871 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16872 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16873 try expectOk(c_assert_DC(.{ .v1 = -0.25, .v2 = 15 }));17192 try expectOk(c_assert_DC(.{ .v1 = -0.25, .v2 = 15 }));
16874}17193}
16875test "DC: Zig returns to C" {17194test "DC: Zig returns to C" {
17195 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16876 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;17196 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17197 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16877 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;17198 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16878 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;17199
16879 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16880 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16881 try expectOk(c_assert_ret_DC());17200 try expectOk(c_assert_ret_DC());
16882}17201}
16883test "DC: C passes to Zig" {17202test "DC: C passes to Zig" {
17203 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
17204 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16884 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;17205 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17206 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16885 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;17207 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16886 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;17208
16887 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16888 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16889 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16890 try expectOk(c_send_DC());17209 try expectOk(c_send_DC());
16891}17210}
16892test "DC: C returns to Zig" {17211test "DC: C returns to Zig" {
17212 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16893 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;17213 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17214 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16894 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;17215 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16895 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;17216
16896 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16897 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16898 try expectEqual(DC{ .v1 = -0.25, .v2 = 15 }, c_ret_DC());17217 try expectEqual(DC{ .v1 = -0.25, .v2 = 15 }, c_ret_DC());
16899}17218}
1690017219
...@@ -16919,36 +17238,35 @@ const CFF = extern struct { v1: u8, v2: f32, v3: f32 };...@@ -16919,36 +17238,35 @@ const CFF = extern struct { v1: u8, v2: f32, v3: f32 };
16919test "CFF: Zig passes to C" {17238test "CFF: Zig passes to C" {
16920 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;17239 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
16921 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;17240 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16922 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;17241 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16923 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;17242 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16924 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17243 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16925 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17244
16926 try expectOk(c_assert_CFF(.{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }));17245 try expectOk(c_assert_CFF(.{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }));
16927}17246}
16928test "CFF: Zig returns to C" {17247test "CFF: Zig returns to C" {
16929 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;17248 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16930 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;17249 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16931 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;17250 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16932 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17251
16933 try expectOk(c_assert_ret_CFF());17252 try expectOk(c_assert_ret_CFF());
16934}17253}
16935test "CFF: C passes to Zig" {17254test "CFF: C passes to Zig" {
16936 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
16937 if (builtin.cpu.arch.isRISCV() and builtin.mode != .debug) return error.SkipZigTest;
16938 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16939 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16940 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16941 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17255 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16942 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17256 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17257 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17258 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17259 if (builtin.cpu.arch.isRISCV() and builtin.mode != .debug) return error.SkipZigTest;
17260 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
1694317261
16944 try expectOk(c_send_CFF());17262 try expectOk(c_send_CFF());
16945}17263}
16946test "CFF: C returns to Zig" {17264test "CFF: C returns to Zig" {
16947 if (builtin.cpu.arch.isRISCV() and builtin.mode != .debug) return error.SkipZigTest;
16948 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16949 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16950 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;17265 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16951 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17266 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17267 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17268 if (builtin.cpu.arch.isRISCV() and builtin.mode != .debug) return error.SkipZigTest;
17269
16952 try expectEqual(CFF{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }, c_ret_CFF());17270 try expectEqual(CFF{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }, c_ret_CFF());
16953}17271}
16954pub extern fn c_assert_CFF(lv: CFF) c_int;17272pub extern fn c_assert_CFF(lv: CFF) c_int;
...@@ -16971,35 +17289,35 @@ pub export fn zig_ret_CFF() CFF {...@@ -16971,35 +17289,35 @@ pub export fn zig_ret_CFF() CFF {
16971const PD = extern struct { v1: ?*anyopaque, v2: f64 };17289const PD = extern struct { v1: ?*anyopaque, v2: f64 };
1697217290
16973test "PD: Zig passes to C" {17291test "PD: Zig passes to C" {
16974 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16975 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16976 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16977 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17292 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16978 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17293 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17294 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17295 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16979 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;17296 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
17297
16980 try expectOk(c_assert_PD(.{ .v1 = null, .v2 = 0.5 }));17298 try expectOk(c_assert_PD(.{ .v1 = null, .v2 = 0.5 }));
16981}17299}
16982test "PD: Zig returns to C" {17300test "PD: Zig returns to C" {
16983 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16984 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16985 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;17301 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16986 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17302 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17303 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17304
16987 try expectOk(c_assert_ret_PD());17305 try expectOk(c_assert_ret_PD());
16988}17306}
16989test "PD: C passes to Zig" {17307test "PD: C passes to Zig" {
16990 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16991 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16992 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
16993 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17308 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16994 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17309 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17310 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17311 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
16995 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;17312 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
17313
16996 try expectOk(c_send_PD());17314 try expectOk(c_send_PD());
16997}17315}
16998test "PD: C returns to Zig" {17316test "PD: C returns to Zig" {
16999 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17000 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
17001 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;17317 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17002 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17318 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17319 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17320
17003 try expectEqual(PD{ .v1 = null, .v2 = 0.5 }, c_ret_PD());17321 try expectEqual(PD{ .v1 = null, .v2 = 0.5 }, c_ret_PD());
17004}17322}
17005pub extern fn c_assert_PD(lv: PD) c_int;17323pub extern fn c_assert_PD(lv: PD) c_int;
...@@ -17033,7 +17351,6 @@ extern fn c_modify_by_ref_param(ByRef) ByRef;...@@ -17033,7 +17351,6 @@ extern fn c_modify_by_ref_param(ByRef) ByRef;
17033test "C function modifies by ref param" {17351test "C function modifies by ref param" {
17034 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;17352 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17035 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;17353 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17036 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1703717354
17038 const res = c_modify_by_ref_param(.{ .val = 1, .arr = undefined });17355 const res = c_modify_by_ref_param(.{ .val = 1, .arr = undefined });
17039 try expect(res.val == 42);17356 try expect(res.val == 42);
...@@ -17054,11 +17371,10 @@ const ByVal = extern struct {...@@ -17054,11 +17371,10 @@ const ByVal = extern struct {
1705417371
17055extern fn c_func_ptr_byval(*anyopaque, *anyopaque, ByVal, c_ulong, *anyopaque, c_ulong) void;17372extern fn c_func_ptr_byval(*anyopaque, *anyopaque, ByVal, c_ulong, *anyopaque, c_ulong) void;
17056test "C function that takes byval struct called via function pointer" {17373test "C function that takes byval struct called via function pointer" {
17374 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
17375 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17057 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;17376 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17058 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;17377 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17059 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17060 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
17061 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
1706217378
17063 var fn_ptr = &c_func_ptr_byval;17379 var fn_ptr = &c_func_ptr_byval;
17064 _ = &fn_ptr;17380 _ = &fn_ptr;
...@@ -17077,17 +17393,16 @@ test "C function that takes byval struct called via function pointer" {...@@ -17077,17 +17393,16 @@ test "C function that takes byval struct called via function pointer" {
1707717393
17078extern fn c_f16(f16) f16;17394extern fn c_f16(f16) f16;
17079test "f16 bare" {17395test "f16 bare" {
17080 if (builtin.cpu.arch == .x86_64) return error.SkipZigTest;17396 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
17081 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
17082 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17397 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
17083 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;17398 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17084 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;17399 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
17400 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
17085 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;17401 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
17086 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17402 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
17087 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;17403 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;
17088 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;17404 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
1708917405 if (builtin.cpu.arch == .x86_64) return error.SkipZigTest;
17090 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
1709117406
17092 const a = c_f16(12);17407 const a = c_f16(12);
17093 try expect(a == 34);17408 try expect(a == 34);
...@@ -17098,9 +17413,9 @@ const f16_struct = extern struct {...@@ -17098,9 +17413,9 @@ const f16_struct = extern struct {
17098};17413};
17099extern fn c_f16_struct(f16_struct) f16_struct;17414extern fn c_f16_struct(f16_struct) f16_struct;
17100test "f16 struct" {17415test "f16 struct" {
17416 if (builtin.cpu.arch.isArm() and builtin.mode != .debug) return error.SkipZigTest;
17101 if (builtin.target.cpu.arch.isMIPS64()) return error.SkipZigTest;17417 if (builtin.target.cpu.arch.isMIPS64()) return error.SkipZigTest;
17102 if (builtin.target.cpu.arch.isPowerPC32()) return error.SkipZigTest;17418 if (builtin.target.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17103 if (builtin.cpu.arch.isArm() and builtin.mode != .debug) return error.SkipZigTest;
17104 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17419 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
17105 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;17420 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1710617421
...@@ -17207,11 +17522,10 @@ const Coord2 = extern struct {...@@ -17207,11 +17522,10 @@ const Coord2 = extern struct {
1720717522
17208extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2;17523extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2;
17209test "Stdcall ABI structs" {17524test "Stdcall ABI structs" {
17525 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
17526 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17210 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;17527 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17211 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;17528 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
17212 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17213 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
17214 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
17215 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;17529 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
1721617530
17217 const res = stdcall_coord2(17531 const res = stdcall_coord2(
...@@ -17225,10 +17539,9 @@ test "Stdcall ABI structs" {...@@ -17225,10 +17539,9 @@ test "Stdcall ABI structs" {
1722517539
17226extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void;17540extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void;
17227test "Stdcall ABI big union" {17541test "Stdcall ABI big union" {
17228 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17229 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17230 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17542 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
17231 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17543 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17544 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
1723217545
17233 const x = BigUnion{17546 const x = BigUnion{
17234 .a = BigStruct{17547 .a = BigStruct{
...@@ -17300,11 +17613,10 @@ const byval_tail_callsite_attr = struct {...@@ -17300,11 +17613,10 @@ const byval_tail_callsite_attr = struct {
17300};17613};
1730117614
17302test "byval tail callsite attribute" {17615test "byval tail callsite attribute" {
17303 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17304 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
17305 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17306 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;17616 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
17307 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;17617 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
17618 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
17619 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
1730817620
17309 // Originally reported at https://github.com/ziglang/zig/issues/1629017621 // Originally reported at https://github.com/ziglang/zig/issues/16290
17310 // the bug was that the extern function had the byval attribute, but17622 // the bug was that the extern function had the byval attribute, but
test/standalone/build.zig-1
...@@ -39,7 +39,6 @@ pub fn build(b: *std.Build) void {...@@ -39,7 +39,6 @@ pub fn build(b: *std.Build) void {
39 "../../tools/gen_parser_oracle.zig",39 "../../tools/gen_parser_oracle.zig",
40 "../../tools/gen_spirv_spec.zig",40 "../../tools/gen_spirv_spec.zig",
41 "../../tools/gen_stubs.zig",41 "../../tools/gen_stubs.zig",
42 "../../tools/generate_c_size_and_align_checks.zig",
43 "../../tools/generate_JSONTestSuite.zig",42 "../../tools/generate_JSONTestSuite.zig",
44 "../../tools/generate_linux_syscalls.zig",43 "../../tools/generate_linux_syscalls.zig",
45 "../../tools/process_headers.zig",44 "../../tools/process_headers.zig",
test/tests.zig+54-16
...@@ -274,6 +274,15 @@ const module_test_targets = blk: {...@@ -274,6 +274,15 @@ const module_test_targets = blk: {
274 },274 },
275 .link_libc = true,275 .link_libc = true,
276 },276 },
277 .{
278 .target = .{
279 .cpu_arch = .arm,
280 .os_tag = .linux,
281 .abi = .musleabi,
282 .ofmt = .c,
283 },
284 .link_libc = true,
285 },
277 .{286 .{
278 .target = .{287 .target = .{
279 .cpu_arch = .arm,288 .cpu_arch = .arm,
...@@ -292,6 +301,15 @@ const module_test_targets = blk: {...@@ -292,6 +301,15 @@ const module_test_targets = blk: {
292 },301 },
293 .link_libc = true,302 .link_libc = true,
294 },303 },
304 .{
305 .target = .{
306 .cpu_arch = .arm,
307 .os_tag = .linux,
308 .abi = .musleabihf,
309 .ofmt = .c,
310 },
311 .link_libc = true,
312 },
295 .{313 .{
296 .target = .{314 .target = .{
297 .cpu_arch = .arm,315 .cpu_arch = .arm,
...@@ -341,6 +359,15 @@ const module_test_targets = blk: {...@@ -341,6 +359,15 @@ const module_test_targets = blk: {
341 },359 },
342 .link_libc = true,360 .link_libc = true,
343 },361 },
362 .{
363 .target = .{
364 .cpu_arch = .armeb,
365 .os_tag = .linux,
366 .abi = .musleabi,
367 .ofmt = .c,
368 },
369 .link_libc = true,
370 },
344 // Crashes in weird ways when applying relocations.371 // Crashes in weird ways when applying relocations.
345 // .{372 // .{
346 // .target = .{373 // .target = .{
...@@ -360,6 +387,15 @@ const module_test_targets = blk: {...@@ -360,6 +387,15 @@ const module_test_targets = blk: {
360 },387 },
361 .link_libc = true,388 .link_libc = true,
362 },389 },
390 .{
391 .target = .{
392 .cpu_arch = .armeb,
393 .os_tag = .linux,
394 .abi = .musleabihf,
395 .ofmt = .c,
396 },
397 .link_libc = true,
398 },
363 // Crashes in weird ways when applying relocations.399 // Crashes in weird ways when applying relocations.
364 // .{400 // .{
365 // .target = .{401 // .target = .{
...@@ -1107,6 +1143,15 @@ const module_test_targets = blk: {...@@ -1107,6 +1143,15 @@ const module_test_targets = blk: {
1107 },1143 },
1108 .link_libc = true,1144 .link_libc = true,
1109 },1145 },
1146 .{
1147 .target = .{
1148 .cpu_arch = .x86,
1149 .os_tag = .linux,
1150 .abi = .musl,
1151 .ofmt = .c,
1152 },
1153 .link_libc = true,
1154 },
1110 .{1155 .{
1111 .target = .{1156 .target = .{
1112 .cpu_arch = .x86,1157 .cpu_arch = .x86,
...@@ -1645,6 +1690,15 @@ const module_test_targets = blk: {...@@ -1645,6 +1690,15 @@ const module_test_targets = blk: {
1645 },1690 },
1646 .link_libc = true,1691 .link_libc = true,
1647 },1692 },
1693 .{
1694 .target = .{
1695 .cpu_arch = .x86,
1696 .os_tag = .windows,
1697 .abi = .gnu,
1698 .ofmt = .c,
1699 },
1700 .link_libc = true,
1701 },
16481702
1649 .{1703 .{
1650 .target = .{1704 .target = .{
...@@ -1961,7 +2015,6 @@ const c_abi_targets = blk: {...@@ -1961,7 +2015,6 @@ const c_abi_targets = blk: {
1961 .abi = .musl,2015 .abi = .musl,
1962 },2016 },
1963 .use_llvm = false,2017 .use_llvm = false,
1964 .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"},
1965 },2018 },
1966 .{2019 .{
1967 .target = .{2020 .target = .{
...@@ -1972,7 +2025,6 @@ const c_abi_targets = blk: {...@@ -1972,7 +2025,6 @@ const c_abi_targets = blk: {
1972 },2025 },
1973 .use_llvm = false,2026 .use_llvm = false,
1974 .strip = true,2027 .strip = true,
1975 .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"},
1976 },2028 },
1977 .{2029 .{
1978 .target = .{2030 .target = .{
...@@ -1983,7 +2035,6 @@ const c_abi_targets = blk: {...@@ -1983,7 +2035,6 @@ const c_abi_targets = blk: {
1983 },2035 },
1984 .use_llvm = false,2036 .use_llvm = false,
1985 .pic = true,2037 .pic = true,
1986 .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"},
1987 },2038 },
1988 .{2039 .{
1989 .target = .{2040 .target = .{
...@@ -2028,7 +2079,6 @@ const c_abi_targets = blk: {...@@ -2028,7 +2079,6 @@ const c_abi_targets = blk: {
2028 .abi = .gnu,2079 .abi = .gnu,
2029 },2080 },
2030 .use_llvm = false,2081 .use_llvm = false,
2031 .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"},
2032 },2082 },
2033 .{2083 .{
2034 .target = .{2084 .target = .{
...@@ -2038,7 +2088,6 @@ const c_abi_targets = blk: {...@@ -2038,7 +2088,6 @@ const c_abi_targets = blk: {
2038 .abi = .gnu,2088 .abi = .gnu,
2039 },2089 },
2040 .use_llvm = false,2090 .use_llvm = false,
2041 .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"},
2042 },2091 },
2043 .{2092 .{
2044 .target = .{2093 .target = .{
...@@ -2048,7 +2097,6 @@ const c_abi_targets = blk: {...@@ -2048,7 +2097,6 @@ const c_abi_targets = blk: {
2048 .abi = .gnu,2097 .abi = .gnu,
2049 },2098 },
2050 .use_llvm = false,2099 .use_llvm = false,
2051 .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"},
2052 },2100 },
2053 .{2101 .{
2054 .target = .{2102 .target = .{
...@@ -2782,16 +2830,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {...@@ -2782,16 +2830,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
27822830
2783 const target = &resolved_target.result;2831 const target = &resolved_target.result;
27842832
2785 if (target.cpu.arch == .s390x and target.ofmt == .c) {
2786 // https://codeberg.org/ziglang/zig/issues/35523
2787 continue;
2788 }
2789
2790 if (target.cpu.arch == .riscv64 and target.ofmt == .c) {
2791 // https://codeberg.org/ziglang/zig/issues/30930
2792 continue;
2793 }
2794
2795 if (std.mem.eql(u8, options.name, "libc")) {2833 if (std.mem.eql(u8, options.name, "libc")) {
2796 // The libc API tests obviously need to link libc. So for test2834 // The libc API tests obviously need to link libc. So for test
2797 // target entries where we wouldn't link libc by default, skip the2835 // target entries where we wouldn't link libc by default, skip the
tools/generate_c_size_and_align_checks.zig deleted-62
...@@ -1,62 +0,0 @@
1//! Usage: zig run tools/generate_c_size_and_align_checks.zig -- [target_triple]
2//! e.g. zig run tools/generate_c_size_and_align_checks.zig -- x86_64-linux-gnu
3//!
4//! Prints _Static_asserts for the size and alignment of all the basic built-in C
5//! types. The output can be run through a compiler for the specified target to
6//! verify that Zig's values are the same as those used by a C compiler for the
7//! target.
8
9const std = @import("std");
10const Io = std.Io;
11
12fn cName(ty: std.Target.CType) []const u8 {
13 return switch (ty) {
14 .char => "char",
15 .short => "short",
16 .ushort => "unsigned short",
17 .int => "int",
18 .uint => "unsigned int",
19 .long => "long",
20 .ulong => "unsigned long",
21 .longlong => "long long",
22 .ulonglong => "unsigned long long",
23 .float => "float",
24 .double => "double",
25 .longdouble => "long double",
26 };
27}
28
29var general_purpose_allocator: std.heap.DebugAllocator(.{}) = .init;
30
31pub fn main(init: std.process.Init) !void {
32 const args = try init.minimal.args.toSlice(init.arena.allocator());
33 const io = init.io;
34
35 if (args.len != 2) {
36 std.debug.print("Usage: {s} [target_triple]\n", .{args[0]});
37 std.process.exit(1);
38 }
39
40 const query = try std.Target.Query.parse(.{ .arch_os_abi = args[1] });
41 const target = try std.zig.system.resolveTargetQuery(io, query);
42
43 var buffer: [2000]u8 = undefined;
44 var stdout_writer = Io.File.stdout().writerStreaming(io, &buffer);
45 const w = &stdout_writer.interface;
46 inline for (@typeInfo(std.Target.CType).@"enum".field_values) |field_value| {
47 const c_type: std.Target.CType = @fromBackingInt(@intCast(field_value));
48 try w.print("_Static_assert(sizeof({0s}) == {1d}, \"sizeof({0s}) == {1d}\");\n", .{
49 cName(c_type),
50 target.cTypeByteSize(c_type),
51 });
52 try w.print("_Static_assert(_Alignof({0s}) == {1d}, \"_Alignof({0s}) == {1d}\");\n", .{
53 cName(c_type),
54 target.cTypeAlignment(c_type),
55 });
56 try w.print("_Static_assert(__alignof({0s}) == {1d}, \"__alignof({0s}) == {1d}\");\n\n", .{
57 cName(c_type),
58 target.cTypePreferredAlignment(c_type),
59 });
60 }
61 try w.flush();
62}