Commit 8f0cd1c2 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[turbofan] Fix passing float parameters on the stack

There was an issue with passing float32 parameters, if the value was
spilled on the stack and passed as stack parameter.
First, we sometimes reduced the stack pointer by 8 bytes instead of 4,
and second, there was a mismatch between movsd and movss.

R=titzer@chromium.org

Bug: chromium:718858
Change-Id: Ia884df369ddd95adeff3733f9715f589996f0b65
Also-By: ahaas@chromium.org
Reviewed-on: https://chromium-review.googlesource.com/684738Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48181}
parent fb35717f
......@@ -1921,15 +1921,15 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ movss(Operand(esp, 0), i.InputDoubleRegister(0));
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
} else if (HasImmediateInput(instr, 0)) {
__ Move(kScratchDoubleReg, i.InputDouble(0));
__ sub(esp, Immediate(kDoubleSize));
__ Move(kScratchDoubleReg, i.InputFloat32(0));
__ sub(esp, Immediate(kFloatSize));
__ movss(Operand(esp, 0), kScratchDoubleReg);
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
} else {
__ movsd(kScratchDoubleReg, i.InputOperand(0));
__ sub(esp, Immediate(kDoubleSize));
__ movss(kScratchDoubleReg, i.InputOperand(0));
__ sub(esp, Immediate(kFloatSize));
__ movss(Operand(esp, 0), kScratchDoubleReg);
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
}
break;
case kIA32PushFloat64:
......
// Copyright 2017 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');
let types = [kWasmI32, kWasmF32, kWasmF64];
let type_names = ["i32", "f32", "f64"];
let type_const = [wasmI32Const, wasmF32Const, wasmF64Const];
function f(values, shift, num_const_params, ...args) {
assertEquals(
values.length + num_const_params, args.length, 'number of arguments');
args.forEach((arg_val, idx) => {
const expected =
idx < values.length ? values[(idx + shift) % values.length] : idx;
assertEquals(expected, arg_val, 'arg #' + idx + ', shifted by ' + shift);
});
}
types.forEach((type, type_idx) => {
for (let num_params = 3; num_params < 32; num_params += 4) {
print(
'Testing ' + num_params + ' parameters of type ' +
type_names[type_idx] + '...');
for (let num_const_params = 0; num_const_params <= 3; ++num_const_params) {
for (let shift = 2; shift <= 5; shift += 3) {
let builder = new WasmModuleBuilder();
let params_outer = new Array(num_params).fill(type);
sig_outer = makeSig(params_outer, []);
let params_inner = new Array(num_params + num_const_params).fill(type);
sig_inner = makeSig(params_inner, []);
let body = [];
for (let i = 0; i < num_params; ++i)
body.push(kExprGetLocal, (i + shift) % num_params);
for (let i = 0; i < num_const_params; ++i)
body.push(...type_const[type_idx](num_params + i));
body.push(kExprCallFunction, 0);
builder.addImport('', 'f', sig_inner);
builder.addFunction(undefined, sig_outer)
.addBody(body)
.exportAs('main');
let values = new Array(num_params).fill(0).map((_, i) => 123 - 3 * i);
instance = builder.instantiate(
{'': {'f': f.bind(null, values, shift, num_const_params)}});
instance.exports.main(...values);
}
}
}
});
......@@ -414,3 +414,20 @@ function assertWasmThrows(runtime_id, values, code) {
}
throw new MjsUnitAssertionError('Did not throw expected: ' + runtime_id + values);
}
function wasmI32Const(val) {
let bytes = [kExprI32Const];
for (let i = 0; i < 4; ++i) {
bytes.push(0x80 | ((val >> (7 * i)) & 0x7f));
}
bytes.push((val >> (7 * 4)) & 0x7f);
return bytes;
}
function wasmF32Const(f) {
return [kExprF32Const].concat(Array.from(new Uint8Array((new Float32Array([f])).buffer)));
}
function wasmF64Const(f) {
return [kExprF64Const].concat(Array.from(new Uint8Array((new Float64Array([f])).buffer)));
}
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