From 95ef7e776e33886a042ce5aa101ee3e614d15c5b Mon Sep 17 00:00:00 2001 From: Clemens Hammacher Date: Wed, 14 Mar 2018 11:24:18 +0100 Subject: [PATCH] [Liftoff] Implement reinterpretations This adds support for i32.reinterpret/f32, i64.reinterpret/f64, f32.reinterpret/i32, and f64.reinterpret/i64. On x64, all operations are straight-forward. On ia32, conversions from or to i64 are done via the stack. R=titzer@chromium.org Bug: v8:6600 Change-Id: If5562caf7367726904c6e405ad4fc5436d21144e Reviewed-on: https://chromium-review.googlesource.com/962224 Reviewed-by: Ben Titzer Commit-Queue: Clemens Hammacher Cr-Commit-Position: refs/heads/master@{#51920} --- .../baseline/ia32/liftoff-assembler-ia32.h | 22 +++++++++++++++++++ src/wasm/baseline/liftoff-compiler.cc | 4 ++++ src/wasm/baseline/x64/liftoff-assembler-x64.h | 12 ++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/wasm/baseline/ia32/liftoff-assembler-ia32.h b/src/wasm/baseline/ia32/liftoff-assembler-ia32.h index 3995c2698f..cbd65ada64 100644 --- a/src/wasm/baseline/ia32/liftoff-assembler-ia32.h +++ b/src/wasm/baseline/ia32/liftoff-assembler-ia32.h @@ -696,6 +696,17 @@ bool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode, LiftoffRegister dst, LiftoffRegister src) { switch (opcode) { + case kExprI32ReinterpretF32: + Movd(dst.gp(), src.fp()); + return true; + case kExprI64ReinterpretF64: + // Push src to the stack. + sub(esp, Immediate(8)); + movsd(Operand(esp, 0), src.fp()); + // Pop to dst. + pop(dst.low_gp()); + pop(dst.high_gp()); + return true; case kExprF32SConvertI32: cvtsi2ss(dst.fp(), src.gp()); return true; @@ -708,6 +719,9 @@ bool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode, case kExprF32ConvertF64: cvtsd2ss(dst.fp(), src.fp()); return true; + case kExprF32ReinterpretI32: + Movd(dst.fp(), src.gp()); + return true; case kExprF64SConvertI32: Cvtsi2sd(dst.fp(), src.gp()); return true; @@ -717,6 +731,14 @@ bool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode, case kExprF64ConvertF32: cvtss2sd(dst.fp(), src.fp()); return true; + case kExprF64ReinterpretI64: + // Push src to the stack. + push(src.high_gp()); + push(src.low_gp()); + // Pop to dst. + movsd(dst.fp(), Operand(esp, 0)); + add(esp, Immediate(8)); + return true; default: return false; } diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index 302c6defd3..957003ecf3 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -625,6 +625,8 @@ class LiftoffCompiler { CASE_FLOAT_UNOP(F32Sqrt, F32, f32_sqrt) CASE_FLOAT_UNOP(F64Neg, F64, f64_neg) CASE_FLOAT_UNOP(F64Sqrt, F64, f64_sqrt) + CASE_TYPE_CONVERSION(I32ReinterpretF32, I32, F32, nullptr) + CASE_TYPE_CONVERSION(I64ReinterpretF64, I64, F64, nullptr) CASE_TYPE_CONVERSION(F32SConvertI32, F32, I32, nullptr) CASE_TYPE_CONVERSION(F32UConvertI32, F32, I32, nullptr) CASE_TYPE_CONVERSION(F32SConvertI64, F32, I64, @@ -632,6 +634,7 @@ class LiftoffCompiler { CASE_TYPE_CONVERSION(F32UConvertI64, F32, I64, &ExternalReference::wasm_uint64_to_float32) CASE_TYPE_CONVERSION(F32ConvertF64, F32, F64, nullptr) + CASE_TYPE_CONVERSION(F32ReinterpretI32, F32, I32, nullptr) CASE_TYPE_CONVERSION(F64SConvertI32, F64, I32, nullptr) CASE_TYPE_CONVERSION(F64UConvertI32, F64, I32, nullptr) CASE_TYPE_CONVERSION(F64SConvertI64, F64, I64, @@ -639,6 +642,7 @@ class LiftoffCompiler { CASE_TYPE_CONVERSION(F64UConvertI64, F64, I64, &ExternalReference::wasm_uint64_to_float64) CASE_TYPE_CONVERSION(F64ConvertF32, F64, F32, nullptr) + CASE_TYPE_CONVERSION(F64ReinterpretI64, F64, I64, nullptr) default: return unsupported(decoder, WasmOpcodes::OpcodeName(opcode)); } diff --git a/src/wasm/baseline/x64/liftoff-assembler-x64.h b/src/wasm/baseline/x64/liftoff-assembler-x64.h index 8545157190..af49d9b506 100644 --- a/src/wasm/baseline/x64/liftoff-assembler-x64.h +++ b/src/wasm/baseline/x64/liftoff-assembler-x64.h @@ -643,6 +643,12 @@ bool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode, LiftoffRegister dst, LiftoffRegister src) { switch (opcode) { + case kExprI32ReinterpretF32: + Movd(dst.gp(), src.fp()); + return true; + case kExprI64ReinterpretF64: + Movq(dst.gp(), src.fp()); + return true; case kExprF32SConvertI32: Cvtlsi2ss(dst.fp(), src.gp()); return true; @@ -659,6 +665,9 @@ bool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode, case kExprF32ConvertF64: Cvtsd2ss(dst.fp(), src.fp()); return true; + case kExprF32ReinterpretI32: + Movd(dst.fp(), src.gp()); + return true; case kExprF64SConvertI32: Cvtlsi2sd(dst.fp(), src.gp()); return true; @@ -675,6 +684,9 @@ bool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode, case kExprF64ConvertF32: Cvtss2sd(dst.fp(), src.fp()); return true; + case kExprF64ReinterpretI64: + Movq(dst.fp(), src.gp()); + return true; default: UNREACHABLE(); }