authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-10 20:28:55+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-10 21:03:37+01:00
logbf46aee878aa3ac6824047038ed887744da3e259
treec02f06b4462f84bfc318881ecb3caa7c3bf02a05
parent6a9ddf244a1a6641991ed45b7ff7cacf7c789bfb
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Basic 128bit integer support

This implements storing, loading and comparing 128bit integers. TODO: Make all >64 bit integers make a call to compiler-rt for binary operations.

2 files changed, 78 insertions(+), 31 deletions(-)

src/arch/wasm/CodeGen.zig+71-25
...@@ -690,7 +690,7 @@ fn typeToValtype(self: *Self, ty: Type) InnerError!wasm.Valtype {...@@ -690,7 +690,7 @@ fn typeToValtype(self: *Self, ty: Type) InnerError!wasm.Valtype {
690 const info = ty.intInfo(self.target);690 const info = ty.intInfo(self.target);
691 if (info.bits <= 32) break :blk wasm.Valtype.i32;691 if (info.bits <= 32) break :blk wasm.Valtype.i32;
692 if (info.bits > 32 and info.bits <= 64) break :blk wasm.Valtype.i64;692 if (info.bits > 32 and info.bits <= 64) break :blk wasm.Valtype.i64;
693 return self.fail("TODO: Support integer bitsize: '{d}'", .{info.bits});693 break :blk wasm.Valtype.i32; // represented as pointer to stack
694 },694 },
695 .Enum => switch (ty.tag()) {695 .Enum => switch (ty.tag()) {
696 .enum_simple => wasm.Valtype.i32,696 .enum_simple => wasm.Valtype.i32,
...@@ -753,7 +753,7 @@ fn genFunctype(self: *Self, fn_ty: Type) !wasm.Type {...@@ -753,7 +753,7 @@ fn genFunctype(self: *Self, fn_ty: Type) !wasm.Type {
753 defer returns.deinit();753 defer returns.deinit();
754 const return_type = fn_ty.fnReturnType();754 const return_type = fn_ty.fnReturnType();
755755
756 const want_sret = isByRef(return_type);756 const want_sret = self.isByRef(return_type);
757757
758 if (want_sret) {758 if (want_sret) {
759 try params.append(try self.typeToValtype(Type.usize));759 try params.append(try self.typeToValtype(Type.usize));
...@@ -1084,7 +1084,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu...@@ -1084,7 +1084,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu
1084 const ret_ty = fn_ty.fnReturnType();1084 const ret_ty = fn_ty.fnReturnType();
1085 // Check if we store the result as a pointer to the stack rather than1085 // Check if we store the result as a pointer to the stack rather than
1086 // by value1086 // by value
1087 if (isByRef(ret_ty)) {1087 if (self.isByRef(ret_ty)) {
1088 // the sret arg will be passed as first argument, therefore we1088 // the sret arg will be passed as first argument, therefore we
1089 // set the `return_value` before allocating locals for regular args.1089 // set the `return_value` before allocating locals for regular args.
1090 result.return_value = .{ .local = self.local_index };1090 result.return_value = .{ .local = self.local_index };
...@@ -1209,7 +1209,7 @@ fn ptrSize(self: *const Self) u16 {...@@ -1209,7 +1209,7 @@ fn ptrSize(self: *const Self) u16 {
12091209
1210/// For a given `Type`, will return true when the type will be passed1210/// For a given `Type`, will return true when the type will be passed
1211/// by reference, rather than by value.1211/// by reference, rather than by value.
1212fn isByRef(ty: Type) bool {1212fn isByRef(self: Self, ty: Type) bool {
1213 switch (ty.zigTypeTag()) {1213 switch (ty.zigTypeTag()) {
1214 .Type,1214 .Type,
1215 .ComptimeInt,1215 .ComptimeInt,
...@@ -1224,7 +1224,6 @@ fn isByRef(ty: Type) bool {...@@ -1224,7 +1224,6 @@ fn isByRef(ty: Type) bool {
1224 .NoReturn,1224 .NoReturn,
1225 .Void,1225 .Void,
1226 .Bool,1226 .Bool,
1227 .Int,
1228 .Float,1227 .Float,
1229 .ErrorSet,1228 .ErrorSet,
1230 .Fn,1229 .Fn,
...@@ -1238,6 +1237,7 @@ fn isByRef(ty: Type) bool {...@@ -1238,6 +1237,7 @@ fn isByRef(ty: Type) bool {
1238 .Frame,1237 .Frame,
1239 .Union,1238 .Union,
1240 => return ty.hasCodeGenBits(),1239 => return ty.hasCodeGenBits(),
1240 .Int => return if (ty.intInfo(self.target).bits > 64) true else false,
1241 .ErrorUnion => {1241 .ErrorUnion => {
1242 const has_tag = ty.errorUnionSet().hasCodeGenBits();1242 const has_tag = ty.errorUnionSet().hasCodeGenBits();
1243 const has_pl = ty.errorUnionPayload().hasCodeGenBits();1243 const has_pl = ty.errorUnionPayload().hasCodeGenBits();
...@@ -1412,7 +1412,7 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -1412,7 +1412,7 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
1412 const child_type = self.air.typeOfIndex(inst).childType();1412 const child_type = self.air.typeOfIndex(inst).childType();
1413 if (child_type.abiSize(self.target) == 0) return WValue{ .none = {} };1413 if (child_type.abiSize(self.target) == 0) return WValue{ .none = {} };
14141414
1415 if (isByRef(child_type)) {1415 if (self.isByRef(child_type)) {
1416 return self.return_value;1416 return self.return_value;
1417 }1417 }
14181418
...@@ -1429,7 +1429,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -1429,7 +1429,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
1429 const ret_ty = self.air.typeOf(un_op).childType();1429 const ret_ty = self.air.typeOf(un_op).childType();
1430 if (!ret_ty.hasCodeGenBits()) return WValue.none;1430 if (!ret_ty.hasCodeGenBits()) return WValue.none;
14311431
1432 if (!isByRef(ret_ty)) {1432 if (!self.isByRef(ret_ty)) {
1433 const result = try self.load(operand, ret_ty, 0);1433 const result = try self.load(operand, ret_ty, 0);
1434 try self.emitWValue(result);1434 try self.emitWValue(result);
1435 }1435 }
...@@ -1451,7 +1451,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -1451,7 +1451,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
1451 else => unreachable,1451 else => unreachable,
1452 };1452 };
1453 const ret_ty = fn_ty.fnReturnType();1453 const ret_ty = fn_ty.fnReturnType();
1454 const first_param_sret = isByRef(ret_ty);1454 const first_param_sret = self.isByRef(ret_ty);
14551455
1456 const target: ?*Decl = blk: {1456 const target: ?*Decl = blk: {
1457 const func_val = self.air.value(pl_op.operand) orelse break :blk null;1457 const func_val = self.air.value(pl_op.operand) orelse break :blk null;
...@@ -1479,7 +1479,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -1479,7 +1479,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
14791479
1480 // If we need to pass by reference, but the argument is a constant,1480 // If we need to pass by reference, but the argument is a constant,
1481 // we must first lower it before passing it.1481 // we must first lower it before passing it.
1482 if (isByRef(arg_ty) and arg_val == .constant) {1482 if (self.isByRef(arg_ty) and arg_val == .constant) {
1483 const arg_local = try self.allocStack(arg_ty);1483 const arg_local = try self.allocStack(arg_ty);
1484 try self.store(arg_local, arg_val, arg_ty, 0);1484 try self.store(arg_local, arg_val, arg_ty, 0);
1485 try self.emitWValue(arg_local);1485 try self.emitWValue(arg_local);
...@@ -1591,7 +1591,12 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro...@@ -1591,7 +1591,12 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro
1591 if (payload_ty.hasCodeGenBits()) {1591 if (payload_ty.hasCodeGenBits()) {
1592 const payload_local = try self.allocLocal(payload_ty);1592 const payload_local = try self.allocLocal(payload_ty);
1593 try self.addLabel(.local_set, payload_local.local);1593 try self.addLabel(.local_set, payload_local.local);
1594 try self.store(lhs, payload_local, payload_ty, payload_offset);1594 if (self.isByRef(payload_ty)) {
1595 const ptr = try self.buildPointerOffset(lhs, payload_offset, .new);
1596 try self.store(ptr, payload_local, payload_ty, 0);
1597 } else {
1598 try self.store(lhs, payload_local, payload_ty, payload_offset);
1599 }
1595 }1600 }
1596 try self.addLabel(.local_set, tag_local.local);1601 try self.addLabel(.local_set, tag_local.local);
15971602
...@@ -1608,7 +1613,7 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro...@@ -1608,7 +1613,7 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro
1608 // Load values from `rhs` stack position and store in `lhs` instead1613 // Load values from `rhs` stack position and store in `lhs` instead
1609 const tag_local = try self.load(rhs, tag_ty, 0);1614 const tag_local = try self.load(rhs, tag_ty, 0);
1610 if (payload_ty.hasCodeGenBits()) {1615 if (payload_ty.hasCodeGenBits()) {
1611 if (isByRef(payload_ty)) {1616 if (self.isByRef(payload_ty)) {
1612 const payload_ptr = try self.buildPointerOffset(rhs, payload_offset, .new);1617 const payload_ptr = try self.buildPointerOffset(rhs, payload_offset, .new);
1613 const lhs_payload_ptr = try self.buildPointerOffset(lhs, payload_offset, .new);1618 const lhs_payload_ptr = try self.buildPointerOffset(lhs, payload_offset, .new);
1614 try self.store(lhs_payload_ptr, payload_ptr, payload_ty, 0);1619 try self.store(lhs_payload_ptr, payload_ptr, payload_ty, 0);
...@@ -1734,7 +1739,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -1734,7 +1739,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
17341739
1735 if (!ty.hasCodeGenBits()) return WValue{ .none = {} };1740 if (!ty.hasCodeGenBits()) return WValue{ .none = {} };
17361741
1737 if (isByRef(ty)) {1742 if (self.isByRef(ty)) {
1738 const new_local = try self.allocStack(ty);1743 const new_local = try self.allocStack(ty);
1739 try self.store(new_local, operand, ty, 0);1744 try self.store(new_local, operand, ty, 0);
1740 return new_local;1745 return new_local;
...@@ -1803,6 +1808,11 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {...@@ -1803,6 +1808,11 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {
1803 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1808 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1804 const lhs = self.resolveInst(bin_op.lhs);1809 const lhs = self.resolveInst(bin_op.lhs);
1805 const rhs = self.resolveInst(bin_op.rhs);1810 const rhs = self.resolveInst(bin_op.rhs);
1811 const operand_ty = self.air.typeOfIndex(inst);
1812
1813 if (self.isByRef(operand_ty)) {
1814 return self.fail("TODO: Implement binary operation for type: {}", .{operand_ty});
1815 }
18061816
1807 try self.emitWValue(lhs);1817 try self.emitWValue(lhs);
1808 try self.emitWValue(rhs);1818 try self.emitWValue(rhs);
...@@ -1893,9 +1903,7 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {...@@ -1893,9 +1903,7 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {
1893 const result = try self.allocStack(ty);1903 const result = try self.allocStack(ty);
1894 var space: Value.BigIntSpace = undefined;1904 var space: Value.BigIntSpace = undefined;
1895 const bigint = val.toBigInt(&space);1905 const bigint = val.toBigInt(&space);
1896 if (bigint.limbs.len == 1) {1906 if (bigint.limbs.len == 1 and bigint.limbs[0] == 0) {
1897 // value is '0'. As wasm's values are zeroed by default,
1898 // just return and pop its stack pointer value.
1899 try self.addLabel(.local_get, result.local);1907 try self.addLabel(.local_get, result.local);
1900 return;1908 return;
1901 }1909 }
...@@ -2277,6 +2285,8 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) Inner...@@ -2277,6 +2285,8 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) Inner
2277 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs2285 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs
2278 return self.cmpOptionals(lhs, rhs, operand_ty, op);2286 return self.cmpOptionals(lhs, rhs, operand_ty, op);
2279 }2287 }
2288 } else if (self.isByRef(operand_ty)) {
2289 return self.cmpBigInt(lhs, rhs, operand_ty, op);
2280 }2290 }
22812291
2282 try self.emitWValue(lhs);2292 try self.emitWValue(lhs);
...@@ -2425,7 +2435,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2425,7 +2435,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2425 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty});2435 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty});
2426 };2436 };
24272437
2428 if (isByRef(field_ty)) {2438 if (self.isByRef(field_ty)) {
2429 return WValue{ .local_with_offset = .{ .local = operand.local, .offset = offset } };2439 return WValue{ .local_with_offset = .{ .local = operand.local, .offset = offset } };
2430 }2440 }
24312441
...@@ -2608,13 +2618,16 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W...@@ -2608,13 +2618,16 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W
2608}2618}
26092619
2610fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue {2620fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2611 if (self.liveness.isUnused(inst)) return WValue.none;2621 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
2612 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2622 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2613 const operand = self.resolveInst(ty_op.operand);2623 const operand = self.resolveInst(ty_op.operand);
2614 const err_ty = self.air.typeOf(ty_op.operand);2624 const err_ty = self.air.typeOf(ty_op.operand);
2615 const payload_ty = err_ty.errorUnionPayload();2625 const payload_ty = err_ty.errorUnionPayload();
2616 if (!payload_ty.hasCodeGenBits()) return WValue.none;2626 if (!payload_ty.hasCodeGenBits()) return WValue{ .none = {} };
2617 const offset = @intCast(u32, err_ty.errorUnionSet().abiSize(self.target));2627 const offset = @intCast(u32, err_ty.errorUnionSet().abiSize(self.target));
2628 if (self.isByRef(payload_ty)) {
2629 return self.buildPointerOffset(operand, offset, .new);
2630 }
2618 return try self.load(operand, payload_ty, offset);2631 return try self.load(operand, payload_ty, offset);
2619}2632}
26202633
...@@ -2741,7 +2754,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2741,7 +2754,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
27412754
2742 const offset = opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target);2755 const offset = opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target);
27432756
2744 if (isByRef(payload_ty)) {2757 if (self.isByRef(payload_ty)) {
2745 return self.buildPointerOffset(operand, offset, .new);2758 return self.buildPointerOffset(operand, offset, .new);
2746 }2759 }
27472760
...@@ -2872,7 +2885,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2872,7 +2885,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2872 const result = try self.allocLocal(elem_ty);2885 const result = try self.allocLocal(elem_ty);
2873 try self.addLabel(.local_set, result.local);2886 try self.addLabel(.local_set, result.local);
28742887
2875 if (isByRef(elem_ty)) {2888 if (self.isByRef(elem_ty)) {
2876 return result;2889 return result;
2877 }2890 }
2878 return try self.load(result, elem_ty, 0);2891 return try self.load(result, elem_ty, 0);
...@@ -3033,7 +3046,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3033,7 +3046,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
30333046
3034 const result = try self.allocLocal(elem_ty);3047 const result = try self.allocLocal(elem_ty);
3035 try self.addLabel(.local_set, result.local);3048 try self.addLabel(.local_set, result.local);
3036 if (isByRef(elem_ty)) {3049 if (self.isByRef(elem_ty)) {
3037 return result;3050 return result;
3038 }3051 }
3039 return try self.load(result, elem_ty, 0);3052 return try self.load(result, elem_ty, 0);
...@@ -3183,7 +3196,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3183,7 +3196,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3183 const result = try self.allocLocal(elem_ty);3196 const result = try self.allocLocal(elem_ty);
3184 try self.addLabel(.local_set, result.local);3197 try self.addLabel(.local_set, result.local);
31853198
3186 if (isByRef(elem_ty)) {3199 if (self.isByRef(elem_ty)) {
3187 return result;3200 return result;
3188 }3201 }
3189 return try self.load(result, elem_ty, 0);3202 return try self.load(result, elem_ty, 0);
...@@ -3244,10 +3257,43 @@ fn cmpOptionals(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std...@@ -3244,10 +3257,43 @@ fn cmpOptionals(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
3244 try self.addLabel(.local_set, result.local);3257 try self.addLabel(.local_set, result.local);
3245 try self.endBlock();3258 try self.endBlock();
32463259
3247 const is_equal = try self.allocLocal(Type.initTag(.i32));
3248 try self.emitWValue(result);3260 try self.emitWValue(result);
3249 try self.addImm32(0);3261 try self.addImm32(0);
3250 try self.addTag(if (op == .eq) .i32_ne else .i32_eq);3262 try self.addTag(if (op == .eq) .i32_ne else .i32_eq);
3251 try self.addLabel(.local_set, is_equal.local);3263 try self.addLabel(.local_set, result.local);
3252 return is_equal;3264 return result;
3265}
3266
3267/// Compares big integers by checking both its high bits and low bits.
3268/// TODO: Lower this to compiler_rt call
3269fn cmpBigInt(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
3270 if (operand_ty.intInfo(self.target).bits > 128) {
3271 return self.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.intInfo(self.target).bits});
3272 }
3273
3274 const result = try self.allocLocal(Type.initTag(.i32));
3275 {
3276 try self.startBlock(.block, wasm.block_empty);
3277 const lhs_high_bit = try self.load(lhs, Type.initTag(.u64), 0);
3278 const lhs_low_bit = try self.load(lhs, Type.initTag(.u64), 8);
3279 const rhs_high_bit = try self.load(rhs, Type.initTag(.u64), 0);
3280 const rhs_low_bit = try self.load(rhs, Type.initTag(.u64), 8);
3281 try self.emitWValue(lhs_high_bit);
3282 try self.emitWValue(rhs_high_bit);
3283 try self.addTag(.i64_ne);
3284 try self.addLabel(.br_if, 0);
3285 try self.emitWValue(lhs_low_bit);
3286 try self.emitWValue(rhs_low_bit);
3287 try self.addTag(.i64_ne);
3288 try self.addLabel(.br_if, 0);
3289 try self.addImm32(1);
3290 try self.addLabel(.local_set, result.local);
3291 try self.endBlock();
3292 }
3293
3294 try self.emitWValue(result);
3295 try self.addImm32(0);
3296 try self.addTag(if (op == .eq) .i32_ne else .i32_eq);
3297 try self.addLabel(.local_set, result.local);
3298 return result;
3253}3299}
test/behavior.zig+7-6
...@@ -20,8 +20,8 @@ test {...@@ -20,8 +20,8 @@ test {
2020
21 if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64) {21 if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64) {
22 // Tests that pass for stage1, llvm backend, C backend, wasm backend.22 // Tests that pass for stage1, llvm backend, C backend, wasm backend.
23 _ = @import("behavior/align.zig");
23 _ = @import("behavior/array.zig");24 _ = @import("behavior/array.zig");
24 _ = @import("behavior/bugs/3586.zig");
25 _ = @import("behavior/basic.zig");25 _ = @import("behavior/basic.zig");
26 _ = @import("behavior/bitcast.zig");26 _ = @import("behavior/bitcast.zig");
27 _ = @import("behavior/bugs/624.zig");27 _ = @import("behavior/bugs/624.zig");
...@@ -31,12 +31,14 @@ test {...@@ -31,12 +31,14 @@ test {
31 _ = @import("behavior/bugs/2692.zig");31 _ = @import("behavior/bugs/2692.zig");
32 _ = @import("behavior/bugs/2889.zig");32 _ = @import("behavior/bugs/2889.zig");
33 _ = @import("behavior/bugs/3046.zig");33 _ = @import("behavior/bugs/3046.zig");
34 _ = @import("behavior/bugs/3586.zig");
34 _ = @import("behavior/bugs/4560.zig");35 _ = @import("behavior/bugs/4560.zig");
35 _ = @import("behavior/bugs/4769_a.zig");36 _ = @import("behavior/bugs/4769_a.zig");
36 _ = @import("behavior/bugs/4769_b.zig");37 _ = @import("behavior/bugs/4769_b.zig");
37 _ = @import("behavior/bugs/4954.zig");38 _ = @import("behavior/bugs/4954.zig");
38 _ = @import("behavior/byval_arg_var.zig");39 _ = @import("behavior/byval_arg_var.zig");
39 _ = @import("behavior/call.zig");40 _ = @import("behavior/call.zig");
41 _ = @import("behavior/cast.zig");
40 _ = @import("behavior/defer.zig");42 _ = @import("behavior/defer.zig");
41 _ = @import("behavior/enum.zig");43 _ = @import("behavior/enum.zig");
42 _ = @import("behavior/error.zig");44 _ = @import("behavior/error.zig");
...@@ -48,12 +50,15 @@ test {...@@ -48,12 +50,15 @@ test {
48 _ = @import("behavior/inttoptr.zig");50 _ = @import("behavior/inttoptr.zig");
49 _ = @import("behavior/member_func.zig");51 _ = @import("behavior/member_func.zig");
50 _ = @import("behavior/null.zig");52 _ = @import("behavior/null.zig");
53 _ = @import("behavior/optional.zig");
51 _ = @import("behavior/pointers.zig");54 _ = @import("behavior/pointers.zig");
52 _ = @import("behavior/ptrcast.zig");55 _ = @import("behavior/ptrcast.zig");
53 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");56 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
57 _ = @import("behavior/src.zig");
54 _ = @import("behavior/struct.zig");58 _ = @import("behavior/struct.zig");
55 _ = @import("behavior/this.zig");59 _ = @import("behavior/this.zig");
56 _ = @import("behavior/truncate.zig");60 _ = @import("behavior/truncate.zig");
61 _ = @import("behavior/try.zig");
57 _ = @import("behavior/undefined.zig");62 _ = @import("behavior/undefined.zig");
58 _ = @import("behavior/underscore.zig");63 _ = @import("behavior/underscore.zig");
59 _ = @import("behavior/usingnamespace.zig");64 _ = @import("behavior/usingnamespace.zig");
...@@ -62,13 +67,9 @@ test {...@@ -62,13 +67,9 @@ test {
6267
63 if (builtin.zig_backend != .stage2_wasm) {68 if (builtin.zig_backend != .stage2_wasm) {
64 // Tests that pass for stage1, llvm backend, C backend69 // Tests that pass for stage1, llvm backend, C backend
65 _ = @import("behavior/align.zig");70 _ = @import("behavior/cast_int.zig");
66 _ = @import("behavior/cast.zig");
67 _ = @import("behavior/int128.zig");71 _ = @import("behavior/int128.zig");
68 _ = @import("behavior/optional.zig");
69 _ = @import("behavior/translate_c_macros.zig");72 _ = @import("behavior/translate_c_macros.zig");
70 _ = @import("behavior/try.zig");
71 _ = @import("behavior/src.zig");
7273
73 if (builtin.zig_backend != .stage2_c) {74 if (builtin.zig_backend != .stage2_c) {
74 // Tests that pass for stage1 and the llvm backend.75 // Tests that pass for stage1 and the llvm backend.