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 {...@@ -645,13 +645,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
645 switch (air_tags[inst]) {645 switch (air_tags[inst]) {
646 // zig fmt: off646 // zig fmt: off
647 .add => try self.airAdd(inst),647 .add => try self.airAdd(inst),
648 .addwrap => try self.airAddWrap(inst),648 .addwrap => try self.airAdd(inst),
649 .add_sat => try self.airAddSat(inst),649 .add_sat => try self.airAddSat(inst),
650 .sub => try self.airSub(inst),650 .sub => try self.airSub(inst),
651 .subwrap => try self.airSubWrap(inst),651 .subwrap => try self.airSub(inst),
652 .sub_sat => try self.airSubSat(inst),652 .sub_sat => try self.airSubSat(inst),
653 .mul => try self.airMul(inst),653 .mul => try self.airMul(inst),
654 .mulwrap => try self.airMulWrap(inst),654 .mulwrap => try self.airMul(inst),
655 .mul_sat => try self.airMulSat(inst),655 .mul_sat => try self.airMulSat(inst),
656 .rem => try self.airRem(inst),656 .rem => try self.airRem(inst),
657 .mod => try self.airMod(inst),657 .mod => try self.airMod(inst),
...@@ -1318,7 +1318,7 @@ fn airAddWrap(self: *Self, inst: Air.Inst.Index) !void {...@@ -1318,7 +1318,7 @@ fn airAddWrap(self: *Self, inst: Air.Inst.Index) !void {
1318 const result: MCValue = if (self.liveness.isUnused(inst))1318 const result: MCValue = if (self.liveness.isUnused(inst))
1319 .dead1319 .dead
1320 else1320 else
1321 return self.fail("TODO implement addwrap for {}", .{self.target.cpu.arch});1321 try self.genBinMathOp(inst, bin_op.lhs, bin_op.rhs);
1322 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1322 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1323}1323}
13241324
...@@ -1375,15 +1375,6 @@ fn airSub(self: *Self, inst: Air.Inst.Index) !void {...@@ -1375,15 +1375,6 @@ fn airSub(self: *Self, inst: Air.Inst.Index) !void {
1375 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1375 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1376}1376}
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
1387fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {1378fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
1388 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1379 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1389 const result: MCValue = if (self.liveness.isUnused(inst))1380 const result: MCValue = if (self.liveness.isUnused(inst))
...@@ -1421,15 +1412,6 @@ fn airMul(self: *Self, inst: Air.Inst.Index) !void {...@@ -1421,15 +1412,6 @@ fn airMul(self: *Self, inst: Air.Inst.Index) !void {
1421 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1412 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1422}1413}
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
1433fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {1415fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
1434 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1416 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1435 const result: MCValue = if (self.liveness.isUnused(inst))1417 const result: MCValue = if (self.liveness.isUnused(inst))
...@@ -1826,7 +1808,7 @@ fn airXor(self: *Self, inst: Air.Inst.Index) !void {...@@ -1826,7 +1808,7 @@ fn airXor(self: *Self, inst: Air.Inst.Index) !void {
1826 const result: MCValue = if (self.liveness.isUnused(inst))1808 const result: MCValue = if (self.liveness.isUnused(inst))
1827 .dead1809 .dead
1828 else1810 else
1829 return self.fail("TODO implement xor for {}", .{self.target.cpu.arch});1811 try self.genBinMathOp(inst, bin_op.lhs, bin_op.rhs);
1830 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1812 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1831}1813}
18321814
test/behavior/math.zig-5
...@@ -320,7 +320,6 @@ test "comptime_int multi-limb partial shift right" {...@@ -320,7 +320,6 @@ test "comptime_int multi-limb partial shift right" {
320320
321test "xor" {321test "xor" {
322 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO322 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
323 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
324323
325 try test_xor();324 try test_xor();
326 comptime try test_xor();325 comptime try test_xor();
...@@ -502,7 +501,6 @@ fn mod(comptime T: type, a: T, b: T) T {...@@ -502,7 +501,6 @@ fn mod(comptime T: type, a: T, b: T) T {
502}501}
503502
504test "unsigned wrapping" {503test "unsigned wrapping" {
505 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
506 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO504 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
507505
508 try testUnsignedWrappingEval(maxInt(u32));506 try testUnsignedWrappingEval(maxInt(u32));
...@@ -516,7 +514,6 @@ fn testUnsignedWrappingEval(x: u32) !void {...@@ -516,7 +514,6 @@ fn testUnsignedWrappingEval(x: u32) !void {
516}514}
517515
518test "signed wrapping" {516test "signed wrapping" {
519 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
520 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO517 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
521518
522 try testSignedWrappingEval(maxInt(i32));519 try testSignedWrappingEval(maxInt(i32));
...@@ -530,7 +527,6 @@ fn testSignedWrappingEval(x: i32) !void {...@@ -530,7 +527,6 @@ fn testSignedWrappingEval(x: i32) !void {
530}527}
531528
532test "signed negation wrapping" {529test "signed negation wrapping" {
533 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
534 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO530 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
535531
536 try testSignedNegationWrappingEval(minInt(i16));532 try testSignedNegationWrappingEval(minInt(i16));
...@@ -543,7 +539,6 @@ fn testSignedNegationWrappingEval(x: i16) !void {...@@ -543,7 +539,6 @@ fn testSignedNegationWrappingEval(x: i16) !void {
543}539}
544540
545test "unsigned negation wrapping" {541test "unsigned negation wrapping" {
546 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
547 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO542 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
548543
549 try testUnsignedNegationWrappingEval(1);544 try testUnsignedNegationWrappingEval(1);