diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index a215764142..0a3413569a 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -530,13 +530,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { switch (air_tags[inst]) { // zig fmt: off .add, .ptr_add => try self.airBinOp(inst), - .addwrap => try self.airAddWrap(inst), + .addwrap => try self.airBinOp(inst), .add_sat => try self.airAddSat(inst), .sub, .ptr_sub => try self.airBinOp(inst), - .subwrap => try self.airSubWrap(inst), + .subwrap => try self.airBinOp(inst), .sub_sat => try self.airSubSat(inst), .mul => try self.airBinOp(inst), - .mulwrap => try self.airMulWrap(inst), + .mulwrap => try self.airBinOp(inst), .mul_sat => try self.airMulSat(inst), .rem => try self.airRem(inst), .mod => try self.airMod(inst), @@ -2237,6 +2237,39 @@ fn binOp( else => unreachable, } }, + .addwrap, + .subwrap, + .mulwrap, + => { + const base_tag: Air.Inst.Tag = switch (tag) { + .addwrap => .add, + .subwrap => .sub, + .mulwrap => .mul, + else => unreachable, + }; + + // Generate an add/sub/mul + const result = try self.binOp(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); + + // Truncate if necessary + switch (lhs_ty.zigTypeTag()) { + .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), + .Int => { + const int_info = lhs_ty.intInfo(self.target.*); + if (int_info.bits <= 32) { + const result_reg = result.register; + + if (int_info.bits < 32) { + try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits); + return result; + } else return result; + } else { + return self.fail("TODO ARM binary operations on integers > u32/i32", .{}); + } + }, + else => unreachable, + } + }, .bit_and, .bit_or, .xor, diff --git a/test/behavior/bugs/11181.zig b/test/behavior/bugs/11181.zig index f7baed5774..738bd4e3e7 100644 --- a/test/behavior/bugs/11181.zig +++ b/test/behavior/bugs/11181.zig @@ -2,7 +2,6 @@ const builtin = @import("builtin"); test "const inferred array of slices" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = struct { v: bool }; @@ -17,7 +16,6 @@ test "const inferred array of slices" { test "var inferred array of slices" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = struct { v: bool }; diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index be8859c0bc..9639f9eef8 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1080,7 +1080,6 @@ test "compile time int to ptr of function" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index c6b5a4efc9..ed71bf3d59 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -389,7 +389,6 @@ test "ability to give comptime types and non comptime types to same parameter" { test "function with inferred error set but returning no error" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn foo() !void {} diff --git a/test/behavior/math.zig b/test/behavior/math.zig index f6f342ec13..770100c69f 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -484,7 +484,6 @@ fn mod(comptime T: type, a: T, b: T) T { test "unsigned wrapping" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testUnsignedWrappingEval(maxInt(u32)); comptime try testUnsignedWrappingEval(maxInt(u32)); @@ -499,7 +498,6 @@ fn testUnsignedWrappingEval(x: u32) !void { test "signed wrapping" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testSignedWrappingEval(maxInt(i32)); comptime try testSignedWrappingEval(maxInt(i32)); @@ -514,7 +512,6 @@ fn testSignedWrappingEval(x: i32) !void { test "signed negation wrapping" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testSignedNegationWrappingEval(minInt(i16)); comptime try testSignedNegationWrappingEval(minInt(i16)); @@ -528,7 +525,6 @@ fn testSignedNegationWrappingEval(x: i16) !void { test "unsigned negation wrapping" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testUnsignedNegationWrappingEval(1); comptime try testUnsignedNegationWrappingEval(1); diff --git a/test/behavior/ptrcast.zig b/test/behavior/ptrcast.zig index 81bf479363..c1fc8ad2de 100644 --- a/test/behavior/ptrcast.zig +++ b/test/behavior/ptrcast.zig @@ -59,7 +59,6 @@ fn testReinterpretStructWrappedBytesAsInteger() !void { } test "reinterpret bytes of an array into an extern struct" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO diff --git a/test/behavior/type.zig b/test/behavior/type.zig index 9d236071f2..04409852c1 100644 --- a/test/behavior/type.zig +++ b/test/behavior/type.zig @@ -468,7 +468,6 @@ test "Type.Union from Type.Enum" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const Tag = @Type(.{ @@ -500,7 +499,6 @@ test "Type.Union from regular enum" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const E = enum { working_as_expected }; diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 1789bf13ca..6d52b4da42 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -385,7 +385,6 @@ extern fn foo(a: usize, b: bool, ...) callconv(.C) usize; extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize; test "type info: generic function types" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; diff --git a/test/behavior/void.zig b/test/behavior/void.zig index b1efda23e4..fc1972c506 100644 --- a/test/behavior/void.zig +++ b/test/behavior/void.zig @@ -19,7 +19,6 @@ test "compare void with void compile time known" { } test "iterate over a void slice" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var j: usize = 0;