authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-31 19:41:50+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-04-01 11:37:18+02:00
logfd29ddc06c914a994ecb41714a7c4470ceda5af3
tree0c9734419eeeaa987afca71152d15a5a15730d73
parent87179d91a76470eb5e09d4e070063a2021c7f176

x64: implement add/sub with wrapping and xor op


2 files changed, 5 insertions(+), 28 deletions(-)

src/arch/x86_64/CodeGen.zig+5-23
......@@ -645,13 +645,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
645645 switch (air_tags[inst]) {
646646 // zig fmt: off
647647 .add => try self.airAdd(inst),
648 .addwrap => try self.airAddWrap(inst),
648 .addwrap => try self.airAdd(inst),
649649 .add_sat => try self.airAddSat(inst),
650650 .sub => try self.airSub(inst),
651 .subwrap => try self.airSubWrap(inst),
651 .subwrap => try self.airSub(inst),
652652 .sub_sat => try self.airSubSat(inst),
653653 .mul => try self.airMul(inst),
654 .mulwrap => try self.airMulWrap(inst),
654 .mulwrap => try self.airMul(inst),
655655 .mul_sat => try self.airMulSat(inst),
656656 .rem => try self.airRem(inst),
657657 .mod => try self.airMod(inst),
......@@ -1318,7 +1318,7 @@ fn airAddWrap(self: *Self, inst: Air.Inst.Index) !void {
13181318 const result: MCValue = if (self.liveness.isUnused(inst))
13191319 .dead
13201320 else
1321 return self.fail("TODO implement addwrap for {}", .{self.target.cpu.arch});
1321 try self.genBinMathOp(inst, bin_op.lhs, bin_op.rhs);
13221322 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
13231323}
13241324
......@@ -1375,15 +1375,6 @@ fn airSub(self: *Self, inst: Air.Inst.Index) !void {
13751375 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
13761376}
13771377
1378fn airSubWrap(self: *Self, inst: Air.Inst.Index) !void {
1379 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1380 const result: MCValue = if (self.liveness.isUnused(inst))
1381 .dead
1382 else
1383 return self.fail("TODO implement subwrap for {}", .{self.target.cpu.arch});
1384 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1385}
1386
13871378fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
13881379 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
13891380 const result: MCValue = if (self.liveness.isUnused(inst))
......@@ -1421,15 +1412,6 @@ fn airMul(self: *Self, inst: Air.Inst.Index) !void {
14211412 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
14221413}
14231414
1424fn airMulWrap(self: *Self, inst: Air.Inst.Index) !void {
1425 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1426 const result: MCValue = if (self.liveness.isUnused(inst))
1427 .dead
1428 else
1429 return self.fail("TODO implement mulwrap for {}", .{self.target.cpu.arch});
1430 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1431}
1432
14331415fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
14341416 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
14351417 const result: MCValue = if (self.liveness.isUnused(inst))
......@@ -1826,7 +1808,7 @@ fn airXor(self: *Self, inst: Air.Inst.Index) !void {
18261808 const result: MCValue = if (self.liveness.isUnused(inst))
18271809 .dead
18281810 else
1829 return self.fail("TODO implement xor for {}", .{self.target.cpu.arch});
1811 try self.genBinMathOp(inst, bin_op.lhs, bin_op.rhs);
18301812 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
18311813}
18321814
test/behavior/math.zig-5
......@@ -320,7 +320,6 @@ test "comptime_int multi-limb partial shift right" {
320320
321321test "xor" {
322322 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
323 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
324323
325324 try test_xor();
326325 comptime try test_xor();
......@@ -502,7 +501,6 @@ fn mod(comptime T: type, a: T, b: T) T {
502501}
503502
504503test "unsigned wrapping" {
505 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
506504 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
507505
508506 try testUnsignedWrappingEval(maxInt(u32));
......@@ -516,7 +514,6 @@ fn testUnsignedWrappingEval(x: u32) !void {
516514}
517515
518516test "signed wrapping" {
519 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
520517 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
521518
522519 try testSignedWrappingEval(maxInt(i32));
......@@ -530,7 +527,6 @@ fn testSignedWrappingEval(x: i32) !void {
530527}
531528
532529test "signed negation wrapping" {
533 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
534530 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
535531
536532 try testSignedNegationWrappingEval(minInt(i16));
......@@ -543,7 +539,6 @@ fn testSignedNegationWrappingEval(x: i16) !void {
543539}
544540
545541test "unsigned negation wrapping" {
546 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
547542 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
548543
549544 try testUnsignedNegationWrappingEval(1);