aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/wasm/CodeGen.zig16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index 14d2cf95c4..af54043f7a 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -4160,7 +4160,7 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const op_bits = toWasmBits(@as(u16, @intCast(operand_ty.bitSize(mod)))).?;
const wanted_bits = toWasmBits(@as(u16, @intCast(ty.bitSize(mod)))).?;
- const result = if (op_bits == wanted_bits)
+ const result = if (op_bits == wanted_bits and !ty.isSignedInt(mod))
func.reuseOperand(ty_op.operand, operand)
else
try (try func.intcast(operand, operand_ty, ty)).toLocal(func, ty);
@@ -4181,7 +4181,19 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
const op_bits = toWasmBits(given_bitsize).?;
const wanted_bits = toWasmBits(wanted_bitsize).?;
- if (op_bits == wanted_bits) return operand;
+ if (op_bits == wanted_bits) {
+ if (given.isSignedInt(mod)) {
+ if (given_bitsize < wanted_bitsize) {
+ // signed integers are stored as two's complement,
+ // when we upcast from a smaller integer to larger
+ // integers, we must get its absolute value similar to
+ // i64_extend_i32_s instruction.
+ return func.signAbsValue(operand, given);
+ }
+ return func.wrapOperand(operand, wanted);
+ }
+ return operand;
+ }
if (op_bits > 32 and op_bits <= 64 and wanted_bits == 32) {
try func.emitWValue(operand);