diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-10-15 05:51:41 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-15 05:51:41 +0200 |
| commit | b0f031f5730be496872591dce3242004cf9a6f22 (patch) | |
| tree | cc529312ee13c80a55f21d95ab051cd7f1cd2cea /src/arch/wasm/CodeGen.zig | |
| parent | a126afa1c3fe7e39678c201f6470b7899aedd47e (diff) | |
| parent | 78fe3feedbfa2f86bfbacd1b478a5104092dffeb (diff) | |
| download | zig-b0f031f5730be496872591dce3242004cf9a6f22.tar.gz zig-b0f031f5730be496872591dce3242004cf9a6f22.zip | |
Merge pull request #17523 from xxxbxxx/wasm-codegen
wasm codegen fixes
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index a898d18382..ebcccd781d 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -3602,11 +3602,6 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO return func.cmpBigInt(lhs, rhs, ty, op); } - // ensure that when we compare pointers, we emit - // the true pointer of a stack value, rather than the stack pointer. - try func.lowerToStack(lhs); - try func.lowerToStack(rhs); - const signedness: std.builtin.Signedness = blk: { // by default we tell the operand type is unsigned (i.e. bools and enum values) if (ty.zigTypeTag(mod) != .Int) break :blk .unsigned; @@ -3614,6 +3609,30 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO // incase of an actual integer, we emit the correct signedness break :blk ty.intInfo(mod).signedness; }; + const extend_sign = blk: { + // do we need to extend the sign bit? + if (signedness != .signed) break :blk false; + if (op == .eq or op == .neq) break :blk false; + const int_bits = ty.intInfo(mod).bits; + const wasm_bits = toWasmBits(int_bits) orelse unreachable; + break :blk (wasm_bits != int_bits); + }; + + const lhs_wasm = if (extend_sign) + try func.signExtendInt(lhs, ty) + else + lhs; + + const rhs_wasm = if (extend_sign) + try func.signExtendInt(rhs, ty) + else + rhs; + + // ensure that when we compare pointers, we emit + // the true pointer of a stack value, rather than the stack pointer. + try func.lowerToStack(lhs_wasm); + try func.lowerToStack(rhs_wasm); + const opcode: wasm.Opcode = buildOpcode(.{ .valtype1 = typeToValtype(ty, mod), .op = switch (op) { @@ -5331,17 +5350,17 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { else => { const result = try func.allocStack(result_ty); const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset + var prev_field_offset: u64 = 0; for (elements, 0..) |elem, elem_index| { if ((try result_ty.structFieldValueComptime(mod, elem_index)) != null) continue; const elem_ty = result_ty.structFieldType(elem_index, mod); - const elem_size: u32 = @intCast(elem_ty.abiSize(mod)); + const field_offset = result_ty.structFieldOffset(elem_index, mod); + _ = try func.buildPointerOffset(offset, @intCast(field_offset - prev_field_offset), .modify); + prev_field_offset = field_offset; + const value = try func.resolveInst(elem); try func.store(offset, value, elem_ty, 0); - - if (elem_index < elements.len - 1) { - _ = try func.buildPointerOffset(offset, elem_size, .modify); - } } break :result_value result; @@ -6920,12 +6939,13 @@ fn signedSat(func: *CodeGen, lhs_operand: WValue, rhs_operand: WValue, ty: Type, const int_info = ty.intInfo(mod); const wasm_bits = toWasmBits(int_info.bits).?; const is_wasm_bits = wasm_bits == int_info.bits; + const ext_ty = if (!is_wasm_bits) try mod.intType(int_info.signedness, wasm_bits) else ty; var lhs = if (!is_wasm_bits) lhs: { - break :lhs try (try func.signExtendInt(lhs_operand, ty)).toLocal(func, ty); + break :lhs try (try func.signExtendInt(lhs_operand, ty)).toLocal(func, ext_ty); } else lhs_operand; var rhs = if (!is_wasm_bits) rhs: { - break :rhs try (try func.signExtendInt(rhs_operand, ty)).toLocal(func, ty); + break :rhs try (try func.signExtendInt(rhs_operand, ty)).toLocal(func, ext_ty); } else rhs_operand; const max_val: u64 = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(int_info.bits - 1))) - 1)); @@ -6941,20 +6961,20 @@ fn signedSat(func: *CodeGen, lhs_operand: WValue, rhs_operand: WValue, ty: Type, else => unreachable, }; - var bin_result = try (try func.binOp(lhs, rhs, ty, op)).toLocal(func, ty); + var bin_result = try (try func.binOp(lhs, rhs, ext_ty, op)).toLocal(func, ext_ty); if (!is_wasm_bits) { defer bin_result.free(func); // not returned in this branch defer lhs.free(func); // uses temporary local for absvalue defer rhs.free(func); // uses temporary local for absvalue try func.emitWValue(bin_result); try func.emitWValue(max_wvalue); - _ = try func.cmp(bin_result, max_wvalue, ty, .lt); + _ = try func.cmp(bin_result, max_wvalue, ext_ty, .lt); try func.addTag(.select); try func.addLabel(.local_set, bin_result.local.value); // re-use local try func.emitWValue(bin_result); try func.emitWValue(min_wvalue); - _ = try func.cmp(bin_result, min_wvalue, ty, .gt); + _ = try func.cmp(bin_result, min_wvalue, ext_ty, .gt); try func.addTag(.select); try func.addLabel(.local_set, bin_result.local.value); // re-use local return (try func.wrapOperand(bin_result, ty)).toLocal(func, ty); @@ -7036,12 +7056,13 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { 64 => WValue{ .imm64 = shift_size }, else => unreachable, }; + const ext_ty = try mod.intType(int_info.signedness, wasm_bits); - var shl_res = try (try func.binOp(lhs, shift_value, ty, .shl)).toLocal(func, ty); + var shl_res = try (try func.binOp(lhs, shift_value, ext_ty, .shl)).toLocal(func, ext_ty); defer shl_res.free(func); - var shl = try (try func.binOp(shl_res, rhs, ty, .shl)).toLocal(func, ty); + var shl = try (try func.binOp(shl_res, rhs, ext_ty, .shl)).toLocal(func, ext_ty); defer shl.free(func); - var shr = try (try func.binOp(shl, rhs, ty, .shr)).toLocal(func, ty); + var shr = try (try func.binOp(shl, rhs, ext_ty, .shr)).toLocal(func, ext_ty); defer shr.free(func); switch (wasm_bits) { @@ -7053,7 +7074,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { try func.addImm32(std.math.minInt(i32)); try func.addImm32(std.math.maxInt(i32)); - _ = try func.cmp(shl_res, .{ .imm32 = 0 }, ty, .lt); + _ = try func.cmp(shl_res, .{ .imm32 = 0 }, ext_ty, .lt); try func.addTag(.select); }, 64 => blk: { @@ -7064,16 +7085,16 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { try func.addImm64(@as(u64, @bitCast(@as(i64, std.math.minInt(i64))))); try func.addImm64(@as(u64, @bitCast(@as(i64, std.math.maxInt(i64))))); - _ = try func.cmp(shl_res, .{ .imm64 = 0 }, ty, .lt); + _ = try func.cmp(shl_res, .{ .imm64 = 0 }, ext_ty, .lt); try func.addTag(.select); }, else => unreachable, } try func.emitWValue(shl); - _ = try func.cmp(shl_res, shr, ty, .neq); + _ = try func.cmp(shl_res, shr, ext_ty, .neq); try func.addTag(.select); try func.addLabel(.local_set, result.local.value); - var shift_result = try func.binOp(result, shift_value, ty, .shr); + var shift_result = try func.binOp(result, shift_value, ext_ty, .shr); if (is_signed) { shift_result = try func.wrapOperand(shift_result, ty); } |
