| author | |
| committer | |
| log | 5e83441096ca77b379be55ad2c197f70ce374eac |
| tree | e7d6616bb07da1bf53af1bafe1d735433af198e1 |
| parent | da06269d706087207fc94c2039006f2f2d18aa2e |
8 files changed, 147 insertions(+), 87 deletions(-)
lib/std/fs.zig+1-3| ... | ... | @@ -3248,9 +3248,7 @@ test { |
| 3248 | 3248 | _ = &makeDirAbsolute; |
| 3249 | 3249 | _ = &makeDirAbsoluteZ; |
| 3250 | 3250 | _ = &copyFileAbsolute; |
| 3251 | if (builtin.zig_backend != .stage2_x86_64) { | |
| 3252 | _ = &updateFileAbsolute; | |
| 3253 | } | |
| 3251 | _ = &updateFileAbsolute; | |
| 3254 | 3252 | } |
| 3255 | 3253 | _ = &Dir.copyFile; |
| 3256 | 3254 | _ = @import("fs/test.zig"); |
lib/std/fs/test.zig-4| ... | ... | @@ -1460,8 +1460,6 @@ test "walker without fully iterating" { |
| 1460 | 1460 | test ". and .. in fs.Dir functions" { |
| 1461 | 1461 | if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest; |
| 1462 | 1462 | |
| 1463 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 1464 | ||
| 1465 | 1463 | if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64) { |
| 1466 | 1464 | // https://github.com/ziglang/zig/issues/17134 |
| 1467 | 1465 | return error.SkipZigTest; |
| ... | ... | @@ -1502,8 +1500,6 @@ test ". and .. in fs.Dir functions" { |
| 1502 | 1500 | test ". and .. in absolute functions" { |
| 1503 | 1501 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 1504 | 1502 | |
| 1505 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 1506 | ||
| 1507 | 1503 | var tmp = tmpDir(.{}); |
| 1508 | 1504 | defer tmp.cleanup(); |
| 1509 | 1505 |
lib/std/io/test.zig-2| ... | ... | @@ -161,8 +161,6 @@ test "setEndPos" { |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | test "updateTimes" { |
| 164 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 165 | ||
| 166 | 164 | var tmp = tmpDir(.{}); |
| 167 | 165 | defer tmp.cleanup(); |
| 168 | 166 |
lib/std/math/big/int_test.zig-20| ... | ... | @@ -1182,8 +1182,6 @@ test "big.int div single-single with rem" { |
| 1182 | 1182 | } |
| 1183 | 1183 | |
| 1184 | 1184 | test "big.int div multi-single no rem" { |
| 1185 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 1186 | ||
| 1187 | 1185 | var op1: u128 = 0xffffeeeeddddcccc; |
| 1188 | 1186 | var op2: u128 = 34; |
| 1189 | 1187 | |
| ... | ... | @@ -1203,8 +1201,6 @@ test "big.int div multi-single no rem" { |
| 1203 | 1201 | } |
| 1204 | 1202 | |
| 1205 | 1203 | test "big.int div multi-single with rem" { |
| 1206 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 1207 | ||
| 1208 | 1204 | var op1: u128 = 0xffffeeeeddddcccf; |
| 1209 | 1205 | var op2: u128 = 34; |
| 1210 | 1206 | |
| ... | ... | @@ -1224,8 +1220,6 @@ test "big.int div multi-single with rem" { |
| 1224 | 1220 | } |
| 1225 | 1221 | |
| 1226 | 1222 | test "big.int div multi>2-single" { |
| 1227 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 1228 | ||
| 1229 | 1223 | var op1: u128 = 0xfefefefefefefefefefefefefefefefe; |
| 1230 | 1224 | var op2: u128 = 0xefab8; |
| 1231 | 1225 | |
| ... | ... | @@ -1405,8 +1399,6 @@ test "big.int div trunc single-single -/-" { |
| 1405 | 1399 | } |
| 1406 | 1400 | |
| 1407 | 1401 | test "big.int divTrunc #15535" { |
| 1408 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 1409 | ||
| 1410 | 1402 | var one = try Managed.initSet(testing.allocator, 1); |
| 1411 | 1403 | defer one.deinit(); |
| 1412 | 1404 | var x = try Managed.initSet(testing.allocator, std.math.pow(u128, 2, 64)); |
| ... | ... | @@ -1949,8 +1941,6 @@ test "big.int truncate multi to multi signed" { |
| 1949 | 1941 | } |
| 1950 | 1942 | |
| 1951 | 1943 | test "big.int truncate negative multi to single" { |
| 1952 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 1953 | ||
| 1954 | 1944 | var a = try Managed.initSet(testing.allocator, -@as(SignedDoubleLimb, maxInt(Limb) + 1)); |
| 1955 | 1945 | defer a.deinit(); |
| 1956 | 1946 | |
| ... | ... | @@ -2362,8 +2352,6 @@ test "big.int bitwise xor simple" { |
| 2362 | 2352 | } |
| 2363 | 2353 | |
| 2364 | 2354 | test "big.int bitwise xor multi-limb" { |
| 2365 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 2366 | ||
| 2367 | 2355 | var x: DoubleLimb = maxInt(Limb) + 1; |
| 2368 | 2356 | var y: DoubleLimb = maxInt(Limb); |
| 2369 | 2357 | var a = try Managed.initSet(testing.allocator, x); |
| ... | ... | @@ -2538,8 +2526,6 @@ test "big.int var args" { |
| 2538 | 2526 | } |
| 2539 | 2527 | |
| 2540 | 2528 | test "big.int gcd non-one small" { |
| 2541 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 2542 | ||
| 2543 | 2529 | var a = try Managed.initSet(testing.allocator, 17); |
| 2544 | 2530 | defer a.deinit(); |
| 2545 | 2531 | var b = try Managed.initSet(testing.allocator, 97); |
| ... | ... | @@ -2553,8 +2539,6 @@ test "big.int gcd non-one small" { |
| 2553 | 2539 | } |
| 2554 | 2540 | |
| 2555 | 2541 | test "big.int gcd non-one medium" { |
| 2556 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 2557 | ||
| 2558 | 2542 | var a = try Managed.initSet(testing.allocator, 4864); |
| 2559 | 2543 | defer a.deinit(); |
| 2560 | 2544 | var b = try Managed.initSet(testing.allocator, 3458); |
| ... | ... | @@ -2568,8 +2552,6 @@ test "big.int gcd non-one medium" { |
| 2568 | 2552 | } |
| 2569 | 2553 | |
| 2570 | 2554 | test "big.int gcd non-one large" { |
| 2571 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 2572 | ||
| 2573 | 2555 | var a = try Managed.initSet(testing.allocator, 0xffffffffffffffff); |
| 2574 | 2556 | defer a.deinit(); |
| 2575 | 2557 | var b = try Managed.initSet(testing.allocator, 0xffffffffffffffff7777); |
| ... | ... | @@ -2602,8 +2584,6 @@ test "big.int gcd large multi-limb result" { |
| 2602 | 2584 | } |
| 2603 | 2585 | |
| 2604 | 2586 | test "big.int gcd one large" { |
| 2605 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 2606 | ||
| 2607 | 2587 | var a = try Managed.initSet(testing.allocator, 1897056385327307); |
| 2608 | 2588 | defer a.deinit(); |
| 2609 | 2589 | var b = try Managed.initSet(testing.allocator, 2251799813685248); |
lib/std/math/big/rational.zig-20| ... | ... | @@ -514,8 +514,6 @@ test "big.rational extractLowBits" { |
| 514 | 514 | } |
| 515 | 515 | |
| 516 | 516 | test "big.rational set" { |
| 517 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 518 | ||
| 519 | 517 | var a = try Rational.init(testing.allocator); |
| 520 | 518 | defer a.deinit(); |
| 521 | 519 | |
| ... | ... | @@ -615,8 +613,6 @@ test "big.rational set/to Float round-trip" { |
| 615 | 613 | } |
| 616 | 614 | |
| 617 | 615 | test "big.rational copy" { |
| 618 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 619 | ||
| 620 | 616 | var a = try Rational.init(testing.allocator); |
| 621 | 617 | defer a.deinit(); |
| 622 | 618 | |
| ... | ... | @@ -681,8 +677,6 @@ test "big.rational abs" { |
| 681 | 677 | } |
| 682 | 678 | |
| 683 | 679 | test "big.rational swap" { |
| 684 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 685 | ||
| 686 | 680 | var a = try Rational.init(testing.allocator); |
| 687 | 681 | defer a.deinit(); |
| 688 | 682 | var b = try Rational.init(testing.allocator); |
| ... | ... | @@ -707,8 +701,6 @@ test "big.rational swap" { |
| 707 | 701 | } |
| 708 | 702 | |
| 709 | 703 | test "big.rational order" { |
| 710 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 711 | ||
| 712 | 704 | var a = try Rational.init(testing.allocator); |
| 713 | 705 | defer a.deinit(); |
| 714 | 706 | var b = try Rational.init(testing.allocator); |
| ... | ... | @@ -724,8 +716,6 @@ test "big.rational order" { |
| 724 | 716 | } |
| 725 | 717 | |
| 726 | 718 | test "big.rational order/orderAbs with negative" { |
| 727 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 728 | ||
| 729 | 719 | var a = try Rational.init(testing.allocator); |
| 730 | 720 | defer a.deinit(); |
| 731 | 721 | var b = try Rational.init(testing.allocator); |
| ... | ... | @@ -738,8 +728,6 @@ test "big.rational order/orderAbs with negative" { |
| 738 | 728 | } |
| 739 | 729 | |
| 740 | 730 | test "big.rational add single-limb" { |
| 741 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 742 | ||
| 743 | 731 | var a = try Rational.init(testing.allocator); |
| 744 | 732 | defer a.deinit(); |
| 745 | 733 | var b = try Rational.init(testing.allocator); |
| ... | ... | @@ -755,8 +743,6 @@ test "big.rational add single-limb" { |
| 755 | 743 | } |
| 756 | 744 | |
| 757 | 745 | test "big.rational add" { |
| 758 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 759 | ||
| 760 | 746 | var a = try Rational.init(testing.allocator); |
| 761 | 747 | defer a.deinit(); |
| 762 | 748 | var b = try Rational.init(testing.allocator); |
| ... | ... | @@ -773,8 +759,6 @@ test "big.rational add" { |
| 773 | 759 | } |
| 774 | 760 | |
| 775 | 761 | test "big.rational sub" { |
| 776 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 777 | ||
| 778 | 762 | var a = try Rational.init(testing.allocator); |
| 779 | 763 | defer a.deinit(); |
| 780 | 764 | var b = try Rational.init(testing.allocator); |
| ... | ... | @@ -791,8 +775,6 @@ test "big.rational sub" { |
| 791 | 775 | } |
| 792 | 776 | |
| 793 | 777 | test "big.rational mul" { |
| 794 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 795 | ||
| 796 | 778 | var a = try Rational.init(testing.allocator); |
| 797 | 779 | defer a.deinit(); |
| 798 | 780 | var b = try Rational.init(testing.allocator); |
| ... | ... | @@ -809,8 +791,6 @@ test "big.rational mul" { |
| 809 | 791 | } |
| 810 | 792 | |
| 811 | 793 | test "big.rational div" { |
| 812 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 813 | ||
| 814 | 794 | { |
| 815 | 795 | var a = try Rational.init(testing.allocator); |
| 816 | 796 | defer a.deinit(); |
lib/std/os/linux/io_uring.zig-2| ... | ... | @@ -2204,8 +2204,6 @@ test "sendmsg/recvmsg" { |
| 2204 | 2204 | test "timeout (after a relative time)" { |
| 2205 | 2205 | if (builtin.os.tag != .linux) return error.SkipZigTest; |
| 2206 | 2206 | |
| 2207 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 2208 | ||
| 2209 | 2207 | var ring = IO_Uring.init(1, 0) catch |err| switch (err) { |
| 2210 | 2208 | error.SystemOutdated => return error.SkipZigTest, |
| 2211 | 2209 | error.PermissionDenied => return error.SkipZigTest, |
lib/std/time.zig-2| ... | ... | @@ -122,8 +122,6 @@ pub fn nanoTimestamp() i128 { |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | test "timestamp" { |
| 125 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 126 | ||
| 127 | 125 | const margin = ns_per_ms * 50; |
| 128 | 126 | |
| 129 | 127 | const time_0 = milliTimestamp(); |
src/arch/x86_64/CodeGen.zig+146-34| ... | ... | @@ -3221,6 +3221,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3221 | 3221 | .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs), |
| 3222 | 3222 | else => {}, |
| 3223 | 3223 | } |
| 3224 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | |
| 3224 | 3225 | |
| 3225 | 3226 | const dst_info = dst_ty.intInfo(mod); |
| 3226 | 3227 | const src_ty = try mod.intType(dst_info.signedness, switch (tag) { |
| ... | ... | @@ -3232,12 +3233,153 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3232 | 3233 | ), |
| 3233 | 3234 | .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits, |
| 3234 | 3235 | }); |
| 3236 | const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); | |
| 3237 | ||
| 3238 | if (dst_abi_size == 16 and src_abi_size == 16) switch (tag) { | |
| 3239 | else => unreachable, | |
| 3240 | .mul, .mul_wrap => {}, | |
| 3241 | .div_trunc, .div_floor, .div_exact, .rem, .mod => { | |
| 3242 | const signed = dst_ty.isSignedInt(mod); | |
| 3243 | var callee_buf: ["__udiv?i3".len]u8 = undefined; | |
| 3244 | const signed_div_floor_state: struct { | |
| 3245 | frame_index: FrameIndex, | |
| 3246 | reloc: Mir.Inst.Index, | |
| 3247 | } = if (signed and tag == .div_floor) state: { | |
| 3248 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, mod)); | |
| 3249 | try self.asmMemoryImmediate( | |
| 3250 | .{ ._, .mov }, | |
| 3251 | Memory.sib(.qword, .{ .base = .{ .frame = frame_index } }), | |
| 3252 | Immediate.u(0), | |
| 3253 | ); | |
| 3254 | ||
| 3255 | const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | |
| 3256 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | |
| 3257 | defer self.register_manager.unlockReg(tmp_lock); | |
| 3258 | ||
| 3259 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | |
| 3260 | if (lhs_mcv.isMemory()) try self.asmRegisterMemory( | |
| 3261 | .{ ._, .mov }, | |
| 3262 | tmp_reg, | |
| 3263 | lhs_mcv.address().offset(8).deref().mem(.qword), | |
| 3264 | ) else try self.asmRegisterRegister( | |
| 3265 | .{ ._, .mov }, | |
| 3266 | tmp_reg, | |
| 3267 | lhs_mcv.register_pair[1], | |
| 3268 | ); | |
| 3269 | ||
| 3270 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | |
| 3271 | if (rhs_mcv.isMemory()) try self.asmRegisterMemory( | |
| 3272 | .{ ._, .xor }, | |
| 3273 | tmp_reg, | |
| 3274 | rhs_mcv.address().offset(8).deref().mem(.qword), | |
| 3275 | ) else try self.asmRegisterRegister( | |
| 3276 | .{ ._, .xor }, | |
| 3277 | tmp_reg, | |
| 3278 | rhs_mcv.register_pair[1], | |
| 3279 | ); | |
| 3280 | const reloc = try self.asmJccReloc(.ns, undefined); | |
| 3281 | ||
| 3282 | break :state .{ .frame_index = frame_index, .reloc = reloc }; | |
| 3283 | } else undefined; | |
| 3284 | const call_mcv = try self.genCall( | |
| 3285 | .{ .lib = .{ | |
| 3286 | .return_type = dst_ty.toIntern(), | |
| 3287 | .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() }, | |
| 3288 | .callee = std.fmt.bufPrint(&callee_buf, "__{s}{s}{c}i3", .{ | |
| 3289 | if (signed) "" else "u", | |
| 3290 | switch (tag) { | |
| 3291 | .div_trunc, .div_exact => "div", | |
| 3292 | .div_floor => if (signed) "mod" else "div", | |
| 3293 | .rem, .mod => "mod", | |
| 3294 | else => unreachable, | |
| 3295 | }, | |
| 3296 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))), | |
| 3297 | }) catch unreachable, | |
| 3298 | } }, | |
| 3299 | &.{ src_ty, src_ty }, | |
| 3300 | &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } }, | |
| 3301 | ); | |
| 3302 | break :result if (signed) switch (tag) { | |
| 3303 | .div_floor => { | |
| 3304 | try self.asmRegisterRegister( | |
| 3305 | .{ ._, .@"or" }, | |
| 3306 | call_mcv.register_pair[0], | |
| 3307 | call_mcv.register_pair[1], | |
| 3308 | ); | |
| 3309 | try self.asmSetccMemory(.nz, Memory.sib(.byte, .{ | |
| 3310 | .base = .{ .frame = signed_div_floor_state.frame_index }, | |
| 3311 | })); | |
| 3312 | try self.performReloc(signed_div_floor_state.reloc); | |
| 3313 | const dst_mcv = try self.genCall( | |
| 3314 | .{ .lib = .{ | |
| 3315 | .return_type = dst_ty.toIntern(), | |
| 3316 | .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() }, | |
| 3317 | .callee = std.fmt.bufPrint(&callee_buf, "__div{c}i3", .{ | |
| 3318 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))), | |
| 3319 | }) catch unreachable, | |
| 3320 | } }, | |
| 3321 | &.{ src_ty, src_ty }, | |
| 3322 | &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } }, | |
| 3323 | ); | |
| 3324 | try self.asmRegisterMemory( | |
| 3325 | .{ ._, .sub }, | |
| 3326 | dst_mcv.register_pair[0], | |
| 3327 | Memory.sib(.qword, .{ | |
| 3328 | .base = .{ .frame = signed_div_floor_state.frame_index }, | |
| 3329 | }), | |
| 3330 | ); | |
| 3331 | try self.asmRegisterImmediate( | |
| 3332 | .{ ._, .sbb }, | |
| 3333 | dst_mcv.register_pair[1], | |
| 3334 | Immediate.u(0), | |
| 3335 | ); | |
| 3336 | try self.freeValue( | |
| 3337 | .{ .load_frame = .{ .index = signed_div_floor_state.frame_index } }, | |
| 3338 | ); | |
| 3339 | break :result dst_mcv; | |
| 3340 | }, | |
| 3341 | .mod => { | |
| 3342 | const dst_regs = call_mcv.register_pair; | |
| 3343 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); | |
| 3344 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); | |
| 3345 | ||
| 3346 | const tmp_regs = | |
| 3347 | try self.register_manager.allocRegs(2, .{null} ** 2, abi.RegisterClass.gp); | |
| 3348 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); | |
| 3349 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); | |
| 3350 | ||
| 3351 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | |
| 3352 | ||
| 3353 | for (tmp_regs, dst_regs) |tmp_reg, dst_reg| | |
| 3354 | try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, dst_reg); | |
| 3355 | if (rhs_mcv.isMemory()) { | |
| 3356 | try self.asmRegisterMemory(.{ ._, .add }, tmp_regs[0], rhs_mcv.mem(.qword)); | |
| 3357 | try self.asmRegisterMemory( | |
| 3358 | .{ ._, .adc }, | |
| 3359 | tmp_regs[1], | |
| 3360 | rhs_mcv.address().offset(8).deref().mem(.qword), | |
| 3361 | ); | |
| 3362 | } else for ( | |
| 3363 | [_]Mir.Inst.Tag{ .add, .adc }, | |
| 3364 | tmp_regs, | |
| 3365 | rhs_mcv.register_pair, | |
| 3366 | ) |op, tmp_reg, rhs_reg| | |
| 3367 | try self.asmRegisterRegister(.{ ._, op }, tmp_reg, rhs_reg); | |
| 3368 | try self.asmRegisterRegister(.{ ._, .@"test" }, dst_regs[1], dst_regs[1]); | |
| 3369 | for (dst_regs, tmp_regs) |dst_reg, tmp_reg| | |
| 3370 | try self.asmCmovccRegisterRegister(.s, dst_reg, tmp_reg); | |
| 3371 | break :result call_mcv; | |
| 3372 | }, | |
| 3373 | else => call_mcv, | |
| 3374 | } else call_mcv; | |
| 3375 | }, | |
| 3376 | }; | |
| 3235 | 3377 | |
| 3236 | 3378 | try self.spillEflagsIfOccupied(); |
| 3237 | 3379 | try self.spillRegisters(&.{ .rax, .rdx }); |
| 3238 | const lhs = try self.resolveInst(bin_op.lhs); | |
| 3239 | const rhs = try self.resolveInst(bin_op.rhs); | |
| 3240 | break :result try self.genMulDivBinOp(tag, inst, dst_ty, src_ty, lhs, rhs); | |
| 3380 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | |
| 3381 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | |
| 3382 | break :result try self.genMulDivBinOp(tag, inst, dst_ty, src_ty, lhs_mcv, rhs_mcv); | |
| 3241 | 3383 | }; |
| 3242 | 3384 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 3243 | 3385 | } |
| ... | ... | @@ -7201,37 +7343,7 @@ fn genMulDivBinOp( |
| 7201 | 7343 | assert(self.eflags_inst == null); |
| 7202 | 7344 | |
| 7203 | 7345 | if (dst_abi_size == 16 and src_abi_size == 16) { |
| 7204 | switch (tag) { | |
| 7205 | else => unreachable, | |
| 7206 | .mul, .mul_wrap => {}, | |
| 7207 | .div_trunc, .div_floor, .div_exact, .rem, .mod => { | |
| 7208 | const signed = dst_ty.isSignedInt(mod); | |
| 7209 | if (signed) switch (tag) { | |
| 7210 | .div_floor, .mod => return self.fail( | |
| 7211 | "TODO implement genMulDivBinOp for {s} from {} to {}", | |
| 7212 | .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) }, | |
| 7213 | ), | |
| 7214 | else => {}, | |
| 7215 | }; | |
| 7216 | var callee_buf: ["__udiv?i3".len]u8 = undefined; | |
| 7217 | return try self.genCall(.{ .lib = .{ | |
| 7218 | .return_type = dst_ty.toIntern(), | |
| 7219 | .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() }, | |
| 7220 | .callee = std.fmt.bufPrint(&callee_buf, "__{s}{s}{c}i3", .{ | |
| 7221 | if (signed) "" else "u", | |
| 7222 | switch (tag) { | |
| 7223 | .div_trunc, .div_exact => "div", | |
| 7224 | .div_floor => if (signed) unreachable else "div", | |
| 7225 | .rem => "mod", | |
| 7226 | .mod => if (signed) unreachable else "mod", | |
| 7227 | else => unreachable, | |
| 7228 | }, | |
| 7229 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))), | |
| 7230 | }) catch unreachable, | |
| 7231 | } }, &.{ src_ty, src_ty }, &.{ lhs_mcv, rhs_mcv }); | |
| 7232 | }, | |
| 7233 | } | |
| 7234 | ||
| 7346 | assert(tag == .mul or tag == .mul_wrap); | |
| 7235 | 7347 | const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }); |
| 7236 | 7348 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); |
| 7237 | 7349 |