| Index: src/compiler/wasm-compiler.cc | 
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc | 
| index dd0dfe3873bca5de94a28196a0072b44184f0d85..69e51d77e5544ff89e21b1c3a4326a468bc89953 100644 | 
| --- a/src/compiler/wasm-compiler.cc | 
| +++ b/src/compiler/wasm-compiler.cc | 
| @@ -742,57 +742,35 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { | 
| } | 
| } | 
| case wasm::kExprF32Floor: { | 
| -      if (m->Float32RoundDown().IsSupported()) { | 
| -        op = m->Float32RoundDown().op(); | 
| -        break; | 
| -      } else { | 
| -        op = UnsupportedOpcode(opcode); | 
| -        break; | 
| -      } | 
| +      if (!m->Float32RoundDown().IsSupported()) return BuildF32Floor(input); | 
| +      op = m->Float32RoundDown().op(); | 
| +      break; | 
| } | 
| case wasm::kExprF32Ceil: { | 
| -      if (m->Float32RoundUp().IsSupported()) { | 
| -        op = m->Float32RoundUp().op(); | 
| -        break; | 
| -      } else { | 
| -        op = UnsupportedOpcode(opcode); | 
| -        break; | 
| -      } | 
| +      if (!m->Float32RoundUp().IsSupported()) return BuildF32Ceil(input); | 
| +      op = m->Float32RoundUp().op(); | 
| +      break; | 
| } | 
| case wasm::kExprF32Trunc: { | 
| -      if (m->Float32RoundTruncate().IsSupported()) { | 
| -        op = m->Float32RoundTruncate().op(); | 
| -      } else { | 
| -        return BuildF32Trunc(input); | 
| -      } | 
| +      if (!m->Float32RoundTruncate().IsSupported()) return BuildF32Trunc(input); | 
| +      op = m->Float32RoundTruncate().op(); | 
| break; | 
| } | 
| case wasm::kExprF32NearestInt: { | 
| -      if (m->Float32RoundTiesEven().IsSupported()) { | 
| -        op = m->Float32RoundTiesEven().op(); | 
| -        break; | 
| -      } else { | 
| -        op = UnsupportedOpcode(opcode); | 
| -        break; | 
| -      } | 
| +      if (!m->Float32RoundTiesEven().IsSupported()) | 
| +        return BuildF32NearestInt(input); | 
| +      op = m->Float32RoundTiesEven().op(); | 
| +      break; | 
| } | 
| case wasm::kExprF64Floor: { | 
| -      if (m->Float64RoundDown().IsSupported()) { | 
| -        op = m->Float64RoundDown().op(); | 
| -        break; | 
| -      } else { | 
| -        op = UnsupportedOpcode(opcode); | 
| -        break; | 
| -      } | 
| +      if (!m->Float64RoundDown().IsSupported()) return BuildF64Floor(input); | 
| +      op = m->Float64RoundDown().op(); | 
| +      break; | 
| } | 
| case wasm::kExprF64Ceil: { | 
| -      if (m->Float64RoundUp().IsSupported()) { | 
| -        op = m->Float64RoundUp().op(); | 
| -        break; | 
| -      } else { | 
| -        op = UnsupportedOpcode(opcode); | 
| -        break; | 
| -      } | 
| +      if (!m->Float64RoundUp().IsSupported()) return BuildF64Ceil(input); | 
| +      op = m->Float64RoundUp().op(); | 
| +      break; | 
| } | 
| case wasm::kExprF64Trunc: { | 
| if (!m->Float64RoundTruncate().IsSupported()) return BuildF64Trunc(input); | 
| @@ -800,13 +778,10 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { | 
| break; | 
| } | 
| case wasm::kExprF64NearestInt: { | 
| -      if (m->Float64RoundTiesEven().IsSupported()) { | 
| -        op = m->Float64RoundTiesEven().op(); | 
| -        break; | 
| -      } else { | 
| -        op = UnsupportedOpcode(opcode); | 
| -        break; | 
| -      } | 
| +      if (!m->Float64RoundTiesEven().IsSupported()) | 
| +        return BuildF64NearestInt(input); | 
| +      op = m->Float64RoundTiesEven().op(); | 
| +      break; | 
| } | 
|  | 
| #if WASM_64 | 
| @@ -1365,99 +1340,89 @@ Node* WasmGraphBuilder::BuildI64Popcnt(Node* input) { | 
| return result; | 
| } | 
|  | 
| - | 
| Node* WasmGraphBuilder::BuildF32Trunc(Node* input) { | 
| -  //  int32_t int_input = bitftoi(input); | 
| -  //  int32_t exponent = int_input & 0x7f800000; | 
| -  //  if (exponent >= ((23 + 127) << 23)) { | 
| -  //    if (input != input) { | 
| -  //      return bititof(int_input | (1 << 22)); | 
| -  //    } | 
| -  //    return input; | 
| -  //  } | 
| -  //  int32_t sign = int_input & 0x80000000; | 
| -  //  if (exponent < (127 << 23)) { | 
| -  //    return bititof(sign); | 
| -  //  } | 
| -  //  int32_t mantissa = int_input & 0x007fffff; | 
| -  //  int32_t shift = (127 + 23) - (exponent >> 23); | 
| -  //  int32_t new_mantissa = (mantissa >> shift) << shift; | 
| -  //  int32_t result = new_mantissa | exponent | sign; | 
| -  //  return bititof(result); | 
| - | 
| -  Node* int_input = Unop(wasm::kExprI32ReinterpretF32, input); | 
| -  Node* exponent = | 
| -      Binop(wasm::kExprI32And, int_input, jsgraph()->Int32Constant(0x7f800000)); | 
| - | 
| -  Node* sign = | 
| -      Binop(wasm::kExprI32And, int_input, jsgraph()->Int32Constant(0x80000000)); | 
| - | 
| -  Node* result_out_of_range = int_input; | 
| - | 
| -  Node* result_nan = | 
| -      Binop(wasm::kExprI32Ior, int_input, jsgraph()->Int32Constant(1 << 22)); | 
| - | 
| -  Node* result_zero = sign; | 
| - | 
| -  Node* mantissa = | 
| -      Binop(wasm::kExprI32And, int_input, jsgraph()->Int32Constant(0x007fffff)); | 
| -  Node* shift = | 
| -      Binop(wasm::kExprI32Sub, jsgraph()->Int32Constant(23 + 127), | 
| -            Binop(wasm::kExprI32ShrU, exponent, jsgraph()->Int32Constant(23))); | 
| -  Node* new_mantissa = Binop(wasm::kExprI32Shl, | 
| -                             Binop(wasm::kExprI32ShrU, mantissa, shift), shift); | 
| -  Node* result_truncate = | 
| -      Binop(wasm::kExprI32Ior, Binop(wasm::kExprI32Ior, new_mantissa, exponent), | 
| -            sign); | 
| - | 
| -  Diamond is_zero( | 
| -      graph(), jsgraph()->common(), | 
| -      Binop(wasm::kExprI32LtU, exponent, jsgraph()->Int32Constant(127 << 23))); | 
| - | 
| -  Node* result_within_range = | 
| -      is_zero.Phi(wasm::kAstI32, result_zero, result_truncate); | 
| - | 
| -  Diamond input_nan(graph(), jsgraph()->common(), | 
| -                    Binop(wasm::kExprF32Ne, input, input)); | 
| -  Node* result_exponent_geq_23 = | 
| -      input_nan.Phi(wasm::kAstI32, result_nan, result_out_of_range); | 
| - | 
| -  Diamond exponent_geq_23(graph(), jsgraph()->common(), | 
| -                          Binop(wasm::kExprI32GeU, exponent, | 
| -                                jsgraph()->Int32Constant((23 + 127) << 23))); | 
| - | 
| -  Node* result = exponent_geq_23.Phi(wasm::kAstI32, result_exponent_geq_23, | 
| -                                     result_within_range); | 
| - | 
| -  return Unop(wasm::kExprF32ReinterpretI32, result); | 
| +  MachineType type = MachineType::Float32(); | 
| +  ExternalReference ref = | 
| +      ExternalReference::f32_trunc_wrapper_function(jsgraph()->isolate()); | 
| +  return BuildRoundingInstruction(input, ref, type); | 
| +} | 
| + | 
| +Node* WasmGraphBuilder::BuildF32Floor(Node* input) { | 
| +  MachineType type = MachineType::Float32(); | 
| +  ExternalReference ref = | 
| +      ExternalReference::f32_floor_wrapper_function(jsgraph()->isolate()); | 
| +  return BuildRoundingInstruction(input, ref, type); | 
| +} | 
| + | 
| +Node* WasmGraphBuilder::BuildF32Ceil(Node* input) { | 
| +  MachineType type = MachineType::Float32(); | 
| +  ExternalReference ref = | 
| +      ExternalReference::f32_ceil_wrapper_function(jsgraph()->isolate()); | 
| +  return BuildRoundingInstruction(input, ref, type); | 
| +} | 
| + | 
| +Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) { | 
| +  MachineType type = MachineType::Float32(); | 
| +  ExternalReference ref = | 
| +      ExternalReference::f32_nearest_int_wrapper_function(jsgraph()->isolate()); | 
| +  return BuildRoundingInstruction(input, ref, type); | 
| } | 
|  | 
| Node* WasmGraphBuilder::BuildF64Trunc(Node* input) { | 
| +  MachineType type = MachineType::Float64(); | 
| +  ExternalReference ref = | 
| +      ExternalReference::f64_trunc_wrapper_function(jsgraph()->isolate()); | 
| +  return BuildRoundingInstruction(input, ref, type); | 
| +} | 
| + | 
| +Node* WasmGraphBuilder::BuildF64Floor(Node* input) { | 
| +  MachineType type = MachineType::Float64(); | 
| +  ExternalReference ref = | 
| +      ExternalReference::f64_floor_wrapper_function(jsgraph()->isolate()); | 
| +  return BuildRoundingInstruction(input, ref, type); | 
| +} | 
| + | 
| +Node* WasmGraphBuilder::BuildF64Ceil(Node* input) { | 
| +  MachineType type = MachineType::Float64(); | 
| +  ExternalReference ref = | 
| +      ExternalReference::f64_ceil_wrapper_function(jsgraph()->isolate()); | 
| +  return BuildRoundingInstruction(input, ref, type); | 
| +} | 
| + | 
| +Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) { | 
| +  MachineType type = MachineType::Float64(); | 
| +  ExternalReference ref = | 
| +      ExternalReference::f64_nearest_int_wrapper_function(jsgraph()->isolate()); | 
| +  return BuildRoundingInstruction(input, ref, type); | 
| +} | 
| + | 
| +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* stack_slot_param = graph()->NewNode( | 
| -      jsgraph()->machine()->StackSlot(MachineRepresentation::kFloat64)); | 
| +  Node* stack_slot_param = | 
| +      graph()->NewNode(jsgraph()->machine()->StackSlot(type.representation())); | 
|  | 
| const Operator* store_op = jsgraph()->machine()->Store( | 
| -      StoreRepresentation(MachineRepresentation::kFloat64, kNoWriteBarrier)); | 
| +      StoreRepresentation(type.representation(), 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* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); | 
|  | 
| Node* args[] = {function, stack_slot_param}; | 
|  | 
| BuildCCall(sig_builder.Build(), args); | 
|  | 
| -  const Operator* load_op = jsgraph()->machine()->Load(MachineType::Float64()); | 
| +  const Operator* load_op = jsgraph()->machine()->Load(type); | 
|  | 
| Node* load = | 
| graph()->NewNode(load_op, stack_slot_param, jsgraph()->Int32Constant(0), | 
|  |