Commit 27e36250 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[Liftoff][x64] Fix and optimize spilling i64 constants

There was a bug in spilling i64 constants, in that the half stack slot
*above* should have been filled with the high word instead of the one *below*.

Instead of just fixing this, this CL optimizes spilling x64 constants to the
stack by emitting shorter and faster code, especially if the constant fits in
31 bits (which is the majority of cases).

R=titzer@chromium.org

Bug: v8:7565,v8:6600
Change-Id: Id75ddafe82615930a84333a0c49bd515ccbcc093
Reviewed-on: https://chromium-review.googlesource.com/965062Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51985}
parent 51c79bc4
......@@ -27,11 +27,6 @@ inline Operand GetStackSlot(uint32_t index) {
return Operand(rbp, -kFirstStackSlotOffset - offset);
}
inline Operand GetHalfStackSlot(uint32_t half_index) {
int32_t offset = half_index * (LiftoffAssembler::kStackSlotSize / 2);
return Operand(rbp, -kFirstStackSlotOffset - offset);
}
// TODO(clemensh): Make this a constexpr variable once Operand is constexpr.
inline Operand GetContextOperand() { return Operand(rbp, -16); }
......@@ -325,13 +320,17 @@ void LiftoffAssembler::Spill(uint32_t index, WasmValue value) {
movl(dst, Immediate(value.to_i32()));
break;
case kWasmI64: {
// We could use movq, but this would require a temporary register. For
// simplicity (and to avoid potentially having to spill another register),
// we use two movl instructions.
int32_t low_word = static_cast<int32_t>(value.to_i64());
int32_t high_word = static_cast<int32_t>(value.to_i64() >> 32);
movl(dst, Immediate(low_word));
movl(liftoff::GetHalfStackSlot(2 * index + 1), Immediate(high_word));
if (is_int32(value.to_i64())) {
// Sign extend low word.
movq(dst, Immediate(static_cast<int32_t>(value.to_i64())));
} else if (is_uint32(value.to_i64())) {
// Zero extend low word.
movl(kScratchRegister, Immediate(static_cast<int32_t>(value.to_i64())));
movq(dst, kScratchRegister);
} else {
movq(kScratchRegister, value.to_i64());
movq(dst, kScratchRegister);
}
break;
}
default:
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
sig0 = makeSig([], [kWasmI32]);
builder.addFunction(undefined, sig0).addLocals({i64_count: 1}).addBody([
kExprLoop, kWasmI32, // loop i32
kExprF32Const, 0x00, 0x00, 0x00, 0x00, // f32.const 0 --> f32:0
kExprGetLocal, 0x00, // get_local 0 --> i64:0
kExprF32SConvertI64, // f32.sconvert/i64 --> f32:0
kExprF32Ge, // f32.ge --> i32:1
kExprEnd, // end
]);
builder.addExport('main', 0);
const module = builder.instantiate();
assertEquals(1, module.exports.main());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment