| author | |
| committer | |
| log | b52057f05218d13901fe576bf2d472b657e58e6f |
| tree | 80203b7f809f94c3a1a49f6e9404331d8947f78b |
| parent | d01609af2aaf5a3c9ddd2ddf75a5d211e0e94b07 |
| parent | 47396c903cb118df9e5562f383026b0f460d38f6 |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35932320 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.zig | 358 | src/codegen/c/type/render_defs.zig |
| 359 | src/codegen/llvm.zig | 359 | src/codegen/llvm.zig |
| 360 | src/codegen/llvm/bindings.zig | 360 | src/codegen/llvm/bindings.zig |
| 361 | src/codegen/loongarch/abi.zig | ||
| 362 | src/codegen/s390x/abi.zig | ||
| 361 | src/crash_report.zig | 363 | src/crash_report.zig |
| 362 | src/dev.zig | 364 | src/dev.zig |
| 363 | src/libs/freebsd.zig | 365 | 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 | } |
| 1560 | 1560 | ||
| 1561 | pub fn cCharSignedness(target: *const Target) std.builtin.Signedness { | 1561 | pub fn cCharSignedness(target: *const Target) std.builtin.Signedness { |
| 1562 | return target.toZigTarget().cCharSignedness(); | 1562 | return target.toZigTarget().cCharSignedness().?; |
| 1563 | } | 1563 | } |
| 1564 | 1564 | ||
| 1565 | pub fn cTypeBitSize(target: *const Target, c_type: std.Target.CType) u16 { | 1565 | pub 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 | } |
| 1568 | 1568 | ||
| 1569 | pub fn cTypeAlignment(target: *const Target, c_type: std.Target.CType) u16 { | 1569 | pub 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 | } |
| 1572 | 1572 | ||
| 1573 | pub fn standardDynamicLinkerPath(target: *const Target) std.Target.DynamicLinker { | 1573 | pub 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 | } |
| 1282 | 1282 | ||
| 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 | }; | ||
| 98 | 97 | ||
| 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. |
| 102 | 101 | ||
| 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); |
| 108 | 107 | ||
| 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 | }; |
| 379 | 378 | ||
| 379 | testing.allocator_instance = .init(std.heap.page_allocator, .{}); | ||
| 380 | testing.io_instance = .init(testing.allocator, .{}); | 380 | testing.io_instance = .init(testing.allocator, .{}); |
| 381 | 381 | ||
| 382 | var passed: u64 = 0; | 382 | var passed: u64 = 0; |
lib/compiler_rt.zig+120-168| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const compiler_rt = @This(); | ||
| 2 | const ofmt_c = builtin.object_format == .c; | 3 | const ofmt_c = builtin.object_format == .c; |
| 3 | const native_endian = builtin.cpu.arch.endian(); | 4 | const native_endian = builtin.cpu.arch.endian(); |
| 4 | 5 | ||
| ... | @@ -84,144 +85,17 @@ comptime { | ... | @@ -84,144 +85,17 @@ comptime { |
| 84 | // Float routines | 85 | // Float routines |
| 85 | // conversion | 86 | // 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"); | ||
| 190 | 91 | ||
| 191 | // comparison | 92 | // 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"); | ||
| 202 | 94 | ||
| 203 | // arithmetic | 95 | // 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"); | ||
| 223 | 98 | ||
| 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"); |
| 241 | 118 | ||
| 242 | // other | 119 | // 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"); | ||
| 257 | 123 | ||
| 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"); |
| 281 | 147 | ||
| 282 | _ = @import("compiler_rt/limb64.zig"); | 148 | if (builtin.cpu.arch.isWasm()) _ = @import("compiler_rt/limb64.zig"); |
| 283 | 149 | ||
| 284 | // extra | 150 | // 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"); |
| 292 | 158 | ||
| 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"); |
| 296 | 162 | ||
| ... | @@ -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 | }; |
| 375 | 238 | ||
| ... | @@ -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) { |
| 443 | pub const want_sparc64_abi = builtin.cpu.arch == .sparc64; | 306 | pub const want_sparc64_abi = builtin.cpu.arch == .sparc64; |
| 444 | pub const want_sparc32_abi = builtin.cpu.arch == .sparc; | 307 | pub const want_sparc32_abi = builtin.cpu.arch == .sparc; |
| 445 | 308 | ||
| 446 | pub fn F16T(comptime OtherType: type) type { | 309 | /// For operations converting between `f16` and another floating point type. |
| 447 | return switch (builtin.cpu.arch) { | 310 | pub 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 f16 | 312 | .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 | } | ||
| 324 | pub const @"f16" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) { | ||
| 325 | .hard => hardFloatAbi(f16), | ||
| 326 | .soft => softFloatAbi(f16), | ||
| 327 | }; | ||
| 328 | pub const @"f32" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 32)) { | ||
| 329 | .hard => hardFloatAbi(f32), | ||
| 330 | .soft => softFloatAbi(f32), | ||
| 331 | }; | ||
| 332 | pub const @"f64" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 64)) { | ||
| 333 | .hard => hardFloatAbi(f64), | ||
| 334 | .soft => softFloatAbi(f64), | ||
| 335 | }; | ||
| 336 | pub 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 | }; | ||
| 352 | pub 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 | }; | ||
| 371 | fn 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 | } | ||
| 383 | fn 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 | } | ||
| 395 | fn 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 | } |
| 458 | 406 | ||
| 407 | pub fn Complex(comptime Float: type) type { | ||
| 408 | return struct { real: Float, imag: Float }; | ||
| 409 | } | ||
| 410 | |||
| 459 | pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void { | 411 | pub 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 | } |
| 590 | 542 | ||
| 591 | fn __negxf2(a: f80) callconv(.c) f80 { | 543 | fn __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 | } |
| 594 | 546 | ||
| 595 | fn __neghf2(a: f16) callconv(.c) f16 { | 547 | fn __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 | } |
| 598 | 550 | ||
| 599 | fn __negdf2(a: f64) callconv(.c) f64 { | 551 | fn __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 | } |
| 602 | 554 | ||
| 603 | fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | 555 | fn __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 | } |
| 606 | 558 | ||
| 607 | fn __negtf2(a: f128) callconv(.c) f128 { | 559 | fn __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 | } |
| 610 | 562 | ||
| 611 | fn __negsf2(a: f32) callconv(.c) f32 { | 563 | fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 { |
| 612 | return fneg(a); | 564 | return fneg(a); |
| 613 | } | 565 | } |
| 614 | 566 | ||
| 615 | fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | 567 | fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { |
| 616 | return fneg(a); | 568 | return fneg(a); |
| 617 | } | 569 | } |
| 618 | 570 |
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 | } |
| 21 | 20 |
lib/compiler_rt/absvdi2.zig+3-2| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | 1 | const compiler_rt = @import("../compiler_rt.zig"); |
| 2 | const absv = @import("./absv.zig").absv; | 2 | const symbol = compiler_rt.symbol; |
| 3 | const absv = @import("absv.zig").absv; | ||
| 3 | 4 | ||
| 4 | comptime { | 5 | comptime { |
| 5 | symbol(&__absvdi2, "__absvdi2"); | 6 | symbol(&__absvdi2, "__absvdi2"); |
lib/compiler_rt/absvsi2.zig+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | 1 | const compiler_rt = @import("../compiler_rt.zig"); |
| 2 | const symbol = compiler_rt.symbol; | 2 | const symbol = compiler_rt.symbol; |
| 3 | const absv = @import("./absv.zig").absv; | 3 | const absv = @import("absv.zig").absv; |
| 4 | 4 | ||
| 5 | comptime { | 5 | comptime { |
| 6 | symbol(&__absvsi2, "__absvsi2"); | 6 | symbol(&__absvsi2, "__absvsi2"); |
lib/compiler_rt/absvti2.zig+3-2| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | 1 | const compiler_rt = @import("../compiler_rt.zig"); |
| 2 | const absv = @import("./absv.zig").absv; | 2 | const symbol = compiler_rt.symbol; |
| 3 | const absv = @import("absv.zig").absv; | ||
| 3 | 4 | ||
| 4 | comptime { | 5 | comptime { |
| 5 | symbol(&__absvti2, "__absvti2"); | 6 | symbol(&__absvti2, "__absvti2"); |
lib/compiler_rt/adddf3.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const addf3 = @import("./addf3.zig").addf3; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_dadd, "__aeabi_dadd"); | ||
| 8 | } else { | ||
| 9 | symbol(&__adddf3, "__adddf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __adddf3(a: f64, b: f64) callconv(.c) f64 { | ||
| 14 | return addf3(f64, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | ||
| 4 | const normalize = compiler_rt.normalize; | 5 | const normalize = compiler_rt.normalize; |
| 5 | 6 | ||
| 7 | comptime { | ||
| 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 | |||
| 28 | fn __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 | } | ||
| 31 | pub fn add_f16(a: f16, b: f16) f16 { | ||
| 32 | return addf3(f16, a, b); | ||
| 33 | } | ||
| 34 | |||
| 35 | fn __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 | } | ||
| 38 | fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 39 | return add_f32(a, b); | ||
| 40 | } | ||
| 41 | pub fn add_f32(a: f32, b: f32) f32 { | ||
| 42 | return addf3(f32, a, b); | ||
| 43 | } | ||
| 44 | |||
| 45 | fn __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 | } | ||
| 48 | fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 49 | return add_f64(a, b); | ||
| 50 | } | ||
| 51 | pub fn add_f64(a: f64, b: f64) f64 { | ||
| 52 | return addf3(f64, a, b); | ||
| 53 | } | ||
| 54 | |||
| 55 | fn __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 | } | ||
| 58 | pub fn add_f80(a: f80, b: f80) f80 { | ||
| 59 | return addf3(f80, a, b); | ||
| 60 | } | ||
| 61 | |||
| 62 | fn __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 | } | ||
| 65 | fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void { | ||
| 66 | c.* = add_f128(a.*, b.*); | ||
| 67 | } | ||
| 68 | pub fn add_f128(a: f128, b: f128) f128 { | ||
| 69 | return addf3(f128, a, b); | ||
| 70 | } | ||
| 71 | |||
| 72 | comptime { | ||
| 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 | |||
| 93 | fn __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 | } | ||
| 96 | pub fn sub_f16(a: f16, b: f16) f16 { | ||
| 97 | return add_f16(a, compiler_rt.fneg(b)); | ||
| 98 | } | ||
| 99 | |||
| 100 | fn __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 | } | ||
| 103 | fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 104 | return sub_f32(a, b); | ||
| 105 | } | ||
| 106 | pub fn sub_f32(a: f32, b: f32) f32 { | ||
| 107 | return add_f32(a, compiler_rt.fneg(b)); | ||
| 108 | } | ||
| 109 | |||
| 110 | fn __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 | } | ||
| 113 | fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 114 | return sub_f64(a, b); | ||
| 115 | } | ||
| 116 | pub fn sub_f64(a: f64, b: f64) f64 { | ||
| 117 | return add_f64(a, compiler_rt.fneg(b)); | ||
| 118 | } | ||
| 119 | |||
| 120 | fn __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 | } | ||
| 123 | pub fn sub_f80(a: f80, b: f80) f80 { | ||
| 124 | return add_f80(a, compiler_rt.fneg(b)); | ||
| 125 | } | ||
| 126 | |||
| 127 | fn __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 | } | ||
| 130 | fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | ||
| 131 | c.* = sub_f128(a.*, b.*); | ||
| 132 | } | ||
| 133 | pub 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.inc | 139 | /// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc |
| 9 | pub inline fn addf3(comptime T: type, a: T, b: T) T { | 140 | inline 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); |
| 12 | 143 |
lib/compiler_rt/addf3_test.zig+7-6| ... | @@ -8,12 +8,13 @@ const builtin = @import("builtin"); | ... | @@ -8,12 +8,13 @@ const builtin = @import("builtin"); |
| 8 | const math = std.math; | 8 | const math = std.math; |
| 9 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); | 9 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); |
| 10 | 10 | ||
| 11 | const __addtf3 = @import("addtf3.zig").__addtf3; | 11 | const impl = @import("addf3.zig"); |
| 12 | const __addxf3 = @import("addxf3.zig").__addxf3; | 12 | const add_f128 = impl.add_f128; |
| 13 | const __subtf3 = @import("subtf3.zig").__subtf3; | 13 | const add_f80 = impl.add_f80; |
| 14 | const sub_f128 = impl.sub_f128; | ||
| 14 | 15 | ||
| 15 | fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { | 16 | fn 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); |
| 17 | 18 | ||
| 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 | } |
| 53 | 54 | ||
| 54 | fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { | 55 | fn 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); |
| 56 | 57 | ||
| 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" { |
| 91 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); | 92 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); |
| 92 | 93 | ||
| 93 | fn test__addxf3(a: f80, b: f80, expected: u80) !void { | 94 | fn 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); |
| 96 | 97 | ||
| 97 | if (rep == expected) | 98 | if (rep == expected) |
lib/compiler_rt/addhf3.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__addhf3, "__addhf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const addf3 = @import("./addf3.zig").addf3; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_fadd, "__aeabi_fadd"); | ||
| 8 | } else { | ||
| 9 | symbol(&__addsf3, "__addsf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __addsf3(a: f32, b: f32) callconv(.c) f32 { | ||
| 14 | return addf3(f32, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __addtf3(a: f128, b: f128) callconv(.c) f128 { | ||
| 17 | return addf3(f128, a, b); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | 1 | const compiler_rt = @import("../compiler_rt.zig"); |
| 2 | const symbol = compiler_rt.symbol; | ||
| 2 | const testing = @import("std").testing; | 3 | const testing = @import("std").testing; |
| 3 | 4 | ||
| 4 | comptime { | 5 | comptime { |
| ... | @@ -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 does | 11 | // 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 | } |
| 15 | 16 |
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 does | 11 | // 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 | } |
| 16 | 16 |
lib/compiler_rt/addxf3.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__addxf3, "__addxf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub 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; |
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | 6 | ||
| 7 | const compiler_rt = @import("../compiler_rt.zig"); | 7 | const compiler_rt = @import("../compiler_rt.zig"); |
| 8 | const symbol = @import("../compiler_rt.zig").symbol; | 8 | const symbol = compiler_rt.symbol; |
| 9 | 9 | ||
| 10 | // This parameter is true iff the target architecture supports the bare minimum | 10 | // 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 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | 2 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | 4 | const symbol = compiler_rt.symbol; |
| 5 | 5 | ||
| 6 | comptime { | 6 | comptime { |
| 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 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const comparef = @import("./comparef.zig"); | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | |||
| 7 | comptime { | ||
| 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`. | ||
| 27 | fn __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." | ||
| 33 | pub 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. | ||
| 40 | pub 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. | ||
| 47 | pub 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." | ||
| 53 | pub fn __ltdf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 54 | return __cmpdf2(a, b); | ||
| 55 | } | ||
| 56 | |||
| 57 | fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 58 | return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Equal); | ||
| 59 | } | ||
| 60 | |||
| 61 | fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 62 | return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Less); | ||
| 63 | } | ||
| 64 | |||
| 65 | fn __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 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const comparef = @import("./comparef.zig"); | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | |||
| 7 | comptime { | ||
| 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`. | ||
| 43 | fn __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." | ||
| 49 | fn __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. | ||
| 56 | fn __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. | ||
| 63 | fn __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." | ||
| 69 | fn __lttf2(a: f128, b: f128) callconv(.c) i32 { | ||
| 70 | return __cmptf2(a, b); | ||
| 71 | } | ||
| 72 | |||
| 73 | const SparcFCMP = enum(i32) { | ||
| 74 | Equal = 0, | ||
| 75 | Less = 1, | ||
| 76 | Greater = 2, | ||
| 77 | Unordered = 3, | ||
| 78 | }; | ||
| 79 | |||
| 80 | fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 81 | return @backingInt(comparef.cmpf2(f128, SparcFCMP, a.*, b.*)); | ||
| 82 | } | ||
| 83 | |||
| 84 | fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 85 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Equal; | ||
| 86 | } | ||
| 87 | |||
| 88 | fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 89 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) != .Equal; | ||
| 90 | } | ||
| 91 | |||
| 92 | fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 93 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Less; | ||
| 94 | } | ||
| 95 | |||
| 96 | fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 97 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Greater; | ||
| 98 | } | ||
| 99 | |||
| 100 | fn _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 | |||
| 107 | fn _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 | |||
| 114 | fn _Q_cmp(a: f128, b: f128) callconv(.c) i32 { | ||
| 115 | return @backingInt(comparef.cmpf2(f128, SparcFCMP, a, b)); | ||
| 116 | } | ||
| 117 | |||
| 118 | fn _Q_feq(a: f128, b: f128) callconv(.c) bool { | ||
| 119 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Equal; | ||
| 120 | } | ||
| 121 | |||
| 122 | fn _Q_fne(a: f128, b: f128) callconv(.c) bool { | ||
| 123 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) != .Equal; | ||
| 124 | } | ||
| 125 | |||
| 126 | fn _Q_flt(a: f128, b: f128) callconv(.c) bool { | ||
| 127 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Less; | ||
| 128 | } | ||
| 129 | |||
| 130 | fn _Q_fgt(a: f128, b: f128) callconv(.c) bool { | ||
| 131 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Greater; | ||
| 132 | } | ||
| 133 | |||
| 134 | fn _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 | |||
| 141 | fn _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 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const comparef = @import("./comparef.zig"); | ||
| 6 | |||
| 7 | comptime { | ||
| 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`. | ||
| 21 | fn __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." | ||
| 27 | fn __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. | ||
| 34 | fn __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. | ||
| 41 | fn __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." | ||
| 47 | fn __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 @@ |
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | 7 | ||
| 8 | const __eqdf2 = @import("./cmpdf2.zig").__eqdf2; | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const __ledf2 = @import("./cmpdf2.zig").__ledf2; | ||
| 10 | const __ltdf2 = @import("./cmpdf2.zig").__ltdf2; | ||
| 11 | const __nedf2 = @import("./cmpdf2.zig").__nedf2; | ||
| 12 | 9 | ||
| 13 | const __gedf2 = @import("./gedf2.zig").__gedf2; | 10 | const impl = @import("comparef.zig"); |
| 14 | const __gtdf2 = @import("./gedf2.zig").__gtdf2; | 11 | const Order = impl.Order; |
| 15 | 12 | const cmp_f64 = impl.cmp_f64; | |
| 16 | const __unorddf2 = @import("./unorddf2.zig").__unorddf2; | 13 | const unord_f64 = impl.unord_f64; |
| 17 | |||
| 18 | const 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 | |||
| 30 | fn 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 | } | ||
| 54 | 14 | ||
| 55 | const arguments = [_]f64{ | 15 | const 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 | }; |
| 75 | 35 | ||
| 76 | fn generateVector(comptime a: f64, comptime b: f64) TestVector { | 36 | test "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 | |||
| 93 | const 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 | |||
| 104 | test "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 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const std = @import("std"); | 2 | const std = @import("std"); |
| 2 | 3 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | 5 | const symbol = compiler_rt.symbol; |
| 5 | 6 | ||
| 6 | comptime { | 7 | const Unordered = if (builtin.cpu.arch == .avr) |
| 7 | if (compiler_rt.want_aeabi) { | 8 | i8 |
| 8 | symbol(&__aeabi_fcmpun, "__aeabi_fcmpun"); | 9 | else if (builtin.cpu.arch.isAARCH64()) |
| 9 | } else { | 10 | i32 |
| 10 | symbol(&__unordsf2, "__unordsf2"); | 11 | else if (builtin.target.cTypeBitSize(.long).? >= builtin.target.ptrBitWidth()) |
| 11 | } | 12 | c_long |
| 12 | 13 | else | |
| 13 | symbol(&__unordxf2, "__unordxf2"); | 14 | c_longlong; |
| 15 | pub const Order = enum(Unordered) { lt = -1, eq = 0, gt = 1 }; | ||
| 16 | const SparcOrder = enum(i32) { eq = 0, lt = 1, gt = 2, un = 3 }; | ||
| 14 | 17 | ||
| 15 | symbol(&__eqhf2, "__eqhf2"); | 18 | comptime { |
| 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"); | ||
| 20 | 27 | ||
| 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 | } |
| 32 | 61 | ||
| 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 | |||
| 40 | pub fn __unordhf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 41 | return unordcmp(f16, a, b); | ||
| 42 | } | 105 | } |
| 43 | 106 | ||
| 44 | pub fn __unordtf2(a: f128, b: f128) callconv(.c) i32 { | 107 | fn __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 | } |
| 47 | 110 | fn __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`. | ||
| 54 | fn __cmpsf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 55 | return @backingInt(cmpf2(f32, LE, a, b)); | ||
| 56 | } | 112 | } |
| 57 | 113 | fn __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." | ||
| 60 | pub fn __lesf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 61 | return __cmpsf2(a, b); | ||
| 62 | } | 115 | } |
| 63 | 116 | pub 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. | ||
| 67 | pub fn __eqsf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 68 | return __cmpsf2(a, b); | ||
| 69 | } | 118 | } |
| 70 | 119 | pub 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. | ||
| 74 | pub fn __nesf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 75 | return __cmpsf2(a, b); | ||
| 76 | } | 121 | } |
| 77 | 122 | ||
| 78 | /// "These functions return a value less than zero if neither argument is NaN, and a | 123 | fn __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; |
| 80 | pub fn __ltsf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 81 | return __cmpsf2(a, b); | ||
| 82 | } | 125 | } |
| 83 | |||
| 84 | fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | 126 | fn __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 | |||
| 88 | fn __aeabi_fcmplt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | 129 | fn __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 | |||
| 92 | fn __aeabi_fcmple(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | 132 | fn __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 | } |
| 95 | 135 | fn __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`. | ||
| 102 | fn __cmphf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 103 | return @backingInt(cmpf2(f16, LE, a, b)); | ||
| 104 | } | 137 | } |
| 105 | 138 | fn __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." | ||
| 108 | fn __lehf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 109 | return __cmphf2(a, b); | ||
| 110 | } | 140 | } |
| 111 | 141 | fn __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. | ||
| 115 | fn __eqhf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 116 | return __cmphf2(a, b); | ||
| 117 | } | 143 | } |
| 118 | 144 | fn __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. | ||
| 122 | fn __nehf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 123 | return __cmphf2(a, b); | ||
| 124 | } | 146 | } |
| 125 | 147 | fn __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 a | 148 | return @intFromBool(unord_f32(a, b)); |
| 127 | /// is strictly less than b." | ||
| 128 | fn __lthf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 129 | return __cmphf2(a, b); | ||
| 130 | } | 149 | } |
| 131 | 150 | pub fn cmp_f32(a: f32, b: f32) ?Order { | |
| 132 | fn __unordxf2(a: f80, b: f80) callconv(.c) i32 { | 151 | return cmpf2(f32, a, b); |
| 133 | return unordcmp(f80, a, b); | 152 | } |
| 153 | pub fn unord_f32(a: f32, b: f32) bool { | ||
| 154 | return unord(f32, a, b); | ||
| 134 | } | 155 | } |
| 135 | 156 | ||
| 136 | pub fn __unordsf2(a: f32, b: f32) callconv(.c) i32 { | 157 | fn __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 | } | ||
| 160 | fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 161 | return @intFromBool(cmp_f64(a, b) == .eq); | ||
| 162 | } | ||
| 163 | fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 164 | return @intFromBool(cmp_f64(a, b) == .lt); | ||
| 165 | } | ||
| 166 | fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 167 | return @intFromBool(cmp_f64(a, b) orelse .gt != .gt); | ||
| 168 | } | ||
| 169 | fn __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 | } | ||
| 172 | fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 173 | return @intFromBool(cmp_f64(a, b) orelse .lt != .lt); | ||
| 174 | } | ||
| 175 | fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 176 | return @intFromBool(cmp_f64(a, b) == .gt); | ||
| 177 | } | ||
| 178 | fn __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 | } | ||
| 181 | fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 182 | return @intFromBool(unord_f64(a, b)); | ||
| 183 | } | ||
| 184 | pub fn cmp_f64(a: f64, b: f64) ?Order { | ||
| 185 | return cmpf2(f64, a, b); | ||
| 186 | } | ||
| 187 | pub fn unord_f64(a: f64, b: f64) bool { | ||
| 188 | return unord(f64, a, b); | ||
| 138 | } | 189 | } |
| 139 | 190 | ||
| 140 | fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | 191 | fn __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 | } | ||
| 194 | fn __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 | } |
| 197 | fn __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 | } | ||
| 200 | pub 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; | ||
| 143 | 207 | ||
| 144 | pub 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; |
| 148 | 212 | ||
| 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; | ||
| 151 | 216 | ||
| 152 | pub 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 | } | ||
| 236 | pub fn unord_f80(a: f80, b: f80) bool { | ||
| 237 | return unord(f80, a, b); | ||
| 238 | } | ||
| 156 | 239 | ||
| 157 | const Unordered: GE = .Less; | 240 | fn __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 | } | ||
| 243 | fn __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 | } | ||
| 246 | fn __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 | } | ||
| 249 | fn _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 | } | ||
| 256 | fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 257 | return @intFromBool(cmp_f128(a.*, b.*) == .eq); | ||
| 258 | } | ||
| 259 | fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 260 | return @intFromBool(cmp_f128(a.*, b.*) != .eq); | ||
| 261 | } | ||
| 262 | fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 263 | return @intFromBool(cmp_f128(a.*, b.*) == .lt); | ||
| 264 | } | ||
| 265 | fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 266 | return @intFromBool((cmp_f128(a.*, b.*) orelse .gt) != .gt); | ||
| 267 | } | ||
| 268 | fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 269 | return @intFromBool(cmp_f128(a.*, b.*) == .gt); | ||
| 270 | } | ||
| 271 | fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 272 | return @intFromBool((cmp_f128(a.*, b.*) orelse .lt) != .lt); | ||
| 273 | } | ||
| 274 | fn _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 | } | ||
| 281 | fn _Q_feq(a: f128, b: f128) callconv(.c) i32 { | ||
| 282 | return @intFromBool(cmp_f128(a, b) == .eq); | ||
| 283 | } | ||
| 284 | fn _Q_fne(a: f128, b: f128) callconv(.c) i32 { | ||
| 285 | return @intFromBool(cmp_f128(a, b) != .eq); | ||
| 286 | } | ||
| 287 | fn _Q_flt(a: f128, b: f128) callconv(.c) i32 { | ||
| 288 | return @intFromBool(cmp_f128(a, b) == .lt); | ||
| 289 | } | ||
| 290 | fn _Q_fle(a: f128, b: f128) callconv(.c) i32 { | ||
| 291 | return @intFromBool((cmp_f128(a, b) orelse .gt) != .gt); | ||
| 292 | } | ||
| 293 | fn _Q_fgt(a: f128, b: f128) callconv(.c) i32 { | ||
| 294 | return @intFromBool(cmp_f128(a, b) == .gt); | ||
| 295 | } | ||
| 296 | fn _Q_fge(a: f128, b: f128) callconv(.c) i32 { | ||
| 297 | return @intFromBool((cmp_f128(a, b) orelse .lt) != .lt); | ||
| 298 | } | ||
| 299 | pub fn cmp_f128(a: f128, b: f128) ?Order { | ||
| 300 | return cmpf2(f128, a, b); | ||
| 301 | } | ||
| 302 | pub fn unord_f128(a: f128, b: f128) bool { | ||
| 303 | return unord(f128, a, b); | ||
| 304 | } | ||
| 159 | 305 | ||
| 160 | pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT { | 306 | inline 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; |
| 176 | 322 | ||
| 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; |
| 179 | 325 | ||
| 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; |
| 182 | 328 | ||
| 183 | // If at least one of a and b is positive, we get the same result comparing | 329 | // 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 the | 338 | // 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 a | 340 | // 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 | } |
| 203 | 349 | ||
| 204 | pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT { | 350 | test 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 | |||
| 241 | test "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 | } |
| 251 | 358 | ||
| 252 | pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { | 359 | inline 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); |
| 254 | 361 | ||
| 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; |
| 263 | 370 | ||
| 264 | return @intFromBool(aAbs > infRep or bAbs > infRep); | 371 | return aAbs > infRep or bAbs > infRep; |
| 265 | } | 372 | } |
| 266 | 373 | ||
| 267 | test { | 374 | test { |
lib/compiler_rt/comparesf2_test.zig+17-73| ... | @@ -5,52 +5,12 @@ | ... | @@ -5,52 +5,12 @@ |
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | 7 | ||
| 8 | const __eqsf2 = @import("./comparef.zig").__eqsf2; | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const __lesf2 = @import("./comparef.zig").__lesf2; | ||
| 10 | const __ltsf2 = @import("./comparef.zig").__ltsf2; | ||
| 11 | const __nesf2 = @import("./comparef.zig").__nesf2; | ||
| 12 | 9 | ||
| 13 | const __gesf2 = @import("./gesf2.zig").__gesf2; | 10 | const impl = @import("comparef.zig"); |
| 14 | const __gtsf2 = @import("./gesf2.zig").__gtsf2; | 11 | const Order = impl.Order; |
| 15 | 12 | const cmp_f32 = impl.cmp_f32; | |
| 16 | const __unordsf2 = @import("./comparef.zig").__unordsf2; | 13 | const unord_f32 = impl.unord_f32; |
| 17 | |||
| 18 | const 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 | |||
| 30 | fn 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 | } | ||
| 54 | 14 | ||
| 55 | const arguments = [_]f32{ | 15 | const 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 | }; |
| 75 | 35 | ||
| 76 | fn generateVector(comptime a: f32, comptime b: f32) TestVector { | 36 | test "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 | |||
| 93 | const 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 | |||
| 104 | test "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; |
| 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; | 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; |
| 14 | 14 | ||
| 15 | const compiler_rt = @import("../compiler_rt.zig"); | 15 | const compiler_rt = @import("../compiler_rt.zig"); |
| 16 | const symbol = @import("../compiler_rt.zig").symbol; | 16 | const symbol = compiler_rt.symbol; |
| 17 | const trig = @import("trig.zig"); | 17 | const trig = @import("trig.zig"); |
| 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; | 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; |
| 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; | 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; |
| 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; | 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 21 | 21 | ||
| 22 | comptime { | 22 | comptime { |
| 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 | } |
| 34 | 31 | ||
| 35 | pub fn cosh(a: f16) callconv(.c) f16 { | 32 | fn __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 | } | ||
| 35 | pub fn cos_f16(x: f16) f16 { | ||
| 36 | // TODO: more efficient implementation | 36 | // TODO: more efficient implementation |
| 37 | return @floatCast(cosf(a)); | 37 | return @floatCast(cos_f32(x)); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | pub fn cosf(x: f32) callconv(.c) f32 { | 40 | fn 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 | } | ||
| 43 | pub 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, 0x54442D18 | 45 | const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 43 | const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 | 46 | 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 | } |
| 96 | 99 | ||
| 97 | pub fn cos(x: f64) callconv(.c) f64 { | 100 | fn 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 | } | ||
| 103 | pub 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; |
| 100 | 106 | ||
| ... | @@ -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 | } |
| 125 | 131 | ||
| 126 | pub fn cosx(x: f80) callconv(.c) f80 { | 132 | fn __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 | } | ||
| 135 | pub 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 | } |
| 149 | 158 | ||
| 150 | pub fn cosq(x: f128) callconv(.c) f128 { | 159 | fn 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 | } | ||
| 162 | pub 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 { |
| 173 | 185 | ||
| 174 | pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble { | 186 | pub 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 | } |
| 182 | 194 | ||
| 183 | fn testCosSpecial(comptime T: type) !void { | 195 | fn 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 | }; |
| 191 | 204 | ||
| 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 { |
| 198 | 211 | ||
| 199 | test "cos32.normal" { | 212 | test "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 | } |
| 209 | 222 | ||
| 210 | test "cos32.special" { | 223 | test "cos32.special" { |
| ... | @@ -213,13 +226,13 @@ test "cos32.special" { | ... | @@ -213,13 +226,13 @@ test "cos32.special" { |
| 213 | 226 | ||
| 214 | test "cos64.normal" { | 227 | test "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 | } |
| 224 | 237 | ||
| 225 | test "cos64.special" { | 238 | test "cos64.special" { |
| ... | @@ -228,13 +241,13 @@ test "cos64.special" { | ... | @@ -228,13 +241,13 @@ test "cos64.special" { |
| 228 | 241 | ||
| 229 | test "cos80.normal" { | 242 | test "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 | } |
| 239 | 252 | ||
| 240 | test "cos80.special" { | 253 | test "cos80.special" { |
| ... | @@ -243,13 +256,13 @@ test "cos80.special" { | ... | @@ -243,13 +256,13 @@ test "cos80.special" { |
| 243 | 256 | ||
| 244 | test "cos128.normal" { | 257 | test "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 | } |
| 254 | 267 | ||
| 255 | test "cos128.special" { | 268 | test "cos128.special" { |
lib/compiler_rt/count0bits.zig+2-1| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const std = @import("std"); | 2 | const std = @import("std"); |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | ||
| 4 | 5 | ||
| 5 | comptime { | 6 | comptime { |
| 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; |
| 7 | const minInt = std.math.minInt; | 7 | const minInt = std.math.minInt; |
| 8 | const isFinite = std.math.isFinite; | 8 | const isFinite = std.math.isFinite; |
| 9 | const copysign = std.math.copysign; | 9 | const copysign = std.math.copysign; |
| 10 | const Complex = @import("mulc3.zig").Complex; | 10 | |
| 11 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 12 | const symbol = compiler_rt.symbol; | ||
| 13 | const Complex = compiler_rt.Complex; | ||
| 14 | |||
| 15 | comptime { | ||
| 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 | |||
| 29 | fn __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 | } | ||
| 35 | pub fn div_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) { | ||
| 36 | return divc3(f16, a, b); | ||
| 37 | } | ||
| 38 | |||
| 39 | fn __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 | } | ||
| 45 | pub fn div_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) { | ||
| 46 | return divc3(f32, a, b); | ||
| 47 | } | ||
| 48 | |||
| 49 | fn __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 | } | ||
| 55 | pub fn div_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) { | ||
| 56 | return divc3(f64, a, b); | ||
| 57 | } | ||
| 58 | |||
| 59 | fn __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 | } | ||
| 65 | pub fn div_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) { | ||
| 66 | return divc3(f80, a, b); | ||
| 67 | } | ||
| 68 | |||
| 69 | fn __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 | } | ||
| 75 | pub fn div_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) { | ||
| 76 | return divc3(f128, a, b); | ||
| 77 | } | ||
| 11 | 78 | ||
| 12 | /// Implementation based on Annex G of C17 Standard (N2176) | 79 | /// Implementation based on Annex G of C17 Standard (N2176) |
| 13 | pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { | 80 | inline 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; | ||
| 16 | 85 | ||
| 17 | // logbw used to prevent under/over-flow | 86 | // 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) { |
| 58 | 127 | ||
| 59 | return result; | 128 | return result; |
| 60 | } | 129 | } |
| 130 | |||
| 131 | test { | ||
| 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"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | const Complex = @import("./mulc3.zig").Complex; | 5 | const Complex = @import("../compiler_rt.zig").Complex; |
| 6 | const __divhc3 = @import("./divhc3.zig").__divhc3; | 6 | |
| 7 | const __divsc3 = @import("./divsc3.zig").__divsc3; | 7 | const impl = @import("divc3.zig"); |
| 8 | const __divdc3 = @import("./divdc3.zig").__divdc3; | 8 | const div_cf16 = impl.div_cf16; |
| 9 | const __divxc3 = @import("./divxc3.zig").__divxc3; | 9 | const div_cf32 = impl.div_cf32; |
| 10 | const __divtc3 = @import("./divtc3.zig").__divtc3; | 10 | const div_cf64 = impl.div_cf64; |
| 11 | const div_cf80 = impl.div_cf80; | ||
| 12 | const div_cf128 = impl.div_cf128; | ||
| 11 | 13 | ||
| 12 | test "divc3" { | 14 | test "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 | } |
| 19 | 21 | ||
| 20 | fn testDiv(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void { | 22 | fn 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 the | 34 | // 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 the | 41 | // 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 is | 48 | // 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 infinity | 49 | // 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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const divc3 = @import("./divc3.zig"); | ||
| 3 | const Complex = @import("./mulc3.zig").Complex; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__divdc3, "__divdc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 | } |
| 19 | 19 | ||
| 20 | pub fn __divdf3(a: f64, b: f64) callconv(.c) f64 { | 20 | fn __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 | } |
| 23 | 23 | ||
| 24 | fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | 24 | fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { |
| 25 | return div(a, b); | 25 | return div_f64(a, b); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | inline fn div(a: f64, b: f64) f64 { | 28 | pub 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); |
| 31 | 31 |
lib/compiler_rt/divdf3_test.zig+2-2| ... | @@ -6,7 +6,7 @@ const std = @import("std"); | ... | @@ -6,7 +6,7 @@ const std = @import("std"); |
| 6 | const math = std.math; | 6 | const math = std.math; |
| 7 | const testing = std.testing; | 7 | const testing = std.testing; |
| 8 | 8 | ||
| 9 | const __divdf3 = @import("divdf3.zig").__divdf3; | 9 | const div_f64 = @import("divdf3.zig").div_f64; |
| 10 | 10 | ||
| 11 | const nanRep: u64 = @as(u64, @bitCast(math.nan(f64))); | 11 | const nanRep: u64 = @as(u64, @bitCast(math.nan(f64))); |
| 12 | const infRep: u64 = @as(u64, @bitCast(math.inf(f64))); | 12 | const 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 | } |
| 31 | 31 | ||
| 32 | fn test__divdf3(a: f64, b: f64, expected: u64) !void { | 32 | fn 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const divc3 = @import("./divc3.zig"); | ||
| 4 | const Complex = @import("./mulc3.zig").Complex; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 8 | symbol(&__divhc3, "__divhc3"); | ||
| 9 | } | ||
| 10 | } | ||
| 11 | |||
| 12 | pub 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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const divsf3 = @import("./divsf3.zig"); | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__divhf3, "__divhf3"); | ||
| 6 | } | ||
| 7 | |||
| 8 | pub 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"); |
| 5 | 5 | ||
| 6 | const compiler_rt = @import("../compiler_rt.zig"); | 6 | const compiler_rt = @import("../compiler_rt.zig"); |
| 7 | const udivmod = @import("udivmodei4.zig").divmod; | 7 | const udivmod = @import("udivmodei4.zig").divmod; |
| 8 | const symbol = @import("../compiler_rt.zig").symbol; | 8 | const symbol = compiler_rt.symbol; |
| 9 | 9 | ||
| 10 | comptime { | 10 | comptime { |
| 11 | symbol(&__divei4, "__divei4"); | 11 | symbol(&__divei4, "__divei4"); |
lib/compiler_rt/divsc3.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const divc3 = @import("./divc3.zig"); | ||
| 2 | const Complex = @import("./mulc3.zig").Complex; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__divsc3, "__divsc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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; |
| 9 | const normalize = compiler_rt.normalize; | 9 | const normalize = compiler_rt.normalize; |
| 10 | 10 | ||
| 11 | comptime { | 11 | comptime { |
| 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 | } |
| 18 | 19 | ||
| 19 | pub fn __divsf3(a: f32, b: f32) callconv(.c) f32 { | 20 | fn __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 | } | ||
| 23 | pub fn div_f16(a: f16, b: f16) f16 { | ||
| 24 | // TODO: more efficient implementation | ||
| 25 | return @floatCast(div_f32(a, b)); | ||
| 26 | } | ||
| 27 | |||
| 28 | fn __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 | } |
| 22 | 31 | ||
| 23 | fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | 32 | fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { |
| 24 | return div(a, b); | 33 | return div_f32(a, b); |
| 25 | } | 34 | } |
| 26 | 35 | ||
| 27 | inline fn div(a: f32, b: f32) f32 { | 36 | pub fn div_f32(a: f32, b: f32) f32 { |
| 28 | const Z = @Int(.unsigned, 32); | 37 | const Z = @Int(.unsigned, 32); |
| 29 | 38 | ||
| 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"); |
| 6 | const math = std.math; | 6 | const math = std.math; |
| 7 | const testing = std.testing; | 7 | const testing = std.testing; |
| 8 | 8 | ||
| 9 | const __divsf3 = @import("divsf3.zig").__divsf3; | 9 | const div_f32 = @import("divsf3.zig").div_f32; |
| 10 | 10 | ||
| 11 | const nanRep: u32 = @as(u32, @bitCast(math.nan(f32))); | 11 | const nanRep: u32 = @as(u32, @bitCast(math.nan(f32))); |
| 12 | const infRep: u32 = @as(u32, @bitCast(math.inf(f32))); | 12 | const 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 | } |
| 31 | 31 | ||
| 32 | fn test__divsf3(a: f32, b: f32, expected: u32) !void { | 32 | fn 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const divc3 = @import("./divc3.zig"); | ||
| 3 | const Complex = @import("./mulc3.zig").Complex; | ||
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 5 | |||
| 6 | comptime { | ||
| 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 | |||
| 14 | pub 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 | } |
| 19 | 20 | ||
| 20 | pub fn __divtf3(a: f128, b: f128) callconv(.c) f128 { | 21 | fn __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 | } |
| 23 | 24 | ||
| 24 | fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | 25 | fn _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 | } |
| 27 | 28 | ||
| 28 | inline fn div(a: f128, b: f128) f128 { | 29 | pub fn div_f128(a: f128, b: f128) f128 { |
| 29 | const Z = @Int(.unsigned, 128); | 30 | const Z = @Int(.unsigned, 128); |
| 30 | 31 | ||
| 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"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const testing = std.testing; | 3 | const testing = std.testing; |
| 4 | 4 | ||
| 5 | const __divtf3 = @import("divtf3.zig").__divtf3; | 5 | const div_f128 = @import("divtf3.zig").div_f128; |
| 6 | 6 | ||
| 7 | fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { | 7 | fn 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 | } |
| 25 | 25 | ||
| 26 | fn test__divtf3(a: f128, b: f128, expectedHi: u64, expectedLo: u64) !void { | 26 | fn 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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const divc3 = @import("./divc3.zig"); | ||
| 3 | const Complex = @import("./mulc3.zig").Complex; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__divxc3, "__divxc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 | } |
| 13 | 13 | ||
| 14 | pub fn __divxf3(a: f80, b: f80) callconv(.c) f80 { | 14 | fn __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 | } | ||
| 17 | pub 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)); |
| 17 | 20 |
lib/compiler_rt/divxf3_test.zig+3-3| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const testing = std.testing; | 3 | const testing = std.testing; |
| 4 | 4 | ||
| 5 | const __divxf3 = @import("divxf3.zig").__divxf3; | 5 | const div_f80 = @import("divxf3.zig").div_f80; |
| 6 | 6 | ||
| 7 | const nanRep: u80 = @as(u80, @bitCast(math.nan(f80))); | 7 | const nanRep: u80 = @as(u80, @bitCast(math.nan(f80))); |
| 8 | const infRep: u80 = @as(u80, @bitCast(math.inf(f80))); | 8 | const 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 | } |
| 20 | 20 | ||
| 21 | fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void { | 21 | fn 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 | } |
| 26 | 26 | ||
| 27 | fn test__divxf3(a: f80, b: f80) !void { | 27 | fn 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); |
| 30 | 30 | ||
| 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; |
| 14 | const expectEqual = std.testing.expectEqual; | 14 | const expectEqual = std.testing.expectEqual; |
| 15 | 15 | ||
| 16 | const compiler_rt = @import("../compiler_rt.zig"); | 16 | const compiler_rt = @import("../compiler_rt.zig"); |
| 17 | const symbol = @import("../compiler_rt.zig").symbol; | 17 | const symbol = compiler_rt.symbol; |
| 18 | 18 | ||
| 19 | comptime { | 19 | comptime { |
| 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 | } |
| 30 | 27 | ||
| 31 | pub fn __exph(a: f16) callconv(.c) f16 { | 28 | fn __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 | } | ||
| 31 | pub fn exp_f16(x: f16) f16 { | ||
| 32 | // TODO: more efficient implementation | 32 | // TODO: more efficient implementation |
| 33 | return @floatCast(expf(a)); | 33 | return @floatCast(exp_f32(x)); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | pub fn expf(x_: f32) callconv(.c) f32 { | 36 | fn 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 | } | ||
| 39 | pub 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 | } |
| 110 | 113 | ||
| 111 | pub fn exp(x_: f64) callconv(.c) f64 { | 114 | fn 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 | } | ||
| 117 | pub 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 | } |
| 191 | 197 | ||
| 192 | pub fn __expx(a: f80) callconv(.c) f80 { | 198 | fn __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 | } | ||
| 201 | pub fn exp_f80(x: f80) f80 { | ||
| 193 | // TODO: more efficient implementation | 202 | // TODO: more efficient implementation |
| 194 | return @floatCast(expq(a)); | 203 | return @floatCast(exp_f128(x)); |
| 195 | } | 204 | } |
| 196 | 205 | ||
| 197 | const expq = @import("exp_f128.zig").exp; | 206 | fn 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 | } | ||
| 209 | pub const exp_f128 = @import("exp_f128.zig").exp; | ||
| 198 | 210 | ||
| 199 | pub fn expl(x: c_longdouble) callconv(.c) c_longdouble { | 211 | pub 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 | } |
| 207 | 219 | ||
| 208 | test "expf() special" { | 220 | test "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 | } |
| 218 | 230 | ||
| 219 | test "expf() sanity" { | 231 | test "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 | } |
| 241 | 253 | ||
| 242 | test "expf() boundary" { | 254 | test "expf() boundary" { |
| 243 | try expectEqual(expf(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite | 255 | 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 inf | 256 | 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 value | 257 | try expectEqual(exp_f32(0x1.fffffep+127), math.inf(f32)); // Max input value |
| 246 | try expectEqual(expf(0x1p-149), 1.0); // Min positive input value | 258 | try expectEqual(exp_f32(0x1p-149), 1.0); // Min positive input value |
| 247 | try expectEqual(expf(-0x1p-149), 1.0); // Min negative input value | 259 | try expectEqual(exp_f32(-0x1p-149), 1.0); // Min negative input value |
| 248 | try expectEqual(expf(0x1p-126), 1.0); // First positive subnormal input | 260 | try expectEqual(exp_f32(0x1p-126), 1.0); // First positive subnormal input |
| 249 | try expectEqual(expf(-0x1p-126), 1.0); // First negative subnormal input | 261 | 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 zero | 262 | 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 zero | 263 | 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 subnormal | 264 | 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 subnormal | 265 | try expectEqual(exp_f32(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal |
| 254 | |||
| 255 | } | 266 | } |
| 256 | 267 | ||
| 257 | test "exp() special" { | 268 | test "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 GCC | 271 | // 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 | } |
| 268 | 279 | ||
| 269 | test "exp() sanity" { | 280 | test "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 | } |
| 291 | 302 | ||
| 292 | test "exp() boundary" { | 303 | test "exp() boundary" { |
| 293 | try expectEqual(exp(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite | 304 | 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 inf | 305 | 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 value | 306 | try expectEqual(exp_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value |
| 296 | try expectEqual(exp(0x1p-1074), 1.0); // Min positive input value | 307 | try expectEqual(exp_f64(0x1p-1074), 1.0); // Min positive input value |
| 297 | try expectEqual(exp(-0x1p-1074), 1.0); // Min negative input value | 308 | try expectEqual(exp_f64(-0x1p-1074), 1.0); // Min negative input value |
| 298 | try expectEqual(exp(0x1p-1022), 1.0); // First positive subnormal input | 309 | try expectEqual(exp_f64(0x1p-1022), 1.0); // First positive subnormal input |
| 299 | try expectEqual(exp(-0x1p-1022), 1.0); // First negative subnormal input | 310 | 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 zero | 311 | 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 zero | 312 | 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 subnormal | 313 | 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 subnormal | 314 | 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 | } |
| 28 | 25 | ||
| 29 | pub fn __exp2h(x: f16) callconv(.c) f16 { | 26 | fn __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 | } | ||
| 29 | pub fn exp2_f16(x: f16) f16 { | ||
| 30 | // TODO: more efficient implementation | 30 | // TODO: more efficient implementation |
| 31 | return @floatCast(exp2f(x)); | 31 | return @floatCast(exp2_f32(x)); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | pub fn exp2f(x: f32) callconv(.c) f32 { | 34 | fn 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 | } | ||
| 37 | pub 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 | } |
| 90 | 93 | ||
| 91 | pub fn exp2(x: f64) callconv(.c) f64 { | 94 | fn 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 | } | ||
| 97 | pub 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 | } |
| 158 | 164 | ||
| 159 | pub fn __exp2x(x: f80) callconv(.c) f80 { | 165 | fn __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 | } | ||
| 168 | pub fn exp2_f80(x: f80) f80 { | ||
| 160 | // TODO: more efficient implementation | 169 | // TODO: more efficient implementation |
| 161 | return @floatCast(exp2q(x)); | 170 | return @floatCast(exp2_f128(x)); |
| 162 | } | 171 | } |
| 163 | 172 | ||
| 164 | pub const exp2q = @import("exp_f128.zig").exp2; | 173 | fn 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 | } | ||
| 176 | pub const exp2_f128 = @import("exp_f128.zig").exp2; | ||
| 165 | 177 | ||
| 166 | pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble { | 178 | pub 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 | } |
| 174 | 186 | ||
| ... | @@ -452,77 +464,77 @@ const exp2dt = [_]f64{ | ... | @@ -452,77 +464,77 @@ const exp2dt = [_]f64{ |
| 452 | }; | 464 | }; |
| 453 | 465 | ||
| 454 | test "exp2f() special" { | 466 | test "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 | } |
| 464 | 476 | ||
| 465 | test "exp2f() sanity" { | 477 | test "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 | } |
| 477 | 489 | ||
| 478 | test "exp2f() boundary" { | 490 | test "exp2f() boundary" { |
| 479 | try expectEqual(exp2f(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite | 491 | 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 result | 492 | 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 zero | 493 | 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 zero | 494 | 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 subnormal | 495 | 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 subnormal | 496 | 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 value | 497 | try expectEqual(exp2_f32(0x1.fffffep+127), math.inf(f32)); // Max input value |
| 486 | try expectEqual(exp2f(0x1p-149), 1); // Min positive input value | 498 | try expectEqual(exp2_f32(0x1p-149), 1); // Min positive input value |
| 487 | try expectEqual(exp2f(-0x1p-149), 1); // Min negative input value | 499 | try expectEqual(exp2_f32(-0x1p-149), 1); // Min negative input value |
| 488 | try expectEqual(exp2f(0x1p-126), 1); // First positive subnormal input | 500 | try expectEqual(exp2_f32(0x1p-126), 1); // First positive subnormal input |
| 489 | try expectEqual(exp2f(-0x1p-126), 1); // First negative subnormal input | 501 | try expectEqual(exp2_f32(-0x1p-126), 1); // First negative subnormal input |
| 490 | } | 502 | } |
| 491 | 503 | ||
| 492 | test "exp2() special" { | 504 | test "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 | } |
| 502 | 514 | ||
| 503 | test "exp2() sanity" { | 515 | test "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 | } |
| 515 | 527 | ||
| 516 | test "exp2() boundary" { | 528 | test "exp2() boundary" { |
| 517 | try expectEqual(exp2(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite | 529 | 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 result | 530 | 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 zero | 531 | 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 zero | 532 | 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 subnormal | 533 | 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 subnormal | 534 | 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 value | 535 | try expectEqual(exp2_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value |
| 524 | try expectEqual(exp2(0x1p-1074), 1); // Min positive input value | 536 | try expectEqual(exp2_f64(0x1p-1074), 1); // Min positive input value |
| 525 | try expectEqual(exp2(-0x1p-1074), 1); // Min negative input value | 537 | try expectEqual(exp2_f64(-0x1p-1074), 1); // Min negative input value |
| 526 | try expectEqual(exp2(0x1p-1022), 1); // First positive subnormal input | 538 | try expectEqual(exp2_f64(0x1p-1022), 1); // First positive subnormal input |
| 527 | try expectEqual(exp2(-0x1p-1022), 1); // First negative subnormal input | 539 | 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(); |
| 26 | const std = @import("std"); | 26 | const std = @import("std"); |
| 27 | const math = std.math; | 27 | const math = std.math; |
| 28 | 28 | ||
| 29 | pub fn exp(x: f128) callconv(.c) f128 { | 29 | pub 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 | } |
| 92 | 92 | ||
| 93 | /// Computes 2^x | 93 | /// Computes 2^x |
| 94 | pub fn exp2(x: f128) callconv(.c) f128 { | 94 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const extendf = @import("./extendf.zig").extendf; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __extenddftf2(a: f64) callconv(.c) f128 { | ||
| 17 | return extendf(f128, f64, @as(u64, @bitCast(a))); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extend_f80 = @import("./extendf.zig").extend_f80; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extenddfxf2, "__extenddfxf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub 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 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub inline fn extendf( | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | comptime dst_t: type, | 4 | const symbol = compiler_rt.symbol; |
| 5 | comptime src_t: type, | 5 | |
| 6 | a: @Int(.unsigned, @typeInfo(src_t).float.bits), | 6 | comptime { |
| 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 | |||
| 59 | fn __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 | } | ||
| 62 | fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) u32 { | ||
| 63 | return @bitCast(f32_floatCast_f16(@bitCast(a))); | ||
| 64 | } | ||
| 65 | pub fn f32_floatCast_f16(a: f16) f32 { | ||
| 66 | return extendf(f32, f16, a); | ||
| 67 | } | ||
| 68 | |||
| 69 | fn __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 | } | ||
| 72 | pub fn f64_floatCast_f16(a: f16) f64 { | ||
| 73 | return extendf(f64, f16, a); | ||
| 74 | } | ||
| 75 | |||
| 76 | fn __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 | } | ||
| 79 | pub fn f80_floatCast_f16(a: f16) f80 { | ||
| 80 | return extend_f80(f16, a); | ||
| 81 | } | ||
| 82 | |||
| 83 | fn __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 | } | ||
| 86 | pub fn f128_floatCast_f16(a: f16) f128 { | ||
| 87 | return extendf(f128, f16, a); | ||
| 88 | } | ||
| 89 | |||
| 90 | fn __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 | } | ||
| 93 | fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 94 | return f64_floatCast_f32(a); | ||
| 95 | } | ||
| 96 | pub fn f64_floatCast_f32(a: f32) f64 { | ||
| 97 | return extendf(f64, f32, a); | ||
| 98 | } | ||
| 99 | |||
| 100 | fn __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 | } | ||
| 103 | pub fn f80_floatCast_f32(a: f32) f80 { | ||
| 104 | return extend_f80(f32, a); | ||
| 105 | } | ||
| 106 | |||
| 107 | pub 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 | } | ||
| 110 | fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void { | ||
| 111 | c.* = f128_floatCast_f32(a); | ||
| 112 | } | ||
| 113 | pub fn f128_floatCast_f32(a: f32) f128 { | ||
| 114 | return extendf(f128, f32, a); | ||
| 115 | } | ||
| 116 | |||
| 117 | fn __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 | } | ||
| 120 | pub fn f80_floatCast_f64(a: f64) f80 { | ||
| 121 | return extend_f80(f64, a); | ||
| 122 | } | ||
| 123 | |||
| 124 | fn __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 | } | ||
| 127 | fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void { | ||
| 128 | c.* = f128_floatCast_f64(a); | ||
| 129 | } | ||
| 130 | pub fn f128_floatCast_f64(a: f64) f128 { | ||
| 131 | return extendf(f128, f64, a); | ||
| 132 | } | ||
| 133 | |||
| 134 | fn __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 | } | ||
| 137 | pub 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 | |||
| 172 | inline 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( |
| 31 | 196 | ||
| 32 | const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits; | 197 | const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits; |
| 33 | 198 | ||
| 199 | const a: src_rep_t = @bitCast(f); | ||
| 34 | // Break a into a sign and representation of the absolute value | 200 | // 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 | } |
| 67 | 233 | ||
| 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 | } |
| 72 | 238 | ||
| 73 | pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_t).float.bits)) f80 { | 239 | inline 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_ |
| 92 | 258 | ||
| 93 | var dst: std.math.F80 = undefined; | 259 | var dst: std.math.F80 = undefined; |
| 94 | 260 | ||
| 261 | const a: src_rep_t = @bitCast(f); | ||
| 95 | // Break a into a sign and representation of the absolute value | 262 | // 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 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | |||
| 3 | const std = @import("std"); | 2 | const std = @import("std"); |
| 4 | const math = std.math; | 3 | const testing = std.testing; |
| 4 | |||
| 5 | const impl = @import("extendf.zig"); | ||
| 6 | |||
| 7 | const f32_floatCast_f16 = impl.f32_floatCast_f16; | ||
| 8 | const f64_floatCast_f16 = impl.f64_floatCast_f16; | ||
| 9 | const f80_floatCast_f16 = impl.f80_floatCast_f16; | ||
| 10 | const f128_floatCast_f16 = impl.f128_floatCast_f16; | ||
| 11 | |||
| 12 | const f64_floatCast_f32 = impl.f64_floatCast_f32; | ||
| 13 | const f80_floatCast_f32 = impl.f80_floatCast_f32; | ||
| 14 | const f128_floatCast_f32 = impl.f128_floatCast_f32; | ||
| 5 | 15 | ||
| 6 | const __extendhfsf2 = @import("extendhfsf2.zig").__extendhfsf2; | 16 | const f80_floatCast_f64 = impl.f80_floatCast_f64; |
| 7 | const __extendhftf2 = @import("extendhftf2.zig").__extendhftf2; | 17 | const f128_floatCast_f64 = impl.f128_floatCast_f64; |
| 8 | const __extendsftf2 = @import("extendsftf2.zig").__extendsftf2; | ||
| 9 | const __extenddftf2 = @import("extenddftf2.zig").__extenddftf2; | ||
| 10 | const __extenddfxf2 = @import("extenddfxf2.zig").__extenddfxf2; | ||
| 11 | const F16T = @import("../compiler_rt.zig").F16T; | ||
| 12 | 18 | ||
| 13 | fn test__extenddfxf2(a: f64, expected: u80) !void { | 19 | const f128_floatCast_f80 = impl.f128_floatCast_f80; |
| 14 | const x = __extenddfxf2(a); | 20 | |
| 21 | fn test_f80_floatCast_f64(a: f64, expected: u80) !void { | ||
| 22 | const x = f80_floatCast_f64(a); | ||
| 15 | 23 | ||
| 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; |
| 23 | 30 | return error.TestFailure; | |
| 24 | @panic("__extenddfxf2 test failure"); | ||
| 25 | } | 31 | } |
| 26 | 32 | ||
| 27 | fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { | 33 | fn 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); |
| 29 | 35 | ||
| 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 { |
| 33 | 39 | ||
| 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 and | 44 | 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 | } |
| 45 | 50 | return error.TestFailure; | |
| 46 | @panic("__extenddftf2 test failure"); | ||
| 47 | } | 51 | } |
| 48 | 52 | ||
| 49 | fn test__extendhfsf2(a: u16, expected: u32) !void { | 53 | fn 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); |
| 52 | 56 | ||
| 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 | } |
| 64 | 67 | ||
| 65 | fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { | 68 | fn 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); |
| 67 | 70 | ||
| 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 { |
| 71 | 74 | ||
| 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 and | 79 | 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 | } |
| 86 | 87 | ||
| 87 | test "extenddfxf2" { | 88 | test f80_floatCast_f64 { |
| 88 | // qNaN | 89 | // qNaN |
| 89 | try test__extenddfxf2(makeQNaN64(), 0x7fffc000000000000000); | 90 | try test_f80_floatCast_f64(makeQNaN64(), 0x7fffc000000000000000); |
| 90 | 91 | ||
| 91 | // NaN | 92 | // 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? |
| 94 | 95 | ||
| 95 | // inf | 96 | // inf |
| 96 | try test__extenddfxf2(makeInf64(), 0x7fff8000000000000000); | 97 | try test_f80_floatCast_f64(makeInf64(), 0x7fff8000000000000000); |
| 97 | 98 | ||
| 98 | // zero | 99 | // zero |
| 99 | try test__extenddfxf2(0.0, 0x0); | 100 | try test_f80_floatCast_f64(0.0, 0x0); |
| 100 | 101 | ||
| 101 | try test__extenddfxf2(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000); | 102 | try test_f80_floatCast_f64(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000); |
| 102 | 103 | ||
| 103 | try test__extenddfxf2(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000); | 104 | try test_f80_floatCast_f64(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000); |
| 104 | 105 | ||
| 105 | try test__extenddfxf2(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000); | 106 | try test_f80_floatCast_f64(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000); |
| 106 | 107 | ||
| 107 | try test__extenddfxf2(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000); | 108 | try test_f80_floatCast_f64(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000); |
| 108 | 109 | ||
| 109 | // subnormal | 110 | // 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 | } |
| 113 | 114 | ||
| 114 | test "extenddftf2" { | 115 | test f128_floatCast_f64 { |
| 115 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 116 | |||
| 117 | // qNaN | 116 | // qNaN |
| 118 | try test__extenddftf2(makeQNaN64(), 0x7fff800000000000, 0x0); | 117 | try test_f128_floatCast_f64(makeQNaN64(), 0x7fff800000000000, 0x0); |
| 119 | 118 | ||
| 120 | // NaN | 119 | // NaN |
| 121 | try test__extenddftf2(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0); | 120 | try test_f128_floatCast_f64(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0); |
| 122 | 121 | ||
| 123 | // inf | 122 | // inf |
| 124 | try test__extenddftf2(makeInf64(), 0x7fff000000000000, 0x0); | 123 | try test_f128_floatCast_f64(makeInf64(), 0x7fff000000000000, 0x0); |
| 125 | 124 | ||
| 126 | // zero | 125 | // zero |
| 127 | try test__extenddftf2(0.0, 0x0, 0x0); | 126 | try test_f128_floatCast_f64(0.0, 0x0, 0x0); |
| 128 | 127 | ||
| 129 | try test__extenddftf2(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000); | 128 | try test_f128_floatCast_f64(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000); |
| 130 | 129 | ||
| 131 | try test__extenddftf2(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000); | 130 | try test_f128_floatCast_f64(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000); |
| 132 | 131 | ||
| 133 | try test__extenddftf2(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000); | 132 | try test_f128_floatCast_f64(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000); |
| 134 | 133 | ||
| 135 | try test__extenddftf2(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000); | 134 | try test_f128_floatCast_f64(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000); |
| 136 | 135 | ||
| 137 | // subnormal | 136 | // 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 | } |
| 141 | 140 | ||
| 142 | test "extendhfsf2" { | 141 | test f32_floatCast_f16 { |
| 143 | try test__extendhfsf2(0x7e00, 0x7fc00000); // qNaN | 142 | try test_f32_floatCast_f16(0x7e00, 0x7fc00000); // qNaN |
| 144 | try test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN | 143 | try test_f32_floatCast_f16(0x7f00, 0x7fe00000); // sNaN |
| 145 | // On x86 the NaN becomes quiet because the return is pushed on the x87 | 144 | // On x86 the NaN becomes quiet because the return is pushed on the x87 |
| 146 | // stack due to ABI requirements | 145 | // 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); // sNaN | 147 | try test_f32_floatCast_f16(0x7c01, 0x7f802000); // sNaN |
| 149 | 148 | ||
| 150 | try test__extendhfsf2(0, 0); // 0 | 149 | try test_f32_floatCast_f16(0, 0); // 0 |
| 151 | try test__extendhfsf2(0x8000, 0x80000000); // -0 | 150 | try test_f32_floatCast_f16(0x8000, 0x80000000); // -0 |
| 152 | 151 | ||
| 153 | try test__extendhfsf2(0x7c00, 0x7f800000); // inf | 152 | try test_f32_floatCast_f16(0x7c00, 0x7f800000); // inf |
| 154 | try test__extendhfsf2(0xfc00, 0xff800000); // -inf | 153 | try test_f32_floatCast_f16(0xfc00, 0xff800000); // -inf |
| 155 | 154 | ||
| 156 | try test__extendhfsf2(0x0001, 0x33800000); // denormal (min), 2**-24 | 155 | try test_f32_floatCast_f16(0x0001, 0x33800000); // denormal (min), 2**-24 |
| 157 | try test__extendhfsf2(0x8001, 0xb3800000); // denormal (min), -2**-24 | 156 | try test_f32_floatCast_f16(0x8001, 0xb3800000); // denormal (min), -2**-24 |
| 158 | 157 | ||
| 159 | try test__extendhfsf2(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24 | 158 | try test_f32_floatCast_f16(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24 |
| 160 | try test__extendhfsf2(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24 | 159 | try test_f32_floatCast_f16(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24 |
| 161 | 160 | ||
| 162 | try test__extendhfsf2(0x0400, 0x38800000); // normal (min), 2**-14 | 161 | try test_f32_floatCast_f16(0x0400, 0x38800000); // normal (min), 2**-14 |
| 163 | try test__extendhfsf2(0x8400, 0xb8800000); // normal (min), -2**-14 | 162 | try test_f32_floatCast_f16(0x8400, 0xb8800000); // normal (min), -2**-14 |
| 164 | 163 | ||
| 165 | try test__extendhfsf2(0x7bff, 0x477fe000); // normal (max), 65504 | 164 | try test_f32_floatCast_f16(0x7bff, 0x477fe000); // normal (max), 65504 |
| 166 | try test__extendhfsf2(0xfbff, 0xc77fe000); // normal (max), -65504 | 165 | try test_f32_floatCast_f16(0xfbff, 0xc77fe000); // normal (max), -65504 |
| 167 | 166 | ||
| 168 | try test__extendhfsf2(0x3c01, 0x3f802000); // normal, 1 + 2**-10 | 167 | try test_f32_floatCast_f16(0x3c01, 0x3f802000); // normal, 1 + 2**-10 |
| 169 | try test__extendhfsf2(0xbc01, 0xbf802000); // normal, -1 - 2**-10 | 168 | try test_f32_floatCast_f16(0xbc01, 0xbf802000); // normal, -1 - 2**-10 |
| 170 | 169 | ||
| 171 | try test__extendhfsf2(0x3555, 0x3eaaa000); // normal, approx. 1/3 | 170 | try test_f32_floatCast_f16(0x3555, 0x3eaaa000); // normal, approx. 1/3 |
| 172 | try test__extendhfsf2(0xb555, 0xbeaaa000); // normal, approx. -1/3 | 171 | try test_f32_floatCast_f16(0xb555, 0xbeaaa000); // normal, approx. -1/3 |
| 173 | } | 172 | } |
| 174 | 173 | ||
| 175 | test "extendsftf2" { | 174 | test f128_floatCast_f32 { |
| 176 | // qNaN | 175 | // qNaN |
| 177 | try test__extendsftf2(makeQNaN32(), 0x7fff800000000000, 0x0); | 176 | try test_f128_floatCast_f32(makeQNaN32(), 0x7fff800000000000, 0x0); |
| 178 | // NaN | 177 | // NaN |
| 179 | try test__extendsftf2(makeNaN32(0x410000), 0x7fff820000000000, 0x0); | 178 | try test_f128_floatCast_f32(makeNaN32(0x410000), 0x7fff820000000000, 0x0); |
| 180 | // inf | 179 | // inf |
| 181 | try test__extendsftf2(makeInf32(), 0x7fff000000000000, 0x0); | 180 | try test_f128_floatCast_f32(makeInf32(), 0x7fff000000000000, 0x0); |
| 182 | // zero | 181 | // 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 | } |
| 189 | 188 | ||
| 190 | fn makeQNaN64() f64 { | 189 | fn 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 | } |
| 213 | 212 | ||
| 214 | fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void { | 213 | fn 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)); |
| 216 | 215 | ||
| 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 | } |
| 235 | 234 | ||
| 236 | test "extendhftf2" { | 235 | test f128_floatCast_f16 { |
| 237 | // qNaN | 236 | // qNaN |
| 238 | try test__extendhftf2(0x7e00, 0x7fff800000000000, 0x0); | 237 | try test_f128_floatCast_f16(0x7e00, 0x7fff800000000000, 0x0); |
| 239 | // NaN | 238 | // NaN |
| 240 | try test__extendhftf2(0x7d00, 0x7fff400000000000, 0x0); | 239 | try test_f128_floatCast_f16(0x7d00, 0x7fff400000000000, 0x0); |
| 241 | // inf | 240 | // 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 | // zero | 243 | // 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 | // denormal | 246 | // 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); |
| 251 | 250 | ||
| 252 | // pi | 251 | // 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); |
| 255 | 254 | ||
| 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const extendf = @import("./extendf.zig").extendf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extendhfdf2, "__extendhfdf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const extendf = @import("./extendf.zig").extendf; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 14 | pub fn __extendhfsf2(a: compiler_rt.F16T(f32)) callconv(.c) f32 { | ||
| 15 | return extendf(f32, f16, @as(u16, @bitCast(a))); | ||
| 16 | } | ||
| 17 | |||
| 18 | fn __gnu_h2f_ieee(a: compiler_rt.F16T(f32)) callconv(.c) f32 { | ||
| 19 | return extendf(f32, f16, @as(u16, @bitCast(a))); | ||
| 20 | } | ||
| 21 | |||
| 22 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extendf = @import("./extendf.zig").extendf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extendhftf2, "__extendhftf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extend_f80 = @import("./extendf.zig").extend_f80; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extendhfxf2, "__extendhfxf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extendf = @import("./extendf.zig").extendf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_f2d, "__aeabi_f2d"); | ||
| 8 | } else { | ||
| 9 | symbol(&__extendsfdf2, "__extendsfdf2"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __extendsfdf2(a: f32) callconv(.c) f64 { | ||
| 14 | return extendf(f64, f32, @as(u32, @bitCast(a))); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extendf = @import("./extendf.zig").extendf; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __extendsftf2(a: f32) callconv(.c) f128 { | ||
| 17 | return extendf(f128, f32, @as(u32, @bitCast(a))); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const extend_f80 = @import("./extendf.zig").extend_f80; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__extendsfxf2, "__extendsfxf2"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extendxftf2, "__extendxftf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __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 | } |
| 18 | 15 | ||
| 19 | pub fn __fabsh(a: f16) callconv(.c) f16 { | 16 | fn __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 | } | ||
| 19 | pub fn fabs_f16(a: f16) f16 { | ||
| 20 | return generic_fabs(a); | 20 | return generic_fabs(a); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | pub fn fabsf(a: f32) callconv(.c) f32 { | 23 | fn 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 | } | ||
| 26 | pub fn fabs_f32(a: f32) f32 { | ||
| 24 | return generic_fabs(a); | 27 | return generic_fabs(a); |
| 25 | } | 28 | } |
| 26 | 29 | ||
| 27 | pub fn fabs(a: f64) callconv(.c) f64 { | 30 | fn 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 | } | ||
| 33 | pub fn fabs_f64(a: f64) f64 { | ||
| 28 | return generic_fabs(a); | 34 | return generic_fabs(a); |
| 29 | } | 35 | } |
| 30 | 36 | ||
| 31 | pub fn __fabsx(a: f80) callconv(.c) f80 { | 37 | fn __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 | } | ||
| 40 | pub fn fabs_f80(a: f80) f80 { | ||
| 32 | return generic_fabs(a); | 41 | return generic_fabs(a); |
| 33 | } | 42 | } |
| 34 | 43 | ||
| 35 | pub fn fabsq(a: f128) callconv(.c) f128 { | 44 | fn 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 | } | ||
| 47 | pub fn fabs_f128(a: f128) f128 { | ||
| 36 | return generic_fabs(a); | 48 | return generic_fabs(a); |
| 37 | } | 49 | } |
| 38 | 50 | ||
| 39 | pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble { | 51 | pub 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 | } |
| 47 | 59 |
lib/compiler_rt/fixdfdi.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 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 | |||
| 17 | pub fn __fixdfdi(a: f64) callconv(.c) i64 { | ||
| 18 | return intFromFloat(i64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixdfei, "__fixdfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_d2iz, "__aeabi_d2iz"); | ||
| 8 | } else { | ||
| 9 | symbol(&__fixdfsi, "__fixdfsi"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __fixdfsi(a: f64) callconv(.c) i32 { | ||
| 14 | return intFromFloat(i32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixdfti, "__fixdfti"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __fixdfti(a: f64) callconv(.c) i128 { | ||
| 10 | return intFromFloat(i128, a); | ||
| 11 | } | ||
lib/compiler_rt/fixhfei.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixhfei, "__fixhfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const math = std.math; | ||
| 3 | const testing = std.testing; | ||
| 4 | |||
| 5 | const fixint = @import("fixint.zig").fixint; | ||
| 6 | |||
| 7 | fn 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 | |||
| 12 | test "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 | |||
| 32 | test "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 | |||
| 53 | test "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 | |||
| 78 | test "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 | |||
| 102 | test "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 | |||
| 127 | test "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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 5 | |||
| 6 | comptime { | ||
| 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 | |||
| 17 | pub fn __fixsfdi(a: f32) callconv(.c) i64 { | ||
| 18 | return intFromFloat(i64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixsfei, "__fixsfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_f2iz, "__aeabi_f2iz"); | ||
| 8 | } else { | ||
| 9 | symbol(&__fixsfsi, "__fixsfsi"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __fixsfsi(a: f32) callconv(.c) i32 { | ||
| 14 | return intFromFloat(i32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__fixsfti, "__fixsfti"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __fixsfti(a: f32) callconv(.c) i128 { | ||
| 11 | return intFromFloat(i128, a); | ||
| 12 | } | ||
lib/compiler_rt/fixtfdi.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __fixtfdi(a: f128) callconv(.c) i64 { | ||
| 17 | return intFromFloat(i64, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixtfei, "__fixtfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __fixtfsi(a: f128) callconv(.c) i32 { | ||
| 17 | return intFromFloat(i32, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) | ||
| 7 | symbol(&__fixtfti, "__fixkfti"); | ||
| 8 | symbol(&__fixtfti, "__fixtfti"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __fixtfti(a: f128) callconv(.c) i128 { | ||
| 12 | return intFromFloat(i128, a); | ||
| 13 | } | ||
lib/compiler_rt/fixunsdfdi.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 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 | |||
| 17 | pub fn __fixunsdfdi(a: f64) callconv(.c) u64 { | ||
| 18 | return intFromFloat(u64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__fixunsdfei, "__fixunsdfei"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_d2uiz, "__aeabi_d2uiz"); | ||
| 8 | } else { | ||
| 9 | symbol(&__fixunsdfsi, "__fixunsdfsi"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __fixunsdfsi(a: f64) callconv(.c) u32 { | ||
| 14 | return intFromFloat(u32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixunsdfti, "__fixunsdfti"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __fixunsdfti(a: f64) callconv(.c) u128 { | ||
| 10 | return intFromFloat(u128, a); | ||
| 11 | } | ||
lib/compiler_rt/fixunshfdi.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__fixunshfdi, "__fixunshfdi"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __fixunshfdi(a: f16) callconv(.c) u64 { | ||
| 9 | return intFromFloat(u64, a); | ||
| 10 | } | ||
lib/compiler_rt/fixunshfei.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__fixunshfei, "__fixunshfei"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixunshfsi, "__fixunshfsi"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __fixunshfsi(a: f16) callconv(.c) u32 { | ||
| 10 | return intFromFloat(u32, a); | ||
| 11 | } | ||
lib/compiler_rt/fixunshfti.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixunshfti, "__fixunshfti"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __fixunshfti(a: f16) callconv(.c) u128 { | ||
| 10 | return intFromFloat(u128, a); | ||
| 11 | } | ||
lib/compiler_rt/fixunssfdi.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 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 | |||
| 17 | pub fn __fixunssfdi(a: f32) callconv(.c) u64 { | ||
| 18 | return intFromFloat(u64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__fixunssfei, "__fixunssfei"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_f2uiz, "__aeabi_f2uiz"); | ||
| 8 | } else { | ||
| 9 | symbol(&__fixunssfsi, "__fixunssfsi"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __fixunssfsi(a: f32) callconv(.c) u32 { | ||
| 14 | return intFromFloat(u32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__fixunssfti, "__fixunssfti"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __fixunssfti(a: f32) callconv(.c) u128 { | ||
| 11 | return intFromFloat(u128, a); | ||
| 12 | } | ||
lib/compiler_rt/fixunstfdi.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __fixunstfdi(a: f128) callconv(.c) u64 { | ||
| 17 | return intFromFloat(u64, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__fixunstfei, "__fixunstfei"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __fixunstfsi(a: f128) callconv(.c) u32 { | ||
| 17 | return intFromFloat(u32, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (compiler_rt.want_ppc_abi) | ||
| 8 | symbol(&__fixunstfti, "__fixunskfti"); | ||
| 9 | symbol(&__fixunstfti, "__fixunstfti"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __fixunstfti(a: f128) callconv(.c) u128 { | ||
| 13 | return intFromFloat(u128, a); | ||
| 14 | } | ||
lib/compiler_rt/fixunsxfdi.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__fixunsxfdi, "__fixunsxfdi"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __fixunsxfdi(a: f80) callconv(.c) u64 { | ||
| 9 | return intFromFloat(u64, a); | ||
| 10 | } | ||
lib/compiler_rt/fixunsxfei.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__fixunsxfei, "__fixunsxfei"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixunsxfsi, "__fixunsxfsi"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __fixunsxfsi(a: f80) callconv(.c) u32 { | ||
| 10 | return intFromFloat(u32, a); | ||
| 11 | } | ||
lib/compiler_rt/fixunsxfti.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__fixunsxfti, "__fixunsxfti"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __fixunsxfti(a: f80) callconv(.c) u128 { | ||
| 11 | return intFromFloat(u128, a); | ||
| 12 | } | ||
lib/compiler_rt/fixxfdi.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__fixxfdi, "__fixxfdi"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __fixxfdi(a: f80) callconv(.c) i64 { | ||
| 9 | return intFromFloat(i64, a); | ||
| 10 | } | ||
lib/compiler_rt/fixxfei.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixxfei, "__fixxfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixxfsi, "__fixxfsi"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __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 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const std = @import("std"); | 2 | const std = @import("std"); |
| 2 | const math = std.math; | 3 | const math = std.math; |
| 3 | 4 | ||
| 4 | pub fn floatFromInt(comptime T: type, x: anytype) T { | 5 | const compiler_rt = @import("../compiler_rt.zig"); |
| 6 | const symbol = compiler_rt.symbol; | ||
| 7 | |||
| 8 | comptime { | ||
| 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 | |||
| 67 | fn __floatsihf(a: i32) callconv(.c) compiler_rt.f16.Abi { | ||
| 68 | return compiler_rt.f16.toAbi(f16_floatFromInt_i32(a)); | ||
| 69 | } | ||
| 70 | pub fn f16_floatFromInt_i32(a: i32) f16 { | ||
| 71 | return floatFromInt(f16, a); | ||
| 72 | } | ||
| 73 | |||
| 74 | fn __floatdihf(a: i64) callconv(.c) compiler_rt.f16.Abi { | ||
| 75 | return compiler_rt.f16.toAbi(f16_floatFromInt_i64(a)); | ||
| 76 | } | ||
| 77 | pub fn f16_floatFromInt_i64(a: i64) f16 { | ||
| 78 | return floatFromInt(f16, a); | ||
| 79 | } | ||
| 80 | |||
| 81 | fn __floattihf(a: i128) callconv(.c) compiler_rt.f16.Abi { | ||
| 82 | return compiler_rt.f16.toAbi(f16_floatFromInt_i128(a)); | ||
| 83 | } | ||
| 84 | pub fn f16_floatFromInt_i128(a: i128) f16 { | ||
| 85 | return floatFromInt(f16, a); | ||
| 86 | } | ||
| 87 | |||
| 88 | fn __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 | } | ||
| 92 | pub fn f16_floatFromInt_signed(a: []const u8) f16 { | ||
| 93 | return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a))); | ||
| 94 | } | ||
| 95 | |||
| 96 | fn __floatsisf(a: i32) callconv(.c) compiler_rt.f32.Abi { | ||
| 97 | return compiler_rt.f32.toAbi(f32_floatFromInt_i32(a)); | ||
| 98 | } | ||
| 99 | fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 100 | return f32_floatFromInt_i32(a); | ||
| 101 | } | ||
| 102 | pub fn f32_floatFromInt_i32(a: i32) f32 { | ||
| 103 | return floatFromInt(f32, a); | ||
| 104 | } | ||
| 105 | |||
| 106 | fn __floatdisf(a: i64) callconv(.c) compiler_rt.f32.Abi { | ||
| 107 | return compiler_rt.f32.toAbi(f32_floatFromInt_i64(a)); | ||
| 108 | } | ||
| 109 | fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 110 | return f32_floatFromInt_i64(a); | ||
| 111 | } | ||
| 112 | pub fn f32_floatFromInt_i64(a: i64) f32 { | ||
| 113 | return floatFromInt(f32, a); | ||
| 114 | } | ||
| 115 | |||
| 116 | fn __floattisf(a: i128) callconv(.c) compiler_rt.f32.Abi { | ||
| 117 | return compiler_rt.f32.toAbi(f32_floatFromInt_i128(a)); | ||
| 118 | } | ||
| 119 | pub fn f32_floatFromInt_i128(a: i128) f32 { | ||
| 120 | return floatFromInt(f32, a); | ||
| 121 | } | ||
| 122 | |||
| 123 | fn __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 | } | ||
| 127 | pub fn f32_floatFromInt_signed(a: []const u8) f32 { | ||
| 128 | return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a))); | ||
| 129 | } | ||
| 130 | |||
| 131 | fn __floatsidf(a: i32) callconv(.c) compiler_rt.f64.Abi { | ||
| 132 | return compiler_rt.f64.toAbi(f64_floatFromInt_i32(a)); | ||
| 133 | } | ||
| 134 | fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 135 | return f64_floatFromInt_i32(a); | ||
| 136 | } | ||
| 137 | pub fn f64_floatFromInt_i32(a: i32) f64 { | ||
| 138 | return floatFromInt(f64, a); | ||
| 139 | } | ||
| 140 | |||
| 141 | fn __floatdidf(a: i64) callconv(.c) compiler_rt.f64.Abi { | ||
| 142 | return compiler_rt.f64.toAbi(f64_floatFromInt_i64(a)); | ||
| 143 | } | ||
| 144 | fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 145 | return f64_floatFromInt_i64(a); | ||
| 146 | } | ||
| 147 | pub fn f64_floatFromInt_i64(a: i64) f64 { | ||
| 148 | return floatFromInt(f64, a); | ||
| 149 | } | ||
| 150 | |||
| 151 | fn __floattidf(a: i128) callconv(.c) compiler_rt.f64.Abi { | ||
| 152 | return compiler_rt.f64.toAbi(f64_floatFromInt_i128(a)); | ||
| 153 | } | ||
| 154 | pub fn f64_floatFromInt_i128(a: i128) f64 { | ||
| 155 | return floatFromInt(f64, a); | ||
| 156 | } | ||
| 157 | |||
| 158 | fn __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 | } | ||
| 162 | pub fn f64_floatFromInt_signed(a: []const u8) f64 { | ||
| 163 | return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a))); | ||
| 164 | } | ||
| 165 | |||
| 166 | fn __floatsixf(a: i32) callconv(.c) compiler_rt.f80.Abi { | ||
| 167 | return compiler_rt.f80.toAbi(f80_floatFromInt_i32(a)); | ||
| 168 | } | ||
| 169 | pub fn f80_floatFromInt_i32(a: i32) f80 { | ||
| 170 | return floatFromInt(f80, a); | ||
| 171 | } | ||
| 172 | |||
| 173 | fn __floatdixf(a: i64) callconv(.c) compiler_rt.f80.Abi { | ||
| 174 | return compiler_rt.f80.toAbi(f80_floatFromInt_i64(a)); | ||
| 175 | } | ||
| 176 | pub fn f80_floatFromInt_i64(a: i64) f80 { | ||
| 177 | return floatFromInt(f80, a); | ||
| 178 | } | ||
| 179 | |||
| 180 | fn __floattixf(a: i128) callconv(.c) compiler_rt.f80.Abi { | ||
| 181 | return compiler_rt.f80.toAbi(f80_floatFromInt_i128(a)); | ||
| 182 | } | ||
| 183 | pub fn f80_floatFromInt_i128(a: i128) f80 { | ||
| 184 | return floatFromInt(f80, a); | ||
| 185 | } | ||
| 186 | |||
| 187 | fn __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 | } | ||
| 191 | pub fn f80_floatFromInt_signed(a: []const u8) f80 { | ||
| 192 | return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a))); | ||
| 193 | } | ||
| 194 | |||
| 195 | fn __floatsitf(a: i32) callconv(.c) compiler_rt.f128.Abi { | ||
| 196 | return compiler_rt.f128.toAbi(f128_floatFromInt_i32(a)); | ||
| 197 | } | ||
| 198 | fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void { | ||
| 199 | c.* = f128_floatFromInt_i32(a); | ||
| 200 | } | ||
| 201 | pub fn f128_floatFromInt_i32(a: i32) f128 { | ||
| 202 | return floatFromInt(f128, a); | ||
| 203 | } | ||
| 204 | |||
| 205 | fn __floatditf(a: i64) callconv(.c) compiler_rt.f128.Abi { | ||
| 206 | return compiler_rt.f128.toAbi(f128_floatFromInt_i64(a)); | ||
| 207 | } | ||
| 208 | fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void { | ||
| 209 | c.* = f128_floatFromInt_i64(a); | ||
| 210 | } | ||
| 211 | pub fn f128_floatFromInt_i64(a: i64) f128 { | ||
| 212 | return floatFromInt(f128, a); | ||
| 213 | } | ||
| 214 | |||
| 215 | fn __floattitf(a: i128) callconv(.c) compiler_rt.f128.Abi { | ||
| 216 | return compiler_rt.f128.toAbi(f128_floatFromInt_i128(a)); | ||
| 217 | } | ||
| 218 | fn __floattitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi { | ||
| 219 | return compiler_rt.f128.toAbi(f128_floatFromInt_i128(@bitCast(a))); | ||
| 220 | } | ||
| 221 | pub fn f128_floatFromInt_i128(a: i128) f128 { | ||
| 222 | return floatFromInt(f128, a); | ||
| 223 | } | ||
| 224 | |||
| 225 | fn __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 | } | ||
| 229 | pub fn f128_floatFromInt_signed(a: []const u8) f128 { | ||
| 230 | return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a))); | ||
| 231 | } | ||
| 232 | |||
| 233 | comptime { | ||
| 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 | |||
| 301 | fn __floatunsihf(a: u32) callconv(.c) compiler_rt.f16.Abi { | ||
| 302 | return compiler_rt.f16.toAbi(f16_floatFromInt_u32(a)); | ||
| 303 | } | ||
| 304 | pub fn f16_floatFromInt_u32(a: u32) f16 { | ||
| 305 | return floatFromInt(f16, a); | ||
| 306 | } | ||
| 307 | |||
| 308 | fn __floatundihf(a: u64) callconv(.c) compiler_rt.f16.Abi { | ||
| 309 | return compiler_rt.f16.toAbi(f16_floatFromInt_u64(a)); | ||
| 310 | } | ||
| 311 | pub fn f16_floatFromInt_u64(a: u64) f16 { | ||
| 312 | return floatFromInt(f16, a); | ||
| 313 | } | ||
| 314 | |||
| 315 | fn __floatuntihf(a: u128) callconv(.c) compiler_rt.f16.Abi { | ||
| 316 | return compiler_rt.f16.toAbi(f16_floatFromInt_u128(a)); | ||
| 317 | } | ||
| 318 | pub fn f16_floatFromInt_u128(a: u128) f16 { | ||
| 319 | return floatFromInt(f16, a); | ||
| 320 | } | ||
| 321 | |||
| 322 | fn __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 | } | ||
| 326 | pub fn f16_floatFromInt_unsigned(a: []const u8) f16 { | ||
| 327 | return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a))); | ||
| 328 | } | ||
| 329 | |||
| 330 | fn __floatunsisf(a: u32) callconv(.c) compiler_rt.f32.Abi { | ||
| 331 | return compiler_rt.f32.toAbi(f32_floatFromInt_u32(a)); | ||
| 332 | } | ||
| 333 | fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 334 | return f32_floatFromInt_u32(a); | ||
| 335 | } | ||
| 336 | pub fn f32_floatFromInt_u32(a: u32) f32 { | ||
| 337 | return floatFromInt(f32, a); | ||
| 338 | } | ||
| 339 | |||
| 340 | fn __floatundisf(a: u64) callconv(.c) compiler_rt.f32.Abi { | ||
| 341 | return compiler_rt.f32.toAbi(f32_floatFromInt_u64(a)); | ||
| 342 | } | ||
| 343 | fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 344 | return f32_floatFromInt_u64(a); | ||
| 345 | } | ||
| 346 | pub fn f32_floatFromInt_u64(a: u64) f32 { | ||
| 347 | return floatFromInt(f32, a); | ||
| 348 | } | ||
| 349 | |||
| 350 | fn __floatuntisf(a: u128) callconv(.c) compiler_rt.f32.Abi { | ||
| 351 | return compiler_rt.f32.toAbi(f32_floatFromInt_u128(a)); | ||
| 352 | } | ||
| 353 | pub fn f32_floatFromInt_u128(a: u128) f32 { | ||
| 354 | return floatFromInt(f32, a); | ||
| 355 | } | ||
| 356 | |||
| 357 | fn __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 | } | ||
| 361 | pub fn f32_floatFromInt_unsigned(a: []const u8) f32 { | ||
| 362 | return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a))); | ||
| 363 | } | ||
| 364 | |||
| 365 | fn __floatunsidf(a: u32) callconv(.c) compiler_rt.f64.Abi { | ||
| 366 | return compiler_rt.f64.toAbi(f64_floatFromInt_u32(a)); | ||
| 367 | } | ||
| 368 | fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 369 | return f64_floatFromInt_u32(a); | ||
| 370 | } | ||
| 371 | pub fn f64_floatFromInt_u32(a: u32) f64 { | ||
| 372 | return floatFromInt(f64, a); | ||
| 373 | } | ||
| 374 | |||
| 375 | fn __floatundidf(a: u64) callconv(.c) compiler_rt.f64.Abi { | ||
| 376 | return compiler_rt.f64.toAbi(f64_floatFromInt_u64(a)); | ||
| 377 | } | ||
| 378 | fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 379 | return f64_floatFromInt_u64(a); | ||
| 380 | } | ||
| 381 | pub fn f64_floatFromInt_u64(a: u64) f64 { | ||
| 382 | return floatFromInt(f64, a); | ||
| 383 | } | ||
| 384 | |||
| 385 | fn __floatuntidf(a: u128) callconv(.c) compiler_rt.f64.Abi { | ||
| 386 | return compiler_rt.f64.toAbi(f64_floatFromInt_u128(a)); | ||
| 387 | } | ||
| 388 | pub fn f64_floatFromInt_u128(a: u128) f64 { | ||
| 389 | return floatFromInt(f64, a); | ||
| 390 | } | ||
| 391 | |||
| 392 | fn __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 | } | ||
| 396 | pub fn f64_floatFromInt_unsigned(a: []const u8) f64 { | ||
| 397 | return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a))); | ||
| 398 | } | ||
| 399 | |||
| 400 | fn __floatunsixf(a: u32) callconv(.c) compiler_rt.f80.Abi { | ||
| 401 | return compiler_rt.f80.toAbi(f80_floatFromInt_u32(a)); | ||
| 402 | } | ||
| 403 | pub fn f80_floatFromInt_u32(a: u32) f80 { | ||
| 404 | return floatFromInt(f80, a); | ||
| 405 | } | ||
| 406 | |||
| 407 | fn __floatundixf(a: u64) callconv(.c) compiler_rt.f80.Abi { | ||
| 408 | return compiler_rt.f80.toAbi(f80_floatFromInt_u64(a)); | ||
| 409 | } | ||
| 410 | pub fn f80_floatFromInt_u64(a: u64) f80 { | ||
| 411 | return floatFromInt(f80, a); | ||
| 412 | } | ||
| 413 | |||
| 414 | fn __floatuntixf(a: u128) callconv(.c) compiler_rt.f80.Abi { | ||
| 415 | return compiler_rt.f80.toAbi(f80_floatFromInt_u128(a)); | ||
| 416 | } | ||
| 417 | pub fn f80_floatFromInt_u128(a: u128) f80 { | ||
| 418 | return floatFromInt(f80, a); | ||
| 419 | } | ||
| 420 | |||
| 421 | fn __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 | } | ||
| 425 | pub fn f80_floatFromInt_unsigned(a: []const u8) f80 { | ||
| 426 | return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a))); | ||
| 427 | } | ||
| 428 | |||
| 429 | fn __floatunsitf(a: u32) callconv(.c) compiler_rt.f128.Abi { | ||
| 430 | return compiler_rt.f128.toAbi(f128_floatFromInt_u32(a)); | ||
| 431 | } | ||
| 432 | fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void { | ||
| 433 | c.* = f128_floatFromInt_u32(a); | ||
| 434 | } | ||
| 435 | pub fn f128_floatFromInt_u32(a: u32) f128 { | ||
| 436 | return floatFromInt(f128, a); | ||
| 437 | } | ||
| 438 | |||
| 439 | fn __floatunditf(a: u64) callconv(.c) compiler_rt.f128.Abi { | ||
| 440 | return compiler_rt.f128.toAbi(f128_floatFromInt_u64(a)); | ||
| 441 | } | ||
| 442 | fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void { | ||
| 443 | c.* = f128_floatFromInt_u64(a); | ||
| 444 | } | ||
| 445 | pub fn f128_floatFromInt_u64(a: u64) f128 { | ||
| 446 | return floatFromInt(f128, a); | ||
| 447 | } | ||
| 448 | |||
| 449 | fn __floatuntitf(a: u128) callconv(.c) compiler_rt.f128.Abi { | ||
| 450 | return compiler_rt.f128.toAbi(f128_floatFromInt_u128(a)); | ||
| 451 | } | ||
| 452 | fn __floatuntitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi { | ||
| 453 | return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast(a))); | ||
| 454 | } | ||
| 455 | fn __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 | } | ||
| 460 | pub fn f128_floatFromInt_u128(a: u128) f128 { | ||
| 461 | return floatFromInt(f128, a); | ||
| 462 | } | ||
| 463 | |||
| 464 | fn __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 | } | ||
| 468 | pub fn f128_floatFromInt_unsigned(a: []const u8) f128 { | ||
| 469 | return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a))); | ||
| 470 | } | ||
| 471 | |||
| 472 | inline fn floatFromInt(comptime T: type, x: anytype) T { | ||
| 5 | if (x == 0) return 0; | 473 | if (x == 0) return 0; |
| 6 | 474 | ||
| 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 | } |
| 55 | 523 | ||
| 56 | const endian = @import("builtin").cpu.arch.endian(); | 524 | const endian = builtin.cpu.arch.endian(); |
| 57 | inline fn limb(limbs: []const u32, index: usize) u32 { | 525 | inline 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 | } |
| 63 | 531 | ||
| 64 | pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin.Signedness, x: []const u32) T { | 532 | inline 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"); |
| 2 | const testing = std.testing; | 2 | const testing = std.testing; |
| 3 | const math = std.math; | 3 | const math = std.math; |
| 4 | 4 | ||
| 5 | const __floatunsihf = @import("floatunsihf.zig").__floatunsihf; | 5 | const impl = @import("float_from_int.zig"); |
| 6 | 6 | ||
| 7 | // Conversion to f32 | 7 | const f16_floatFromInt_i32 = impl.f16_floatFromInt_i32; |
| 8 | const __floatsisf = @import("floatsisf.zig").__floatsisf; | 8 | const f16_floatFromInt_u32 = impl.f16_floatFromInt_u32; |
| 9 | const __floatunsisf = @import("floatunsisf.zig").__floatunsisf; | 9 | const f16_floatFromInt_i64 = impl.f16_floatFromInt_i64; |
| 10 | const __floatdisf = @import("floatdisf.zig").__floatdisf; | 10 | const f16_floatFromInt_u64 = impl.f16_floatFromInt_u64; |
| 11 | const __floatundisf = @import("floatundisf.zig").__floatundisf; | 11 | const f16_floatFromInt_i128 = impl.f16_floatFromInt_i128; |
| 12 | const __floattisf = @import("floattisf.zig").__floattisf; | 12 | const f16_floatFromInt_u128 = impl.f16_floatFromInt_u128; |
| 13 | const __floatuntisf = @import("floatuntisf.zig").__floatuntisf; | 13 | const f16_floatFromInt_signed = impl.f16_floatFromInt_signed; |
| 14 | const __floateisf = @import("floateisf.zig").__floateisf; | 14 | const f16_floatFromInt_unsigned = impl.f16_floatFromInt_unsigned; |
| 15 | const __floatuneisf = @import("floatuneisf.zig").__floatuneisf; | 15 | |
| 16 | 16 | const f32_floatFromInt_i32 = impl.f32_floatFromInt_i32; | |
| 17 | // Conversion to f64 | 17 | const f32_floatFromInt_u32 = impl.f32_floatFromInt_u32; |
| 18 | const __floatsidf = @import("floatsidf.zig").__floatsidf; | 18 | const f32_floatFromInt_i64 = impl.f32_floatFromInt_i64; |
| 19 | const __floatunsidf = @import("floatunsidf.zig").__floatunsidf; | 19 | const f32_floatFromInt_u64 = impl.f32_floatFromInt_u64; |
| 20 | const __floatdidf = @import("floatdidf.zig").__floatdidf; | 20 | const f32_floatFromInt_i128 = impl.f32_floatFromInt_i128; |
| 21 | const __floatundidf = @import("floatundidf.zig").__floatundidf; | 21 | const f32_floatFromInt_u128 = impl.f32_floatFromInt_u128; |
| 22 | const __floattidf = @import("floattidf.zig").__floattidf; | 22 | const f32_floatFromInt_signed = impl.f32_floatFromInt_signed; |
| 23 | const __floatuntidf = @import("floatuntidf.zig").__floatuntidf; | 23 | const f32_floatFromInt_unsigned = impl.f32_floatFromInt_unsigned; |
| 24 | 24 | ||
| 25 | // Conversion to f128 | 25 | const f64_floatFromInt_i32 = impl.f64_floatFromInt_i32; |
| 26 | const __floatsitf = @import("floatsitf.zig").__floatsitf; | 26 | const f64_floatFromInt_u32 = impl.f64_floatFromInt_u32; |
| 27 | const __floatunsitf = @import("floatunsitf.zig").__floatunsitf; | 27 | const f64_floatFromInt_i64 = impl.f64_floatFromInt_i64; |
| 28 | const __floatditf = @import("floatditf.zig").__floatditf; | 28 | const f64_floatFromInt_u64 = impl.f64_floatFromInt_u64; |
| 29 | const __floatunditf = @import("floatunditf.zig").__floatunditf; | 29 | const f64_floatFromInt_i128 = impl.f64_floatFromInt_i128; |
| 30 | const __floattitf = @import("floattitf.zig").__floattitf; | 30 | const f64_floatFromInt_u128 = impl.f64_floatFromInt_u128; |
| 31 | const __floatuntitf = @import("floatuntitf.zig").__floatuntitf; | 31 | const f64_floatFromInt_signed = impl.f64_floatFromInt_signed; |
| 32 | 32 | const f64_floatFromInt_unsigned = impl.f64_floatFromInt_unsigned; | |
| 33 | fn test__floatsisf(a: i32, expected: u32) !void { | 33 | |
| 34 | const r = __floatsisf(a); | 34 | const f80_floatFromInt_i32 = impl.f80_floatFromInt_i32; |
| 35 | const f80_floatFromInt_u32 = impl.f80_floatFromInt_u32; | ||
| 36 | const f80_floatFromInt_i64 = impl.f80_floatFromInt_i64; | ||
| 37 | const f80_floatFromInt_u64 = impl.f80_floatFromInt_u64; | ||
| 38 | const f80_floatFromInt_i128 = impl.f80_floatFromInt_i128; | ||
| 39 | const f80_floatFromInt_u128 = impl.f80_floatFromInt_u128; | ||
| 40 | const f80_floatFromInt_signed = impl.f80_floatFromInt_signed; | ||
| 41 | const f80_floatFromInt_unsigned = impl.f80_floatFromInt_unsigned; | ||
| 42 | |||
| 43 | const f128_floatFromInt_i32 = impl.f128_floatFromInt_i32; | ||
| 44 | const f128_floatFromInt_u32 = impl.f128_floatFromInt_u32; | ||
| 45 | const f128_floatFromInt_i64 = impl.f128_floatFromInt_i64; | ||
| 46 | const f128_floatFromInt_u64 = impl.f128_floatFromInt_u64; | ||
| 47 | const f128_floatFromInt_i128 = impl.f128_floatFromInt_i128; | ||
| 48 | const f128_floatFromInt_u128 = impl.f128_floatFromInt_u128; | ||
| 49 | const f128_floatFromInt_signed = impl.f128_floatFromInt_signed; | ||
| 50 | const f128_floatFromInt_unsigned = impl.f128_floatFromInt_unsigned; | ||
| 51 | |||
| 52 | fn 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 | } |
| 37 | 56 | ||
| 38 | fn test_one_floatunsisf(a: u32, expected: u32) !void { | 57 | fn 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 | } |
| 42 | 61 | ||
| 43 | test "floatsisf" { | 62 | test 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 | } |
| 50 | 71 | ||
| 51 | test "floatunsisf" { | 72 | test f32_floatFromInt_u32 { |
| 52 | // Test the produced bit pattern | 73 | // 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 | |||
| 90 | fn test_f32_floatFromInt_i64(a: i64, expected: f32) !void { | ||
| 91 | const x = f32_floatFromInt_i64(a); | ||
| 92 | try testing.expect(x == expected); | ||
| 58 | } | 93 | } |
| 59 | 94 | ||
| 60 | fn test__floatdisf(a: i64, expected: f32) !void { | 95 | fn 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 | } |
| 64 | 99 | ||
| 65 | fn test__floatundisf(a: u64, expected: f32) !void { | 100 | test 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); |
| 68 | 103 | try test_f32_floatFromInt_i64(2, 2.0); | |
| 69 | test "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); | 125 | test 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); |
| 93 | 128 | try test_f32_floatFromInt_u64(2, 2.0); | |
| 94 | test "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); | 150 | fn 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 | |||
| 119 | fn 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 | } |
| 123 | 154 | ||
| 124 | fn test__floatuntisf(a: u128, expected: f32) !void { | 155 | fn 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 | } |
| 128 | 159 | ||
| 129 | test "floattisf" { | 160 | test f32_floatFromInt_i128 { |
| 130 | try test__floattisf(0, 0.0); | 161 | try test_f32_floatFromInt_i128(0, 0.0); |
| 131 | 162 | ||
| 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); |
| 136 | 167 | ||
| 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); |
| 139 | 170 | ||
| 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); |
| 142 | 173 | ||
| 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); |
| 145 | 176 | ||
| 146 | try test__floattisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 177 | try test_f32_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 147 | 178 | ||
| 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); |
| 153 | 184 | ||
| 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); |
| 159 | 190 | ||
| 160 | try test__floattisf(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114); | 191 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114); |
| 161 | 192 | ||
| 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); |
| 167 | 198 | ||
| 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 | } |
| 174 | 205 | ||
| 175 | test "floatuntisf" { | 206 | test f32_floatFromInt_u128 { |
| 176 | try test__floatuntisf(0, 0.0); | 207 | try test_f32_floatFromInt_u128(0, 0.0); |
| 177 | 208 | ||
| 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); |
| 181 | 212 | ||
| 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); |
| 184 | 215 | ||
| 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); |
| 188 | 219 | ||
| 189 | try test__floatuntisf(make_uti(0x8000000000000000, 0), 0x1.000000p+127); | 220 | try test_f32_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127); |
| 190 | 221 | ||
| 191 | try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 222 | try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 192 | 223 | ||
| 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); |
| 195 | 226 | ||
| 196 | try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | 227 | try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); |
| 197 | 228 | ||
| 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); |
| 201 | 232 | ||
| 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); |
| 204 | 235 | ||
| 205 | try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 236 | try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 206 | 237 | ||
| 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); |
| 212 | 243 | ||
| 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); |
| 218 | 249 | ||
| 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); |
| 231 | 262 | ||
| 232 | // Test overflow to infinity | 263 | // 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 | } |
| 235 | 266 | ||
| 236 | fn test_floateisf(expected: u32, comptime T: type, a: T) !void { | 267 | fn 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 | } |
| 244 | 275 | ||
| 245 | test "floateisf" { | 276 | test 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 | } |
| 267 | 298 | ||
| 268 | test "floatuneisf" { | 299 | test 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 | } |
| 281 | 312 | ||
| 282 | fn test_one_floatsidf(a: i32, expected: u64) !void { | 313 | fn 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 | } |
| 286 | 317 | ||
| 287 | fn test_one_floatunsidf(a: u32, expected: u64) !void { | 318 | fn 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 | } |
| 291 | 322 | ||
| 292 | test "floatsidf" { | 323 | test 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 | } |
| 299 | 330 | ||
| 300 | test "floatunsidf" { | 331 | test 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 | } |
| 307 | 338 | ||
| 308 | fn test__floatdidf(a: i64, expected: f64) !void { | 339 | fn 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 | } |
| 312 | 343 | ||
| 313 | fn test__floatundidf(a: u64, expected: f64) !void { | 344 | fn 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 | } |
| 317 | 348 | ||
| 318 | test "floatdidf" { | 349 | test 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); // 0x8000000000000001 | 366 | 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 | } |
| 363 | 394 | ||
| 364 | test "floatundidf" { | 395 | test 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 | } |
| 406 | 437 | ||
| 407 | fn test__floattidf(a: i128, expected: f64) !void { | 438 | fn 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 | } |
| 411 | 442 | ||
| 412 | fn test__floatuntidf(a: u128, expected: f64) !void { | 443 | fn 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 | } |
| 416 | 447 | ||
| 417 | test "floattidf" { | 448 | test f64_floatFromInt_i128 { |
| 418 | try test__floattidf(0, 0.0); | 449 | try test_f64_floatFromInt_i128(0, 0.0); |
| 419 | 450 | ||
| 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); |
| 426 | 457 | ||
| 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); |
| 431 | 462 | ||
| 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); |
| 436 | 467 | ||
| 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); |
| 439 | 470 | ||
| 440 | try test__floattidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 471 | try test_f64_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 441 | 472 | ||
| 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); |
| 447 | 478 | ||
| 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); |
| 453 | 484 | ||
| 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); |
| 469 | 500 | ||
| 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 | } |
| 486 | 517 | ||
| 487 | test "floatuntidf" { | 518 | test f64_floatFromInt_u128 { |
| 488 | try test__floatuntidf(0, 0.0); | 519 | try test_f64_floatFromInt_u128(0, 0.0); |
| 489 | 520 | ||
| 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); |
| 493 | 524 | ||
| 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); |
| 498 | 529 | ||
| 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); |
| 503 | 534 | ||
| 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); |
| 506 | 537 | ||
| 507 | try test__floatuntidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 538 | try test_f64_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 508 | 539 | ||
| 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); |
| 514 | 545 | ||
| 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); |
| 520 | 551 | ||
| 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); |
| 536 | 567 | ||
| 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 | } |
| 553 | 584 | ||
| 554 | fn test__floatsitf(a: i32, expected: u128) !void { | 585 | fn 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 | } |
| 558 | 589 | ||
| 559 | test "floatsitf" { | 590 | fn 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 | |||
| 568 | fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void { | ||
| 569 | const x = __floatunsitf(a); | ||
| 570 | 592 | ||
| 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 | } | ||
| 584 | 608 | ||
| 585 | @panic("__floatunsitf test failure"); | 609 | test 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 | } |
| 587 | 617 | ||
| 588 | test "floatunsitf" { | 618 | test 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 | } |
| 594 | 624 | ||
| 595 | fn test__floatditf(a: i64, expected: f128) !void { | 625 | fn 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 | } |
| 599 | 629 | ||
| 600 | fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void { | 630 | fn 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); |
| 602 | 632 | ||
| 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 | } |
| 616 | 646 | return error.TestFailure; | |
| 617 | @panic("__floatunditf test failure"); | 647 | } |
| 618 | } | 648 | |
| 619 | 649 | test f128_floatFromInt_i64 { | |
| 620 | test "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 | |
| 631 | 661 | test f128_floatFromInt_u64 { | |
| 632 | test "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 | |
| 642 | 672 | fn test_f128_floatFromInt_i128(a: i128, expected: f128) !void { | |
| 643 | fn 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 | } |
| 647 | 676 | ||
| 648 | fn test__floatuntitf(a: u128, expected: f128) !void { | 677 | fn 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 | } |
| 652 | 681 | ||
| 653 | test "floattitf" { | 682 | test f128_floatFromInt_i128 { |
| 654 | try test__floattitf(0, 0.0); | 683 | try test_f128_floatFromInt_i128(0, 0.0); |
| 655 | 684 | ||
| 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); |
| 662 | 691 | ||
| 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); |
| 667 | 696 | ||
| 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); |
| 672 | 701 | ||
| 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); |
| 675 | 704 | ||
| 676 | try test__floattitf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 705 | try test_f128_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 677 | 706 | ||
| 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); |
| 683 | 712 | ||
| 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); |
| 689 | 718 | ||
| 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); |
| 705 | 734 | ||
| 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); |
| 721 | 750 | ||
| 722 | try test__floattitf(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); | 751 | try test_f128_floatFromInt_i128(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); |
| 723 | 752 | ||
| 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 | } |
| 734 | 763 | ||
| 735 | test "floatuntitf" { | 764 | test f128_floatFromInt_u128 { |
| 736 | try test__floatuntitf(0, 0.0); | 765 | try test_f128_floatFromInt_u128(0, 0.0); |
| 737 | 766 | ||
| 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); |
| 741 | 770 | ||
| 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); |
| 749 | 778 | ||
| 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); |
| 754 | 783 | ||
| 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); |
| 757 | 786 | ||
| 758 | try test__floatuntitf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 787 | try test_f128_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 759 | 788 | ||
| 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); |
| 765 | 794 | ||
| 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); |
| 771 | 800 | ||
| 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); |
| 787 | 816 | ||
| 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); |
| 803 | 832 | ||
| 804 | try test__floatuntitf(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); | 833 | try test_f128_floatFromInt_u128(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); |
| 805 | 834 | ||
| 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); |
| 808 | 837 | ||
| 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 | } |
| 819 | 848 | ||
| 820 | fn make_ti(high: u64, low: u64) i128 { | 849 | fn 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 | } |
| 840 | 869 | ||
| 841 | test "conversion to f16" { | 870 | test 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 | } |
| 847 | 876 | ||
| 848 | test "conversion to f32" { | 877 | test 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 - Exact | 882 | |
| 854 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even | 883 | test f80_floatFromInt_u64 { |
| 855 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact | 884 | 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 even | 885 | } |
| 857 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact | 886 | |
| 858 | } | 887 | test f80_floatFromInt_i128 { |
| 859 | 888 | try testing.expect(f80_floatFromInt_i128(-12) == -12); | |
| 860 | test "conversion to f80" { | 889 | } |
| 861 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | 890 | |
| 862 | 891 | test 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)); |
| 866 | 895 | 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); // Exact | 900 | 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 down | 901 | 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 - Exact | 902 | 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 up | 903 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 3) == math.maxInt(u65) + 1); // Tie - Rounds down |
| 875 | 904 | 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 up | 905 | 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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 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 | |||
| 17 | pub fn __floatdidf(a: i64) callconv(.c) f64 { | ||
| 18 | return floatFromInt(f64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__floatdihf, "__floatdihf"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __floatdihf(a: i64) callconv(.c) f16 { | ||
| 9 | return floatFromInt(f16, a); | ||
| 10 | } | ||
lib/compiler_rt/floatdisf.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __floatdisf(a: i64) callconv(.c) f32 { | ||
| 17 | return floatFromInt(f32, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __floatditf(a: i64) callconv(.c) f128 { | ||
| 17 | return floatFromInt(f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__floatdixf, "__floatdixf"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __floatdixf(a: i64) callconv(.c) f80 { | ||
| 9 | return floatFromInt(f80, a); | ||
| 10 | } | ||
lib/compiler_rt/floateidf.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__floateidf, "__floateidf"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub 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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floateihf, "__floateihf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floateisf, "__floateisf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floateitf, "__floateitf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__floateixf, "__floateixf"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_i2d, "__aeabi_i2d"); | ||
| 8 | } else { | ||
| 9 | symbol(&__floatsidf, "__floatsidf"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __floatsidf(a: i32) callconv(.c) f64 { | ||
| 14 | return floatFromInt(f64, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatsihf, "__floatsihf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatsihf(a: i32) callconv(.c) f16 { | ||
| 10 | return floatFromInt(f16, a); | ||
| 11 | } | ||
lib/compiler_rt/floatsisf.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_i2f, "__aeabi_i2f"); | ||
| 8 | } else { | ||
| 9 | symbol(&__floatsisf, "__floatsisf"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __floatsisf(a: i32) callconv(.c) f32 { | ||
| 14 | return floatFromInt(f32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __floatsitf(a: i32) callconv(.c) f128 { | ||
| 17 | return floatFromInt(f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatsixf, "__floatsixf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatsixf(a: i32) callconv(.c) f80 { | ||
| 10 | return floatFromInt(f80, a); | ||
| 11 | } | ||
lib/compiler_rt/floattidf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floattidf, "__floattidf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __floattidf(a: i128) callconv(.c) f64 { | ||
| 10 | return floatFromInt(f64, a); | ||
| 11 | } | ||
lib/compiler_rt/floattihf.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__floattihf, "__floattihf"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __floattihf(a: i128) callconv(.c) f16 { | ||
| 11 | return floatFromInt(f16, a); | ||
| 12 | } | ||
lib/compiler_rt/floattisf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floattisf, "__floattisf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __floattisf(a: i128) callconv(.c) f32 { | ||
| 10 | return floatFromInt(f32, a); | ||
| 11 | } | ||
lib/compiler_rt/floattitf.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) | ||
| 7 | symbol(&__floattitf, "__floattikf"); | ||
| 8 | symbol(&__floattitf, "__floattitf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floattitf(a: i128) callconv(.c) f128 { | ||
| 12 | return floatFromInt(f128, a); | ||
| 13 | } | ||
lib/compiler_rt/floattixf.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__floattixf, "__floattixf"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __floattixf(a: i128) callconv(.c) f80 { | ||
| 11 | return floatFromInt(f80, a); | ||
| 12 | } | ||
lib/compiler_rt/floatundidf.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __floatundidf(a: u64) callconv(.c) f64 { | ||
| 17 | return floatFromInt(f64, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatundihf, "__floatundihf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatundihf(a: u64) callconv(.c) f16 { | ||
| 10 | return floatFromInt(f16, a); | ||
| 11 | } | ||
lib/compiler_rt/floatundisf.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 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 | |||
| 17 | pub fn __floatundisf(a: u64) callconv(.c) f32 { | ||
| 18 | return floatFromInt(f32, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __floatunditf(a: u64) callconv(.c) f128 { | ||
| 17 | return floatFromInt(f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatundixf, "__floatundixf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatundixf(a: u64) callconv(.c) f80 { | ||
| 10 | return floatFromInt(f80, a); | ||
| 11 | } | ||
lib/compiler_rt/floatuneidf.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floatuneidf, "__floatuneidf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floatuneihf, "__floatuneihf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floatuneisf, "__floatuneisf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__floatuneitf, "__floatuneitf"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub 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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floatuneixf, "__floatuneixf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_ui2d, "__aeabi_ui2d"); | ||
| 8 | } else { | ||
| 9 | symbol(&__floatunsidf, "__floatunsidf"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __floatunsidf(a: u32) callconv(.c) f64 { | ||
| 14 | return floatFromInt(f64, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__floatunsihf, "__floatunsihf"); | ||
| 6 | } | ||
| 7 | |||
| 8 | pub fn __floatunsihf(a: u32) callconv(.c) f16 { | ||
| 9 | return floatFromInt(f16, a); | ||
| 10 | } | ||
lib/compiler_rt/floatunsisf.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_ui2f, "__aeabi_ui2f"); | ||
| 8 | } else { | ||
| 9 | symbol(&__floatunsisf, "__floatunsisf"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __floatunsisf(a: u32) callconv(.c) f32 { | ||
| 14 | return floatFromInt(f32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __floatunsitf(a: u32) callconv(.c) f128 { | ||
| 17 | return floatFromInt(f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatunsixf, "__floatunsixf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatunsixf(a: u32) callconv(.c) f80 { | ||
| 10 | return floatFromInt(f80, a); | ||
| 11 | } | ||
lib/compiler_rt/floatuntidf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatuntidf, "__floatuntidf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __floatuntidf(a: u128) callconv(.c) f64 { | ||
| 10 | return floatFromInt(f64, a); | ||
| 11 | } | ||
lib/compiler_rt/floatuntihf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatuntihf, "__floatuntihf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __floatuntihf(a: u128) callconv(.c) f16 { | ||
| 10 | return floatFromInt(f16, a); | ||
| 11 | } | ||
lib/compiler_rt/floatuntisf.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__floatuntisf, "__floatuntisf"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __floatuntisf(a: u128) callconv(.c) f32 { | ||
| 11 | return floatFromInt(f32, a); | ||
| 12 | } | ||
lib/compiler_rt/floatuntitf.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) | ||
| 7 | symbol(&__floatuntitf, "__floatuntikf"); | ||
| 8 | symbol(&__floatuntitf, "__floatuntitf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floatuntitf(a: u128) callconv(.c) f128 { | ||
| 12 | return floatFromInt(f128, a); | ||
| 13 | } | ||
lib/compiler_rt/floatuntixf.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__floatuntixf, "__floatuntixf"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub 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; |
| 15 | const expect = std.testing.expect; | 15 | const expect = std.testing.expect; |
| 16 | 16 | ||
| 17 | const compiler_rt = @import("../compiler_rt.zig"); | 17 | const compiler_rt = @import("../compiler_rt.zig"); |
| 18 | const symbol = @import("../compiler_rt.zig").symbol; | 18 | const symbol = compiler_rt.symbol; |
| 19 | 19 | ||
| 20 | comptime { | 20 | comptime { |
| 21 | // floor | 21 | // 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"); |
| 31 | 28 | ||
| 32 | // ceil | 29 | // 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 | } |
| 43 | 37 | ||
| 44 | pub fn __floorh(x: f16) callconv(.c) f16 { | 38 | fn __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 | } | ||
| 41 | pub fn floor_f16(x: f16) f16 { | ||
| 45 | return impl(f16, .floor, x); | 42 | return impl(f16, .floor, x); |
| 46 | } | 43 | } |
| 47 | 44 | ||
| 48 | pub fn floorf(x: f32) callconv(.c) f32 { | 45 | fn 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 | } | ||
| 48 | pub fn floor_f32(x: f32) f32 { | ||
| 49 | return impl(f32, .floor, x); | 49 | return impl(f32, .floor, x); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | pub fn floor(x: f64) callconv(.c) f64 { | 52 | fn 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 | } | ||
| 55 | pub fn floor_f64(x: f64) f64 { | ||
| 53 | return impl(f64, .floor, x); | 56 | return impl(f64, .floor, x); |
| 54 | } | 57 | } |
| 55 | 58 | ||
| 56 | pub fn __floorx(x: f80) callconv(.c) f80 { | 59 | fn __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 | } | ||
| 62 | pub fn floor_f80(x: f80) f80 { | ||
| 57 | return impl(f80, .floor, x); | 63 | return impl(f80, .floor, x); |
| 58 | } | 64 | } |
| 59 | 65 | ||
| 60 | pub fn floorq(x: f128) callconv(.c) f128 { | 66 | fn 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 | } | ||
| 69 | pub fn floor_f128(x: f128) f128 { | ||
| 61 | return impl(f128, .floor, x); | 70 | return impl(f128, .floor, x); |
| 62 | } | 71 | } |
| 63 | 72 | ||
| 64 | pub fn floorl(x: c_longdouble) callconv(.c) c_longdouble { | 73 | pub 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 | } |
| 67 | 81 | ||
| 68 | pub fn __ceilh(x: f16) callconv(.c) f16 { | 82 | fn __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 | } | ||
| 85 | pub fn ceil_f16(x: f16) f16 { | ||
| 69 | return impl(f16, .ceil, x); | 86 | return impl(f16, .ceil, x); |
| 70 | } | 87 | } |
| 71 | 88 | ||
| 72 | pub fn ceilf(x: f32) callconv(.c) f32 { | 89 | fn 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 | } | ||
| 92 | pub fn ceil_f32(x: f32) f32 { | ||
| 73 | return impl(f32, .ceil, x); | 93 | return impl(f32, .ceil, x); |
| 74 | } | 94 | } |
| 75 | 95 | ||
| 76 | pub fn ceil(x: f64) callconv(.c) f64 { | 96 | fn 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 | } | ||
| 99 | pub fn ceil_f64(x: f64) f64 { | ||
| 77 | return impl(f64, .ceil, x); | 100 | return impl(f64, .ceil, x); |
| 78 | } | 101 | } |
| 79 | 102 | ||
| 80 | pub fn __ceilx(x: f80) callconv(.c) f80 { | 103 | fn __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 | } | ||
| 106 | pub fn ceil_f80(x: f80) f80 { | ||
| 81 | return impl(f80, .ceil, x); | 107 | return impl(f80, .ceil, x); |
| 82 | } | 108 | } |
| 83 | 109 | ||
| 84 | pub fn ceilq(x: f128) callconv(.c) f128 { | 110 | fn 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 | } | ||
| 113 | pub fn ceil_f128(x: f128) f128 { | ||
| 85 | return impl(f128, .ceil, x); | 114 | return impl(f128, .ceil, x); |
| 86 | } | 115 | } |
| 87 | 116 | ||
| 88 | pub fn ceill(x: c_longdouble) callconv(.c) c_longdouble { | 117 | pub 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 | } |
| 91 | 125 | ||
| 92 | inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { | 126 | 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,142 +178,122 @@ inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { |
| 144 | } | 178 | } |
| 145 | } | 179 | } |
| 146 | 180 | ||
| 147 | test "floor16" { | 181 | test 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))); |
| 152 | 186 | try expect(math.isPositiveZero(floor_f16(0.0))); | |
| 153 | test "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 | } |
| 158 | 192 | ||
| 159 | test "floor64" { | 193 | test 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))); |
| 164 | 198 | try expect(math.isPositiveZero(floor_f32(0.0))); | |
| 165 | test "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 | } |
| 170 | 204 | ||
| 171 | test "floor128" { | 205 | test 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))); |
| 176 | 210 | try expect(math.isPositiveZero(floor_f64(0.0))); | |
| 177 | test "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 | } | 217 | test floor_f80 { |
| 184 | 218 | try expect(floor_f80(1.3) == 1.0); | |
| 185 | test "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)))); |
| 192 | 226 | try expect(math.isNan(floor_f80(math.nan(f80)))); | |
| 193 | test "floor64.special" { | 227 | } |
| 194 | try expect(floor(0.0) == 0.0); | 228 | |
| 195 | try expect(floor(-0.0) == -0.0); | 229 | test 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))); |
| 200 | 234 | try expect(math.isPositiveZero(floor_f128(0.0))); | |
| 201 | test "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 | } | 241 | test ceil_f16 { |
| 208 | 242 | try expect(ceil_f16(1.3) == 2.0); | |
| 209 | test "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)))); |
| 216 | 250 | try expect(math.isNan(ceil_f16(math.nan(f16)))); | |
| 217 | test "ceil16" { | 251 | } |
| 218 | try expect(__ceilh(1.3) == 2.0); | 252 | |
| 219 | try expect(__ceilh(-1.3) == -1.0); | 253 | test 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); |
| 222 | 256 | try expect(ceil_f32(0.2) == 1.0); | |
| 223 | test "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)))); |
| 228 | 262 | try expect(math.isNan(ceil_f32(math.nan(f32)))); | |
| 229 | test "ceil64" { | 263 | } |
| 230 | try expect(ceil(1.3) == 2.0); | 264 | |
| 231 | try expect(ceil(-1.3) == -1.0); | 265 | test 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); |
| 234 | 268 | try expect(ceil_f64(0.2) == 1.0); | |
| 235 | test "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)))); |
| 240 | 274 | try expect(math.isNan(ceil_f64(math.nan(f64)))); | |
| 241 | test "ceil128" { | 275 | } |
| 242 | try expect(ceilq(1.3) == 2.0); | 276 | |
| 243 | try expect(ceilq(-1.3) == -1.0); | 277 | test 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); |
| 246 | 280 | try expect(ceil_f80(0.2) == 1.0); | |
| 247 | test "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 | } |
| 254 | 288 | ||
| 255 | test "ceil32.special" { | 289 | test 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))); |
| 262 | 296 | try expect(math.isPositiveInf(ceil_f128(math.inf(f128)))); | |
| 263 | test "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 | |||
| 271 | test "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 | |||
| 279 | test "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 | } |
| 25 | 22 | ||
| 26 | pub fn __fmah(x: f16, y: f16, z: f16) callconv(.c) f16 { | 23 | fn __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 | } | ||
| 26 | pub fn fma_f16(x: f16, y: f16, z: f16) f16 { | ||
| 27 | // TODO: more efficient implementation | 27 | // TODO: more efficient implementation |
| 28 | return @floatCast(fmaf(x, y, z)); | 28 | return @floatCast(fma_f32(x, y, z)); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 { | 31 | fn 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 | } | ||
| 34 | pub 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 | } |
| 44 | 47 | ||
| 48 | fn 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. |
| 46 | pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 { | 52 | pub 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 | } |
| 92 | 98 | ||
| 93 | pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 { | 99 | fn __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 | } | ||
| 102 | pub fn fma_f80(a: f80, b: f80, c: f80) f80 { | ||
| 94 | // TODO: more efficient implementation | 103 | // TODO: more efficient implementation |
| 95 | return @floatCast(fmaq(a, b, c)); | 104 | return @floatCast(fma_f128(a, b, c)); |
| 96 | } | 105 | } |
| 97 | 106 | ||
| 107 | fn 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 the | 112 | /// 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 the | 115 | /// 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). |
| 105 | pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 { | 117 | pub 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 { |
| 151 | 163 | ||
| 152 | pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble { | 164 | pub 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 | } |
| 160 | 172 | ||
| ... | @@ -316,35 +328,35 @@ fn dd_mul128(a: f128, b: f128) dd128 { | ... | @@ -316,35 +328,35 @@ fn dd_mul128(a: f128, b: f128) dd128 { |
| 316 | test "32" { | 328 | test "32" { |
| 317 | const epsilon = 0.000001; | 329 | const epsilon = 0.000001; |
| 318 | 330 | ||
| 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 | } |
| 327 | 339 | ||
| 328 | test "64" { | 340 | test "64" { |
| 329 | const epsilon = 0.000001; | 341 | const epsilon = 0.000001; |
| 330 | 342 | ||
| 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 | } |
| 339 | 351 | ||
| 340 | test "128" { | 352 | test "128" { |
| 341 | const epsilon = 0.000001; | 353 | const epsilon = 0.000001; |
| 342 | 354 | ||
| 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 | } |
| 19 | 16 | ||
| 20 | pub fn __fmaxh(x: f16, y: f16) callconv(.c) f16 { | 17 | fn __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 | } | ||
| 20 | pub fn fmax_f16(x: f16, y: f16) f16 { | ||
| 21 | return generic_fmax(f16, x, y); | 21 | return generic_fmax(f16, x, y); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | pub fn fmaxf(x: f32, y: f32) callconv(.c) f32 { | 24 | fn 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 | } | ||
| 27 | pub fn fmax_f32(x: f32, y: f32) f32 { | ||
| 25 | return generic_fmax(f32, x, y); | 28 | return generic_fmax(f32, x, y); |
| 26 | } | 29 | } |
| 27 | 30 | ||
| 28 | pub fn fmax(x: f64, y: f64) callconv(.c) f64 { | 31 | fn 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 | } | ||
| 34 | pub fn fmax_f64(x: f64, y: f64) f64 { | ||
| 29 | return generic_fmax(f64, x, y); | 35 | return generic_fmax(f64, x, y); |
| 30 | } | 36 | } |
| 31 | 37 | ||
| 32 | pub fn __fmaxx(x: f80, y: f80) callconv(.c) f80 { | 38 | fn __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 | } | ||
| 41 | pub fn fmax_f80(x: f80, y: f80) f80 { | ||
| 33 | return generic_fmax(f80, x, y); | 42 | return generic_fmax(f80, x, y); |
| 34 | } | 43 | } |
| 35 | 44 | ||
| 36 | pub fn fmaxq(x: f128, y: f128) callconv(.c) f128 { | 45 | fn 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 | } | ||
| 48 | pub fn fmax_f128(x: f128, y: f128) f128 { | ||
| 37 | return generic_fmax(f128, x, y); | 49 | return generic_fmax(f128, x, y); |
| 38 | } | 50 | } |
| 39 | 51 | ||
| 40 | pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { | 52 | pub 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 | } |
| 48 | 60 |
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 | } |
| 19 | 16 | ||
| 20 | pub fn __fminh(x: f16, y: f16) callconv(.c) f16 { | 17 | fn __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 | } | ||
| 20 | pub fn fmin_f16(x: f16, y: f16) f16 { | ||
| 21 | return generic_fmin(f16, x, y); | 21 | return generic_fmin(f16, x, y); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | pub fn fminf(x: f32, y: f32) callconv(.c) f32 { | 24 | fn 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 | } | ||
| 27 | pub fn fmin_f32(x: f32, y: f32) f32 { | ||
| 25 | return generic_fmin(f32, x, y); | 28 | return generic_fmin(f32, x, y); |
| 26 | } | 29 | } |
| 27 | 30 | ||
| 28 | pub fn fmin(x: f64, y: f64) callconv(.c) f64 { | 31 | fn 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 | } | ||
| 34 | pub fn fmin_f64(x: f64, y: f64) f64 { | ||
| 29 | return generic_fmin(f64, x, y); | 35 | return generic_fmin(f64, x, y); |
| 30 | } | 36 | } |
| 31 | 37 | ||
| 32 | pub fn __fminx(x: f80, y: f80) callconv(.c) f80 { | 38 | fn __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 | } | ||
| 41 | pub fn fmin_f80(x: f80, y: f80) f80 { | ||
| 33 | return generic_fmin(f80, x, y); | 42 | return generic_fmin(f80, x, y); |
| 34 | } | 43 | } |
| 35 | 44 | ||
| 36 | pub fn fminq(x: f128, y: f128) callconv(.c) f128 { | 45 | fn 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 | } | ||
| 48 | pub fn fmin_f128(x: f128, y: f128) f128 { | ||
| 37 | return generic_fmin(f128, x, y); | 49 | return generic_fmin(f128, x, y); |
| 38 | } | 50 | } |
| 39 | 51 | ||
| 40 | pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { | 52 | pub 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 | } |
| 48 | 60 |
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 | } |
| 21 | 18 | ||
| 22 | pub fn __fmodh(x: f16, y: f16) callconv(.c) f16 { | 19 | fn __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 | } | ||
| 22 | pub fn fmod_f16(x: f16, y: f16) f16 { | ||
| 23 | // TODO: more efficient implementation | 23 | // TODO: more efficient implementation |
| 24 | return @floatCast(fmodf(x, y)); | 24 | return @floatCast(fmod_f32(x, y)); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | pub fn fmodf(x: f32, y: f32) callconv(.c) f32 { | 27 | fn 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 | } | ||
| 30 | pub fn fmod_f32(x: f32, y: f32) f32 { | ||
| 28 | return generic_fmod(f32, x, y); | 31 | return generic_fmod(f32, x, y); |
| 29 | } | 32 | } |
| 30 | 33 | ||
| 31 | pub fn fmod(x: f64, y: f64) callconv(.c) f64 { | 34 | fn 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 | } | ||
| 37 | pub fn fmod_f64(x: f64, y: f64) f64 { | ||
| 32 | return generic_fmod(f64, x, y); | 38 | return generic_fmod(f64, x, y); |
| 33 | } | 39 | } |
| 34 | 40 | ||
| 41 | fn __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 types | 44 | /// fmodx - floating modulo large, returns the remainder of division for f80 types |
| 36 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits | 45 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits |
| 37 | pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 { | 46 | pub 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)); |
| 40 | 49 | ||
| ... | @@ -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 | } |
| 132 | 141 | ||
| 142 | fn 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 types | 145 | /// fmodq - floating modulo large, returns the remainder of division for f128 types |
| 134 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits | 146 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits |
| 135 | pub fn fmodq(a: f128, b: f128) callconv(.c) f128 { | 147 | pub 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 { |
| 251 | 263 | ||
| 252 | pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble { | 264 | pub 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 | } |
| 260 | 272 | ||
| ... | @@ -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 | } |
| 344 | 356 | ||
| 345 | test "fmodf" { | 357 | test 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); |
| 348 | 360 | ||
| 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))); |
| 354 | 366 | ||
| 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)); |
| 357 | 369 | ||
| 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 | } |
| 363 | 375 | ||
| 364 | test "fmod" { | 376 | test 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); |
| 367 | 379 | ||
| 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))); |
| 373 | 385 | ||
| 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)); |
| 376 | 388 | ||
| 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 | } |
| 382 | 394 | ||
| 383 | test { | 395 | test { |
lib/compiler_rt/fmodq_test.zig+32-32| ... | @@ -1,52 +1,52 @@ | ... | @@ -1,52 +1,52 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const fmod = @import("fmod.zig"); | 2 | const fmod_f128 = @import("fmod.zig").fmod_f128; |
| 3 | const testing = std.testing; | 3 | const testing = std.testing; |
| 4 | 4 | ||
| 5 | fn test_fmodq(a: f128, b: f128, exp: f128) !void { | 5 | fn 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 | } |
| 9 | 9 | ||
| 10 | fn test_fmodq_nans() !void { | 10 | fn 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 | } |
| 16 | 16 | ||
| 17 | fn test_fmodq_infs() !void { | 17 | fn 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 | } |
| 23 | 23 | ||
| 24 | test "fmodq" { | 24 | test 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); |
| 39 | 39 | ||
| 40 | // Denormals | 40 | // 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); |
| 49 | 49 | ||
| 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 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const fmod = @import("fmod.zig"); | 3 | const fmod_f80 = @import("fmod.zig").fmod_f80; |
| 4 | const testing = std.testing; | 4 | const testing = std.testing; |
| 5 | 5 | ||
| 6 | fn test_fmodx(a: f80, b: f80, exp: f80) !void { | 6 | fn 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 | } |
| 10 | 10 | ||
| 11 | fn test_fmodx_nans() !void { | 11 | fn 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 | } |
| 17 | 17 | ||
| 18 | fn test_fmodx_infs() !void { | 18 | fn 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 | } |
| 24 | 24 | ||
| 25 | test "fmodx" { | 25 | test 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); |
| 39 | 39 | ||
| 40 | // Denormals | 40 | // 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); |
| 49 | 49 | ||
| 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 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const comparef = @import("./comparef.zig"); | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | |||
| 7 | comptime { | ||
| 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." | ||
| 19 | pub 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." | ||
| 25 | pub fn __gtdf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 26 | return __gedf2(a, b); | ||
| 27 | } | ||
| 28 | |||
| 29 | fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 30 | return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) != .Less); | ||
| 31 | } | ||
| 32 | |||
| 33 | fn __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 | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | const comparef = @import("./comparef.zig"); | ||
| 5 | |||
| 6 | comptime { | ||
| 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." | ||
| 13 | pub 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." | ||
| 19 | pub 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 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const comparef = @import("./comparef.zig"); | ||
| 6 | |||
| 7 | comptime { | ||
| 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." | ||
| 19 | pub 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." | ||
| 25 | pub fn __gtsf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 26 | return __gesf2(a, b); | ||
| 27 | } | ||
| 28 | |||
| 29 | fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 30 | return @intFromBool(comparef.cmpf2(f32, comparef.GE, a, b) != .Less); | ||
| 31 | } | ||
| 32 | |||
| 33 | fn __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 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const comparef = @import("./comparef.zig"); | ||
| 6 | |||
| 7 | comptime { | ||
| 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." | ||
| 18 | fn __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." | ||
| 24 | fn __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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const comparef = @import("./comparef.zig"); | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__gexf2, "__gexf2"); | ||
| 6 | symbol(&__gtxf2, "__gtxf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __gexf2(a: f80, b: f80) callconv(.c) i32 { | ||
| 10 | return @backingInt(comparef.cmp_f80(comparef.GE, a, b)); | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __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 { |
| 36 | 36 | ||
| 37 | pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 { | 37 | pub 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 | } |
| 42 | 42 | ||
| ... | @@ -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 |
| 69 | 69 | ||
| 70 | pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 { | 70 | pub 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 | } |
| 75 | 75 | ||
| ... | @@ -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 | } |
| 81 | 81 | ||
| 82 | const cases__divmoddi4 = | 82 | const 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 | }; | ||
| 97 | 96 | ||
| 98 | test "test_divmoddi4" { | 97 | test "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 | } |
| 107 | 106 | ||
| 108 | test "test_udivmoddi4" { | ||
| 109 | _ = @import("udivmoddi4_test.zig"); | ||
| 110 | } | ||
| 111 | |||
| 112 | pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 { | 107 | pub 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 { |
| 209 | 204 | ||
| 210 | pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 { | 205 | pub 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 | } |
| 215 | 210 | ||
| 216 | const cases__divmodsi4 = | 211 | const 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 | }; | ||
| 231 | 225 | ||
| 232 | fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void { | 226 | fn 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" { |
| 243 | 237 | ||
| 244 | pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 { | 238 | pub 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 | } |
| 249 | 243 | ||
| ... | @@ -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 | } |
| 487 | 481 | ||
| 488 | pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 { | 482 | pub 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 | } |
| 491 | 485 | ||
| 492 | test "test_modsi3" { | 486 | test "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 | } |
| 516 | 510 | ||
| 517 | pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 { | 511 | pub 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 | } |
| 520 | 514 | ||
| 521 | test "test_umodsi3" { | 515 | test "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 | |||
| 661 | test { | ||
| 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 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const std = @import("std"); | 2 | const std = @import("std"); |
| 2 | const math = std.math; | 3 | const math = std.math; |
| 3 | const Log2Int = std.math.Log2Int; | 4 | const 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"); |
| 6 | const symbol = compiler_rt.symbol; | 7 | const symbol = compiler_rt.symbol; |
| 7 | 8 | ||
| 8 | comptime { | 9 | comptime { |
| 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 | |||
| 66 | fn __fixhfsi(a: compiler_rt.f16.Abi) callconv(.c) i32 { | ||
| 67 | return i32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 68 | } | ||
| 69 | pub fn i32_intFromFloat_f16(a: f16) i32 { | ||
| 70 | return intFromFloat(i32, a); | ||
| 71 | } | ||
| 72 | |||
| 73 | fn __fixhfdi(a: compiler_rt.f16.Abi) callconv(.c) i64 { | ||
| 74 | return i64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 75 | } | ||
| 76 | pub fn i64_intFromFloat_f16(a: f16) i64 { | ||
| 77 | return intFromFloat(i64, a); | ||
| 78 | } | ||
| 79 | |||
| 80 | fn __fixhfti(a: compiler_rt.f16.Abi) callconv(.c) i128 { | ||
| 81 | return i128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 82 | } | ||
| 83 | pub fn i128_intFromFloat_f16(a: f16) i128 { | ||
| 84 | return intFromFloat(i128, a); | ||
| 85 | } | ||
| 86 | |||
| 87 | fn __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 | } | ||
| 91 | pub fn signed_intFromFloat_f16(result: []u8, a: f16) void { | ||
| 92 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 93 | } | ||
| 94 | |||
| 95 | fn __fixsfsi(a: compiler_rt.f32.Abi) callconv(.c) i32 { | ||
| 96 | return i32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 97 | } | ||
| 98 | fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 99 | return i32_intFromFloat_f32(a); | ||
| 100 | } | ||
| 101 | pub fn i32_intFromFloat_f32(a: f32) i32 { | ||
| 102 | return intFromFloat(i32, a); | ||
| 103 | } | ||
| 104 | |||
| 105 | fn __fixsfdi(a: compiler_rt.f32.Abi) callconv(.c) i64 { | ||
| 106 | return i64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 107 | } | ||
| 108 | fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 { | ||
| 109 | return i64_intFromFloat_f32(a); | ||
| 110 | } | ||
| 111 | pub fn i64_intFromFloat_f32(a: f32) i64 { | ||
| 112 | return intFromFloat(i64, a); | ||
| 113 | } | ||
| 114 | |||
| 115 | fn __fixsfti(a: compiler_rt.f32.Abi) callconv(.c) i128 { | ||
| 116 | return i128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 117 | } | ||
| 118 | fn __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 | } | ||
| 139 | pub fn i128_intFromFloat_f32(a: f32) i128 { | ||
| 140 | return intFromFloat(i128, a); | ||
| 141 | } | ||
| 142 | |||
| 143 | fn __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 | } | ||
| 147 | pub fn signed_intFromFloat_f32(result: []u8, a: f32) void { | ||
| 148 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 149 | } | ||
| 150 | |||
| 151 | fn __fixdfsi(a: compiler_rt.f64.Abi) callconv(.c) i32 { | ||
| 152 | return i32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 153 | } | ||
| 154 | fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 155 | return i32_intFromFloat_f64(a); | ||
| 156 | } | ||
| 157 | pub fn i32_intFromFloat_f64(a: f64) i32 { | ||
| 158 | return intFromFloat(i32, a); | ||
| 159 | } | ||
| 160 | |||
| 161 | fn __fixdfdi(a: compiler_rt.f64.Abi) callconv(.c) i64 { | ||
| 162 | return i64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 163 | } | ||
| 164 | fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 { | ||
| 165 | return i64_intFromFloat_f64(a); | ||
| 166 | } | ||
| 167 | pub fn i64_intFromFloat_f64(a: f64) i64 { | ||
| 168 | return intFromFloat(i64, a); | ||
| 13 | } | 169 | } |
| 14 | 170 | ||
| 15 | pub fn __fixhfti(a: f16) callconv(.c) i128 { | 171 | fn __fixdfti(a: compiler_rt.f64.Abi) callconv(.c) i128 { |
| 172 | return i128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 173 | } | ||
| 174 | fn __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 | } | ||
| 196 | pub fn i128_intFromFloat_f64(a: f64) i128 { | ||
| 16 | return intFromFloat(i128, a); | 197 | return intFromFloat(i128, a); |
| 17 | } | 198 | } |
| 18 | 199 | ||
| 19 | fn __fixhfdi(a: f16) callconv(.c) i64 { | 200 | fn __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 | } | ||
| 204 | pub fn signed_intFromFloat_f64(result: []u8, a: f64) void { | ||
| 205 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 206 | } | ||
| 207 | |||
| 208 | fn __fixxfsi(a: compiler_rt.f80.Abi) callconv(.c) i32 { | ||
| 209 | return i32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 210 | } | ||
| 211 | pub fn i32_intFromFloat_f80(a: f80) i32 { | ||
| 212 | return intFromFloat(i32, a); | ||
| 213 | } | ||
| 214 | |||
| 215 | fn __fixxfdi(a: compiler_rt.f80.Abi) callconv(.c) i64 { | ||
| 216 | return i64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 217 | } | ||
| 218 | pub fn i64_intFromFloat_f80(a: f80) i64 { | ||
| 20 | return intFromFloat(i64, a); | 219 | return intFromFloat(i64, a); |
| 21 | } | 220 | } |
| 22 | 221 | ||
| 23 | fn __fixhfsi(a: f16) callconv(.c) i32 { | 222 | fn __fixxfti(a: compiler_rt.f80.Abi) callconv(.c) i128 { |
| 223 | return i128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 224 | } | ||
| 225 | pub fn i128_intFromFloat_f80(a: f80) i128 { | ||
| 226 | return intFromFloat(i128, a); | ||
| 227 | } | ||
| 228 | |||
| 229 | fn __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 | } | ||
| 233 | pub fn signed_intFromFloat_f80(result: []u8, a: f80) void { | ||
| 234 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 235 | } | ||
| 236 | |||
| 237 | fn __fixtfsi(a: compiler_rt.f128.Abi) callconv(.c) i32 { | ||
| 238 | return i32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 239 | } | ||
| 240 | fn _Qp_qtoi(a: *const f128) callconv(.c) i32 { | ||
| 241 | return i32_intFromFloat_f128(a.*); | ||
| 242 | } | ||
| 243 | pub fn i32_intFromFloat_f128(a: f128) i32 { | ||
| 24 | return intFromFloat(i32, a); | 244 | return intFromFloat(i32, a); |
| 25 | } | 245 | } |
| 26 | 246 | ||
| 27 | pub fn __fixxfti(a: f80) callconv(.c) i128 { | 247 | fn __fixtfdi(a: compiler_rt.f128.Abi) callconv(.c) i64 { |
| 248 | return i64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 249 | } | ||
| 250 | fn _Qp_qtox(a: *const f128) callconv(.c) i64 { | ||
| 251 | return i64_intFromFloat_f128(a.*); | ||
| 252 | } | ||
| 253 | pub fn i64_intFromFloat_f128(a: f128) i64 { | ||
| 254 | return intFromFloat(i64, a); | ||
| 255 | } | ||
| 256 | |||
| 257 | fn __fixtfti(a: compiler_rt.f128.Abi) callconv(.c) i128 { | ||
| 258 | return i128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 259 | } | ||
| 260 | pub fn i128_intFromFloat_f128(a: f128) i128 { | ||
| 28 | return intFromFloat(i128, a); | 261 | return intFromFloat(i128, a); |
| 29 | } | 262 | } |
| 30 | 263 | ||
| 31 | pub inline fn intFromFloat(comptime I: type, a: anytype) I { | 264 | fn __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 | } | ||
| 268 | pub fn signed_intFromFloat_f128(result: []u8, a: f128) void { | ||
| 269 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 270 | } | ||
| 271 | |||
| 272 | comptime { | ||
| 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 | |||
| 329 | fn __fixunshfsi(a: compiler_rt.f16.Abi) callconv(.c) u32 { | ||
| 330 | return u32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 331 | } | ||
| 332 | pub fn u32_intFromFloat_f16(a: f16) u32 { | ||
| 333 | return intFromFloat(u32, a); | ||
| 334 | } | ||
| 335 | |||
| 336 | fn __fixunshfdi(a: compiler_rt.f16.Abi) callconv(.c) u64 { | ||
| 337 | return u64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 338 | } | ||
| 339 | pub fn u64_intFromFloat_f16(a: f16) u64 { | ||
| 340 | return intFromFloat(u64, a); | ||
| 341 | } | ||
| 342 | |||
| 343 | fn __fixunshfti(a: compiler_rt.f16.Abi) callconv(.c) u128 { | ||
| 344 | return u128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 345 | } | ||
| 346 | pub fn u128_intFromFloat_f16(a: f16) u128 { | ||
| 347 | return intFromFloat(u128, a); | ||
| 348 | } | ||
| 349 | |||
| 350 | fn __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 | } | ||
| 354 | pub fn unsigned_intFromFloat_f16(result: []u8, a: f16) void { | ||
| 355 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 356 | } | ||
| 357 | |||
| 358 | fn __fixunssfsi(a: compiler_rt.f32.Abi) callconv(.c) u32 { | ||
| 359 | return u32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 360 | } | ||
| 361 | fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 { | ||
| 362 | return u32_intFromFloat_f32(a); | ||
| 363 | } | ||
| 364 | pub fn u32_intFromFloat_f32(a: f32) u32 { | ||
| 365 | return intFromFloat(u32, a); | ||
| 366 | } | ||
| 367 | |||
| 368 | fn __fixunssfdi(a: compiler_rt.f32.Abi) callconv(.c) u64 { | ||
| 369 | return u64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 370 | } | ||
| 371 | fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 { | ||
| 372 | return u64_intFromFloat_f32(a); | ||
| 373 | } | ||
| 374 | pub fn u64_intFromFloat_f32(a: f32) u64 { | ||
| 375 | return intFromFloat(u64, a); | ||
| 376 | } | ||
| 377 | |||
| 378 | fn __fixunssfti(a: compiler_rt.f32.Abi) callconv(.c) u128 { | ||
| 379 | return u128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 380 | } | ||
| 381 | fn __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 | } | ||
| 402 | pub fn u128_intFromFloat_f32(a: f32) u128 { | ||
| 403 | return intFromFloat(u128, a); | ||
| 404 | } | ||
| 405 | |||
| 406 | fn __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 | } | ||
| 410 | pub fn unsigned_intFromFloat_f32(result: []u8, a: f32) void { | ||
| 411 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 412 | } | ||
| 413 | |||
| 414 | fn __fixunsdfsi(a: compiler_rt.f64.Abi) callconv(.c) u32 { | ||
| 415 | return u32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 416 | } | ||
| 417 | fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 { | ||
| 418 | return u32_intFromFloat_f64(a); | ||
| 419 | } | ||
| 420 | pub fn u32_intFromFloat_f64(a: f64) u32 { | ||
| 421 | return intFromFloat(u32, a); | ||
| 422 | } | ||
| 423 | |||
| 424 | fn __fixunsdfdi(a: compiler_rt.f64.Abi) callconv(.c) u64 { | ||
| 425 | return u64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 426 | } | ||
| 427 | fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 { | ||
| 428 | return u64_intFromFloat_f64(a); | ||
| 429 | } | ||
| 430 | pub fn u64_intFromFloat_f64(a: f64) u64 { | ||
| 431 | return intFromFloat(u64, a); | ||
| 432 | } | ||
| 433 | |||
| 434 | fn __fixunsdfti(a: compiler_rt.f64.Abi) callconv(.c) u128 { | ||
| 435 | return u128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 436 | } | ||
| 437 | fn __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 | } | ||
| 459 | pub fn u128_intFromFloat_f64(a: f64) u128 { | ||
| 460 | return intFromFloat(u128, a); | ||
| 461 | } | ||
| 462 | |||
| 463 | fn __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 | } | ||
| 467 | pub fn unsigned_intFromFloat_f64(result: []u8, a: f64) void { | ||
| 468 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 469 | } | ||
| 470 | |||
| 471 | fn __fixunsxfsi(a: compiler_rt.f80.Abi) callconv(.c) u32 { | ||
| 472 | return u32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 473 | } | ||
| 474 | pub fn u32_intFromFloat_f80(a: f80) u32 { | ||
| 475 | return intFromFloat(u32, a); | ||
| 476 | } | ||
| 477 | |||
| 478 | fn __fixunsxfdi(a: compiler_rt.f80.Abi) callconv(.c) u64 { | ||
| 479 | return u64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 480 | } | ||
| 481 | pub fn u64_intFromFloat_f80(a: f80) u64 { | ||
| 482 | return intFromFloat(u64, a); | ||
| 483 | } | ||
| 484 | |||
| 485 | fn __fixunsxfti(a: compiler_rt.f80.Abi) callconv(.c) u128 { | ||
| 486 | return u128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 487 | } | ||
| 488 | pub fn u128_intFromFloat_f80(a: f80) u128 { | ||
| 489 | return intFromFloat(u128, a); | ||
| 490 | } | ||
| 491 | |||
| 492 | fn __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 | } | ||
| 496 | pub fn unsigned_intFromFloat_f80(result: []u8, a: f80) void { | ||
| 497 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 498 | } | ||
| 499 | |||
| 500 | fn __fixunstfsi(a: compiler_rt.f128.Abi) callconv(.c) u32 { | ||
| 501 | return u32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 502 | } | ||
| 503 | fn _Qp_qtoui(a: *const f128) callconv(.c) u32 { | ||
| 504 | return u32_intFromFloat_f128(a.*); | ||
| 505 | } | ||
| 506 | pub fn u32_intFromFloat_f128(a: f128) u32 { | ||
| 507 | return intFromFloat(u32, a); | ||
| 508 | } | ||
| 509 | |||
| 510 | fn __fixunstfdi(a: compiler_rt.f128.Abi) callconv(.c) u64 { | ||
| 511 | return u64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 512 | } | ||
| 513 | fn _Qp_qtoux(a: *const f128) callconv(.c) u64 { | ||
| 514 | return u64_intFromFloat_f128(a.*); | ||
| 515 | } | ||
| 516 | pub fn u64_intFromFloat_f128(a: f128) u64 { | ||
| 517 | return intFromFloat(u64, a); | ||
| 518 | } | ||
| 519 | |||
| 520 | fn __fixunstfti(a: compiler_rt.f128.Abi) callconv(.c) u128 { | ||
| 521 | return u128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 522 | } | ||
| 523 | pub fn u128_intFromFloat_f128(a: f128) u128 { | ||
| 524 | return intFromFloat(u128, a); | ||
| 525 | } | ||
| 526 | |||
| 527 | fn __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 | } | ||
| 531 | pub fn unsigned_intFromFloat_f128(result: []u8, a: f128) void { | ||
| 532 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 533 | } | ||
| 534 | |||
| 535 | inline 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 | } |
| 78 | 582 | ||
| 79 | pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void { | 583 | inline 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"); |
| 2 | const testing = std.testing; | 2 | const testing = std.testing; |
| 3 | const math = std.math; | 3 | const math = std.math; |
| 4 | 4 | ||
| 5 | const __fixunshfti = @import("fixunshfti.zig").__fixunshfti; | 5 | const impl = @import("int_from_float.zig"); |
| 6 | const __fixunsxfti = @import("fixunsxfti.zig").__fixunsxfti; | 6 | |
| 7 | 7 | const i32_intFromFloat_f16 = impl.i32_intFromFloat_f16; | |
| 8 | // Conversion from f32 | 8 | const u32_intFromFloat_f16 = impl.u32_intFromFloat_f16; |
| 9 | const __fixsfsi = @import("fixsfsi.zig").__fixsfsi; | 9 | const i64_intFromFloat_f16 = impl.i64_intFromFloat_f16; |
| 10 | const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi; | 10 | const u64_intFromFloat_f16 = impl.u64_intFromFloat_f16; |
| 11 | const __fixsfdi = @import("fixsfdi.zig").__fixsfdi; | 11 | const i128_intFromFloat_f16 = impl.i128_intFromFloat_f16; |
| 12 | const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi; | 12 | const u128_intFromFloat_f16 = impl.u128_intFromFloat_f16; |
| 13 | const __fixsfti = @import("fixsfti.zig").__fixsfti; | 13 | const signed_intFromFloat_f16 = impl.signed_intFromFloat_f16; |
| 14 | const __fixunssfti = @import("fixunssfti.zig").__fixunssfti; | 14 | const unsigned_intFromFloat_f16 = impl.unsigned_intFromFloat_f16; |
| 15 | const __fixsfei = @import("fixsfei.zig").__fixsfei; | 15 | |
| 16 | const __fixunssfei = @import("fixunssfei.zig").__fixunssfei; | 16 | const i32_intFromFloat_f32 = impl.i32_intFromFloat_f32; |
| 17 | 17 | const u32_intFromFloat_f32 = impl.u32_intFromFloat_f32; | |
| 18 | // Conversion from f64 | 18 | const i64_intFromFloat_f32 = impl.i64_intFromFloat_f32; |
| 19 | const __fixdfsi = @import("fixdfsi.zig").__fixdfsi; | 19 | const u64_intFromFloat_f32 = impl.u64_intFromFloat_f32; |
| 20 | const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi; | 20 | const i128_intFromFloat_f32 = impl.i128_intFromFloat_f32; |
| 21 | const __fixdfdi = @import("fixdfdi.zig").__fixdfdi; | 21 | const u128_intFromFloat_f32 = impl.u128_intFromFloat_f32; |
| 22 | const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi; | 22 | const signed_intFromFloat_f32 = impl.signed_intFromFloat_f32; |
| 23 | const __fixdfti = @import("fixdfti.zig").__fixdfti; | 23 | const unsigned_intFromFloat_f32 = impl.unsigned_intFromFloat_f32; |
| 24 | const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti; | 24 | |
| 25 | const __fixdfei = @import("fixdfei.zig").__fixdfei; | 25 | const i32_intFromFloat_f64 = impl.i32_intFromFloat_f64; |
| 26 | const __fixunsdfei = @import("fixunsdfei.zig").__fixunsdfei; | 26 | const u32_intFromFloat_f64 = impl.u32_intFromFloat_f64; |
| 27 | 27 | const i64_intFromFloat_f64 = impl.i64_intFromFloat_f64; | |
| 28 | // Conversion from f128 | 28 | const u64_intFromFloat_f64 = impl.u64_intFromFloat_f64; |
| 29 | const __fixtfsi = @import("fixtfsi.zig").__fixtfsi; | 29 | const i128_intFromFloat_f64 = impl.i128_intFromFloat_f64; |
| 30 | const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi; | 30 | const u128_intFromFloat_f64 = impl.u128_intFromFloat_f64; |
| 31 | const __fixtfdi = @import("fixtfdi.zig").__fixtfdi; | 31 | const signed_intFromFloat_f64 = impl.signed_intFromFloat_f64; |
| 32 | const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi; | 32 | const unsigned_intFromFloat_f64 = impl.unsigned_intFromFloat_f64; |
| 33 | const __fixtfti = @import("fixtfti.zig").__fixtfti; | 33 | |
| 34 | const __fixunstfti = @import("fixunstfti.zig").__fixunstfti; | 34 | const i32_intFromFloat_f80 = impl.i32_intFromFloat_f80; |
| 35 | 35 | const u32_intFromFloat_f80 = impl.u32_intFromFloat_f80; | |
| 36 | fn test__fixsfsi(a: f32, expected: i32) !void { | 36 | const i64_intFromFloat_f80 = impl.i64_intFromFloat_f80; |
| 37 | const x = __fixsfsi(a); | 37 | const u64_intFromFloat_f80 = impl.u64_intFromFloat_f80; |
| 38 | const i128_intFromFloat_f80 = impl.i128_intFromFloat_f80; | ||
| 39 | const u128_intFromFloat_f80 = impl.u128_intFromFloat_f80; | ||
| 40 | const signed_intFromFloat_f80 = impl.signed_intFromFloat_f80; | ||
| 41 | const unsigned_intFromFloat_f80 = impl.unsigned_intFromFloat_f80; | ||
| 42 | |||
| 43 | const i32_intFromFloat_f128 = impl.i32_intFromFloat_f128; | ||
| 44 | const u32_intFromFloat_f128 = impl.u32_intFromFloat_f128; | ||
| 45 | const i64_intFromFloat_f128 = impl.i64_intFromFloat_f128; | ||
| 46 | const u64_intFromFloat_f128 = impl.u64_intFromFloat_f128; | ||
| 47 | const i128_intFromFloat_f128 = impl.i128_intFromFloat_f128; | ||
| 48 | const u128_intFromFloat_f128 = impl.u128_intFromFloat_f128; | ||
| 49 | const signed_intFromFloat_f128 = impl.signed_intFromFloat_f128; | ||
| 50 | const unsigned_intFromFloat_f128 = impl.unsigned_intFromFloat_f128; | ||
| 51 | |||
| 52 | fn 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 | } |
| 40 | 56 | ||
| 41 | fn test__fixunssfsi(a: f32, expected: u32) !void { | 57 | fn 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 | } |
| 45 | 61 | ||
| 46 | test "fixsfsi" { | 62 | test 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)); |
| 48 | 64 | ||
| 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); |
| 51 | 67 | ||
| 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); |
| 55 | 71 | ||
| 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); |
| 60 | 76 | ||
| 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); |
| 63 | 79 | ||
| 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); |
| 68 | 84 | ||
| 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); |
| 75 | 91 | ||
| 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); |
| 86 | 102 | ||
| 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); |
| 91 | 107 | ||
| 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); |
| 94 | 110 | ||
| 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); |
| 99 | 115 | ||
| 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); |
| 103 | 119 | ||
| 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)); |
| 106 | 122 | ||
| 107 | try test__fixsfsi(math.floatMax(f32), math.maxInt(i32)); | 123 | try test_i32_intFromFloat_f32(math.floatMax(f32), math.maxInt(i32)); |
| 108 | } | 124 | } |
| 109 | 125 | ||
| 110 | test "fixunssfsi" { | 126 | test u32_intFromFloat_f32 { |
| 111 | try test__fixunssfsi(0.0, 0); | 127 | try test_u32_intFromFloat_f32(0.0, 0); |
| 112 | 128 | ||
| 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); |
| 122 | 138 | ||
| 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); |
| 128 | 144 | ||
| 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); |
| 134 | 150 | ||
| 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 | } |
| 138 | 154 | ||
| 139 | fn test__fixsfdi(a: f32, expected: i64) !void { | 155 | fn 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 | } |
| 143 | 159 | ||
| 144 | fn test__fixunssfdi(a: f32, expected: u64) !void { | 160 | fn 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 | } |
| 148 | 164 | ||
| 149 | test "fixsfdi" { | 165 | test 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)); |
| 151 | 167 | ||
| 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); |
| 154 | 170 | ||
| 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); |
| 158 | 174 | ||
| 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); |
| 163 | 179 | ||
| 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); |
| 167 | 183 | ||
| 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); |
| 184 | 200 | ||
| 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); |
| 188 | 204 | ||
| 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); |
| 193 | 209 | ||
| 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); |
| 197 | 213 | ||
| 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)); |
| 200 | 216 | ||
| 201 | try test__fixsfdi(math.floatMax(f32), math.maxInt(i64)); | 217 | try test_i64_intFromFloat_f32(math.floatMax(f32), math.maxInt(i64)); |
| 202 | } | 218 | } |
| 203 | 219 | ||
| 204 | test "fixunssfdi" { | 220 | test u64_intFromFloat_f32 { |
| 205 | try test__fixunssfdi(0.0, 0); | 221 | try test_u64_intFromFloat_f32(0.0, 0); |
| 206 | 222 | ||
| 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); |
| 216 | 232 | ||
| 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); |
| 222 | 238 | ||
| 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); |
| 227 | 243 | ||
| 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 | } |
| 231 | 247 | ||
| 232 | fn test__fixsfti(a: f32, expected: i128) !void { | 248 | fn 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 | } |
| 236 | 252 | ||
| 237 | fn test__fixunssfti(a: f32, expected: u128) !void { | 253 | fn 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 | } |
| 241 | 257 | ||
| 242 | test "fixsfti" { | 258 | test 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)); |
| 244 | 260 | ||
| 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); |
| 247 | 263 | ||
| 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); |
| 254 | 270 | ||
| 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); |
| 259 | 275 | ||
| 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); |
| 263 | 279 | ||
| 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); |
| 268 | 284 | ||
| 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); |
| 285 | 301 | ||
| 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); |
| 290 | 306 | ||
| 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); |
| 294 | 310 | ||
| 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); |
| 299 | 315 | ||
| 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); |
| 306 | 322 | ||
| 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)); |
| 309 | 325 | ||
| 310 | try test__fixsfti(math.floatMax(f32), math.maxInt(i128)); | 326 | try test_i128_intFromFloat_f32(math.floatMax(f32), math.maxInt(i128)); |
| 311 | } | 327 | } |
| 312 | 328 | ||
| 313 | test "fixunssfti" { | 329 | test u128_intFromFloat_f32 { |
| 314 | try test__fixunssfti(0.0, 0); | 330 | try test_u128_intFromFloat_f32(0.0, 0); |
| 315 | 331 | ||
| 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); |
| 325 | 341 | ||
| 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); |
| 331 | 347 | ||
| 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); |
| 340 | 356 | ||
| 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 | } |
| 348 | 364 | ||
| 349 | fn test_fixsfei(comptime T: type, expected: T, a: f32) !void { | 365 | fn 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 | } |
| 358 | 374 | ||
| 359 | test "fixsfei" { | 375 | test 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 | } |
| 372 | 388 | ||
| 373 | test "fixunsfei" { | 389 | test 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 | } |
| 381 | 397 | ||
| 382 | fn test__fixdfsi(a: f64, expected: i32) !void { | 398 | fn 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 | } |
| 386 | 402 | ||
| 387 | fn test__fixunsdfsi(a: f64, expected: u32) !void { | 403 | fn 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 | } |
| 391 | 407 | ||
| 392 | test "fixdfsi" { | 408 | test 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)); |
| 394 | 410 | ||
| 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); |
| 397 | 413 | ||
| 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); |
| 401 | 417 | ||
| 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); |
| 406 | 422 | ||
| 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); |
| 409 | 425 | ||
| 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); |
| 413 | 429 | ||
| 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); |
| 430 | 446 | ||
| 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); |
| 434 | 450 | ||
| 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); |
| 437 | 453 | ||
| 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); |
| 442 | 458 | ||
| 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); |
| 446 | 462 | ||
| 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)); |
| 449 | 465 | ||
| 450 | try test__fixdfsi(math.floatMax(f64), math.maxInt(i32)); | 466 | try test_i32_intFromFloat_f64(math.floatMax(f64), math.maxInt(i32)); |
| 451 | } | 467 | } |
| 452 | 468 | ||
| 453 | test "fixunsdfsi" { | 469 | test u32_intFromFloat_f64 { |
| 454 | try test__fixunsdfsi(0.0, 0); | 470 | try test_u32_intFromFloat_f64(0.0, 0); |
| 455 | 471 | ||
| 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); |
| 470 | 486 | ||
| 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); |
| 476 | 492 | ||
| 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); |
| 479 | 495 | ||
| 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 | } |
| 484 | 500 | ||
| 485 | fn test__fixdfdi(a: f64, expected: i64) !void { | 501 | fn 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 | } |
| 489 | 505 | ||
| 490 | fn test__fixunsdfdi(a: f64, expected: u64) !void { | 506 | fn 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 | } |
| 494 | 510 | ||
| 495 | test "fixdfdi" { | 511 | test 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)); |
| 497 | 513 | ||
| 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); |
| 500 | 516 | ||
| 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); |
| 504 | 520 | ||
| 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); |
| 509 | 525 | ||
| 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); |
| 512 | 528 | ||
| 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); |
| 529 | 545 | ||
| 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); |
| 532 | 548 | ||
| 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); |
| 537 | 553 | ||
| 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); |
| 541 | 557 | ||
| 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)); |
| 544 | 560 | ||
| 545 | try test__fixdfdi(math.floatMax(f64), math.maxInt(i64)); | 561 | try test_i64_intFromFloat_f64(math.floatMax(f64), math.maxInt(i64)); |
| 546 | } | 562 | } |
| 547 | 563 | ||
| 548 | test "fixunsdfdi" { | 564 | test 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); |
| 564 | 580 | ||
| 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); |
| 567 | 583 | ||
| 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); |
| 570 | 586 | ||
| 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); |
| 575 | 591 | ||
| 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 | } |
| 579 | 595 | ||
| 580 | fn test__fixdfti(a: f64, expected: i128) !void { | 596 | fn 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 | } |
| 584 | 600 | ||
| 585 | fn test__fixunsdfti(a: f64, expected: u128) !void { | 601 | fn 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 | } |
| 589 | 605 | ||
| 590 | test "fixdfti" { | 606 | test 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)); |
| 592 | 608 | ||
| 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); |
| 595 | 611 | ||
| 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); |
| 599 | 615 | ||
| 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); |
| 604 | 620 | ||
| 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); |
| 607 | 623 | ||
| 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); |
| 624 | 640 | ||
| 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); |
| 627 | 643 | ||
| 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); |
| 632 | 648 | ||
| 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); |
| 636 | 652 | ||
| 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)); |
| 639 | 655 | ||
| 640 | try test__fixdfti(math.floatMax(f64), math.maxInt(i128)); | 656 | try test_i128_intFromFloat_f64(math.floatMax(f64), math.maxInt(i128)); |
| 641 | } | 657 | } |
| 642 | 658 | ||
| 643 | test "fixunsdfti" { | 659 | test u128_intFromFloat_f64 { |
| 644 | try test__fixunsdfti(0.0, 0); | 660 | try test_u128_intFromFloat_f64(0.0, 0); |
| 645 | 661 | ||
| 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); |
| 660 | 676 | ||
| 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); |
| 663 | 679 | ||
| 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); |
| 666 | 682 | ||
| 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); |
| 671 | 687 | ||
| 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); |
| 677 | 693 | ||
| 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 | } |
| 681 | 697 | ||
| 682 | fn test_fixdfei(comptime T: type, expected: T, a: f64) !void { | 698 | fn 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 | } |
| 691 | 707 | ||
| 692 | test "fixdfei" { | 708 | test 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 | } |
| 707 | 723 | ||
| 708 | test "fixundfei" { | 724 | test 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 | } |
| 717 | 733 | ||
| 718 | fn test__fixtfsi(a: f128, expected: i32) !void { | 734 | fn 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 | } |
| 722 | 738 | ||
| 723 | fn test__fixunstfsi(a: f128, expected: u32) !void { | 739 | fn 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 | } |
| 727 | 743 | ||
| 728 | test "fixtfsi" { | 744 | test 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)); |
| 730 | 746 | ||
| 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); |
| 733 | 749 | ||
| 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); |
| 737 | 753 | ||
| 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); |
| 742 | 758 | ||
| 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); |
| 745 | 761 | ||
| 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); |
| 750 | 766 | ||
| 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); |
| 767 | 783 | ||
| 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); |
| 772 | 788 | ||
| 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); |
| 775 | 791 | ||
| 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); |
| 780 | 796 | ||
| 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); |
| 784 | 800 | ||
| 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)); |
| 787 | 803 | ||
| 788 | try test__fixtfsi(math.floatMax(f128), math.maxInt(i32)); | 804 | try test_i32_intFromFloat_f128(math.floatMax(f128), math.maxInt(i32)); |
| 789 | } | 805 | } |
| 790 | 806 | ||
| 791 | test "fixunstfsi" { | 807 | test 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); |
| 800 | 816 | ||
| 801 | try test__fixunstfsi(0x1p+32, 0xFFFFFFFF); | 817 | try test_u32_intFromFloat_f128(0x1p+32, 0xFFFFFFFF); |
| 802 | } | 818 | } |
| 803 | 819 | ||
| 804 | fn test__fixtfdi(a: f128, expected: i64) !void { | 820 | fn 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 | } |
| 808 | 824 | ||
| 809 | fn test__fixunstfdi(a: f128, expected: u64) !void { | 825 | fn 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 | } |
| 813 | 829 | ||
| 814 | test "fixtfdi" { | 830 | test 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)); |
| 816 | 832 | ||
| 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); |
| 819 | 835 | ||
| 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); |
| 823 | 839 | ||
| 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); |
| 828 | 844 | ||
| 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); |
| 831 | 847 | ||
| 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); |
| 836 | 852 | ||
| 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); |
| 853 | 869 | ||
| 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); |
| 858 | 874 | ||
| 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); |
| 861 | 877 | ||
| 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); |
| 866 | 882 | ||
| 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); |
| 870 | 886 | ||
| 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)); |
| 873 | 889 | ||
| 874 | try test__fixtfdi(math.floatMax(f128), math.maxInt(i64)); | 890 | try test_i64_intFromFloat_f128(math.floatMax(f128), math.maxInt(i64)); |
| 875 | } | 891 | } |
| 876 | 892 | ||
| 877 | test "fixunstfdi" { | 893 | test u64_intFromFloat_f128 { |
| 878 | try test__fixunstfdi(0.0, 0); | 894 | try test_u64_intFromFloat_f128(0.0, 0); |
| 879 | 895 | ||
| 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); |
| 894 | 910 | ||
| 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); |
| 897 | 913 | ||
| 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); |
| 900 | 916 | ||
| 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); |
| 903 | 919 | ||
| 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); |
| 906 | 922 | ||
| 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); |
| 913 | 929 | ||
| 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 | } |
| 918 | 934 | ||
| 919 | fn test__fixtfti(a: f128, expected: i128) !void { | 935 | fn 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 | } |
| 923 | 939 | ||
| 924 | fn test__fixunstfti(a: f128, expected: u128) !void { | 940 | fn 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 | } |
| 928 | 944 | ||
| 929 | test "fixtfti" { | 945 | test 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)); |
| 931 | 947 | ||
| 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); |
| 934 | 950 | ||
| 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); |
| 938 | 954 | ||
| 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); |
| 943 | 959 | ||
| 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); |
| 946 | 962 | ||
| 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); |
| 963 | 979 | ||
| 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); |
| 966 | 982 | ||
| 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); |
| 971 | 987 | ||
| 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); |
| 975 | 991 | ||
| 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)); |
| 978 | 994 | ||
| 979 | try test__fixtfti(math.floatMax(f128), math.maxInt(i128)); | 995 | try test_i128_intFromFloat_f128(math.floatMax(f128), math.maxInt(i128)); |
| 980 | } | 996 | } |
| 981 | 997 | ||
| 982 | test "fixunstfti" { | 998 | test u128_intFromFloat_f128 { |
| 983 | try test__fixunstfti(math.inf(f128), 0xffffffffffffffffffffffffffffffff); | 999 | try test_u128_intFromFloat_f128(math.inf(f128), 0xffffffffffffffffffffffffffffffff); |
| 984 | 1000 | ||
| 985 | try test__fixunstfti(0.0, 0); | 1001 | try test_u128_intFromFloat_f128(0.0, 0); |
| 986 | 1002 | ||
| 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); |
| 996 | 1012 | ||
| 997 | try test__fixunstfti(0x1p+128, 0xffffffffffffffffffffffffffffffff); | 1013 | try test_u128_intFromFloat_f128(0x1p+128, 0xffffffffffffffffffffffffffffffff); |
| 998 | 1014 | ||
| 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 | } |
| 1004 | 1020 | ||
| 1005 | fn test__fixunshfti(a: f16, expected: u128) !void { | 1021 | fn 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 | } |
| 1009 | 1025 | ||
| 1010 | test "fixunshfti for f16" { | 1026 | test 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 | } |
| 1014 | 1030 | ||
| 1015 | fn test__fixunsxfti(a: f80, expected: u128) !void { | 1031 | fn 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 | } |
| 1019 | 1035 | ||
| 1020 | test "fixunsxfti for f80" { | 1036 | test 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; |
| 6 | 6 | ||
| 7 | const builtin = @import("builtin"); | 7 | const builtin = @import("builtin"); |
| 8 | const compiler_rt = @import("../compiler_rt.zig"); | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const symbol = @import("../compiler_rt.zig").symbol; | 9 | const symbol = compiler_rt.symbol; |
| 10 | 10 | ||
| 11 | const endian = builtin.cpu.arch.endian(); | 11 | const endian = builtin.cpu.arch.endian(); |
| 12 | 12 |
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; |
| 11 | const expectApproxEqRel = std.testing.expectApproxEqRel; | 11 | const expectApproxEqRel = std.testing.expectApproxEqRel; |
| 12 | 12 | ||
| 13 | const compiler_rt = @import("../compiler_rt.zig"); | 13 | const compiler_rt = @import("../compiler_rt.zig"); |
| 14 | const symbol = @import("../compiler_rt.zig").symbol; | 14 | const symbol = compiler_rt.symbol; |
| 15 | 15 | ||
| 16 | comptime { | 16 | comptime { |
| 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 | } |
| 27 | 24 | ||
| 28 | pub fn __logh(a: f16) callconv(.c) f16 { | 25 | fn __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 | } | ||
| 28 | pub fn log_f16(a: f16) f16 { | ||
| 29 | // TODO: more efficient implementation | 29 | // TODO: more efficient implementation |
| 30 | return @floatCast(logf(a)); | 30 | return @floatCast(log_f32(a)); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub fn logf(x_: f32) callconv(.c) f32 { | 33 | fn 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 | } | ||
| 36 | pub 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 | } |
| 84 | 87 | ||
| 85 | pub fn log(x: f64) callconv(.c) f64 { | 88 | fn 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 | } | ||
| 91 | pub 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 | } |
| 434 | 440 | ||
| 435 | pub fn __logx(a: f80) callconv(.c) f80 { | 441 | fn __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 | } | ||
| 444 | pub fn log_f80(a: f80) f80 { | ||
| 436 | // TODO: more efficient implementation | 445 | // TODO: more efficient implementation |
| 437 | return @floatCast(logq(a)); | 446 | return @floatCast(log_f128(a)); |
| 438 | } | 447 | } |
| 439 | 448 | ||
| 449 | fn 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), 1990 | 453 | /// 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 ulp | 463 | /// <= 0.5 ulp: 99.96%, worst case <= 0.528 ulp |
| 452 | pub fn logq(x: f128) callconv(.c) f128 { | 464 | pub fn log_f128(x: f128) f128 { |
| 453 | const impl = @import("log_f128.zig"); | 465 | const impl = @import("log_f128.zig"); |
| 454 | 466 | ||
| 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 { |
| 626 | 638 | ||
| 627 | pub fn logl(x: c_longdouble) callconv(.c) c_longdouble { | 639 | pub 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 | } |
| 635 | 647 | ||
| 636 | test "logf() special" { | 648 | test "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 | } |
| 647 | 659 | ||
| 648 | test "logf() sanity" { | 660 | test "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 | } |
| 660 | 672 | ||
| 661 | test "logf() boundary" { | 673 | test "logf() boundary" { |
| 662 | try expectEqual(logf(0x1.fffffep+127), 0x1.62e430p+6); // Max input value | 674 | 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 value | 675 | try expectEqual(log_f32(0x1p-149), -0x1.9d1da0p+6); // Min positive input value |
| 664 | try expect(math.isNan(logf(-0x1p-149))); // Min negative input value | 676 | 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 +0 | 677 | 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 -0 | 678 | 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 subnormal | 679 | try expectEqual(log_f32(0x1p-126), -0x1.5d58a0p+6); // First subnormal |
| 668 | try expect(math.isNan(logf(-0x1p-126))); // First negative subnormal | 680 | try expect(math.isNan(log_f32(-0x1p-126))); // First negative subnormal |
| 669 | } | 681 | } |
| 670 | 682 | ||
| 671 | test "log() special" { | 683 | test "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 | } |
| 682 | 694 | ||
| 683 | test "log() sanity" { | 695 | test "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 | } |
| 695 | 707 | ||
| 696 | test "log() boundary" { | 708 | test "log() boundary" { |
| 697 | try expectEqual(log(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value | 709 | 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 value | 710 | try expectEqual(log_f64(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value |
| 699 | try expect(math.isNan(log(-0x1p-1074))); // Min negative input value | 711 | 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 +0 | 712 | 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 -0 | 713 | 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 subnormal | 714 | try expectEqual(log_f64(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal |
| 703 | try expect(math.isNan(log(-0x1p-1022))); // First negative subnormal | 715 | try expect(math.isNan(log_f64(-0x1p-1022))); // First negative subnormal |
| 704 | } | 716 | } |
| 705 | 717 | ||
| 706 | test "logq() special" { | 718 | test "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.9999999999999999999999999999999999 | 722 | // 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 | } |
| 719 | 731 | ||
| 720 | test "logq() boundary" { | 732 | test "logq() boundary" { |
| 721 | try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value | 733 | try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value |
| 722 | try expectEqual(logq(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value | 734 | try expectEqual(log_f128(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value |
| 723 | try expect(math.isNan(logq(-0x1p-16494))); // Min negative input value | 735 | 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 +0 | 736 | 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 -0 | 737 | try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0 |
| 726 | try expectEqual(logq(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal | 738 | try expectEqual(log_f128(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal |
| 727 | try expect(math.isNan(logq(-0x1p-16382))); // First negative subnormal | 739 | try expect(math.isNan(log_f128(-0x1p-16382))); // First negative subnormal |
| 728 | } | 740 | } |
| 729 | 741 | ||
| 730 | test "logq() sanity" { | 742 | test "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 1 | 754 | // 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 | } |
| 27 | 24 | ||
| 28 | pub fn __log10h(a: f16) callconv(.c) f16 { | 25 | fn __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 | } | ||
| 28 | pub fn log10_f16(a: f16) f16 { | ||
| 29 | // TODO: more efficient implementation | 29 | // TODO: more efficient implementation |
| 30 | return @floatCast(log10f(a)); | 30 | return @floatCast(log10_f32(a)); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub fn log10f(x_: f32) callconv(.c) f32 { | 33 | fn 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 | } | ||
| 36 | pub 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 | } |
| 92 | 95 | ||
| 93 | pub fn log10(x_: f64) callconv(.c) f64 { | 96 | fn 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 | } | ||
| 99 | pub 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 | } |
| 167 | 173 | ||
| 168 | pub fn __log10x(a: f80) callconv(.c) f80 { | 174 | fn __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 | } | ||
| 177 | pub fn log10_f80(a: f80) f80 { | ||
| 169 | // TODO: more efficient implementation | 178 | // TODO: more efficient implementation |
| 170 | return @floatCast(log10q(a)); | 179 | return @floatCast(log10_f128(a)); |
| 171 | } | 180 | } |
| 172 | 181 | ||
| 182 | fn 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), 1990 | 186 | /// 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 ulp | 196 | /// <= 0.5 ulp: 99.96%, worst case <= 0.565 ulp |
| 185 | pub fn log10q(x: f128) callconv(.c) f128 { | 197 | pub fn log10_f128(x: f128) f128 { |
| 186 | const impl = @import("log_f128.zig"); | 198 | const impl = @import("log_f128.zig"); |
| 187 | 199 | ||
| 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 { |
| 359 | 371 | ||
| 360 | pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble { | 372 | pub 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 | } |
| 368 | 380 | ||
| 369 | test "log10f() special" { | 381 | test "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 | } |
| 381 | 393 | ||
| 382 | test "log10f() sanity" { | 394 | test "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 bit | 400 | 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 | } |
| 394 | 406 | ||
| 395 | test "log10f() boundary" { | 407 | test "log10f() boundary" { |
| 396 | try expectEqual(log10f(0x1.fffffep+127), 0x1.344136p+5); // Max input value | 408 | 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 value | 409 | try expectEqual(log10_f32(0x1p-149), -0x1.66d3e8p+5); // Min positive input value |
| 398 | try expect(math.isNan(log10f(-0x1p-149))); // Min negative input value | 410 | 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 +0 | 411 | 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 -0 | 412 | 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 subnormal | 413 | try expectEqual(log10_f32(0x1p-126), -0x1.2f7030p+5); // First subnormal |
| 402 | try expect(math.isNan(log10f(-0x1p-126))); // First negative subnormal | 414 | try expect(math.isNan(log10_f32(-0x1p-126))); // First negative subnormal |
| 403 | } | 415 | } |
| 404 | 416 | ||
| 405 | test "log10() special" { | 417 | test "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 | } |
| 417 | 429 | ||
| 418 | test "log10() sanity" { | 430 | test "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 | } |
| 430 | 442 | ||
| 431 | test "log10() boundary" { | 443 | test "log10() boundary" { |
| 432 | try expectEqual(log10(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value | 444 | 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 value | 445 | try expectEqual(log10_f64(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value |
| 434 | try expect(math.isNan(log10(-0x1p-1074))); // Min negative input value | 446 | 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 +0 | 447 | 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 -0 | 448 | 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 subnormal | 449 | try expectEqual(log10_f64(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal |
| 438 | try expect(math.isNan(log10(-0x1p-1022))); // First negative subnormal | 450 | try expect(math.isNan(log10_f64(-0x1p-1022))); // First negative subnormal |
| 439 | } | 451 | } |
| 440 | 452 | ||
| 441 | test "log10q() special" { | 453 | test "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 | } |
| 453 | 465 | ||
| 454 | test "log10q() sanity" { | 466 | test "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 1 | 477 | // 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 | } |
| 473 | 485 | ||
| 474 | test "log10q() boundary" { | 486 | test "log10q() boundary" { |
| 475 | try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value | 487 | try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value |
| 476 | try expectEqual(log10q(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value | 488 | try expectEqual(log10_f128(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value |
| 477 | try expect(math.isNan(log10q(-0x1p-16494))); // Min negative input value | 489 | 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 +0 | 490 | 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 -0 | 491 | 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 subnormal | 492 | try expectEqual(log10_f128(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal |
| 481 | try expect(math.isNan(log10q(-0x1p-16382))); // First negative subnormal | 493 | 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 | } |
| 28 | 25 | ||
| 29 | pub fn __log2h(a: f16) callconv(.c) f16 { | 26 | fn __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 | } | ||
| 29 | pub fn log2_f16(a: f16) f16 { | ||
| 30 | // TODO: more efficient implementation | 30 | // TODO: more efficient implementation |
| 31 | return @floatCast(log2f(a)); | 31 | return @floatCast(log2_f32(a)); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | pub fn log2f(x_: f32) callconv(.c) f32 { | 34 | fn 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 | } | ||
| 37 | pub 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 | } |
| 89 | 92 | ||
| 90 | pub fn log2(x_: f64) callconv(.c) f64 { | 93 | fn 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 | } | ||
| 96 | pub 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 | } |
| 160 | 166 | ||
| 161 | pub fn __log2x(a: f80) callconv(.c) f80 { | 167 | fn __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 | } | ||
| 170 | pub fn log2_f80(a: f80) f80 { | ||
| 162 | // TODO: more efficient implementation | 171 | // TODO: more efficient implementation |
| 163 | return @floatCast(log2q(a)); | 172 | return @floatCast(log2_f128(a)); |
| 164 | } | 173 | } |
| 165 | 174 | ||
| 175 | fn 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), 1990 | 179 | /// 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 ulp | 189 | /// <= 0.5 ulp: 99.86%, worst case <= 0.546 ulp |
| 178 | pub fn log2q(x: f128) callconv(.c) f128 { | 190 | pub fn log2_f128(x: f128) f128 { |
| 179 | const impl = @import("log_f128.zig"); | 191 | const impl = @import("log_f128.zig"); |
| 180 | 192 | ||
| 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 { |
| 351 | 363 | ||
| 352 | pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble { | 364 | pub 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 | } |
| 360 | 372 | ||
| 361 | test "log2f() special" { | 373 | test "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 | } |
| 372 | 384 | ||
| 373 | test "log2f() sanity" { | 385 | test "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 bit | 391 | 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 | } |
| 385 | 397 | ||
| 386 | test "log2f() boundary" { | 398 | test "log2f() boundary" { |
| 387 | try expectEqual(log2f(0x1.fffffep+127), 0x1p+7); // Max input value | 399 | try expectEqual(log2_f32(0x1.fffffep+127), 0x1p+7); // Max input value |
| 388 | try expectEqual(log2f(0x1p-149), -0x1.2ap+7); // Min positive input value | 400 | try expectEqual(log2_f32(0x1p-149), -0x1.2ap+7); // Min positive input value |
| 389 | try expect(math.isNan(log2f(-0x1p-149))); // Min negative input value | 401 | 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 +0 | 402 | 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 -0 | 403 | 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 subnormal | 404 | try expectEqual(log2_f32(0x1p-126), -0x1.f8p+6); // First subnormal |
| 393 | try expect(math.isNan(log2f(-0x1p-126))); // First negative subnormal | 405 | try expect(math.isNan(log2_f32(-0x1p-126))); // First negative subnormal |
| 394 | 406 | ||
| 395 | } | 407 | } |
| 396 | 408 | ||
| 397 | test "log2() special" { | 409 | test "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 | } |
| 408 | 420 | ||
| 409 | test "log2() sanity" { | 421 | test "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 | } |
| 421 | 433 | ||
| 422 | test "log2() boundary" { | 434 | test "log2() boundary" { |
| 423 | try expectEqual(log2(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value | 435 | try expectEqual(log2_f64(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value |
| 424 | try expectEqual(log2(0x1p-1074), -0x1.0c8p+10); // Min positive input value | 436 | try expectEqual(log2_f64(0x1p-1074), -0x1.0c8p+10); // Min positive input value |
| 425 | try expect(math.isNan(log2(-0x1p-1074))); // Min negative input value | 437 | 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 +0 | 438 | 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 -0 | 439 | 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 subnormal | 440 | try expectEqual(log2_f64(0x1p-1022), -0x1.ffp+9); // First subnormal |
| 429 | try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal | 441 | try expect(math.isNan(log2_f64(-0x1p-1022))); // First negative subnormal |
| 430 | } | 442 | } |
| 431 | 443 | ||
| 432 | test "log2q() special" { | 444 | test "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 | } |
| 443 | 455 | ||
| 444 | test "log2q() boundary" { | 456 | test "log2q() boundary" { |
| 445 | try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value | 457 | try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value |
| 446 | try expectEqual(log2q(0x1p-16494), -0x1.01b8p14); // Min positive input value | 458 | try expectEqual(log2_f128(0x1p-16494), -0x1.01b8p14); // Min positive input value |
| 447 | try expect(math.isNan(log2q(-0x1p-16494))); // Min negative input value | 459 | 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 +0 | 460 | 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 -0 | 461 | 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 subnormal | 462 | try expectEqual(log2_f128(0x1p-16382), -0x1.fffp13); // First subnormal |
| 451 | try expect(math.isNan(log2q(-0x1p-16382))); // First negative subnormal | 463 | try expect(math.isNan(log2_f128(-0x1p-16382))); // First negative subnormal |
| 452 | } | 464 | } |
| 453 | 465 | ||
| 454 | test "log2q() sanity" { | 466 | test "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 1 | 473 | // 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; |
| 3 | const isInf = std.math.isInf; | 3 | const isInf = std.math.isInf; |
| 4 | const copysign = std.math.copysign; | 4 | const copysign = std.math.copysign; |
| 5 | 5 | ||
| 6 | pub fn Complex(comptime T: type) type { | 6 | const compiler_rt = @import("../compiler_rt.zig"); |
| 7 | return extern struct { | 7 | const symbol = compiler_rt.symbol; |
| 8 | real: T, | 8 | const Complex = compiler_rt.Complex; |
| 9 | imag: T, | 9 | |
| 10 | }; | 10 | comptime { |
| 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 | |||
| 24 | fn __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 | } | ||
| 30 | pub fn mul_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) { | ||
| 31 | return mulc3(f16, a, b); | ||
| 32 | } | ||
| 33 | |||
| 34 | fn __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 | } | ||
| 40 | pub fn mul_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) { | ||
| 41 | return mulc3(f32, a, b); | ||
| 42 | } | ||
| 43 | |||
| 44 | fn __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 | } | ||
| 50 | pub fn mul_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) { | ||
| 51 | return mulc3(f64, a, b); | ||
| 52 | } | ||
| 53 | |||
| 54 | fn __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 | } | ||
| 60 | pub fn mul_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) { | ||
| 61 | return mulc3(f80, a, b); | ||
| 62 | } | ||
| 63 | |||
| 64 | fn __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 | } | ||
| 70 | pub fn mul_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) { | ||
| 71 | return mulc3(f128, a, b); | ||
| 11 | } | 72 | } |
| 12 | 73 | ||
| 13 | /// Implementation based on Annex G of C17 Standard (N2176) | 74 | /// Implementation based on Annex G of C17 Standard (N2176) |
| 14 | pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Complex(T) { | 75 | inline 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; |
| 19 | 80 | ||
| 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 | |||
| 142 | test { | ||
| 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"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | const Complex = @import("./mulc3.zig").Complex; | 5 | const Complex = @import("../compiler_rt.zig").Complex; |
| 6 | const __mulhc3 = @import("./mulhc3.zig").__mulhc3; | 6 | const impl = @import("mulc3.zig"); |
| 7 | const __mulsc3 = @import("./mulsc3.zig").__mulsc3; | 7 | const mul_cf16 = impl.mul_cf16; |
| 8 | const __muldc3 = @import("./muldc3.zig").__muldc3; | 8 | const mul_cf32 = impl.mul_cf32; |
| 9 | const __mulxc3 = @import("./mulxc3.zig").__mulxc3; | 9 | const mul_cf64 = impl.mul_cf64; |
| 10 | const __multc3 = @import("./multc3.zig").__multc3; | 10 | const mul_cf80 = impl.mul_cf80; |
| 11 | const mul_cf128 = impl.mul_cf128; | ||
| 11 | 12 | ||
| 12 | test "mulc3" { | 13 | test "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 | } |
| 19 | 20 | ||
| 20 | fn testMul(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void { | 21 | fn 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 @@ | ||
| 1 | const mulc3 = @import("./mulc3.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 6 | symbol(&__muldc3, "__muldc3"); | ||
| 7 | } | ||
| 8 | } | ||
| 9 | |||
| 10 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_dmul, "__aeabi_dmul"); | ||
| 8 | } else { | ||
| 9 | symbol(&__muldf3, "__muldf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __muldf3(a: f64, b: f64) callconv(.c) f64 { | ||
| 14 | return mulf3(f64, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const builtin = @import("builtin"); | 3 | const builtin = @import("builtin"); |
| 4 | const compiler_rt = @import("../compiler_rt.zig"); | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 5 | const symbol = compiler_rt.symbol; | ||
| 6 | |||
| 7 | comptime { | ||
| 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 | |||
| 28 | fn __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 | } | ||
| 31 | pub fn mul_f16(a: f16, b: f16) f16 { | ||
| 32 | return mulf3(f16, a, b); | ||
| 33 | } | ||
| 34 | |||
| 35 | fn __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 | } | ||
| 38 | fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 39 | return mul_f32(a, b); | ||
| 40 | } | ||
| 41 | pub fn mul_f32(a: f32, b: f32) f32 { | ||
| 42 | return mulf3(f32, a, b); | ||
| 43 | } | ||
| 44 | |||
| 45 | fn __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 | } | ||
| 48 | fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 49 | return mul_f64(a, b); | ||
| 50 | } | ||
| 51 | pub fn mul_f64(a: f64, b: f64) f64 { | ||
| 52 | return mulf3(f64, a, b); | ||
| 53 | } | ||
| 54 | |||
| 55 | fn __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 | } | ||
| 58 | pub fn mul_f80(a: f80, b: f80) f80 { | ||
| 59 | return mulf3(f80, a, b); | ||
| 60 | } | ||
| 61 | |||
| 62 | fn __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 | } | ||
| 65 | fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | ||
| 66 | c.* = mul_f128(a.*, b.*); | ||
| 67 | } | ||
| 68 | pub fn mul_f128(a: f128, b: f128) f128 { | ||
| 69 | return mulf3(f128, a, b); | ||
| 70 | } | ||
| 5 | 71 | ||
| 6 | /// Ported from: | 72 | /// Ported from: |
| 7 | /// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc | 73 | /// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc |
| 8 | pub inline fn mulf3(comptime T: type, a: T, b: T) T { | 74 | inline 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; |
| 7 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); | 7 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); |
| 8 | const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64); | 8 | const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64); |
| 9 | 9 | ||
| 10 | const __multf3 = @import("multf3.zig").__multf3; | 10 | const impl = @import("mulf3.zig"); |
| 11 | const __mulxf3 = @import("mulxf3.zig").__mulxf3; | 11 | const mul_f16 = impl.mul_f16; |
| 12 | const __muldf3 = @import("muldf3.zig").__muldf3; | 12 | const mul_f32 = impl.mul_f32; |
| 13 | const __mulsf3 = @import("mulsf3.zig").__mulsf3; | 13 | const mul_f64 = impl.mul_f64; |
| 14 | const mul_f80 = impl.mul_f80; | ||
| 15 | const mul_f128 = impl.mul_f128; | ||
| 14 | 16 | ||
| 15 | // return true if equal | 17 | // return true if equal |
| 16 | // use two 64-bit integers instead of one 128-bit integer | 18 | // 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 | } |
| 36 | 38 | ||
| 37 | fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { | 39 | fn 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); |
| 39 | 41 | ||
| 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 | } |
| 50 | test "multf3" { | 52 | test "multf3" { |
| 51 | // qNaN * any = qNaN | 53 | // qNaN * any = qNaN |
| 52 | try test__multf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); | 54 | try test_mul_f128(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); |
| 53 | 55 | ||
| 54 | // NaN * any = NaN | 56 | // 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 = inf | 59 | // inf * any = inf |
| 58 | try test__multf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0); | 60 | try test_mul_f128(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0); |
| 59 | 61 | ||
| 60 | // any * any | 62 | // 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 | ); |
| 67 | 69 | ||
| 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 | ); |
| 74 | 76 | ||
| 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 | ); |
| 81 | 83 | ||
| 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 | ); |
| 88 | 90 | ||
| 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); |
| 90 | 92 | ||
| 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 | ); |
| 104 | 106 | ||
| 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 | } |
| 109 | 111 | ||
| 110 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); | 112 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); |
| 111 | 113 | ||
| 112 | fn test__mulxf3(a: f80, b: f80, expected: u80) !void { | 114 | fn 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); |
| 115 | 117 | ||
| 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 { |
| 124 | 126 | ||
| 125 | test "mulxf3" { | 127 | test "mulxf3" { |
| 126 | // NaN * any = NaN | 128 | // 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))); |
| 129 | 131 | ||
| 130 | // any * NaN = NaN | 132 | // 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))); |
| 133 | 135 | ||
| 134 | // NaN * inf = NaN | 136 | // 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))); |
| 136 | 138 | ||
| 137 | // inf * NaN = NaN | 139 | // 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))); |
| 139 | 141 | ||
| 140 | // inf * inf = inf | 142 | // 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)))); |
| 142 | 144 | ||
| 143 | // inf * -inf = -inf | 145 | // 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)))); |
| 145 | 147 | ||
| 146 | // -inf + inf = -inf | 148 | // -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)))); |
| 148 | 150 | ||
| 149 | // inf * any = inf | 151 | // 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)))); |
| 151 | 153 | ||
| 152 | // any * inf = inf | 154 | // 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)))); |
| 154 | 156 | ||
| 155 | // any * any | 157 | // 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); // exact | 159 | try test_mul_f80(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact |
| 158 | 160 | ||
| 159 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact | 161 | 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 down | 162 | 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 even | 163 | 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 up | 164 | 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); // exact | 165 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact |
| 164 | 166 | ||
| 165 | try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even | 167 | 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 up | 168 | 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 -> normal | 169 | 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 -> normal | 170 | 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 -> denormal | 171 | 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulc3 = @import("./mulc3.zig"); | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__mulhc3, "__mulhc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__mulhf3, "__mulhf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub 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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const mulc3 = @import("./mulc3.zig"); | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 6 | symbol(&__mulsc3, "__mulsc3"); | ||
| 7 | } | ||
| 8 | } | ||
| 9 | |||
| 10 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_fmul, "__aeabi_fmul"); | ||
| 8 | } else { | ||
| 9 | symbol(&__mulsf3, "__mulsf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __mulsf3(a: f32, b: f32) callconv(.c) f32 { | ||
| 14 | return mulf3(f32, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const mulc3 = @import("./mulc3.zig"); | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 13 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __multf3(a: f128, b: f128) callconv(.c) f128 { | ||
| 17 | return mulf3(f128, a, b); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ |
| 1 | const testing = @import("std").testing; | 1 | const testing = @import("std").testing; |
| 2 | 2 | ||
| 3 | const mulv = @import("mulo.zig"); | 3 | const mulv = @import("mulo.zig"); |
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 5 | const symbol = compiler_rt.symbol; | ||
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | symbol(&__mulvsi3, "__mulvsi3"); | 8 | symbol(&__mulvsi3, "__mulvsi3"); |
| ... | @@ -10,7 +11,7 @@ comptime { | ... | @@ -10,7 +11,7 @@ comptime { |
| 10 | pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 { | 11 | pub 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 | } |
| 16 | 17 |
lib/compiler_rt/mulxc3.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulc3 = @import("./mulc3.zig"); | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__mulxc3, "__mulxc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__mulxf3, "__mulxf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub 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 | } |
| 40 | 39 |
lib/compiler_rt/os_version_check.zig-1| ... | @@ -3,7 +3,6 @@ const testing = std.testing; | ... | @@ -3,7 +3,6 @@ const testing = std.testing; |
| 3 | const builtin = @import("builtin"); | 3 | const builtin = @import("builtin"); |
| 4 | const compiler_rt = @import("../compiler_rt.zig"); | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 5 | const symbol = compiler_rt.symbol; | 5 | const symbol = compiler_rt.symbol; |
| 6 | const panic = @import("../compiler_rt.zig").panic; | ||
| 7 | 6 | ||
| 8 | const have_availability_version_check = builtin.os.tag.isDarwin() and | 7 | const 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 => 1 | 1 | //! parity - if number of bits set is even => 0, else => 1 |
| 2 | //! - pariytXi2_generic for big and little endian | 2 | //! - pariytXi2_generic for big and little endian |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | ||
| 4 | 5 | ||
| 5 | comptime { | 6 | comptime { |
| 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". |
| 8 | 8 | ||
| 9 | const symbol = @import("../compiler_rt.zig").symbol; | 9 | const compiler_rt = @import("../compiler_rt.zig"); |
| 10 | const symbol = compiler_rt.symbol; | ||
| 10 | 11 | ||
| 11 | comptime { | 12 | comptime { |
| 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. |
| 5 | 5 | ||
| 6 | const compiler_rt = @import("../compiler_rt.zig"); | 6 | const compiler_rt = @import("../compiler_rt.zig"); |
| 7 | const symbol = @import("../compiler_rt.zig").symbol; | 7 | const symbol = compiler_rt.symbol; |
| 8 | 8 | ||
| 9 | comptime { | 9 | comptime { |
| 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 | } |
| 18 | 20 | ||
| 19 | inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { | 21 | 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,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 | } |
| 34 | 36 | ||
| 35 | pub fn __powihf2(a: f16, b: i32) callconv(.c) f16 { | 37 | fn __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 | } | ||
| 40 | pub fn powi_f16(a: f16, b: i32) f16 { | ||
| 36 | return powiXf2(f16, a, b); | 41 | return powiXf2(f16, a, b); |
| 37 | } | 42 | } |
| 38 | 43 | ||
| 39 | pub fn __powisf2(a: f32, b: i32) callconv(.c) f32 { | 44 | fn __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 | } | ||
| 47 | pub fn powi_f32(a: f32, b: i32) f32 { | ||
| 40 | return powiXf2(f32, a, b); | 48 | return powiXf2(f32, a, b); |
| 41 | } | 49 | } |
| 42 | 50 | ||
| 43 | pub fn __powidf2(a: f64, b: i32) callconv(.c) f64 { | 51 | fn __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 | } | ||
| 54 | pub fn powi_f64(a: f64, b: i32) f64 { | ||
| 44 | return powiXf2(f64, a, b); | 55 | return powiXf2(f64, a, b); |
| 45 | } | 56 | } |
| 46 | 57 | ||
| 47 | pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 { | 58 | fn __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 | } |
| 50 | 61 | pub fn powi_f80(a: f80, b: i32) f80 { | |
| 51 | pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 { | ||
| 52 | return powiXf2(f80, a, b); | 62 | return powiXf2(f80, a, b); |
| 53 | } | 63 | } |
| 54 | 64 | ||
| 65 | fn __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 | } | ||
| 68 | pub fn powi_f128(a: f128, b: i32) f128 { | ||
| 69 | return powiXf2(f128, a, b); | ||
| 70 | } | ||
| 71 | |||
| 55 | test { | 72 | test { |
| 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.c | 2 | // powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c |
| 3 | // powihf2 adapted from powisf2 tests | 3 | // powihf2 adapted from powisf2 tests |
| 4 | 4 | ||
| 5 | const powiXf2 = @import("powiXf2.zig"); | ||
| 6 | const std = @import("std"); | 5 | const std = @import("std"); |
| 7 | const builtin = @import("builtin"); | ||
| 8 | const testing = std.testing; | 6 | const testing = std.testing; |
| 9 | const math = std.math; | 7 | const math = std.math; |
| 10 | 8 | ||
| 11 | fn test__powihf2(a: f16, b: i32, expected: f16) !void { | 9 | const impl = @import("powiXf2.zig"); |
| 12 | const result = powiXf2.__powihf2(a, b); | 10 | |
| 11 | const powi_f16 = impl.powi_f16; | ||
| 12 | const powi_f32 = impl.powi_f32; | ||
| 13 | const powi_f64 = impl.powi_f64; | ||
| 14 | const powi_f80 = impl.powi_f80; | ||
| 15 | const powi_f128 = impl.powi_f128; | ||
| 16 | |||
| 17 | fn 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 | } |
| 15 | 21 | ||
| 16 | fn test__powisf2(a: f32, b: i32, expected: f32) !void { | 22 | fn 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 | } |
| 20 | 26 | ||
| 21 | fn test__powidf2(a: f64, b: i32, expected: f64) !void { | 27 | fn 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 | } |
| 25 | 31 | ||
| 26 | fn test__powitf2(a: f128, b: i32, expected: f128) !void { | 32 | fn 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 | } |
| 30 | 36 | ||
| 31 | fn test__powixf2(a: f80, b: i32, expected: f80) !void { | 37 | fn 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 | } |
| 35 | 41 | ||
| 36 | test "powihf2" { | 42 | test 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); |
| 43 | 49 | ||
| 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); |
| 49 | 55 | ||
| 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); |
| 56 | 62 | ||
| 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); |
| 63 | 69 | ||
| 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); |
| 70 | 76 | ||
| 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); |
| 77 | 83 | ||
| 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 = +inf | 95 | 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); |
| 92 | 98 | ||
| 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 = +inf | 103 | 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 = -inf | 104 | 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); |
| 100 | 106 | ||
| 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 = 1 | 111 | 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); |
| 108 | 114 | ||
| 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); |
| 124 | 130 | ||
| 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); |
| 129 | 135 | ||
| 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); |
| 136 | 142 | ||
| 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 | } |
| 144 | 150 | ||
| 145 | test "powisf2" { | 151 | test 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); |
| 152 | 158 | ||
| 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); |
| 158 | 164 | ||
| 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); |
| 165 | 171 | ||
| 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); |
| 172 | 178 | ||
| 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); |
| 179 | 185 | ||
| 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); |
| 186 | 192 | ||
| 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); |
| 193 | 199 | ||
| 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); |
| 201 | 207 | ||
| 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); |
| 209 | 215 | ||
| 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); |
| 217 | 223 | ||
| 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); |
| 225 | 231 | ||
| 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); |
| 233 | 239 | ||
| 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); |
| 243 | 249 | ||
| 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 | } |
| 249 | 255 | ||
| 250 | test "powidf2" { | 256 | test 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); |
| 257 | 263 | ||
| 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); |
| 263 | 269 | ||
| 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); |
| 270 | 276 | ||
| 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); |
| 277 | 283 | ||
| 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); |
| 284 | 290 | ||
| 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); |
| 291 | 297 | ||
| 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); |
| 298 | 304 | ||
| 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); |
| 306 | 312 | ||
| 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); |
| 314 | 320 | ||
| 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); |
| 322 | 328 | ||
| 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); |
| 330 | 336 | ||
| 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); |
| 338 | 344 | ||
| 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); |
| 343 | 349 | ||
| 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); |
| 348 | 354 | ||
| 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 | } |
| 354 | 360 | ||
| 355 | test "powitf2" { | 361 | test 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); |
| 362 | 368 | ||
| 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); |
| 368 | 374 | ||
| 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); |
| 375 | 381 | ||
| 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); |
| 382 | 388 | ||
| 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); |
| 389 | 395 | ||
| 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); |
| 396 | 402 | ||
| 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); |
| 403 | 409 | ||
| 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); |
| 411 | 417 | ||
| 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); |
| 419 | 425 | ||
| 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); |
| 427 | 433 | ||
| 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); |
| 435 | 441 | ||
| 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); |
| 443 | 449 | ||
| 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); |
| 448 | 454 | ||
| 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); |
| 453 | 459 | ||
| 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 | } |
| 459 | 465 | ||
| 460 | test "powixf2" { | 466 | test 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); |
| 467 | 473 | ||
| 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); |
| 473 | 479 | ||
| 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); |
| 480 | 486 | ||
| 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); |
| 487 | 493 | ||
| 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); |
| 494 | 500 | ||
| 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); |
| 501 | 507 | ||
| 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); |
| 508 | 514 | ||
| 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); |
| 516 | 522 | ||
| 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); |
| 524 | 530 | ||
| 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); |
| 532 | 538 | ||
| 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); |
| 540 | 546 | ||
| 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); |
| 548 | 554 | ||
| 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); |
| 553 | 559 | ||
| 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); |
| 558 | 564 | ||
| 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 | } |
| 27 | 24 | ||
| 28 | pub fn __roundh(x: f16) callconv(.c) f16 { | 25 | fn __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 | } | ||
| 28 | pub fn round_f16(x: f16) f16 { | ||
| 29 | // TODO: more efficient implementation | 29 | // TODO: more efficient implementation |
| 30 | return @floatCast(roundf(x)); | 30 | return @floatCast(round_f32(x)); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub fn roundf(x_: f32) callconv(.c) f32 { | 33 | fn 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 | } | ||
| 36 | pub fn round_f32(x_: f32) f32 { | ||
| 34 | const f32_toint = 1.0 / math.floatEps(f32); | 37 | const f32_toint = 1.0 / math.floatEps(f32); |
| 35 | 38 | ||
| 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 | } |
| 67 | 70 | ||
| 68 | pub fn round(x_: f64) callconv(.c) f64 { | 71 | fn 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 | } | ||
| 74 | pub fn round_f64(x_: f64) f64 { | ||
| 69 | const f64_toint = 1.0 / math.floatEps(f64); | 75 | const f64_toint = 1.0 / math.floatEps(f64); |
| 70 | 76 | ||
| 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 | } |
| 102 | 108 | ||
| 103 | pub fn __roundx(x: f80) callconv(.c) f80 { | 109 | fn __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 | } | ||
| 112 | pub fn round_f80(x: f80) f80 { | ||
| 104 | // TODO: more efficient implementation | 113 | // TODO: more efficient implementation |
| 105 | return @floatCast(roundq(x)); | 114 | return @floatCast(round_f128(x)); |
| 106 | } | 115 | } |
| 107 | 116 | ||
| 108 | pub fn roundq(x_: f128) callconv(.c) f128 { | 117 | fn 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 | } | ||
| 120 | pub fn round_f128(x_: f128) f128 { | ||
| 109 | const f128_toint = 1.0 / math.floatEps(f128); | 121 | const f128_toint = 1.0 / math.floatEps(f128); |
| 110 | 122 | ||
| 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 { |
| 142 | 154 | ||
| 143 | pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble { | 155 | pub 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 | } |
| 151 | 163 | ||
| 152 | test "round32" { | 164 | test 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))); |
| 158 | 170 | try expect(math.isNegativeZero(round_f16(-0.2))); | |
| 159 | test "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 | } |
| 165 | 177 | ||
| 166 | test "round128" { | 178 | test 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 | } |
| 172 | 191 | ||
| 173 | test "round32.special" { | 192 | test 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 | } |
| 180 | 205 | ||
| 181 | test "round64.special" { | 206 | test 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 | } |
| 188 | 219 | ||
| 189 | test "round128.special" { | 220 | test 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; |
| 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; | 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; |
| 14 | 14 | ||
| 15 | const compiler_rt = @import("../compiler_rt.zig"); | 15 | const compiler_rt = @import("../compiler_rt.zig"); |
| 16 | const symbol = @import("../compiler_rt.zig").symbol; | 16 | const symbol = compiler_rt.symbol; |
| 17 | const trig = @import("trig.zig"); | 17 | const trig = @import("trig.zig"); |
| 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; | 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; |
| 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; | 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; |
| 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; | 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 21 | 21 | ||
| 22 | comptime { | 22 | comptime { |
| 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 | } |
| 34 | 31 | ||
| 35 | pub fn sinh(x: f16) callconv(.c) f16 { | 32 | fn __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 | } | ||
| 35 | pub fn sin_f16(x: f16) f16 { | ||
| 36 | // TODO: more efficient implementation | 36 | // TODO: more efficient implementation |
| 37 | return @floatCast(sinf(x)); | 37 | return @floatCast(sin_f32(x)); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | pub fn sinf(x: f32) callconv(.c) f32 { | 40 | fn 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 | } | ||
| 43 | pub 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, 0x54442D18 | 45 | const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 43 | const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 | 46 | 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 | } |
| 100 | 103 | ||
| 101 | pub fn sin(x: f64) callconv(.c) f64 { | 104 | fn 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 | } | ||
| 107 | pub 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; |
| 104 | 110 | ||
| ... | @@ -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 | } |
| 135 | 141 | ||
| 136 | fn sinx(x: f80) callconv(.c) f80 { | 142 | fn __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 | } | ||
| 145 | pub 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 | } |
| 162 | 171 | ||
| 163 | pub fn sinq(x: f128) callconv(.c) f128 { | 172 | fn 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 | } | ||
| 175 | pub 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 { |
| 189 | 201 | ||
| 190 | pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble { | 202 | pub 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 | } |
| 198 | 210 | ||
| 199 | fn testSinSpecial(comptime T: type) !void { | 211 | fn 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 | }; |
| 207 | 220 | ||
| 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 { |
| 214 | 227 | ||
| 215 | test "sin32.normal" { | 228 | test "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 | } |
| 225 | 238 | ||
| 226 | test "sin32.special" { | 239 | test "sin32.special" { |
| ... | @@ -229,13 +242,13 @@ test "sin32.special" { | ... | @@ -229,13 +242,13 @@ test "sin32.special" { |
| 229 | 242 | ||
| 230 | test "sin64.normal" { | 243 | test "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 | } |
| 240 | 253 | ||
| 241 | test "sin64.special" { | 254 | test "sin64.special" { |
| ... | @@ -244,13 +257,13 @@ test "sin64.special" { | ... | @@ -244,13 +257,13 @@ test "sin64.special" { |
| 244 | 257 | ||
| 245 | test "sin80.normal" { | 258 | test "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 | } |
| 255 | 268 | ||
| 256 | test "sin80.special" { | 269 | test "sin80.special" { |
| ... | @@ -259,13 +272,13 @@ test "sin80.special" { | ... | @@ -259,13 +272,13 @@ test "sin80.special" { |
| 259 | 272 | ||
| 260 | test "sin128.normal" { | 273 | test "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 | } |
| 270 | 283 | ||
| 271 | test "sin128.special" { | 284 | test "sin128.special" { |
| ... | @@ -274,10 +287,10 @@ test "sin128.special" { | ... | @@ -274,10 +287,10 @@ test "sin128.special" { |
| 274 | 287 | ||
| 275 | test "sin32 #9901" { | 288 | test "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 | } |
| 279 | 292 | ||
| 280 | test "sin64 #9901" { | 293 | test "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 | } |
| 27 | 24 | ||
| 28 | pub fn sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void { | 25 | fn 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 | } | ||
| 30 | pub fn sincos_f16(x: f16) struct { f16, f16 } { | ||
| 29 | // TODO: more efficient implementation | 31 | // 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 | } |
| 36 | 35 | ||
| 37 | pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | 36 | fn 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 | } | ||
| 41 | pub fn sincos_f32(x: f32) struct { f32, f32 } { | ||
| 38 | const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 | 42 | const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 39 | const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 | 43 | const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| 40 | const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 | 44 | 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 | } |
| 67 | 67 | ||
| 68 | // |x| ~<= 5*pi/4 | 68 | // |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/4 | 70 | // |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 +0 | 78 | // -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 | } |
| 86 | 84 | ||
| 87 | // |x| ~<= 9*pi/4 | 85 | // |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/4 | 87 | // |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 | } |
| 104 | 100 | ||
| 105 | // sin(Inf or NaN) is NaN | 101 | // 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 | } |
| 112 | 106 | ||
| 113 | // general argument reduction needed | 107 | // 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 | } |
| 137 | 119 | ||
| 138 | pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { | 120 | fn 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 | } | ||
| 125 | pub 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; |
| 140 | 127 | ||
| 141 | // |x| ~< pi/4 | 128 | // |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 | } |
| 161 | 144 | ||
| 162 | // sincos(Inf or NaN) is NaN | 145 | // 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 | } |
| 169 | 150 | ||
| 170 | // argument reduction needed | 151 | // 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 | } |
| 194 | 163 | ||
| 195 | pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { | 164 | fn 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 | } | ||
| 169 | pub 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 | } |
| 203 | 175 | ||
| 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!=0 | 182 | // 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 | } |
| 219 | 187 | ||
| 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 | } |
| 243 | 199 | ||
| 244 | pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { | 200 | fn 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 | } | ||
| 205 | pub 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 | } |
| 252 | 211 | ||
| 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!=0 | 218 | // 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 | } |
| 268 | 223 | ||
| 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 | } |
| 292 | 235 | ||
| 293 | pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void { | 236 | pub 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 | } |
| 301 | 244 | ||
| 302 | fn testSincosSpecial(comptime T: type) !void { | 245 | fn 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 | }; |
| 310 | 254 | ||
| 311 | var s: T = undefined; | 255 | var s: T = undefined; |
| 312 | var c: T = undefined; | 256 | var c: T = undefined; |
| 313 | 257 | ||
| 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); |
| 317 | 261 | ||
| 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); |
| 321 | 265 | ||
| 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)); |
| 325 | 269 | ||
| 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)); |
| 329 | 273 | ||
| 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; |
| 339 | 283 | ||
| 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); |
| 343 | 287 | ||
| 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); |
| 347 | 291 | ||
| 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); |
| 351 | 295 | ||
| 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); |
| 355 | 299 | ||
| 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); |
| 359 | 303 | ||
| 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); |
| 363 | 307 | ||
| 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; |
| 377 | 321 | ||
| 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); |
| 381 | 325 | ||
| 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); |
| 385 | 329 | ||
| 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); |
| 389 | 333 | ||
| 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); |
| 393 | 337 | ||
| 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); |
| 397 | 341 | ||
| 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); |
| 401 | 345 | ||
| 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; |
| 415 | 359 | ||
| 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); |
| 419 | 363 | ||
| 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); |
| 423 | 367 | ||
| 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); |
| 427 | 371 | ||
| 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); |
| 431 | 375 | ||
| 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); |
| 435 | 379 | ||
| 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); |
| 439 | 383 | ||
| 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; |
| 453 | 397 | ||
| 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); |
| 457 | 401 | ||
| 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); |
| 461 | 405 | ||
| 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); |
| 465 | 409 | ||
| 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); |
| 469 | 413 | ||
| 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); |
| 473 | 417 | ||
| 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); |
| 477 | 421 | ||
| 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 | } |
| 30 | 28 | ||
| 31 | pub fn __sqrth(x: f16) callconv(.c) f16 { | 29 | fn __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 | } | ||
| 32 | pub 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; |
| 34 | 35 | ||
| ... | @@ -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 | } |
| 95 | 96 | ||
| 96 | pub fn sqrtf(x: f32) callconv(.c) f32 { | 97 | fn 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 | } | ||
| 100 | pub fn sqrt_f32(x: f32) f32 { | ||
| 97 | var ix: u32 = @bitCast(x); | 101 | var ix: u32 = @bitCast(x); |
| 98 | 102 | ||
| 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 | } |
| 149 | 153 | ||
| 150 | pub fn sqrt(x: f64) callconv(.c) f64 { | 154 | fn 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 | } | ||
| 157 | pub 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; |
| 153 | 160 | ||
| ... | @@ -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 | } |
| 286 | 293 | ||
| 287 | pub fn __sqrtx(x: f80) callconv(.c) f80 { | 294 | fn __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 | } | ||
| 297 | pub 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; |
| 290 | 300 | ||
| ... | @@ -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 | } |
| 383 | 393 | ||
| 384 | pub fn sqrtq(x: f128) callconv(.c) f128 { | 394 | fn 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 | } | ||
| 397 | pub 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; |
| 387 | 400 | ||
| ... | @@ -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 { |
| 483 | 496 | ||
| 484 | pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble { | 497 | pub 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 | } |
| 492 | 505 | ||
| ... | @@ -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 | } |
| 547 | 560 | ||
| 548 | test "__sqrth" { | 561 | test "sqrt_f16" { |
| 549 | // sqrt(±0) is ±0 | 562 | // 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 finite | 565 | // 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)=2 | 567 | // 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±ulp | 569 | // 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-zero | 573 | // 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-zero | 575 | // 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 inf | 577 | // 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 nan | 579 | // 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 nan | 581 | // 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 arguments | 585 | // 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 | } |
| 584 | 597 | ||
| 585 | test "sqrtf" { | 598 | test "sqrt_f32" { |
| 586 | // sqrt(±0) is ±0 | 599 | // 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 finite | 602 | // 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)=2 | 604 | // 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±ulp | 606 | // 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-zero | 610 | // 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-zero | 612 | // 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 inf | 614 | // 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 nan | 616 | // 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 nan | 618 | // 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 arguments | 622 | // 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 | } |
| 621 | 634 | ||
| 622 | test "sqrt" { | 635 | test "sqrt_f64" { |
| 623 | // sqrt(±0) is ±0 | 636 | // 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 finite | 639 | // 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)=2 | 641 | // 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±ulp | 643 | // 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-zero | 647 | // 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-zero | 649 | // 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 inf | 651 | // 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 nan | 653 | // 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 nan | 655 | // 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 arguments | 659 | // 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 | } |
| 658 | 671 | ||
| 659 | test "__sqrtx" { | 672 | test "__sqrtx" { |
| 660 | // sqrt(±0) is ±0 | 673 | // 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 finite | 676 | // 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)=2 | 678 | // 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±ulp | 680 | // 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-zero | 684 | // 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-zero | 686 | // 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 inf | 688 | // 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 nan | 690 | // 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 nan | 692 | // 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 arguments | 696 | // 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 | } |
| 695 | 708 | ||
| 696 | test "sqrtq" { | 709 | test "sqrt_f128" { |
| 697 | // sqrt(±0) is ±0 | 710 | // 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 finite | 713 | // 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)=2 | 715 | // 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±ulp | 717 | // 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-zero | 721 | // 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-zero | 723 | // 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 inf | 725 | // 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 nan | 727 | // 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 nan | 729 | // 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 arguments | 733 | // 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const addf3 = @import("./addf3.zig").addf3; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_dsub, "__aeabi_dsub"); | ||
| 8 | } else { | ||
| 9 | symbol(&__subdf3, "__subdf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __subdf3(a: f64, b: f64) callconv(.c) f64 { | ||
| 14 | return sub(a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 18 | return sub(a, b); | ||
| 19 | } | ||
| 20 | |||
| 21 | inline 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__subhf3, "__subhf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_fsub, "__aeabi_fsub"); | ||
| 8 | } else { | ||
| 9 | symbol(&__subsf3, "__subsf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __subsf3(a: f32, b: f32) callconv(.c) f32 { | ||
| 14 | return sub(a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 18 | return sub(a, b); | ||
| 19 | } | ||
| 20 | |||
| 21 | inline 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __subtf3(a: f128, b: f128) callconv(.c) f128 { | ||
| 17 | return sub(a, b); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | ||
| 21 | c.* = sub(a.*, b.*); | ||
| 22 | } | ||
| 23 | |||
| 24 | inline 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 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const testing = @import("std").testing; | 1 | const testing = @import("std").testing; |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 3 | 4 | ||
| 4 | comptime { | 5 | comptime { |
| 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 the | 11 | // 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 | } |
| 15 | 16 |
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 the | 11 | // 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 | } |
| 16 | 16 |
lib/compiler_rt/subxf3.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__subxf3, "__subxf3"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __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; |
| 21 | 21 | ||
| 22 | const arch = builtin.cpu.arch; | 22 | const arch = builtin.cpu.arch; |
| 23 | const compiler_rt = @import("../compiler_rt.zig"); | 23 | const compiler_rt = @import("../compiler_rt.zig"); |
| 24 | const symbol = @import("../compiler_rt.zig").symbol; | 24 | const symbol = compiler_rt.symbol; |
| 25 | 25 | ||
| 26 | comptime { | 26 | comptime { |
| 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 | } |
| 37 | 34 | ||
| 38 | pub fn tanh(x: f16) callconv(.c) f16 { | 35 | fn __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 | } | ||
| 38 | pub fn tan_f16(x: f16) f16 { | ||
| 39 | // TODO: more efficient implementation | 39 | // TODO: more efficient implementation |
| 40 | return @floatCast(tanf(x)); | 40 | return @floatCast(tan_f32(x)); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | pub fn tanf(x: f32) callconv(.c) f32 { | 43 | fn 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 | } | ||
| 46 | pub 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, 0x54442D18 | 48 | const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 46 | const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 | 49 | 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 | } |
| 92 | 95 | ||
| 93 | pub fn tan(x: f64) callconv(.c) f64 { | 96 | fn 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 | } | ||
| 99 | pub 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; |
| 96 | 102 | ||
| ... | @@ -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 | } |
| 122 | 128 | ||
| 123 | pub fn tanx(x: f80) callconv(.c) f80 { | 129 | fn __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 | } | ||
| 132 | pub 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 | } |
| 143 | 152 | ||
| 144 | pub fn tanq(x: f128) callconv(.c) f128 { | 153 | fn 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 | } | ||
| 156 | pub 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 { |
| 164 | 176 | ||
| 165 | pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble { | 177 | pub 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 | } |
| 173 | 185 | ||
| 174 | fn testTanNormal(comptime T: type) !void { | 186 | fn 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; |
| 181 | 196 | ||
| ... | @@ -189,11 +204,12 @@ fn testTanNormal(comptime T: type) !void { | ... | @@ -189,11 +204,12 @@ fn testTanNormal(comptime T: type) !void { |
| 189 | 204 | ||
| 190 | fn testTanSpecial(comptime T: type) !void { | 205 | fn 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 | }; |
| 198 | 214 | ||
| 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" { |
| 214 | test "tan80.normal" { | 230 | test "tan80.normal" { |
| 215 | const epsilon = math.floatEps(f80); | 231 | const epsilon = math.floatEps(f80); |
| 216 | 232 | ||
| 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 | } |
| 224 | 240 | ||
| 225 | test "tan128.normal" { | 241 | test "tan128.normal" { |
| 226 | const epsilon = math.floatEps(f128); | 242 | const epsilon = math.floatEps(f128); |
| 227 | 243 | ||
| 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 | } |
| 235 | 251 | ||
| 236 | test "tan32.special" { | 252 | test "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 | } |
| 26 | 23 | ||
| 27 | pub fn __trunch(x: f16) callconv(.c) f16 { | 24 | fn __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 | } | ||
| 27 | pub fn trunc_f16(x: f16) f16 { | ||
| 28 | // TODO: more efficient implementation | 28 | // TODO: more efficient implementation |
| 29 | return @floatCast(truncf(x)); | 29 | return @floatCast(trunc_f32(x)); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | pub fn truncf(x: f32) callconv(.c) f32 { | 32 | fn 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 | } | ||
| 35 | pub 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 | } |
| 52 | 55 | ||
| 53 | pub fn trunc(x: f64) callconv(.c) f64 { | 56 | fn 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 | } | ||
| 59 | pub 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 | } |
| 73 | 79 | ||
| 74 | pub fn __truncx(x: f80) callconv(.c) f80 { | 80 | fn __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 | } | ||
| 83 | pub fn trunc_f80(x: f80) f80 { | ||
| 75 | // TODO: more efficient implementation | 84 | // TODO: more efficient implementation |
| 76 | return @floatCast(truncq(x)); | 85 | return @floatCast(trunc_f128(x)); |
| 77 | } | 86 | } |
| 78 | 87 | ||
| 79 | pub fn truncq(x: f128) callconv(.c) f128 { | 88 | fn 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 | } | ||
| 91 | pub 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 { |
| 99 | 111 | ||
| 100 | pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble { | 112 | pub 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 | } |
| 108 | 120 | ||
| 109 | test "trunc32" { | 121 | test 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))); |
| 114 | 126 | try expect(math.isPositiveZero(trunc_f16(0.0))); | |
| 115 | test "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 | } |
| 120 | 132 | ||
| 121 | test "trunc128" { | 133 | test 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 | } |
| 126 | 144 | ||
| 127 | test "trunc32.special" { | 145 | test trunc_f64 { |
| 128 | try expect(truncf(0.0) == 0.0); // 0x3F800000 | 146 | 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 | } |
| 134 | 156 | ||
| 135 | test "trunc64.special" { | 157 | test 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 | } |
| 142 | 168 | ||
| 143 | test "trunc128.special" { | 169 | test 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const truncf = @import("./truncf.zig").truncf; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_d2h, "__aeabi_d2h"); | ||
| 8 | } | ||
| 9 | symbol(&__truncdfhf2, "__truncdfhf2"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __truncdfhf2(a: f64) callconv(.c) compiler_rt.F16T(f64) { | ||
| 13 | return @bitCast(truncf(f16, f64, a)); | ||
| 14 | } | ||
| 15 | |||
| 16 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const truncf = @import("./truncf.zig").truncf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_d2f, "__aeabi_d2f"); | ||
| 8 | } else { | ||
| 9 | symbol(&__truncdfsf2, "__truncdfsf2"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __truncdfsf2(a: f64) callconv(.c) f32 { | ||
| 14 | return truncf(f32, f64, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | |||
| 6 | comptime { | ||
| 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 | |||
| 61 | fn __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 | } | ||
| 64 | fn __aeabi_f2h(a: u32) callconv(.{ .arm_aapcs = .{} }) u16 { | ||
| 65 | return @bitCast(f16_floatCast_f32(@bitCast(a))); | ||
| 66 | } | ||
| 67 | pub fn f16_floatCast_f32(a: f32) f16 { | ||
| 68 | return truncf(f16, f32, a); | ||
| 69 | } | ||
| 70 | |||
| 71 | fn __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 | } | ||
| 74 | fn __aeabi_d2h(a: u64) callconv(.{ .arm_aapcs = .{} }) u16 { | ||
| 75 | return @bitCast(f16_floatCast_f64(@bitCast(a))); | ||
| 76 | } | ||
| 77 | pub fn f16_floatCast_f64(a: f64) f16 { | ||
| 78 | return truncf(f16, f64, a); | ||
| 79 | } | ||
| 80 | |||
| 81 | fn __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 | } | ||
| 84 | pub fn f16_floatCast_f80(a: f80) f16 { | ||
| 85 | return trunc_f80(f16, a); | ||
| 86 | } | ||
| 87 | |||
| 88 | fn __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 | } | ||
| 91 | pub fn f16_floatCast_f128(a: f128) f16 { | ||
| 92 | return truncf(f16, f128, a); | ||
| 93 | } | ||
| 94 | |||
| 95 | fn __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 | } | ||
| 98 | fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 99 | return f32_floatCast_f64(a); | ||
| 100 | } | ||
| 101 | pub fn f32_floatCast_f64(a: f64) f32 { | ||
| 102 | return truncf(f32, f64, a); | ||
| 103 | } | ||
| 104 | |||
| 105 | fn __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 | } | ||
| 108 | pub fn f32_floatCast_f80(a: f80) f32 { | ||
| 109 | return trunc_f80(f32, a); | ||
| 110 | } | ||
| 111 | |||
| 112 | fn __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 | } | ||
| 115 | fn _Qp_qtos(a: *const f128) callconv(.c) f32 { | ||
| 116 | return f32_floatCast_f128(a.*); | ||
| 117 | } | ||
| 118 | pub fn f32_floatCast_f128(a: f128) f32 { | ||
| 119 | return truncf(f32, f128, a); | ||
| 120 | } | ||
| 121 | |||
| 122 | fn __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 | } | ||
| 125 | pub fn f64_floatCast_f80(a: f80) f64 { | ||
| 126 | return trunc_f80(f64, a); | ||
| 127 | } | ||
| 128 | |||
| 129 | fn __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 | } | ||
| 132 | fn _Qp_qtod(a: *const f128) callconv(.c) f64 { | ||
| 133 | return f64_floatCast_f128(a.*); | ||
| 134 | } | ||
| 135 | pub fn f64_floatCast_f128(a: f128) f64 { | ||
| 136 | return truncf(f64, f128, a); | ||
| 137 | } | ||
| 138 | |||
| 139 | fn __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 | } | ||
| 142 | pub 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 | |||
| 201 | inline 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 | } |
| 101 | 299 | ||
| 102 | pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t { | 300 | inline 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 bit | 302 | 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 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const testing = std.testing; | 2 | const testing = std.testing; |
| 3 | 3 | ||
| 4 | const __truncsfhf2 = @import("truncsfhf2.zig").__truncsfhf2; | 4 | const impl = @import("truncf.zig"); |
| 5 | const __truncdfhf2 = @import("truncdfhf2.zig").__truncdfhf2; | ||
| 6 | const __truncdfsf2 = @import("truncdfsf2.zig").__truncdfsf2; | ||
| 7 | const __trunctfhf2 = @import("trunctfhf2.zig").__trunctfhf2; | ||
| 8 | const __trunctfsf2 = @import("trunctfsf2.zig").__trunctfsf2; | ||
| 9 | const __trunctfdf2 = @import("trunctfdf2.zig").__trunctfdf2; | ||
| 10 | const __trunctfxf2 = @import("trunctfxf2.zig").__trunctfxf2; | ||
| 11 | |||
| 12 | fn test__truncsfhf2(a: u32, expected: u16) !void { | ||
| 13 | const actual: u16 = @bitCast(__truncsfhf2(@bitCast(a))); | ||
| 14 | |||
| 15 | if (actual == expected) { | ||
| 16 | return; | ||
| 17 | } | ||
| 18 | 5 | ||
| 19 | return error.TestFailure; | 6 | const f16_floatCast_f32 = impl.f16_floatCast_f32; |
| 7 | const f16_floatCast_f64 = impl.f16_floatCast_f64; | ||
| 8 | const f16_floatCast_f80 = impl.f16_floatCast_f80; | ||
| 9 | const f16_floatCast_f128 = impl.f16_floatCast_f128; | ||
| 10 | |||
| 11 | const f32_floatCast_f64 = impl.f32_floatCast_f64; | ||
| 12 | const f32_floatCast_f80 = impl.f32_floatCast_f80; | ||
| 13 | const f32_floatCast_f128 = impl.f32_floatCast_f128; | ||
| 14 | |||
| 15 | const f64_floatCast_f80 = impl.f64_floatCast_f80; | ||
| 16 | const f64_floatCast_f128 = impl.f64_floatCast_f128; | ||
| 17 | |||
| 18 | const f80_floatCast_f128 = impl.f80_floatCast_f128; | ||
| 19 | |||
| 20 | fn 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 | } |
| 21 | 24 | ||
| 22 | test "truncsfhf2" { | 25 | test f16_floatCast_f32 { |
| 23 | try test__truncsfhf2(0x7fc00000, 0x7e00); // qNaN | 26 | try test_f16_floatCast_f32(0x7fc00000, 0x7e00); // qNaN |
| 24 | try test__truncsfhf2(0x7fe00000, 0x7f00); // sNaN | 27 | try test_f16_floatCast_f32(0x7fe00000, 0x7f00); // sNaN |
| 25 | 28 | ||
| 26 | try test__truncsfhf2(0, 0); // 0 | 29 | try test_f16_floatCast_f32(0, 0); // 0 |
| 27 | try test__truncsfhf2(0x80000000, 0x8000); // -0 | 30 | try test_f16_floatCast_f32(0x80000000, 0x8000); // -0 |
| 28 | 31 | ||
| 29 | try test__truncsfhf2(0x7f800000, 0x7c00); // inf | 32 | try test_f16_floatCast_f32(0x7f800000, 0x7c00); // inf |
| 30 | try test__truncsfhf2(0xff800000, 0xfc00); // -inf | 33 | try test_f16_floatCast_f32(0xff800000, 0xfc00); // -inf |
| 31 | 34 | ||
| 32 | try test__truncsfhf2(0x477ff000, 0x7c00); // 65520 -> inf | 35 | try test_f16_floatCast_f32(0x477ff000, 0x7c00); // 65520 -> inf |
| 33 | try test__truncsfhf2(0xc77ff000, 0xfc00); // -65520 -> -inf | 36 | try test_f16_floatCast_f32(0xc77ff000, 0xfc00); // -65520 -> -inf |
| 34 | 37 | ||
| 35 | try test__truncsfhf2(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf | 38 | try test_f16_floatCast_f32(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf |
| 36 | try test__truncsfhf2(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf | 39 | try test_f16_floatCast_f32(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf |
| 37 | 40 | ||
| 38 | try test__truncsfhf2(0x38800000, 0x0400); // normal (min), 2**-14 | 41 | try test_f16_floatCast_f32(0x38800000, 0x0400); // normal (min), 2**-14 |
| 39 | try test__truncsfhf2(0xb8800000, 0x8400); // normal (min), -2**-14 | 42 | try test_f16_floatCast_f32(0xb8800000, 0x8400); // normal (min), -2**-14 |
| 40 | 43 | ||
| 41 | try test__truncsfhf2(0x477fe000, 0x7bff); // normal (max), 65504 | 44 | try test_f16_floatCast_f32(0x477fe000, 0x7bff); // normal (max), 65504 |
| 42 | try test__truncsfhf2(0xc77fe000, 0xfbff); // normal (max), -65504 | 45 | try test_f16_floatCast_f32(0xc77fe000, 0xfbff); // normal (max), -65504 |
| 43 | 46 | ||
| 44 | try test__truncsfhf2(0x477fe100, 0x7bff); // normal, 65505 -> 65504 | 47 | try test_f16_floatCast_f32(0x477fe100, 0x7bff); // normal, 65505 -> 65504 |
| 45 | try test__truncsfhf2(0xc77fe100, 0xfbff); // normal, -65505 -> -65504 | 48 | try test_f16_floatCast_f32(0xc77fe100, 0xfbff); // normal, -65505 -> -65504 |
| 46 | 49 | ||
| 47 | try test__truncsfhf2(0x477fef00, 0x7bff); // normal, 65519 -> 65504 | 50 | try test_f16_floatCast_f32(0x477fef00, 0x7bff); // normal, 65519 -> 65504 |
| 48 | try test__truncsfhf2(0xc77fef00, 0xfbff); // normal, -65519 -> -65504 | 51 | try test_f16_floatCast_f32(0xc77fef00, 0xfbff); // normal, -65519 -> -65504 |
| 49 | 52 | ||
| 50 | try test__truncsfhf2(0x3f802000, 0x3c01); // normal, 1 + 2**-10 | 53 | try test_f16_floatCast_f32(0x3f802000, 0x3c01); // normal, 1 + 2**-10 |
| 51 | try test__truncsfhf2(0xbf802000, 0xbc01); // normal, -1 - 2**-10 | 54 | try test_f16_floatCast_f32(0xbf802000, 0xbc01); // normal, -1 - 2**-10 |
| 52 | 55 | ||
| 53 | try test__truncsfhf2(0x3eaaa000, 0x3555); // normal, approx. 1/3 | 56 | try test_f16_floatCast_f32(0x3eaaa000, 0x3555); // normal, approx. 1/3 |
| 54 | try test__truncsfhf2(0xbeaaa000, 0xb555); // normal, approx. -1/3 | 57 | try test_f16_floatCast_f32(0xbeaaa000, 0xb555); // normal, approx. -1/3 |
| 55 | 58 | ||
| 56 | try test__truncsfhf2(0x40490fdb, 0x4248); // normal, 3.1415926535 | 59 | try test_f16_floatCast_f32(0x40490fdb, 0x4248); // normal, 3.1415926535 |
| 57 | try test__truncsfhf2(0xc0490fdb, 0xc248); // normal, -3.1415926535 | 60 | try test_f16_floatCast_f32(0xc0490fdb, 0xc248); // normal, -3.1415926535 |
| 58 | 61 | ||
| 59 | try test__truncsfhf2(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12 | 62 | try test_f16_floatCast_f32(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12 |
| 60 | 63 | ||
| 61 | try test__truncsfhf2(0x3f800000, 0x3c00); // normal, 1 | 64 | try test_f16_floatCast_f32(0x3f800000, 0x3c00); // normal, 1 |
| 62 | try test__truncsfhf2(0x38800000, 0x0400); // normal, 0x1.0p-14 | 65 | try test_f16_floatCast_f32(0x38800000, 0x0400); // normal, 0x1.0p-14 |
| 63 | 66 | ||
| 64 | try test__truncsfhf2(0x33800000, 0x0001); // denormal (min), 2**-24 | 67 | try test_f16_floatCast_f32(0x33800000, 0x0001); // denormal (min), 2**-24 |
| 65 | try test__truncsfhf2(0xb3800000, 0x8001); // denormal (min), -2**-24 | 68 | try test_f16_floatCast_f32(0xb3800000, 0x8001); // denormal (min), -2**-24 |
| 66 | 69 | ||
| 67 | try test__truncsfhf2(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24 | 70 | try test_f16_floatCast_f32(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24 |
| 68 | try test__truncsfhf2(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24 | 71 | try test_f16_floatCast_f32(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24 |
| 69 | 72 | ||
| 70 | try test__truncsfhf2(0x35800000, 0x0010); // denormal, 0x1.0p-20 | 73 | try test_f16_floatCast_f32(0x35800000, 0x0010); // denormal, 0x1.0p-20 |
| 71 | try test__truncsfhf2(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24 | 74 | try test_f16_floatCast_f32(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24 |
| 72 | try test__truncsfhf2(0x33000000, 0x0000); // 0x1.0p-25 -> zero | 75 | try test_f16_floatCast_f32(0x33000000, 0x0000); // 0x1.0p-25 -> zero |
| 73 | } | 76 | } |
| 74 | 77 | ||
| 75 | fn test__truncdfhf2(a: f64, expected: u16) void { | 78 | fn 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)); |
| 77 | 80 | ||
| 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 | } |
| 87 | 90 | return error.TestFailure; | |
| 88 | @panic("__truncdfhf2 test failure"); | ||
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | fn test__truncdfhf2_raw(a: u64, expected: u16) void { | 93 | fn 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))); |
| 93 | 95 | try testing.expect(actual == expected); | |
| 94 | if (actual == expected) { | ||
| 95 | return; | ||
| 96 | } | ||
| 97 | |||
| 98 | @panic("__truncdfhf2 test failure"); | ||
| 99 | } | 96 | } |
| 100 | 97 | ||
| 101 | test "truncdfhf2" { | 98 | test f16_floatCast_f64 { |
| 102 | test__truncdfhf2_raw(0x7ff8000000000000, 0x7e00); // qNaN | 99 | try test_f16_floatCast_f64_raw(0x7ff8000000000000, 0x7e00); // qNaN |
| 103 | test__truncdfhf2_raw(0x7ff0000000008000, 0x7e00); // NaN | 100 | try test_f16_floatCast_f64_raw(0x7ff0000000008000, 0x7e00); // NaN |
| 104 | 101 | ||
| 105 | test__truncdfhf2_raw(0x7ff0000000000000, 0x7c00); //inf | 102 | try test_f16_floatCast_f64_raw(0x7ff0000000000000, 0x7c00); //inf |
| 106 | test__truncdfhf2_raw(0xfff0000000000000, 0xfc00); // -inf | 103 | try test_f16_floatCast_f64_raw(0xfff0000000000000, 0xfc00); // -inf |
| 107 | 104 | ||
| 108 | test__truncdfhf2(0.0, 0x0); // zero | 105 | try test_f16_floatCast_f64(0.0, 0x0); // zero |
| 109 | test__truncdfhf2_raw(0x80000000 << 32, 0x8000); // -zero | 106 | try test_f16_floatCast_f64_raw(0x80000000 << 32, 0x8000); // -zero |
| 110 | 107 | ||
| 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); |
| 113 | 110 | ||
| 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); |
| 118 | 115 | ||
| 119 | // denormal | 116 | // 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); |
| 124 | 121 | ||
| 125 | // and back to zero | 122 | // 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); |
| 128 | 125 | ||
| 129 | // max (precise) | 126 | // max (precise) |
| 130 | test__truncdfhf2(65504.0, 0x7bff); | 127 | try test_f16_floatCast_f64(65504.0, 0x7bff); |
| 131 | 128 | ||
| 132 | // max (rounded) | 129 | // max (rounded) |
| 133 | test__truncdfhf2(65519.0, 0x7bff); | 130 | try test_f16_floatCast_f64(65519.0, 0x7bff); |
| 134 | 131 | ||
| 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 | } |
| 140 | 137 | ||
| 141 | fn test__trunctfsf2(a: f128, expected: u32) void { | 138 | fn test_f32_floatCast_f128(a: f128, expected: u32) !void { |
| 142 | const x = __trunctfsf2(a); | 139 | const x = f32_floatCast_f128(a); |
| 143 | 140 | ||
| 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 | } |
| 154 | 151 | return error.TestFailure; | |
| 155 | @panic("__trunctfsf2 test failure"); | ||
| 156 | } | 152 | } |
| 157 | 153 | ||
| 158 | test "trunctfsf2" { | 154 | test f32_floatCast_f128 { |
| 159 | // qnan | 155 | // qnan |
| 160 | test__trunctfsf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000); | 156 | try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000); |
| 161 | // nan | 157 | // 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 | // inf | 159 | // inf |
| 164 | test__trunctfsf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000); | 160 | try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000); |
| 165 | // zero | 161 | // zero |
| 166 | test__trunctfsf2(0.0, 0x0); | 162 | try test_f32_floatCast_f128(0.0, 0x0); |
| 167 | 163 | ||
| 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 | } |
| 173 | 169 | ||
| 174 | fn test__trunctfdf2(a: f128, expected: u64) void { | 170 | fn test_f64_floatCast_f128(a: f128, expected: u64) !void { |
| 175 | const x = __trunctfdf2(a); | 171 | const x = f64_floatCast_f128(a); |
| 176 | 172 | ||
| 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 | } |
| 187 | 183 | return error.TestFailure; | |
| 188 | @panic("__trunctfsf2 test failure"); | ||
| 189 | } | 184 | } |
| 190 | 185 | ||
| 191 | test "trunctfdf2" { | 186 | test f64_floatCast_f128 { |
| 192 | // qnan | 187 | // qnan |
| 193 | test__trunctfdf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000); | 188 | try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000); |
| 194 | // nan | 189 | // 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 | // inf | 191 | // inf |
| 197 | test__trunctfdf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000); | 192 | try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000); |
| 198 | // zero | 193 | // zero |
| 199 | test__trunctfdf2(0.0, 0x0); | 194 | try test_f64_floatCast_f128(0.0, 0x0); |
| 200 | 195 | ||
| 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 | } |
| 206 | 201 | ||
| 207 | fn test__truncdfsf2(a: f64, expected: u32) void { | 202 | fn test_f32_floatCast_f64(a: f64, expected: u32) !void { |
| 208 | const x = __truncdfsf2(a); | 203 | const x = f32_floatCast_f64(a); |
| 209 | 204 | ||
| 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 | } |
| 220 | 215 | return error.TestFailure; | |
| 221 | std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected }); | ||
| 222 | |||
| 223 | @panic("__trunctfsf2 test failure"); | ||
| 224 | } | 216 | } |
| 225 | 217 | ||
| 226 | test "truncdfsf2" { | 218 | test f32_floatCast_f64 { |
| 227 | // nan & qnan | 219 | // 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 | // inf | 222 | // 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); |
| 233 | 225 | ||
| 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); |
| 237 | 229 | ||
| 238 | // huge number becomes inf | 230 | // huge number becomes inf |
| 239 | test__truncdfsf2(340282366920938463463374607431768211456.0, 0x7f800000); | 231 | try test_f32_floatCast_f64(340282366920938463463374607431768211456.0, 0x7f800000); |
| 240 | } | 232 | } |
| 241 | 233 | ||
| 242 | fn test__trunctfhf2(a: f128, expected: u16) void { | 234 | fn test_f16_floatCast_f128(a: f128, expected: u16) !void { |
| 243 | const x = __trunctfhf2(a); | 235 | const x = f16_floatCast_f128(a); |
| 244 | 236 | ||
| 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 | } |
| 254 | 240 | ||
| 255 | test "trunctfhf2" { | 241 | test f16_floatCast_f128 { |
| 256 | // qNaN | 242 | // qNaN |
| 257 | test__trunctfhf2(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00); | 243 | try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00); |
| 258 | // NaN | 244 | // NaN |
| 259 | test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00); | 245 | try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00); |
| 260 | // inf | 246 | // 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 | // zero | 249 | // 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); |
| 266 | 252 | ||
| 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 | // denormal | 259 | // 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 zero | 264 | // 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); |
| 289 | 275 | ||
| 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 | } |
| 295 | 281 | ||
| 296 | test "trunctfxf2" { | 282 | fn 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 | } |
| 302 | 286 | ||
| 303 | fn test__trunctfxf2(a: f128, expected: f80) !void { | 287 | test 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const truncf = @import("./truncf.zig").truncf; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 14 | pub fn __truncsfhf2(a: f32) callconv(.c) compiler_rt.F16T(f32) { | ||
| 15 | return @bitCast(truncf(f16, f32, a)); | ||
| 16 | } | ||
| 17 | |||
| 18 | fn __gnu_f2h_ieee(a: f32) callconv(.c) compiler_rt.F16T(f32) { | ||
| 19 | return @bitCast(truncf(f16, f32, a)); | ||
| 20 | } | ||
| 21 | |||
| 22 | fn __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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const truncf = @import("./truncf.zig").truncf; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __trunctfdf2(a: f128) callconv(.c) f64 { | ||
| 17 | return truncf(f64, f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const truncf = @import("./truncf.zig").truncf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__trunctfhf2, "__trunctfhf2"); | ||
| 7 | if (compiler_rt.want_ppc_abi) { | ||
| 8 | symbol(&__trunctfhf2, "__trunckfhf2"); | ||
| 9 | } | ||
| 10 | } | ||
| 11 | |||
| 12 | pub 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 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const truncf = @import("./truncf.zig").truncf; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 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 | |||
| 16 | pub fn __trunctfsf2(a: f128) callconv(.c) f32 { | ||
| 17 | return truncf(f32, f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _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 @@ | ||
| 1 | const math = @import("std").math; | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__trunctfxf2, "__trunctfxf2"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub 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 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__truncxfdf2, "__truncxfdf2"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __truncxfdf2(a: f80) callconv(.c) f64 { | ||
| 9 | return trunc_f80(f64, a); | ||
| 10 | } | ||
lib/compiler_rt/truncxfhf2.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__truncxfhf2, "__truncxfhf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __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 @@ | ||
| 1 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__truncxfsf2, "__truncxfsf2"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __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; |
| 6 | const shl = std.math.shl; | 6 | const shl = std.math.shl; |
| 7 | 7 | ||
| 8 | const compiler_rt = @import("../compiler_rt.zig"); | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const symbol = @import("../compiler_rt.zig").symbol; | 9 | const symbol = compiler_rt.symbol; |
| 10 | 10 | ||
| 11 | const max_limbs = @divCeil(65535, 32); // max supported type is u65535 | 11 | const max_limbs = @divCeil(65535, 32); // max supported type is u65535 |
| 12 | 12 |
lib/compiler_rt/unorddf2.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const comparef = @import("./comparef.zig"); | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_dcmpun, "__aeabi_dcmpun"); | ||
| 8 | } else { | ||
| 9 | symbol(&__unorddf2, "__unorddf2"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __unorddf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 14 | return comparef.unordcmp(f64, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __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. |
| 5 | const Semaphore = @This(); | 5 | const Semaphore = @This(); |
| 6 | 6 | ||
| 7 | const builtin = @import("builtin"); | ||
| 8 | |||
| 9 | const std = @import("../std.zig"); | 7 | const std = @import("../std.zig"); |
| 10 | const Io = std.Io; | 8 | const Io = std.Io; |
| 11 | const testing = std.testing; | 9 | const 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 | } |
| 875 | 875 | ||
| 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. |
| 877 | pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.builtin.Endian) Error!void { | 877 | pub 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 |
| 882 | 882 | ||
| 883 | /// The function is inline to avoid the dead code in case `endian` is | 883 | /// 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. |
| 885 | pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.builtin.Endian) Error!void { | 885 | pub 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 | } |
| 2818 | 2818 | ||
| 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 | }; |
| 2828 | 2828 |
lib/std/Random/RomuTrio.zig-1| ... | @@ -122,7 +122,6 @@ test fill { | ... | @@ -122,7 +122,6 @@ test fill { |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | test "buf seeding test" { | 124 | test "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 | } |
| 90 | 90 | ||
| 91 | test "sequence" { | 91 | test "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); |
| 95 | 93 | ||
| 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 { |
| 1797 | 1797 | ||
| 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 target | 3067 | /// Default signedness of `char` for the native C compiler for this target |
| 3067 | /// Note that char signedness is implementation-defined and many compilers provide | 3068 | /// 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-char | 3069 | /// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char |
| 3069 | pub fn cCharSignedness(target: *const Target) std.builtin.Signedness { | 3070 | /// Returns `null` if no C ABI is defined for this target. |
| 3071 | pub 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 | }; |
| 3116 | 3121 | ||
| 3117 | pub fn cTypeByteSize(t: *const Target, c_type: CType) u16 { | 3122 | /// Returns `null` if no C ABI is defined for this target. |
| 3123 | pub 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), |
| 3131 | 3137 | ||
| 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 | } |
| 3140 | 3146 | ||
| 3141 | pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 { | 3147 | /// Returns `null` if no C ABI is defined for this target. |
| 3148 | pub 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 | }, |
| 3461 | 3468 | ||
| 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 | } |
| 3469 | 3477 | ||
| 3470 | pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 { | 3478 | /// Returns `null` if no C ABI is defined for this target. |
| 3479 | pub fn cTypeAlignment(target: *const Target, c_type: CType) ?u16 { | ||
| 3471 | // Overrides for unusual alignments | 3480 | // 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 { |
| 3500 | 3509 | ||
| 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 | } |
| 3577 | 3586 | ||
| 3578 | pub 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 | |||
| 3692 | pub fn cMaxIntAlignment(target: *const Target) u16 { | 3587 | pub 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, |
| 3714 | 3609 | ||
| 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 { |
| 3766 | pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention { | 3665 | pub 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 | } |
| 1708 | 1708 | ||
| 1709 | test Integer { | 1709 | test 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); |
| 6 | const has_avx = builtin.cpu.has(.x86, .avx); | 6 | const has_avx = builtin.cpu.has(.x86, .avx); |
| 7 | const has_armaes = builtin.cpu.has(.aarch64, .aes); | 7 | const 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. |
| 9 | const impl = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c and has_aesni and has_avx) impl: { | 9 | const 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; |
| 262 | const testing = std.testing; | 262 | const testing = std.testing; |
| 263 | 263 | ||
| 264 | test "AesOcb test vector 1" { | 264 | test "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 | } |
| 282 | 280 | ||
| 283 | test "AesOcb test vector 2" { | 281 | test "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 | } |
| 304 | 300 | ||
| 305 | test "AesOcb test vector 3" { | 301 | test "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 | } |
| 330 | 324 | ||
| 331 | test "AesOcb test vector 4" { | 325 | test "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 | } |
| 357 | 349 | ||
| 358 | test "AesOcb in-place encryption-decryption" { | 350 | test "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 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std"); | 1 | const std = @import("std"); |
| 3 | const crypto = std.crypto; | 2 | const crypto = std.crypto; |
| 4 | const fmt = std.fmt; | 3 | const 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 | } |
| 416 | 415 | ||
| 417 | test "Basic operations over EcdsaP384Sha384" { | 416 | test "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 | } |
| 433 | 430 | ||
| 434 | test "Basic operations over Secp256k1" { | 431 | test "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 | } |
| 450 | 445 | ||
| 451 | test "Basic operations over EcdsaP384Sha256" { | 446 | test "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 | } |
| 467 | 460 | ||
| 468 | test "Verifying a existing signature with EcdsaP384Sha256" { | 461 | test "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: off | 463 | // 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 | } |
| 504 | 495 | ||
| 505 | test "Prehashed message operations" { | 496 | test "Prehashed message operations" { |
| 506 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 507 | |||
| 508 | const io = testing.io; | 497 | const io = testing.io; |
| 509 | 498 | ||
| 510 | const Scheme = EcdsaP256Sha256; | 499 | const Scheme = EcdsaP256Sha256; |
| ... | @@ -539,8 +528,6 @@ const TestVector = struct { | ... | @@ -539,8 +528,6 @@ const TestVector = struct { |
| 539 | }; | 528 | }; |
| 540 | 529 | ||
| 541 | test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" { | 530 | test "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 valid | 532 | // 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 | } |
| 712 | 699 | ||
| 713 | test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" { | 700 | test "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 invalid | 702 | // 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 | } |
| 1027 | 1012 | ||
| 1028 | test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" { | 1013 | test "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 valid | 1015 | // 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 | } |
| 1244 | 1227 | ||
| 1245 | test "Test vectors from Project Wycheproof - EcdsaP384Sha384 invalid" { | 1228 | test "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 invalid | 1230 | // 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 | } |
| 1632 | 1613 | ||
| 1633 | test "Sec1 encoding/decoding" { | 1614 | test "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 | }; |
| 967 | 967 | ||
| 968 | test "finite field arithmetic" { | 968 | test "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 | } |
| 1067 | 1065 | ||
| 1068 | fn testCt(ct_: anytype) !void { | 1066 | fn 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 | } |
| 57 | 57 | ||
| 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 { |
| 395 | 395 | ||
| 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 { |
| 407 | 407 | ||
| 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 { |
| 419 | 419 | ||
| 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 | }; |
| 479 | 479 | ||
| 480 | test { | 480 | test { |
| 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 | }; |
| 52 | 52 | ||
| 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 | } |
| 110 | 110 | ||
| 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 { |
| 423 | 423 | ||
| 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 { |
| 435 | 435 | ||
| 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 { |
| 497 | 497 | ||
| 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 | }; |
| 557 | 557 | ||
| 558 | test { | 558 | test { |
| 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 | } |
| 1083 | 1083 | ||
| 1084 | test "union" { | 1084 | test "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 { |
| 65 | 65 | ||
| 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 | } |
| 2206 | 2206 | ||
| 2207 | test "chmod" { | 2207 | test "chmod" { |
| 2208 | if (native_os == .windows or native_os == .wasi) return; | 2208 | if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; |
| 2209 | 2209 | ||
| 2210 | const io = testing.io; | 2210 | const io = testing.io; |
| 2211 | 2211 | ||
| ... | @@ -2228,8 +2228,7 @@ test "chmod" { | ... | @@ -2228,8 +2228,7 @@ test "chmod" { |
| 2228 | } | 2228 | } |
| 2229 | 2229 | ||
| 2230 | test "change ownership" { | 2230 | test "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; | ||
| 2233 | 2232 | ||
| 2234 | const io = testing.io; | 2233 | const io = testing.io; |
| 2235 | 2234 |
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 { |
| 225 | 225 | ||
| 226 | test "typeContainsSlice" { | 226 | test "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))); |
| 229 | 229 | ||
| 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 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const mem = std.mem; | 2 | const mem = std.mem; |
| 4 | const expectEqual = std.testing.expectEqual; | 3 | const expectEqual = std.testing.expectEqual; |
| 5 | 4 | ||
| ... | @@ -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 | } |
| 789 | 788 | ||
| 790 | test "xxhash3" { | 789 | test "xxhash3" { |
| 791 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 792 | const H = XxHash3; | 790 | const H = XxHash3; |
| 793 | // Non-Seeded Tests | 791 | // 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 | } |
| 821 | 819 | ||
| 822 | test "xxhash3 smhasher" { | 820 | test "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 | } |
| 833 | 830 | ||
| 834 | test "xxhash3 iterative api" { | 831 | test "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 | } |
| 1520 | 1520 | ||
| 1521 | /// This function is used in the debugger pretty formatters in tools/ to fetch the | 1521 | /// 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 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const native_endian = builtin.cpu.arch.endian(); | ||
| 3 | 2 | ||
| 4 | const std = @import("std"); | 3 | const std = @import("std"); |
| 5 | const http = std.http; | 4 | const 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 | } |
| 35 | 34 | ||
| 36 | test "trailers" { | 35 | test "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/30806 | 36 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 39 | 37 | ||
| 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 | } |
| 122 | 120 | ||
| 123 | test "HTTP server handles a chunked transfer coding request" { | 121 | test "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/30806 | 122 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 126 | 123 | ||
| 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 | } |
| 191 | 188 | ||
| 192 | test "echo content server" { | 189 | test "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/30806 | 190 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 195 | 191 | ||
| 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 | } |
| 282 | 278 | ||
| 283 | test "Server.Request.respondStreaming non-chunked, unknown content-length" { | 279 | test "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/30806 | 280 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 286 | 281 | ||
| 287 | const io = std.testing.io; | 282 | const io = std.testing.io; |
| 288 | 283 | ||
| 289 | if (builtin.os.tag == .windows) { | 284 | if (builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows) { |
| 290 | // https://github.com/ziglang/zig/issues/21457 | 285 | // 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 | } |
| 361 | 356 | ||
| 362 | test "receiving arbitrary http headers from the client" { | 357 | test "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/30806 | 358 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 365 | 359 | ||
| 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 | } |
| 427 | 421 | ||
| 428 | test "general client/server API coverage" { | 422 | test "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/30806 | 423 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 431 | 424 | ||
| 432 | const io = std.testing.io; | 425 | const io = std.testing.io; |
| 433 | 426 | ||
| 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 | } |
| 923 | 911 | ||
| 924 | test "Server streams both reading and writing" { | 912 | test "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/30806 | 913 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 927 | 914 | ||
| 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 { |
| 1162 | 1149 | ||
| 1163 | fn createTestServer(io: Io, S: type) !*TestServer { | 1150 | fn 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 | } | ||
| 1169 | 1152 | ||
| 1170 | const address = try net.IpAddress.parse("127.0.0.1", 0); | 1153 | const address = try net.IpAddress.parse("127.0.0.1", 0); |
| 1171 | 1154 | ||
| ... | @@ -1192,7 +1175,6 @@ fn createTestServer(io: Io, S: type) !*TestServer { | ... | @@ -1192,7 +1175,6 @@ fn createTestServer(io: Io, S: type) !*TestServer { |
| 1192 | } | 1175 | } |
| 1193 | 1176 | ||
| 1194 | test "redirect to different connection" { | 1177 | test "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/30806 | 1178 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 1197 | 1179 | ||
| 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 | } |
| 1281 | 1263 | ||
| 1282 | test "boot failed connections from the pool" { | 1264 | test "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/30806 | 1265 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 1285 | 1266 | ||
| 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. |
| 77 | pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { | 77 | pub 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); |
| 80 | 80 | ||
| 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. |
| 105 | pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool { | 105 | pub 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); |
| 108 | 108 | ||
| 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 | } |
| 463 | test wrap { | 463 | test 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/35520 | 465 | // 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 | } |
| 1386 | 1386 | ||
| 1387 | test lerp { | 1387 | test lerp { |
| 1388 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884 | 1388 | 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/17884 | 1390 | if (builtin.zig_backend == .stage2_x86_64 and !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884 |
| 1390 | 1391 | ||
| 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 | } |
| 338 | 338 | ||
| 339 | test "acosBinary16.special" { | 339 | test "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 | } |
| 351 | 349 | ||
| 352 | test "acosBinary16" { | 350 | test "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 | } |
| 327 | 327 | ||
| 328 | test "asinBinary16.special" { | 328 | test "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 | } |
| 341 | 339 | ||
| 342 | test "asinBinary16" { | 340 | test "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 | } |
| 482 | 482 | ||
| 483 | test "atanBinary16.special" { | 483 | test "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 | } |
| 494 | 492 | ||
| 495 | test "atanBinary16" { | 493 | test "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" { |
| 252 | 252 | ||
| 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" { |
| 276 | 276 | ||
| 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 @@ |
| 1 | const std = @import("../../std.zig"); | 1 | const std = @import("../../std.zig"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const mem = std.mem; | 2 | const mem = std.mem; |
| 4 | const testing = std.testing; | 3 | const testing = std.testing; |
| 5 | const Managed = std.math.big.int.Managed; | 4 | const 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 | } |
| 278 | test setFloat { | 277 | test 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 | } |
| 486 | test toFloat { | 483 | test 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 | } |
| 1392 | 1388 | ||
| 1393 | test "mul multi-multi" { | 1389 | test "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 | } |
| 1515 | 1509 | ||
| 1516 | test "mulWrap multi-multi unsigned" { | 1510 | test "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 | } |
| 1534 | 1526 | ||
| 1535 | test "mulWrap multi-multi signed" { | 1527 | test "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 | } |
| 1745 | 1732 | ||
| 1746 | test "div multi-multi q < r" { | 1733 | test "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 | } |
| 2167 | 2152 | ||
| 2168 | test "div multi-multi with rem" { | 2153 | test "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 | } |
| 2185 | 2168 | ||
| 2186 | test "div multi-multi no rem" { | 2169 | test "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 | } |
| 2203 | 2184 | ||
| 2204 | test "div multi-multi (2 branch)" { | 2185 | test "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 | } |
| 2221 | 2200 | ||
| 2222 | test "div multi-multi (3.1/3.3 branch)" { | 2201 | test "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 | } |
| 2239 | 2216 | ||
| 2240 | test "div multi-single zero-limb trailing" { | 2217 | test "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 | } |
| 2259 | 2234 | ||
| 2260 | test "div multi-multi zero-limb trailing (with rem)" { | 2235 | test "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 | } |
| 2280 | 2253 | ||
| 2281 | test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" { | 2254 | test "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 | } |
| 2301 | 2272 | ||
| 2302 | test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" { | 2273 | test "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 | } |
| 2833 | 2802 | ||
| 2834 | test "bitNotWrap more than two limbs" { | 2803 | test "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(); |
| 2841 | 2806 | ||
| ... | @@ -3179,8 +3144,6 @@ test "gcd non-one large" { | ... | @@ -3179,8 +3144,6 @@ test "gcd non-one large" { |
| 3179 | } | 3144 | } |
| 3180 | 3145 | ||
| 3181 | test "gcd large multi-limb result" { | 3146 | test "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); |
| 3433 | 3396 | ||
| 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; |
| 3436 | 3399 | ||
| 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 | } |
| 264 | 264 | ||
| 265 | test "gamma.special" { | 265 | test "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 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 3 | const math = std.math; | 2 | const math = std.math; |
| 4 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| ... | @@ -93,14 +92,10 @@ const hypot_test_cases = .{ | ... | @@ -93,14 +92,10 @@ const hypot_test_cases = .{ |
| 93 | }; | 92 | }; |
| 94 | 93 | ||
| 95 | test hypot { | 94 | test 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 | } |
| 99 | 97 | ||
| 100 | test "hypot.correct" { | 98 | test "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 | } |
| 111 | 106 | ||
| 112 | test "hypot.precise" { | 107 | test "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 ulp | 108 | 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 | } |
| 123 | 115 | ||
| 124 | test "hypot.special" { | 116 | test "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 | } |
| 28 | 28 | ||
| 29 | test isSignalNan { | 29 | test 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 in | 31 | // 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 and | 36 | builtin.cpu.arch != .hexagon and |
| 44 | !builtin.cpu.arch.isMIPS32() and | 37 | !builtin.cpu.arch.isMIPS32() and |
| 45 | !builtin.cpu.arch.isPowerPC() and | 38 | !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 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const testing = std.testing; | 2 | const testing = std.testing; |
| 4 | 3 | ||
| 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 | } |
| 136 | 135 | ||
| 137 | test log10_int { | 136 | test 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 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const math = std.math; | 2 | const math = std.math; |
| 4 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 5 | const expectEqual = std.testing.expectEqual; | 4 | const 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 }; |
| 92 | 88 | ||
| 93 | inline for (widths) |len| { | 89 | inline for (widths) |len| { |
lib/std/math/signbit.zig+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const std = @import("../std.zig"); | 2 | const std = @import("../std.zig"); |
| 2 | const math = std.math; | 3 | const math = std.math; |
| 3 | const expect = std.testing.expect; | 4 | const 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 { |
| 4780 | pub fn doNotOptimizeAway(val: anytype) void { | 4780 | pub fn doNotOptimizeAway(val: anytype) void { |
| 4781 | if (@inComptime()) return; | 4781 | if (@inComptime()) return; |
| 4782 | 4782 | ||
| 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 | } |
| 4828 | 4823 | ||
| 4829 | /// .stage2_c doesn't support asm blocks yet, so use volatile stores instead | ||
| 4830 | var deopt_target: if (builtin.zig_backend == .stage2_c) u8 else void = undefined; | ||
| 4831 | fn 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 | |||
| 4839 | test doNotOptimizeAway { | 4824 | test doNotOptimizeAway { |
| 4840 | comptime doNotOptimizeAway("test"); | 4825 | comptime doNotOptimizeAway("test"); |
| 4841 | 4826 | ||
| ... | @@ -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 | } |
| 4995 | 4980 | ||
| 4996 | test "read/write(Var)PackedInt" { | 4981 | test "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 | } | ||
| 5003 | 4985 | ||
| 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 | } |
| 165 | 165 | ||
| 166 | /// This function is used in the debugger pretty formatters in tools/ to fetch the | 166 | /// 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 the | 684 | /// 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 | } |
| 1837 | 1837 | ||
| 1838 | test "accept_direct" { | 1838 | test "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 }); |
| 1842 | 1840 | ||
| 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" { |
| 1925 | test "accept_multishot_direct" { | 1923 | test "accept_multishot_direct" { |
| 1926 | try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 }); | 1924 | try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 }); |
| 1927 | 1925 | ||
| 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; |
| 154 | pub fn restore_rt() callconv(.naked) noreturn { | 154 | pub 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 #0 | 158 | \\ 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 | } |
| 175 | 175 | ||
| 176 | pub fn restore() callconv(.naked) noreturn { | 176 | pub fn restore() callconv(.naked) noreturn { |
| 177 | asm volatile ( | 177 | switch (builtin.zig_backend) { |
| 178 | \\svc 0 | 178 | .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 | } |
| 183 | 191 | ||
| 184 | pub fn restore_rt() callconv(.naked) noreturn { | 192 | pub fn restore_rt() callconv(.naked) noreturn { |
| 185 | asm volatile ( | 193 | switch (builtin.zig_backend) { |
| 186 | \\svc 0 | 194 | .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 | } |
| 191 | 207 | ||
| 192 | pub const time_t = i64; | 208 | pub 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 | } |
| 709 | 709 | ||
| 710 | test value { | 710 | test value { |
| 711 | if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 711 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 712 | 712 | ||
| 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, |
| 17 | strip: bool, | 17 | strip: bool, |
| 18 | 18 | ||
| 19 | source_filename: String, | 19 | source_filename: String, |
| 20 | data_layout: String, | 20 | data_layout: DataLayout, |
| 21 | target_triple: String, | 21 | target_triple: String, |
| 22 | module_asm: std.ArrayList(u8), | 22 | module_asm: std.ArrayList(u8), |
| 23 | 23 | ||
| ... | @@ -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 | }; |
| 89 | 89 | ||
| 90 | pub 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 | |||
| 90 | pub const String = enum(u32) { | 539 | pub 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 | } |
| 143 | 592 | ||
| 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 | } |
| 148 | 597 | ||
| 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 | }; |
| 935 | 1450 | ||
| 936 | pub const Attribute = union(Kind) { | 1451 | pub const Attribute = union(Kind) { |
| 937 | // Parameter Attributes | 1452 | // 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, | ||
| 968 | 1490 | ||
| 969 | // Function Attributes | 1491 | // 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, |
| 1026 | 1554 | nooutline, | |
| 1027 | // Global Attributes | 1555 | nocreateundeforpoison, |
| 1028 | no_sanitize_address, | ||
| 1029 | no_sanitize_hwaddress, | ||
| 1030 | //sanitize_memtag, | ||
| 1031 | sanitize_address_dyninit, | ||
| 1032 | 1556 | ||
| 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 | } |
| 1162 | 1600 | ||
| ... | @@ -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) { |
| 1344 | 1832 | ||
| 1345 | pub const Kind = enum(u32) { | 1833 | pub const Kind = enum(u32) { |
| 1346 | // Parameter Attributes | 1834 | // 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), | ||
| 1377 | 1872 | ||
| 1378 | // Function Attributes | 1873 | // 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), |
| 1435 | 1930 | denormal_fpenv = @backingInt(ATTR_KIND.DENORMAL_FPENV), | |
| 1436 | // Global Attributes | 1931 | 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), | ||
| 1441 | 1938 | ||
| 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) { |
| 1447 | 1944 | ||
| 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 | } |
| 1454 | 1951 | ||
| 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 | }; |
| 1461 | 2070 | ||
| 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 | }; |
| 1508 | 2117 | ||
| 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) { |
| 1907 | 2543 | ||
| 1908 | // See llvm/lib/Target/X86/X86.h | 2544 | // 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); |
| 1913 | 2549 | ||
| 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; |
| 1919 | 2555 | ||
| 1920 | // See llvm/lib/Target/AVR/AVR.h | 2556 | // 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 | }; |
| 1930 | 2566 | ||
| 1931 | // See llvm/lib/Target/NVPTX/NVPTX.h | 2567 | // 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 | }; |
| 1940 | 2576 | ||
| 1941 | // See llvm/lib/Target/AMDGPU/AMDGPU.h | 2577 | // 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 | }; |
| 1973 | 2609 | ||
| 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 | }; |
| 1984 | 2620 | ||
| 1985 | // See llvm/include/llvm/CodeGen/WasmAddressSpaces.h | 2621 | // 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 | }; |
| 1992 | 2628 | ||
| 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 | _, |
| 2031 | 2667 | ||
| 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 | } |
| 2063 | 2699 | ||
| 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 | } |
| 2070 | 2713 | ||
| 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 | } |
| 2262 | 2905 | ||
| 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 | } |
| 2267 | 2909 | ||
| 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 | } |
| 2399 | 3041 | ||
| 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 | } |
| 2403 | 3045 | ||
| 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 { |
| 2539 | 3181 | ||
| 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, | ||
| 2747 | 3405 | ||
| 2748 | // Arithmetic with Overflow | 3406 | // 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 | }, |
| 2948 | 3606 | ||
| 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 | }, |
| 3303 | 4089 | ||
| 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 | }, |
| 3366 | 4161 | ||
| 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 | }, |
| 3427 | 4222 | ||
| 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 | }, |
| 3482 | 4277 | ||
| 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 | }, |
| 3563 | 4358 | ||
| 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 | }, |
| 3582 | 4377 | ||
| 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 | }, |
| 3724 | 4519 | ||
| 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 | }, |
| 3734 | 4529 | ||
| 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 | }, |
| 3943 | 4738 | ||
| 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 | }, |
| 3962 | 4757 | ||
| 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 | }, |
| 4015 | 4810 | ||
| 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 | } |
| 4168 | 4963 | ||
| 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 | } |
| 4488 | 5287 | ||
| 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 | } |
| 4492 | 5291 | ||
| 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 { |
| 4963 | 5762 | ||
| 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 | } |
| 4968 | 5767 | ||
| 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); |
| 5158 | 5957 | ||
| 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 | } |
| 5162 | 5961 | ||
| ... | @@ -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); |
| 5329 | 6128 | ||
| 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 | } |
| 5333 | 6132 | ||
| ... | @@ -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 | } |
| 5727 | 6526 | ||
| 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 | } |
| 5771 | 6570 | ||
| 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); |
| 6415 | 7214 | ||
| 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 | } |
| 6432 | 7231 | ||
| 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, |
| 6437 | 7236 | ||
| ... | @@ -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 | } |
| 6453 | 7252 | ||
| 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 | _, |
| 7270 | 8069 | ||
| 7271 | const first_global: Constant = @fromBackingInt(@intCast(1 << 29)); | 8070 | const first_global: Constant = @fromBackingInt(1 << 29); |
| 7272 | 8071 | ||
| 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, |
| 7407 | 8206 | ||
| 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 | }; |
| 7410 | 8220 | ||
| 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 | else | 8256 | else |
| 7447 | .{ .global = @fromBackingInt(@intCast(@backingInt(self) - @backingInt(first_global))) }; | 8257 | .{ .global = @fromBackingInt(@backingInt(self) - @backingInt(first_global)) }; |
| 7448 | } | 8258 | } |
| 7449 | 8259 | ||
| 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 | } |
| 7453 | 8263 | ||
| 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 | else | 8736 | 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 | } |
| 8021 | 8831 | ||
| 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 | } |
| 8082 | 8892 | ||
| 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, |
| 8736 | 9546 | ||
| 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, |
| 8741 | 9558 | ||
| ... | @@ -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, |
| 8745 | 9562 | ||
| 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, |
| 8759 | 9576 | ||
| 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); |
| 8793 | 9610 | ||
| 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); |
| 8796 | 9615 | ||
| 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); |
| 8798 | 9617 | ||
| 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 | } | ||
| 8802 | 9619 | ||
| 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 { |
| 8891 | pub fn deinit(self: *Builder) void { | 9708 | pub fn deinit(self: *Builder) void { |
| 8892 | const gpa = self.gpa; | 9709 | const gpa = self.gpa; |
| 8893 | 9710 | ||
| 9711 | self.data_layout.deinit(gpa); | ||
| 9712 | |||
| 8894 | self.module_asm.deinit(gpa); | 9713 | self.module_asm.deinit(gpa); |
| 8895 | 9714 | ||
| 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 | } |
| 9097 | 9916 | ||
| 9098 | pub fn fnAttrs(self: *Builder, fn_attributes: []const Attributes) Allocator.Error!FunctionAttributes { | 9917 | pub 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 + 1 | 9921 | last + 1 |
| 9103 | else | 9922 | else |
| 9104 | 0], | 9923 | 0], |
| 9105 | )))); | 9924 | ))); |
| 9106 | 9925 | ||
| 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); |
| 9712 | 10531 | ||
| 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 | }; |
| 11926 | 12745 | ||
| 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 { |
| 13345 | 14164 | ||
| 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 | } |
| 13420 | 14239 | ||
| 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 | }; |
| 14783 | 15619 | ||
| 14784 | // Emit function level metadata block | 15620 | // 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 | } |
| 14795 | 15631 | ||
| ... | @@ -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 | } |
| 500 | 500 | ||
| 501 | pub fn intAlignment(target: *const std.Target, bits: u16) u16 { | 501 | pub 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 | } |
| 529 | 510 | ||
| 511 | pub 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 | |||
| 530 | const std = @import("std"); | 528 | const std = @import("std"); |
| 531 | const assert = std.debug.assert; | 529 | const assert = std.debug.assert; |
| 532 | const Allocator = std.mem.Allocator; | 530 | const 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`. |
| 10 | 10 | ||
| 11 | const std = @import("std"); | 11 | const std = @import("std"); |
| 12 | const builtin = @import("builtin"); | ||
| 13 | const Allocator = std.mem.Allocator; | 12 | const Allocator = std.mem.Allocator; |
| 14 | const Ast = std.zig.Ast; | 13 | const Ast = std.zig.Ast; |
| 15 | const Zoir = std.zig.Zoir; | 14 | const Zoir = std.zig.Zoir; |
| ... | @@ -1868,8 +1867,6 @@ test "std.zon tuples" { | ... | @@ -1868,8 +1867,6 @@ test "std.zon tuples" { |
| 1868 | 1867 | ||
| 1869 | // Test sizes 0 to 3 since small sizes get parsed differently | 1868 | // Test sizes 0 to 3 since small sizes get parsed differently |
| 1870 | test "std.zon arrays and slices" { | 1869 | test "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; |
| 1874 | 1871 | ||
| 1875 | // Literals | 1872 | // Literals |
| ... | @@ -2802,8 +2799,6 @@ test "std.zon negative char" { | ... | @@ -2802,8 +2799,6 @@ test "std.zon negative char" { |
| 2802 | } | 2799 | } |
| 2803 | 2800 | ||
| 2804 | test "std.zon parse float" { | 2801 | test "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; |
| 2808 | 2803 | ||
| 2809 | // Test decimals | 2804 | // Test decimals |
| ... | @@ -3135,7 +3130,7 @@ test "std.zon free on error" { | ... | @@ -3135,7 +3130,7 @@ test "std.zon free on error" { |
| 3135 | } | 3130 | } |
| 3136 | 3131 | ||
| 3137 | test "std.zon vector" { | 3132 | test "std.zon vector" { |
| 3138 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/15330 | 3133 | 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/25957 | 3134 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .s390x) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25957 |
| 3140 | 3135 | ||
| 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 | } |
| 1152 | 1152 | ||
| 1153 | test "std.zon stringify primitives" { | 1153 | test "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 | #endif | 166 | #endif |
| 167 | #define zig_expand_has_builtin(b) zig_has_builtin(b) | 167 | #define zig_expand_has_builtin(b) zig_has_builtin(b) |
| 168 | 168 | ||
| 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 | #else | 177 | #else |
| ... | @@ -175,9 +181,9 @@ | ... | @@ -175,9 +181,9 @@ |
| 175 | #if __STDC_VERSION__ >= 201112L | 181 | #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 | #else | 185 | #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 | #endif | 187 | #endif |
| 182 | 188 | ||
| 183 | #if __STDC_VERSION__ >= 202311L | 189 | #if __STDC_VERSION__ >= 202311L |
| ... | @@ -193,10 +199,8 @@ | ... | @@ -193,10 +199,8 @@ |
| 193 | #endif | 199 | #endif |
| 194 | 200 | ||
| 195 | #if defined(zig_msvc) | 201 | #if defined(zig_msvc) |
| 196 | #define zig_const_arr | ||
| 197 | #define zig_callconv(c) __##c | 202 | #define zig_callconv(c) __##c |
| 198 | #else | 203 | #else |
| 199 | #define zig_const_arr static const | ||
| 200 | #define zig_callconv(c) __attribute__((c)) | 204 | #define zig_callconv(c) __attribute__((c)) |
| 201 | #endif | 205 | #endif |
| 202 | 206 | ||
| ... | @@ -267,12 +271,20 @@ | ... | @@ -267,12 +271,20 @@ |
| 267 | 271 | ||
| 268 | #if __STDC_VERSION__ >= 202311L | 272 | #if __STDC_VERSION__ >= 202311L |
| 269 | #define zig_align(alignment) alignas(alignment) | 273 | #define zig_align(alignment) alignas(alignment) |
| 270 | #elif __STDC_VERSION__ >= 201112L | 274 | #elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignas) |
| 271 | #define zig_align(alignment) _Alignas(alignment) | 275 | #define zig_align(alignment) _Alignas(alignment) |
| 272 | #else | 276 | #else |
| 273 | #define zig_align(alignment) zig_under_align(alignment) | 277 | #define zig_align(alignment) zig_under_align(alignment) |
| 274 | #endif | 278 | #endif |
| 275 | 279 | ||
| 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 | #else | 363 | #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 | #endif | 366 | #endif |
| 355 | 367 | ||
| 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 */ |
| 370 | 380 | ||
| ... | @@ -550,6 +560,9 @@ | ... | @@ -550,6 +560,9 @@ |
| 550 | #define zig_noreturn | 560 | #define zig_noreturn |
| 551 | #endif | 561 | #endif |
| 552 | 562 | ||
| 563 | #define zig_has_always 1 | ||
| 564 | #define zig_has_never 0 | ||
| 565 | |||
| 553 | #define zig_compiler_rt_abbrev_uint32_t si | 566 | #define zig_compiler_rt_abbrev_uint32_t si |
| 554 | #define zig_compiler_rt_abbrev_int32_t si | 567 | #define zig_compiler_rt_abbrev_int32_t si |
| 555 | #define zig_compiler_rt_abbrev_uint64_t di | 568 | #define zig_compiler_rt_abbrev_uint64_t di |
| ... | @@ -560,7 +573,11 @@ | ... | @@ -560,7 +573,11 @@ |
| 560 | #define zig_compiler_rt_abbrev_zig_f32 sf | 573 | #define zig_compiler_rt_abbrev_zig_f32 sf |
| 561 | #define zig_compiler_rt_abbrev_zig_f64 df | 574 | #define zig_compiler_rt_abbrev_zig_f64 df |
| 562 | #define zig_compiler_rt_abbrev_zig_f80 xf | 575 | #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 tf | 579 | #define zig_compiler_rt_abbrev_zig_f128 tf |
| 580 | #endif | ||
| 564 | 581 | ||
| 565 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); | 582 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); |
| 566 | zig_extern void *memset (void *, int, size_t); | 583 | zig_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)) |
| 647 | 664 | ||
| 648 | #if defined(zig_ez80) | ||
| 649 | typedef unsigned int uint24_t; | ||
| 650 | typedef 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 == 0xFFFFFFFF | 665 | #if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF |
| 659 | typedef unsigned char uint32_t; | 666 | typedef unsigned char uint32_t; |
| 660 | typedef signed char int32_t; | 667 | typedef 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)) |
| 687 | 694 | ||
| 688 | #if defined(zig_ez80) | ||
| 689 | typedef unsigned __int48 uint48_t; | ||
| 690 | typedef 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 == 0xFFFFFFFFFFFFFFFF | 695 | #if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF |
| 700 | typedef unsigned char uint64_t; | 696 | typedef unsigned char uint64_t; |
| 701 | typedef signed char int64_t; | 697 | typedef 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)) |
| 728 | 724 | ||
| 725 | #if defined(zig_ez80) | ||
| 726 | |||
| 727 | typedef unsigned int uint24_t; | ||
| 728 | typedef 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 | |||
| 735 | typedef unsigned __int48 uint48_t; | ||
| 736 | typedef 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 | |||
| 729 | typedef size_t uintptr_t; | 746 | typedef size_t uintptr_t; |
| 730 | typedef ptrdiff_t intptr_t; | 747 | typedef ptrdiff_t intptr_t; |
| 731 | 748 | ||
| ... | @@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t; | ... | @@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t; |
| 739 | #define zig_maxInt_i16 INT16_MAX | 756 | #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_MAX | 758 | #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_MIN | 759 | #define zig_minInt_i32 INT32_MIN |
| 747 | #define zig_maxInt_i32 INT32_MAX | 760 | #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_MAX | 762 | #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_MIN | 763 | #define zig_minInt_i64 INT64_MIN |
| 755 | #define zig_maxInt_i64 INT64_MAX | 764 | #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_MAX | 766 | #define zig_maxInt_u64 UINT64_MAX |
| 758 | 767 | ||
| 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 | ||
| 772 | typedef unsigned int zig_promoted_i8; | ||
| 773 | #elif INT8_MAX <= LONG_MAX | ||
| 774 | typedef unsigned long zig_promoted_i8; | ||
| 775 | #elif INT8_MAX <= LLONG_MAX | ||
| 776 | typedef unsigned long long zig_promoted_i8; | ||
| 777 | #else | ||
| 778 | typedef int8_t zig_promoted_i8; | ||
| 779 | #endif | ||
| 780 | #if UINT8_MAX <= UINT_MAX | ||
| 781 | typedef unsigned int zig_promoted_u8; | ||
| 782 | #elif UINT8_MAX <= ULONG_MAX | ||
| 783 | typedef unsigned long zig_promoted_u8; | ||
| 784 | #elif UINT8_MAX <= ULLONG_MAX | ||
| 785 | typedef unsigned long long zig_promoted_u8; | ||
| 786 | #else | ||
| 787 | typedef uint8_t zig_promoted_u8; | ||
| 788 | #endif | ||
| 789 | |||
| 790 | #if INT16_MAX <= INT_MAX | ||
| 791 | typedef unsigned int zig_promoted_i16; | ||
| 792 | #elif INT16_MAX <= LONG_MAX | ||
| 793 | typedef unsigned long zig_promoted_i16; | ||
| 794 | #elif INT16_MAX <= LLONG_MAX | ||
| 795 | typedef unsigned long long zig_promoted_i16; | ||
| 796 | #else | ||
| 797 | typedef int16_t zig_promoted_i16; | ||
| 798 | #endif | ||
| 799 | #if UINT16_MAX <= UINT_MAX | ||
| 800 | typedef unsigned int zig_promoted_u16; | ||
| 801 | #elif UINT16_MAX <= ULONG_MAX | ||
| 802 | typedef unsigned long zig_promoted_u16; | ||
| 803 | #elif UINT16_MAX <= ULLONG_MAX | ||
| 804 | typedef unsigned long long zig_promoted_u16; | ||
| 805 | #else | ||
| 806 | typedef uint16_t zig_promoted_u16; | ||
| 807 | #endif | ||
| 808 | |||
| 809 | #if INT32_MAX <= INT_MAX | ||
| 810 | typedef unsigned int zig_promoted_i32; | ||
| 811 | #elif INT32_MAX <= LONG_MAX | ||
| 812 | typedef unsigned long zig_promoted_i32; | ||
| 813 | #elif INT32_MAX <= LLONG_MAX | ||
| 814 | typedef unsigned long long zig_promoted_i32; | ||
| 815 | #else | ||
| 816 | typedef int32_t zig_promoted_i32; | ||
| 817 | #endif | ||
| 818 | #if UINT32_MAX <= UINT_MAX | ||
| 819 | typedef unsigned int zig_promoted_u32; | ||
| 820 | #elif UINT32_MAX <= ULONG_MAX | ||
| 821 | typedef unsigned long zig_promoted_u32; | ||
| 822 | #elif UINT32_MAX <= ULLONG_MAX | ||
| 823 | typedef unsigned long long zig_promoted_u32; | ||
| 824 | #else | ||
| 825 | typedef uint32_t zig_promoted_u32; | ||
| 826 | #endif | ||
| 827 | |||
| 828 | #if INT64_MAX <= INT_MAX | ||
| 829 | typedef unsigned int zig_promoted_i64; | ||
| 830 | #elif INT64_MAX <= LONG_MAX | ||
| 831 | typedef unsigned long zig_promoted_i64; | ||
| 832 | #elif INT64_MAX <= LLONG_MAX | ||
| 833 | typedef unsigned long long zig_promoted_i64; | ||
| 834 | #else | ||
| 835 | typedef int64_t zig_promoted_i64; | ||
| 836 | #endif | ||
| 837 | #if UINT64_MAX <= UINT_MAX | ||
| 838 | typedef unsigned int zig_promoted_u64; | ||
| 839 | #elif UINT64_MAX <= ULONG_MAX | ||
| 840 | typedef unsigned long zig_promoted_u64; | ||
| 841 | #elif UINT64_MAX <= ULLONG_MAX | ||
| 842 | typedef unsigned long long zig_promoted_u64; | ||
| 843 | #else | ||
| 844 | typedef 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 | ||
| 859 | typedef unsigned int zig_promoted_i24; | ||
| 860 | #elif INT24_MAX <= LONG_MAX | ||
| 861 | typedef unsigned long zig_promoted_i24; | ||
| 862 | #elif INT24_MAX <= LLONG_MAX | ||
| 863 | typedef unsigned long long zig_promoted_i24; | ||
| 864 | #else | ||
| 865 | typedef int24_t zig_promoted_i24; | ||
| 866 | #endif | ||
| 867 | #if UINT24_MAX <= UINT_MAX | ||
| 868 | typedef unsigned int zig_promoted_u24; | ||
| 869 | #elif UINT24_MAX <= ULONG_MAX | ||
| 870 | typedef unsigned long zig_promoted_u24; | ||
| 871 | #elif UINT24_MAX <= ULLONG_MAX | ||
| 872 | typedef unsigned long long zig_promoted_u24; | ||
| 873 | #else | ||
| 874 | typedef uint24_t zig_promoted_u24; | ||
| 875 | #endif | ||
| 876 | |||
| 877 | #if INT48_MAX <= INT_MAX | ||
| 878 | typedef unsigned int zig_promoted_i48; | ||
| 879 | #elif INT48_MAX <= LONG_MAX | ||
| 880 | typedef unsigned long zig_promoted_i48; | ||
| 881 | #elif INT48_MAX <= LLONG_MAX | ||
| 882 | typedef unsigned long long zig_promoted_i48; | ||
| 883 | #else | ||
| 884 | typedef int48_t zig_promoted_i48; | ||
| 885 | #endif | ||
| 886 | #if UINT48_MAX <= UINT_MAX | ||
| 887 | typedef unsigned int zig_promoted_u48; | ||
| 888 | #elif UINT48_MAX <= ULONG_MAX | ||
| 889 | typedef unsigned long zig_promoted_u48; | ||
| 890 | #elif UINT48_MAX <= ULLONG_MAX | ||
| 891 | typedef unsigned long long zig_promoted_u48; | ||
| 892 | #else | ||
| 893 | typedef 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_MAX | 1054 | zig_int_operators(8) |
| 865 | zig_int_helpers(8, unsigned int) | 1055 | zig_int_operators(16) |
| 866 | #elif UINT8_MAX <= ULONG_MAX | 1056 | zig_int_operators(32) |
| 867 | zig_int_helpers(8, unsigned long) | 1057 | zig_int_operators(64) |
| 868 | #elif UINT8_MAX <= ULLONG_MAX | 1058 | #ifdef zig_ez80 |
| 869 | zig_int_helpers(8, unsigned long long) | 1059 | zig_int_operators(24) |
| 870 | #else | 1060 | zig_int_operators(48) |
| 871 | zig_int_helpers(8, uint8_t) | 1061 | #endif |
| 872 | #endif | 1062 | |
| 873 | #if UINT16_MAX <= UINT_MAX | 1063 | #define zig_int_casts(bw, sw) \ |
| 874 | zig_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_MAX | 1065 | return (uint##sw##_t)arg; \ |
| 876 | zig_int_helpers(16, unsigned long) | 1066 | } \ |
| 877 | #elif UINT16_MAX <= ULLONG_MAX | 1067 | \ |
| 878 | zig_int_helpers(16, unsigned long long) | 1068 | static inline uint##sw##_t zig_u##sw##_intCast_i##bw(int##bw##_t arg) { \ |
| 879 | #else | 1069 | return (uint##sw##_t)arg; \ |
| 880 | zig_int_helpers(16, uint16_t) | 1070 | } \ |
| 881 | #endif | 1071 | \ |
| 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_MAX | 1073 | return (int##sw##_t)arg; \ |
| 884 | zig_int_helpers(24, unsigned int) | 1074 | } \ |
| 885 | #elif UINT24_MAX <= ULONG_MAX | 1075 | \ |
| 886 | zig_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_MAX | 1077 | return (int##sw##_t)arg; \ |
| 888 | zig_int_helpers(24, unsigned long long) | 1078 | } \ |
| 889 | #else | 1079 | \ |
| 890 | zig_int_helpers(24, uint24_t) | 1080 | zig_int_casts_common(bw, sw) |
| 891 | #endif | 1081 | zig_int_casts(16, 8) |
| 892 | #endif | 1082 | zig_int_casts(32, 8) |
| 893 | #if UINT32_MAX <= UINT_MAX | 1083 | zig_int_casts(64, 8) |
| 894 | zig_int_helpers(32, unsigned int) | 1084 | zig_int_casts(32, 16) |
| 895 | #elif UINT32_MAX <= ULONG_MAX | 1085 | zig_int_casts(64, 16) |
| 896 | zig_int_helpers(32, unsigned long) | 1086 | zig_int_casts(64, 32) |
| 897 | #elif UINT32_MAX <= ULLONG_MAX | 1087 | #ifdef zig_ez80 |
| 898 | zig_int_helpers(32, unsigned long long) | 1088 | zig_int_casts(32, 24) |
| 899 | #else | 1089 | zig_int_casts(48, 24) |
| 900 | zig_int_helpers(32, uint32_t) | 1090 | zig_int_casts(64, 24) |
| 901 | #endif | 1091 | zig_int_casts(64, 48) |
| 902 | #if defined(zig_ez80) | ||
| 903 | #if UINT24_MAX <= UINT_MAX | ||
| 904 | zig_int_helpers(48, unsigned int) | ||
| 905 | #elif UINT24_MAX <= ULONG_MAX | ||
| 906 | zig_int_helpers(48, unsigned long) | ||
| 907 | #elif UINT24_MAX <= ULLONG_MAX | ||
| 908 | zig_int_helpers(48, unsigned long long) | ||
| 909 | #else | ||
| 910 | zig_int_helpers(48, uint48_t) | ||
| 911 | #endif | ||
| 912 | #endif | ||
| 913 | #if UINT64_MAX <= UINT_MAX | ||
| 914 | zig_int_helpers(64, unsigned int) | ||
| 915 | #elif UINT64_MAX <= ULONG_MAX | ||
| 916 | zig_int_helpers(64, unsigned long) | ||
| 917 | #elif UINT64_MAX <= ULLONG_MAX | ||
| 918 | zig_int_helpers(64, unsigned long long) | ||
| 919 | #else | ||
| 920 | zig_int_helpers(64, uint64_t) | ||
| 921 | #endif | 1092 | #endif |
| 922 | 1093 | ||
| 923 | static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1094 | static 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 | #else | 1100 | #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 | #else | 1112 | #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 | #endif | 1115 | #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 | } |
| 946 | 1117 | ||
| 947 | static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { | 1118 | static 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 | #else | 1124 | #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 | #else | 1136 | #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 | #endif | 1139 | #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 | } |
| 970 | 1141 | ||
| 971 | static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { | 1142 | static 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 | #else | 1148 | #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 | #endif | 1153 | #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 | #else | 1162 | #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 | #endif | 1167 | #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 | #else | 1176 | #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 | #endif | 1181 | #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 | #else | 1190 | #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 | #endif | 1195 | #endif |
| 1025 | } | 1196 | } |
| 1026 | 1197 | ||
| 1027 | #if defined(zig_ez80) | 1198 | #if defined(zig_ez80) |
| 1199 | |||
| 1028 | static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1200 | static 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 | #else | 1206 | #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 | #endif | 1211 | #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 | #else | 1220 | #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 | #endif | 1225 | #endif |
| 1054 | } | 1226 | } |
| 1055 | #endif | ||
| 1056 | 1227 | ||
| 1057 | #if defined(zig_ez80) | ||
| 1058 | static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1228 | static 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 | #else | 1234 | #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 | #endif | 1239 | #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 | #else | 1248 | #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 | #endif | 1253 | #endif |
| 1084 | } | 1254 | } |
| 1255 | |||
| 1085 | #endif | 1256 | #endif |
| 1086 | 1257 | ||
| 1087 | static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1258 | static 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 | #else | 1264 | #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 | #else | 1276 | #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 | #endif | 1279 | #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 | } |
| 1110 | 1281 | ||
| 1111 | |||
| 1112 | static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { | 1282 | static 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 | #else | 1288 | #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 | #else | 1300 | #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 | #endif | 1303 | #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 | } |
| 1135 | 1305 | ||
| 1136 | static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { | 1306 | static 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 | #else | 1312 | #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 | #endif | 1317 | #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 | #else | 1326 | #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 | #endif | 1331 | #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 | #else | 1340 | #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 | #endif | 1345 | #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 | #else | 1354 | #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 | #endif | 1359 | #endif |
| 1190 | } | 1360 | } |
| 1191 | 1361 | ||
| 1192 | #if defined(zig_ez80) | 1362 | #if defined(zig_ez80) |
| 1363 | |||
| 1193 | static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1364 | static 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 | #else | 1370 | #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 | #endif | 1375 | #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 | #else | 1384 | #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 | #endif | 1389 | #endif |
| 1219 | } | 1390 | } |
| 1220 | #endif | ||
| 1221 | 1391 | ||
| 1222 | #if defined(zig_ez80) | ||
| 1223 | static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1392 | static 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 | #else | 1398 | #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 | #endif | 1403 | #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 | #else | 1412 | #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 | #endif | 1417 | #endif |
| 1249 | } | 1418 | } |
| 1419 | |||
| 1250 | #endif | 1420 | #endif |
| 1251 | 1421 | ||
| 1252 | static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1422 | static 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 | #else | 1428 | #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 | #endif | 1431 | #endif |
| 1262 | } | 1432 | } |
| 1263 | 1433 | ||
| 1264 | zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow); | ||
| 1265 | static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { | 1434 | static 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 | #endif | 1443 | #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 | } |
| 1277 | 1447 | ||
| ... | @@ -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 | #else | 1454 | #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 | #endif | 1457 | #endif |
| 1288 | } | 1458 | } |
| 1289 | 1459 | ||
| 1290 | zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow); | ||
| 1291 | static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { | 1460 | static 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 | #endif | 1469 | #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 | } |
| 1303 | 1473 | ||
| ... | @@ -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 | #else | 1480 | #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 | #endif | 1485 | #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 | #else | 1494 | #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 | #endif | 1499 | #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 | #else | 1508 | #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 | #endif | 1513 | #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 | #else | 1522 | #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 | #endif | 1527 | #endif |
| 1358 | } | 1528 | } |
| 1359 | 1529 | ||
| 1360 | #if defined(zig_ez80) | 1530 | #if defined(zig_ez80) |
| 1531 | |||
| 1361 | static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1532 | static 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 | #else | 1538 | #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 | #endif | 1543 | #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 | #else | 1552 | #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 | #endif | 1557 | #endif |
| 1387 | } | 1558 | } |
| 1388 | #endif | ||
| 1389 | 1559 | ||
| 1390 | #if defined(zig_ez80) | ||
| 1391 | static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1560 | static 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 | #else | 1566 | #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 | #endif | 1571 | #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 | #else | 1580 | #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 | #endif | 1585 | #endif |
| 1417 | } | 1586 | } |
| 1587 | |||
| 1418 | #endif | 1588 | #endif |
| 1419 | 1589 | ||
| 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 | } |
| 1477 | zig_int_builtins(8) | 1652 | zig_int_sat_builtins(8) |
| 1478 | zig_int_builtins(16) | 1653 | zig_int_sat_builtins(16) |
| 1479 | #if defined(zig_ez80) | 1654 | zig_int_sat_builtins(32) |
| 1480 | zig_int_builtins(24) | 1655 | zig_int_sat_builtins(64) |
| 1481 | #endif | ||
| 1482 | zig_int_builtins(32) | ||
| 1483 | #if defined(zig_ez80) | 1656 | #if defined(zig_ez80) |
| 1484 | zig_int_builtins(48) | 1657 | zig_int_sat_builtins(24) |
| 1658 | zig_int_sat_builtins(48) | ||
| 1485 | #endif | 1659 | #endif |
| 1486 | zig_int_builtins(64) | ||
| 1487 | 1660 | ||
| 1488 | #define zig_builtin8(name, val) __builtin_##name(val) | 1661 | #define zig_builtin8(name, arg) __builtin_##name(arg) |
| 1489 | typedef unsigned int zig_Builtin8; | 1662 | typedef unsigned int zig_Builtin8; |
| 1490 | 1663 | ||
| 1491 | #define zig_builtin16(name, val) __builtin_##name(val) | 1664 | #define zig_builtin16(name, arg) __builtin_##name(arg) |
| 1492 | typedef unsigned int zig_Builtin16; | 1665 | typedef unsigned int zig_Builtin16; |
| 1493 | 1666 | ||
| 1494 | #if defined(zig_ez80) | ||
| 1495 | #define zig_builtin24(name, val) __builtin_##name(val) | ||
| 1496 | typedef unsigned int zig_Builtin24; | ||
| 1497 | #endif | ||
| 1498 | |||
| 1499 | #if INT_MIN <= INT32_MIN | 1667 | #if INT_MIN <= INT32_MIN |
| 1500 | #define zig_builtin32(name, val) __builtin_##name(val) | 1668 | #define zig_builtin32(name, arg) __builtin_##name(arg) |
| 1501 | typedef unsigned int zig_Builtin32; | 1669 | typedef unsigned int zig_Builtin32; |
| 1502 | #elif LONG_MIN <= INT32_MIN | 1670 | #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) |
| 1504 | typedef unsigned long zig_Builtin32; | 1672 | typedef unsigned long zig_Builtin32; |
| 1505 | #endif | 1673 | #endif |
| 1506 | 1674 | ||
| 1507 | #if defined(zig_ez80) | ||
| 1508 | #define zig_builtin48(name, val) __builtin_##name(val) | ||
| 1509 | typedef unsigned long long zig_Builtin48; | ||
| 1510 | #endif | ||
| 1511 | |||
| 1512 | #if INT_MIN <= INT64_MIN | 1675 | #if INT_MIN <= INT64_MIN |
| 1513 | #define zig_builtin64(name, val) __builtin_##name(val) | 1676 | #define zig_builtin64(name, arg) __builtin_##name(arg) |
| 1514 | typedef unsigned int zig_Builtin64; | 1677 | typedef unsigned int zig_Builtin64; |
| 1515 | #elif LONG_MIN <= INT64_MIN | 1678 | #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) |
| 1517 | typedef unsigned long zig_Builtin64; | 1680 | typedef unsigned long zig_Builtin64; |
| 1518 | #elif LLONG_MIN <= INT64_MIN | 1681 | #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) |
| 1520 | typedef unsigned long long zig_Builtin64; | 1683 | typedef unsigned long long zig_Builtin64; |
| 1521 | #endif | 1684 | #endif |
| 1522 | 1685 | ||
| 1523 | static 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) |
| 1688 | typedef unsigned int zig_Builtin24; | ||
| 1689 | #define zig_builtin48(name, arg) __builtin_##name(arg) | ||
| 1690 | typedef unsigned long long zig_Builtin48; | ||
| 1691 | #endif | ||
| 1692 | |||
| 1693 | static inline uint8_t zig_byteSwap_u8(uint8_t arg, uint8_t bits) { | ||
| 1694 | return zig_u8_truncate_u8(arg >> (8 - bits), bits); | ||
| 1525 | } | 1695 | } |
| 1526 | 1696 | ||
| 1527 | static inline int8_t zig_byte_swap_i8(int8_t val, uint8_t bits) { | 1697 | static 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 | } |
| 1530 | 1700 | ||
| 1531 | static inline uint16_t zig_byte_swap_u16(uint16_t val, uint8_t bits) { | 1701 | static 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 | #else | 1705 | #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 | #endif | 1708 | #endif |
| 1539 | return zig_wrap_u16(full_res >> (16 - bits), bits); | 1709 | return zig_u16_truncate_u16(full_res >> (16 - bits), bits); |
| 1540 | } | 1710 | } |
| 1541 | 1711 | ||
| 1542 | static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) { | 1712 | static 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 | } |
| 1545 | 1715 | ||
| 1546 | #if defined(zig_ez80) | 1716 | #if defined(zig_ez80) |
| 1547 | static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) { | 1717 | static 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 | #else | 1721 | #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 | #endif | 1724 | #endif |
| 1555 | return zig_wrap_u24(full_res >> (24 - bits), bits); | 1725 | return zig_u24_truncate_u24(full_res >> (24 - bits), bits); |
| 1556 | } | 1726 | } |
| 1557 | 1727 | ||
| 1558 | static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) { | 1728 | static 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 | #endif | 1731 | #endif |
| 1562 | 1732 | ||
| 1563 | static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) { | 1733 | static 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 | #else | 1737 | #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 | #endif | 1740 | #endif |
| 1571 | return zig_wrap_u32(full_res >> (32 - bits), bits); | 1741 | return zig_u32_truncate_u32(full_res >> (32 - bits), bits); |
| 1572 | } | 1742 | } |
| 1573 | 1743 | ||
| 1574 | static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) { | 1744 | static 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 | } |
| 1577 | 1747 | ||
| 1578 | #if defined(zig_ez80) | 1748 | #if defined(zig_ez80) |
| 1579 | static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) { | 1749 | static 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 | #else | 1753 | #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 | #endif | 1756 | #endif |
| 1587 | return zig_wrap_u48(full_res >> (48 - bits), bits); | 1757 | return zig_u48_truncate_u48(full_res >> (48 - bits), bits); |
| 1588 | } | 1758 | } |
| 1589 | 1759 | ||
| 1590 | static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) { | 1760 | static 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 | #endif | 1763 | #endif |
| 1594 | 1764 | ||
| 1595 | static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) { | 1765 | static 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 | #else | 1769 | #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 | #endif | 1772 | #endif |
| 1603 | return zig_wrap_u64(full_res >> (64 - bits), bits); | 1773 | return zig_u64_truncate_u64(full_res >> (64 - bits), bits); |
| 1604 | } | 1774 | } |
| 1605 | 1775 | ||
| 1606 | static inline int64_t zig_byte_swap_i64(int64_t val, uint8_t bits) { | 1776 | static 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 | } |
| 1609 | 1779 | ||
| 1610 | static inline uint8_t zig_bit_reverse_u8(uint8_t val, uint8_t bits) { | 1780 | static 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 | #else | 1784 | #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, 0xf | 1787 | 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 | #endif | 1790 | #endif |
| 1621 | return zig_wrap_u8(full_res >> (8 - bits), bits); | 1791 | return zig_u8_truncate_u8(full_res >> (8 - bits), bits); |
| 1622 | } | 1792 | } |
| 1623 | 1793 | ||
| 1624 | static inline int8_t zig_bit_reverse_i8(int8_t val, uint8_t bits) { | 1794 | static 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 | } |
| 1627 | 1797 | ||
| 1628 | static inline uint16_t zig_bit_reverse_u16(uint16_t val, uint8_t bits) { | 1798 | static 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 | #else | 1802 | #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 | #endif | 1805 | #endif |
| 1636 | return zig_wrap_u16(full_res >> (16 - bits), bits); | 1806 | return zig_u16_truncate_u16(full_res >> (16 - bits), bits); |
| 1637 | } | 1807 | } |
| 1638 | 1808 | ||
| 1639 | static inline int16_t zig_bit_reverse_i16(int16_t val, uint8_t bits) { | 1809 | static 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 | } |
| 1642 | 1812 | ||
| 1643 | #if defined(zig_ez80) | 1813 | #if defined(zig_ez80) |
| 1644 | static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) { | 1814 | static 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 | #else | 1818 | #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 | #endif | 1821 | #endif |
| 1652 | return zig_wrap_u24(full_res >> (24 - bits), bits); | 1822 | return zig_u24_truncate_u24(full_res >> (24 - bits), bits); |
| 1653 | } | 1823 | } |
| 1654 | 1824 | ||
| 1655 | static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) { | 1825 | static 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 | #endif | 1828 | #endif |
| 1659 | 1829 | ||
| 1660 | static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) { | 1830 | static 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 | #else | 1834 | #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 | #endif | 1837 | #endif |
| 1668 | return zig_wrap_u32(full_res >> (32 - bits), bits); | 1838 | return zig_u32_truncate_u32(full_res >> (32 - bits), bits); |
| 1669 | } | 1839 | } |
| 1670 | 1840 | ||
| 1671 | static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) { | 1841 | static 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 | } |
| 1674 | 1844 | ||
| 1675 | #if defined(zig_ez80) | 1845 | #if defined(zig_ez80) |
| 1676 | static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) { | 1846 | static 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 | #else | 1850 | #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 | #endif | 1853 | #endif |
| 1684 | return zig_wrap_u32(full_res >> (48 - bits), bits); | 1854 | return zig_u48_truncate_u48(full_res >> (48 - bits), bits); |
| 1685 | } | 1855 | } |
| 1686 | 1856 | ||
| 1687 | static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) { | 1857 | static 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 | #endif | 1860 | #endif |
| 1691 | 1861 | ||
| 1692 | static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) { | 1862 | static 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 | #else | 1866 | #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 | #endif | 1869 | #endif |
| 1700 | return zig_wrap_u64(full_res >> (64 - bits), bits); | 1870 | return zig_u64_truncate_u64(full_res >> (64 - bits), bits); |
| 1701 | } | 1871 | } |
| 1702 | 1872 | ||
| 1703 | static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) { | 1873 | static 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 | } |
| 1706 | 1876 | ||
| 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 | #else | 1889 | #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 | ||
| 1731 | zig_builtin_popcount(8) | ||
| 1732 | zig_builtin_popcount(16) | ||
| 1733 | #if defined(zig_ez80) | ||
| 1734 | zig_builtin_popcount(24) | ||
| 1735 | #endif | 1900 | #endif |
| 1736 | zig_builtin_popcount(32) | 1901 | zig_builtin_popCount(8) |
| 1902 | zig_builtin_popCount(16) | ||
| 1903 | zig_builtin_popCount(32) | ||
| 1904 | zig_builtin_popCount(64) | ||
| 1737 | #if defined(zig_ez80) | 1905 | #if defined(zig_ez80) |
| 1738 | zig_builtin_popcount(48) | 1906 | zig_builtin_popCount(24) |
| 1907 | zig_builtin_popCount(48) | ||
| 1739 | #endif | 1908 | #endif |
| 1740 | zig_builtin_popcount(64) | ||
| 1741 | 1909 | ||
| 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 | #else | 1922 | #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 | #endif | 1929 | #endif |
| 1762 | zig_builtin_ctz(8) | 1930 | zig_builtin_ctz(8) |
| 1763 | zig_builtin_ctz(16) | 1931 | zig_builtin_ctz(16) |
| 1764 | #if defined(zig_ez80) | ||
| 1765 | zig_builtin_ctz(24) | ||
| 1766 | #endif | ||
| 1767 | zig_builtin_ctz(32) | 1932 | zig_builtin_ctz(32) |
| 1933 | zig_builtin_ctz(64) | ||
| 1768 | #if defined(zig_ez80) | 1934 | #if defined(zig_ez80) |
| 1935 | zig_builtin_ctz(24) | ||
| 1769 | zig_builtin_ctz(48) | 1936 | zig_builtin_ctz(48) |
| 1770 | #endif | 1937 | #endif |
| 1771 | zig_builtin_ctz(64) | ||
| 1772 | 1938 | ||
| 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 | #else | 1951 | #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 | #endif | 1958 | #endif |
| 1793 | zig_builtin_clz(8) | 1959 | zig_builtin_clz(8) |
| 1794 | zig_builtin_clz(16) | 1960 | zig_builtin_clz(16) |
| 1795 | #if defined(zig_ez80) | ||
| 1796 | zig_builtin_clz(24) | ||
| 1797 | #endif | ||
| 1798 | zig_builtin_clz(32) | 1961 | zig_builtin_clz(32) |
| 1962 | zig_builtin_clz(64) | ||
| 1799 | #if defined(zig_ez80) | 1963 | #if defined(zig_ez80) |
| 1964 | zig_builtin_clz(24) | ||
| 1800 | zig_builtin_clz(48) | 1965 | zig_builtin_clz(48) |
| 1801 | #endif | 1966 | #endif |
| 1802 | zig_builtin_clz(64) | ||
| 1803 | 1967 | ||
| 1804 | /* ======================== 128-bit Integer Support ========================= */ | 1968 | /* ======================== 128-bit Integer Support ========================= */ |
| 1805 | 1969 | ||
| ... | @@ -1816,16 +1980,14 @@ zig_builtin_clz(64) | ... | @@ -1816,16 +1980,14 @@ zig_builtin_clz(64) |
| 1816 | typedef unsigned __int128 zig_u128; | 1980 | typedef unsigned __int128 zig_u128; |
| 1817 | typedef signed __int128 zig_i128; | 1981 | typedef signed __int128 zig_i128; |
| 1818 | 1982 | ||
| 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 | } |
| 1837 | 1999 | ||
| 1838 | #else /* zig_has_int128 */ | 2000 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { |
| 2001 | return lhs << rhs; | ||
| 2002 | } | ||
| 1839 | 2003 | ||
| 1840 | #if zig_little_endian | 2004 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { |
| 1841 | typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128; | 2005 | return lhs >> rhs; |
| 1842 | typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128; | 2006 | } |
| 2007 | |||
| 2008 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2009 | return lhs << rhs; | ||
| 2010 | } | ||
| 2011 | |||
| 2012 | static 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 | #else | 2019 | #else |
| 1844 | typedef 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); |
| 1845 | typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; | 2021 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; |
| 1846 | #endif | 2022 | #endif |
| 2023 | } | ||
| 1847 | 2024 | ||
| 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) }) | ||
| 1850 | 2026 | ||
| 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) } | 2028 | typedef 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) } | 2029 | typedef 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) | 2031 | typedef 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) | 2032 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) int64_t hi; uint64_t lo; } zig_i128; |
| 1857 | #endif | 2033 | #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 | } |
| 1874 | 2053 | ||
| 2054 | static 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 | |||
| 2060 | static 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 | |||
| 2066 | static 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 | |||
| 2072 | static 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 */ |
| 1876 | 2079 | ||
| 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, |) |
| 1891 | zig_bit_int128(u128, xor, ^) | 2094 | zig_bit_int128(u128, xor, ^) |
| 1892 | zig_bit_int128(i128, xor, ^) | 2095 | zig_bit_int128(i128, xor, ^) |
| 1893 | 2096 | ||
| 1894 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs); | 2097 | static inline uint8_t zig_u8_intCast_u128(zig_u128 arg) { |
| 2098 | return (uint8_t)zig_lo_u128(arg); | ||
| 2099 | } | ||
| 2100 | static inline uint8_t zig_u8_intCast_i128(zig_i128 arg) { | ||
| 2101 | return (uint8_t)zig_lo_i128(arg); | ||
| 2102 | } | ||
| 2103 | static inline int8_t zig_i8_intCast_i128(zig_i128 arg) { | ||
| 2104 | return (int8_t)zig_lo_i128(arg); | ||
| 2105 | } | ||
| 2106 | static inline int8_t zig_i8_intCast_u128(zig_u128 arg) { | ||
| 2107 | return (int8_t)zig_lo_u128(arg); | ||
| 2108 | } | ||
| 1895 | 2109 | ||
| 1896 | #if zig_has_int128 | 2110 | static inline uint16_t zig_u16_intCast_u128(zig_u128 arg) { |
| 2111 | return (uint16_t)zig_lo_u128(arg); | ||
| 2112 | } | ||
| 2113 | static inline uint16_t zig_u16_intCast_i128(zig_i128 arg) { | ||
| 2114 | return (uint16_t)zig_lo_i128(arg); | ||
| 2115 | } | ||
| 2116 | static inline int16_t zig_i16_intCast_i128(zig_i128 arg) { | ||
| 2117 | return (int16_t)zig_lo_i128(arg); | ||
| 2118 | } | ||
| 2119 | static inline int16_t zig_i16_intCast_u128(zig_u128 arg) { | ||
| 2120 | return (int16_t)zig_lo_u128(arg); | ||
| 2121 | } | ||
| 1897 | 2122 | ||
| 1898 | static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) { | 2123 | static 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 | } | ||
| 2126 | static inline uint32_t zig_u32_intCast_i128(zig_i128 arg) { | ||
| 2127 | return (uint32_t)zig_lo_i128(arg); | ||
| 2128 | } | ||
| 2129 | static inline int32_t zig_i32_intCast_i128(zig_i128 arg) { | ||
| 2130 | return (int32_t)zig_lo_i128(arg); | ||
| 2131 | } | ||
| 2132 | static inline int32_t zig_i32_intCast_u128(zig_u128 arg) { | ||
| 2133 | return (int32_t)zig_lo_u128(arg); | ||
| 1900 | } | 2134 | } |
| 1901 | 2135 | ||
| 1902 | static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) { | 2136 | static inline uint64_t zig_u64_intCast_u128(zig_u128 arg) { |
| 1903 | (void)bits; | 2137 | return zig_lo_u128(arg); |
| 1904 | return ~val; | 2138 | } |
| 2139 | static inline uint64_t zig_u64_intCast_i128(zig_i128 arg) { | ||
| 2140 | return zig_lo_i128(arg); | ||
| 2141 | } | ||
| 2142 | static inline int64_t zig_i64_intCast_i128(zig_i128 arg) { | ||
| 2143 | return (int64_t)zig_lo_i128(arg); | ||
| 2144 | } | ||
| 2145 | static inline int64_t zig_i64_intCast_u128(zig_u128 arg) { | ||
| 2146 | return (int64_t)zig_lo_u128(arg); | ||
| 1905 | } | 2147 | } |
| 1906 | 2148 | ||
| 1907 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { | 2149 | static inline zig_u128 zig_u128_intCast_u8(uint8_t arg) { |
| 1908 | return lhs >> rhs; | 2150 | return zig_make_u128(UINT8_C(0), arg); |
| 2151 | } | ||
| 2152 | static inline zig_u128 zig_u128_intCast_i8(int8_t arg) { | ||
| 2153 | return zig_make_u128(UINT8_C(0), (uint8_t)arg); | ||
| 2154 | } | ||
| 2155 | static inline zig_i128 zig_i128_intCast_i8(int8_t arg) { | ||
| 2156 | return zig_make_i128(zig_shr_i64(arg, 63), (uint8_t)arg); | ||
| 2157 | } | ||
| 2158 | static inline zig_i128 zig_i128_intCast_u8(uint8_t arg) { | ||
| 2159 | return zig_make_i128(INT8_C(0), arg); | ||
| 1909 | } | 2160 | } |
| 1910 | 2161 | ||
| 1911 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { | 2162 | static inline zig_u128 zig_u128_intCast_u16(uint16_t arg) { |
| 1912 | return lhs << rhs; | 2163 | return zig_make_u128(UINT16_C(0), arg); |
| 2164 | } | ||
| 2165 | static inline zig_u128 zig_u128_intCast_i16(int16_t arg) { | ||
| 2166 | return zig_make_u128(UINT16_C(0), (uint16_t)arg); | ||
| 2167 | } | ||
| 2168 | static inline zig_i128 zig_i128_intCast_i16(int16_t arg) { | ||
| 2169 | return zig_make_i128(zig_shr_i64(arg, 63), (uint16_t)arg); | ||
| 2170 | } | ||
| 2171 | static inline zig_i128 zig_i128_intCast_u16(uint16_t arg) { | ||
| 2172 | return zig_make_i128(INT16_C(0), arg); | ||
| 1913 | } | 2173 | } |
| 1914 | 2174 | ||
| 1915 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | 2175 | static inline zig_u128 zig_u128_intCast_u32(uint32_t arg) { |
| 1916 | // This works around a GCC miscompilation, but it has the side benefit of | 2176 | return zig_make_u128(UINT32_C(0), arg); |
| 1917 | // emitting better code. It is behind the `#if` because it depends on | 2177 | } |
| 1918 | // arithmetic right shift, which is implementation-defined in C, but should | 2178 | static 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; | 2181 | static inline zig_i128 zig_i128_intCast_i32(int32_t arg) { |
| 2182 | return zig_make_i128(zig_shr_i64(arg, 63), (uint32_t)arg); | ||
| 2183 | } | ||
| 2184 | static inline zig_i128 zig_i128_intCast_u32(uint32_t arg) { | ||
| 2185 | return zig_make_i128(INT32_C(0), arg); | ||
| 2186 | } | ||
| 2187 | |||
| 2188 | static inline zig_u128 zig_u128_intCast_u64(uint64_t arg) { | ||
| 2189 | return zig_make_u128(UINT64_C(0), arg); | ||
| 2190 | } | ||
| 2191 | static inline zig_u128 zig_u128_intCast_i64(int64_t arg) { | ||
| 2192 | return zig_make_u128(UINT64_C(0), (uint64_t)arg); | ||
| 2193 | } | ||
| 2194 | static inline zig_i128 zig_i128_intCast_i64(int64_t arg) { | ||
| 2195 | return zig_make_i128(zig_shr_i64(arg, 63), (uint64_t)arg); | ||
| 2196 | } | ||
| 2197 | static inline zig_i128 zig_i128_intCast_u64(uint64_t arg) { | ||
| 2198 | return zig_make_i128(INT64_C(0), arg); | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | static inline zig_u128 zig_u128_intCast_u128(zig_u128 arg) { | ||
| 2202 | return arg; | ||
| 2203 | } | ||
| 2204 | static inline zig_u128 zig_u128_intCast_i128(zig_i128 arg) { | ||
| 2205 | #if zig_has_int128 | ||
| 2206 | return (zig_u128)arg; | ||
| 1922 | #else | 2207 | #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 | } | ||
| 2211 | static inline zig_i128 zig_i128_intCast_i128(zig_i128 arg) { | ||
| 2212 | return arg; | ||
| 2213 | } | ||
| 2214 | static 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 | #endif | 2219 | #endif |
| 1926 | } | 2220 | } |
| 1927 | 2221 | ||
| 1928 | static 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 | } | ||
| 2230 | zig_int128_cast_builtins(8) | ||
| 2231 | zig_int128_cast_builtins(16) | ||
| 2232 | zig_int128_cast_builtins(32) | ||
| 2233 | zig_int128_cast_builtins(64) | ||
| 2234 | |||
| 2235 | static 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 | } | ||
| 2238 | static 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 | |||
| 2244 | static inline zig_u128 zig_u128_bitCast_u128(zig_u128 arg, uint8_t bits) { | ||
| 2245 | (void)bits; | ||
| 2246 | return arg; | ||
| 2247 | } | ||
| 2248 | static 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 | } | ||
| 2251 | static inline zig_i128 zig_i128_bitCast_i128(zig_i128 arg, uint8_t bits) { | ||
| 2252 | (void)bits; | ||
| 2253 | return arg; | ||
| 2254 | } | ||
| 2255 | static 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 | |||
| 2261 | static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) { | ||
| 2262 | return arg ^ zig_maxInt_u(128, bits); | ||
| 2263 | } | ||
| 2264 | |||
| 2265 | static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) { | ||
| 2266 | (void)bits; | ||
| 2267 | return ~arg; | ||
| 1930 | } | 2268 | } |
| 1931 | 2269 | ||
| 1932 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { | 2270 | static 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 | } |
| 1955 | 2293 | ||
| 1956 | static inline zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { | 2294 | static inline zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1957 | return lhs / rhs; | 2295 | return lhs / rhs; |
| 1958 | } | 2296 | } |
| 1959 | 2297 | ||
| 1960 | static inline zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { | 2298 | static inline zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1961 | return lhs / rhs; | 2299 | return lhs / rhs; |
| 1962 | } | 2300 | } |
| 1963 | 2301 | ||
| ... | @@ -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) { |
| 1971 | 2309 | ||
| 1972 | #else /* zig_has_int128 */ | 2310 | #else /* zig_has_int128 */ |
| 1973 | 2311 | ||
| 1974 | static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) { | 2312 | static 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 | |||
| 1978 | static 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 | |||
| 1982 | static 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 | |||
| 1988 | static 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 | |||
| 1994 | static 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 | } |
| 1999 | 2316 | ||
| 2000 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | 2317 | static 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 | } |
| 2005 | 2321 | ||
| 2006 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { | 2322 | static 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 | } |
| 2029 | 2345 | ||
| 2030 | zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs); | ||
| 2031 | static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { | 2346 | static 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 | } |
| 2034 | 2350 | ||
| 2035 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) { | 2351 | static 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 | } |
| 2038 | 2354 | ||
| 2039 | zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); | 2355 | static zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2040 | static 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 | } |
| 2043 | 2359 | ||
| 2044 | zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs); | 2360 | static zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2045 | static 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 | } |
| 2048 | 2364 | ||
| 2049 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); | ||
| 2050 | static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) { | 2365 | static 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 | } |
| 2053 | 2369 | ||
| 2054 | zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs); | ||
| 2055 | static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { | 2370 | static 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 | } |
| 2058 | 2374 | ||
| 2059 | #endif /* zig_has_int128 */ | 2375 | #endif /* zig_has_int128 */ |
| 2060 | 2376 | ||
| 2061 | #define zig_div_floor_u128 zig_div_trunc_u128 | 2377 | #define zig_divFloor_u128 zig_divTrunc_u128 |
| 2062 | 2378 | ||
| 2063 | static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) { | 2379 | static 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 | } |
| 2069 | 2385 | ||
| 2070 | static inline zig_u128 zig_div_ceil_u128(zig_u128 lhs, zig_u128 rhs) { | 2386 | static 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 | } |
| 2076 | 2392 | ||
| 2077 | static inline zig_i128 zig_div_ceil_i128(zig_i128 lhs, zig_i128 rhs) { | 2393 | static 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 | } |
| 2084 | 2400 | ||
| 2085 | #define zig_mod_u128 zig_rem_u128 | 2401 | #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 | } |
| 2109 | 2425 | ||
| 2110 | static 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 | |||
| 2114 | static 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 | |||
| 2120 | static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) { | 2426 | static 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 | } |
| 2123 | 2429 | ||
| 2124 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 2430 | static 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 | } |
| 2127 | 2433 | ||
| 2128 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2434 | static 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 | } |
| 2131 | 2437 | ||
| 2132 | static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2438 | static 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 | } |
| 2135 | 2441 | ||
| 2136 | static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2442 | static 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 | } |
| 2139 | 2445 | ||
| 2140 | static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2446 | static 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 | } |
| 2143 | 2449 | ||
| 2144 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2450 | static 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 | } |
| 2147 | 2453 | ||
| 2148 | static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2454 | static 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 | } |
| 2151 | 2457 | ||
| 2152 | static inline zig_u128 zig_abs_i128(zig_i128 val) { | 2458 | static 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 | } |
| 2156 | 2462 | ||
| 2157 | #if zig_has_int128 | 2463 | #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 | #else | 2471 | #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 | #endif | 2484 | #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 | } |
| 2182 | 2488 | ||
| ... | @@ -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 | #else | 2495 | #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 | #endif | 2508 | #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 | } |
| 2206 | 2512 | ||
| ... | @@ -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 | #else | 2519 | #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 | #endif | 2522 | #endif |
| 2217 | } | 2523 | } |
| 2218 | 2524 | ||
| 2219 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2220 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2525 | static 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 | #endif | 2534 | #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 | } |
| 2232 | 2538 | ||
| 2233 | #else /* zig_has_int128 */ | 2539 | #else /* zig_has_int128 */ |
| 2234 | 2540 | ||
| 2235 | static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2541 | static 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 | } |
| 2240 | 2553 | ||
| 2241 | static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2554 | static 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 | } |
| 2246 | 2566 | ||
| 2247 | static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2567 | static 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 | } |
| 2252 | 2579 | ||
| 2253 | static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2580 | static 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 | } |
| 2258 | 2592 | ||
| 2259 | static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2593 | static 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 | } |
| 2264 | 2598 | ||
| 2265 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2266 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2599 | static 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 | } |
| 2275 | 2609 | ||
| ... | @@ -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 |
| 2282 | 2616 | ||
| 2283 | static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 2617 | static 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 | } |
| 2289 | 2623 | ||
| 2290 | static 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 | } | ||
| 2645 | zig_int128_shls_builtins(8) | ||
| 2646 | zig_int128_shls_builtins(16) | ||
| 2647 | zig_int128_shls_builtins(32) | ||
| 2648 | zig_int128_shls_builtins(64) | ||
| 2649 | |||
| 2650 | static 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 | } |
| 2299 | 2659 | ||
| 2300 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) { | 2660 | static 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 | } |
| 2343 | 2703 | ||
| 2344 | static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) { | 2704 | static 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 | } |
| 2349 | 2709 | ||
| 2350 | static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) { | 2710 | static 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 | } |
| 2353 | 2713 | ||
| 2354 | static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) { | 2714 | static 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 | } |
| 2358 | 2718 | ||
| 2359 | static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) { | 2719 | static 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 | } |
| 2362 | 2722 | ||
| 2363 | static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) { | 2723 | static 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 | } |
| 2367 | 2727 | ||
| 2368 | static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) { | 2728 | static 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 | } |
| 2371 | 2731 | ||
| 2372 | static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) { | 2732 | static 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 | #else | 2736 | #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 | #endif | 2741 | #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 | } |
| 2382 | 2744 | ||
| 2383 | static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) { | 2745 | static 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 | } |
| 2386 | 2748 | ||
| 2387 | static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) { | 2749 | static 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 | } |
| 2392 | 2755 | ||
| 2393 | static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { | 2756 | static 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 | } |
| 2396 | 2759 | ||
| 2397 | #if zig_has_int128 | 2760 | #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 =========================== */ |
| 2412 | 2775 | ||
| 2413 | static inline uint16_t zig_int_bytes(uint16_t bits) { | 2776 | static 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 | } |
| 2419 | 2783 | ||
| 2420 | static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 2784 | static 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 | |||
| 2816 | static 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 | |||
| 2848 | static 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 | |||
| 2859 | static 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 | |||
| 2876 | static 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 | } | ||
| 2940 | zig_big_casts(false, u, 8, uint8_t) | ||
| 2941 | zig_big_casts(true , i, 8, int8_t) | ||
| 2942 | zig_big_casts(false, u, 16, uint16_t) | ||
| 2943 | zig_big_casts(true , i, 16, int16_t) | ||
| 2944 | zig_big_casts(false, u, 32, uint32_t) | ||
| 2945 | zig_big_casts(true , i, 32, int32_t) | ||
| 2946 | zig_big_casts(false, u, 64, uint64_t) | ||
| 2947 | zig_big_casts(true , i, 64, int64_t) | ||
| 2948 | zig_big_casts(false, u, 128, zig_u128) | ||
| 2949 | zig_big_casts(true , i, 128, zig_i128) | ||
| 2950 | |||
| 2951 | static 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 | |||
| 2987 | static 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 | #endif | 2995 | #endif |
| 2430 | 2996 | ||
| 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; |
| 2433 | 3000 | ||
| 2434 | #if zig_little_endian | 3001 | #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 |
| 2437 | 3004 | ||
| 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); |
| 2441 | 3008 | ||
| 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); |
| 2449 | 3015 | ||
| 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 | } |
| 2454 | 3019 | ||
| ... | @@ -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 | } |
| 2462 | 3027 | ||
| 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_endian | 3031 | #if zig_little_endian |
| 2465 | byte_offset -= 64 / CHAR_BIT; | 3032 | byte_offset -= 64 / CHAR_BIT; |
| 2466 | #endif | 3033 | #endif |
| 2467 | 3034 | ||
| 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); |
| 2471 | 3038 | ||
| 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); |
| 2479 | 3045 | ||
| 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 | } |
| 2484 | 3049 | ||
| ... | @@ -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 | } |
| 2491 | 3056 | ||
| 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_endian | 3060 | #if zig_little_endian |
| 2494 | byte_offset -= 32 / CHAR_BIT; | 3061 | byte_offset -= 32 / CHAR_BIT; |
| 2495 | #endif | 3062 | #endif |
| 2496 | 3063 | ||
| 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); |
| 2500 | 3067 | ||
| 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); |
| 2508 | 3074 | ||
| 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 | } |
| 2513 | 3078 | ||
| ... | @@ -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 | } |
| 2520 | 3085 | ||
| 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_endian | 3089 | #if zig_little_endian |
| 2523 | byte_offset -= 16 / CHAR_BIT; | 3090 | byte_offset -= 16 / CHAR_BIT; |
| 2524 | #endif | 3091 | #endif |
| 2525 | 3092 | ||
| 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); |
| 2529 | 3096 | ||
| 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); |
| 2537 | 3103 | ||
| 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 | } |
| 2542 | 3107 | ||
| ... | @@ -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 | } |
| 2549 | 3114 | ||
| 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_endian | 3118 | #if zig_little_endian |
| 2552 | byte_offset -= 8 / CHAR_BIT; | 3119 | byte_offset -= 8 / CHAR_BIT; |
| 2553 | #endif | 3120 | #endif |
| 2554 | 3121 | ||
| 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); | ||
| 2558 | 3126 | ||
| 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; |
| 2566 | 3134 | ||
| 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 | } |
| 2571 | 3138 | ||
| ... | @@ -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 | } |
| 2581 | 3148 | ||
| 2582 | static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 3149 | static 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 | ||
| 2589 | 3159 | ||
| 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; | ||
| 2594 | 3162 | ||
| 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 | } | ||
| 2599 | 3183 | ||
| 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 | } |
| 2603 | 3191 | ||
| 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 |
| 2608 | 3196 | ||
| 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 | } | ||
| 2613 | 3213 | ||
| 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 | } |
| 2617 | 3220 | ||
| 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 |
| 2622 | 3225 | ||
| 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 | } | ||
| 2627 | 3242 | ||
| 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 | } |
| 2631 | 3249 | ||
| 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 |
| 2636 | 3254 | ||
| 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 | } | ||
| 2641 | 3271 | ||
| 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 | } |
| 2645 | 3278 | ||
| 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 |
| 2650 | 3283 | ||
| 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 | } | ||
| 2655 | 3300 | ||
| 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 | } |
| 2660 | 3310 | ||
| 2661 | static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 3311 | static 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 | ||
| 2668 | 3321 | ||
| 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; | ||
| 2673 | 3324 | ||
| 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 | } | ||
| 2678 | 3344 | ||
| 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 | } |
| 2682 | 3351 | ||
| 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; | ||
| 2687 | 3354 | ||
| 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 | } | ||
| 2692 | 3374 | ||
| 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 | } |
| 2696 | 3381 | ||
| 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; | ||
| 2701 | 3384 | ||
| 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 | } | ||
| 2706 | 3404 | ||
| 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 | } |
| 2710 | 3411 | ||
| 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; | ||
| 2715 | 3414 | ||
| 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)); | ||
| 2720 | 3418 | ||
| 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 | |||
| 3473 | static 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 | |||
| 3552 | static 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 | } | ||
| 2724 | 3615 | ||
| 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 | } |
| 2818 | 3709 | ||
| 3710 | static 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 | |||
| 3841 | static 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 | |||
| 3972 | static 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 | |||
| 4104 | static 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 | |||
| 4108 | static 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 | |||
| 2819 | static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 4112 | static 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; |
| 2827 | 4120 | ||
| 2828 | #if zig_big_endian | 4121 | #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; |
| 3043 | 4336 | ||
| 3044 | #if zig_big_endian | 4337 | #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 | } |
| 3240 | 4533 | ||
| 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 | |||
| 4544 | static 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 | |||
| 4548 | static 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 | |||
| 4552 | static 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 | |||
| 4562 | static 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 | |||
| 4566 | static 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 | |||
| 4570 | static 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 | |||
| 4580 | static 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 | |||
| 4801 | static 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 | |||
| 4805 | static 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 | |||
| 4809 | static 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 | |||
| 4819 | static 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 | |||
| 4829 | static 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 | |||
| 4839 | static 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 | |||
| 4853 | static 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 | |||
| 4865 | static 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 | |||
| 4875 | static 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 | |||
| 4950 | static 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 | |||
| 5094 | static 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 | |||
| 5098 | static 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 | } | ||
| 5132 | zig_big_shls_builtin(8) | ||
| 5133 | zig_big_shls_builtin(16) | ||
| 5134 | zig_big_shls_builtin(32) | ||
| 5135 | zig_big_shls_builtin(64) | ||
| 5136 | |||
| 5137 | static 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]; | ||
| 3242 | 5159 | ||
| 3243 | #if zig_little_endian | 5160 | #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 | #endif | 5164 | #endif |
| 3246 | } | 5165 | } |
| 3247 | 5166 | ||
| 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 | ||
| 3250 | 5173 | ||
| 3251 | static 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); | ||
| 3254 | 5179 | ||
| 3255 | static 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 | } | ||
| 3258 | 5181 | ||
| 3259 | zig_extern void __udivei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits); | 5182 | #if zig_little_endian |
| 3260 | static 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 | } |
| 3268 | 5191 | ||
| 3269 | static inline void zig_div_floor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5192 | static 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))); | ||
| 3274 | 5201 | ||
| 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 | ||
| 3277 | 5207 | ||
| 3278 | static 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 | ||
| 3281 | 5212 | ||
| 3282 | zig_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)); |
| 3283 | static 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 | } |
| 3288 | 5219 | ||
| 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 | ||
| 3291 | 5226 | ||
| 3292 | static 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 | } |
| 3297 | 5243 | ||
| 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 | } |
| 3300 | 5268 | ||
| 3301 | static inline uint16_t zig_clz_big(const void *val, bool is_signed, uint16_t bits) { | 5269 | static 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; |
| 3309 | 5276 | ||
| 3310 | #if zig_little_endian | 5277 | #if zig_big_endian |
| 3311 | byte_offset = remaining_bytes; | 5278 | byte_offset = zig_int_bytes(bits); |
| 3312 | #endif | 5279 | #endif |
| 3313 | 5280 | ||
| 3314 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5281 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 3315 | #if zig_little_endian | 5282 | 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 | #endif | 5286 | #endif |
| 3318 | 5287 | ||
| 3319 | { | 5288 | { |
| 3320 | zig_u128 val_limb; | 5289 | zig_u128 arg_limb; |
| 3321 | 5290 | ||
| 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 | } |
| 3325 | 5294 | ||
| 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; |
| 3330 | 5296 | ||
| 3331 | #if zig_big_endian | 5297 | #if zig_little_endian |
| 3332 | byte_offset += 128 / CHAR_BIT; | 5298 | byte_offset += 128 / CHAR_BIT; |
| 3333 | #endif | 5299 | #endif |
| 3334 | } | 5300 | } |
| 3335 | 5301 | ||
| 3336 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5302 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3337 | #if zig_little_endian | 5303 | 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 | #endif | 5307 | #endif |
| 3340 | 5308 | ||
| 3341 | { | 5309 | { |
| 3342 | uint64_t val_limb; | 5310 | uint64_t arg_limb; |
| 3343 | 5311 | ||
| 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 | } |
| 3347 | 5315 | ||
| 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; |
| 3352 | 5317 | ||
| 3353 | #if zig_big_endian | 5318 | #if zig_little_endian |
| 3354 | byte_offset += 64 / CHAR_BIT; | 5319 | byte_offset += 64 / CHAR_BIT; |
| 3355 | #endif | 5320 | #endif |
| 3356 | } | 5321 | } |
| 3357 | 5322 | ||
| 3358 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5323 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3359 | #if zig_little_endian | 5324 | 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 | #endif | 5328 | #endif |
| 3362 | 5329 | ||
| 3363 | { | 5330 | { |
| 3364 | uint32_t val_limb; | 5331 | uint32_t arg_limb; |
| 3365 | 5332 | ||
| 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 | } |
| 3369 | 5336 | ||
| 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; |
| 3374 | 5338 | ||
| 3375 | #if zig_big_endian | 5339 | #if zig_little_endian |
| 3376 | byte_offset += 32 / CHAR_BIT; | 5340 | byte_offset += 32 / CHAR_BIT; |
| 3377 | #endif | 5341 | #endif |
| 3378 | } | 5342 | } |
| 3379 | 5343 | ||
| 3380 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5344 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3381 | #if zig_little_endian | 5345 | 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 | #endif | 5349 | #endif |
| 3384 | 5350 | ||
| 3385 | { | 5351 | { |
| 3386 | uint16_t val_limb; | 5352 | uint16_t arg_limb; |
| 3387 | 5353 | ||
| 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 | } |
| 3391 | 5357 | ||
| 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; |
| 3396 | 5359 | ||
| 3397 | #if zig_big_endian | 5360 | #if zig_little_endian |
| 3398 | byte_offset += 16 / CHAR_BIT; | 5361 | byte_offset += 16 / CHAR_BIT; |
| 3399 | #endif | 5362 | #endif |
| 3400 | } | 5363 | } |
| 3401 | 5364 | ||
| 3402 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5365 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3403 | #if zig_little_endian | 5366 | 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 | #endif | 5370 | #endif |
| 3406 | 5371 | ||
| 3407 | { | 5372 | { |
| 3408 | uint8_t val_limb; | 5373 | uint8_t arg_limb; |
| 3409 | 5374 | ||
| 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 | } |
| 3413 | 5378 | ||
| 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; |
| 3418 | 5380 | ||
| 3419 | #if zig_big_endian | 5381 | #if zig_little_endian |
| 3420 | byte_offset += 8 / CHAR_BIT; | 5382 | byte_offset += 8 / CHAR_BIT; |
| 3421 | #endif | 5383 | #endif |
| 3422 | } | 5384 | } |
| 3423 | 5385 | ||
| 3424 | return total_lz; | 5386 | return total_pc; |
| 3425 | } | 5387 | } |
| 3426 | 5388 | ||
| 3427 | static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bits) { | 5389 | static 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; |
| 3434 | 5397 | ||
| 3435 | #if zig_big_endian | 5398 | #if zig_big_endian |
| 3436 | byte_offset = remaining_bytes; | 5399 | byte_offset = zig_int_bytes(bits); |
| 3437 | #endif | 5400 | #endif |
| 3438 | 5401 | ||
| 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_endian | 5405 | #if zig_big_endian |
| 3441 | byte_offset -= 128 / CHAR_BIT; | 5406 | byte_offset -= 128 / CHAR_BIT; |
| 3442 | #endif | 5407 | #endif |
| 3443 | 5408 | ||
| 3444 | { | 5409 | { |
| 3445 | zig_u128 val_limb; | 5410 | zig_u128 arg_limb; |
| 3446 | 5411 | ||
| 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 | } |
| 3450 | 5415 | ||
| 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; |
| 3454 | 5419 | ||
| 3455 | #if zig_little_endian | 5420 | #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 | } |
| 3459 | 5424 | ||
| 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_endian | 5428 | #if zig_big_endian |
| 3462 | byte_offset -= 64 / CHAR_BIT; | 5429 | byte_offset -= 64 / CHAR_BIT; |
| 3463 | #endif | 5430 | #endif |
| 3464 | 5431 | ||
| 3465 | { | 5432 | { |
| 3466 | uint64_t val_limb; | 5433 | uint64_t arg_limb; |
| 3467 | 5434 | ||
| 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 | } |
| 3471 | 5438 | ||
| 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; |
| 3475 | 5442 | ||
| 3476 | #if zig_little_endian | 5443 | #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 | } |
| 3480 | 5447 | ||
| 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_endian | 5451 | #if zig_big_endian |
| 3483 | byte_offset -= 32 / CHAR_BIT; | 5452 | byte_offset -= 32 / CHAR_BIT; |
| 3484 | #endif | 5453 | #endif |
| 3485 | 5454 | ||
| 3486 | { | 5455 | { |
| 3487 | uint32_t val_limb; | 5456 | uint32_t arg_limb; |
| 3488 | 5457 | ||
| 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 | } |
| 3492 | 5461 | ||
| 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; |
| 3496 | 5465 | ||
| 3497 | #if zig_little_endian | 5466 | #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 | } |
| 3501 | 5470 | ||
| 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_endian | 5474 | #if zig_big_endian |
| 3504 | byte_offset -= 16 / CHAR_BIT; | 5475 | byte_offset -= 16 / CHAR_BIT; |
| 3505 | #endif | 5476 | #endif |
| 3506 | 5477 | ||
| 3507 | { | 5478 | { |
| 3508 | uint16_t val_limb; | 5479 | uint16_t arg_limb; |
| 3509 | 5480 | ||
| 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 | } |
| 3513 | 5484 | ||
| 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; |
| 3517 | 5488 | ||
| 3518 | #if zig_little_endian | 5489 | #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 | } |
| 3522 | 5493 | ||
| 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_endian | 5497 | #if zig_big_endian |
| 3525 | byte_offset -= 8 / CHAR_BIT; | 5498 | byte_offset -= 8 / CHAR_BIT; |
| 3526 | #endif | 5499 | #endif |
| 3527 | 5500 | ||
| 3528 | { | 5501 | { |
| 3529 | uint8_t val_limb; | 5502 | uint8_t arg_limb; |
| 3530 | 5503 | ||
| 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 | } |
| 3534 | 5507 | ||
| 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; |
| 3538 | 5511 | ||
| 3539 | #if zig_little_endian | 5512 | #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 | } |
| 3546 | 5519 | ||
| 3547 | static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_t bits) { | 5520 | static 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; |
| 3553 | 5529 | ||
| 3554 | #if zig_big_endian | 5530 | #if zig_big_endian |
| 3555 | byte_offset = remaining_bytes; | 5531 | byte_offset = zig_int_bytes(bits) - remaining_bytes; |
| 3556 | #endif | 5532 | #endif |
| 3557 | 5533 | ||
| 3558 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5534 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 3559 | #if zig_big_endian | 5535 | 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 | #endif | 5539 | #endif |
| 3562 | 5540 | ||
| 3563 | { | 5541 | { |
| 3564 | zig_u128 val_limb; | 5542 | zig_u128 arg_limb; |
| 3565 | 5543 | ||
| 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 | } |
| 3569 | 5547 | ||
| 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; |
| 3571 | 5552 | ||
| 3572 | #if zig_little_endian | 5553 | #if zig_big_endian |
| 3573 | byte_offset += 128 / CHAR_BIT; | 5554 | byte_offset += 128 / CHAR_BIT; |
| 3574 | #endif | 5555 | #endif |
| 3575 | } | 5556 | } |
| 3576 | 5557 | ||
| 3577 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5558 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3578 | #if zig_big_endian | 5559 | 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 | #endif | 5563 | #endif |
| 3581 | 5564 | ||
| 3582 | { | 5565 | { |
| 3583 | uint64_t val_limb; | 5566 | uint64_t arg_limb; |
| 3584 | 5567 | ||
| 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 | } |
| 3588 | 5571 | ||
| 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; |
| 3590 | 5576 | ||
| 3591 | #if zig_little_endian | 5577 | #if zig_big_endian |
| 3592 | byte_offset += 64 / CHAR_BIT; | 5578 | byte_offset += 64 / CHAR_BIT; |
| 3593 | #endif | 5579 | #endif |
| 3594 | } | 5580 | } |
| 3595 | 5581 | ||
| 3596 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5582 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3597 | #if zig_big_endian | 5583 | 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 | #endif | 5587 | #endif |
| 3600 | 5588 | ||
| 3601 | { | 5589 | { |
| 3602 | uint32_t val_limb; | 5590 | uint32_t arg_limb; |
| 3603 | 5591 | ||
| 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 | } |
| 3607 | 5595 | ||
| 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; |
| 3609 | 5600 | ||
| 3610 | #if zig_little_endian | 5601 | #if zig_big_endian |
| 3611 | byte_offset += 32 / CHAR_BIT; | 5602 | byte_offset += 32 / CHAR_BIT; |
| 3612 | #endif | 5603 | #endif |
| 3613 | } | 5604 | } |
| 3614 | 5605 | ||
| 3615 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5606 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3616 | #if zig_big_endian | 5607 | 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 | #endif | 5611 | #endif |
| 3619 | 5612 | ||
| 3620 | { | 5613 | { |
| 3621 | uint16_t val_limb; | 5614 | uint16_t arg_limb; |
| 3622 | 5615 | ||
| 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 | } |
| 3626 | 5619 | ||
| 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; |
| 3628 | 5624 | ||
| 3629 | #if zig_little_endian | 5625 | #if zig_big_endian |
| 3630 | byte_offset += 16 / CHAR_BIT; | 5626 | byte_offset += 16 / CHAR_BIT; |
| 3631 | #endif | 5627 | #endif |
| 3632 | } | 5628 | } |
| 3633 | 5629 | ||
| 3634 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5630 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3635 | #if zig_big_endian | 5631 | 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 | #endif | 5635 | #endif |
| 3638 | 5636 | ||
| 3639 | { | 5637 | { |
| 3640 | uint8_t val_limb; | 5638 | uint8_t arg_limb; |
| 3641 | 5639 | ||
| 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 | } |
| 3645 | 5643 | ||
| 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; |
| 3647 | 5648 | ||
| 3648 | #if zig_little_endian | 5649 | #if zig_big_endian |
| 3649 | byte_offset += 8 / CHAR_BIT; | 5650 | byte_offset += 8 / CHAR_BIT; |
| 3650 | #endif | 5651 | #endif |
| 3651 | } | 5652 | } |
| 3652 | 5653 | ||
| 3653 | return total_pc; | 5654 | return total_lz; |
| 3654 | } | 5655 | } |
| 3655 | 5656 | ||
| 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 | #else | 5690 | #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 | #endif | 5696 | #endif |
| 3696 | 5697 | ||
| 3697 | #define zig_has_f16 1 | 5698 | #define zig_has_f16 1 |
| 3698 | #define zig_libc_name_f16(name) __##name##h | 5699 | #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 == 11 | 5701 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT_MANT_DIG == 11 |
| 3701 | typedef float zig_f16; | 5702 | typedef float zig_f16; |
| 3702 | #define zig_make_f16(fp, repr) fp##f | 5703 | #define zig_make_f16(fp, repr) fp##f |
| 3703 | #elif DBL_MANT_DIG == 11 | 5704 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && DBL_MANT_DIG == 11 |
| 3704 | typedef double zig_f16; | 5705 | typedef double zig_f16; |
| 3705 | #define zig_make_f16(fp, repr) fp | 5706 | #define zig_make_f16(fp, repr) fp |
| 3706 | #elif LDBL_MANT_DIG == 11 | 5707 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && LDBL_MANT_DIG == 11 |
| 3707 | typedef long double zig_f16; | 5708 | typedef long double zig_f16; |
| 3708 | #define zig_make_f16(fp, repr) fp##l | 5709 | #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)) |
| 3710 | typedef _Float16 zig_f16; | 5711 | typedef _Float16 zig_f16; |
| 3711 | #define zig_make_f16(fp, repr) fp##f16 | 5712 | #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__) |
| 3713 | typedef __fp16 zig_f16; | 5714 | typedef __fp16 zig_f16; |
| 3714 | #define zig_make_f16(fp, repr) fp##f16 | 5715 | #define zig_make_f16(fp, repr) fp##f16 |
| 3715 | #else | 5716 | #else |
| ... | @@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16; | ... | @@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16; |
| 3723 | #undef zig_init_special_f16 | 5724 | #undef zig_init_special_f16 |
| 3724 | #define zig_init_special_f16(sign, name, arg, repr) repr | 5725 | #define zig_init_special_f16(sign, name, arg, repr) repr |
| 3725 | #endif | 5726 | #endif |
| 3726 | #if defined(zig_darwin) && defined(zig_x86) | ||
| 3727 | typedef uint16_t zig_compiler_rt_f16; | ||
| 3728 | #else | ||
| 3729 | typedef zig_f16 zig_compiler_rt_f16; | ||
| 3730 | #endif | ||
| 3731 | 5727 | ||
| 3732 | #define zig_has_f32 1 | 5728 | #define zig_has_f32 1 |
| 3733 | #define zig_libc_name_f32(name) name##f | 5729 | #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 | #else | 5732 | #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 | #endif | 5734 | #endif |
| 3739 | #if FLT_MANT_DIG == 24 | 5735 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT_MANT_DIG == 24 |
| 3740 | typedef float zig_f32; | 5736 | typedef float zig_f32; |
| 3741 | #define zig_make_f32(fp, repr) fp##f | 5737 | #define zig_make_f32(fp, repr) fp##f |
| 3742 | #elif DBL_MANT_DIG == 24 | 5738 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && DBL_MANT_DIG == 24 |
| 3743 | typedef double zig_f32; | 5739 | typedef double zig_f32; |
| 3744 | #define zig_make_f32(fp, repr) fp | 5740 | #define zig_make_f32(fp, repr) fp |
| 3745 | #elif LDBL_MANT_DIG == 24 | 5741 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && LDBL_MANT_DIG == 24 |
| 3746 | typedef long double zig_f32; | 5742 | typedef long double zig_f32; |
| 3747 | #define zig_make_f32(fp, repr) fp##l | 5743 | #define zig_make_f32(fp, repr) fp##l |
| 3748 | #elif FLT32_MANT_DIG == 24 | 5744 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT32_MANT_DIG == 24 |
| 3749 | typedef _Float32 zig_f32; | 5745 | typedef _Float32 zig_f32; |
| 3750 | #define zig_make_f32(fp, repr) fp##f32 | 5746 | #define zig_make_f32(fp, repr) fp##f32 |
| 3751 | #else | 5747 | #else |
| ... | @@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32; | ... | @@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32; |
| 3768 | #else | 5764 | #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 | #endif | 5766 | #endif |
| 3771 | #if FLT_MANT_DIG == 53 | 5767 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT_MANT_DIG == 53 |
| 3772 | typedef float zig_f64; | 5768 | typedef float zig_f64; |
| 3773 | #define zig_make_f64(fp, repr) fp##f | 5769 | #define zig_make_f64(fp, repr) fp##f |
| 3774 | #elif DBL_MANT_DIG == 53 | 5770 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && DBL_MANT_DIG == 53 |
| 3775 | typedef double zig_f64; | 5771 | typedef double zig_f64; |
| 3776 | #define zig_make_f64(fp, repr) fp | 5772 | #define zig_make_f64(fp, repr) fp |
| 3777 | #elif LDBL_MANT_DIG == 53 | 5773 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && LDBL_MANT_DIG == 53 |
| 3778 | typedef long double zig_f64; | 5774 | typedef long double zig_f64; |
| 3779 | #define zig_make_f64(fp, repr) fp##l | 5775 | #define zig_make_f64(fp, repr) fp##l |
| 3780 | #elif FLT64_MANT_DIG == 53 | 5776 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT64_MANT_DIG == 53 |
| 3781 | typedef _Float64 zig_f64; | 5777 | typedef _Float64 zig_f64; |
| 3782 | #define zig_make_f64(fp, repr) fp##f64 | 5778 | #define zig_make_f64(fp, repr) fp##f64 |
| 3783 | #elif FLT32X_MANT_DIG == 53 | 5779 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT32X_MANT_DIG == 53 |
| 3784 | typedef _Float32x zig_f64; | 5780 | typedef _Float32x zig_f64; |
| 3785 | #define zig_make_f64(fp, repr) fp##f32x | 5781 | #define zig_make_f64(fp, repr) fp##f32x |
| 3786 | #else | 5782 | #else |
| ... | @@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64; | ... | @@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64; |
| 3798 | #define zig_has_f80 1 | 5794 | #define zig_has_f80 1 |
| 3799 | #define zig_libc_name_f80(name) __##name##x | 5795 | #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 == 64 | 5797 | #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F80_ABI |
| 5798 | #undef zig_has_f80 | ||
| 5799 | typedef 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 | ||
| 3802 | typedef float zig_f80; | 5805 | typedef float zig_f80; |
| 3803 | #define zig_make_f80(fp, repr) fp##f | 5806 | #define zig_make_f80(fp, repr) fp##f |
| 3804 | #elif DBL_MANT_DIG == 64 | 5807 | #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##l | 5821 | #define zig_make_f80(fp, repr) fp##l |
| 3819 | #else | 5822 | #else |
| 3820 | #undef zig_has_f80 | 5823 | #undef zig_has_f80 |
| 3821 | #define zig_has_f80 0 | ||
| 3822 | #define zig_repr_f80 u128 | ||
| 3823 | typedef zig_u128 zig_f80; | 5824 | typedef 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) repr | 5832 | #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_f80 | 5836 | #undef zig_make_special_f80 |
| 3826 | #define zig_make_special_f80(sign, name, arg, repr) repr | 5837 | #define zig_make_special_f80(sign, name, arg, repr) repr |
| 3827 | #undef zig_init_special_f80 | 5838 | #undef zig_init_special_f80 |
| 3828 | #define zig_init_special_f80(sign, name, arg, repr) repr | 5839 | #define zig_init_special_f80(sign, name, arg, repr) repr |
| 3829 | #endif | 5840 | #endif |
| 3830 | 5841 | ||
| 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 1 | 5842 | #define zig_has_f128 1 |
| 3838 | #define zig_libc_name_f128(name) name##q | 5843 | #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 == 113 | 5845 | #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F128_ABI |
| 5846 | #undef zig_has_f128 | ||
| 5847 | #if zig_little_endian | ||
| 5848 | typedef struct { uint64_t lo, hi; } zig_f128; | ||
| 5849 | #else | ||
| 5850 | typedef 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 | ||
| 3841 | typedef float zig_f128; | 5856 | typedef float zig_f128; |
| 3842 | #define zig_make_f128(fp, repr) fp##f | 5857 | #define zig_make_f128(fp, repr) fp##f |
| 3843 | #elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113 | 5858 | #elif DBL_MANT_DIG == 113 |
| 3844 | typedef double zig_f128; | 5859 | typedef double zig_f128; |
| 3845 | #define zig_make_f128(fp, repr) fp | 5860 | #define zig_make_f128(fp, repr) fp |
| 3846 | #elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113 | 5861 | #elif LDBL_MANT_DIG == 113 |
| 3847 | typedef long double zig_f128; | 5862 | typedef long double zig_f128; |
| 3848 | #define zig_make_f128(fp, repr) fp##l | 5863 | #define zig_make_f128(fp, repr) fp##l |
| 3849 | #elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113 | 5864 | #elif FLT128_MANT_DIG == 113 |
| 3850 | typedef _Float128 zig_f128; | 5865 | typedef _Float128 zig_f128; |
| 3851 | #define zig_make_f128(fp, repr) fp##f128 | 5866 | #define zig_make_f128(fp, repr) fp##f128 |
| 3852 | #elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113 | 5867 | #elif FLT64X_MANT_DIG == 113 |
| 3853 | typedef _Float64x zig_f128; | 5868 | typedef _Float64x zig_f128; |
| 3854 | #define zig_make_f128(fp, repr) fp##f64x | 5869 | #define zig_make_f128(fp, repr) fp##f64x |
| 3855 | #elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__) | 5870 | #elif defined(__SIZEOF_FLOAT128__) |
| 3856 | typedef __float128 zig_f128; | 5871 | typedef __float128 zig_f128; |
| 3857 | #define zig_make_f128(fp, repr) fp##q | 5872 | #define zig_make_f128(fp, repr) fp##q |
| 3858 | #undef zig_make_special_f128 | 5873 | #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 | #else | 5875 | #else |
| 3861 | #undef zig_has_f128 | 5876 | #undef zig_has_f128 |
| 3862 | #define zig_has_f128 0 | 5877 | #if defined(zig_x86_64) && defined(ZIG_TARGET_ABI_MSVC) |
| 3863 | #undef zig_make_special_f128 | 5878 | #if defined(zig_msvc) && !defined(__clang__) |
| 3864 | #undef zig_init_special_f128 | 5879 | #include <emmintrin.h> |
| 3865 | #if defined(zig_darwin) || defined(zig_aarch64) | 5880 | typedef __m128i zig_f128; |
| 3866 | typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64; | 5881 | #define zig_init_repr_f128(hi, lo) { .m128i_u64 = { lo, hi } } |
| 3867 | zig_basic_operator(zig_v2u64, xor_v2u64, ^) | 5882 | #define zig_lo_repr_f128(arg) (arg).m128i_u64[0] |
| 3868 | #define zig_repr_f128 v2u64 | 5883 | #define zig_hi_repr_f128(arg) (arg).m128i_u64[1] |
| 3869 | typedef zig_v2u64 zig_f128; | 5884 | #else |
| 3870 | #define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi } | 5885 | typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_f128; |
| 3871 | #define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u128 | 5886 | #define zig_init_repr_f128(hi, lo) { lo, hi } |
| 3872 | #define zig_make_f128(fp, repr) zig_make_f128_##repr | 5887 | #define zig_lo_repr_f128(arg) (arg)[0] |
| 3873 | #define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr | 5888 | #define zig_hi_repr_f128(arg) (arg)[1] |
| 3874 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr | 5889 | #endif |
| 3875 | #else | 5890 | #else |
| 3876 | #define zig_repr_f128 u128 | ||
| 3877 | typedef zig_u128 zig_f128; | 5891 | typedef 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) repr | 5900 | #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) repr | 5905 | #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) repr | 5907 | #define zig_init_special_f128(sign, name, arg, repr) repr |
| 3881 | #endif | 5908 | #endif |
| 3882 | #endif | ||
| 3883 | 5909 | ||
| 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; |
| 3892 | typedef long double zig_c_longdouble; | 5918 | typedef long double zig_c_longdouble; |
| 3893 | #endif | 5919 | #endif |
| 3894 | 5920 | ||
| 3895 | #define zig_bitCast_float(Type, ReprType) \ | 5921 | #if __AVR__ |
| 3896 | static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \ | 5922 | typedef signed char zig_FloatCompareResult; |
| 3897 | zig_##Type result; \ | 5923 | #elif defined(zig_aarch64) |
| 3898 | memcpy(&result, &repr, sizeof(result)); \ | 5924 | typedef signed int zig_FloatCompareResult; |
| 3899 | return result; \ | 5925 | #elif __SIZEOF_LONG__ >= __SIZEOF_POINTER__ |
| 5926 | typedef signed long zig_FloatCompareResult; | ||
| 5927 | #else | ||
| 5928 | typedef 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 | } |
| 3901 | zig_bitCast_float(f16, uint16_t) | 5952 | zig_bitCast_float(16, 16, uint16_t, int16_t) |
| 3902 | zig_bitCast_float(f32, uint32_t) | 5953 | zig_bitCast_float(32, 32, uint32_t, int32_t) |
| 3903 | zig_bitCast_float(f64, uint64_t) | 5954 | zig_bitCast_float(64, 64, uint64_t, int64_t) |
| 3904 | zig_bitCast_float(f80, zig_u128) | 5955 | #if zig_has_f80 |
| 3905 | zig_bitCast_float(f128, zig_u128) | 5956 | zig_bitCast_float(80, 128, zig_u128, zig_i128) |
| 5957 | #else | ||
| 5958 | static 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 | } | ||
| 5961 | static 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 | } | ||
| 5964 | static 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 | } | ||
| 5967 | static 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 | ||
| 5971 | static 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 | } | ||
| 5974 | static 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 | ||
| 5982 | zig_bitCast_float(128, 128, zig_u128, zig_i128) | ||
| 5983 | #else | ||
| 5984 | static 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 | } | ||
| 5987 | static 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 | } | ||
| 5990 | static 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 | } | ||
| 5993 | static 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 | ||
| 3906 | 5997 | ||
| 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; \ | 6019 | zig_convert_floats(f16, f32) |
| 3920 | } | 6020 | zig_convert_floats(f16, f64) |
| 3921 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2) | 6021 | zig_convert_floats(f16, f80) |
| 3922 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2) | 6022 | zig_convert_floats(f16, f128) |
| 3923 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2) | 6023 | zig_convert_floats(f32, f64) |
| 3924 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2) | 6024 | zig_convert_floats(f32, f80) |
| 3925 | zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2) | 6025 | zig_convert_floats(f32, f128) |
| 3926 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2) | 6026 | zig_convert_floats(f64, f80) |
| 3927 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2) | 6027 | zig_convert_floats(f64, f128) |
| 3928 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2) | 6028 | zig_convert_floats(f80, f128) |
| 3929 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2) | 6029 | |
| 3930 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2) | 6030 | #define zig_float_negate_builtin_0(w, sb) \ |
| 3931 | zig_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)) |
| 3932 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2) | 6032 | #define zig_float_negate_builtin_1(w, sb) -arg |
| 3933 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2) | 6033 | #define zig_float_negate_builtin(w, sb) \ |
| 3934 | zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2) | ||
| 3935 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2) | ||
| 3936 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2) | ||
| 3937 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2) | ||
| 3938 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2) | ||
| 3939 | |||
| 3940 | #ifdef __ARM_EABI__ | ||
| 3941 | |||
| 3942 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_d2f(zig_f64); | ||
| 3943 | static inline zig_f32 zig_truncdfsf(zig_f64 arg) { return __aeabi_d2f(arg); } | ||
| 3944 | |||
| 3945 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_f2d(zig_f32); | ||
| 3946 | static inline zig_f64 zig_extendsfdf(zig_f32 arg) { return __aeabi_f2d(arg); } | ||
| 3947 | |||
| 3948 | #else /* __ARM_EABI__ */ | ||
| 3949 | |||
| 3950 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2) | ||
| 3951 | zig_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 | } |
| 3962 | zig_float_negate_builtin(16, , UINT16_C(1) << 15 ) | 6037 | zig_float_negate_builtin(16, UINT16_C(1) << 15) |
| 3963 | zig_float_negate_builtin(32, , UINT32_C(1) << 31 ) | 6038 | zig_float_negate_builtin(32, UINT32_C(1) << 31) |
| 3964 | zig_float_negate_builtin(64, , UINT64_C(1) << 63 ) | 6039 | zig_float_negate_builtin(64, UINT64_C(1) << 63) |
| 3965 | zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0))) | 6040 | |
| 3966 | zig_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)) | ||
| 6044 | zig_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)) | ||
| 6049 | zig_float_negate_builtin(128, UINT64_C(1) << 63) | ||
| 3967 | 6050 | ||
| 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 | } |
| 3996 | 6079 | ||
| 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 | } |
| 4049 | zig_common_float_builtins(16) | ||
| 4050 | zig_common_float_builtins(32) | ||
| 4051 | zig_common_float_builtins(64) | ||
| 4052 | zig_common_float_builtins(80) | ||
| 4053 | zig_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, ) | ||
| 4062 | zig_float_builtins(16) | 6171 | zig_float_builtins(16) |
| 4063 | zig_float_builtins(80) | ||
| 4064 | zig_float_builtins(128) | ||
| 4065 | |||
| 4066 | #ifdef __ARM_EABI__ | ||
| 4067 | |||
| 4068 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_f2iz(zig_f32); | ||
| 4069 | static inline int32_t zig_fixsfsi(zig_f32 arg) { return __aeabi_f2iz(arg); } | ||
| 4070 | |||
| 4071 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_f2uiz(zig_f32); | ||
| 4072 | static inline uint32_t zig_fixunssfsi(zig_f32 arg) { return __aeabi_f2uiz(arg); } | ||
| 4073 | |||
| 4074 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_f2ulz(zig_f32); | ||
| 4075 | static inline uint64_t zig_fixunssfdi(zig_f32 arg) { return __aeabi_f2ulz(arg); } | ||
| 4076 | |||
| 4077 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_i2f(int32_t); | ||
| 4078 | static inline zig_f32 zig_floatsisf(int32_t arg) { return __aeabi_i2f(arg); } | ||
| 4079 | |||
| 4080 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ui2f(uint32_t); | ||
| 4081 | static inline zig_f32 zig_floatunsisf(uint32_t arg) { return __aeabi_ui2f(arg); } | ||
| 4082 | |||
| 4083 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ul2f(uint64_t); | ||
| 4084 | static inline zig_f32 zig_floatundisf(uint64_t arg) { return __aeabi_ul2f(arg); } | ||
| 4085 | |||
| 4086 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_d2iz(zig_f64); | ||
| 4087 | static inline int32_t zig_fixdfsi(zig_f64 arg) { return __aeabi_d2iz(arg); } | ||
| 4088 | |||
| 4089 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_d2uiz(zig_f64); | ||
| 4090 | static inline uint32_t zig_fixunsdfsi(zig_f64 arg) { return __aeabi_d2uiz(arg); } | ||
| 4091 | |||
| 4092 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_d2ulz(zig_f64); | ||
| 4093 | static inline uint64_t zig_fixunsdfdi(zig_f64 arg) { return __aeabi_d2ulz(arg); } | ||
| 4094 | |||
| 4095 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_i2d(int32_t); | ||
| 4096 | static inline zig_f64 zig_floatsidf(int32_t arg) { return __aeabi_i2d(arg); } | ||
| 4097 | |||
| 4098 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ui2d(uint32_t); | ||
| 4099 | static inline zig_f64 zig_floatunsidf(uint32_t arg) { return __aeabi_ui2d(arg); } | ||
| 4100 | |||
| 4101 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ul2d(uint64_t); | ||
| 4102 | static inline zig_f64 zig_floatundidf(uint64_t arg) { return __aeabi_ul2d(arg); } | ||
| 4103 | |||
| 4104 | #else /* __ARM_EABI__ */ | ||
| 4105 | |||
| 4106 | zig_float_builtins(32) | 6172 | zig_float_builtins(32) |
| 4107 | zig_float_builtins(64) | 6173 | zig_float_builtins(64) |
| 4108 | 6174 | zig_float_builtins(80) | |
| 4109 | #endif /* __ARM_EABI__ */ | 6175 | #if defined(zig_x86_32) |
| 6176 | zig_common_float_builtins(128) | ||
| 6177 | static 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 | } | ||
| 6181 | static 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) | ||
| 6186 | zig_common_float_builtins(128) | ||
| 6187 | static inline zig_f128 zig_floattitf(zig_i128 arg) { | ||
| 6188 | extern zig_f128 __floattitf(zig_i128 arg); | ||
| 6189 | return __floattitf(arg); | ||
| 6190 | } | ||
| 6191 | static 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 | ||
| 6196 | zig_float_builtins(128) | ||
| 6197 | #endif | ||
| 4110 | 6198 | ||
| 4111 | /* ============================ Atomics Support ============================= */ | 6199 | /* ============================ Atomics Support ============================= */ |
| 4112 | 6200 | ||
| ... | @@ -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 | } |
| 4427 | 6515 | ||
| 4428 | zig_msvc_atomics( u8, uint8_t, char, 8, 8) | 6516 | zig_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 | } |
| 4478 | 6566 | ||
| ... | @@ -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 | } |
| 4503 | 6591 | ||
| 4504 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) { | 6592 | static 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 | } |
| 4509 | 6597 | ||
| 4510 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) { | 6598 | static 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 | } |
| 4533 | 6621 | ||
| 4534 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) { | 6622 | static 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 | } |
| 4539 | 6627 | ||
| 4540 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) { | 6628 | static 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; |
| 2135 | 2135 | ||
| 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 | } |
| 4195 | 4195 | ||
| 4196 | /// This function is used in the debugger pretty formatters in tools/ to fetch the | 4196 | /// 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 | }, |
| 4243 | 4234 | ||
| 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 | }, |
| 5202 | 5202 | ||
| ... | @@ -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( |
| 25675 | 25676 | ||
| 25676 | .@"opaque", | 25677 | .@"opaque", |
| 25677 | .bool, | 25678 | .bool, |
| 25678 | .float, | ||
| 25679 | .@"anyframe", | 25679 | .@"anyframe", |
| 25680 | => unreachable, // these *are* allowed | 25680 | => unreachable, // these *are* allowed |
| 25681 | 25681 | ||
| ... | @@ -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 | }, |
| 25686 | 25686 | ||
| 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), |
| 1020 | 1035 | ||
| 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 | }, |
| 1035 | 1064 | ||
| 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), |
| 1169 | 1204 | ||
| 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).?, |
| 1180 | 1215 | ||
| 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, | ||
| 1189 | 1243 | ||
| 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. |
| 1734 | pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool { | 1788 | pub 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. |
| 1746 | pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool { | 1800 | pub 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).?, |
| 1886 | 1940 | ||
| 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 | } |
| 2149 | 2203 | ||
| 2150 | /// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len. | ||
| 2151 | pub 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 | |||
| 2157 | pub fn isArrayOrVector(ty: Type, zcu: *const Zcu) bool { | 2204 | pub 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 | } |
| 2418 | 2465 | ||
| 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"`. | ||
| 2424 | pub 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 | |||
| 2447 | pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) ?Value { | 2466 | pub 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 |
| 3122 | 3140 | ||
| 3123 | .@"opaque", | 3141 | .@"opaque", |
| 3124 | .bool, | 3142 | .bool, |
| 3125 | .float, | ||
| 3126 | .@"anyframe", | 3143 | .@"anyframe", |
| 3127 | => true, | 3144 | => true, |
| 3128 | 3145 | ||
| ... | @@ -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 { |
| 3600 | pub const packed_struct_layout_version = 2; | 3621 | pub const packed_struct_layout_version = 2; |
| 3601 | 3622 | ||
| 3602 | fn cTypeAlign(target: *const Target, c_type: Target.CType) Alignment { | 3623 | fn 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{ |
| 2825 | 2825 | ||
| 2826 | pub fn init(zcu: *Zcu, gpa: Allocator, io: Io, thread_count: usize) !void { | 2826 | pub 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. | ||
| 2832 | pub fn initAfterCompilation(zcu: *Zcu) void { | ||
| 2828 | zcu.initTracyPlots(); | 2833 | zcu.initTracyPlots(); |
| 2829 | } | 2834 | } |
| 2830 | 2835 | ||
| ... | @@ -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 | ||
| 4639 | 4634 | ||
| 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, | ||
| 4652 | 4640 | ||
| 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 | } |
| 1126 | 1126 | ||
| 1127 | pub const FlattenedItem = struct { offset: u64, type: ?Type }; | ||
| 1128 | pub 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 | |||
| 1127 | test { | 1322 | test { |
| 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 @@ |
| 1 | const assert = @import("std").debug.assert; | 1 | const assert = std.debug.assert; |
| 2 | const std = @import("std"); | 2 | const std = @import("std"); |
| 3 | const InternPool = @import("../../InternPool.zig"); | 3 | const InternPool = @import("../../InternPool.zig"); |
| 4 | const Type = @import("../../Type.zig"); | 4 | const 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; |
| 41 | 41 | ||
| 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 | } |
| 45 | 45 | ||
| ... | @@ -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; |
| 64 | 64 | ||
| 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 | } |
| 68 | 68 | ||
| ... | @@ -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 implementing | 78 | 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 { |
| 164 | 164 | ||
| 165 | const LocalType = struct { | 165 | const LocalType = struct { |
| 166 | type: Type, | 166 | type: Type, |
| 167 | alignment: Alignment, | 167 | alignment: Alignment = .none, |
| 168 | array_len: u2 = 1, | ||
| 168 | }; | 169 | }; |
| 169 | 170 | ||
| 170 | const LocalIndex = u16; | 171 | const LocalIndex = u16; |
| ... | @@ -184,13 +185,11 @@ const ValueRenderLocation = enum { | ... | @@ -184,13 +185,11 @@ const ValueRenderLocation = enum { |
| 184 | } | 185 | } |
| 185 | }; | 186 | }; |
| 186 | 187 | ||
| 187 | const BuiltinInfo = enum { none, bits }; | 188 | const BuiltinInfo = enum { none, bits, bits_none, big_temp_bits }; |
| 188 | 189 | ||
| 189 | const reserved_idents = std.StaticStringMap(void).initComptime(.{ | 190 | const reserved_idents = std.StaticStringMap(void).initComptime(.{ |
| 190 | // C language | 191 | // 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.h | 301 | // stddef.h |
| 303 | .{ "offsetof", {} }, | 302 | .{ "offsetof", {} }, |
| 304 | 303 | ||
| 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.h | 382 | // 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 | } |
| 318 | 410 | ||
| 319 | // windows.h | ||
| 320 | if (mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or | ||
| 321 | mem.startsWith(u8, ident, "DUMMYUNIONNAME")) | ||
| 322 | { | ||
| 323 | return true; | ||
| 324 | } | ||
| 325 | |||
| 326 | // CType | 411 | // CType |
| 327 | if (mem.startsWith(u8, ident, "enum__") or | 412 | if (mem.startsWith(u8, ident, "enum__") or |
| 328 | mem.startsWith(u8, ident, "bitpack__") or | 413 | mem.startsWith(u8, ident, "bitpack__") or |
| ... | @@ -469,10 +554,7 @@ pub const Function = struct { | ... | @@ -469,10 +554,7 @@ pub const Function = struct { |
| 469 | } | 554 | } |
| 470 | 555 | ||
| 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 | } |
| 477 | 559 | ||
| 478 | /// Only allocates the local; does not print anything. Will attempt to re-use locals, so should | 560 | /// 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 | } |
| 566 | 648 | ||
| 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 | } |
| 677 | 757 | ||
| 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 | } |
| 743 | 825 | ||
| 744 | // We shouldn't cast C function pointers as this is UB (when you call | 826 | // 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 | } |
| 760 | 842 | ||
| 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); |
| 961 | 1063 | ||
| 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 | }; |
| 972 | 1071 | ||
| 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 | } |
| 981 | 1080 | ||
| 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 nan | 1095 | // 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 get | 1129 | // 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; | ||
| 1324 | 1427 | ||
| 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 | } |
| 1640 | 1752 | ||
| 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 true | 1753 | // 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 { |
| 1651 | 1761 | ||
| 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 | } |
| 1728 | 1839 | ||
| 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 | } |
| 2004 | 1986 | ||
| 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 | }; |
| 2058 | 2040 | ||
| 2041 | pub 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 | |||
| 2059 | pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void { | 2107 | pub 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; |
| 2071 | 2119 | ||
| 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"); | ||
| 2083 | 2131 | ||
| 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 | } |
| 2120 | 2173 | ||
| 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( |
| 2164 | 2220 | ||
| 2165 | const fn_val = zcu.navValue(fn_nav); | 2221 | const fn_val = zcu.navValue(fn_nav); |
| 2166 | 2222 | ||
| 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); |
| 2273 | 2331 | ||
| 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)}); | ||
| 2294 | 2354 | ||
| 2295 | f.free_locals_map.clearRetainingCapacity(); | 2355 | f.free_locals_map.clearRetainingCapacity(); |
| 2296 | 2356 | ||
| 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 { |
| 2397 | 2487 | ||
| 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 | } |
| 2466 | pub fn genDeclValueFwd(dg: *DeclGen, w: *Writer, options: struct { | 2563 | pub 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), |
| 2663 | 2762 | ||
| 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), |
| 2666 | 2765 | ||
| 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 | else | 2774 | 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), |
| 2682 | 2781 | ||
| 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), |
| 2691 | 2790 | ||
| 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 | } | ||
| 3128 | 3236 | ||
| 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 | } |
| 3300 | 3408 | ||
| 3301 | fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { | 3409 | fn 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; |
| 3305 | 3413 | ||
| 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); |
| 3313 | 3418 | 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 | |||
| 3332 | fn 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; | ||
| 3336 | 3419 | ||
| 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}); |
| 3339 | 3422 | ||
| 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); | ||
| 3354 | 3425 | ||
| 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 | } |
| 3417 | 3462 | ||
| ... | @@ -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; |
| 3527 | 3572 | ||
| 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 }); |
| 3531 | 3580 | ||
| 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); | ||
| 3535 | 3583 | ||
| 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); | ||
| 3537 | 3586 | ||
| 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('('); |
| 3548 | 3599 | ||
| 3549 | // '&dest', possibly preceded by a cast | 3600 | // '&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 to | 3604 | // '&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 a | 3605 | // 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); |
| 3567 | 3619 | ||
| 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 | } | ||
| 3627 | 3699 | ||
| 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); |
| 3664 | 3736 | ||
| 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); | ||
| 3678 | 3752 | ||
| 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); | ||
| 3734 | 3810 | ||
| 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); |
| 3864 | 3940 | ||
| 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 | } | ||
| 3867 | 3952 | ||
| 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( |
| 4058 | fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { | 4140 | fn 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 emit | 4143 | 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); |
| 4435 | 4508 | ||
| 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()) or | 4509 | 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)); | ||
| 4480 | 4537 | ||
| 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 | } |
| 4541 | 4573 | ||
| 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( |
| 4906 | 4938 | ||
| 4907 | fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool { | 4939 | fn 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 an | 5029 | // 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 | else | 5874 | else |
| 5854 | unreachable; | 5875 | unreachable; |
| 5855 | 5876 | ||
| 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; |
| 5895 | 6012 | ||
| 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}); | ||
| 5902 | 6021 | ||
| 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); |
| 5905 | 6024 | ||
| 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; |
| 5943 | 6068 | ||
| 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); | ||
| 5946 | 6072 | ||
| 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( |
| 5950 | 6076 | ||
| 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); | ||
| 5954 | 6081 | ||
| 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); | ||
| 5957 | 6085 | ||
| 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); |
| 5986 | 6151 | ||
| 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 | } |
| 6600 | 6776 | ||
| 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; |
| 6655 | 6831 | ||
| 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(); |
| 6743 | 6926 | ||
| 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 | } |
| 7099 | 7314 | ||
| 7100 | fn 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 | |||
| 7195 | fn toAtomicRmwSuffix(order: std.lang.AtomicRmwOp) []const u8 { | 7315 | fn 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 { |
| 7224 | 7344 | ||
| 7225 | fn compilerRtAbbrev(ty: Type, zcu: *Zcu, target: *const std.Target) []const u8 { | 7345 | fn 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 | } |
| 7240 | 7361 | ||
| ... | @@ -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 | } |
| 7392 | 7513 | ||
| 7393 | fn undefPattern(comptime IntType: type) IntType { | 7514 | fn 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 | } |
| 7398 | 7517 | ||
| 7399 | const FormatIntLiteralContext = struct { | 7518 | const 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 | } |
| 7737 | 7853 | ||
| 7854 | const 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 | }; | ||
| 7866 | const 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 | |||
| 7738 | const Materialize = struct { | 7879 | const Materialize = struct { |
| 7739 | local: CValue, | 7880 | local: CValue, |
| 7740 | 7881 |
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 | }, |
| 48 | 49 | ||
| 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 `(...)` appears | 216 | /// 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 wrapped | 217 | /// 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: off | 299 | // zig fmt: off |
| 133 | .char => target.cTypeBitSize(.char), | 300 | .char => target.cTypeBitSize(.char).?, |
| 134 | 301 | ||
| 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).?, |
| 139 | 306 | ||
| 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).?, |
| 144 | 311 | ||
| 145 | .uintptr_t, .intptr_t => target.ptrBitWidth(), | 312 | .uintptr_t, .intptr_t => target.ptrBitWidth(), |
| 146 | 313 | ||
| 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: on | 321 | // 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 | }, |
| 768 | 943 | ||
| ... | @@ -812,7 +987,7 @@ pub const CType = union(enum) { | ... | @@ -812,7 +987,7 @@ pub const CType = union(enum) { |
| 812 | => {}, | 987 | => {}, |
| 813 | 988 | ||
| 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`. |
| 33 | pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error!void { | 36 | pub 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 | } |
| 51 | 64 | ||
| 52 | /// Renders a forward declaration of the `struct` which represents an error union whose payload type | 65 | /// 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 | } |
| 106 | 120 | ||
| 107 | /// If the Zig type `ty` lowers to a `struct` or `union` type, renders a forward declaration of that | 121 | /// 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 | } |
| 149 | 166 | ||
| 150 | /// If the Zig type `ty` lowers to a `struct` or `union` type, or to a `typedef`, renders the | 167 | /// 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( |
| 163 | 180 | ||
| 164 | ty.assertHasLayout(zcu); | 181 | ty.assertHasLayout(zcu); |
| 165 | 182 | ||
| 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); |
| 188 | 205 | ||
| 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 mess | 264 | 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, |
| 258 | 275 | ||
| 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 | }, |
| 267 | 286 | ||
| 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 | } |
| 337 | fn defineBitpack( | 345 | fn 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 | } |
| 354 | fn defineTuple( | 362 | fn 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; |
| 365 | 372 | ||
| 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. | ||
| 367 | 375 | ||
| 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 | }; | ||
| 384 | 377 | ||
| 385 | // If the alignment of other fields would not give the tuple sufficient alignment, we | 378 | // 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 always | 379 | // 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 | }; | ||
| 397 | 387 | ||
| 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` field | 395 | 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 its | 406 | 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 be | 409 | 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 | } |
| 442 | fn defineStruct( | 429 | fn 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; |
| 452 | 438 | ||
| 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( |
| 489 | 475 | ||
| 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(';'); |
| 533 | 518 | return name_cty; | |
| 534 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | ||
| 535 | } | 519 | } |
| 536 | fn defineUnionAuto( | 520 | fn 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; |
| 546 | 529 | ||
| 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 would | 541 | // 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 not | 542 | // 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); |
| 586 | 569 | ||
| 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("};"); |
| 623 | 605 | return name_cty; | |
| 624 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | ||
| 625 | } | 606 | } |
| 626 | fn defineUnionExtern( | 607 | fn 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; |
| 636 | 616 | ||
| 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; |
| 648 | 628 | ||
| ... | @@ -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("); |
| 669 | 649 | ||
| 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 | }); |
| 675 | 654 | ||
| 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(';'); |
| 695 | 674 | return name_cty; | |
| 696 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | ||
| 697 | } | 675 | } |
| 698 | 676 | ||
| 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 | } |
| 713 | 691 | ||
| 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`. |
| 715 | fn writeStaticAssertLayout( | 693 | pub 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. | ||
| 703 | pub 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 | } |
| 730 | 718 |
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 | } |
| 347 | 347 | ||
| 348 | pub 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. |
| 503 | const CodeModel = enum { | 349 | const 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(); |
| 618 | 466 | ||
| 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 of | 469 | // 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 | } |
| 705 | 552 | ||
| 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 | } |
| 722 | 570 | ||
| 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); |
| 751 | 599 | ||
| 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); | ||
| 1211 | 1055 | ||
| 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); |
| 1214 | 1058 | ||
| 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); |
| 1328 | 1190 | ||
| 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 | } |
| 1509 | 1371 | ||
| 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). Of | 1377 | // 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 { |
| 1599 | 1467 | ||
| 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 rather | 1502 | // 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 | } |
| 1640 | 1508 | ||
| 1641 | const llvm_global_ty = global_index.typeOf(&o.builder); | 1509 | const llvm_global_ty = llvm_global.typeOf(&o.builder); |
| 1642 | 1510 | ||
| 1643 | // All exports are represented as aliases to the original global. | 1511 | // All exports are represented as aliases to the original global. |
| 1644 | 1512 | ||
| ... | @@ -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, then | 1544 | 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 one | 1551 | // 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 references | 1552 | // 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 | } |
| 1735 | 1600 | ||
| ... | @@ -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 | ); |
| 2104 | 1969 | ||
| 2105 | return try o.builder.debugStructType( | 1970 | return o.builder.debugStructType( |
| 2106 | name, | 1971 | name, |
| 2107 | null, // File | 1972 | null, // File |
| 2108 | o.debug_compile_unit.unwrap().?, // Scope | 1973 | 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); |
| 2141 | 2006 | ||
| 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 | } |
| 2581 | 2446 | ||
| 2582 | /// Sets the attributes and callconv of the given `Builder.Function`, which corresponds to the | 2447 | 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; | ||
| 2598 | 2530 | ||
| 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 | } | ||
| 2601 | 2534 | ||
| 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 | }; |
| 2614 | 2547 | ||
| 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).?; |
| 2620 | 2549 | ||
| 2621 | function_index.setCallConv(cc_info.llvm_cc, &o.builder); | 2550 | llvm_function.setCallConv(cc_info.llvm_cc, &o.builder); |
| 2622 | 2551 | ||
| 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 | } |
| 2626 | 2555 | ||
| 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 | } |
| 2674 | 2603 | ||
| 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); |
| 2689 | 2605 | ||
| 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 0 | 2608 | 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), |
| 2695 | 2611 | 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 | } |
| 2720 | 2636 | ||
| 2721 | if (remaining_inreg_int > 0 and | 2637 | 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 | } |
| 2777 | 2691 | ||
| 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 | } |
| 2847 | 2709 | ||
| 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 | }; |
| 2856 | 2721 | ||
| 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 | } |
| 2863 | 2890 | ||
| 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; |
| 2868 | 2895 | ||
| 2869 | if (repr == .by_value) { | 2896 | switch (repr) { |
| 2870 | assert(!isByRef(t, zcu)); // by-ref types must only be manipulated in memory | 2897 | .as_value => assert(!isByRef(t, zcu)), // by-ref types must only be manipulated in memory |
| 2898 | .memory_access, .in_memory => {}, | ||
| 2871 | } | 2899 | } |
| 2872 | 2900 | ||
| 2873 | return switch (t.toIntern()) { | 2901 | return switch (t.toIntern()) { |
| 2874 | .u0_type => unreachable, // no runtime bits | 2902 | .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 bits | 3306 | .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 types | 3313 | // 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 | } |
| 3285 | 3336 | ||
| 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(); |
| 3290 | 3357 | ||
| 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); | ||
| 3294 | 3359 | ||
| 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 | } |
| 3307 | 3372 | ||
| 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 { |
| 3347 | 3412 | ||
| 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); |
| 3601 | 3666 | ||
| ... | @@ -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 | } |
| 3843 | 3913 | ||
| 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 { |
| 3912 | 4093 | ||
| 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); |
| 3934 | 4115 | ||
| 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" })); |
| 3963 | 4144 | ||
| 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 | } |
| 3991 | 4171 | ||
| 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 | } |
| 4057 | 4237 | ||
| 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 | } |
| 4072 | 4259 | ||
| 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 { |
| 4075 | 4262 | ||
| 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 space | 4264 | // 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); |
| 4087 | 4274 | ||
| 4088 | o.error_name_table = variable_index; | 4275 | o.error_name_table = llvm_variable; |
| 4089 | return variable_index; | 4276 | return llvm_variable; |
| 4090 | } | 4277 | } |
| 4091 | 4278 | ||
| 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()); |
| 4134 | 4321 | ||
| 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); |
| 4138 | 4325 | ||
| 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); |
| 4141 | 4328 | ||
| 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); |
| 4145 | 4332 | ||
| 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); |
| 4149 | 4336 | ||
| 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); |
| 4177 | 4364 | ||
| 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 | }); |
| 4182 | 4369 | ||
| 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-numbered | 4372 | .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); |
| 4189 | 4376 | ||
| ... | @@ -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()); |
| 4231 | 4418 | ||
| 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); |
| 4235 | 4422 | ||
| 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); |
| 4239 | 4426 | ||
| 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); |
| 4243 | 4430 | ||
| 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 { |
| 4256 | 4443 | ||
| 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 { |
| 4278 | 4465 | ||
| 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 | }; |
| 4297 | 4491 | ||
| ... | @@ -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 | } |
| 4587 | 4782 | ||
| 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. | ||
| 4591 | pub 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. | ||
| 4605 | pub 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. | ||
| 4615 | pub 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 or | 4784 | /// However we don't want to ever call LLVMABIAlignmentOfType or |
| 4631 | /// LLVMABISizeOfType because these functions will trip assertions | 4785 | /// 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); |
| 192 | 192 | ||
| 193 | var it = iterateParamTypes(o, fn_info); | 193 | var it = iterateParamTypes(o, fn_info.cc, fn_info.param_types.get(ip)); |
| 194 | 194 | ||
| 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; | ||
| 240 | 241 | ||
| 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); |
| 251 | 252 | ||
| ... | @@ -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 | } |
| 723 | 724 | ||
| 724 | const CallAttr = enum { | 725 | fn 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 | |||
| 732 | fn 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 | |||
| 764 | fn 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)); |
| 759 | 782 | ||
| 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); |
| 762 | 785 | ||
| 763 | var attributes: Builder.FunctionAttributes.Wip = .{}; | 786 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 764 | defer attributes.deinit(&o.builder); | 787 | defer attributes.deinit(&o.builder); |
| 765 | 788 | ||
| 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 | } |
| 769 | 792 | ||
| 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 |
| 775 | 798 | ||
| 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); | ||
| 779 | 803 | ||
| 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 |
| 792 | 816 | ||
| 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); | ||
| 894 | 822 | ||
| 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)) { |
| 903 | 831 | 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)); | ||
| 909 | 857 | ||
| 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 | } | ||
| 915 | 918 | ||
| 916 | const cc_info = llvm.toLlvmCallConv(fn_info.cc, target).?; | 919 | const cc_info = llvm.toLlvmCallConv(fn_info.cc, target).?; |
| 917 | 920 | ||
| 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, |
| 962 | 965 | ||
| 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; |
| 968 | 971 | ||
| ... | @@ -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 | } |
| 991 | 994 | ||
| 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 | ); |
| 1006 | 1009 | ||
| 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 | } | ||
| 1014 | 1012 | ||
| 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 | } |
| 1034 | 1032 | ||
| ... | @@ -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); |
| 1042 | 1040 | ||
| 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); |
| 1044 | 1042 | ||
| ... | @@ -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 |
| 1067 | 1065 | ||
| 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)).?; |
| 1069 | 1067 | ||
| 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); |
| 1073 | 1071 | ||
| ... | @@ -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); |
| 1169 | 1167 | ||
| 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 will | 1508 | // 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. |
| 1512 | 1510 | ||
| 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 | else | 1514 | 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, ""); |
| 1730 | 1728 | ||
| 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; |
| 1863 | 1861 | ||
| 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 | } |
| 2030 | 2028 | ||
| 2031 | fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { | 2029 | fn 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; |
| 2035 | 2033 | ||
| 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); |
| 2040 | 2038 | ||
| 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(); |
| 2045 | 2042 | ||
| 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 | ); | ||
| 2052 | 2045 | ||
| 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 | }); |
| 2072 | 2068 | 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 standard | 2071 | .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 | } |
| 2092 | 2074 | ||
| 2093 | fn airIntFromFloat( | 2075 | fn 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; |
| 2099 | 2081 | ||
| 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; |
| 2104 | 2086 | ||
| 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); |
| 2108 | 2090 | ||
| 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); | ||
| 2112 | 2095 | ||
| 2113 | if (intrinsicsAllowed(operand_scalar_ty, target)) { | 2096 | if (intrinsicsAllowed(.compiler_rt, operand_scalar_ty, target)) { |
| 2114 | // TODO set fast math flag | 2097 | // 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 | } |
| 2122 | 2100 | ||
| 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 | }); |
| 2144 | 2112 | 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 | } |
| 2161 | 2119 | ||
| 2162 | fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { | 2120 | fn 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 |
| 2167 | fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { | 2125 | fn 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->float | 2325 | // 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; |
| 2397 | 2355 | ||
| 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); |
| 2400 | 2358 | ||
| 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); |
| 2616 | 2574 | ||
| 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; |
| 2651 | 2609 | ||
| 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 | } |
| 2656 | 2614 | ||
| ... | @@ -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)); |
| 2731 | 2689 | ||
| 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; |
| 2734 | 2692 | ||
| 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; |
| 2744 | 2702 | ||
| 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 | } |
| 2962 | 2920 | ||
| 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); |
| 2990 | 2948 | ||
| 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); |
| 3157 | 3115 | ||
| 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); |
| 3160 | 3118 | ||
| 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-ref | 3194 | 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); |
| 3238 | 3196 | ||
| 3239 | const result_ptr = try self.buildZigAlloca(err_un_ty, .none); | 3197 | const result_ptr = try self.buildZigAlloca(err_un_ty, .none); |
| 3240 | 3198 | ||
| ... | @@ -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 | } |
| 3347 | 3305 | ||
| 3348 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { | 3306 | fn 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); |
| 3374 | 3332 | ||
| 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 }, ""); |
| 3379 | 3337 | ||
| ... | @@ -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); |
| 3550 | 3508 | ||
| 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); |
| 3599 | 3557 | ||
| 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); |
| 3639 | 3597 | ||
| 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); |
| 3697 | 3654 | ||
| 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(); |
| 3711 | 3671 | ||
| 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 | )); |
| 3727 | 3688 | ||
| ... | @@ -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-ref | 3751 | assert(isByRef(inst_ty, zcu)); // auto structs are by-ref |
| 3791 | 3752 | ||
| 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 }, ""); |
| 3796 | 3757 | ||
| ... | @@ -3818,34 +3779,97 @@ fn airOverflow( | ... | @@ -3818,34 +3779,97 @@ fn airOverflow( |
| 3818 | } | 3779 | } |
| 3819 | 3780 | ||
| 3820 | fn buildElementwiseCall( | 3781 | fn 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); | ||
| 3829 | 3812 | ||
| 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); | ||
| 3834 | 3815 | ||
| 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 appropriate | 3877 | /// Creates a floating point comparison by lowering to the appropriate |
| 3854 | /// hardware instruction or softfloat routine for the target | 3878 | /// hardware instruction or softfloat routine for the target |
| 3855 | fn buildFloatCmp( | 3879 | fn 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); | ||
| 3867 | 3890 | ||
| 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 | } |
| 3879 | 3902 | ||
| 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 | }); |
| 3891 | 3914 | 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().?, |
| 3893 | 3916 | .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 | } |
| 3925 | 3928 | ||
| 3926 | const FloatOp = enum { | 3929 | const FloatOp = enum { |
| ... | @@ -3949,32 +3952,30 @@ const FloatOp = enum { | ... | @@ -3949,32 +3952,30 @@ const FloatOp = enum { |
| 3949 | trunc, | 3952 | trunc, |
| 3950 | }; | 3953 | }; |
| 3951 | 3954 | ||
| 3952 | const 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 softfloat | 3956 | /// by lowering to the appropriate hardware instruction or softfloat |
| 3959 | /// routine for the target | 3957 | /// routine for the target |
| 3960 | fn buildFloatOp( | 3958 | fn 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); | ||
| 3973 | 3970 | ||
| 3974 | if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) { | 3971 | switch (op) { |
| 3975 | // Some operations are dedicated LLVM instructions, not available as intrinsics | 3972 | // 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 | }; | ||
| 4032 | 4034 | ||
| 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 the | 4038 | .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 | } | ||
| 4076 | 4200 | ||
| 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( | 4202 | fn 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, .{ |
| 4087 | 4211 | .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 | } |
| 4098 | 4216 | ||
| 4099 | fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 4217 | fn 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-ref | 4248 | assert(isByRef(dest_ty, zcu)); // auto structs are by-ref |
| 4131 | 4249 | ||
| 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), ""); |
| 4133 | 4251 | ||
| 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); |
| 4198 | 4316 | ||
| 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 | else | 4320 | 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 | } |
| 4223 | 4341 | ||
| ... | @@ -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 |
| 4231 | 4349 | ||
| 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); |
| 4236 | 4354 | ||
| 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); |
| 4247 | 4365 | ||
| 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); |
| 4321 | 4439 | ||
| 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); |
| 4324 | 4442 | ||
| 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! |
| 4382 | 4500 | ||
| 4383 | if (!have_min_check and !have_max_check) break :bounds_check; | 4501 | if (!have_min_check and !have_max_check) break :bounds_check; |
| 4384 | 4502 | ||
| 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); |
| 4387 | 4505 | ||
| 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! |
| 4461 | fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 4579 | fn 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 | } |
| 4467 | 4585 | ||
| ... | @@ -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(); |
| 4476 | 4596 | ||
| 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); |
| 4482 | 4602 | 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 | } |
| 4501 | 4607 | ||
| 4502 | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 4608 | 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,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(); |
| 4510 | 4618 | ||
| 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); |
| 4516 | 4624 | 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 | } |
| 4541 | 4629 | ||
| 4542 | fn airBitCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value { | 4630 | fn 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/float | 4646 | // * 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. | ||
| 4562 | 4651 | ||
| 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); | ||
| 4565 | 4662 | ||
| 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)); |
| 4607 | 4828 | ||
| 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 | } |
| 4612 | 4833 | ||
| ... | @@ -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); |
| 4621 | 4842 | ||
| 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 | } |
| 4626 | 4847 | ||
| ... | @@ -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 | } |
| 4762 | 4980 | ||
| 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 | } |
| 4834 | 5052 | ||
| 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); |
| 4851 | 5069 | ||
| 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, ""); | ||
| 4858 | 5085 | ||
| 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, ""); | ||
| 4862 | 5088 | ||
| 4863 | try fg.store(ptr, ptr_alignment, modified_vector, vec_ty, access_kind); | ||
| 4864 | return .none; | 5089 | return .none; |
| 4865 | } | 5090 | } |
| 4866 | 5091 | ||
| 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); |
| 4871 | 5096 | ||
| 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); |
| 4873 | 5098 | ||
| ... | @@ -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; |
| 4928 | 5153 | ||
| 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 | } |
| 4939 | 5171 | ||
| 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 | } |
| 4943 | 5175 | ||
| 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); |
| 4949 | 5179 | ||
| 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); |
| 4951 | 5181 | ||
| 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); | ||
| 4956 | 5247 | ||
| 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 |
| 5002 | fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5293 | fn 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/11946 | 5298 | // 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 |
| 5014 | fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5305 | fn 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 | } |
| 5019 | 5310 | ||
| 5020 | fn airCmpxchg( | 5311 | fn 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 truncating | 5328 | // 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); |
| 5105 | 5396 | ||
| 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 |
| 5130 | 5421 | ||
| 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 | }; |
| 5136 | 5427 | ||
| ... | @@ -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); |
| 5173 | 5464 | ||
| 5174 | self.maybeMarkAllowZeroAccess(info); | 5465 | self.maybeMarkAllowZeroAccess(info); |
| 5175 | 5466 | ||
| ... | @@ -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 | } |
| 5512 | 5803 | ||
| 5513 | fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value { | 5804 | fn 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 | } |
| 5530 | 5821 | ||
| 5531 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5822 | fn 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 |
| 5538 | 5829 | ||
| 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); |
| 5542 | 5833 | ||
| 5543 | if (bits % 16 == 8) { | 5834 | if (bits % 16 == 8) { |
| 5544 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte | 5835 | // 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 |
| 5559 | 5850 | ||
| 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 | } |
| 5564 | 5855 | ||
| 5565 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5856 | fn 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 |
| 5579 | 5870 | ||
| 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); |
| 5639 | 5930 | ||
| 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), ""); |
| 5642 | 5933 | ||
| 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 | } |
| 5654 | 5945 | ||
| 5655 | fn airSelect(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5946 | fn 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); |
| 5777 | 6068 | ||
| 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); |
| 5782 | 6073 | ||
| ... | @@ -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 | } |
| 5850 | 6141 | ||
| 5851 | /// Reduce a vector by repeatedly applying `llvm_fn` to produce an accumulated result. | 6142 | fn 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 | /// ``` | ||
| 5861 | fn 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 | |||
| 5919 | fn 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(); |
| 5923 | 6146 | ||
| 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); | ||
| 5930 | 6151 | ||
| 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 | else | 6163 | 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 | else | 6167 | 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 | }; |
| 5996 | 6217 | 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 | } |
| 6027 | 6295 | ||
| 6028 | fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 6296 | fn 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]); |
| 6036 | 6304 | ||
| 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; |
| 6059 | 6337 | ||
| 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 | else | 6343 | 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 0xaa | 6356 | // 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); |
| 6082 | 6360 | ||
| 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); |
| 6090 | 6368 | ||
| 6091 | const llvm_field_val = try self.resolveInst(elem); | 6369 | const llvm_field_val = try fg.resolveInst(elem); |
| 6092 | 6370 | ||
| 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 | } |
| 6095 | 6373 | ||
| 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)); |
| 6101 | 6379 | ||
| 6102 | const alloca_inst = try self.buildZigAlloca(result_ty, .none); | 6380 | const alloca_inst = try fg.buildZigAlloca(result_ty, .none); |
| 6103 | 6381 | ||
| 6104 | const array_info = result_ty.arrayInfo(zcu); | 6382 | const array_info = result_ty.arrayInfo(zcu); |
| 6105 | 6383 | ||
| 6106 | const elem_size = array_info.elem_type.abiSize(zcu); | 6384 | const elem_size = array_info.elem_type.abiSize(zcu); |
| 6107 | 6385 | ||
| 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 | } |
| 6118 | 6396 | ||
| 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-numbered | 6435 | 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 | } |
| 6223 | 6501 | ||
| 6224 | fn workIntrinsic( | 6502 | fn workIntrinsic( |
| ... | @@ -6370,7 +6648,7 @@ fn load( | ... | @@ -6370,7 +6648,7 @@ fn load( |
| 6370 | }; | 6648 | }; |
| 6371 | 6649 | ||
| 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 | } |
| 6386 | 6664 | ||
| 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); |
| 6389 | 6667 | ||
| 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 special | 6670 | // `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's | 6671 | // 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 load | 6680 | // 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 bits | 6683 | // 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 is | 6684 | // 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 | }; |
| 6444 | 6722 | ||
| 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 | } |
| 6458 | 6736 | ||
| 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)); |
| 6460 | 6738 | ||
| 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); |
| 6463 | 6741 | ||
| 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---see | 6744 | // `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 | } |
| 6482 | 6753 | ||
| 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 | } |
| 6493 | 6757 | ||
| 6494 | fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void { | 6758 | fn 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; |
| 6518 | 6782 | ||
| 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(); |
| 6521 | 6785 | ||
| 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 { |
| 6650 | 6914 | ||
| 6651 | const ParamTypeIterator = struct { | 6915 | const 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, |
| 6660 | 6925 | ||
| 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 | }; |
| 6673 | 6938 | ||
| 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 | } |
| 6681 | 6945 | ||
| 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 | } |
| 6695 | 6958 | ||
| 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) or | 6986 | 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 callconvs | 7240 | // 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 | } |
| 6841 | 7248 | ||
| 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 | } |
| 6882 | 7289 | ||
| 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 | }; |
| 6986 | pub fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTypeIterator { | 7383 | pub 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 | } |
| 6998 | 7400 | ||
| ... | @@ -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 lowered | 7419 | /// 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 then | 7420 | /// 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. |
| 7020 | pub fn fnReturnStrat(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!FnReturnStrat { | 7422 | pub 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() and | 7431 | 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) and | 7432 | 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 returns | 7435 | 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 | }; |
| 7039 | 7439 | 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 callconvs | 7558 | // TODO investigate other callconvs |
| 7099 | else => return .forceByVal(o, ret_ty), | 7559 | else => .forceByVal(o, ret_ty), |
| 7100 | } | 7560 | }; |
| 7101 | } | 7561 | } |
| 7102 | 7562 | ||
| 7103 | fn lowerX86FastcallFnRetTy(o: *Object, zcu: *Zcu, ty: Type) Allocator.Error!FnReturnStrat { | 7563 | fn 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 | } |
| 7117 | 7577 | ||
| 7118 | fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!FnReturnStrat { | 7578 | fn 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 | } |
| 7152 | 7611 | ||
| 7153 | fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!FnReturnStrat { | 7612 | fn 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 only | 7650 | .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` above | 7658 | .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 | } |
| 7226 | 7672 | ||
| 7227 | /// This function deliberately does not handle `_BitInt` because it typically | 7673 | /// 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 | } |
| 7236 | 7682 | ||
| 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; | ||
| 7242 | 7696 | ||
| 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)); |
| 7244 | 7698 | ||
| 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, |
| 7349 | 7800 | ||
| 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 |
| 7392 | fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value { | 7856 | fn 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 | } |
| 7409 | 7873 | ||
| 7410 | fn compilerRtIntBits(bits: u16) ?u16 { | 7874 | fn 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 | } |
| 7418 | 7889 | ||
| ... | @@ -7471,13 +7942,21 @@ fn appendConstraints( | ... | @@ -7471,13 +7942,21 @@ fn appendConstraints( |
| 7471 | } | 7942 | } |
| 7472 | 7943 | ||
| 7473 | /// LLVM does not support all relevant intrinsics for all targets, so we | 7944 | /// 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. |
| 7475 | fn intrinsicsAllowed(scalar_ty: Type, target: *const std.Target) bool { | 7946 | fn 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 | } |
| 7483 | 7962 | ||
| ... | @@ -7823,12 +8302,14 @@ const Builder = std.zig.llvm.Builder; | ... | @@ -7823,12 +8302,14 @@ const Builder = std.zig.llvm.Builder; |
| 7823 | const assert = std.debug.assert; | 8302 | const assert = std.debug.assert; |
| 7824 | const math = std.math; | 8303 | const math = std.math; |
| 7825 | 8304 | ||
| 7826 | const x86_64_abi = @import("../x86_64/abi.zig"); | ||
| 7827 | const wasm_c_abi = @import("../wasm/abi.zig"); | ||
| 7828 | const aarch64_c_abi = @import("../aarch64/abi.zig"); | 8305 | const aarch64_c_abi = @import("../aarch64/abi.zig"); |
| 7829 | const arm_c_abi = @import("../arm/abi.zig"); | 8306 | const arm_c_abi = @import("../arm/abi.zig"); |
| 7830 | const riscv_c_abi = @import("../riscv64/abi.zig"); | 8307 | const loongarch_c_abi = @import("../loongarch/abi.zig"); |
| 7831 | const mips_c_abi = @import("../mips/abi.zig"); | 8308 | const mips_c_abi = @import("../mips/abi.zig"); |
| 8309 | const riscv_c_abi = @import("../riscv64/abi.zig"); | ||
| 8310 | const s390x_c_abi = @import("../s390x/abi.zig"); | ||
| 8311 | const wasm_c_abi = @import("../wasm/abi.zig"); | ||
| 8312 | const x86_64_abi = @import("../x86_64/abi.zig"); | ||
| 7832 | 8313 | ||
| 7833 | const Zcu = @import("../../Zcu.zig"); | 8314 | const Zcu = @import("../../Zcu.zig"); |
| 7834 | const Air = @import("../../Air.zig"); | 8315 | const Air = @import("../../Air.zig"); |
src/codegen/loongarch/abi.zig created+133| ... | @@ -0,0 +1,133 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const InternPool = @import("../../InternPool.zig"); | ||
| 3 | const Type = @import("../../Type.zig"); | ||
| 4 | const Zcu = @import("../../Zcu.zig"); | ||
| 5 | |||
| 6 | pub 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 | |||
| 32 | pub fn classifyType(ty: Type, zcu: *Zcu) Class { | ||
| 33 | return Classifier.init(zcu).classifyType(ty); | ||
| 34 | } | ||
| 35 | |||
| 36 | const 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); |
| 5040 | 5040 | ||
| 5041 | // set the vtype to hold the entire vector's contents in a single element | 5041 | // 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 then | 6871 | // 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 @@ | ||
| 1 | const assert = std.debug.assert; | ||
| 2 | const std = @import("std"); | ||
| 3 | const InternPool = @import("../../InternPool.zig"); | ||
| 4 | const Type = @import("../../Type.zig"); | ||
| 5 | const Zcu = @import("../../Zcu.zig"); | ||
| 6 | |||
| 7 | pub const Context = enum { ret, arg }; | ||
| 8 | |||
| 9 | pub const Class = enum { | ||
| 10 | none, | ||
| 11 | double_or_float, | ||
| 12 | vector, | ||
| 13 | simple, | ||
| 14 | simple_aggregate, | ||
| 15 | pointer, | ||
| 16 | }; | ||
| 17 | |||
| 18 | pub 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; |
| 24 | const errUnionPayloadOffset = codegen.errUnionPayloadOffset; | 24 | const errUnionPayloadOffset = codegen.errUnionPayloadOffset; |
| 25 | const errUnionErrorOffset = codegen.errUnionErrorOffset; | 25 | const errUnionErrorOffset = codegen.errUnionErrorOffset; |
| 26 | 26 | ||
| 27 | const target_util = @import("../../target.zig"); | ||
| 28 | const libcFloatPrefix = target_util.libcFloatPrefix; | ||
| 29 | const libcFloatSuffix = target_util.libcFloatSuffix; | ||
| 30 | const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev; | ||
| 31 | const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; | ||
| 32 | |||
| 33 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { | 27 | pub 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 | } |
| 4346 | 4340 | ||
| ... | @@ -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 | } |
| 4382 | 4376 | ||
| ... | @@ -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 | } |
| 4393 | 4387 | ||
| ... | @@ -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 | } |
| 4411 | 4405 | ||
| ... | @@ -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 | } |
| 4421 | 4415 | ||
| ... | @@ -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 | } |
| 4431 | 4425 | ||
| ... | @@ -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 | } |
| 4441 | 4435 | ||
| ... | @@ -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 | } |
| 4451 | 4445 | ||
| ... | @@ -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 | } |
| 4461 | 4455 | ||
| ... | @@ -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 | } |
| 4471 | 4465 | ||
| ... | @@ -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 | } |
| 4481 | 4475 | ||
| ... | @@ -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 | } |
| 4491 | 4485 | ||
| ... | @@ -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 | } |
| 4509 | 4503 | ||
| ... | @@ -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 | } |
| 4527 | 4521 | ||
| ... | @@ -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 | } |
| 4545 | 4539 | ||
| ... | @@ -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 | } |
| 4563 | 4557 |
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 and | 241 | if (unaligned_size == 8 * 1 * 1 and len == 1) { |
| 242 | elem_ty.isRuntimeFloat()) return Class.stack; // what | 242 | 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, // how | 251 | .sse_sse_x87_per_qword, .none, .none, .none, .none, .none, .none, .none, // how? |
| 250 | } else Class.len_integers, // why | 252 | } 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 | } |
| 396 | 396 | ||
| ... | @@ -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 | } |
| 432 | 435 | ||
| 436 | fn 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 | |||
| 433 | pub const zigcc = struct { | 456 | pub 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 { |
| 91 | 91 | ||
| 92 | fn defineBuiltins(pp: *Preprocessor) !void { | 92 | fn 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); |
| 98 | 98 | ||
| 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 | } |
| 1239 | 1239 | ||
| 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 | } |
| 2132 | 2132 | ||
| 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. |
| 44 | align_dependency_masks: std.ArrayList(u64), | 44 | align_dependency_masks: std.ArrayList(u64), |
| 45 | 45 | ||
| 46 | /// Emitted at the top of the file. This can be cached since it only depends on the target. | ||
| 47 | header: 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. |
| 47 | navs: std.array_hash_map.Auto(InternPool.Nav.Index, RenderedDecl), | 49 | navs: 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 the | 50 | /// 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); |
| 424 | 425 | ||
| 425 | const c_file = try arena.create(C); | 426 | const c = try arena.create(C); |
| 426 | 427 | 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 | }; |
| 450 | 451 | return c; | |
| 451 | return c_file; | ||
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | pub fn deinit(c: *C) void { | 454 | pub 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 | } |
| 471 | 471 | ||
| 472 | pub 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 | |||
| 472 | pub fn updateContainerType( | 487 | pub 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 begin | 957 | // 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 definitions | 961 | // * 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 assembly | 963 | // * 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 |
| 968 | 982 | ||
| 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! |
| 970 | 984 | ||
| 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 definitions | 986 | 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>") |
| 986 | 1000 | ||
| 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 | ); | ||
| 1001 | 1002 | ||
| 1002 | // Big-int type definitions | 1003 | // 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( |
| 3835 | 3835 | ||
| 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-standard | 878 | 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 | } |
| 883 | 883 | ||
| 884 | pub fn compilerRtFloatAbbrev(float_bits: u16) []const u8 { | 884 | pub 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 | #endif | 166 | #endif |
| 167 | #define zig_expand_has_builtin(b) zig_has_builtin(b) | 167 | #define zig_expand_has_builtin(b) zig_has_builtin(b) |
| 168 | 168 | ||
| 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 | #else | 177 | #else |
| ... | @@ -175,9 +181,9 @@ | ... | @@ -175,9 +181,9 @@ |
| 175 | #if __STDC_VERSION__ >= 201112L | 181 | #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 | #else | 185 | #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 | #endif | 187 | #endif |
| 182 | 188 | ||
| 183 | #if __STDC_VERSION__ >= 202311L | 189 | #if __STDC_VERSION__ >= 202311L |
| ... | @@ -193,10 +199,8 @@ | ... | @@ -193,10 +199,8 @@ |
| 193 | #endif | 199 | #endif |
| 194 | 200 | ||
| 195 | #if defined(zig_msvc) | 201 | #if defined(zig_msvc) |
| 196 | #define zig_const_arr | ||
| 197 | #define zig_callconv(c) __##c | 202 | #define zig_callconv(c) __##c |
| 198 | #else | 203 | #else |
| 199 | #define zig_const_arr static const | ||
| 200 | #define zig_callconv(c) __attribute__((c)) | 204 | #define zig_callconv(c) __attribute__((c)) |
| 201 | #endif | 205 | #endif |
| 202 | 206 | ||
| ... | @@ -267,12 +271,20 @@ | ... | @@ -267,12 +271,20 @@ |
| 267 | 271 | ||
| 268 | #if __STDC_VERSION__ >= 202311L | 272 | #if __STDC_VERSION__ >= 202311L |
| 269 | #define zig_align(alignment) alignas(alignment) | 273 | #define zig_align(alignment) alignas(alignment) |
| 270 | #elif __STDC_VERSION__ >= 201112L | 274 | #elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignas) |
| 271 | #define zig_align(alignment) _Alignas(alignment) | 275 | #define zig_align(alignment) _Alignas(alignment) |
| 272 | #else | 276 | #else |
| 273 | #define zig_align(alignment) zig_under_align(alignment) | 277 | #define zig_align(alignment) zig_under_align(alignment) |
| 274 | #endif | 278 | #endif |
| 275 | 279 | ||
| 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 | #else | 363 | #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 | #endif | 366 | #endif |
| 355 | 367 | ||
| 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 */ |
| 370 | 380 | ||
| ... | @@ -550,6 +560,9 @@ | ... | @@ -550,6 +560,9 @@ |
| 550 | #define zig_noreturn | 560 | #define zig_noreturn |
| 551 | #endif | 561 | #endif |
| 552 | 562 | ||
| 563 | #define zig_has_always 1 | ||
| 564 | #define zig_has_never 0 | ||
| 565 | |||
| 553 | #define zig_compiler_rt_abbrev_uint32_t si | 566 | #define zig_compiler_rt_abbrev_uint32_t si |
| 554 | #define zig_compiler_rt_abbrev_int32_t si | 567 | #define zig_compiler_rt_abbrev_int32_t si |
| 555 | #define zig_compiler_rt_abbrev_uint64_t di | 568 | #define zig_compiler_rt_abbrev_uint64_t di |
| ... | @@ -560,7 +573,11 @@ | ... | @@ -560,7 +573,11 @@ |
| 560 | #define zig_compiler_rt_abbrev_zig_f32 sf | 573 | #define zig_compiler_rt_abbrev_zig_f32 sf |
| 561 | #define zig_compiler_rt_abbrev_zig_f64 df | 574 | #define zig_compiler_rt_abbrev_zig_f64 df |
| 562 | #define zig_compiler_rt_abbrev_zig_f80 xf | 575 | #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 tf | 579 | #define zig_compiler_rt_abbrev_zig_f128 tf |
| 580 | #endif | ||
| 564 | 581 | ||
| 565 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); | 582 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); |
| 566 | zig_extern void *memset (void *, int, size_t); | 583 | zig_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)) |
| 647 | 664 | ||
| 648 | #if defined(zig_ez80) | ||
| 649 | typedef unsigned int uint24_t; | ||
| 650 | typedef 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 == 0xFFFFFFFF | 665 | #if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF |
| 659 | typedef unsigned char uint32_t; | 666 | typedef unsigned char uint32_t; |
| 660 | typedef signed char int32_t; | 667 | typedef 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)) |
| 687 | 694 | ||
| 688 | #if defined(zig_ez80) | ||
| 689 | typedef unsigned __int48 uint48_t; | ||
| 690 | typedef 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 == 0xFFFFFFFFFFFFFFFF | 695 | #if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF |
| 700 | typedef unsigned char uint64_t; | 696 | typedef unsigned char uint64_t; |
| 701 | typedef signed char int64_t; | 697 | typedef 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)) |
| 728 | 724 | ||
| 725 | #if defined(zig_ez80) | ||
| 726 | |||
| 727 | typedef unsigned int uint24_t; | ||
| 728 | typedef 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 | |||
| 735 | typedef unsigned __int48 uint48_t; | ||
| 736 | typedef 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 | |||
| 729 | typedef size_t uintptr_t; | 746 | typedef size_t uintptr_t; |
| 730 | typedef ptrdiff_t intptr_t; | 747 | typedef ptrdiff_t intptr_t; |
| 731 | 748 | ||
| ... | @@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t; | ... | @@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t; |
| 739 | #define zig_maxInt_i16 INT16_MAX | 756 | #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_MAX | 758 | #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_MIN | 759 | #define zig_minInt_i32 INT32_MIN |
| 747 | #define zig_maxInt_i32 INT32_MAX | 760 | #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_MAX | 762 | #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_MIN | 763 | #define zig_minInt_i64 INT64_MIN |
| 755 | #define zig_maxInt_i64 INT64_MAX | 764 | #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_MAX | 766 | #define zig_maxInt_u64 UINT64_MAX |
| 758 | 767 | ||
| 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 | ||
| 772 | typedef unsigned int zig_promoted_i8; | ||
| 773 | #elif INT8_MAX <= LONG_MAX | ||
| 774 | typedef unsigned long zig_promoted_i8; | ||
| 775 | #elif INT8_MAX <= LLONG_MAX | ||
| 776 | typedef unsigned long long zig_promoted_i8; | ||
| 777 | #else | ||
| 778 | typedef int8_t zig_promoted_i8; | ||
| 779 | #endif | ||
| 780 | #if UINT8_MAX <= UINT_MAX | ||
| 781 | typedef unsigned int zig_promoted_u8; | ||
| 782 | #elif UINT8_MAX <= ULONG_MAX | ||
| 783 | typedef unsigned long zig_promoted_u8; | ||
| 784 | #elif UINT8_MAX <= ULLONG_MAX | ||
| 785 | typedef unsigned long long zig_promoted_u8; | ||
| 786 | #else | ||
| 787 | typedef uint8_t zig_promoted_u8; | ||
| 788 | #endif | ||
| 789 | |||
| 790 | #if INT16_MAX <= INT_MAX | ||
| 791 | typedef unsigned int zig_promoted_i16; | ||
| 792 | #elif INT16_MAX <= LONG_MAX | ||
| 793 | typedef unsigned long zig_promoted_i16; | ||
| 794 | #elif INT16_MAX <= LLONG_MAX | ||
| 795 | typedef unsigned long long zig_promoted_i16; | ||
| 796 | #else | ||
| 797 | typedef int16_t zig_promoted_i16; | ||
| 798 | #endif | ||
| 799 | #if UINT16_MAX <= UINT_MAX | ||
| 800 | typedef unsigned int zig_promoted_u16; | ||
| 801 | #elif UINT16_MAX <= ULONG_MAX | ||
| 802 | typedef unsigned long zig_promoted_u16; | ||
| 803 | #elif UINT16_MAX <= ULLONG_MAX | ||
| 804 | typedef unsigned long long zig_promoted_u16; | ||
| 805 | #else | ||
| 806 | typedef uint16_t zig_promoted_u16; | ||
| 807 | #endif | ||
| 808 | |||
| 809 | #if INT32_MAX <= INT_MAX | ||
| 810 | typedef unsigned int zig_promoted_i32; | ||
| 811 | #elif INT32_MAX <= LONG_MAX | ||
| 812 | typedef unsigned long zig_promoted_i32; | ||
| 813 | #elif INT32_MAX <= LLONG_MAX | ||
| 814 | typedef unsigned long long zig_promoted_i32; | ||
| 815 | #else | ||
| 816 | typedef int32_t zig_promoted_i32; | ||
| 817 | #endif | ||
| 818 | #if UINT32_MAX <= UINT_MAX | ||
| 819 | typedef unsigned int zig_promoted_u32; | ||
| 820 | #elif UINT32_MAX <= ULONG_MAX | ||
| 821 | typedef unsigned long zig_promoted_u32; | ||
| 822 | #elif UINT32_MAX <= ULLONG_MAX | ||
| 823 | typedef unsigned long long zig_promoted_u32; | ||
| 824 | #else | ||
| 825 | typedef uint32_t zig_promoted_u32; | ||
| 826 | #endif | ||
| 827 | |||
| 828 | #if INT64_MAX <= INT_MAX | ||
| 829 | typedef unsigned int zig_promoted_i64; | ||
| 830 | #elif INT64_MAX <= LONG_MAX | ||
| 831 | typedef unsigned long zig_promoted_i64; | ||
| 832 | #elif INT64_MAX <= LLONG_MAX | ||
| 833 | typedef unsigned long long zig_promoted_i64; | ||
| 834 | #else | ||
| 835 | typedef int64_t zig_promoted_i64; | ||
| 836 | #endif | ||
| 837 | #if UINT64_MAX <= UINT_MAX | ||
| 838 | typedef unsigned int zig_promoted_u64; | ||
| 839 | #elif UINT64_MAX <= ULONG_MAX | ||
| 840 | typedef unsigned long zig_promoted_u64; | ||
| 841 | #elif UINT64_MAX <= ULLONG_MAX | ||
| 842 | typedef unsigned long long zig_promoted_u64; | ||
| 843 | #else | ||
| 844 | typedef 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 | ||
| 859 | typedef unsigned int zig_promoted_i24; | ||
| 860 | #elif INT24_MAX <= LONG_MAX | ||
| 861 | typedef unsigned long zig_promoted_i24; | ||
| 862 | #elif INT24_MAX <= LLONG_MAX | ||
| 863 | typedef unsigned long long zig_promoted_i24; | ||
| 864 | #else | ||
| 865 | typedef int24_t zig_promoted_i24; | ||
| 866 | #endif | ||
| 867 | #if UINT24_MAX <= UINT_MAX | ||
| 868 | typedef unsigned int zig_promoted_u24; | ||
| 869 | #elif UINT24_MAX <= ULONG_MAX | ||
| 870 | typedef unsigned long zig_promoted_u24; | ||
| 871 | #elif UINT24_MAX <= ULLONG_MAX | ||
| 872 | typedef unsigned long long zig_promoted_u24; | ||
| 873 | #else | ||
| 874 | typedef uint24_t zig_promoted_u24; | ||
| 875 | #endif | ||
| 876 | |||
| 877 | #if INT48_MAX <= INT_MAX | ||
| 878 | typedef unsigned int zig_promoted_i48; | ||
| 879 | #elif INT48_MAX <= LONG_MAX | ||
| 880 | typedef unsigned long zig_promoted_i48; | ||
| 881 | #elif INT48_MAX <= LLONG_MAX | ||
| 882 | typedef unsigned long long zig_promoted_i48; | ||
| 883 | #else | ||
| 884 | typedef int48_t zig_promoted_i48; | ||
| 885 | #endif | ||
| 886 | #if UINT48_MAX <= UINT_MAX | ||
| 887 | typedef unsigned int zig_promoted_u48; | ||
| 888 | #elif UINT48_MAX <= ULONG_MAX | ||
| 889 | typedef unsigned long zig_promoted_u48; | ||
| 890 | #elif UINT48_MAX <= ULLONG_MAX | ||
| 891 | typedef unsigned long long zig_promoted_u48; | ||
| 892 | #else | ||
| 893 | typedef 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_MAX | 1054 | zig_int_operators(8) |
| 865 | zig_int_helpers(8, unsigned int) | 1055 | zig_int_operators(16) |
| 866 | #elif UINT8_MAX <= ULONG_MAX | 1056 | zig_int_operators(32) |
| 867 | zig_int_helpers(8, unsigned long) | 1057 | zig_int_operators(64) |
| 868 | #elif UINT8_MAX <= ULLONG_MAX | 1058 | #ifdef zig_ez80 |
| 869 | zig_int_helpers(8, unsigned long long) | 1059 | zig_int_operators(24) |
| 870 | #else | 1060 | zig_int_operators(48) |
| 871 | zig_int_helpers(8, uint8_t) | 1061 | #endif |
| 872 | #endif | 1062 | |
| 873 | #if UINT16_MAX <= UINT_MAX | 1063 | #define zig_int_casts(bw, sw) \ |
| 874 | zig_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_MAX | 1065 | return (uint##sw##_t)arg; \ |
| 876 | zig_int_helpers(16, unsigned long) | 1066 | } \ |
| 877 | #elif UINT16_MAX <= ULLONG_MAX | 1067 | \ |
| 878 | zig_int_helpers(16, unsigned long long) | 1068 | static inline uint##sw##_t zig_u##sw##_intCast_i##bw(int##bw##_t arg) { \ |
| 879 | #else | 1069 | return (uint##sw##_t)arg; \ |
| 880 | zig_int_helpers(16, uint16_t) | 1070 | } \ |
| 881 | #endif | 1071 | \ |
| 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_MAX | 1073 | return (int##sw##_t)arg; \ |
| 884 | zig_int_helpers(24, unsigned int) | 1074 | } \ |
| 885 | #elif UINT24_MAX <= ULONG_MAX | 1075 | \ |
| 886 | zig_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_MAX | 1077 | return (int##sw##_t)arg; \ |
| 888 | zig_int_helpers(24, unsigned long long) | 1078 | } \ |
| 889 | #else | 1079 | \ |
| 890 | zig_int_helpers(24, uint24_t) | 1080 | zig_int_casts_common(bw, sw) |
| 891 | #endif | 1081 | zig_int_casts(16, 8) |
| 892 | #endif | 1082 | zig_int_casts(32, 8) |
| 893 | #if UINT32_MAX <= UINT_MAX | 1083 | zig_int_casts(64, 8) |
| 894 | zig_int_helpers(32, unsigned int) | 1084 | zig_int_casts(32, 16) |
| 895 | #elif UINT32_MAX <= ULONG_MAX | 1085 | zig_int_casts(64, 16) |
| 896 | zig_int_helpers(32, unsigned long) | 1086 | zig_int_casts(64, 32) |
| 897 | #elif UINT32_MAX <= ULLONG_MAX | 1087 | #ifdef zig_ez80 |
| 898 | zig_int_helpers(32, unsigned long long) | 1088 | zig_int_casts(32, 24) |
| 899 | #else | 1089 | zig_int_casts(48, 24) |
| 900 | zig_int_helpers(32, uint32_t) | 1090 | zig_int_casts(64, 24) |
| 901 | #endif | 1091 | zig_int_casts(64, 48) |
| 902 | #if defined(zig_ez80) | ||
| 903 | #if UINT24_MAX <= UINT_MAX | ||
| 904 | zig_int_helpers(48, unsigned int) | ||
| 905 | #elif UINT24_MAX <= ULONG_MAX | ||
| 906 | zig_int_helpers(48, unsigned long) | ||
| 907 | #elif UINT24_MAX <= ULLONG_MAX | ||
| 908 | zig_int_helpers(48, unsigned long long) | ||
| 909 | #else | ||
| 910 | zig_int_helpers(48, uint48_t) | ||
| 911 | #endif | ||
| 912 | #endif | ||
| 913 | #if UINT64_MAX <= UINT_MAX | ||
| 914 | zig_int_helpers(64, unsigned int) | ||
| 915 | #elif UINT64_MAX <= ULONG_MAX | ||
| 916 | zig_int_helpers(64, unsigned long) | ||
| 917 | #elif UINT64_MAX <= ULLONG_MAX | ||
| 918 | zig_int_helpers(64, unsigned long long) | ||
| 919 | #else | ||
| 920 | zig_int_helpers(64, uint64_t) | ||
| 921 | #endif | 1092 | #endif |
| 922 | 1093 | ||
| 923 | static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1094 | static 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 | #else | 1100 | #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 | #else | 1112 | #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 | #endif | 1115 | #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 | } |
| 946 | 1117 | ||
| 947 | static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { | 1118 | static 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 | #else | 1124 | #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 | #else | 1136 | #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 | #endif | 1139 | #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 | } |
| 970 | 1141 | ||
| 971 | static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { | 1142 | static 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 | #else | 1148 | #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 | #endif | 1153 | #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 | #else | 1162 | #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 | #endif | 1167 | #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 | #else | 1176 | #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 | #endif | 1181 | #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 | #else | 1190 | #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 | #endif | 1195 | #endif |
| 1025 | } | 1196 | } |
| 1026 | 1197 | ||
| 1027 | #if defined(zig_ez80) | 1198 | #if defined(zig_ez80) |
| 1199 | |||
| 1028 | static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1200 | static 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 | #else | 1206 | #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 | #endif | 1211 | #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 | #else | 1220 | #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 | #endif | 1225 | #endif |
| 1054 | } | 1226 | } |
| 1055 | #endif | ||
| 1056 | 1227 | ||
| 1057 | #if defined(zig_ez80) | ||
| 1058 | static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1228 | static 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 | #else | 1234 | #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 | #endif | 1239 | #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 | #else | 1248 | #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 | #endif | 1253 | #endif |
| 1084 | } | 1254 | } |
| 1255 | |||
| 1085 | #endif | 1256 | #endif |
| 1086 | 1257 | ||
| 1087 | static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1258 | static 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 | #else | 1264 | #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 | #else | 1276 | #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 | #endif | 1279 | #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 | } |
| 1110 | 1281 | ||
| 1111 | |||
| 1112 | static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { | 1282 | static 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 | #else | 1288 | #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 | #else | 1300 | #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 | #endif | 1303 | #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 | } |
| 1135 | 1305 | ||
| 1136 | static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { | 1306 | static 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 | #else | 1312 | #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 | #endif | 1317 | #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 | #else | 1326 | #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 | #endif | 1331 | #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 | #else | 1340 | #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 | #endif | 1345 | #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 | #else | 1354 | #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 | #endif | 1359 | #endif |
| 1190 | } | 1360 | } |
| 1191 | 1361 | ||
| 1192 | #if defined(zig_ez80) | 1362 | #if defined(zig_ez80) |
| 1363 | |||
| 1193 | static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1364 | static 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 | #else | 1370 | #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 | #endif | 1375 | #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 | #else | 1384 | #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 | #endif | 1389 | #endif |
| 1219 | } | 1390 | } |
| 1220 | #endif | ||
| 1221 | 1391 | ||
| 1222 | #if defined(zig_ez80) | ||
| 1223 | static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1392 | static 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 | #else | 1398 | #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 | #endif | 1403 | #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 | #else | 1412 | #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 | #endif | 1417 | #endif |
| 1249 | } | 1418 | } |
| 1419 | |||
| 1250 | #endif | 1420 | #endif |
| 1251 | 1421 | ||
| 1252 | static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1422 | static 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 | #else | 1428 | #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 | #endif | 1431 | #endif |
| 1262 | } | 1432 | } |
| 1263 | 1433 | ||
| 1264 | zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow); | ||
| 1265 | static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { | 1434 | static 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 | #endif | 1443 | #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 | } |
| 1277 | 1447 | ||
| ... | @@ -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 | #else | 1454 | #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 | #endif | 1457 | #endif |
| 1288 | } | 1458 | } |
| 1289 | 1459 | ||
| 1290 | zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow); | ||
| 1291 | static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { | 1460 | static 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 | #endif | 1469 | #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 | } |
| 1303 | 1473 | ||
| ... | @@ -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 | #else | 1480 | #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 | #endif | 1485 | #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 | #else | 1494 | #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 | #endif | 1499 | #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 | #else | 1508 | #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 | #endif | 1513 | #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 | #else | 1522 | #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 | #endif | 1527 | #endif |
| 1358 | } | 1528 | } |
| 1359 | 1529 | ||
| 1360 | #if defined(zig_ez80) | 1530 | #if defined(zig_ez80) |
| 1531 | |||
| 1361 | static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1532 | static 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 | #else | 1538 | #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 | #endif | 1543 | #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 | #else | 1552 | #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 | #endif | 1557 | #endif |
| 1387 | } | 1558 | } |
| 1388 | #endif | ||
| 1389 | 1559 | ||
| 1390 | #if defined(zig_ez80) | ||
| 1391 | static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1560 | static 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 | #else | 1566 | #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 | #endif | 1571 | #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 | #else | 1580 | #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 | #endif | 1585 | #endif |
| 1417 | } | 1586 | } |
| 1587 | |||
| 1418 | #endif | 1588 | #endif |
| 1419 | 1589 | ||
| 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 | } |
| 1477 | zig_int_builtins(8) | 1652 | zig_int_sat_builtins(8) |
| 1478 | zig_int_builtins(16) | 1653 | zig_int_sat_builtins(16) |
| 1479 | #if defined(zig_ez80) | 1654 | zig_int_sat_builtins(32) |
| 1480 | zig_int_builtins(24) | 1655 | zig_int_sat_builtins(64) |
| 1481 | #endif | ||
| 1482 | zig_int_builtins(32) | ||
| 1483 | #if defined(zig_ez80) | 1656 | #if defined(zig_ez80) |
| 1484 | zig_int_builtins(48) | 1657 | zig_int_sat_builtins(24) |
| 1658 | zig_int_sat_builtins(48) | ||
| 1485 | #endif | 1659 | #endif |
| 1486 | zig_int_builtins(64) | ||
| 1487 | 1660 | ||
| 1488 | #define zig_builtin8(name, val) __builtin_##name(val) | 1661 | #define zig_builtin8(name, arg) __builtin_##name(arg) |
| 1489 | typedef unsigned int zig_Builtin8; | 1662 | typedef unsigned int zig_Builtin8; |
| 1490 | 1663 | ||
| 1491 | #define zig_builtin16(name, val) __builtin_##name(val) | 1664 | #define zig_builtin16(name, arg) __builtin_##name(arg) |
| 1492 | typedef unsigned int zig_Builtin16; | 1665 | typedef unsigned int zig_Builtin16; |
| 1493 | 1666 | ||
| 1494 | #if defined(zig_ez80) | ||
| 1495 | #define zig_builtin24(name, val) __builtin_##name(val) | ||
| 1496 | typedef unsigned int zig_Builtin24; | ||
| 1497 | #endif | ||
| 1498 | |||
| 1499 | #if INT_MIN <= INT32_MIN | 1667 | #if INT_MIN <= INT32_MIN |
| 1500 | #define zig_builtin32(name, val) __builtin_##name(val) | 1668 | #define zig_builtin32(name, arg) __builtin_##name(arg) |
| 1501 | typedef unsigned int zig_Builtin32; | 1669 | typedef unsigned int zig_Builtin32; |
| 1502 | #elif LONG_MIN <= INT32_MIN | 1670 | #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) |
| 1504 | typedef unsigned long zig_Builtin32; | 1672 | typedef unsigned long zig_Builtin32; |
| 1505 | #endif | 1673 | #endif |
| 1506 | 1674 | ||
| 1507 | #if defined(zig_ez80) | ||
| 1508 | #define zig_builtin48(name, val) __builtin_##name(val) | ||
| 1509 | typedef unsigned long long zig_Builtin48; | ||
| 1510 | #endif | ||
| 1511 | |||
| 1512 | #if INT_MIN <= INT64_MIN | 1675 | #if INT_MIN <= INT64_MIN |
| 1513 | #define zig_builtin64(name, val) __builtin_##name(val) | 1676 | #define zig_builtin64(name, arg) __builtin_##name(arg) |
| 1514 | typedef unsigned int zig_Builtin64; | 1677 | typedef unsigned int zig_Builtin64; |
| 1515 | #elif LONG_MIN <= INT64_MIN | 1678 | #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) |
| 1517 | typedef unsigned long zig_Builtin64; | 1680 | typedef unsigned long zig_Builtin64; |
| 1518 | #elif LLONG_MIN <= INT64_MIN | 1681 | #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) |
| 1520 | typedef unsigned long long zig_Builtin64; | 1683 | typedef unsigned long long zig_Builtin64; |
| 1521 | #endif | 1684 | #endif |
| 1522 | 1685 | ||
| 1523 | static 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) |
| 1688 | typedef unsigned int zig_Builtin24; | ||
| 1689 | #define zig_builtin48(name, arg) __builtin_##name(arg) | ||
| 1690 | typedef unsigned long long zig_Builtin48; | ||
| 1691 | #endif | ||
| 1692 | |||
| 1693 | static inline uint8_t zig_byteSwap_u8(uint8_t arg, uint8_t bits) { | ||
| 1694 | return zig_u8_truncate_u8(arg >> (8 - bits), bits); | ||
| 1525 | } | 1695 | } |
| 1526 | 1696 | ||
| 1527 | static inline int8_t zig_byte_swap_i8(int8_t val, uint8_t bits) { | 1697 | static 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 | } |
| 1530 | 1700 | ||
| 1531 | static inline uint16_t zig_byte_swap_u16(uint16_t val, uint8_t bits) { | 1701 | static 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 | #else | 1705 | #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 | #endif | 1708 | #endif |
| 1539 | return zig_wrap_u16(full_res >> (16 - bits), bits); | 1709 | return zig_u16_truncate_u16(full_res >> (16 - bits), bits); |
| 1540 | } | 1710 | } |
| 1541 | 1711 | ||
| 1542 | static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) { | 1712 | static 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 | } |
| 1545 | 1715 | ||
| 1546 | #if defined(zig_ez80) | 1716 | #if defined(zig_ez80) |
| 1547 | static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) { | 1717 | static 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 | #else | 1721 | #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 | #endif | 1724 | #endif |
| 1555 | return zig_wrap_u24(full_res >> (24 - bits), bits); | 1725 | return zig_u24_truncate_u24(full_res >> (24 - bits), bits); |
| 1556 | } | 1726 | } |
| 1557 | 1727 | ||
| 1558 | static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) { | 1728 | static 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 | #endif | 1731 | #endif |
| 1562 | 1732 | ||
| 1563 | static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) { | 1733 | static 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 | #else | 1737 | #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 | #endif | 1740 | #endif |
| 1571 | return zig_wrap_u32(full_res >> (32 - bits), bits); | 1741 | return zig_u32_truncate_u32(full_res >> (32 - bits), bits); |
| 1572 | } | 1742 | } |
| 1573 | 1743 | ||
| 1574 | static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) { | 1744 | static 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 | } |
| 1577 | 1747 | ||
| 1578 | #if defined(zig_ez80) | 1748 | #if defined(zig_ez80) |
| 1579 | static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) { | 1749 | static 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 | #else | 1753 | #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 | #endif | 1756 | #endif |
| 1587 | return zig_wrap_u48(full_res >> (48 - bits), bits); | 1757 | return zig_u48_truncate_u48(full_res >> (48 - bits), bits); |
| 1588 | } | 1758 | } |
| 1589 | 1759 | ||
| 1590 | static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) { | 1760 | static 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 | #endif | 1763 | #endif |
| 1594 | 1764 | ||
| 1595 | static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) { | 1765 | static 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 | #else | 1769 | #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 | #endif | 1772 | #endif |
| 1603 | return zig_wrap_u64(full_res >> (64 - bits), bits); | 1773 | return zig_u64_truncate_u64(full_res >> (64 - bits), bits); |
| 1604 | } | 1774 | } |
| 1605 | 1775 | ||
| 1606 | static inline int64_t zig_byte_swap_i64(int64_t val, uint8_t bits) { | 1776 | static 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 | } |
| 1609 | 1779 | ||
| 1610 | static inline uint8_t zig_bit_reverse_u8(uint8_t val, uint8_t bits) { | 1780 | static 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 | #else | 1784 | #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, 0xf | 1787 | 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 | #endif | 1790 | #endif |
| 1621 | return zig_wrap_u8(full_res >> (8 - bits), bits); | 1791 | return zig_u8_truncate_u8(full_res >> (8 - bits), bits); |
| 1622 | } | 1792 | } |
| 1623 | 1793 | ||
| 1624 | static inline int8_t zig_bit_reverse_i8(int8_t val, uint8_t bits) { | 1794 | static 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 | } |
| 1627 | 1797 | ||
| 1628 | static inline uint16_t zig_bit_reverse_u16(uint16_t val, uint8_t bits) { | 1798 | static 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 | #else | 1802 | #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 | #endif | 1805 | #endif |
| 1636 | return zig_wrap_u16(full_res >> (16 - bits), bits); | 1806 | return zig_u16_truncate_u16(full_res >> (16 - bits), bits); |
| 1637 | } | 1807 | } |
| 1638 | 1808 | ||
| 1639 | static inline int16_t zig_bit_reverse_i16(int16_t val, uint8_t bits) { | 1809 | static 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 | } |
| 1642 | 1812 | ||
| 1643 | #if defined(zig_ez80) | 1813 | #if defined(zig_ez80) |
| 1644 | static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) { | 1814 | static 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 | #else | 1818 | #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 | #endif | 1821 | #endif |
| 1652 | return zig_wrap_u24(full_res >> (24 - bits), bits); | 1822 | return zig_u24_truncate_u24(full_res >> (24 - bits), bits); |
| 1653 | } | 1823 | } |
| 1654 | 1824 | ||
| 1655 | static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) { | 1825 | static 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 | #endif | 1828 | #endif |
| 1659 | 1829 | ||
| 1660 | static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) { | 1830 | static 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 | #else | 1834 | #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 | #endif | 1837 | #endif |
| 1668 | return zig_wrap_u32(full_res >> (32 - bits), bits); | 1838 | return zig_u32_truncate_u32(full_res >> (32 - bits), bits); |
| 1669 | } | 1839 | } |
| 1670 | 1840 | ||
| 1671 | static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) { | 1841 | static 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 | } |
| 1674 | 1844 | ||
| 1675 | #if defined(zig_ez80) | 1845 | #if defined(zig_ez80) |
| 1676 | static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) { | 1846 | static 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 | #else | 1850 | #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 | #endif | 1853 | #endif |
| 1684 | return zig_wrap_u32(full_res >> (48 - bits), bits); | 1854 | return zig_u48_truncate_u48(full_res >> (48 - bits), bits); |
| 1685 | } | 1855 | } |
| 1686 | 1856 | ||
| 1687 | static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) { | 1857 | static 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 | #endif | 1860 | #endif |
| 1691 | 1861 | ||
| 1692 | static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) { | 1862 | static 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 | #else | 1866 | #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 | #endif | 1869 | #endif |
| 1700 | return zig_wrap_u64(full_res >> (64 - bits), bits); | 1870 | return zig_u64_truncate_u64(full_res >> (64 - bits), bits); |
| 1701 | } | 1871 | } |
| 1702 | 1872 | ||
| 1703 | static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) { | 1873 | static 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 | } |
| 1706 | 1876 | ||
| 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 | #else | 1889 | #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 | ||
| 1731 | zig_builtin_popcount(8) | ||
| 1732 | zig_builtin_popcount(16) | ||
| 1733 | #if defined(zig_ez80) | ||
| 1734 | zig_builtin_popcount(24) | ||
| 1735 | #endif | 1900 | #endif |
| 1736 | zig_builtin_popcount(32) | 1901 | zig_builtin_popCount(8) |
| 1902 | zig_builtin_popCount(16) | ||
| 1903 | zig_builtin_popCount(32) | ||
| 1904 | zig_builtin_popCount(64) | ||
| 1737 | #if defined(zig_ez80) | 1905 | #if defined(zig_ez80) |
| 1738 | zig_builtin_popcount(48) | 1906 | zig_builtin_popCount(24) |
| 1907 | zig_builtin_popCount(48) | ||
| 1739 | #endif | 1908 | #endif |
| 1740 | zig_builtin_popcount(64) | ||
| 1741 | 1909 | ||
| 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 | #else | 1922 | #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 | #endif | 1929 | #endif |
| 1762 | zig_builtin_ctz(8) | 1930 | zig_builtin_ctz(8) |
| 1763 | zig_builtin_ctz(16) | 1931 | zig_builtin_ctz(16) |
| 1764 | #if defined(zig_ez80) | ||
| 1765 | zig_builtin_ctz(24) | ||
| 1766 | #endif | ||
| 1767 | zig_builtin_ctz(32) | 1932 | zig_builtin_ctz(32) |
| 1933 | zig_builtin_ctz(64) | ||
| 1768 | #if defined(zig_ez80) | 1934 | #if defined(zig_ez80) |
| 1935 | zig_builtin_ctz(24) | ||
| 1769 | zig_builtin_ctz(48) | 1936 | zig_builtin_ctz(48) |
| 1770 | #endif | 1937 | #endif |
| 1771 | zig_builtin_ctz(64) | ||
| 1772 | 1938 | ||
| 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 | #else | 1951 | #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 | #endif | 1958 | #endif |
| 1793 | zig_builtin_clz(8) | 1959 | zig_builtin_clz(8) |
| 1794 | zig_builtin_clz(16) | 1960 | zig_builtin_clz(16) |
| 1795 | #if defined(zig_ez80) | ||
| 1796 | zig_builtin_clz(24) | ||
| 1797 | #endif | ||
| 1798 | zig_builtin_clz(32) | 1961 | zig_builtin_clz(32) |
| 1962 | zig_builtin_clz(64) | ||
| 1799 | #if defined(zig_ez80) | 1963 | #if defined(zig_ez80) |
| 1964 | zig_builtin_clz(24) | ||
| 1800 | zig_builtin_clz(48) | 1965 | zig_builtin_clz(48) |
| 1801 | #endif | 1966 | #endif |
| 1802 | zig_builtin_clz(64) | ||
| 1803 | 1967 | ||
| 1804 | /* ======================== 128-bit Integer Support ========================= */ | 1968 | /* ======================== 128-bit Integer Support ========================= */ |
| 1805 | 1969 | ||
| ... | @@ -1816,16 +1980,14 @@ zig_builtin_clz(64) | ... | @@ -1816,16 +1980,14 @@ zig_builtin_clz(64) |
| 1816 | typedef unsigned __int128 zig_u128; | 1980 | typedef unsigned __int128 zig_u128; |
| 1817 | typedef signed __int128 zig_i128; | 1981 | typedef signed __int128 zig_i128; |
| 1818 | 1982 | ||
| 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 | } |
| 1837 | 1999 | ||
| 1838 | #else /* zig_has_int128 */ | 2000 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { |
| 2001 | return lhs << rhs; | ||
| 2002 | } | ||
| 1839 | 2003 | ||
| 1840 | #if zig_little_endian | 2004 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { |
| 1841 | typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128; | 2005 | return lhs >> rhs; |
| 1842 | typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128; | 2006 | } |
| 2007 | |||
| 2008 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2009 | return lhs << rhs; | ||
| 2010 | } | ||
| 2011 | |||
| 2012 | static 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 | #else | 2019 | #else |
| 1844 | typedef 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); |
| 1845 | typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; | 2021 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; |
| 1846 | #endif | 2022 | #endif |
| 2023 | } | ||
| 1847 | 2024 | ||
| 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) }) | ||
| 1850 | 2026 | ||
| 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) } | 2028 | typedef 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) } | 2029 | typedef 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) | 2031 | typedef 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) | 2032 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) int64_t hi; uint64_t lo; } zig_i128; |
| 1857 | #endif | 2033 | #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 | } |
| 1874 | 2053 | ||
| 2054 | static 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 | |||
| 2060 | static 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 | |||
| 2066 | static 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 | |||
| 2072 | static 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 */ |
| 1876 | 2079 | ||
| 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, |) |
| 1891 | zig_bit_int128(u128, xor, ^) | 2094 | zig_bit_int128(u128, xor, ^) |
| 1892 | zig_bit_int128(i128, xor, ^) | 2095 | zig_bit_int128(i128, xor, ^) |
| 1893 | 2096 | ||
| 1894 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs); | 2097 | static inline uint8_t zig_u8_intCast_u128(zig_u128 arg) { |
| 2098 | return (uint8_t)zig_lo_u128(arg); | ||
| 2099 | } | ||
| 2100 | static inline uint8_t zig_u8_intCast_i128(zig_i128 arg) { | ||
| 2101 | return (uint8_t)zig_lo_i128(arg); | ||
| 2102 | } | ||
| 2103 | static inline int8_t zig_i8_intCast_i128(zig_i128 arg) { | ||
| 2104 | return (int8_t)zig_lo_i128(arg); | ||
| 2105 | } | ||
| 2106 | static inline int8_t zig_i8_intCast_u128(zig_u128 arg) { | ||
| 2107 | return (int8_t)zig_lo_u128(arg); | ||
| 2108 | } | ||
| 1895 | 2109 | ||
| 1896 | #if zig_has_int128 | 2110 | static inline uint16_t zig_u16_intCast_u128(zig_u128 arg) { |
| 2111 | return (uint16_t)zig_lo_u128(arg); | ||
| 2112 | } | ||
| 2113 | static inline uint16_t zig_u16_intCast_i128(zig_i128 arg) { | ||
| 2114 | return (uint16_t)zig_lo_i128(arg); | ||
| 2115 | } | ||
| 2116 | static inline int16_t zig_i16_intCast_i128(zig_i128 arg) { | ||
| 2117 | return (int16_t)zig_lo_i128(arg); | ||
| 2118 | } | ||
| 2119 | static inline int16_t zig_i16_intCast_u128(zig_u128 arg) { | ||
| 2120 | return (int16_t)zig_lo_u128(arg); | ||
| 2121 | } | ||
| 1897 | 2122 | ||
| 1898 | static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) { | 2123 | static 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 | } | ||
| 2126 | static inline uint32_t zig_u32_intCast_i128(zig_i128 arg) { | ||
| 2127 | return (uint32_t)zig_lo_i128(arg); | ||
| 2128 | } | ||
| 2129 | static inline int32_t zig_i32_intCast_i128(zig_i128 arg) { | ||
| 2130 | return (int32_t)zig_lo_i128(arg); | ||
| 2131 | } | ||
| 2132 | static inline int32_t zig_i32_intCast_u128(zig_u128 arg) { | ||
| 2133 | return (int32_t)zig_lo_u128(arg); | ||
| 1900 | } | 2134 | } |
| 1901 | 2135 | ||
| 1902 | static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) { | 2136 | static inline uint64_t zig_u64_intCast_u128(zig_u128 arg) { |
| 1903 | (void)bits; | 2137 | return zig_lo_u128(arg); |
| 1904 | return ~val; | 2138 | } |
| 2139 | static inline uint64_t zig_u64_intCast_i128(zig_i128 arg) { | ||
| 2140 | return zig_lo_i128(arg); | ||
| 2141 | } | ||
| 2142 | static inline int64_t zig_i64_intCast_i128(zig_i128 arg) { | ||
| 2143 | return (int64_t)zig_lo_i128(arg); | ||
| 2144 | } | ||
| 2145 | static inline int64_t zig_i64_intCast_u128(zig_u128 arg) { | ||
| 2146 | return (int64_t)zig_lo_u128(arg); | ||
| 1905 | } | 2147 | } |
| 1906 | 2148 | ||
| 1907 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { | 2149 | static inline zig_u128 zig_u128_intCast_u8(uint8_t arg) { |
| 1908 | return lhs >> rhs; | 2150 | return zig_make_u128(UINT8_C(0), arg); |
| 2151 | } | ||
| 2152 | static inline zig_u128 zig_u128_intCast_i8(int8_t arg) { | ||
| 2153 | return zig_make_u128(UINT8_C(0), (uint8_t)arg); | ||
| 2154 | } | ||
| 2155 | static inline zig_i128 zig_i128_intCast_i8(int8_t arg) { | ||
| 2156 | return zig_make_i128(zig_shr_i64(arg, 63), (uint8_t)arg); | ||
| 2157 | } | ||
| 2158 | static inline zig_i128 zig_i128_intCast_u8(uint8_t arg) { | ||
| 2159 | return zig_make_i128(INT8_C(0), arg); | ||
| 1909 | } | 2160 | } |
| 1910 | 2161 | ||
| 1911 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { | 2162 | static inline zig_u128 zig_u128_intCast_u16(uint16_t arg) { |
| 1912 | return lhs << rhs; | 2163 | return zig_make_u128(UINT16_C(0), arg); |
| 2164 | } | ||
| 2165 | static inline zig_u128 zig_u128_intCast_i16(int16_t arg) { | ||
| 2166 | return zig_make_u128(UINT16_C(0), (uint16_t)arg); | ||
| 2167 | } | ||
| 2168 | static inline zig_i128 zig_i128_intCast_i16(int16_t arg) { | ||
| 2169 | return zig_make_i128(zig_shr_i64(arg, 63), (uint16_t)arg); | ||
| 2170 | } | ||
| 2171 | static inline zig_i128 zig_i128_intCast_u16(uint16_t arg) { | ||
| 2172 | return zig_make_i128(INT16_C(0), arg); | ||
| 1913 | } | 2173 | } |
| 1914 | 2174 | ||
| 1915 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | 2175 | static inline zig_u128 zig_u128_intCast_u32(uint32_t arg) { |
| 1916 | // This works around a GCC miscompilation, but it has the side benefit of | 2176 | return zig_make_u128(UINT32_C(0), arg); |
| 1917 | // emitting better code. It is behind the `#if` because it depends on | 2177 | } |
| 1918 | // arithmetic right shift, which is implementation-defined in C, but should | 2178 | static 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; | 2181 | static inline zig_i128 zig_i128_intCast_i32(int32_t arg) { |
| 2182 | return zig_make_i128(zig_shr_i64(arg, 63), (uint32_t)arg); | ||
| 2183 | } | ||
| 2184 | static inline zig_i128 zig_i128_intCast_u32(uint32_t arg) { | ||
| 2185 | return zig_make_i128(INT32_C(0), arg); | ||
| 2186 | } | ||
| 2187 | |||
| 2188 | static inline zig_u128 zig_u128_intCast_u64(uint64_t arg) { | ||
| 2189 | return zig_make_u128(UINT64_C(0), arg); | ||
| 2190 | } | ||
| 2191 | static inline zig_u128 zig_u128_intCast_i64(int64_t arg) { | ||
| 2192 | return zig_make_u128(UINT64_C(0), (uint64_t)arg); | ||
| 2193 | } | ||
| 2194 | static inline zig_i128 zig_i128_intCast_i64(int64_t arg) { | ||
| 2195 | return zig_make_i128(zig_shr_i64(arg, 63), (uint64_t)arg); | ||
| 2196 | } | ||
| 2197 | static inline zig_i128 zig_i128_intCast_u64(uint64_t arg) { | ||
| 2198 | return zig_make_i128(INT64_C(0), arg); | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | static inline zig_u128 zig_u128_intCast_u128(zig_u128 arg) { | ||
| 2202 | return arg; | ||
| 2203 | } | ||
| 2204 | static inline zig_u128 zig_u128_intCast_i128(zig_i128 arg) { | ||
| 2205 | #if zig_has_int128 | ||
| 2206 | return (zig_u128)arg; | ||
| 1922 | #else | 2207 | #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 | } | ||
| 2211 | static inline zig_i128 zig_i128_intCast_i128(zig_i128 arg) { | ||
| 2212 | return arg; | ||
| 2213 | } | ||
| 2214 | static 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 | #endif | 2219 | #endif |
| 1926 | } | 2220 | } |
| 1927 | 2221 | ||
| 1928 | static 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 | } | ||
| 2230 | zig_int128_cast_builtins(8) | ||
| 2231 | zig_int128_cast_builtins(16) | ||
| 2232 | zig_int128_cast_builtins(32) | ||
| 2233 | zig_int128_cast_builtins(64) | ||
| 2234 | |||
| 2235 | static 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 | } | ||
| 2238 | static 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 | |||
| 2244 | static inline zig_u128 zig_u128_bitCast_u128(zig_u128 arg, uint8_t bits) { | ||
| 2245 | (void)bits; | ||
| 2246 | return arg; | ||
| 2247 | } | ||
| 2248 | static 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 | } | ||
| 2251 | static inline zig_i128 zig_i128_bitCast_i128(zig_i128 arg, uint8_t bits) { | ||
| 2252 | (void)bits; | ||
| 2253 | return arg; | ||
| 2254 | } | ||
| 2255 | static 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 | |||
| 2261 | static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) { | ||
| 2262 | return arg ^ zig_maxInt_u(128, bits); | ||
| 2263 | } | ||
| 2264 | |||
| 2265 | static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) { | ||
| 2266 | (void)bits; | ||
| 2267 | return ~arg; | ||
| 1930 | } | 2268 | } |
| 1931 | 2269 | ||
| 1932 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { | 2270 | static 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 | } |
| 1955 | 2293 | ||
| 1956 | static inline zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { | 2294 | static inline zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1957 | return lhs / rhs; | 2295 | return lhs / rhs; |
| 1958 | } | 2296 | } |
| 1959 | 2297 | ||
| 1960 | static inline zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { | 2298 | static inline zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1961 | return lhs / rhs; | 2299 | return lhs / rhs; |
| 1962 | } | 2300 | } |
| 1963 | 2301 | ||
| ... | @@ -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) { |
| 1971 | 2309 | ||
| 1972 | #else /* zig_has_int128 */ | 2310 | #else /* zig_has_int128 */ |
| 1973 | 2311 | ||
| 1974 | static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) { | 2312 | static 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 | |||
| 1978 | static 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 | |||
| 1982 | static 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 | |||
| 1988 | static 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 | |||
| 1994 | static 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 | } |
| 1999 | 2316 | ||
| 2000 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | 2317 | static 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 | } |
| 2005 | 2321 | ||
| 2006 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { | 2322 | static 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 | } |
| 2029 | 2345 | ||
| 2030 | zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs); | ||
| 2031 | static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { | 2346 | static 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 | } |
| 2034 | 2350 | ||
| 2035 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) { | 2351 | static 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 | } |
| 2038 | 2354 | ||
| 2039 | zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); | 2355 | static zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2040 | static 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 | } |
| 2043 | 2359 | ||
| 2044 | zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs); | 2360 | static zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2045 | static 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 | } |
| 2048 | 2364 | ||
| 2049 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); | ||
| 2050 | static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) { | 2365 | static 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 | } |
| 2053 | 2369 | ||
| 2054 | zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs); | ||
| 2055 | static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { | 2370 | static 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 | } |
| 2058 | 2374 | ||
| 2059 | #endif /* zig_has_int128 */ | 2375 | #endif /* zig_has_int128 */ |
| 2060 | 2376 | ||
| 2061 | #define zig_div_floor_u128 zig_div_trunc_u128 | 2377 | #define zig_divFloor_u128 zig_divTrunc_u128 |
| 2062 | 2378 | ||
| 2063 | static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) { | 2379 | static 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 | } |
| 2069 | 2385 | ||
| 2070 | static inline zig_u128 zig_div_ceil_u128(zig_u128 lhs, zig_u128 rhs) { | 2386 | static 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 | } |
| 2076 | 2392 | ||
| 2077 | static inline zig_i128 zig_div_ceil_i128(zig_i128 lhs, zig_i128 rhs) { | 2393 | static 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 | } |
| 2084 | 2400 | ||
| 2085 | #define zig_mod_u128 zig_rem_u128 | 2401 | #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 | } |
| 2109 | 2425 | ||
| 2110 | static 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 | |||
| 2114 | static 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 | |||
| 2120 | static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) { | 2426 | static 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 | } |
| 2123 | 2429 | ||
| 2124 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 2430 | static 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 | } |
| 2127 | 2433 | ||
| 2128 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2434 | static 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 | } |
| 2131 | 2437 | ||
| 2132 | static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2438 | static 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 | } |
| 2135 | 2441 | ||
| 2136 | static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2442 | static 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 | } |
| 2139 | 2445 | ||
| 2140 | static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2446 | static 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 | } |
| 2143 | 2449 | ||
| 2144 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2450 | static 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 | } |
| 2147 | 2453 | ||
| 2148 | static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2454 | static 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 | } |
| 2151 | 2457 | ||
| 2152 | static inline zig_u128 zig_abs_i128(zig_i128 val) { | 2458 | static 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 | } |
| 2156 | 2462 | ||
| 2157 | #if zig_has_int128 | 2463 | #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 | #else | 2471 | #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 | #endif | 2484 | #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 | } |
| 2182 | 2488 | ||
| ... | @@ -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 | #else | 2495 | #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 | #endif | 2508 | #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 | } |
| 2206 | 2512 | ||
| ... | @@ -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 | #else | 2519 | #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 | #endif | 2522 | #endif |
| 2217 | } | 2523 | } |
| 2218 | 2524 | ||
| 2219 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2220 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2525 | static 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 | #endif | 2534 | #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 | } |
| 2232 | 2538 | ||
| 2233 | #else /* zig_has_int128 */ | 2539 | #else /* zig_has_int128 */ |
| 2234 | 2540 | ||
| 2235 | static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2541 | static 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 | } |
| 2240 | 2553 | ||
| 2241 | static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2554 | static 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 | } |
| 2246 | 2566 | ||
| 2247 | static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2567 | static 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 | } |
| 2252 | 2579 | ||
| 2253 | static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2580 | static 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 | } |
| 2258 | 2592 | ||
| 2259 | static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2593 | static 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 | } |
| 2264 | 2598 | ||
| 2265 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2266 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2599 | static 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 | } |
| 2275 | 2609 | ||
| ... | @@ -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 |
| 2282 | 2616 | ||
| 2283 | static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 2617 | static 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 | } |
| 2289 | 2623 | ||
| 2290 | static 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 | } | ||
| 2645 | zig_int128_shls_builtins(8) | ||
| 2646 | zig_int128_shls_builtins(16) | ||
| 2647 | zig_int128_shls_builtins(32) | ||
| 2648 | zig_int128_shls_builtins(64) | ||
| 2649 | |||
| 2650 | static 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 | } |
| 2299 | 2659 | ||
| 2300 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) { | 2660 | static 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 | } |
| 2343 | 2703 | ||
| 2344 | static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) { | 2704 | static 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 | } |
| 2349 | 2709 | ||
| 2350 | static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) { | 2710 | static 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 | } |
| 2353 | 2713 | ||
| 2354 | static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) { | 2714 | static 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 | } |
| 2358 | 2718 | ||
| 2359 | static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) { | 2719 | static 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 | } |
| 2362 | 2722 | ||
| 2363 | static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) { | 2723 | static 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 | } |
| 2367 | 2727 | ||
| 2368 | static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) { | 2728 | static 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 | } |
| 2371 | 2731 | ||
| 2372 | static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) { | 2732 | static 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 | #else | 2736 | #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 | #endif | 2741 | #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 | } |
| 2382 | 2744 | ||
| 2383 | static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) { | 2745 | static 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 | } |
| 2386 | 2748 | ||
| 2387 | static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) { | 2749 | static 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 | } |
| 2392 | 2755 | ||
| 2393 | static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { | 2756 | static 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 | } |
| 2396 | 2759 | ||
| 2397 | #if zig_has_int128 | 2760 | #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 =========================== */ |
| 2412 | 2775 | ||
| 2413 | static inline uint16_t zig_int_bytes(uint16_t bits) { | 2776 | static 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 | } |
| 2419 | 2783 | ||
| 2420 | static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 2784 | static 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 | |||
| 2816 | static 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 | |||
| 2848 | static 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 | |||
| 2859 | static 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 | |||
| 2876 | static 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 | } | ||
| 2940 | zig_big_casts(false, u, 8, uint8_t) | ||
| 2941 | zig_big_casts(true , i, 8, int8_t) | ||
| 2942 | zig_big_casts(false, u, 16, uint16_t) | ||
| 2943 | zig_big_casts(true , i, 16, int16_t) | ||
| 2944 | zig_big_casts(false, u, 32, uint32_t) | ||
| 2945 | zig_big_casts(true , i, 32, int32_t) | ||
| 2946 | zig_big_casts(false, u, 64, uint64_t) | ||
| 2947 | zig_big_casts(true , i, 64, int64_t) | ||
| 2948 | zig_big_casts(false, u, 128, zig_u128) | ||
| 2949 | zig_big_casts(true , i, 128, zig_i128) | ||
| 2950 | |||
| 2951 | static 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 | |||
| 2987 | static 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 | #endif | 2995 | #endif |
| 2430 | 2996 | ||
| 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; |
| 2433 | 3000 | ||
| 2434 | #if zig_little_endian | 3001 | #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 |
| 2437 | 3004 | ||
| 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); |
| 2441 | 3008 | ||
| 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); |
| 2449 | 3015 | ||
| 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 | } |
| 2454 | 3019 | ||
| ... | @@ -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 | } |
| 2462 | 3027 | ||
| 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_endian | 3031 | #if zig_little_endian |
| 2465 | byte_offset -= 64 / CHAR_BIT; | 3032 | byte_offset -= 64 / CHAR_BIT; |
| 2466 | #endif | 3033 | #endif |
| 2467 | 3034 | ||
| 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); |
| 2471 | 3038 | ||
| 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); |
| 2479 | 3045 | ||
| 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 | } |
| 2484 | 3049 | ||
| ... | @@ -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 | } |
| 2491 | 3056 | ||
| 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_endian | 3060 | #if zig_little_endian |
| 2494 | byte_offset -= 32 / CHAR_BIT; | 3061 | byte_offset -= 32 / CHAR_BIT; |
| 2495 | #endif | 3062 | #endif |
| 2496 | 3063 | ||
| 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); |
| 2500 | 3067 | ||
| 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); |
| 2508 | 3074 | ||
| 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 | } |
| 2513 | 3078 | ||
| ... | @@ -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 | } |
| 2520 | 3085 | ||
| 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_endian | 3089 | #if zig_little_endian |
| 2523 | byte_offset -= 16 / CHAR_BIT; | 3090 | byte_offset -= 16 / CHAR_BIT; |
| 2524 | #endif | 3091 | #endif |
| 2525 | 3092 | ||
| 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); |
| 2529 | 3096 | ||
| 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); |
| 2537 | 3103 | ||
| 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 | } |
| 2542 | 3107 | ||
| ... | @@ -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 | } |
| 2549 | 3114 | ||
| 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_endian | 3118 | #if zig_little_endian |
| 2552 | byte_offset -= 8 / CHAR_BIT; | 3119 | byte_offset -= 8 / CHAR_BIT; |
| 2553 | #endif | 3120 | #endif |
| 2554 | 3121 | ||
| 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); | ||
| 2558 | 3126 | ||
| 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; |
| 2566 | 3134 | ||
| 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 | } |
| 2571 | 3138 | ||
| ... | @@ -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 | } |
| 2581 | 3148 | ||
| 2582 | static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 3149 | static 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 | ||
| 2589 | 3159 | ||
| 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; | ||
| 2594 | 3162 | ||
| 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 | } | ||
| 2599 | 3183 | ||
| 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 | } |
| 2603 | 3191 | ||
| 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 |
| 2608 | 3196 | ||
| 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 | } | ||
| 2613 | 3213 | ||
| 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 | } |
| 2617 | 3220 | ||
| 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 |
| 2622 | 3225 | ||
| 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 | } | ||
| 2627 | 3242 | ||
| 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 | } |
| 2631 | 3249 | ||
| 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 |
| 2636 | 3254 | ||
| 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 | } | ||
| 2641 | 3271 | ||
| 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 | } |
| 2645 | 3278 | ||
| 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 |
| 2650 | 3283 | ||
| 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 | } | ||
| 2655 | 3300 | ||
| 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 | } |
| 2660 | 3310 | ||
| 2661 | static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 3311 | static 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 | ||
| 2668 | 3321 | ||
| 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; | ||
| 2673 | 3324 | ||
| 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 | } | ||
| 2678 | 3344 | ||
| 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 | } |
| 2682 | 3351 | ||
| 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; | ||
| 2687 | 3354 | ||
| 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 | } | ||
| 2692 | 3374 | ||
| 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 | } |
| 2696 | 3381 | ||
| 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; | ||
| 2701 | 3384 | ||
| 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 | } | ||
| 2706 | 3404 | ||
| 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 | } |
| 2710 | 3411 | ||
| 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; | ||
| 2715 | 3414 | ||
| 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)); | ||
| 2720 | 3418 | ||
| 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 | |||
| 3473 | static 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 | |||
| 3552 | static 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 | } | ||
| 2724 | 3615 | ||
| 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 | } |
| 2818 | 3709 | ||
| 3710 | static 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 | |||
| 3841 | static 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 | |||
| 3972 | static 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 | |||
| 4104 | static 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 | |||
| 4108 | static 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 | |||
| 2819 | static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 4112 | static 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; |
| 2827 | 4120 | ||
| 2828 | #if zig_big_endian | 4121 | #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; |
| 3043 | 4336 | ||
| 3044 | #if zig_big_endian | 4337 | #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 | } |
| 3240 | 4533 | ||
| 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 | |||
| 4544 | static 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 | |||
| 4548 | static 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 | |||
| 4552 | static 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 | |||
| 4562 | static 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 | |||
| 4566 | static 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 | |||
| 4570 | static 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 | |||
| 4580 | static 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 | |||
| 4801 | static 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 | |||
| 4805 | static 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 | |||
| 4809 | static 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 | |||
| 4819 | static 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 | |||
| 4829 | static 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 | |||
| 4839 | static 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 | |||
| 4853 | static 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 | |||
| 4865 | static 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 | |||
| 4875 | static 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 | |||
| 4950 | static 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 | |||
| 5094 | static 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 | |||
| 5098 | static 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 | } | ||
| 5132 | zig_big_shls_builtin(8) | ||
| 5133 | zig_big_shls_builtin(16) | ||
| 5134 | zig_big_shls_builtin(32) | ||
| 5135 | zig_big_shls_builtin(64) | ||
| 5136 | |||
| 5137 | static 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]; | ||
| 3242 | 5159 | ||
| 3243 | #if zig_little_endian | 5160 | #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 | #endif | 5164 | #endif |
| 3246 | } | 5165 | } |
| 3247 | 5166 | ||
| 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 | ||
| 3250 | 5173 | ||
| 3251 | static 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); | ||
| 3254 | 5179 | ||
| 3255 | static 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 | } | ||
| 3258 | 5181 | ||
| 3259 | zig_extern void __udivei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits); | 5182 | #if zig_little_endian |
| 3260 | static 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 | } |
| 3268 | 5191 | ||
| 3269 | static inline void zig_div_floor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5192 | static 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))); | ||
| 3274 | 5201 | ||
| 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 | ||
| 3277 | 5207 | ||
| 3278 | static 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 | ||
| 3281 | 5212 | ||
| 3282 | zig_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)); |
| 3283 | static 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 | } |
| 3288 | 5219 | ||
| 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 | ||
| 3291 | 5226 | ||
| 3292 | static 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 | } |
| 3297 | 5243 | ||
| 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 | } |
| 3300 | 5268 | ||
| 3301 | static inline uint16_t zig_clz_big(const void *val, bool is_signed, uint16_t bits) { | 5269 | static 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; |
| 3309 | 5276 | ||
| 3310 | #if zig_little_endian | 5277 | #if zig_big_endian |
| 3311 | byte_offset = remaining_bytes; | 5278 | byte_offset = zig_int_bytes(bits); |
| 3312 | #endif | 5279 | #endif |
| 3313 | 5280 | ||
| 3314 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5281 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 3315 | #if zig_little_endian | 5282 | 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 | #endif | 5286 | #endif |
| 3318 | 5287 | ||
| 3319 | { | 5288 | { |
| 3320 | zig_u128 val_limb; | 5289 | zig_u128 arg_limb; |
| 3321 | 5290 | ||
| 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 | } |
| 3325 | 5294 | ||
| 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; |
| 3330 | 5296 | ||
| 3331 | #if zig_big_endian | 5297 | #if zig_little_endian |
| 3332 | byte_offset += 128 / CHAR_BIT; | 5298 | byte_offset += 128 / CHAR_BIT; |
| 3333 | #endif | 5299 | #endif |
| 3334 | } | 5300 | } |
| 3335 | 5301 | ||
| 3336 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5302 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3337 | #if zig_little_endian | 5303 | 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 | #endif | 5307 | #endif |
| 3340 | 5308 | ||
| 3341 | { | 5309 | { |
| 3342 | uint64_t val_limb; | 5310 | uint64_t arg_limb; |
| 3343 | 5311 | ||
| 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 | } |
| 3347 | 5315 | ||
| 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; |
| 3352 | 5317 | ||
| 3353 | #if zig_big_endian | 5318 | #if zig_little_endian |
| 3354 | byte_offset += 64 / CHAR_BIT; | 5319 | byte_offset += 64 / CHAR_BIT; |
| 3355 | #endif | 5320 | #endif |
| 3356 | } | 5321 | } |
| 3357 | 5322 | ||
| 3358 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5323 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3359 | #if zig_little_endian | 5324 | 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 | #endif | 5328 | #endif |
| 3362 | 5329 | ||
| 3363 | { | 5330 | { |
| 3364 | uint32_t val_limb; | 5331 | uint32_t arg_limb; |
| 3365 | 5332 | ||
| 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 | } |
| 3369 | 5336 | ||
| 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; |
| 3374 | 5338 | ||
| 3375 | #if zig_big_endian | 5339 | #if zig_little_endian |
| 3376 | byte_offset += 32 / CHAR_BIT; | 5340 | byte_offset += 32 / CHAR_BIT; |
| 3377 | #endif | 5341 | #endif |
| 3378 | } | 5342 | } |
| 3379 | 5343 | ||
| 3380 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5344 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3381 | #if zig_little_endian | 5345 | 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 | #endif | 5349 | #endif |
| 3384 | 5350 | ||
| 3385 | { | 5351 | { |
| 3386 | uint16_t val_limb; | 5352 | uint16_t arg_limb; |
| 3387 | 5353 | ||
| 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 | } |
| 3391 | 5357 | ||
| 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; |
| 3396 | 5359 | ||
| 3397 | #if zig_big_endian | 5360 | #if zig_little_endian |
| 3398 | byte_offset += 16 / CHAR_BIT; | 5361 | byte_offset += 16 / CHAR_BIT; |
| 3399 | #endif | 5362 | #endif |
| 3400 | } | 5363 | } |
| 3401 | 5364 | ||
| 3402 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5365 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3403 | #if zig_little_endian | 5366 | 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 | #endif | 5370 | #endif |
| 3406 | 5371 | ||
| 3407 | { | 5372 | { |
| 3408 | uint8_t val_limb; | 5373 | uint8_t arg_limb; |
| 3409 | 5374 | ||
| 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 | } |
| 3413 | 5378 | ||
| 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; |
| 3418 | 5380 | ||
| 3419 | #if zig_big_endian | 5381 | #if zig_little_endian |
| 3420 | byte_offset += 8 / CHAR_BIT; | 5382 | byte_offset += 8 / CHAR_BIT; |
| 3421 | #endif | 5383 | #endif |
| 3422 | } | 5384 | } |
| 3423 | 5385 | ||
| 3424 | return total_lz; | 5386 | return total_pc; |
| 3425 | } | 5387 | } |
| 3426 | 5388 | ||
| 3427 | static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bits) { | 5389 | static 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; |
| 3434 | 5397 | ||
| 3435 | #if zig_big_endian | 5398 | #if zig_big_endian |
| 3436 | byte_offset = remaining_bytes; | 5399 | byte_offset = zig_int_bytes(bits); |
| 3437 | #endif | 5400 | #endif |
| 3438 | 5401 | ||
| 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_endian | 5405 | #if zig_big_endian |
| 3441 | byte_offset -= 128 / CHAR_BIT; | 5406 | byte_offset -= 128 / CHAR_BIT; |
| 3442 | #endif | 5407 | #endif |
| 3443 | 5408 | ||
| 3444 | { | 5409 | { |
| 3445 | zig_u128 val_limb; | 5410 | zig_u128 arg_limb; |
| 3446 | 5411 | ||
| 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 | } |
| 3450 | 5415 | ||
| 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; |
| 3454 | 5419 | ||
| 3455 | #if zig_little_endian | 5420 | #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 | } |
| 3459 | 5424 | ||
| 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_endian | 5428 | #if zig_big_endian |
| 3462 | byte_offset -= 64 / CHAR_BIT; | 5429 | byte_offset -= 64 / CHAR_BIT; |
| 3463 | #endif | 5430 | #endif |
| 3464 | 5431 | ||
| 3465 | { | 5432 | { |
| 3466 | uint64_t val_limb; | 5433 | uint64_t arg_limb; |
| 3467 | 5434 | ||
| 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 | } |
| 3471 | 5438 | ||
| 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; |
| 3475 | 5442 | ||
| 3476 | #if zig_little_endian | 5443 | #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 | } |
| 3480 | 5447 | ||
| 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_endian | 5451 | #if zig_big_endian |
| 3483 | byte_offset -= 32 / CHAR_BIT; | 5452 | byte_offset -= 32 / CHAR_BIT; |
| 3484 | #endif | 5453 | #endif |
| 3485 | 5454 | ||
| 3486 | { | 5455 | { |
| 3487 | uint32_t val_limb; | 5456 | uint32_t arg_limb; |
| 3488 | 5457 | ||
| 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 | } |
| 3492 | 5461 | ||
| 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; |
| 3496 | 5465 | ||
| 3497 | #if zig_little_endian | 5466 | #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 | } |
| 3501 | 5470 | ||
| 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_endian | 5474 | #if zig_big_endian |
| 3504 | byte_offset -= 16 / CHAR_BIT; | 5475 | byte_offset -= 16 / CHAR_BIT; |
| 3505 | #endif | 5476 | #endif |
| 3506 | 5477 | ||
| 3507 | { | 5478 | { |
| 3508 | uint16_t val_limb; | 5479 | uint16_t arg_limb; |
| 3509 | 5480 | ||
| 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 | } |
| 3513 | 5484 | ||
| 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; |
| 3517 | 5488 | ||
| 3518 | #if zig_little_endian | 5489 | #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 | } |
| 3522 | 5493 | ||
| 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_endian | 5497 | #if zig_big_endian |
| 3525 | byte_offset -= 8 / CHAR_BIT; | 5498 | byte_offset -= 8 / CHAR_BIT; |
| 3526 | #endif | 5499 | #endif |
| 3527 | 5500 | ||
| 3528 | { | 5501 | { |
| 3529 | uint8_t val_limb; | 5502 | uint8_t arg_limb; |
| 3530 | 5503 | ||
| 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 | } |
| 3534 | 5507 | ||
| 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; |
| 3538 | 5511 | ||
| 3539 | #if zig_little_endian | 5512 | #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 | } |
| 3546 | 5519 | ||
| 3547 | static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_t bits) { | 5520 | static 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; |
| 3553 | 5529 | ||
| 3554 | #if zig_big_endian | 5530 | #if zig_big_endian |
| 3555 | byte_offset = remaining_bytes; | 5531 | byte_offset = zig_int_bytes(bits) - remaining_bytes; |
| 3556 | #endif | 5532 | #endif |
| 3557 | 5533 | ||
| 3558 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5534 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 3559 | #if zig_big_endian | 5535 | 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 | #endif | 5539 | #endif |
| 3562 | 5540 | ||
| 3563 | { | 5541 | { |
| 3564 | zig_u128 val_limb; | 5542 | zig_u128 arg_limb; |
| 3565 | 5543 | ||
| 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 | } |
| 3569 | 5547 | ||
| 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; |
| 3571 | 5552 | ||
| 3572 | #if zig_little_endian | 5553 | #if zig_big_endian |
| 3573 | byte_offset += 128 / CHAR_BIT; | 5554 | byte_offset += 128 / CHAR_BIT; |
| 3574 | #endif | 5555 | #endif |
| 3575 | } | 5556 | } |
| 3576 | 5557 | ||
| 3577 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5558 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3578 | #if zig_big_endian | 5559 | 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 | #endif | 5563 | #endif |
| 3581 | 5564 | ||
| 3582 | { | 5565 | { |
| 3583 | uint64_t val_limb; | 5566 | uint64_t arg_limb; |
| 3584 | 5567 | ||
| 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 | } |
| 3588 | 5571 | ||
| 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; |
| 3590 | 5576 | ||
| 3591 | #if zig_little_endian | 5577 | #if zig_big_endian |
| 3592 | byte_offset += 64 / CHAR_BIT; | 5578 | byte_offset += 64 / CHAR_BIT; |
| 3593 | #endif | 5579 | #endif |
| 3594 | } | 5580 | } |
| 3595 | 5581 | ||
| 3596 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5582 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3597 | #if zig_big_endian | 5583 | 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 | #endif | 5587 | #endif |
| 3600 | 5588 | ||
| 3601 | { | 5589 | { |
| 3602 | uint32_t val_limb; | 5590 | uint32_t arg_limb; |
| 3603 | 5591 | ||
| 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 | } |
| 3607 | 5595 | ||
| 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; |
| 3609 | 5600 | ||
| 3610 | #if zig_little_endian | 5601 | #if zig_big_endian |
| 3611 | byte_offset += 32 / CHAR_BIT; | 5602 | byte_offset += 32 / CHAR_BIT; |
| 3612 | #endif | 5603 | #endif |
| 3613 | } | 5604 | } |
| 3614 | 5605 | ||
| 3615 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5606 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3616 | #if zig_big_endian | 5607 | 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 | #endif | 5611 | #endif |
| 3619 | 5612 | ||
| 3620 | { | 5613 | { |
| 3621 | uint16_t val_limb; | 5614 | uint16_t arg_limb; |
| 3622 | 5615 | ||
| 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 | } |
| 3626 | 5619 | ||
| 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; |
| 3628 | 5624 | ||
| 3629 | #if zig_little_endian | 5625 | #if zig_big_endian |
| 3630 | byte_offset += 16 / CHAR_BIT; | 5626 | byte_offset += 16 / CHAR_BIT; |
| 3631 | #endif | 5627 | #endif |
| 3632 | } | 5628 | } |
| 3633 | 5629 | ||
| 3634 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5630 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3635 | #if zig_big_endian | 5631 | 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 | #endif | 5635 | #endif |
| 3638 | 5636 | ||
| 3639 | { | 5637 | { |
| 3640 | uint8_t val_limb; | 5638 | uint8_t arg_limb; |
| 3641 | 5639 | ||
| 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 | } |
| 3645 | 5643 | ||
| 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; |
| 3647 | 5648 | ||
| 3648 | #if zig_little_endian | 5649 | #if zig_big_endian |
| 3649 | byte_offset += 8 / CHAR_BIT; | 5650 | byte_offset += 8 / CHAR_BIT; |
| 3650 | #endif | 5651 | #endif |
| 3651 | } | 5652 | } |
| 3652 | 5653 | ||
| 3653 | return total_pc; | 5654 | return total_lz; |
| 3654 | } | 5655 | } |
| 3655 | 5656 | ||
| 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 | #else | 5690 | #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 | #endif | 5696 | #endif |
| 3696 | 5697 | ||
| 3697 | #define zig_has_f16 1 | 5698 | #define zig_has_f16 1 |
| 3698 | #define zig_libc_name_f16(name) __##name##h | 5699 | #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 == 11 | 5701 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT_MANT_DIG == 11 |
| 3701 | typedef float zig_f16; | 5702 | typedef float zig_f16; |
| 3702 | #define zig_make_f16(fp, repr) fp##f | 5703 | #define zig_make_f16(fp, repr) fp##f |
| 3703 | #elif DBL_MANT_DIG == 11 | 5704 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && DBL_MANT_DIG == 11 |
| 3704 | typedef double zig_f16; | 5705 | typedef double zig_f16; |
| 3705 | #define zig_make_f16(fp, repr) fp | 5706 | #define zig_make_f16(fp, repr) fp |
| 3706 | #elif LDBL_MANT_DIG == 11 | 5707 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && LDBL_MANT_DIG == 11 |
| 3707 | typedef long double zig_f16; | 5708 | typedef long double zig_f16; |
| 3708 | #define zig_make_f16(fp, repr) fp##l | 5709 | #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)) |
| 3710 | typedef _Float16 zig_f16; | 5711 | typedef _Float16 zig_f16; |
| 3711 | #define zig_make_f16(fp, repr) fp##f16 | 5712 | #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__) |
| 3713 | typedef __fp16 zig_f16; | 5714 | typedef __fp16 zig_f16; |
| 3714 | #define zig_make_f16(fp, repr) fp##f16 | 5715 | #define zig_make_f16(fp, repr) fp##f16 |
| 3715 | #else | 5716 | #else |
| ... | @@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16; | ... | @@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16; |
| 3723 | #undef zig_init_special_f16 | 5724 | #undef zig_init_special_f16 |
| 3724 | #define zig_init_special_f16(sign, name, arg, repr) repr | 5725 | #define zig_init_special_f16(sign, name, arg, repr) repr |
| 3725 | #endif | 5726 | #endif |
| 3726 | #if defined(zig_darwin) && defined(zig_x86) | ||
| 3727 | typedef uint16_t zig_compiler_rt_f16; | ||
| 3728 | #else | ||
| 3729 | typedef zig_f16 zig_compiler_rt_f16; | ||
| 3730 | #endif | ||
| 3731 | 5727 | ||
| 3732 | #define zig_has_f32 1 | 5728 | #define zig_has_f32 1 |
| 3733 | #define zig_libc_name_f32(name) name##f | 5729 | #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 | #else | 5732 | #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 | #endif | 5734 | #endif |
| 3739 | #if FLT_MANT_DIG == 24 | 5735 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT_MANT_DIG == 24 |
| 3740 | typedef float zig_f32; | 5736 | typedef float zig_f32; |
| 3741 | #define zig_make_f32(fp, repr) fp##f | 5737 | #define zig_make_f32(fp, repr) fp##f |
| 3742 | #elif DBL_MANT_DIG == 24 | 5738 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && DBL_MANT_DIG == 24 |
| 3743 | typedef double zig_f32; | 5739 | typedef double zig_f32; |
| 3744 | #define zig_make_f32(fp, repr) fp | 5740 | #define zig_make_f32(fp, repr) fp |
| 3745 | #elif LDBL_MANT_DIG == 24 | 5741 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && LDBL_MANT_DIG == 24 |
| 3746 | typedef long double zig_f32; | 5742 | typedef long double zig_f32; |
| 3747 | #define zig_make_f32(fp, repr) fp##l | 5743 | #define zig_make_f32(fp, repr) fp##l |
| 3748 | #elif FLT32_MANT_DIG == 24 | 5744 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT32_MANT_DIG == 24 |
| 3749 | typedef _Float32 zig_f32; | 5745 | typedef _Float32 zig_f32; |
| 3750 | #define zig_make_f32(fp, repr) fp##f32 | 5746 | #define zig_make_f32(fp, repr) fp##f32 |
| 3751 | #else | 5747 | #else |
| ... | @@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32; | ... | @@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32; |
| 3768 | #else | 5764 | #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 | #endif | 5766 | #endif |
| 3771 | #if FLT_MANT_DIG == 53 | 5767 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT_MANT_DIG == 53 |
| 3772 | typedef float zig_f64; | 5768 | typedef float zig_f64; |
| 3773 | #define zig_make_f64(fp, repr) fp##f | 5769 | #define zig_make_f64(fp, repr) fp##f |
| 3774 | #elif DBL_MANT_DIG == 53 | 5770 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && DBL_MANT_DIG == 53 |
| 3775 | typedef double zig_f64; | 5771 | typedef double zig_f64; |
| 3776 | #define zig_make_f64(fp, repr) fp | 5772 | #define zig_make_f64(fp, repr) fp |
| 3777 | #elif LDBL_MANT_DIG == 53 | 5773 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && LDBL_MANT_DIG == 53 |
| 3778 | typedef long double zig_f64; | 5774 | typedef long double zig_f64; |
| 3779 | #define zig_make_f64(fp, repr) fp##l | 5775 | #define zig_make_f64(fp, repr) fp##l |
| 3780 | #elif FLT64_MANT_DIG == 53 | 5776 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT64_MANT_DIG == 53 |
| 3781 | typedef _Float64 zig_f64; | 5777 | typedef _Float64 zig_f64; |
| 3782 | #define zig_make_f64(fp, repr) fp##f64 | 5778 | #define zig_make_f64(fp, repr) fp##f64 |
| 3783 | #elif FLT32X_MANT_DIG == 53 | 5779 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT32X_MANT_DIG == 53 |
| 3784 | typedef _Float32x zig_f64; | 5780 | typedef _Float32x zig_f64; |
| 3785 | #define zig_make_f64(fp, repr) fp##f32x | 5781 | #define zig_make_f64(fp, repr) fp##f32x |
| 3786 | #else | 5782 | #else |
| ... | @@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64; | ... | @@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64; |
| 3798 | #define zig_has_f80 1 | 5794 | #define zig_has_f80 1 |
| 3799 | #define zig_libc_name_f80(name) __##name##x | 5795 | #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 == 64 | 5797 | #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F80_ABI |
| 5798 | #undef zig_has_f80 | ||
| 5799 | typedef 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 | ||
| 3802 | typedef float zig_f80; | 5805 | typedef float zig_f80; |
| 3803 | #define zig_make_f80(fp, repr) fp##f | 5806 | #define zig_make_f80(fp, repr) fp##f |
| 3804 | #elif DBL_MANT_DIG == 64 | 5807 | #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##l | 5821 | #define zig_make_f80(fp, repr) fp##l |
| 3819 | #else | 5822 | #else |
| 3820 | #undef zig_has_f80 | 5823 | #undef zig_has_f80 |
| 3821 | #define zig_has_f80 0 | ||
| 3822 | #define zig_repr_f80 u128 | ||
| 3823 | typedef zig_u128 zig_f80; | 5824 | typedef 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) repr | 5832 | #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_f80 | 5836 | #undef zig_make_special_f80 |
| 3826 | #define zig_make_special_f80(sign, name, arg, repr) repr | 5837 | #define zig_make_special_f80(sign, name, arg, repr) repr |
| 3827 | #undef zig_init_special_f80 | 5838 | #undef zig_init_special_f80 |
| 3828 | #define zig_init_special_f80(sign, name, arg, repr) repr | 5839 | #define zig_init_special_f80(sign, name, arg, repr) repr |
| 3829 | #endif | 5840 | #endif |
| 3830 | 5841 | ||
| 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 1 | 5842 | #define zig_has_f128 1 |
| 3838 | #define zig_libc_name_f128(name) name##q | 5843 | #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 == 113 | 5845 | #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F128_ABI |
| 5846 | #undef zig_has_f128 | ||
| 5847 | #if zig_little_endian | ||
| 5848 | typedef struct { uint64_t lo, hi; } zig_f128; | ||
| 5849 | #else | ||
| 5850 | typedef 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 | ||
| 3841 | typedef float zig_f128; | 5856 | typedef float zig_f128; |
| 3842 | #define zig_make_f128(fp, repr) fp##f | 5857 | #define zig_make_f128(fp, repr) fp##f |
| 3843 | #elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113 | 5858 | #elif DBL_MANT_DIG == 113 |
| 3844 | typedef double zig_f128; | 5859 | typedef double zig_f128; |
| 3845 | #define zig_make_f128(fp, repr) fp | 5860 | #define zig_make_f128(fp, repr) fp |
| 3846 | #elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113 | 5861 | #elif LDBL_MANT_DIG == 113 |
| 3847 | typedef long double zig_f128; | 5862 | typedef long double zig_f128; |
| 3848 | #define zig_make_f128(fp, repr) fp##l | 5863 | #define zig_make_f128(fp, repr) fp##l |
| 3849 | #elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113 | 5864 | #elif FLT128_MANT_DIG == 113 |
| 3850 | typedef _Float128 zig_f128; | 5865 | typedef _Float128 zig_f128; |
| 3851 | #define zig_make_f128(fp, repr) fp##f128 | 5866 | #define zig_make_f128(fp, repr) fp##f128 |
| 3852 | #elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113 | 5867 | #elif FLT64X_MANT_DIG == 113 |
| 3853 | typedef _Float64x zig_f128; | 5868 | typedef _Float64x zig_f128; |
| 3854 | #define zig_make_f128(fp, repr) fp##f64x | 5869 | #define zig_make_f128(fp, repr) fp##f64x |
| 3855 | #elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__) | 5870 | #elif defined(__SIZEOF_FLOAT128__) |
| 3856 | typedef __float128 zig_f128; | 5871 | typedef __float128 zig_f128; |
| 3857 | #define zig_make_f128(fp, repr) fp##q | 5872 | #define zig_make_f128(fp, repr) fp##q |
| 3858 | #undef zig_make_special_f128 | 5873 | #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 | #else | 5875 | #else |
| 3861 | #undef zig_has_f128 | 5876 | #undef zig_has_f128 |
| 3862 | #define zig_has_f128 0 | 5877 | #if defined(zig_x86_64) && defined(ZIG_TARGET_ABI_MSVC) |
| 3863 | #undef zig_make_special_f128 | 5878 | #if defined(zig_msvc) && !defined(__clang__) |
| 3864 | #undef zig_init_special_f128 | 5879 | #include <emmintrin.h> |
| 3865 | #if defined(zig_darwin) || defined(zig_aarch64) | 5880 | typedef __m128i zig_f128; |
| 3866 | typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64; | 5881 | #define zig_init_repr_f128(hi, lo) { .m128i_u64 = { lo, hi } } |
| 3867 | zig_basic_operator(zig_v2u64, xor_v2u64, ^) | 5882 | #define zig_lo_repr_f128(arg) (arg).m128i_u64[0] |
| 3868 | #define zig_repr_f128 v2u64 | 5883 | #define zig_hi_repr_f128(arg) (arg).m128i_u64[1] |
| 3869 | typedef zig_v2u64 zig_f128; | 5884 | #else |
| 3870 | #define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi } | 5885 | typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_f128; |
| 3871 | #define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u128 | 5886 | #define zig_init_repr_f128(hi, lo) { lo, hi } |
| 3872 | #define zig_make_f128(fp, repr) zig_make_f128_##repr | 5887 | #define zig_lo_repr_f128(arg) (arg)[0] |
| 3873 | #define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr | 5888 | #define zig_hi_repr_f128(arg) (arg)[1] |
| 3874 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr | 5889 | #endif |
| 3875 | #else | 5890 | #else |
| 3876 | #define zig_repr_f128 u128 | ||
| 3877 | typedef zig_u128 zig_f128; | 5891 | typedef 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) repr | 5900 | #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) repr | 5905 | #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) repr | 5907 | #define zig_init_special_f128(sign, name, arg, repr) repr |
| 3881 | #endif | 5908 | #endif |
| 3882 | #endif | ||
| 3883 | 5909 | ||
| 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; |
| 3892 | typedef long double zig_c_longdouble; | 5918 | typedef long double zig_c_longdouble; |
| 3893 | #endif | 5919 | #endif |
| 3894 | 5920 | ||
| 3895 | #define zig_bitCast_float(Type, ReprType) \ | 5921 | #if __AVR__ |
| 3896 | static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \ | 5922 | typedef signed char zig_FloatCompareResult; |
| 3897 | zig_##Type result; \ | 5923 | #elif defined(zig_aarch64) |
| 3898 | memcpy(&result, &repr, sizeof(result)); \ | 5924 | typedef signed int zig_FloatCompareResult; |
| 3899 | return result; \ | 5925 | #elif __SIZEOF_LONG__ >= __SIZEOF_POINTER__ |
| 5926 | typedef signed long zig_FloatCompareResult; | ||
| 5927 | #else | ||
| 5928 | typedef 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 | } |
| 3901 | zig_bitCast_float(f16, uint16_t) | 5952 | zig_bitCast_float(16, 16, uint16_t, int16_t) |
| 3902 | zig_bitCast_float(f32, uint32_t) | 5953 | zig_bitCast_float(32, 32, uint32_t, int32_t) |
| 3903 | zig_bitCast_float(f64, uint64_t) | 5954 | zig_bitCast_float(64, 64, uint64_t, int64_t) |
| 3904 | zig_bitCast_float(f80, zig_u128) | 5955 | #if zig_has_f80 |
| 3905 | zig_bitCast_float(f128, zig_u128) | 5956 | zig_bitCast_float(80, 128, zig_u128, zig_i128) |
| 5957 | #else | ||
| 5958 | static 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 | } | ||
| 5961 | static 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 | } | ||
| 5964 | static 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 | } | ||
| 5967 | static 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 | ||
| 5971 | static 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 | } | ||
| 5974 | static 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 | ||
| 5982 | zig_bitCast_float(128, 128, zig_u128, zig_i128) | ||
| 5983 | #else | ||
| 5984 | static 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 | } | ||
| 5987 | static 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 | } | ||
| 5990 | static 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 | } | ||
| 5993 | static 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 | ||
| 3906 | 5997 | ||
| 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; \ | 6019 | zig_convert_floats(f16, f32) |
| 3920 | } | 6020 | zig_convert_floats(f16, f64) |
| 3921 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2) | 6021 | zig_convert_floats(f16, f80) |
| 3922 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2) | 6022 | zig_convert_floats(f16, f128) |
| 3923 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2) | 6023 | zig_convert_floats(f32, f64) |
| 3924 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2) | 6024 | zig_convert_floats(f32, f80) |
| 3925 | zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2) | 6025 | zig_convert_floats(f32, f128) |
| 3926 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2) | 6026 | zig_convert_floats(f64, f80) |
| 3927 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2) | 6027 | zig_convert_floats(f64, f128) |
| 3928 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2) | 6028 | zig_convert_floats(f80, f128) |
| 3929 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2) | 6029 | |
| 3930 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2) | 6030 | #define zig_float_negate_builtin_0(w, sb) \ |
| 3931 | zig_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)) |
| 3932 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2) | 6032 | #define zig_float_negate_builtin_1(w, sb) -arg |
| 3933 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2) | 6033 | #define zig_float_negate_builtin(w, sb) \ |
| 3934 | zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2) | ||
| 3935 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2) | ||
| 3936 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2) | ||
| 3937 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2) | ||
| 3938 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2) | ||
| 3939 | |||
| 3940 | #ifdef __ARM_EABI__ | ||
| 3941 | |||
| 3942 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_d2f(zig_f64); | ||
| 3943 | static inline zig_f32 zig_truncdfsf(zig_f64 arg) { return __aeabi_d2f(arg); } | ||
| 3944 | |||
| 3945 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_f2d(zig_f32); | ||
| 3946 | static inline zig_f64 zig_extendsfdf(zig_f32 arg) { return __aeabi_f2d(arg); } | ||
| 3947 | |||
| 3948 | #else /* __ARM_EABI__ */ | ||
| 3949 | |||
| 3950 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2) | ||
| 3951 | zig_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 | } |
| 3962 | zig_float_negate_builtin(16, , UINT16_C(1) << 15 ) | 6037 | zig_float_negate_builtin(16, UINT16_C(1) << 15) |
| 3963 | zig_float_negate_builtin(32, , UINT32_C(1) << 31 ) | 6038 | zig_float_negate_builtin(32, UINT32_C(1) << 31) |
| 3964 | zig_float_negate_builtin(64, , UINT64_C(1) << 63 ) | 6039 | zig_float_negate_builtin(64, UINT64_C(1) << 63) |
| 3965 | zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0))) | 6040 | |
| 3966 | zig_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)) | ||
| 6044 | zig_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)) | ||
| 6049 | zig_float_negate_builtin(128, UINT64_C(1) << 63) | ||
| 3967 | 6050 | ||
| 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 | } |
| 3996 | 6079 | ||
| 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 | } |
| 4049 | zig_common_float_builtins(16) | ||
| 4050 | zig_common_float_builtins(32) | ||
| 4051 | zig_common_float_builtins(64) | ||
| 4052 | zig_common_float_builtins(80) | ||
| 4053 | zig_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, ) | ||
| 4062 | zig_float_builtins(16) | 6171 | zig_float_builtins(16) |
| 4063 | zig_float_builtins(80) | ||
| 4064 | zig_float_builtins(128) | ||
| 4065 | |||
| 4066 | #ifdef __ARM_EABI__ | ||
| 4067 | |||
| 4068 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_f2iz(zig_f32); | ||
| 4069 | static inline int32_t zig_fixsfsi(zig_f32 arg) { return __aeabi_f2iz(arg); } | ||
| 4070 | |||
| 4071 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_f2uiz(zig_f32); | ||
| 4072 | static inline uint32_t zig_fixunssfsi(zig_f32 arg) { return __aeabi_f2uiz(arg); } | ||
| 4073 | |||
| 4074 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_f2ulz(zig_f32); | ||
| 4075 | static inline uint64_t zig_fixunssfdi(zig_f32 arg) { return __aeabi_f2ulz(arg); } | ||
| 4076 | |||
| 4077 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_i2f(int32_t); | ||
| 4078 | static inline zig_f32 zig_floatsisf(int32_t arg) { return __aeabi_i2f(arg); } | ||
| 4079 | |||
| 4080 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ui2f(uint32_t); | ||
| 4081 | static inline zig_f32 zig_floatunsisf(uint32_t arg) { return __aeabi_ui2f(arg); } | ||
| 4082 | |||
| 4083 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ul2f(uint64_t); | ||
| 4084 | static inline zig_f32 zig_floatundisf(uint64_t arg) { return __aeabi_ul2f(arg); } | ||
| 4085 | |||
| 4086 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_d2iz(zig_f64); | ||
| 4087 | static inline int32_t zig_fixdfsi(zig_f64 arg) { return __aeabi_d2iz(arg); } | ||
| 4088 | |||
| 4089 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_d2uiz(zig_f64); | ||
| 4090 | static inline uint32_t zig_fixunsdfsi(zig_f64 arg) { return __aeabi_d2uiz(arg); } | ||
| 4091 | |||
| 4092 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_d2ulz(zig_f64); | ||
| 4093 | static inline uint64_t zig_fixunsdfdi(zig_f64 arg) { return __aeabi_d2ulz(arg); } | ||
| 4094 | |||
| 4095 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_i2d(int32_t); | ||
| 4096 | static inline zig_f64 zig_floatsidf(int32_t arg) { return __aeabi_i2d(arg); } | ||
| 4097 | |||
| 4098 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ui2d(uint32_t); | ||
| 4099 | static inline zig_f64 zig_floatunsidf(uint32_t arg) { return __aeabi_ui2d(arg); } | ||
| 4100 | |||
| 4101 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ul2d(uint64_t); | ||
| 4102 | static inline zig_f64 zig_floatundidf(uint64_t arg) { return __aeabi_ul2d(arg); } | ||
| 4103 | |||
| 4104 | #else /* __ARM_EABI__ */ | ||
| 4105 | |||
| 4106 | zig_float_builtins(32) | 6172 | zig_float_builtins(32) |
| 4107 | zig_float_builtins(64) | 6173 | zig_float_builtins(64) |
| 4108 | 6174 | zig_float_builtins(80) | |
| 4109 | #endif /* __ARM_EABI__ */ | 6175 | #if defined(zig_x86_32) |
| 6176 | zig_common_float_builtins(128) | ||
| 6177 | static 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 | } | ||
| 6181 | static 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) | ||
| 6186 | zig_common_float_builtins(128) | ||
| 6187 | static inline zig_f128 zig_floattitf(zig_i128 arg) { | ||
| 6188 | extern zig_f128 __floattitf(zig_i128 arg); | ||
| 6189 | return __floattitf(arg); | ||
| 6190 | } | ||
| 6191 | static 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 | ||
| 6196 | zig_float_builtins(128) | ||
| 6197 | #endif | ||
| 4110 | 6198 | ||
| 4111 | /* ============================ Atomics Support ============================= */ | 6199 | /* ============================ Atomics Support ============================= */ |
| 4112 | 6200 | ||
| ... | @@ -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 | } |
| 4427 | 6515 | ||
| 4428 | zig_msvc_atomics( u8, uint8_t, char, 8, 8) | 6516 | zig_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 | } |
| 4478 | 6566 | ||
| ... | @@ -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 | } |
| 4503 | 6591 | ||
| 4504 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) { | 6592 | static 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 | } |
| 4509 | 6597 | ||
| 4510 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) { | 6598 | static 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 | } |
| 4533 | 6621 | ||
| 4534 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) { | 6622 | static 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 | } |
| 4539 | 6627 | ||
| 4540 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) { | 6628 | static 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; // TODO | 144 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 145 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 145 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 146 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 146 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 147 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 148 | 147 | ||
| 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 { |
| 256 | 255 | ||
| 257 | test "@abs int vectors" { | 256 | test "@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; // TODO | 258 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 261 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 259 | 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, |
| 136 | 135 | ||
| ... | @@ -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 | }, |
| 145 | 144 | .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, |
| 161 | 186 | ||
| 162 | .b_align = 16, | 187 | .b_align = 8, |
| 163 | .b_size = 32, | 188 | .b_size = 24, |
| 164 | 189 | ||
| 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" { |
| 200 | 223 | ||
| 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); |
| 207 | 229 | ||
| 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); |
| 210 | 232 | ||
| 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 | } |
| 548 | 570 | ||
| 549 | test "alignment of zero-bit types is respected" { | 571 | test "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; // TODO | 573 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 554 | 574 | ||
| ... | @@ -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; | ||
| 586 | 605 | ||
| 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; // TODO | 800 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 801 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 801 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 802 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 802 | 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; // TODO | 803 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO |
| 805 | 804 | ||
| 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; // TODO | 1397 | 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 | ||
| 1402 | 1400 | ||
| 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" { |
| 147 | 147 | ||
| 148 | test "Saturating Shift Left" { | 148 | test "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 |
| 210 | 210 | ||
| 211 | test "@bitCast packed struct of floats" { | 211 | test "@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; // TODO | 214 | 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" { |
| 247 | 246 | ||
| 248 | test "comptime @bitCast packed struct to int and back" { | 247 | test "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; // TODO | 250 | 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" { |
| 283 | test "bitcast vector to integer and back" { | 281 | test "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; // TODO | 283 | 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; |
| 289 | 286 | ||
| ... | @@ -329,10 +326,10 @@ fn bitCastWrapper128(x: f128) u128 { | ... | @@ -329,10 +326,10 @@ fn bitCastWrapper128(x: f128) u128 { |
| 329 | } | 326 | } |
| 330 | test "bitcast nan float does not modify signaling bit" { | 327 | test "bitcast nan float does not modify signaling bit" { |
| 331 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 328 | 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; | ||
| 336 | 333 | ||
| 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" { |
| 383 | test "@bitCast of packed struct of bools all true" { | 380 | test "@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; // TODO | 382 | 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; // TODO | 383 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO |
| 388 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 384 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 389 | 385 | ||
| ... | @@ -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" { |
| 404 | test "@bitCast of packed struct of bools all false" { | 400 | test "@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; // TODO | 402 | 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; // TODO | 403 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO |
| 409 | 404 | ||
| 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; | ||
| 138 | 137 | ||
| 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; | ||
| 164 | 162 | ||
| 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; // TODO | 180 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 183 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 181 | 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; | ||
| 187 | 185 | ||
| 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 symbols | 208 | 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" { |
| 281 | test "@intFromFloat" { | 279 | test "@intFromFloat" { |
| 282 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 280 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 283 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 281 | 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 { |
| 1473 | test "cast function with an opaque parameter" { | 1472 | test "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; |
| 1475 | 1474 | ||
| 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; // TODO | 1718 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1725 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1719 | 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; | ||
| 1730 | 1722 | ||
| 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" { |
| 1831 | 1823 | ||
| 1832 | test "coerce between pointers of compatible differently-named floats" { | 1824 | test "coerce between pointers of compatible differently-named floats" { |
| 1833 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1825 | 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; // TODO | 1826 | 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; |
| 1838 | 1829 | ||
| 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" { |
| 168 | 168 | ||
| 169 | test "@intCast > 128 bits" { | 169 | test "@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; |
| 173 | 172 | ||
| 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; // TODO | 513 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 514 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 514 | 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; |
| 518 | 517 | ||
| 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"); |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | test "anyopaque extern symbol" { | 5 | test "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; |
| 9 | 8 |
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 | } |
| 587 | 587 | ||
| 588 | test "@fieldParentPtr unaligned packed struct" { | 588 | test "@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 | } |
| 726 | 725 | ||
| 727 | test "@fieldParentPtr aligned packed struct" { | 726 | test "@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 | } |
| 1898 | 1896 | ||
| 1899 | test "@fieldParentPtr tagged union all zero-bit fields" { | 1897 | test "@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; |
| 1903 | 1900 |
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 { |
| 118 | test "cmp f16" { | 118 | test "cmp f16" { |
| 119 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 119 | 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 | ||
| 122 | 121 | ||
| 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" { |
| 127 | test "cmp f32" { | 126 | test "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; // TODO | 128 | 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 | ||
| 131 | 129 | ||
| 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" { |
| 142 | 140 | ||
| 143 | test "cmp f128" { | 141 | test "cmp f128" { |
| 144 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 142 | 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; |
| 148 | 145 | ||
| ... | @@ -152,7 +149,6 @@ test "cmp f128" { | ... | @@ -152,7 +149,6 @@ test "cmp f128" { |
| 152 | 149 | ||
| 153 | test "cmp f80/c_longdouble" { | 150 | test "cmp f80/c_longdouble" { |
| 154 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 151 | 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; |
| 158 | 154 | ||
| ... | @@ -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; // TODO | 217 | 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; |
| 225 | 220 | ||
| 226 | try testCmpVector(f16); | 221 | try testCmpVector(f16); |
| ... | @@ -253,7 +248,6 @@ test "vector cmp f64" { | ... | @@ -253,7 +248,6 @@ test "vector cmp f64" { |
| 253 | test "vector cmp f128" { | 248 | test "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; // TODO | 250 | 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; // TODO | 375 | 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; |
| 384 | 378 | 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 | } | ||
| 389 | 379 | ||
| 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 and | 937 | builtin.cpu.arch == .aarch64 and |
| 948 | builtin.os.tag == .windows) return error.SkipZigTest; | 938 | builtin.os.tag == .windows) return error.SkipZigTest; |
| 949 | 939 | ||
| 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/35518 | 941 | // 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" { |
| 1054 | 1044 | ||
| 1055 | test "@abs f80/f128/c_longdouble" { | 1045 | test "@abs f80/f128/c_longdouble" { |
| 1056 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1046 | 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; // TODO | 1047 | 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" { |
| 1172 | 1161 | ||
| 1173 | test "@floor f80/f128/c_longdouble" { | 1162 | test "@floor f80/f128/c_longdouble" { |
| 1174 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1163 | 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; // TODO | 1164 | 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; |
| 1179 | 1167 | ||
| 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" { |
| 1261 | 1244 | ||
| 1262 | test "@ceil f80/f128/c_longdouble" { | 1245 | test "@ceil f80/f128/c_longdouble" { |
| 1263 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1246 | 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; // TODO | 1247 | 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; |
| 1268 | 1250 | ||
| 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" { |
| 1281 | 1258 | ||
| 1282 | test "@ceil f80 maxInt(u64)" { | 1259 | test "@ceil f80 maxInt(u64)" { |
| 1283 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1260 | 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; // TODO | 1261 | 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; |
| 1288 | 1264 | ||
| 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" { |
| 1368 | 1339 | ||
| 1369 | test "@trunc f80/f128/c_longdouble" { | 1340 | test "@trunc f80/f128/c_longdouble" { |
| 1370 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1341 | 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; // TODO | 1342 | 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; |
| 1375 | 1345 | ||
| 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; // TODO | 1405 | 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; |
| 1442 | 1407 | ||
| 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 { |
| 1501 | 1461 | ||
| 1502 | // subnormals | 1462 | // 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 { |
| 147 | 147 | ||
| 148 | test "extern struct with stdcallcc fn pointer" { | 148 | test "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; |
| 152 | 151 | ||
| 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" { |
| 873 | test "128-bit multiplication" { | 873 | test "128-bit multiplication" { |
| 874 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 874 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 875 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 875 | 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; |
| 878 | 877 | ||
| 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; // TODO | 967 | 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; // TODO | 969 | 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; | ||
| 972 | 970 | ||
| 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" { |
| 1136 | 1134 | ||
| 1137 | test "@mulWithOverflow bitsize 128 bits" { | 1135 | test "@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; // TODO | 1138 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1142 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1139 | 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" { |
| 1163 | 1160 | ||
| 1164 | test "@mulWithOverflow > 128 bits" { | 1161 | test "@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; |
| 1168 | 1164 | ||
| 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" { |
| 1193 | 1189 | ||
| 1194 | test "@mulWithOverflow bitsize 256 bits" { | 1190 | test "@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; |
| 1199 | 1194 | ||
| ... | @@ -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; // TODO | 1293 | 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; // TODO | 1295 | 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; | ||
| 1302 | 1296 | ||
| 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" { |
| 1389 | 1383 | ||
| 1390 | test "@shlWithOverflow > 128 bits" { | 1384 | test "@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; |
| 1394 | 1387 | ||
| 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 { |
| 1419 | 1412 | ||
| 1420 | test "and > 128 bits" { | 1413 | test "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; | ||
| 1423 | 1415 | ||
| 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 { |
| 1448 | 1440 | ||
| 1449 | test "or > 128 bits" { | 1441 | test "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; | ||
| 1452 | 1443 | ||
| 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 { |
| 1477 | 1468 | ||
| 1478 | test "xor > 128 bits" { | 1469 | test "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; | ||
| 1481 | 1471 | ||
| 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 { |
| 1506 | 1496 | ||
| 1507 | test "not > 128 bits" { | 1497 | test "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; | ||
| 1510 | 1499 | ||
| 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 { |
| 1535 | 1524 | ||
| 1536 | test "shl > 128 bits" { | 1525 | test "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; | ||
| 1539 | 1527 | ||
| 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 { |
| 1564 | 1552 | ||
| 1565 | test "shr > 128 bits" { | 1553 | test "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; | ||
| 1568 | 1555 | ||
| 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 { |
| 1593 | 1580 | ||
| 1594 | test "@clz > 128 bits" { | 1581 | test "@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; |
| 1598 | 1584 | ||
| 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 { |
| 1623 | 1609 | ||
| 1624 | test "@ctz > 128 bits" { | 1610 | test "@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; |
| 1628 | 1613 | ||
| 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 { |
| 1653 | 1638 | ||
| 1654 | test "@popCount > 128 bits" { | 1639 | test "@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; |
| 1658 | 1642 | ||
| 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 { |
| 1683 | 1667 | ||
| 1684 | test "@bitReverse > 128 bits" { | 1668 | test "@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; |
| 1688 | 1671 | ||
| 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 { |
| 1713 | 1696 | ||
| 1714 | test "@byteSwap > 128 bits" { | 1697 | test "@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; |
| 1718 | 1700 | ||
| 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 { |
| 1743 | 1725 | ||
| 1744 | test "@max > 128 bits" { | 1726 | test "@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; |
| 1748 | 1729 | ||
| 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 { |
| 1773 | 1754 | ||
| 1774 | test "@min > 128 bits" { | 1755 | test "@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; |
| 1778 | 1758 | ||
| 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 { |
| 1803 | 1783 | ||
| 1804 | test "@abs > 128 bits" { | 1784 | test "@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; | ||
| 1807 | 1786 | ||
| 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 { |
| 1827 | 1806 | ||
| 1828 | test "@rem > 128 bits" { | 1807 | test "@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; |
| 1832 | 1810 | ||
| 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 { |
| 1855 | 1833 | ||
| 1856 | test "@mod > 128 bits" { | 1834 | test "@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; |
| 1860 | 1837 | ||
| 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 |
| 1883 | 1860 | ||
| 1884 | test "@divFloor > 128 bits" { | 1861 | test "@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; |
| 1888 | 1864 | ||
| 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 |
| 1912 | 1888 | ||
| 1913 | test "@divCeil > 128 bits" { | 1889 | test "@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; |
| 1917 | 1892 | ||
| 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 |
| 1941 | 1916 | ||
| 1942 | test "@divTrunc > 128 bits" { | 1917 | test "@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; |
| 1946 | 1920 | ||
| 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; // TODO | 2140 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2167 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2141 | 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; |
| 2171 | 2144 | ||
| 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; |
| 2178 | 2146 | ||
| 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; // TODO | 2283 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2316 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2284 | 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; |
| 2320 | 2287 | ||
| 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; // TODO | 2293 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2327 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2294 | 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; |
| 2331 | 2297 | ||
| 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; // TODO | 2332 | 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 | ||
| 2370 | 2335 | ||
| 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; // TODO | 115 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 116 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 116 | 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; |
| 120 | 119 | ||
| 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; // TODO | 49 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 50 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 50 | 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; |
| 54 | 53 | ||
| 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; // TODO | 67 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 69 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 68 | 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; |
| 73 | 71 | ||
| 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; // TODO | 167 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 170 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 168 | 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; |
| 174 | 171 | ||
| 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; // TODO | 191 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 195 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 192 | 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; |
| 199 | 195 | ||
| 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; // TODO | 405 | 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; // TODO | 407 | 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 | } |
| 580 | 579 | ||
| 581 | test "nested packed struct field access test" { | 580 | test "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; // TODO | 581 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 584 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 582 | 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; // TODO | 732 | 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; |
| 738 | 735 | ||
| 739 | const S = struct { | 736 | const S = struct { |
| ... | @@ -1171,7 +1168,6 @@ test "packed struct equality" { | ... | @@ -1171,7 +1168,6 @@ test "packed struct equality" { |
| 1171 | 1168 | ||
| 1172 | test "packed struct equality ignores padding bits" { | 1169 | test "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; |
| 1176 | 1172 | ||
| 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 | } |
| 276 | 276 | ||
| 277 | test "allowzero pointer and slice" { | 277 | test "allowzero pointer and slice" { |
| 278 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 278 | 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; // TODO | 280 | 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; // TODO | 144 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 145 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 145 | 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; |
| 149 | 148 | ||
| 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; // TODO | 237 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 239 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 238 | 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; |
| 243 | 241 | ||
| 244 | const S = struct { | 242 | const S = struct { |
| ... | @@ -313,7 +311,6 @@ test "saturating shift-left" { | ... | @@ -313,7 +311,6 @@ test "saturating shift-left" { |
| 313 | 311 | ||
| 314 | test "saturating shift-left large rhs" { | 312 | test "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" { |
| 361 | 358 | ||
| 362 | test "sat add > 128 bits" { | 359 | test "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; |
| 366 | 362 | ||
| 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" { |
| 377 | 373 | ||
| 378 | test "sat sub > 128 bits" { | 374 | test "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; |
| 382 | 377 | ||
| 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" { |
| 393 | 388 | ||
| 394 | test "sat mul > 128 bits" { | 389 | test "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; |
| 398 | 392 | ||
| 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" { |
| 409 | 403 | ||
| 410 | test "sat shl > 128 bits" { | 404 | test "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; |
| 414 | 407 | ||
| 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" { |
| 535 | test "packed struct with non-ABI-aligned field" { | 535 | test "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; // TODO | 537 | 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; // TODO | 538 | 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; // TODO | 791 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 793 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 792 | 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; |
| 797 | 795 | ||
| 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 | } |
| 1540 | 1538 | ||
| 1541 | test "struct field pointer has correct alignment" { | 1539 | test "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; // TODO | 1540 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1544 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1541 | 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 | } |
| 1570 | 1567 | ||
| 1571 | test "extern struct field pointer has correct alignment" { | 1568 | test "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; // TODO | 1569 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1574 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1570 | 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 | } |
| 2008 | 2004 | ||
| 2009 | test "struct containing optional pointer to array of @This()" { | 2005 | test "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; |
| 2012 | 2007 | ||
| 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" { |
| 2266 | 2261 | ||
| 2267 | test "struct contains underaligned field with overaligned pointer to itself" { | 2262 | test "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; // TODO | 2264 | 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" { |
| 1267 | test "switch evaluation order" { | 1267 | test "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" { |
| 223 | 223 | ||
| 224 | test "switch loop on larger than pointer integer" { | 224 | test "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; |
| 228 | 227 | ||
| 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" { |
| 268 | 267 | ||
| 269 | test "switch loop with discarded tag capture" { | 268 | test "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; // TODO | 10 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 11 | 11 | ||
| 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 { |
| 49 | 49 | ||
| 50 | test "@truncate > 128 bits" { | 50 | test "@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; |
| 54 | 53 | ||
| 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 | } |
| 1438 | 1438 | ||
| 1439 | test "defined-layout union field pointer has correct alignment" { | 1439 | test "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; // TODO | 1440 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1442 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1441 | 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 | } |
| 1473 | 1472 | ||
| 1474 | test "undefined-layout union field pointer has correct alignment" { | 1473 | test "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; // TODO | 1474 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1477 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1475 | 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 | } |
| 1612 | 1610 | ||
| 1613 | test "reinterpret extern union" { | 1611 | test "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/19389 | 1617 | // 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 | }; |
| 1679 | 1681 | ||
| 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 | } |
| 1685 | 1685 | ||
| ... | @@ -1758,8 +1758,6 @@ test "reinterpret packed union" { | ... | @@ -1758,8 +1758,6 @@ test "reinterpret packed union" { |
| 1758 | }; | 1758 | }; |
| 1759 | 1759 | ||
| 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 | } |
| 1765 | 1763 | ||
| ... | @@ -1800,8 +1798,6 @@ test "reinterpret packed union inside packed struct" { | ... | @@ -1800,8 +1798,6 @@ test "reinterpret packed union inside packed struct" { |
| 1800 | }; | 1798 | }; |
| 1801 | 1799 | ||
| 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 | } |
| 1807 | 1803 |
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; // TODO | 128 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 129 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 129 | 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 | } | ||
| 138 | 131 | ||
| 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; // TODO | 273 | 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; | ||
| 284 | 276 | ||
| 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; // TODO | 728 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 737 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 729 | 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 | ||
| 742 | 732 | ||
| 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)); | ||
| 779 | 771 | ||
| 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)); | ||
| 797 | 791 | ||
| 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)); | ||
| 809 | 805 | ||
| 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)); | ||
| 821 | 819 | ||
| 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)); | ||
| 828 | 827 | ||
| 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); | ||
| 840 | 841 | ||
| 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); | ||
| 844 | 847 | ||
| 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)); | ||
| 848 | 853 | ||
| 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)); | ||
| 852 | 859 | ||
| 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 | }; |
| 858 | 867 | ||
| ... | @@ -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; |
| 1323 | 1332 | ||
| 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; // TODO | 1442 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1439 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1443 | 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; |
| 1442 | 1445 | ||
| 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; // TODO | 1472 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1470 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1473 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1471 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO | 1474 | 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; |
| 1474 | 1476 | ||
| 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; // TODO | 1613 | 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; | ||
| 1614 | 1615 | ||
| 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; // TODO | 41 | 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; | ||
| 45 | 44 | ||
| 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_COMPLEX | 77 | # define ZIG_NO_COMPLEX |
| 78 | #endif | 78 | #endif |
| 79 | 79 | ||
| 80 | #ifdef ZIG_PPC32 | 80 | #ifdef __powerpc__ |
| 81 | # define ZIG_NO_COMPLEX | 81 | # define ZIG_NO_COMPLEX |
| 82 | #endif | 82 | #endif |
| 83 | 83 | ||
| ... | @@ -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 | } |
| 410 | 410 | ||
| 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)) | ||
| 412 | 416 | ||
| 413 | typedef bool Vector_2_bool __attribute__((ext_vector_type(2))); | 417 | typedef bool Vector_2_bool __attribute__((ext_vector_type(2))); |
| 414 | 418 | ||
| ... | @@ -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 | } |
| 4659 | 4663 | ||
| 4664 | #endif | ||
| 4665 | #endif | ||
| 4666 | #endif | ||
| 4667 | #endif | ||
| 4660 | #endif | 4668 | #endif |
| 4661 | 4669 | ||
| 4662 | typedef uint8_t Vector_1_u8 __attribute__((vector_size(1 * sizeof(uint8_t)))); | 4670 | typedef 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 | } |
| 15188 | 15196 | ||
| 15197 | struct Struct_array_1_f32 { | ||
| 15198 | float a[1]; | ||
| 15199 | }; | ||
| 15200 | |||
| 15201 | struct Struct_array_1_f32 zig_ret_struct_array_1_f32(void); | ||
| 15202 | void zig_struct_array_1_f32(struct Struct_array_1_f32, size_t); | ||
| 15203 | |||
| 15204 | struct Struct_array_1_f32 c_ret_struct_array_1_f32(void) { | ||
| 15205 | return (struct Struct_array_1_f32){ .a = { 4 } }; | ||
| 15206 | } | ||
| 15207 | void 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 | } | ||
| 15211 | void 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 | |||
| 15217 | struct Struct_array_2_f32 { | ||
| 15218 | float a[2]; | ||
| 15219 | }; | ||
| 15220 | |||
| 15221 | struct Struct_array_2_f32 zig_ret_struct_array_2_f32(void); | ||
| 15222 | void zig_struct_array_2_f32(struct Struct_array_2_f32, size_t); | ||
| 15223 | |||
| 15224 | struct Struct_array_2_f32 c_ret_struct_array_2_f32(void) { | ||
| 15225 | return (struct Struct_array_2_f32){ .a = { 6, 7 } }; | ||
| 15226 | } | ||
| 15227 | void 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 | } | ||
| 15232 | void 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 | |||
| 15239 | struct Struct_array_3_f32 { | ||
| 15240 | float a[3]; | ||
| 15241 | }; | ||
| 15242 | |||
| 15243 | struct Struct_array_3_f32 zig_ret_struct_array_3_f32(void); | ||
| 15244 | void zig_struct_array_3_f32(struct Struct_array_3_f32, size_t); | ||
| 15245 | |||
| 15246 | struct Struct_array_3_f32 c_ret_struct_array_3_f32(void) { | ||
| 15247 | return (struct Struct_array_3_f32){ .a = { 8, 9, 10 } }; | ||
| 15248 | } | ||
| 15249 | void 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 | } | ||
| 15255 | void 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 | |||
| 15263 | struct Struct_array_4_f32 { | ||
| 15264 | float a[4]; | ||
| 15265 | }; | ||
| 15266 | |||
| 15267 | struct Struct_array_4_f32 zig_ret_struct_array_4_f32(void); | ||
| 15268 | void zig_struct_array_4_f32(struct Struct_array_4_f32, size_t); | ||
| 15269 | |||
| 15270 | struct Struct_array_4_f32 c_ret_struct_array_4_f32(void) { | ||
| 15271 | return (struct Struct_array_4_f32){ .a = { 10, 11, 12, 13 } }; | ||
| 15272 | } | ||
| 15273 | void 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 | } | ||
| 15280 | void 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 | |||
| 15289 | struct Struct_array_5_f32 { | ||
| 15290 | float a[5]; | ||
| 15291 | }; | ||
| 15292 | |||
| 15293 | struct Struct_array_5_f32 zig_ret_struct_array_5_f32(void); | ||
| 15294 | void zig_struct_array_5_f32(struct Struct_array_5_f32, size_t); | ||
| 15295 | |||
| 15296 | struct 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 | } | ||
| 15299 | void 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 | } | ||
| 15307 | void 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 | |||
| 15189 | struct Struct_f32a8 { | 15317 | struct 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 | } |
| 15403 | 15531 | ||
| 15532 | struct Struct_array_1_f64 { | ||
| 15533 | double a[1]; | ||
| 15534 | }; | ||
| 15535 | |||
| 15536 | struct Struct_array_1_f64 zig_ret_struct_array_1_f64(void); | ||
| 15537 | void zig_struct_array_1_f64(struct Struct_array_1_f64, size_t); | ||
| 15538 | |||
| 15539 | struct Struct_array_1_f64 c_ret_struct_array_1_f64(void) { | ||
| 15540 | return (struct Struct_array_1_f64){ .a = { 4 } }; | ||
| 15541 | } | ||
| 15542 | void 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 | } | ||
| 15546 | void 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 | |||
| 15552 | struct Struct_array_2_f64 { | ||
| 15553 | double a[2]; | ||
| 15554 | }; | ||
| 15555 | |||
| 15556 | struct Struct_array_2_f64 zig_ret_struct_array_2_f64(void); | ||
| 15557 | void zig_struct_array_2_f64(struct Struct_array_2_f64, size_t); | ||
| 15558 | |||
| 15559 | struct Struct_array_2_f64 c_ret_struct_array_2_f64(void) { | ||
| 15560 | return (struct Struct_array_2_f64){ .a = { 6, 7 } }; | ||
| 15561 | } | ||
| 15562 | void 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 | } | ||
| 15567 | void 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 | |||
| 15574 | struct Struct_array_3_f64 { | ||
| 15575 | double a[3]; | ||
| 15576 | }; | ||
| 15577 | |||
| 15578 | struct Struct_array_3_f64 zig_ret_struct_array_3_f64(void); | ||
| 15579 | void zig_struct_array_3_f64(struct Struct_array_3_f64, size_t); | ||
| 15580 | |||
| 15581 | struct Struct_array_3_f64 c_ret_struct_array_3_f64(void) { | ||
| 15582 | return (struct Struct_array_3_f64){ .a = { 8, 9, 10 } }; | ||
| 15583 | } | ||
| 15584 | void 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 | } | ||
| 15590 | void 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 | |||
| 15598 | struct Struct_array_4_f64 { | ||
| 15599 | double a[4]; | ||
| 15600 | }; | ||
| 15601 | |||
| 15602 | struct Struct_array_4_f64 zig_ret_struct_array_4_f64(void); | ||
| 15603 | void zig_struct_array_4_f64(struct Struct_array_4_f64, size_t); | ||
| 15604 | |||
| 15605 | struct Struct_array_4_f64 c_ret_struct_array_4_f64(void) { | ||
| 15606 | return (struct Struct_array_4_f64){ .a = { 10, 11, 12, 13 } }; | ||
| 15607 | } | ||
| 15608 | void 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 | } | ||
| 15615 | void 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 | |||
| 15624 | struct Struct_array_5_f64 { | ||
| 15625 | double a[5]; | ||
| 15626 | }; | ||
| 15627 | |||
| 15628 | struct Struct_array_5_f64 zig_ret_struct_array_5_f64(void); | ||
| 15629 | void zig_struct_array_5_f64(struct Struct_array_5_f64, size_t); | ||
| 15630 | |||
| 15631 | struct 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 | } | ||
| 15634 | void 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 | } | ||
| 15642 | void 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 | |||
| 15404 | struct Struct_u32_Union_u32_u32u32 { | 15652 | struct 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_MIPS64 | 15813 | #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 | #endif | 15820 | #endif |
| 15574 | #endif | 15821 | #endif |
| 15575 | #endif | 15822 | #endif |
| 15576 | #endif | ||
| 15577 | 15823 | ||
| 15578 | #ifndef __hexagon__ | 15824 | #ifndef __hexagon__ |
| 15579 | #ifndef __loongarch__ | 15825 | #ifndef __loongarch__ |
| 15580 | #ifndef ZIG_MIPS64 | 15826 | #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 | #endif | 15833 | #endif |
| 15589 | #endif | 15834 | #endif |
| 15590 | #endif | 15835 | #endif |
| 15591 | #endif | ||
| 15592 | 15836 | ||
| 15593 | #ifndef ZIG_NO_I128 | 15837 | #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_MIPS64 | 15858 | #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 | #endif | 15866 | #endif |
| 15624 | #endif | 15867 | #endif |
| 15625 | #endif | 15868 | #endif |
| 15626 | #endif | ||
| 15627 | 15869 | ||
| 15628 | #ifndef __hexagon__ | 15870 | #ifndef __hexagon__ |
| 15629 | #ifndef __loongarch__ | 15871 | #ifndef __loongarch__ |
| 15630 | #ifndef ZIG_MIPS64 | 15872 | #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 | #endif | 15879 | #endif |
| 15639 | #endif | 15880 | #endif |
| 15640 | #endif | 15881 | #endif |
| 15641 | #endif | ||
| 15642 | 15882 | ||
| 15643 | #ifndef __hexagon__ | 15883 | #ifndef __hexagon__ |
| 15644 | #ifndef __i386__ | 15884 | #ifndef __i386__ |
| 15645 | #ifndef __loongarch__ | 15885 | #ifndef __loongarch__ |
| 15646 | #ifndef ZIG_MIPS64 | 15886 | #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 | #endif | 15894 | #endif |
| 15656 | #endif | 15895 | #endif |
| 15657 | #endif | 15896 | #endif |
| 15658 | #endif | ||
| 15659 | 15897 | ||
| 15660 | #ifndef __hexagon__ | 15898 | #ifndef __hexagon__ |
| 15661 | #ifndef __loongarch__ | 15899 | #ifndef __loongarch__ |
| 15662 | #ifndef ZIG_MIPS64 | 15900 | #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 | #endif | 15911 | #endif |
| 15675 | #endif | 15912 | #endif |
| 15676 | #endif | 15913 | #endif |
| 15677 | #endif | ||
| 15678 | #endif | 15914 | #endif |
| 15679 | 15915 | ||
| 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; |
| 13 | const have_i128 = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isArm() and | 13 | const 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 and | 14 | !builtin.cpu.arch.isMIPS() and !builtin.cpu.arch.isPowerPC32() and builtin.cpu.arch != .riscv32 and |
| 15 | builtin.cpu.arch != .hexagon and | 15 | builtin.cpu.arch != .hexagon and |
| 16 | builtin.cpu.arch != .s390x; // https://github.com/llvm/llvm-project/issues/168460 | 16 | builtin.cpu.arch != .s390x; |
| 17 | 17 | ||
| 18 | const have_f128 = builtin.cpu.arch.isWasm() or (builtin.cpu.arch.isX86() and !builtin.os.tag.isDarwin() and builtin.abi != .msvc); | 18 | const have_f128 = builtin.cpu.arch.isWasm() or (builtin.cpu.arch.isX86() and !builtin.os.tag.isDarwin() and builtin.abi != .msvc); |
| 19 | const have_f80 = builtin.cpu.arch.isX86() and builtin.abi != .msvc; | 19 | const 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; |
| 161 | extern fn c_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble; | 161 | extern fn c_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble; |
| 162 | 162 | ||
| 163 | const complex_abi_compatible = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isMIPS() and | 163 | const 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() and | 164 | !builtin.cpu.arch.isArm() and !builtin.cpu.arch.isPowerPC() and !builtin.cpu.arch.isRISCV() and |
| 165 | builtin.cpu.arch != .hexagon and | 165 | builtin.cpu.arch != .hexagon and |
| 166 | builtin.cpu.arch != .s390x and | 166 | 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" { |
| 451 | 451 | ||
| 452 | comptime { | 452 | comptime { |
| 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; | ||
| 456 | 459 | ||
| 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; |
| 474 | extern fn c_test_vector_2_bool() void; | 477 | extern fn c_test_vector_2_bool() void; |
| 475 | 478 | ||
| 476 | test "@Vector(2, bool)" { | 479 | test "@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; | ||
| 478 | 487 | ||
| 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)" { |
| 488 | 497 | ||
| 489 | comptime { | 498 | comptime { |
| 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; | ||
| 493 | 505 | ||
| 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; |
| 515 | extern fn c_test_vector_4_bool() void; | 527 | extern fn c_test_vector_4_bool() void; |
| 516 | 528 | ||
| 517 | test "@Vector(4, bool)" { | 529 | test "@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; | ||
| 519 | 537 | ||
| 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)" { |
| 533 | 551 | ||
| 534 | comptime { | 552 | comptime { |
| 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; | ||
| 538 | 559 | ||
| 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; |
| 568 | extern fn c_test_vector_8_bool() void; | 589 | extern fn c_test_vector_8_bool() void; |
| 569 | 590 | ||
| 570 | test "@Vector(8, bool)" { | 591 | test "@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; | ||
| 572 | 599 | ||
| 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)" { |
| 594 | 621 | ||
| 595 | comptime { | 622 | comptime { |
| 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; | ||
| 599 | 629 | ||
| 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; |
| 645 | extern fn c_test_vector_16_bool() void; | 675 | extern fn c_test_vector_16_bool() void; |
| 646 | 676 | ||
| 647 | test "@Vector(16, bool)" { | 677 | test "@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; | ||
| 649 | 685 | ||
| 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)" { |
| 687 | 723 | ||
| 688 | comptime { | 724 | comptime { |
| 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; | ||
| 692 | 731 | ||
| 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; |
| 770 | extern fn c_test_vector_32_bool() void; | 809 | extern fn c_test_vector_32_bool() void; |
| 771 | 810 | ||
| 772 | test "@Vector(32, bool)" { | 811 | test "@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; | ||
| 774 | 819 | ||
| 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)" { |
| 844 | 889 | ||
| 845 | comptime { | 890 | comptime { |
| 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; | ||
| 849 | 897 | ||
| 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; |
| 991 | extern fn c_test_vector_64_bool() void; | 1039 | extern fn c_test_vector_64_bool() void; |
| 992 | 1040 | ||
| 993 | test "@Vector(64, bool)" { | 1041 | test "@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; | ||
| 995 | 1047 | ||
| 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)" { |
| 1129 | 1181 | ||
| 1130 | comptime { | 1182 | comptime { |
| 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; | ||
| 1134 | 1189 | ||
| 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; |
| 1404 | extern fn c_test_vector_128_bool() void; | 1459 | extern fn c_test_vector_128_bool() void; |
| 1405 | 1460 | ||
| 1406 | test "@Vector(128, bool)" { | 1461 | test "@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; | ||
| 1408 | 1467 | ||
| 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)" { |
| 1670 | 1729 | ||
| 1671 | comptime { | 1730 | comptime { |
| 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; | ||
| 1675 | 1737 | ||
| 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; |
| 2201 | extern fn c_test_vector_256_bool() void; | 2263 | extern fn c_test_vector_256_bool() void; |
| 2202 | 2264 | ||
| 2203 | test "@Vector(256, bool)" { | 2265 | test "@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; | ||
| 2205 | 2271 | ||
| 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)" { |
| 2723 | 2789 | ||
| 2724 | comptime { | 2790 | comptime { |
| 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; | ||
| 2728 | 2797 | ||
| 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; |
| 3766 | extern fn c_test_vector_512_bool() void; | 3835 | extern fn c_test_vector_512_bool() void; |
| 3767 | 3836 | ||
| 3768 | test "@Vector(512, bool)" { | 3837 | test "@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; | ||
| 3770 | 3843 | ||
| 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; |
| 4844 | 4917 | ||
| 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; | ||
| 4873 | 4945 | ||
| 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; |
| 4916 | 4988 | ||
| 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; | ||
| 4950 | 5021 | ||
| 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; | ||
| 5140 | 5210 | ||
| 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; | ||
| 5224 | 5293 | ||
| 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; | ||
| 5334 | 5402 | ||
| 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; | ||
| 5477 | 5544 | ||
| 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; | ||
| 5672 | 5738 | ||
| 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; | ||
| 5935 | 6000 | ||
| 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; | ||
| 6300 | 6364 | ||
| 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; | ||
| 6801 | 6864 | ||
| 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; | ||
| 7506 | 7568 | ||
| 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; | ||
| 8483 | 8544 | ||
| 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; |
| 9077 | 9138 | ||
| 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; | ||
| 9105 | 9165 | ||
| 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; | ||
| 9254 | 9313 | ||
| 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; | ||
| 9304 | 9362 | ||
| 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; | ||
| 9370 | 9427 | ||
| 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; | ||
| 9454 | 9510 | ||
| 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; | ||
| 9564 | 9619 | ||
| 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; | ||
| 9708 | 9762 | ||
| 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; | ||
| 9903 | 9956 | ||
| 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; | ||
| 10166 | 10218 | ||
| 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; | ||
| 10531 | 10582 | ||
| 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; | ||
| 11032 | 11082 | ||
| 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; | ||
| 11449 | 11498 | ||
| 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; | ||
| 11485 | 11533 | ||
| 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; | ||
| 11528 | 11575 | ||
| 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; | ||
| 11578 | 11624 | ||
| 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; | ||
| 11644 | 11689 | ||
| 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; | ||
| 11729 | 11773 | ||
| 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; | ||
| 11839 | 11882 | ||
| 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; | ||
| 11983 | 12025 | ||
| 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; | ||
| 12178 | 12219 | ||
| 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; | ||
| 12441 | 12481 | ||
| 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; |
| 12594 | extern fn c_test_vector_1_u64() void; | 12634 | extern fn c_test_vector_1_u64() void; |
| 12595 | 12635 | ||
| 12596 | test "@Vector(1, u64)" { | 12636 | test "@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; | ||
| 12648 | 12685 | ||
| 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; | ||
| 12677 | 12713 | ||
| 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; | ||
| 12744 | 12779 | ||
| 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; | ||
| 12836 | 12870 | ||
| 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; | ||
| 12985 | 13018 | ||
| 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; | ||
| 13237 | 13269 | ||
| 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; | ||
| 13331 | 13362 | ||
| 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; | ||
| 13453 | 13483 | ||
| 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; | ||
| 13490 | 13519 | ||
| 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; | ||
| 13533 | 13561 | ||
| 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; | ||
| 13584 | 13611 | ||
| 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; | ||
| 13650 | 13676 | ||
| 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; | ||
| 13735 | 13760 | ||
| 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; | ||
| 13845 | 13869 | ||
| 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; | ||
| 13989 | 14012 | ||
| 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; | ||
| 14184 | 14206 | ||
| 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; | ||
| 14447 | 14468 | ||
| 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; | ||
| 14655 | 14675 | ||
| 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 | ||
| 14685 | 14703 | ||
| 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; | ||
| 14718 | 14735 | ||
| 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 | ||
| 14755 | 14770 | ||
| 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; | ||
| 14798 | 14812 | ||
| 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; | ||
| 14849 | 14862 | ||
| 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; | ||
| 14915 | 14927 | ||
| 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; | ||
| 15000 | 15011 | ||
| 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; | ||
| 15110 | 15120 | ||
| 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; | ||
| 15254 | 15263 | ||
| 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; |
| 15345 | test "struct u8" { | 15354 | test "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; |
| 15350 | 15358 | ||
| 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; |
| 15382 | 15389 | ||
| 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; |
| 15417 | 15423 | ||
| 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; |
| 15455 | 15460 | ||
| 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; |
| 15481 | test "struct u16" { | 15486 | test "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; |
| 15486 | 15490 | ||
| 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; |
| 15518 | 15521 | ||
| 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; |
| 15554 | 15556 | ||
| 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; |
| 15593 | 15594 | ||
| 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; |
| 15619 | test "struct u32" { | 15620 | test "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; |
| 15624 | 15624 | ||
| 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; |
| 15649 | test "struct u32, u32" { | 15649 | test "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; |
| 15656 | 15655 | ||
| 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; | ||
| 15690 | 15688 | ||
| 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; | ||
| 15727 | 15724 | ||
| 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; |
| 15753 | test "struct u64" { | 15750 | test "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; |
| 15758 | 15754 | ||
| 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; |
| 15831 | test "struct u64, u64" { | 15827 | test "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; | ||
| 15835 | 15830 | ||
| 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; |
| 15871 | test "struct u64, u64, u64" { | 15866 | test "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; | ||
| 15876 | 15870 | ||
| 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; |
| 15907 | test "struct u64, u64, u64, u64" { | 15901 | test "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; | ||
| 15912 | 15905 | ||
| 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; |
| 15937 | 15930 | ||
| 15938 | test "struct f32" { | 15931 | test "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; |
| 15943 | 15935 | ||
| 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; |
| 15976 | 15967 | ||
| 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; | ||
| 16011 | 16001 | ||
| 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; | ||
| 16049 | 16038 | ||
| 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; | ||
| 16089 | 16077 | ||
| 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 | } |
| 16099 | 16087 | ||
| 16088 | const Struct_array_1_f32 = extern struct { | ||
| 16089 | a: [1]f32, | ||
| 16090 | }; | ||
| 16091 | |||
| 16092 | comptime { | ||
| 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 | |||
| 16108 | extern fn c_ret_struct_array_1_f32() Struct_array_1_f32; | ||
| 16109 | extern fn c_struct_array_1_f32(Struct_array_1_f32, usize) void; | ||
| 16110 | extern fn c_test_struct_array_1_f32() void; | ||
| 16111 | |||
| 16112 | test "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 | |||
| 16127 | const Struct_array_2_f32 = extern struct { | ||
| 16128 | a: [2]f32, | ||
| 16129 | }; | ||
| 16130 | |||
| 16131 | export fn zig_ret_struct_array_2_f32() Struct_array_2_f32 { | ||
| 16132 | return .{ .a = .{ 1, 2 } }; | ||
| 16133 | } | ||
| 16134 | export 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 | |||
| 16140 | extern fn c_ret_struct_array_2_f32() Struct_array_2_f32; | ||
| 16141 | extern fn c_struct_array_2_f32(Struct_array_2_f32, usize) void; | ||
| 16142 | extern fn c_test_struct_array_2_f32() void; | ||
| 16143 | |||
| 16144 | test "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 | |||
| 16159 | const Struct_array_3_f32 = extern struct { | ||
| 16160 | a: [3]f32, | ||
| 16161 | }; | ||
| 16162 | |||
| 16163 | export fn zig_ret_struct_array_3_f32() Struct_array_3_f32 { | ||
| 16164 | return .{ .a = .{ 1, 2, 3 } }; | ||
| 16165 | } | ||
| 16166 | export 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 | |||
| 16173 | extern fn c_ret_struct_array_3_f32() Struct_array_3_f32; | ||
| 16174 | extern fn c_struct_array_3_f32(Struct_array_3_f32, usize) void; | ||
| 16175 | extern fn c_test_struct_array_3_f32() void; | ||
| 16176 | |||
| 16177 | test "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 | |||
| 16192 | const Struct_array_4_f32 = extern struct { | ||
| 16193 | a: [4]f32, | ||
| 16194 | }; | ||
| 16195 | |||
| 16196 | export fn zig_ret_struct_array_4_f32() Struct_array_4_f32 { | ||
| 16197 | return .{ .a = .{ 1, 2, 3, 4 } }; | ||
| 16198 | } | ||
| 16199 | export 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 | |||
| 16207 | extern fn c_ret_struct_array_4_f32() Struct_array_4_f32; | ||
| 16208 | extern fn c_struct_array_4_f32(Struct_array_4_f32, usize) void; | ||
| 16209 | extern fn c_test_struct_array_4_f32() void; | ||
| 16210 | |||
| 16211 | test "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 | |||
| 16227 | const Struct_array_5_f32 = extern struct { | ||
| 16228 | a: [5]f32, | ||
| 16229 | }; | ||
| 16230 | |||
| 16231 | export fn zig_ret_struct_array_5_f32() Struct_array_5_f32 { | ||
| 16232 | return .{ .a = .{ 1, 2, 3, 4, 5 } }; | ||
| 16233 | } | ||
| 16234 | export 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 | |||
| 16243 | extern fn c_ret_struct_array_5_f32() Struct_array_5_f32; | ||
| 16244 | extern fn c_struct_array_5_f32(Struct_array_5_f32, usize) void; | ||
| 16245 | extern fn c_test_struct_array_5_f32() void; | ||
| 16246 | |||
| 16247 | test "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 | |||
| 16100 | const Struct_f32a8 = extern struct { | 16263 | const 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; |
| 16125 | 16287 | ||
| 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; |
| 16159 | 16320 | ||
| 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; | ||
| 16192 | 16352 | ||
| 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; | ||
| 16226 | 16385 | ||
| 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; |
| 16250 | 16409 | ||
| 16251 | test "struct f64" { | 16410 | test "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; |
| 16257 | 16415 | ||
| 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; |
| 16282 | test "struct f64, f64" { | 16440 | test "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; | ||
| 16287 | 16444 | ||
| 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; |
| 16315 | test "struct f64, f64, f64" { | 16472 | test "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; | ||
| 16320 | 16476 | ||
| 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; |
| 16351 | test "struct f64, f64, f64, f64" { | 16507 | test "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; | ||
| 16356 | 16511 | ||
| 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; |
| 16390 | test "struct f64, f64, f64, f64, f64" { | 16545 | test "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; | ||
| 16395 | 16549 | ||
| 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 | } |
| 16405 | 16559 | ||
| 16560 | const Struct_array_1_f64 = extern struct { | ||
| 16561 | a: [1]f64, | ||
| 16562 | }; | ||
| 16563 | |||
| 16564 | comptime { | ||
| 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 | |||
| 16580 | extern fn c_ret_struct_array_1_f64() Struct_array_1_f64; | ||
| 16581 | extern fn c_struct_array_1_f64(Struct_array_1_f64, usize) void; | ||
| 16582 | extern fn c_test_struct_array_1_f64() void; | ||
| 16583 | |||
| 16584 | test "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 | |||
| 16599 | const Struct_array_2_f64 = extern struct { | ||
| 16600 | a: [2]f64, | ||
| 16601 | }; | ||
| 16602 | |||
| 16603 | export fn zig_ret_struct_array_2_f64() Struct_array_2_f64 { | ||
| 16604 | return .{ .a = .{ 1, 2 } }; | ||
| 16605 | } | ||
| 16606 | export 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 | |||
| 16612 | extern fn c_ret_struct_array_2_f64() Struct_array_2_f64; | ||
| 16613 | extern fn c_struct_array_2_f64(Struct_array_2_f64, usize) void; | ||
| 16614 | extern fn c_test_struct_array_2_f64() void; | ||
| 16615 | |||
| 16616 | test "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 | |||
| 16632 | const Struct_array_3_f64 = extern struct { | ||
| 16633 | a: [3]f64, | ||
| 16634 | }; | ||
| 16635 | |||
| 16636 | export fn zig_ret_struct_array_3_f64() Struct_array_3_f64 { | ||
| 16637 | return .{ .a = .{ 1, 2, 3 } }; | ||
| 16638 | } | ||
| 16639 | export 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 | |||
| 16646 | extern fn c_ret_struct_array_3_f64() Struct_array_3_f64; | ||
| 16647 | extern fn c_struct_array_3_f64(Struct_array_3_f64, usize) void; | ||
| 16648 | extern fn c_test_struct_array_3_f64() void; | ||
| 16649 | |||
| 16650 | test "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 | |||
| 16665 | const Struct_array_4_f64 = extern struct { | ||
| 16666 | a: [4]f64, | ||
| 16667 | }; | ||
| 16668 | |||
| 16669 | export fn zig_ret_struct_array_4_f64() Struct_array_4_f64 { | ||
| 16670 | return .{ .a = .{ 1, 2, 3, 4 } }; | ||
| 16671 | } | ||
| 16672 | export 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 | |||
| 16680 | extern fn c_ret_struct_array_4_f64() Struct_array_4_f64; | ||
| 16681 | extern fn c_struct_array_4_f64(Struct_array_4_f64, usize) void; | ||
| 16682 | extern fn c_test_struct_array_4_f64() void; | ||
| 16683 | |||
| 16684 | test "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 | |||
| 16700 | const Struct_array_5_f64 = extern struct { | ||
| 16701 | a: [5]f64, | ||
| 16702 | }; | ||
| 16703 | |||
| 16704 | export fn zig_ret_struct_array_5_f64() Struct_array_5_f64 { | ||
| 16705 | return .{ .a = .{ 1, 2, 3, 4, 5 } }; | ||
| 16706 | } | ||
| 16707 | export 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 | |||
| 16716 | extern fn c_ret_struct_array_5_f64() Struct_array_5_f64; | ||
| 16717 | extern fn c_struct_array_5_f64(Struct_array_5_f64, usize) void; | ||
| 16718 | extern fn c_test_struct_array_5_f64() void; | ||
| 16719 | |||
| 16720 | test "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 | |||
| 16406 | const Struct_u32_Union_u32_u32u32 = extern struct { | 16735 | const 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; | ||
| 16435 | 16763 | ||
| 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; |
| 16449 | extern fn c_struct_i32_i32(Struct_i32_i32) void; | 16777 | extern fn c_struct_i32_i32(Struct_i32_i32) void; |
| 16450 | 16778 | ||
| 16451 | test "struct i32 i32" { | 16779 | test "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; |
| 16458 | 16785 | ||
| 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 { |
| 16483 | extern fn c_big_struct(BigStruct) void; | 16810 | extern fn c_big_struct(BigStruct) void; |
| 16484 | 16811 | ||
| 16485 | test "big struct" { | 16812 | test "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; | ||
| 16491 | 16817 | ||
| 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 { |
| 16513 | extern fn c_big_union(BigUnion) void; | 16839 | extern fn c_big_union(BigUnion) void; |
| 16514 | 16840 | ||
| 16515 | test "big union" { | 16841 | test "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; | ||
| 16520 | 16845 | ||
| 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; |
| 16548 | extern fn c_ret_med_struct_mixed() MedStructMixed; | 16873 | extern fn c_ret_med_struct_mixed() MedStructMixed; |
| 16549 | 16874 | ||
| 16550 | test "medium struct of ints and floats" { | 16875 | test "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; | ||
| 16556 | 16880 | ||
| 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 { |
| 16628 | extern fn c_split_struct_ints(SplitStructInt) void; | 16952 | extern fn c_split_struct_ints(SplitStructInt) void; |
| 16629 | 16953 | ||
| 16630 | test "split struct of ints" { | 16954 | test "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; | ||
| 16637 | 16960 | ||
| 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; |
| 16658 | extern fn c_ret_split_struct_mixed() SplitStructMixed; | 16981 | extern fn c_ret_split_struct_mixed() SplitStructMixed; |
| 16659 | 16982 | ||
| 16660 | test "split struct of ints and floats" { | 16983 | test "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; | ||
| 16667 | 16989 | ||
| 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 { |
| 16686 | extern fn c_big_struct_both(BigStruct) BigStruct; | 17008 | extern fn c_big_struct_both(BigStruct) BigStruct; |
| 16687 | 17009 | ||
| 16688 | test "sret and byval together" { | 17010 | test "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; | ||
| 16694 | 17015 | ||
| 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; |
| 16800 | extern fn c_ret_struct_with_array() StructWithArray; | 17121 | extern fn c_ret_struct_with_array() StructWithArray; |
| 16801 | 17122 | ||
| 16802 | test "Struct with array as padding." { | 17123 | test "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; | ||
| 16809 | 17129 | ||
| 16810 | c_struct_with_array(.{ .a = 1, .padding = undefined, .b = 2 }); | 17130 | c_struct_with_array(.{ .a = 1, .padding = undefined, .b = 2 }); |
| 16811 | 17131 | ||
| ... | @@ -16829,11 +17149,10 @@ extern fn c_float_array_struct(FloatArrayStruct) void; | ... | @@ -16829,11 +17149,10 @@ extern fn c_float_array_struct(FloatArrayStruct) void; |
| 16829 | extern fn c_ret_float_array_struct() FloatArrayStruct; | 17149 | extern fn c_ret_float_array_struct() FloatArrayStruct; |
| 16830 | 17150 | ||
| 16831 | test "Float array like struct" { | 17151 | test "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; | ||
| 16837 | 17156 | ||
| 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 struct | 17183 | /// Tests for Double + Char struct |
| 16865 | const DC = extern struct { v1: f64, v2: u8 }; | 17184 | const DC = extern struct { v1: f64, v2: u8 }; |
| 16866 | test "DC: Zig passes to C" { | 17185 | test "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 | } |
| 16875 | test "DC: Zig returns to C" { | 17194 | test "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 | } |
| 16883 | test "DC: C passes to Zig" { | 17202 | test "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 | } |
| 16892 | test "DC: C returns to Zig" { | 17211 | test "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 | } |
| 16900 | 17219 | ||
| ... | @@ -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 }; |
| 16919 | test "CFF: Zig passes to C" { | 17238 | test "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 | } |
| 16928 | test "CFF: Zig returns to C" { | 17247 | test "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 | } |
| 16935 | test "CFF: C passes to Zig" { | 17254 | test "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; | ||
| 16943 | 17261 | ||
| 16944 | try expectOk(c_send_CFF()); | 17262 | try expectOk(c_send_CFF()); |
| 16945 | } | 17263 | } |
| 16946 | test "CFF: C returns to Zig" { | 17264 | test "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 | } |
| 16954 | pub extern fn c_assert_CFF(lv: CFF) c_int; | 17272 | pub 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 { |
| 16971 | const PD = extern struct { v1: ?*anyopaque, v2: f64 }; | 17289 | const PD = extern struct { v1: ?*anyopaque, v2: f64 }; |
| 16972 | 17290 | ||
| 16973 | test "PD: Zig passes to C" { | 17291 | test "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 | } |
| 16982 | test "PD: Zig returns to C" { | 17300 | test "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 | } |
| 16989 | test "PD: C passes to Zig" { | 17307 | test "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 | } |
| 16998 | test "PD: C returns to Zig" { | 17316 | test "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 | } |
| 17005 | pub extern fn c_assert_PD(lv: PD) c_int; | 17323 | pub 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; |
| 17033 | test "C function modifies by ref param" { | 17351 | test "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; | ||
| 17037 | 17354 | ||
| 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 { |
| 17054 | 17371 | ||
| 17055 | extern fn c_func_ptr_byval(*anyopaque, *anyopaque, ByVal, c_ulong, *anyopaque, c_ulong) void; | 17372 | extern fn c_func_ptr_byval(*anyopaque, *anyopaque, ByVal, c_ulong, *anyopaque, c_ulong) void; |
| 17056 | test "C function that takes byval struct called via function pointer" { | 17373 | test "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; | ||
| 17062 | 17378 | ||
| 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" { |
| 17077 | 17393 | ||
| 17078 | extern fn c_f16(f16) f16; | 17394 | extern fn c_f16(f16) f16; |
| 17079 | test "f16 bare" { | 17395 | test "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; |
| 17089 | 17405 | if (builtin.cpu.arch == .x86_64) return error.SkipZigTest; | |
| 17090 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 17091 | 17406 | ||
| 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 | }; |
| 17099 | extern fn c_f16_struct(f16_struct) f16_struct; | 17414 | extern fn c_f16_struct(f16_struct) f16_struct; |
| 17100 | test "f16 struct" { | 17415 | test "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; |
| 17106 | 17421 | ||
| ... | @@ -17207,11 +17522,10 @@ const Coord2 = extern struct { | ... | @@ -17207,11 +17522,10 @@ const Coord2 = extern struct { |
| 17207 | 17522 | ||
| 17208 | extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2; | 17523 | extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2; |
| 17209 | test "Stdcall ABI structs" { | 17524 | test "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; |
| 17216 | 17530 | ||
| 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" { |
| 17225 | 17539 | ||
| 17226 | extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void; | 17540 | extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void; |
| 17227 | test "Stdcall ABI big union" { | 17541 | test "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; | ||
| 17232 | 17545 | ||
| 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 | }; |
| 17301 | 17614 | ||
| 17302 | test "byval tail callsite attribute" { | 17615 | test "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; | ||
| 17308 | 17620 | ||
| 17309 | // Originally reported at https://github.com/ziglang/zig/issues/16290 | 17621 | // Originally reported at https://github.com/ziglang/zig/issues/16290 |
| 17310 | // the bug was that the extern function had the byval attribute, but | 17622 | // 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 | }, | ||
| 1648 | 1702 | ||
| 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 { |
| 2782 | 2830 | ||
| 2783 | const target = &resolved_target.result; | 2831 | const target = &resolved_target.result; |
| 2784 | 2832 | ||
| 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 test | 2834 | // The libc API tests obviously need to link libc. So for test |
| 2797 | // target entries where we wouldn't link libc by default, skip the | 2835 | // 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 | |||
| 9 | const std = @import("std"); | ||
| 10 | const Io = std.Io; | ||
| 11 | |||
| 12 | fn 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 | |||
| 29 | var general_purpose_allocator: std.heap.DebugAllocator(.{}) = .init; | ||
| 30 | |||
| 31 | pub 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 | } | ||