[wasm] Backoff implementation for F64Trunc using std::trunc.
R=titzer@chromium.org Review URL: https://codereview.chromium.org/1638283004 Cr-Commit-Position: refs/heads/master@{#33670}
This commit is contained in:
parent
7feaf896bb
commit
3f4163cd24
@ -34,6 +34,7 @@
|
||||
|
||||
#include "src/assembler.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include "src/api.h"
|
||||
#include "src/base/cpu.h"
|
||||
@ -1131,6 +1132,12 @@ ExternalReference ExternalReference::compute_output_frames_function(
|
||||
Redirect(isolate, FUNCTION_ADDR(Deoptimizer::ComputeOutputFrames)));
|
||||
}
|
||||
|
||||
static void trunc64_wrapper(double* param) { *param = trunc(*param); }
|
||||
|
||||
ExternalReference ExternalReference::trunc64_wrapper_function(
|
||||
Isolate* isolate) {
|
||||
return ExternalReference(Redirect(isolate, FUNCTION_ADDR(trunc64_wrapper)));
|
||||
}
|
||||
|
||||
ExternalReference ExternalReference::log_enter_external_function(
|
||||
Isolate* isolate) {
|
||||
|
@ -913,6 +913,8 @@ class ExternalReference BASE_EMBEDDED {
|
||||
static ExternalReference new_deoptimizer_function(Isolate* isolate);
|
||||
static ExternalReference compute_output_frames_function(Isolate* isolate);
|
||||
|
||||
static ExternalReference trunc64_wrapper_function(Isolate* isolate);
|
||||
|
||||
// Log support.
|
||||
static ExternalReference log_enter_external_function(Isolate* isolate);
|
||||
static ExternalReference log_leave_external_function(Isolate* isolate);
|
||||
|
@ -795,13 +795,9 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
|
||||
}
|
||||
}
|
||||
case wasm::kExprF64Trunc: {
|
||||
if (m->Float64RoundTruncate().IsSupported()) {
|
||||
op = m->Float64RoundTruncate().op();
|
||||
break;
|
||||
} else {
|
||||
op = UnsupportedOpcode(opcode);
|
||||
break;
|
||||
}
|
||||
if (!m->Float64RoundTruncate().IsSupported()) return BuildF64Trunc(input);
|
||||
op = m->Float64RoundTruncate().op();
|
||||
break;
|
||||
}
|
||||
case wasm::kExprF64NearestInt: {
|
||||
if (m->Float64RoundTiesEven().IsSupported()) {
|
||||
@ -1436,6 +1432,60 @@ Node* WasmGraphBuilder::BuildF32Trunc(Node* input) {
|
||||
return Unop(wasm::kExprF32ReinterpretI32, result);
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildF64Trunc(Node* input) {
|
||||
// We do truncation by calling a C function which calculates the truncation
|
||||
// for us. The input is passed to the C function as a double* to avoid double
|
||||
// parameters. For this we reserve a slot on the stack, store the parameter in
|
||||
// that slot, pass a pointer to the slot to the C function, and after calling
|
||||
// the C function we collect the return value from the stack slot.
|
||||
|
||||
Node* stack_slot_param = graph()->NewNode(
|
||||
jsgraph()->machine()->StackSlot(MachineRepresentation::kFloat64));
|
||||
|
||||
const Operator* store_op = jsgraph()->machine()->Store(
|
||||
StoreRepresentation(MachineRepresentation::kFloat64, kNoWriteBarrier));
|
||||
*effect_ =
|
||||
graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0),
|
||||
input, *effect_, *control_);
|
||||
|
||||
Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0, 1);
|
||||
sig_builder.AddParam(MachineType::Pointer());
|
||||
Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(
|
||||
ExternalReference::trunc64_wrapper_function(jsgraph()->isolate())));
|
||||
|
||||
Node* args[] = {function, stack_slot_param};
|
||||
|
||||
BuildCCall(sig_builder.Build(), args);
|
||||
|
||||
const Operator* load_op = jsgraph()->machine()->Load(MachineType::Float64());
|
||||
|
||||
Node* load =
|
||||
graph()->NewNode(load_op, stack_slot_param, jsgraph()->Int32Constant(0),
|
||||
*effect_, *control_);
|
||||
*effect_ = load;
|
||||
return load;
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
|
||||
const size_t params = sig->parameter_count();
|
||||
const size_t extra = 2; // effect and control inputs.
|
||||
const size_t count = 1 + params + extra;
|
||||
|
||||
// Reallocate the buffer to make space for extra inputs.
|
||||
args = Realloc(args, count);
|
||||
|
||||
// Add effect and control inputs.
|
||||
args[params + 1] = *effect_;
|
||||
args[params + 2] = *control_;
|
||||
|
||||
CallDescriptor* desc =
|
||||
Linkage::GetSimplifiedCDescriptor(jsgraph()->zone(), sig);
|
||||
|
||||
const Operator* op = jsgraph()->common()->Call(desc);
|
||||
Node* call = graph()->NewNode(op, static_cast<int>(count), args);
|
||||
*effect_ = call;
|
||||
return call;
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args) {
|
||||
const size_t params = sig->parameter_count();
|
||||
|
@ -159,6 +159,7 @@ class WasmGraphBuilder {
|
||||
Node* MemBuffer(uint32_t offset);
|
||||
void BoundsCheckMem(MachineType memtype, Node* index, uint32_t offset);
|
||||
|
||||
Node* BuildCCall(MachineSignature* sig, Node** args);
|
||||
Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args);
|
||||
Node* BuildF32Neg(Node* input);
|
||||
Node* BuildF64Neg(Node* input);
|
||||
@ -177,6 +178,7 @@ class WasmGraphBuilder {
|
||||
Node* BuildI64Ctz(Node* input);
|
||||
Node* BuildI64Popcnt(Node* input);
|
||||
Node* BuildF32Trunc(Node* input);
|
||||
Node* BuildF64Trunc(Node* input);
|
||||
|
||||
Node** Realloc(Node** buffer, size_t count) {
|
||||
Node** buf = Buffer(count);
|
||||
|
@ -264,6 +264,7 @@ CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone,
|
||||
// The target for WASM calls is always a code object.
|
||||
MachineType target_type = MachineType::AnyTagged();
|
||||
LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
|
||||
|
||||
return new (zone) CallDescriptor( // --
|
||||
CallDescriptor::kCallCodeObject, // kind
|
||||
target_type, // target MachineType
|
||||
|
@ -119,6 +119,8 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
|
||||
"InvokeFunctionCallback");
|
||||
Add(ExternalReference::invoke_accessor_getter_callback(isolate).address(),
|
||||
"InvokeAccessorGetterCallback");
|
||||
Add(ExternalReference::trunc64_wrapper_function(isolate).address(),
|
||||
"trunc64_wrapper");
|
||||
Add(ExternalReference::log_enter_external_function(isolate).address(),
|
||||
"Logger::EnterExternal");
|
||||
Add(ExternalReference::log_leave_external_function(isolate).address(),
|
||||
|
@ -5588,6 +5588,19 @@ TEST(RunCallCFunction8) {
|
||||
}
|
||||
#endif // USE_SIMULATOR
|
||||
|
||||
TEST(RunCallExternalReferenceF64Trunc) {
|
||||
BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
|
||||
Node* stack_slot = m.StackSlot(MachineRepresentation::kFloat64);
|
||||
m.Store(MachineRepresentation::kFloat64, stack_slot, m.Parameter(0),
|
||||
WriteBarrierKind::kNoWriteBarrier);
|
||||
Node* function = m.ExternalConstant(
|
||||
ExternalReference::trunc64_wrapper_function(m.isolate()));
|
||||
m.CallCFunction1(MachineType::Pointer(), MachineType::Pointer(), function,
|
||||
stack_slot);
|
||||
m.Return(m.Load(MachineType::Float64(), stack_slot));
|
||||
FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(trunc(*i), m.Call(*i)); }
|
||||
}
|
||||
|
||||
#if V8_TARGET_ARCH_64_BIT
|
||||
// TODO(titzer): run int64 tests on all platforms when supported.
|
||||
TEST(RunCheckedLoadInt64) {
|
||||
|
@ -3006,14 +3006,6 @@ TEST(Run_Wasm_F64Ceil) {
|
||||
}
|
||||
|
||||
|
||||
TEST(Run_Wasm_F64Trunc) {
|
||||
WasmRunner<double> r(MachineType::Float64());
|
||||
BUILD(r, WASM_F64_TRUNC(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(trunc(*i), r.Call(*i)); }
|
||||
}
|
||||
|
||||
|
||||
TEST(Run_Wasm_F64NearestInt) {
|
||||
WasmRunner<double> r(MachineType::Float64());
|
||||
BUILD(r, WASM_F64_NEARESTINT(WASM_GET_LOCAL(0)));
|
||||
@ -3023,6 +3015,12 @@ TEST(Run_Wasm_F64NearestInt) {
|
||||
|
||||
#endif
|
||||
|
||||
TEST(Run_Wasm_F64Trunc) {
|
||||
WasmRunner<double> r(MachineType::Float64());
|
||||
BUILD(r, WASM_F64_TRUNC(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(trunc(*i), r.Call(*i)); }
|
||||
}
|
||||
|
||||
TEST(Run_Wasm_F32Min) {
|
||||
WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
|
||||
|
Loading…
Reference in New Issue
Block a user