From 6e0debe287c7b0aac5d7f2889ab305d18df9bd2e Mon Sep 17 00:00:00 2001 From: Rerumu Date: Wed, 29 Jun 2022 23:53:02 -0400 Subject: [PATCH] Fix `i64` sign extension for `i32` --- codegen/luajit/runtime/runtime.lua | 14 +++++++----- codegen/luau/runtime/runtime.lua | 22 ++++++++++++++----- wasm-ast/src/node.rs | 35 ++++++++++++++++-------------- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/codegen/luajit/runtime/runtime.lua b/codegen/luajit/runtime/runtime.lua index 4d36e44..365b16e 100644 --- a/codegen/luajit/runtime/runtime.lua +++ b/codegen/luajit/runtime/runtime.lua @@ -331,7 +331,7 @@ do trunc.f32 = truncate trunc.f64 = truncate - function extend.i32_i8(num) + function extend.i32_n8(num) num = bit_and(num, 0xFF) if num >= 0x80 then @@ -341,7 +341,7 @@ do end end - function extend.i32_i16(num) + function extend.i32_n16(num) num = bit_and(num, 0xFFFF) if num >= 0x8000 then @@ -351,7 +351,7 @@ do end end - function extend.i64_i8(num) + function extend.i64_n8(num) num = bit_and(num, 0xFF) if num >= 0x80 then @@ -361,7 +361,7 @@ do end end - function extend.i64_i16(num) + function extend.i64_n16(num) num = bit_and(num, 0xFFFF) if num >= 0x8000 then @@ -371,7 +371,7 @@ do end end - function extend.i64_i32(num) + function extend.i64_n32(num) num = bit_and(num, 0xFFFFFFFF) if num >= 0x80000000 then @@ -381,7 +381,9 @@ do end end - function extend.u64_i32(num) + extend.i64_i32 = i64 + + function extend.i64_u32(num) RE_INSTANCE.i64 = ID_ZERO RE_INSTANCE.i32 = num diff --git a/codegen/luau/runtime/runtime.lua b/codegen/luau/runtime/runtime.lua index c032476..095d4d6 100644 --- a/codegen/luau/runtime/runtime.lua +++ b/codegen/luau/runtime/runtime.lua @@ -422,7 +422,7 @@ do trunc.f64 = trunc.f32 - function extend.i32_i8(num) + function extend.i32_n8(num) num = bit_and(num, 0xFF) if num >= 0x80 then @@ -432,7 +432,7 @@ do end end - function extend.i32_i16(num) + function extend.i32_n16(num) num = bit_and(num, 0xFFFF) if num >= 0x8000 then @@ -442,7 +442,7 @@ do end end - function extend.i64_i8(num) + function extend.i64_n8(num) local data_1, _ = num_into_u32(num) data_1 = bit_and(data_1, 0xFF) @@ -456,7 +456,7 @@ do end end - function extend.i64_i16(num) + function extend.i64_n16(num) local data_1, _ = num_into_u32(num) data_1 = bit_and(data_1, 0xFFFF) @@ -470,6 +470,18 @@ do end end + function extend.i64_n32(num) + local data_1, _ = num_into_u32(num) + + if data_1 >= 0x80000000 then + local temp = num_from_u32(-data_1 + 0x100000000, 0) + + return num_negate(temp) + else + return num_from_u32(data_1, 0) + end + end + function extend.i64_i32(num) if num >= 0x80000000 then local temp = num_from_u32(-num + 0x100000000, 0) @@ -480,7 +492,7 @@ do end end - function extend.u64_i32(num) + function extend.i64_u32(num) return num_from_u32(num, 0) end diff --git a/wasm-ast/src/node.rs b/wasm-ast/src/node.rs index 8281d5b..d39b1f9 100644 --- a/wasm-ast/src/node.rs +++ b/wasm-ast/src/node.rs @@ -151,12 +151,13 @@ pub enum UnOpType { Trunc_U32_F32, Trunc_I32_F64, Trunc_U32_F64, - Extend_I32_I8, - Extend_I32_I16, - Extend_I64_I8, - Extend_I64_I16, + Extend_I32_N8, + Extend_I32_N16, + Extend_I64_N8, + Extend_I64_N16, + Extend_I64_N32, Extend_I64_I32, - Extend_U64_I32, + Extend_I64_U32, Trunc_I64_F32, Trunc_U64_F32, Trunc_I64_F64, @@ -206,12 +207,13 @@ impl UnOpType { Self::Trunc_U32_F32 => ("trunc", "u32_f32"), Self::Trunc_I32_F64 => ("trunc", "i32_f64"), Self::Trunc_U32_F64 => ("trunc", "u32_f64"), - Self::Extend_I32_I8 => ("extend", "i32_i8"), - Self::Extend_I32_I16 => ("extend", "i32_i16"), - Self::Extend_I64_I8 => ("extend", "i64_i8"), - Self::Extend_I64_I16 => ("extend", "i64_i16"), + Self::Extend_I32_N8 => ("extend", "i32_n8"), + Self::Extend_I32_N16 => ("extend", "i32_n16"), + Self::Extend_I64_N8 => ("extend", "i64_n8"), + Self::Extend_I64_N16 => ("extend", "i64_n16"), + Self::Extend_I64_N32 => ("extend", "i64_n32"), Self::Extend_I64_I32 => ("extend", "i64_i32"), - Self::Extend_U64_I32 => ("extend", "u64_i32"), + Self::Extend_I64_U32 => ("extend", "i64_u32"), Self::Trunc_I64_F32 => ("trunc", "i64_f32"), Self::Trunc_U64_F32 => ("trunc", "u64_f32"), Self::Trunc_I64_F64 => ("trunc", "i64_f64"), @@ -264,12 +266,13 @@ impl TryFrom<&Operator<'_>> for UnOpType { Operator::I32TruncF32U => Self::Trunc_U32_F32, Operator::I32TruncF64S => Self::Trunc_I32_F64, Operator::I32TruncF64U => Self::Trunc_U32_F64, - Operator::I32Extend8S => Self::Extend_I32_I8, - Operator::I32Extend16S => Self::Extend_I32_I16, - Operator::I64Extend8S => Self::Extend_I64_I8, - Operator::I64Extend16S => Self::Extend_I64_I16, - Operator::I64Extend32S | Operator::I64ExtendI32S => Self::Extend_I64_I32, - Operator::I64ExtendI32U => Self::Extend_U64_I32, + Operator::I32Extend8S => Self::Extend_I32_N8, + Operator::I32Extend16S => Self::Extend_I32_N16, + Operator::I64Extend8S => Self::Extend_I64_N8, + Operator::I64Extend16S => Self::Extend_I64_N16, + Operator::I64Extend32S => Self::Extend_I64_N32, + Operator::I64ExtendI32S => Self::Extend_I64_I32, + Operator::I64ExtendI32U => Self::Extend_I64_U32, Operator::I64TruncF32S => Self::Trunc_I64_F32, Operator::I64TruncF32U => Self::Trunc_U64_F32, Operator::I64TruncF64S => Self::Trunc_I64_F64,