[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 <titzer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51920}
This commit is contained in:
Clemens Hammacher 2018-03-14 11:24:18 +01:00 committed by Commit Bot
parent b5da57a06d
commit 95ef7e776e
3 changed files with 38 additions and 0 deletions

View File

@ -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;
}

View File

@ -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));
}

View File

@ -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();
}