| Index: src/compiler/wasm-compiler.cc
|
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
|
| index e25a72809c0e1d2644e72baf10b9c5d1ec7db0a1..bc37ce30abb2d477dcb4298182dfe7c69f7c29a9 100644
|
| --- a/src/compiler/wasm-compiler.cc
|
| +++ b/src/compiler/wasm-compiler.cc
|
| @@ -697,6 +697,15 @@ Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left,
|
| return BuildF32Max(left, right);
|
| case wasm::kExprF64Max:
|
| return BuildF64Max(left, right);
|
| + case wasm::kExprF64Pow: {
|
| + return BuildF64Pow(left, right);
|
| + }
|
| + case wasm::kExprF64Atan2: {
|
| + return BuildF64Atan2(left, right);
|
| + }
|
| + case wasm::kExprF64Mod: {
|
| + return BuildF64Mod(left, right);
|
| + }
|
| default:
|
| op = UnsupportedOpcode(opcode);
|
| }
|
| @@ -824,6 +833,30 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
|
| op = m->Float64RoundTiesEven().op();
|
| break;
|
| }
|
| + case wasm::kExprF64Acos: {
|
| + return BuildF64Acos(input);
|
| + }
|
| + case wasm::kExprF64Asin: {
|
| + return BuildF64Asin(input);
|
| + }
|
| + case wasm::kExprF64Atan: {
|
| + return BuildF64Atan(input);
|
| + }
|
| + case wasm::kExprF64Cos: {
|
| + return BuildF64Cos(input);
|
| + }
|
| + case wasm::kExprF64Sin: {
|
| + return BuildF64Sin(input);
|
| + }
|
| + case wasm::kExprF64Tan: {
|
| + return BuildF64Tan(input);
|
| + }
|
| + case wasm::kExprF64Exp: {
|
| + return BuildF64Exp(input);
|
| + }
|
| + case wasm::kExprF64Log: {
|
| + return BuildF64Log(input);
|
| + }
|
| case wasm::kExprI32ConvertI64:
|
| op = m->TruncateInt64ToInt32();
|
| break;
|
| @@ -1418,88 +1451,185 @@ Node* WasmGraphBuilder::BuildF32Trunc(Node* input) {
|
| MachineType type = MachineType::Float32();
|
| ExternalReference ref =
|
| ExternalReference::f32_trunc_wrapper_function(jsgraph()->isolate());
|
| - return BuildRoundingInstruction(input, ref, type);
|
| + return BuildCFuncInstruction(ref, type, input);
|
| }
|
|
|
| Node* WasmGraphBuilder::BuildF32Floor(Node* input) {
|
| MachineType type = MachineType::Float32();
|
| ExternalReference ref =
|
| ExternalReference::f32_floor_wrapper_function(jsgraph()->isolate());
|
| - return BuildRoundingInstruction(input, ref, type);
|
| + return BuildCFuncInstruction(ref, type, input);
|
| }
|
|
|
| Node* WasmGraphBuilder::BuildF32Ceil(Node* input) {
|
| MachineType type = MachineType::Float32();
|
| ExternalReference ref =
|
| ExternalReference::f32_ceil_wrapper_function(jsgraph()->isolate());
|
| - return BuildRoundingInstruction(input, ref, type);
|
| + return BuildCFuncInstruction(ref, type, input);
|
| }
|
|
|
| Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) {
|
| MachineType type = MachineType::Float32();
|
| ExternalReference ref =
|
| ExternalReference::f32_nearest_int_wrapper_function(jsgraph()->isolate());
|
| - return BuildRoundingInstruction(input, ref, type);
|
| + return BuildCFuncInstruction(ref, type, input);
|
| }
|
|
|
| Node* WasmGraphBuilder::BuildF64Trunc(Node* input) {
|
| MachineType type = MachineType::Float64();
|
| ExternalReference ref =
|
| ExternalReference::f64_trunc_wrapper_function(jsgraph()->isolate());
|
| - return BuildRoundingInstruction(input, ref, type);
|
| + return BuildCFuncInstruction(ref, type, input);
|
| }
|
|
|
| Node* WasmGraphBuilder::BuildF64Floor(Node* input) {
|
| MachineType type = MachineType::Float64();
|
| ExternalReference ref =
|
| ExternalReference::f64_floor_wrapper_function(jsgraph()->isolate());
|
| - return BuildRoundingInstruction(input, ref, type);
|
| + return BuildCFuncInstruction(ref, type, input);
|
| }
|
|
|
| Node* WasmGraphBuilder::BuildF64Ceil(Node* input) {
|
| MachineType type = MachineType::Float64();
|
| ExternalReference ref =
|
| ExternalReference::f64_ceil_wrapper_function(jsgraph()->isolate());
|
| - return BuildRoundingInstruction(input, ref, type);
|
| + return BuildCFuncInstruction(ref, type, input);
|
| }
|
|
|
| Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) {
|
| MachineType type = MachineType::Float64();
|
| ExternalReference ref =
|
| ExternalReference::f64_nearest_int_wrapper_function(jsgraph()->isolate());
|
| - return BuildRoundingInstruction(input, ref, type);
|
| + return BuildCFuncInstruction(ref, type, input);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildF64Acos(Node* input) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_acos_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, input);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildF64Asin(Node* input) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_asin_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, input);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildF64Atan(Node* input) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_atan_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, input);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildF64Cos(Node* input) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_cos_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, input);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildF64Sin(Node* input) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_sin_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, input);
|
| }
|
|
|
| -Node* WasmGraphBuilder::BuildRoundingInstruction(Node* input,
|
| - ExternalReference ref,
|
| - MachineType type) {
|
| - // 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* WasmGraphBuilder::BuildF64Tan(Node* input) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_tan_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, input);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildF64Exp(Node* input) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_exp_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, input);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildF64Log(Node* input) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_log_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, input);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildF64Atan2(Node* left, Node* right) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_atan2_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, left, right);
|
| +}
|
|
|
| - Node* stack_slot_param =
|
| +Node* WasmGraphBuilder::BuildF64Pow(Node* left, Node* right) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_pow_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, left, right);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildF64Mod(Node* left, Node* right) {
|
| + MachineType type = MachineType::Float64();
|
| + ExternalReference ref =
|
| + ExternalReference::f64_mod_wrapper_function(jsgraph()->isolate());
|
| + return BuildCFuncInstruction(ref, type, left, right);
|
| +}
|
| +
|
| +Node* WasmGraphBuilder::BuildCFuncInstruction(ExternalReference ref,
|
| + MachineType type, Node* input0,
|
| + Node* input1) {
|
| + // We do truncation by calling a C function which calculates the result.
|
| + // The input is passed to the C function as a double*'s to avoid double
|
| + // parameters. For this we reserve slots on the stack, store the parameters
|
| + // in those slots, pass pointers 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_param0 =
|
| graph()->NewNode(jsgraph()->machine()->StackSlot(type.representation()));
|
|
|
| - const Operator* store_op = jsgraph()->machine()->Store(
|
| + const Operator* store_op0 = jsgraph()->machine()->Store(
|
| StoreRepresentation(type.representation(), kNoWriteBarrier));
|
| - *effect_ =
|
| - graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0),
|
| - input, *effect_, *control_);
|
| + *effect_ = graph()->NewNode(store_op0, stack_slot_param0,
|
| + jsgraph()->Int32Constant(0), input0, *effect_,
|
| + *control_);
|
|
|
| - Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0, 1);
|
| - sig_builder.AddParam(MachineType::Pointer());
|
| Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
|
| + Node** args = Buffer(4);
|
| + args[0] = function;
|
| + args[1] = stack_slot_param0;
|
| + int input_count = 1;
|
| +
|
| + if (input1 != nullptr) {
|
| + Node* stack_slot_param1 = graph()->NewNode(
|
| + jsgraph()->machine()->StackSlot(type.representation()));
|
| + const Operator* store_op1 = jsgraph()->machine()->Store(
|
| + StoreRepresentation(type.representation(), kNoWriteBarrier));
|
| + *effect_ = graph()->NewNode(store_op1, stack_slot_param1,
|
| + jsgraph()->Int32Constant(0), input1, *effect_,
|
| + *control_);
|
| + args = Realloc(args, 5);
|
| + args[2] = stack_slot_param1;
|
| + ++input_count;
|
| + }
|
|
|
| - Node* args[] = {function, stack_slot_param};
|
| -
|
| + Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0,
|
| + input_count);
|
| + sig_builder.AddParam(MachineType::Pointer());
|
| + if (input1 != nullptr) {
|
| + sig_builder.AddParam(MachineType::Pointer());
|
| + }
|
| BuildCCall(sig_builder.Build(), args);
|
|
|
| const Operator* load_op = jsgraph()->machine()->Load(type);
|
|
|
| Node* load =
|
| - graph()->NewNode(load_op, stack_slot_param, jsgraph()->Int32Constant(0),
|
| + graph()->NewNode(load_op, stack_slot_param0, jsgraph()->Int32Constant(0),
|
| *effect_, *control_);
|
| *effect_ = load;
|
| return load;
|
| @@ -1547,7 +1677,6 @@ Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args) {
|
| return call;
|
| }
|
|
|
| -
|
| Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args) {
|
| DCHECK_NULL(args[0]);
|
|
|
|
|