| author | |
| committer | |
| log | 6db520a4cd1ce2391c79d0d55b2b2d5297e133a3 |
| tree | 279f46702877d50bdfaa04a23c4923758e264c1c |
| parent | 47c5f556c08c1b15c74dbaca743d17a3297bcdef |
- make ubsan to be linkable by linker
- currently ignore bool vectors tests for `.stage2_wasm`, let defer handling it properly after supporting simd128 in backend (mainly tiny fixes + enabling it for matrix)
- I needed to refactor `wasm/abi.zig`, still bad9 files changed, 202 insertions(+), 64 deletions(-)
src/codegen/llvm/FuncGen.zig+2-2| ... | @@ -7156,7 +7156,7 @@ const ParamTypeIterator = struct { | ... | @@ -7156,7 +7156,7 @@ const ParamTypeIterator = struct { |
| 7156 | }, | 7156 | }, |
| 7157 | } | 7157 | } |
| 7158 | }, | 7158 | }, |
| 7159 | .wasm_mvp => switch (wasm_c_abi.classifyType(ty, zcu)) { | 7159 | .wasm_mvp => switch (wasm_c_abi.classifyTypeForLlvm(ty, zcu)) { |
| 7160 | .direct => |scalar_ty| { | 7160 | .direct => |scalar_ty| { |
| 7161 | if (isScalar(zcu, ty)) { | 7161 | if (isScalar(zcu, ty)) { |
| 7162 | it.zig_index += 1; | 7162 | it.zig_index += 1; |
| ... | @@ -7508,7 +7508,7 @@ pub fn fnReturnStrat(o: *Object, cc: std.lang.CallingConvention, ret_ty: Type) A | ... | @@ -7508,7 +7508,7 @@ pub fn fnReturnStrat(o: *Object, cc: std.lang.CallingConvention, ret_ty: Type) A |
| 7508 | .simple_aggregate => unreachable, | 7508 | .simple_aggregate => unreachable, |
| 7509 | .pointer => .sret, | 7509 | .pointer => .sret, |
| 7510 | }, | 7510 | }, |
| 7511 | .wasm_mvp => switch (wasm_c_abi.classifyType(ret_ty, zcu)) { | 7511 | .wasm_mvp => switch (wasm_c_abi.classifyTypeForLlvm(ret_ty, zcu)) { |
| 7512 | .direct => |scalar_ty| if (scalar_ty.toIntern() == ret_ty.toIntern()) { | 7512 | .direct => |scalar_ty| if (scalar_ty.toIntern() == ret_ty.toIntern()) { |
| 7513 | assert(!isByRef(ret_ty, zcu)); | 7513 | assert(!isByRef(ret_ty, zcu)); |
| 7514 | return .by_val; | 7514 | return .by_val; |
src/codegen/wasm/CodeGen.zig+81-32| ... | @@ -927,21 +927,26 @@ fn resolveCallingConventionValues( | ... | @@ -927,21 +927,26 @@ fn resolveCallingConventionValues( |
| 927 | }, | 927 | }, |
| 928 | .wasm_mvp => { | 928 | .wasm_mvp => { |
| 929 | for (fn_info.param_types.get(ip)) |ty| { | 929 | for (fn_info.param_types.get(ip)) |ty| { |
| 930 | if (!Type.fromInterned(ty).hasRuntimeBits(zcu)) { | 930 | const param_ty: Type = .fromInterned(ty); |
| 931 | if (!param_ty.hasRuntimeBits(zcu)) { | ||
| 931 | continue; | 932 | continue; |
| 932 | } | 933 | } |
| 933 | switch (abi.classifyType(.fromInterned(ty), zcu)) { | 934 | |
| 934 | .direct => |scalar_ty| if (!abi.lowerAsDoubleI64(scalar_ty, zcu)) { | 935 | switch (abi.classifyType(param_ty, zcu, target)) { |
| 936 | .direct, .indirect => { | ||
| 935 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); | 937 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); |
| 936 | result.local_index += 1; | 938 | result.local_index += 1; |
| 937 | } else { | 939 | }, |
| 940 | .double_i64 => { | ||
| 938 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); | 941 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); |
| 939 | try args.append(.{ .local = .{ .value = result.local_index + 1, .references = 1 } }); | 942 | try args.append(.{ .local = .{ .value = result.local_index + 1, .references = 1 } }); |
| 940 | result.local_index += 2; | 943 | result.local_index += 2; |
| 941 | }, | 944 | }, |
| 942 | .indirect => { | 945 | .unrolled => |vector| { |
| 943 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); | 946 | for (0..vector.len) |_| { |
| 944 | result.local_index += 1; | 947 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); |
| 948 | result.local_index += 1; | ||
| 949 | } | ||
| 945 | }, | 950 | }, |
| 946 | } | 951 | } |
| 947 | } | 952 | } |
| ... | @@ -968,9 +973,10 @@ pub fn firstParamSRet( | ... | @@ -968,9 +973,10 @@ pub fn firstParamSRet( |
| 968 | switch (cc) { | 973 | switch (cc) { |
| 969 | .@"inline" => unreachable, | 974 | .@"inline" => unreachable, |
| 970 | .auto => return isByRef(return_type, zcu, target), | 975 | .auto => return isByRef(return_type, zcu, target), |
| 971 | .wasm_mvp => switch (abi.classifyType(return_type, zcu)) { | 976 | .wasm_mvp => switch (abi.classifyType(return_type, zcu, target)) { |
| 972 | .direct => |scalar_ty| return abi.lowerAsDoubleI64(scalar_ty, zcu), | 977 | .direct => return false, |
| 973 | .indirect => return true, | 978 | .double_i64, .indirect => return true, |
| 979 | .unrolled => |vector| return vector.len > 1, | ||
| 974 | }, | 980 | }, |
| 975 | else => return false, | 981 | else => return false, |
| 976 | } | 982 | } |
| ... | @@ -985,18 +991,15 @@ fn lowerArg(cg: *CodeGen, cc: std.lang.CallingConvention, ty: Type, value: WValu | ... | @@ -985,18 +991,15 @@ fn lowerArg(cg: *CodeGen, cc: std.lang.CallingConvention, ty: Type, value: WValu |
| 985 | 991 | ||
| 986 | const zcu = cg.pt.zcu; | 992 | const zcu = cg.pt.zcu; |
| 987 | 993 | ||
| 988 | switch (abi.classifyType(ty, zcu)) { | 994 | switch (abi.classifyType(ty, zcu, cg.target)) { |
| 989 | .direct => |scalar_type| if (!abi.lowerAsDoubleI64(scalar_type, zcu)) { | 995 | .direct => |scalar_ty| { |
| 990 | if (!isByRef(ty, zcu, cg.target)) { | 996 | if (!isByRef(ty, zcu, cg.target)) { |
| 991 | return cg.lowerToStack(value); | 997 | return cg.lowerToStack(value); |
| 992 | } else { | 998 | } else { |
| 993 | switch (value) { | 999 | _ = try cg.load(value, scalar_ty, 0); |
| 994 | .nav_ref, .stack_offset => _ = try cg.load(value, scalar_type, 0), | ||
| 995 | .dead => unreachable, | ||
| 996 | else => try cg.emitWValue(value), | ||
| 997 | } | ||
| 998 | } | 1000 | } |
| 999 | } else { | 1001 | }, |
| 1002 | .double_i64 => { | ||
| 1000 | assert(ty.abiSize(zcu) == 16); | 1003 | assert(ty.abiSize(zcu) == 16); |
| 1001 | // in this case we have an integer or float that must be lowered as 2 i64's. | 1004 | // in this case we have an integer or float that must be lowered as 2 i64's. |
| 1002 | try cg.emitWValue(value); | 1005 | try cg.emitWValue(value); |
| ... | @@ -1004,7 +1007,17 @@ fn lowerArg(cg: *CodeGen, cc: std.lang.CallingConvention, ty: Type, value: WValu | ... | @@ -1004,7 +1007,17 @@ fn lowerArg(cg: *CodeGen, cc: std.lang.CallingConvention, ty: Type, value: WValu |
| 1004 | try cg.emitWValue(value); | 1007 | try cg.emitWValue(value); |
| 1005 | try cg.addMemArg(.i64_load, .{ .offset = value.offset() + 8, .alignment = 8 }); | 1008 | try cg.addMemArg(.i64_load, .{ .offset = value.offset() + 8, .alignment = 8 }); |
| 1006 | }, | 1009 | }, |
| 1007 | .indirect => return cg.lowerToStack(value), | 1010 | .indirect => { |
| 1011 | const stack_copy = try cg.allocStack(ty); | ||
| 1012 | try cg.store(stack_copy, value, ty, 0); | ||
| 1013 | return cg.lowerToStack(stack_copy); | ||
| 1014 | }, | ||
| 1015 | .unrolled => |vector| { | ||
| 1016 | const elem_size: u32 = @intCast(vector.elem_type.abiSize(zcu)); | ||
| 1017 | for (0..vector.len) |index| { | ||
| 1018 | _ = try cg.load(value, vector.elem_type, @intCast(index * elem_size)); | ||
| 1019 | } | ||
| 1020 | }, | ||
| 1008 | } | 1021 | } |
| 1009 | } | 1022 | } |
| 1010 | 1023 | ||
| ... | @@ -1947,16 +1960,19 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -1947,16 +1960,19 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1947 | if (cg.return_value != .none) { | 1960 | if (cg.return_value != .none) { |
| 1948 | try cg.store(cg.return_value, operand, ret_ty, 0); | 1961 | try cg.store(cg.return_value, operand, ret_ty, 0); |
| 1949 | } else if (fn_info.cc == .wasm_mvp and ret_ty.hasRuntimeBits(zcu)) { | 1962 | } else if (fn_info.cc == .wasm_mvp and ret_ty.hasRuntimeBits(zcu)) { |
| 1950 | switch (abi.classifyType(ret_ty, zcu)) { | 1963 | switch (abi.classifyType(ret_ty, zcu, cg.target)) { |
| 1951 | .direct => |scalar_type| { | 1964 | .direct => |scalar_type| { |
| 1952 | assert(!abi.lowerAsDoubleI64(scalar_type, zcu)); | ||
| 1953 | if (!isByRef(ret_ty, zcu, cg.target)) { | 1965 | if (!isByRef(ret_ty, zcu, cg.target)) { |
| 1954 | try cg.emitWValue(operand); | 1966 | try cg.emitWValue(operand); |
| 1955 | } else { | 1967 | } else { |
| 1956 | _ = try cg.load(operand, scalar_type, 0); | 1968 | _ = try cg.load(operand, scalar_type, 0); |
| 1957 | } | 1969 | } |
| 1958 | }, | 1970 | }, |
| 1959 | .indirect => unreachable, | 1971 | .double_i64, .indirect => unreachable, |
| 1972 | .unrolled => |vector| { | ||
| 1973 | assert(vector.len == 1); | ||
| 1974 | _ = try cg.load(operand, vector.elem_type, 0); | ||
| 1975 | }, | ||
| 1960 | } | 1976 | } |
| 1961 | } else { | 1977 | } else { |
| 1962 | if (!ret_ty.hasRuntimeBits(zcu) and ret_ty.isError(zcu)) { | 1978 | if (!ret_ty.hasRuntimeBits(zcu) and ret_ty.isError(zcu)) { |
| ... | @@ -2003,8 +2019,18 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2003,8 +2019,18 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2003 | try cg.addImm32(0); | 2019 | try cg.addImm32(0); |
| 2004 | } | 2020 | } |
| 2005 | } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), zcu, cg.target)) { | 2021 | } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), zcu, cg.target)) { |
| 2006 | // leave on the stack | 2022 | if (fn_info.cc == .wasm_mvp) { |
| 2007 | _ = try cg.load(operand, ret_ty, 0); | 2023 | switch (abi.classifyType(ret_ty, zcu, cg.target)) { |
| 2024 | .direct => |scalar_type| _ = try cg.load(operand, scalar_type, 0), | ||
| 2025 | .double_i64, .indirect => unreachable, | ||
| 2026 | .unrolled => |vector| { | ||
| 2027 | assert(vector.len == 1); | ||
| 2028 | _ = try cg.load(operand, vector.elem_type, 0); | ||
| 2029 | }, | ||
| 2030 | } | ||
| 2031 | } else { | ||
| 2032 | _ = try cg.load(operand, ret_ty, 0); | ||
| 2033 | } | ||
| 2008 | } | 2034 | } |
| 2009 | 2035 | ||
| 2010 | try cg.restoreStackPointer(); | 2036 | try cg.restoreStackPointer(); |
| ... | @@ -2132,22 +2158,30 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier) | ... | @@ -2132,22 +2158,30 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier) |
| 2132 | } else if (first_param_sret) { | 2158 | } else if (first_param_sret) { |
| 2133 | break :result_value sret; | 2159 | break :result_value sret; |
| 2134 | } else if (zcu.typeToFunc(fn_ty).?.cc == .wasm_mvp) { | 2160 | } else if (zcu.typeToFunc(fn_ty).?.cc == .wasm_mvp) { |
| 2135 | switch (abi.classifyType(ret_ty, zcu)) { | 2161 | switch (abi.classifyType(ret_ty, zcu, cg.target)) { |
| 2136 | .direct => |scalar_type| { | 2162 | .direct => |scalar_type| { |
| 2137 | assert(!abi.lowerAsDoubleI64(scalar_type, zcu)); | ||
| 2138 | if (!isByRef(ret_ty, zcu, cg.target)) { | 2163 | if (!isByRef(ret_ty, zcu, cg.target)) { |
| 2139 | const result_local = try cg.allocLocal(ret_ty); | 2164 | const result_local = try cg.allocLocal(ret_ty); |
| 2140 | try cg.addLocal(.local_set, result_local.local.value); | 2165 | try cg.addLocal(.local_set, result_local.local.value); |
| 2141 | break :result_value result_local; | 2166 | break :result_value result_local; |
| 2142 | } else { | 2167 | } else { |
| 2143 | const result_local = try cg.allocLocal(ret_ty); | 2168 | const result_local = try cg.allocLocal(scalar_type); |
| 2144 | try cg.addLocal(.local_set, result_local.local.value); | 2169 | try cg.addLocal(.local_set, result_local.local.value); |
| 2145 | const result = try cg.allocStack(ret_ty); | 2170 | const result = try cg.allocStack(ret_ty); |
| 2146 | try cg.store(result, result_local, scalar_type, 0); | 2171 | try cg.store(result, result_local, scalar_type, 0); |
| 2147 | break :result_value result; | 2172 | break :result_value result; |
| 2148 | } | 2173 | } |
| 2149 | }, | 2174 | }, |
| 2150 | .indirect => unreachable, | 2175 | .double_i64, .indirect => unreachable, |
| 2176 | .unrolled => |vector| { | ||
| 2177 | assert(vector.len == 1); | ||
| 2178 | const result_local = try cg.allocLocal(vector.elem_type); | ||
| 2179 | // save call result from operand stack | ||
| 2180 | try cg.addLocal(.local_set, result_local.local.value); | ||
| 2181 | const result = try cg.allocStack(ret_ty); | ||
| 2182 | try cg.store(result, result_local, vector.elem_type, 0); | ||
| 2183 | break :result_value result; | ||
| 2184 | }, | ||
| 2151 | } | 2185 | } |
| 2152 | } else { | 2186 | } else { |
| 2153 | const result_local = try cg.allocLocal(ret_ty); | 2187 | const result_local = try cg.allocLocal(ret_ty); |
| ... | @@ -2450,17 +2484,32 @@ fn airArg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2450,17 +2484,32 @@ fn airArg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2450 | const cc = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?.cc; | 2484 | const cc = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?.cc; |
| 2451 | const arg_ty = cg.typeOfIndex(inst); | 2485 | const arg_ty = cg.typeOfIndex(inst); |
| 2452 | if (cc == .wasm_mvp) { | 2486 | if (cc == .wasm_mvp) { |
| 2453 | switch (abi.classifyType(arg_ty, zcu)) { | 2487 | switch (abi.classifyType(arg_ty, zcu, cg.target)) { |
| 2454 | .direct => |scalar_ty| if (!abi.lowerAsDoubleI64(scalar_ty, zcu)) { | 2488 | .direct => |scalar_type| { |
| 2455 | cg.arg_index += 1; | 2489 | cg.arg_index += 1; |
| 2456 | } else { | 2490 | if (isByRef(arg_ty, zcu, cg.target)) { |
| 2491 | const result = try cg.allocStack(arg_ty); | ||
| 2492 | try cg.store(result, arg, scalar_type, 0); | ||
| 2493 | return cg.finishAir(inst, result, &.{}); | ||
| 2494 | } | ||
| 2495 | }, | ||
| 2496 | .indirect => cg.arg_index += 1, | ||
| 2497 | .double_i64 => { | ||
| 2457 | cg.arg_index += 2; | 2498 | cg.arg_index += 2; |
| 2458 | const result = try cg.allocStack(arg_ty); | 2499 | const result = try cg.allocStack(arg_ty); |
| 2459 | try cg.store(result, arg, Type.u64, 0); | 2500 | try cg.store(result, arg, Type.u64, 0); |
| 2460 | try cg.store(result, cg.args[arg_index + 1], Type.u64, 8); | 2501 | try cg.store(result, cg.args[arg_index + 1], Type.u64, 8); |
| 2461 | return cg.finishAir(inst, result, &.{}); | 2502 | return cg.finishAir(inst, result, &.{}); |
| 2462 | }, | 2503 | }, |
| 2463 | .indirect => cg.arg_index += 1, | 2504 | .unrolled => |vector| { |
| 2505 | const result = try cg.allocStack(arg_ty); | ||
| 2506 | const elem_size: u32 = @intCast(vector.elem_type.abiSize(zcu)); | ||
| 2507 | for (0..vector.len) |index| { | ||
| 2508 | try cg.store(result, cg.args[cg.arg_index], vector.elem_type, @intCast(index * elem_size)); | ||
| 2509 | cg.arg_index += 1; | ||
| 2510 | } | ||
| 2511 | return cg.finishAir(inst, result, &.{}); | ||
| 2512 | }, | ||
| 2464 | } | 2513 | } |
| 2465 | } else { | 2514 | } else { |
| 2466 | cg.arg_index += 1; | 2515 | cg.arg_index += 1; |
src/codegen/wasm/abi.zig+35-11| ... | @@ -11,16 +11,44 @@ const assert = std.debug.assert; | ... | @@ -11,16 +11,44 @@ const assert = std.debug.assert; |
| 11 | const Type = @import("../../Type.zig"); | 11 | const Type = @import("../../Type.zig"); |
| 12 | const Zcu = @import("../../Zcu.zig"); | 12 | const Zcu = @import("../../Zcu.zig"); |
| 13 | 13 | ||
| 14 | /// Defines how to pass a type as part of a function signature, | 14 | /// Describes how the Wasm backend represents a C ABI value. |
| 15 | /// both for parameters as well as return values. | ||
| 16 | pub const Class = union(enum) { | 15 | pub const Class = union(enum) { |
| 17 | direct: Type, | 16 | direct: Type, |
| 17 | double_i64, | ||
| 18 | indirect, | 18 | indirect, |
| 19 | unrolled: struct { | ||
| 20 | elem_type: Type, | ||
| 21 | len: u32, | ||
| 22 | }, | ||
| 19 | }; | 23 | }; |
| 20 | 24 | ||
| 21 | /// Classifies a given Zig type to determine how they must be passed | 25 | pub const LlvmClass = union(enum) { |
| 22 | /// or returned as value within a wasm function. | 26 | direct: Type, |
| 23 | pub fn classifyType(ty: Type, zcu: *const Zcu) Class { | 27 | indirect, |
| 28 | }; | ||
| 29 | |||
| 30 | pub fn classifyType(ty: Type, zcu: *const Zcu, target: *const Target) Class { | ||
| 31 | if (ty.zigTypeTag(zcu) == .vector) { | ||
| 32 | if (!(ty.bitSize(zcu) == 128 and target.cpu.has(.wasm, .simd128))) { | ||
| 33 | const elem_type = ty.childType(zcu); | ||
| 34 | return .{ .unrolled = .{ | ||
| 35 | .elem_type = elem_type, | ||
| 36 | .len = ty.vectorLen(zcu), | ||
| 37 | } }; | ||
| 38 | } | ||
| 39 | return .{ .direct = ty }; | ||
| 40 | } | ||
| 41 | |||
| 42 | return switch (classifyTypeForLlvm(ty, zcu)) { | ||
| 43 | .direct => |scalar_ty| if (scalar_ty.bitSize(zcu) > 64) | ||
| 44 | .double_i64 | ||
| 45 | else | ||
| 46 | .{ .direct = scalar_ty }, | ||
| 47 | .indirect => .indirect, | ||
| 48 | }; | ||
| 49 | } | ||
| 50 | |||
| 51 | pub fn classifyTypeForLlvm(ty: Type, zcu: *const Zcu) LlvmClass { | ||
| 24 | const ip = &zcu.intern_pool; | 52 | const ip = &zcu.intern_pool; |
| 25 | assert(ty.hasRuntimeBits(zcu)); | 53 | assert(ty.hasRuntimeBits(zcu)); |
| 26 | switch (ty.zigTypeTag(zcu)) { | 54 | switch (ty.zigTypeTag(zcu)) { |
| ... | @@ -56,7 +84,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { | ... | @@ -56,7 +84,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { |
| 56 | if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(zcu))) | 84 | if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(zcu))) |
| 57 | return .indirect; | 85 | return .indirect; |
| 58 | } | 86 | } |
| 59 | return classifyType(field_ty, zcu); | 87 | return classifyTypeForLlvm(field_ty, zcu); |
| 60 | }, | 88 | }, |
| 61 | .@"union" => { | 89 | .@"union" => { |
| 62 | const union_obj = zcu.typeToUnion(ty).?; | 90 | const union_obj = zcu.typeToUnion(ty).?; |
| ... | @@ -67,7 +95,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { | ... | @@ -67,7 +95,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { |
| 67 | assert(layout.tag_size == 0); | 95 | assert(layout.tag_size == 0); |
| 68 | if (union_obj.field_types.len > 1) return .indirect; | 96 | if (union_obj.field_types.len > 1) return .indirect; |
| 69 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); | 97 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); |
| 70 | return classifyType(first_field_ty, zcu); | 98 | return classifyTypeForLlvm(first_field_ty, zcu); |
| 71 | }, | 99 | }, |
| 72 | .error_union, | 100 | .error_union, |
| 73 | .frame, | 101 | .frame, |
| ... | @@ -86,7 +114,3 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { | ... | @@ -86,7 +114,3 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { |
| 86 | => unreachable, | 114 | => unreachable, |
| 87 | } | 115 | } |
| 88 | } | 116 | } |
| 89 | |||
| 90 | pub fn lowerAsDoubleI64(scalar_ty: Type, zcu: *const Zcu) bool { | ||
| 91 | return scalar_ty.bitSize(zcu) > 64; | ||
| 92 | } |
src/link/Wasm.zig+22-13| ... | @@ -4938,12 +4938,15 @@ fn convertZcuFnType( | ... | @@ -4938,12 +4938,15 @@ fn convertZcuFnType( |
| 4938 | try params_buffer.append(gpa, .i32); // memory address is always a 32-bit handle | 4938 | try params_buffer.append(gpa, .i32); // memory address is always a 32-bit handle |
| 4939 | } else if (return_type.hasRuntimeBits(zcu)) { | 4939 | } else if (return_type.hasRuntimeBits(zcu)) { |
| 4940 | if (cc == .wasm_mvp) { | 4940 | if (cc == .wasm_mvp) { |
| 4941 | switch (abi.classifyType(return_type, zcu)) { | 4941 | switch (abi.classifyType(return_type, zcu, target)) { |
| 4942 | .direct => |scalar_ty| { | 4942 | .direct => |scalar_type| { |
| 4943 | assert(!abi.lowerAsDoubleI64(scalar_ty, zcu)); | 4943 | try returns_buffer.append(gpa, CodeGen.typeToValtype(scalar_type, zcu, target)); |
| 4944 | try returns_buffer.append(gpa, CodeGen.typeToValtype(scalar_ty, zcu, target)); | 4944 | }, |
| 4945 | .double_i64, .indirect => unreachable, | ||
| 4946 | .unrolled => |vector| { | ||
| 4947 | assert(vector.len == 1); | ||
| 4948 | try returns_buffer.append(gpa, CodeGen.typeToValtype(vector.elem_type, zcu, target)); | ||
| 4945 | }, | 4949 | }, |
| 4946 | .indirect => unreachable, | ||
| 4947 | } | 4950 | } |
| 4948 | } else { | 4951 | } else { |
| 4949 | try returns_buffer.append(gpa, CodeGen.typeToValtype(return_type, zcu, target)); | 4952 | try returns_buffer.append(gpa, CodeGen.typeToValtype(return_type, zcu, target)); |
| ... | @@ -4959,16 +4962,22 @@ fn convertZcuFnType( | ... | @@ -4959,16 +4962,22 @@ fn convertZcuFnType( |
| 4959 | 4962 | ||
| 4960 | switch (cc) { | 4963 | switch (cc) { |
| 4961 | .wasm_mvp => { | 4964 | .wasm_mvp => { |
| 4962 | switch (abi.classifyType(param_type, zcu)) { | 4965 | switch (abi.classifyType(param_type, zcu, target)) { |
| 4963 | .direct => |scalar_ty| { | 4966 | .direct => |scalar_type| { |
| 4964 | if (!abi.lowerAsDoubleI64(scalar_ty, zcu)) { | 4967 | try params_buffer.append(gpa, CodeGen.typeToValtype(scalar_type, zcu, target)); |
| 4965 | try params_buffer.append(gpa, CodeGen.typeToValtype(scalar_ty, zcu, target)); | 4968 | }, |
| 4966 | } else { | 4969 | .double_i64 => { |
| 4967 | try params_buffer.append(gpa, .i64); | 4970 | try params_buffer.append(gpa, .i64); |
| 4968 | try params_buffer.append(gpa, .i64); | 4971 | try params_buffer.append(gpa, .i64); |
| 4972 | }, | ||
| 4973 | .indirect => { | ||
| 4974 | try params_buffer.append(gpa, CodeGen.typeToValtype(param_type, zcu, target)); | ||
| 4975 | }, | ||
| 4976 | .unrolled => |vector| { | ||
| 4977 | for (0..vector.len) |_| { | ||
| 4978 | try params_buffer.append(gpa, CodeGen.typeToValtype(vector.elem_type, zcu, target)); | ||
| 4969 | } | 4979 | } |
| 4970 | }, | 4980 | }, |
| 4971 | .indirect => try params_buffer.append(gpa, CodeGen.typeToValtype(param_type, zcu, target)), | ||
| 4972 | } | 4981 | } |
| 4973 | }, | 4982 | }, |
| 4974 | else => try params_buffer.append(gpa, CodeGen.typeToValtype(param_type, zcu, target)), | 4983 | else => try params_buffer.append(gpa, CodeGen.typeToValtype(param_type, zcu, target)), |
src/link/Wasm/Flush.zig+33-4| ... | @@ -248,6 +248,9 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -248,6 +248,9 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 248 | 248 | ||
| 249 | if (comp.zcu) |zcu| { | 249 | if (comp.zcu) |zcu| { |
| 250 | const ip: *const InternPool = &zcu.intern_pool; // No mutations allowed! | 250 | const ip: *const InternPool = &zcu.intern_pool; // No mutations allowed! |
| 251 | const function_imports_start = wasm.function_imports.entries.len; | ||
| 252 | const global_imports_start = wasm.global_imports.entries.len; | ||
| 253 | const data_imports_start = wasm.data_imports.entries.len; | ||
| 251 | 254 | ||
| 252 | log.debug("total MIR instructions: {d}", .{wasm.mir_instructions.len}); | 255 | log.debug("total MIR instructions: {d}", .{wasm.mir_instructions.len}); |
| 253 | 256 | ||
| ... | @@ -464,6 +467,35 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -464,6 +467,35 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 464 | else => continue, | 467 | else => continue, |
| 465 | }; | 468 | }; |
| 466 | 469 | ||
| 470 | // marking above may discover additional imports | ||
| 471 | try f.function_imports.ensureUnusedCapacity(gpa, wasm.function_imports.entries.len - function_imports_start); | ||
| 472 | for ( | ||
| 473 | wasm.function_imports.keys()[function_imports_start..], | ||
| 474 | wasm.function_imports.values()[function_imports_start..], | ||
| 475 | ) |name, id| { | ||
| 476 | if (!f.function_imports.contains(name) and Wasm.FunctionIndex.fromSymbolName(wasm, name) == null) { | ||
| 477 | f.function_imports.putAssumeCapacity(name, id); | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | try f.global_imports.ensureUnusedCapacity(gpa, wasm.global_imports.entries.len - global_imports_start); | ||
| 482 | for ( | ||
| 483 | wasm.global_imports.keys()[global_imports_start..], | ||
| 484 | wasm.global_imports.values()[global_imports_start..], | ||
| 485 | ) |name, id| { | ||
| 486 | if (!f.global_imports.contains(name)) f.global_imports.putAssumeCapacity(name, id); | ||
| 487 | } | ||
| 488 | |||
| 489 | try f.data_imports.ensureUnusedCapacity(gpa, wasm.data_imports.entries.len - data_imports_start); | ||
| 490 | for ( | ||
| 491 | wasm.data_imports.keys()[data_imports_start..], | ||
| 492 | wasm.data_imports.values()[data_imports_start..], | ||
| 493 | ) |name, id| { | ||
| 494 | if (!f.data_imports.contains(name) and !f.data_exports.contains(name)) { | ||
| 495 | f.data_imports.putAssumeCapacity(name, id); | ||
| 496 | } | ||
| 497 | } | ||
| 498 | |||
| 467 | for (f.missing_exports.keys()) |exp_name| { | 499 | for (f.missing_exports.keys()) |exp_name| { |
| 468 | diags.addError("manually specified export name '{s}' undefined", .{exp_name.slice(wasm)}); | 500 | diags.addError("manually specified export name '{s}' undefined", .{exp_name.slice(wasm)}); |
| 469 | } | 501 | } |
| ... | @@ -1075,13 +1107,10 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -1075,13 +1107,10 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 1075 | if (wasm.functions.getIndex(.__wasm_init_memory)) |func_index| { | 1107 | if (wasm.functions.getIndex(.__wasm_init_memory)) |func_index| { |
| 1076 | try emitStartSection(gpa, binary_bytes, .fromFunctionIndex(wasm, @fromBackingInt(@intCast(func_index)))); | 1108 | try emitStartSection(gpa, binary_bytes, .fromFunctionIndex(wasm, @fromBackingInt(@intCast(func_index)))); |
| 1077 | section_index += 1; | 1109 | section_index += 1; |
| 1078 | } else if (Wasm.OutputFunctionIndex.fromResolution(wasm, wasm.entry_resolution)) |func_index| { | ||
| 1079 | try emitStartSection(gpa, binary_bytes, func_index); | ||
| 1080 | section_index += 1; | ||
| 1081 | } | 1110 | } |
| 1082 | 1111 | ||
| 1083 | // element section | 1112 | // element section |
| 1084 | if (f.indirect_function_table.entries.len > 0) { | 1113 | if (!is_obj and f.indirect_function_table.entries.len > 0) { |
| 1085 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 1114 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 1086 | 1115 | ||
| 1087 | // indirect function table elements | 1116 | // indirect function table elements |
src/link/Wasm/Object.zig+1-1| ... | @@ -856,7 +856,7 @@ pub fn parse( | ... | @@ -856,7 +856,7 @@ pub fn parse( |
| 856 | start_function = @fromBackingInt(@intCast(functions_start + index)); | 856 | start_function = @fromBackingInt(@intCast(functions_start + index)); |
| 857 | }, | 857 | }, |
| 858 | .element => { | 858 | .element => { |
| 859 | log.warn("unimplemented: element section in {f} {?s}", .{ path, archive_member_name }); | 859 | // element section is not needed for linking, validating it serves no purpose |
| 860 | pos = section_end; | 860 | pos = section_end; |
| 861 | }, | 861 | }, |
| 862 | .code => { | 862 | .code => { |
src/target.zig+1-1| ... | @@ -450,7 +450,7 @@ pub fn canBuildLibUbsanRt(target: *const std.Target) enum { no, yes, llvm_only, | ... | @@ -450,7 +450,7 @@ pub fn canBuildLibUbsanRt(target: *const std.Target) enum { no, yes, llvm_only, |
| 450 | else => {}, | 450 | else => {}, |
| 451 | } | 451 | } |
| 452 | return switch (zigBackend(target, false)) { | 452 | return switch (zigBackend(target, false)) { |
| 453 | .stage2_wasm => .llvm_lld_only, | 453 | .stage2_wasm => .yes, |
| 454 | .stage2_x86_64 => .yes, | 454 | .stage2_x86_64 => .yes, |
| 455 | else => .llvm_only, | 455 | else => .llvm_only, |
| 456 | }; | 456 | }; |
test/c_abi/main.zig+18| ... | @@ -451,6 +451,7 @@ test "long double" { | ... | @@ -451,6 +451,7 @@ test "long double" { |
| 451 | 451 | ||
| 452 | comptime { | 452 | comptime { |
| 453 | skip: { | 453 | skip: { |
| 454 | if (builtin.zig_backend == .stage2_wasm) break :skip; | ||
| 454 | if (builtin.cpu.arch == .hexagon) break :skip; | 455 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 455 | if (builtin.cpu.arch == .loongarch64) break :skip; | 456 | if (builtin.cpu.arch == .loongarch64) break :skip; |
| 456 | if (builtin.cpu.arch.isMIPS()) break :skip; | 457 | if (builtin.cpu.arch.isMIPS()) break :skip; |
| ... | @@ -477,6 +478,7 @@ extern fn c_vector_2_bool(@Vector(2, bool)) void; | ... | @@ -477,6 +478,7 @@ extern fn c_vector_2_bool(@Vector(2, bool)) void; |
| 477 | extern fn c_test_vector_2_bool() void; | 478 | extern fn c_test_vector_2_bool() void; |
| 478 | 479 | ||
| 479 | test "@Vector(2, bool)" { | 480 | test "@Vector(2, bool)" { |
| 481 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 480 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | 482 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; |
| 481 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 483 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 482 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 484 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| ... | @@ -497,6 +499,7 @@ test "@Vector(2, bool)" { | ... | @@ -497,6 +499,7 @@ test "@Vector(2, bool)" { |
| 497 | 499 | ||
| 498 | comptime { | 500 | comptime { |
| 499 | skip: { | 501 | skip: { |
| 502 | if (builtin.zig_backend == .stage2_wasm) break :skip; | ||
| 500 | if (builtin.cpu.arch == .hexagon) break :skip; | 503 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 501 | if (builtin.cpu.arch == .loongarch64) break :skip; | 504 | if (builtin.cpu.arch == .loongarch64) break :skip; |
| 502 | if (builtin.cpu.arch.isMIPS()) break :skip; | 505 | if (builtin.cpu.arch.isMIPS()) break :skip; |
| ... | @@ -527,6 +530,7 @@ extern fn c_vector_4_bool(@Vector(4, bool)) void; | ... | @@ -527,6 +530,7 @@ extern fn c_vector_4_bool(@Vector(4, bool)) void; |
| 527 | extern fn c_test_vector_4_bool() void; | 530 | extern fn c_test_vector_4_bool() void; |
| 528 | 531 | ||
| 529 | test "@Vector(4, bool)" { | 532 | test "@Vector(4, bool)" { |
| 533 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 530 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | 534 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; |
| 531 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 535 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 532 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 536 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| ... | @@ -551,6 +555,7 @@ test "@Vector(4, bool)" { | ... | @@ -551,6 +555,7 @@ test "@Vector(4, bool)" { |
| 551 | 555 | ||
| 552 | comptime { | 556 | comptime { |
| 553 | skip: { | 557 | skip: { |
| 558 | if (builtin.zig_backend == .stage2_wasm) break :skip; | ||
| 554 | if (builtin.cpu.arch == .hexagon) break :skip; | 559 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 555 | if (builtin.cpu.arch == .loongarch64) break :skip; | 560 | if (builtin.cpu.arch == .loongarch64) break :skip; |
| 556 | if (builtin.cpu.arch.isMIPS()) break :skip; | 561 | if (builtin.cpu.arch.isMIPS()) break :skip; |
| ... | @@ -589,6 +594,7 @@ extern fn c_vector_8_bool(@Vector(8, bool)) void; | ... | @@ -589,6 +594,7 @@ extern fn c_vector_8_bool(@Vector(8, bool)) void; |
| 589 | extern fn c_test_vector_8_bool() void; | 594 | extern fn c_test_vector_8_bool() void; |
| 590 | 595 | ||
| 591 | test "@Vector(8, bool)" { | 596 | test "@Vector(8, bool)" { |
| 597 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 592 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | 598 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; |
| 593 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 599 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 594 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 600 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| ... | @@ -621,6 +627,7 @@ test "@Vector(8, bool)" { | ... | @@ -621,6 +627,7 @@ test "@Vector(8, bool)" { |
| 621 | 627 | ||
| 622 | comptime { | 628 | comptime { |
| 623 | skip: { | 629 | skip: { |
| 630 | if (builtin.zig_backend == .stage2_wasm) break :skip; | ||
| 624 | if (builtin.cpu.arch == .hexagon) break :skip; | 631 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 625 | if (builtin.cpu.arch == .loongarch64) break :skip; | 632 | if (builtin.cpu.arch == .loongarch64) break :skip; |
| 626 | if (builtin.cpu.arch.isMIPS()) break :skip; | 633 | if (builtin.cpu.arch.isMIPS()) break :skip; |
| ... | @@ -675,6 +682,7 @@ extern fn c_vector_16_bool(@Vector(16, bool)) void; | ... | @@ -675,6 +682,7 @@ extern fn c_vector_16_bool(@Vector(16, bool)) void; |
| 675 | extern fn c_test_vector_16_bool() void; | 682 | extern fn c_test_vector_16_bool() void; |
| 676 | 683 | ||
| 677 | test "@Vector(16, bool)" { | 684 | test "@Vector(16, bool)" { |
| 685 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 678 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | 686 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; |
| 679 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 687 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 680 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 688 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| ... | @@ -723,6 +731,7 @@ test "@Vector(16, bool)" { | ... | @@ -723,6 +731,7 @@ test "@Vector(16, bool)" { |
| 723 | 731 | ||
| 724 | comptime { | 732 | comptime { |
| 725 | skip: { | 733 | skip: { |
| 734 | if (builtin.zig_backend == .stage2_wasm) break :skip; | ||
| 726 | if (builtin.cpu.arch == .hexagon) break :skip; | 735 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 727 | if (builtin.cpu.arch == .loongarch64) break :skip; | 736 | if (builtin.cpu.arch == .loongarch64) break :skip; |
| 728 | if (builtin.cpu.arch.isMIPS()) break :skip; | 737 | if (builtin.cpu.arch.isMIPS()) break :skip; |
| ... | @@ -809,6 +818,7 @@ extern fn c_vector_32_bool(@Vector(32, bool)) void; | ... | @@ -809,6 +818,7 @@ extern fn c_vector_32_bool(@Vector(32, bool)) void; |
| 809 | extern fn c_test_vector_32_bool() void; | 818 | extern fn c_test_vector_32_bool() void; |
| 810 | 819 | ||
| 811 | test "@Vector(32, bool)" { | 820 | test "@Vector(32, bool)" { |
| 821 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 812 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | 822 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; |
| 813 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 823 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 814 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 824 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| ... | @@ -889,6 +899,7 @@ test "@Vector(32, bool)" { | ... | @@ -889,6 +899,7 @@ test "@Vector(32, bool)" { |
| 889 | 899 | ||
| 890 | comptime { | 900 | comptime { |
| 891 | skip: { | 901 | skip: { |
| 902 | if (builtin.zig_backend == .stage2_wasm) break :skip; | ||
| 892 | if (builtin.cpu.arch == .hexagon) break :skip; | 903 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 893 | if (builtin.cpu.arch == .loongarch64) break :skip; | 904 | if (builtin.cpu.arch == .loongarch64) break :skip; |
| 894 | if (builtin.cpu.arch.isMIPS()) break :skip; | 905 | if (builtin.cpu.arch.isMIPS()) break :skip; |
| ... | @@ -1039,6 +1050,7 @@ extern fn c_vector_64_bool(@Vector(64, bool)) void; | ... | @@ -1039,6 +1050,7 @@ extern fn c_vector_64_bool(@Vector(64, bool)) void; |
| 1039 | extern fn c_test_vector_64_bool() void; | 1050 | extern fn c_test_vector_64_bool() void; |
| 1040 | 1051 | ||
| 1041 | test "@Vector(64, bool)" { | 1052 | test "@Vector(64, bool)" { |
| 1053 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 1042 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 1054 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 1043 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 1055 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 1044 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 1056 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| ... | @@ -1181,6 +1193,7 @@ test "@Vector(64, bool)" { | ... | @@ -1181,6 +1193,7 @@ test "@Vector(64, bool)" { |
| 1181 | 1193 | ||
| 1182 | comptime { | 1194 | comptime { |
| 1183 | skip: { | 1195 | skip: { |
| 1196 | if (builtin.zig_backend == .stage2_wasm) break :skip; | ||
| 1184 | if (builtin.cpu.arch == .hexagon) break :skip; | 1197 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 1185 | if (builtin.cpu.arch == .loongarch64) break :skip; | 1198 | if (builtin.cpu.arch == .loongarch64) break :skip; |
| 1186 | if (builtin.cpu.arch.isMIPS()) break :skip; | 1199 | if (builtin.cpu.arch.isMIPS()) break :skip; |
| ... | @@ -1459,6 +1472,7 @@ extern fn c_vector_128_bool(@Vector(128, bool)) void; | ... | @@ -1459,6 +1472,7 @@ extern fn c_vector_128_bool(@Vector(128, bool)) void; |
| 1459 | extern fn c_test_vector_128_bool() void; | 1472 | extern fn c_test_vector_128_bool() void; |
| 1460 | 1473 | ||
| 1461 | test "@Vector(128, bool)" { | 1474 | test "@Vector(128, bool)" { |
| 1475 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 1462 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 1476 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 1463 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 1477 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 1464 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 1478 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| ... | @@ -1729,6 +1743,7 @@ test "@Vector(128, bool)" { | ... | @@ -1729,6 +1743,7 @@ test "@Vector(128, bool)" { |
| 1729 | 1743 | ||
| 1730 | comptime { | 1744 | comptime { |
| 1731 | skip: { | 1745 | skip: { |
| 1746 | if (builtin.zig_backend == .stage2_wasm) break :skip; | ||
| 1732 | if (builtin.cpu.arch == .hexagon) break :skip; | 1747 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 1733 | if (builtin.cpu.arch == .loongarch64) break :skip; | 1748 | if (builtin.cpu.arch == .loongarch64) break :skip; |
| 1734 | if (builtin.cpu.arch.isMIPS()) break :skip; | 1749 | if (builtin.cpu.arch.isMIPS()) break :skip; |
| ... | @@ -2263,6 +2278,7 @@ extern fn c_vector_256_bool(@Vector(256, bool)) void; | ... | @@ -2263,6 +2278,7 @@ extern fn c_vector_256_bool(@Vector(256, bool)) void; |
| 2263 | extern fn c_test_vector_256_bool() void; | 2278 | extern fn c_test_vector_256_bool() void; |
| 2264 | 2279 | ||
| 2265 | test "@Vector(256, bool)" { | 2280 | test "@Vector(256, bool)" { |
| 2281 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 2266 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 2282 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 2267 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 2283 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 2268 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 2284 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| ... | @@ -2789,6 +2805,7 @@ test "@Vector(256, bool)" { | ... | @@ -2789,6 +2805,7 @@ test "@Vector(256, bool)" { |
| 2789 | 2805 | ||
| 2790 | comptime { | 2806 | comptime { |
| 2791 | skip: { | 2807 | skip: { |
| 2808 | if (builtin.zig_backend == .stage2_wasm) break :skip; | ||
| 2792 | if (builtin.cpu.arch == .hexagon) break :skip; | 2809 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 2793 | if (builtin.cpu.arch == .loongarch64) break :skip; | 2810 | if (builtin.cpu.arch == .loongarch64) break :skip; |
| 2794 | if (builtin.cpu.arch.isMIPS()) break :skip; | 2811 | if (builtin.cpu.arch.isMIPS()) break :skip; |
| ... | @@ -3835,6 +3852,7 @@ extern fn c_vector_512_bool(@Vector(512, bool)) void; | ... | @@ -3835,6 +3852,7 @@ extern fn c_vector_512_bool(@Vector(512, bool)) void; |
| 3835 | extern fn c_test_vector_512_bool() void; | 3852 | extern fn c_test_vector_512_bool() void; |
| 3836 | 3853 | ||
| 3837 | test "@Vector(512, bool)" { | 3854 | test "@Vector(512, bool)" { |
| 3855 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 3838 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 3856 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 3839 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 3857 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 3840 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 3858 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
test/tests.zig+9| ... | @@ -2060,6 +2060,15 @@ const c_abi_targets = blk: { | ... | @@ -2060,6 +2060,15 @@ const c_abi_targets = blk: { |
| 2060 | .abi = .musl, | 2060 | .abi = .musl, |
| 2061 | }, | 2061 | }, |
| 2062 | }, | 2062 | }, |
| 2063 | .{ | ||
| 2064 | .target = .{ | ||
| 2065 | .cpu_arch = .wasm32, | ||
| 2066 | .os_tag = .wasi, | ||
| 2067 | .abi = .musl, | ||
| 2068 | }, | ||
| 2069 | .use_llvm = false, | ||
| 2070 | .use_lld = false, | ||
| 2071 | }, | ||
| 2063 | 2072 | ||
| 2064 | // Windows Targets | 2073 | // Windows Targets |
| 2065 | 2074 |