[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/684738 Reviewed-by: Andreas Haas <ahaas@chromium.org> Reviewed-by: Ben Titzer <titzer@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#48181}
This commit is contained in:
parent
fb35717fde
commit
8f0cd1c244
@ -1921,15 +1921,15 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
|||||||
__ movss(Operand(esp, 0), i.InputDoubleRegister(0));
|
__ movss(Operand(esp, 0), i.InputDoubleRegister(0));
|
||||||
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
|
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
|
||||||
} else if (HasImmediateInput(instr, 0)) {
|
} else if (HasImmediateInput(instr, 0)) {
|
||||||
__ Move(kScratchDoubleReg, i.InputDouble(0));
|
__ Move(kScratchDoubleReg, i.InputFloat32(0));
|
||||||
__ sub(esp, Immediate(kDoubleSize));
|
__ sub(esp, Immediate(kFloatSize));
|
||||||
__ movss(Operand(esp, 0), kScratchDoubleReg);
|
__ movss(Operand(esp, 0), kScratchDoubleReg);
|
||||||
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
|
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
|
||||||
} else {
|
} else {
|
||||||
__ movsd(kScratchDoubleReg, i.InputOperand(0));
|
__ movss(kScratchDoubleReg, i.InputOperand(0));
|
||||||
__ sub(esp, Immediate(kDoubleSize));
|
__ sub(esp, Immediate(kFloatSize));
|
||||||
__ movss(Operand(esp, 0), kScratchDoubleReg);
|
__ movss(Operand(esp, 0), kScratchDoubleReg);
|
||||||
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
|
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kIA32PushFloat64:
|
case kIA32PushFloat64:
|
||||||
|
55
test/mjsunit/wasm/many-parameters.js
Normal file
55
test/mjsunit/wasm/many-parameters.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// 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);
|
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)));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user