wasm-compiler.h 25.6 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2015 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.

#ifndef V8_COMPILER_WASM_COMPILER_H_
#define V8_COMPILER_WASM_COMPILER_H_

8 9
#include <memory>

10 11
// Clients of this interface shouldn't depend on lots of compiler internals.
// Do not include anything from src/compiler here!
12
#include "src/runtime/runtime.h"
13
#include "src/wasm/function-body-decoder.h"
14
#include "src/wasm/function-compiler.h"
15
#include "src/wasm/wasm-module.h"
16
#include "src/wasm/wasm-opcodes.h"
17
#include "src/wasm/wasm-result.h"
18
#include "src/zone/zone.h"
19 20 21

namespace v8 {
namespace internal {
22
struct AssemblerOptions;
23

24 25
namespace compiler {
// Forward declarations for some compiler data structures.
26
class CallDescriptor;
27
class Graph;
28
class MachineGraph;
29
class Node;
30
class NodeOriginTable;
31
class Operator;
32
class SourcePositionTable;
33
class WasmDecorator;
34
enum class TrapId : uint32_t;
35
}  // namespace compiler
36 37

namespace wasm {
38
struct DecodeStruct;
39
// Expose {Node} and {Graph} opaquely as {wasm::TFNode} and {wasm::TFGraph}.
40 41
using TFNode = compiler::Node;
using TFGraph = compiler::MachineGraph;
42
class WasmCode;
43
struct WasmFeatures;
44
}  // namespace wasm
45 46

namespace compiler {
47

48
class TurbofanWasmCompilationUnit {
49
 public:
50 51
  explicit TurbofanWasmCompilationUnit(wasm::WasmCompilationUnit* wasm_unit);
  ~TurbofanWasmCompilationUnit();
52

53 54
  bool BuildGraphForWasmFunction(AccountingAllocator* allocator,
                                 wasm::CompilationEnv* env,
55
                                 const wasm::FunctionBody& func_body,
56 57 58
                                 wasm::WasmFeatures* detected,
                                 double* decode_ms, MachineGraph* mcgraph,
                                 NodeOriginTable* node_origins,
59
                                 SourcePositionTable* source_positions);
60

61 62
  wasm::WasmCompilationResult ExecuteCompilation(wasm::WasmEngine*,
                                                 wasm::CompilationEnv*,
63 64 65
                                                 const wasm::FunctionBody&,
                                                 Counters*,
                                                 wasm::WasmFeatures* detected);
66 67

 private:
68 69 70
  wasm::WasmCompilationUnit* const wasm_unit_;

  DISALLOW_COPY_AND_ASSIGN(TurbofanWasmCompilationUnit);
71
};
72

73 74 75 76 77
class InterpreterCompilationUnit final {
 public:
  explicit InterpreterCompilationUnit(wasm::WasmCompilationUnit* wasm_unit)
      : wasm_unit_(wasm_unit) {}

78 79
  wasm::WasmCompilationResult ExecuteCompilation(wasm::WasmEngine*,
                                                 wasm::CompilationEnv*,
80 81 82 83 84 85 86 87 88 89 90 91 92
                                                 const wasm::FunctionBody&,
                                                 Counters*,
                                                 wasm::WasmFeatures* detected);

 private:
  wasm::WasmCompilationUnit* const wasm_unit_;

  DISALLOW_COPY_AND_ASSIGN(InterpreterCompilationUnit);
};

// Calls to WASM imports are handled in several different ways, depending on the
// type of the target function/callable and whether the signature matches the
// argument arity.
93
enum class WasmImportCallKind : uint8_t {
94 95 96 97 98 99 100
  kLinkError,                      // static WASM->WASM type error
  kRuntimeTypeError,               // runtime WASM->JS type error
  kWasmToWasm,                     // fast WASM->WASM call
  kJSFunctionArityMatch,           // fast WASM->JS call
  kJSFunctionArityMatchSloppy,     // fast WASM->JS call, sloppy receiver
  kJSFunctionArityMismatch,        // WASM->JS, needs adapter frame
  kJSFunctionArityMismatchSloppy,  // WASM->JS, needs adapter frame, sloppy
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
  // Math functions imported from JavaScript that are intrinsified
  kFirstMathIntrinsic,
  kF64Acos = kFirstMathIntrinsic,
  kF64Asin,
  kF64Atan,
  kF64Cos,
  kF64Sin,
  kF64Tan,
  kF64Exp,
  kF64Log,
  kF64Atan2,
  kF64Pow,
  kF64Ceil,
  kF64Floor,
  kF64Sqrt,
  kF64Min,
  kF64Max,
  kF64Abs,
  kF32Min,
  kF32Max,
  kF32Abs,
  kF32Ceil,
  kF32Floor,
  kF32Sqrt,
  kF32ConvertF64,
  kLastMathIntrinsic = kF32ConvertF64,
  // For everything else, there's the call builtin.
  kUseCallBuiltin
129 130
};

131 132 133
V8_EXPORT_PRIVATE WasmImportCallKind
GetWasmImportCallKind(Handle<JSReceiver> callable, wasm::FunctionSig* sig,
                      bool has_bigint_feature);
134 135

// Compiles an import call wrapper, which allows WASM to call imports.
136 137 138
V8_EXPORT_PRIVATE wasm::WasmCode* CompileWasmImportCallWrapper(
    wasm::WasmEngine*, wasm::NativeModule*, WasmImportCallKind,
    wasm::FunctionSig*, bool source_positions);
139

140 141
// Creates a code object calling a wasm function with the given signature,
// callable from JS.
142 143 144
V8_EXPORT_PRIVATE MaybeHandle<Code> CompileJSToWasmWrapper(Isolate*,
                                                           wasm::FunctionSig*,
                                                           bool is_import);
145

146 147
// Compiles a stub that redirects a call to a wasm function to the wasm
// interpreter. It's ABI compatible with the compiled wasm function.
148
V8_EXPORT_PRIVATE wasm::WasmCompilationResult CompileWasmInterpreterEntry(
149 150
    wasm::WasmEngine*, const wasm::WasmFeatures& enabled_features,
    uint32_t func_index, wasm::FunctionSig*);
151

152
enum CWasmEntryParameters {
153
  kCodeEntry,
154
  kObjectRef,
155 156 157 158 159 160 161 162
  kArgumentsBuffer,
  // marker:
  kNumParameters
};

// Compiles a stub with JS linkage, taking parameters as described by
// {CWasmEntryParameters}. It loads the wasm parameters from the argument
// buffer and calls the wasm function given as first parameter.
163
MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig);
164

165
// Values from the instance object are cached between WASM-level function calls.
166 167
// This struct allows the SSA environment handling this cache to be defined
// and manipulated in wasm-compiler.{h,cc} instead of inside the WASM decoder.
168 169
// (Note that currently, the globals base is immutable, so not cached here.)
struct WasmInstanceCacheNodes {
170 171
  Node* mem_start;
  Node* mem_size;
172
  Node* mem_mask;
173 174
};

175 176
// Abstracts details of building TurboFan graph nodes for wasm to separate
// the wasm decoder from the internal details of TurboFan.
177 178
class WasmGraphBuilder {
 public:
179
  enum EnforceBoundsCheck : bool {  // --
180 181 182
    kNeedsBoundsCheck = true,
    kCanOmitBoundsCheck = false
  };
183 184 185 186 187 188 189 190
  enum UseRetpoline : bool {  // --
    kRetpoline = true,
    kNoRetpoline = false
  };
  enum ExtraCallableParam : bool {  // --
    kExtraCallableParam = true,
    kNoExtraCallableParam = false
  };
191

192 193 194
  V8_EXPORT_PRIVATE WasmGraphBuilder(
      wasm::CompilationEnv* env, Zone* zone, MachineGraph* mcgraph,
      wasm::FunctionSig* sig, compiler::SourcePositionTable* spt = nullptr);
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210

  Node** Buffer(size_t count) {
    if (count > cur_bufsize_) {
      size_t new_size = count + cur_bufsize_ + 5;
      cur_buffer_ =
          reinterpret_cast<Node**>(zone_->New(new_size * sizeof(Node*)));
      cur_bufsize_ = new_size;
    }
    return cur_buffer_;
  }

  //-----------------------------------------------------------------------
  // Operations independent of {control} or {effect}.
  //-----------------------------------------------------------------------
  Node* Error();
  Node* Start(unsigned params);
211
  Node* Param(unsigned index);
212
  Node* Loop(Node* entry);
213 214
  Node* TerminateLoop(Node* effect, Node* control);
  Node* TerminateThrow(Node* effect, Node* control);
215
  Node* Merge(unsigned count, Node** controls);
216
  Node* Phi(wasm::ValueType type, unsigned count, Node** vals, Node* control);
217 218
  Node* CreateOrMergeIntoPhi(MachineRepresentation rep, Node* merge,
                             Node* tnode, Node* fnode);
219
  Node* CreateOrMergeIntoEffectPhi(Node* merge, Node* tnode, Node* fnode);
220
  Node* EffectPhi(unsigned count, Node** effects, Node* control);
221
  Node* RefNull();
222
  Node* Uint32Constant(uint32_t value);
223 224
  Node* Int32Constant(int32_t value);
  Node* Int64Constant(int64_t value);
225
  Node* IntPtrConstant(intptr_t value);
226 227
  Node* Float32Constant(float value);
  Node* Float64Constant(double value);
228 229 230 231
  Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right,
              wasm::WasmCodePosition position = wasm::kNoCodePosition);
  Node* Unop(wasm::WasmOpcode opcode, Node* input,
             wasm::WasmCodePosition position = wasm::kNoCodePosition);
232
  Node* MemoryGrow(Node* input);
233
  Node* Throw(uint32_t exception_index, const wasm::WasmException* exception,
234
              const Vector<Node*> values);
235
  Node* Rethrow(Node* except_obj);
236 237 238
  Node* ExceptionTagEqual(Node* caught_tag, Node* expected_tag);
  Node* LoadExceptionTagFromTable(uint32_t exception_index);
  Node* GetExceptionTag(Node* except_obj);
239
  Node** GetExceptionValues(Node* except_obj,
240
                            const wasm::WasmException* exception);
241
  bool IsPhiWithMerge(Node* phi, Node* merge);
242
  bool ThrowsException(Node* node, Node** if_success, Node** if_exception);
243
  void AppendToMerge(Node* merge, Node* from);
244
  void AppendToPhi(Node* phi, Node* from);
245

246 247
  void StackCheck(wasm::WasmCodePosition position, Node** effect = nullptr,
                  Node** control = nullptr);
248

249 250
  void PatchInStackCheckIfNeeded();

251 252 253
  //-----------------------------------------------------------------------
  // Operations that read and/or write {control} and {effect}.
  //-----------------------------------------------------------------------
254 255 256 257
  Node* BranchNoHint(Node* cond, Node** true_node, Node** false_node);
  Node* BranchExpectTrue(Node* cond, Node** true_node, Node** false_node);
  Node* BranchExpectFalse(Node* cond, Node** true_node, Node** false_node);

258 259 260 261 262 263 264 265 266 267 268 269 270
  Node* TrapIfTrue(wasm::TrapReason reason, Node* cond,
                   wasm::WasmCodePosition position);
  Node* TrapIfFalse(wasm::TrapReason reason, Node* cond,
                    wasm::WasmCodePosition position);
  Node* TrapIfEq32(wasm::TrapReason reason, Node* node, int32_t val,
                   wasm::WasmCodePosition position);
  Node* ZeroCheck32(wasm::TrapReason reason, Node* node,
                    wasm::WasmCodePosition position);
  Node* TrapIfEq64(wasm::TrapReason reason, Node* node, int64_t val,
                   wasm::WasmCodePosition position);
  Node* ZeroCheck64(wasm::TrapReason reason, Node* node,
                    wasm::WasmCodePosition position);

271 272 273
  Node* Switch(unsigned count, Node* key);
  Node* IfValue(int32_t value, Node* sw);
  Node* IfDefault(Node* sw);
274 275 276 277 278 279
  Node* Return(unsigned count, Node** nodes);
  template <typename... Nodes>
  Node* Return(Node* fst, Nodes*... more) {
    Node* arr[] = {fst, more...};
    return Return(arraysize(arr), arr);
  }
280
  Node* ReturnVoid();
281 282
  Node* Unreachable(wasm::WasmCodePosition position);

283 284
  Node* CallDirect(uint32_t index, Node** args, Node*** rets,
                   wasm::WasmCodePosition position);
285 286
  Node* CallIndirect(uint32_t table_index, uint32_t sig_index, Node** args,
                     Node*** rets, wasm::WasmCodePosition position);
287

288 289
  Node* ReturnCall(uint32_t index, Node** args,
                   wasm::WasmCodePosition position);
290 291
  Node* ReturnCallIndirect(uint32_t table_index, uint32_t sig_index,
                           Node** args, wasm::WasmCodePosition position);
292

293 294
  Node* Invert(Node* node);

295 296
  Node* GetGlobal(uint32_t index);
  Node* SetGlobal(uint32_t index, Node* val);
297 298 299 300
  Node* GetTable(uint32_t table_index, Node* index,
                 wasm::WasmCodePosition position);
  Node* SetTable(uint32_t table_index, Node* index, Node* val,
                 wasm::WasmCodePosition position);
301 302 303
  //-----------------------------------------------------------------------
  // Operations that concern the linear memory.
  //-----------------------------------------------------------------------
304
  Node* CurrentMemoryPages();
305 306
  Node* TraceMemoryOperation(bool is_store, MachineRepresentation, Node* index,
                             uint32_t offset, wasm::WasmCodePosition);
307
  Node* LoadMem(wasm::ValueType type, MachineType memtype, Node* index,
308 309
                uint32_t offset, uint32_t alignment,
                wasm::WasmCodePosition position);
310
  Node* StoreMem(MachineRepresentation mem_rep, Node* index, uint32_t offset,
311
                 uint32_t alignment, Node* val, wasm::WasmCodePosition position,
312
                 wasm::ValueType type);
313 314
  static void PrintDebugName(Node* node);

315 316
  void set_instance_node(Node* instance_node) {
    this->instance_node_ = instance_node;
317 318
  }

319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
  Node* Control() {
    DCHECK_NOT_NULL(*control_);
    return *control_;
  }
  Node* Effect() {
    DCHECK_NOT_NULL(*effect_);
    return *effect_;
  }
  Node* SetControl(Node* node) {
    *control_ = node;
    return node;
  }
  Node* SetEffect(Node* node) {
    *effect_ = node;
    return node;
  }
335 336 337 338 339

  void set_control_ptr(Node** control) { this->control_ = control; }

  void set_effect_ptr(Node** effect) { this->effect_ = effect; }

340 341
  Node* GetImportedMutableGlobals();

342
  void GetGlobalBaseAndOffset(MachineType mem_type, const wasm::WasmGlobal&,
343
                              Node** base_node, Node** offset_node);
344

345 346 347
  void GetBaseAndOffsetForImportedMutableAnyRefGlobal(
      const wasm::WasmGlobal& global, Node** base, Node** offset);

348 349 350 351
  void BoundsCheckTable(uint32_t table_index, Node* index,
                        wasm::WasmCodePosition position,
                        wasm::TrapReason trap_reason, Node** base_node);

352 353 354 355
  void GetTableBaseAndOffset(uint32_t table_index, Node* index,
                             wasm::WasmCodePosition position, Node** base_node,
                             Node** offset_node);

356 357 358 359 360 361 362 363 364 365 366
  // Utilities to manipulate sets of instance cache nodes.
  void InitInstanceCache(WasmInstanceCacheNodes* instance_cache);
  void PrepareInstanceCacheForLoop(WasmInstanceCacheNodes* instance_cache,
                                   Node* control);
  void NewInstanceCacheMerge(WasmInstanceCacheNodes* to,
                             WasmInstanceCacheNodes* from, Node* merge);
  void MergeInstanceCacheInto(WasmInstanceCacheNodes* to,
                              WasmInstanceCacheNodes* from, Node* merge);

  void set_instance_cache(WasmInstanceCacheNodes* instance_cache) {
    this->instance_cache_ = instance_cache;
367
  }
368

369
  wasm::FunctionSig* GetFunctionSignature() { return sig_; }
370

371
  V8_EXPORT_PRIVATE void LowerInt64();
372

373
  V8_EXPORT_PRIVATE void SimdScalarLoweringForTesting();
374

375
  void SetSourcePosition(Node* node, wasm::WasmCodePosition position);
376

377 378 379 380
  Node* S128Zero();
  Node* S1x4Zero();
  Node* S1x8Zero();
  Node* S1x16Zero();
381

382
  Node* SimdOp(wasm::WasmOpcode opcode, Node* const* inputs);
383

384
  Node* SimdLaneOp(wasm::WasmOpcode opcode, uint8_t lane, Node* const* inputs);
385

386
  Node* SimdShiftOp(wasm::WasmOpcode opcode, uint8_t shift,
387
                    Node* const* inputs);
388

389
  Node* Simd8x16ShuffleOp(const uint8_t shuffle[16], Node* const* inputs);
390

391
  Node* AtomicOp(wasm::WasmOpcode opcode, Node* const* inputs,
392
                 uint32_t alignment, uint32_t offset,
393 394
                 wasm::WasmCodePosition position);

395 396 397 398
  // Returns a pointer to the dropped_data_segments array. Traps if the data
  // segment is active or has been dropped.
  Node* CheckDataSegmentIsPassiveAndNotDropped(uint32_t data_segment_index,
                                               wasm::WasmCodePosition position);
399 400
  Node* CheckElemSegmentIsPassiveAndNotDropped(uint32_t elem_segment_index,
                                               wasm::WasmCodePosition position);
401 402
  Node* MemoryInit(uint32_t data_segment_index, Node* dst, Node* src,
                   Node* size, wasm::WasmCodePosition position);
403 404
  Node* MemoryCopy(Node* dst, Node* src, Node* size,
                   wasm::WasmCodePosition position);
405
  Node* DataDrop(uint32_t data_segment_index, wasm::WasmCodePosition position);
406 407 408
  Node* MemoryFill(Node* dst, Node* fill, Node* size,
                   wasm::WasmCodePosition position);

409 410
  Node* TableInit(uint32_t table_index, uint32_t elem_segment_index, Node* dst,
                  Node* src, Node* size, wasm::WasmCodePosition position);
411
  Node* ElemDrop(uint32_t elem_segment_index, wasm::WasmCodePosition position);
412 413
  Node* TableCopy(uint32_t table_src_index, uint32_t table_dst_index, Node* dst,
                  Node* src, Node* size, wasm::WasmCodePosition position);
414

415 416
  bool has_simd() const { return has_simd_; }

417 418
  const wasm::WasmModule* module() { return env_ ? env_->module : nullptr; }

419 420 421
  wasm::UseTrapHandler use_trap_handler() const {
    return env_ ? env_->use_trap_handler : wasm::kNoTrapHandler;
  }
422

423
  MachineGraph* mcgraph() { return mcgraph_; }
424
  Graph* graph();
425

426 427 428 429 430
  void AddBytecodePositionDecorator(NodeOriginTable* node_origins,
                                    wasm::Decoder* decoder);

  void RemoveBytecodePositionDecorator();

431
 protected:
432 433
  static const int kDefaultBufferSize = 16;

434
  Zone* const zone_;
435
  MachineGraph* const mcgraph_;
436
  wasm::CompilationEnv* const env_;
437

438 439
  Node** control_ = nullptr;
  Node** effect_ = nullptr;
440
  WasmInstanceCacheNodes* instance_cache_ = nullptr;
441 442

  SetOncePointer<Node> instance_node_;
443
  SetOncePointer<Node> globals_start_;
444
  SetOncePointer<Node> imported_mutable_globals_;
445
  SetOncePointer<Node> stack_check_code_node_;
446
  SetOncePointer<const Operator> stack_check_call_operator_;
447

448 449 450
  Node** cur_buffer_;
  size_t cur_bufsize_;
  Node* def_buffer_[kDefaultBufferSize];
451
  bool has_simd_ = false;
452
  bool needs_stack_check_ = false;
453
  const bool untrusted_code_mitigations_ = true;
454

455
  wasm::FunctionSig* const sig_;
456

457 458
  compiler::WasmDecorator* decorator_ = nullptr;

459
  compiler::SourcePositionTable* const source_position_table_ = nullptr;
460

461 462
  Node* NoContextConstant();

463
  Node* MemBuffer(uint32_t offset);
464 465 466
  // BoundsCheckMem receives a uint32 {index} node and returns a ptrsize index.
  Node* BoundsCheckMem(uint8_t access_size, Node* index, uint32_t offset,
                       wasm::WasmCodePosition, EnforceBoundsCheck);
467
  // Check that the range [start, start + size) is in the range [0, max).
468 469 470 471 472 473 474 475 476 477
  // Also updates *size with the valid range. Returns true if the range is
  // partially out-of-bounds, traps if it is completely out-of-bounds.
  Node* BoundsCheckRange(Node* start, Node** size, Node* max,
                         wasm::WasmCodePosition);
  // BoundsCheckMemRange receives a uint32 {start} and {size}, and checks if it
  // is in bounds. Also updates *size with the valid range, and converts *start
  // to a pointer into memory at that index. Returns true if the range is
  // partially out-of-bounds, traps if it is completely out-of-bounds.
  Node* BoundsCheckMemRange(Node** start, Node** size, wasm::WasmCodePosition);

478 479
  Node* CheckBoundsAndAlignment(uint8_t access_size, Node* index,
                                uint32_t offset, wasm::WasmCodePosition);
480

481
  Node* Uint32ToUintptr(Node*);
482
  const Operator* GetSafeLoadOperator(int offset, wasm::ValueType type);
483
  const Operator* GetSafeStoreOperator(int offset, wasm::ValueType type);
484
  Node* BuildChangeEndiannessStore(Node* node, MachineRepresentation rep,
485 486 487
                                   wasm::ValueType wasmtype = wasm::kWasmStmt);
  Node* BuildChangeEndiannessLoad(Node* node, MachineType type,
                                  wasm::ValueType wasmtype = wasm::kWasmStmt);
488

489 490 491
  Node* MaskShiftCount32(Node* node);
  Node* MaskShiftCount64(Node* node);

492 493
  enum IsReturnCall : bool { kReturnCall = true, kCallContinues = false };

494 495
  template <typename... Args>
  Node* BuildCCall(MachineSignature* sig, Node* function, Args... args);
496 497 498
  Node* BuildCallNode(wasm::FunctionSig* sig, Node** args,
                      wasm::WasmCodePosition position, Node* instance_node,
                      const Operator* op);
499
  // Special implementation for CallIndirect for table 0.
500 501 502
  Node* BuildIndirectCall(uint32_t sig_index, Node** args, Node*** rets,
                          wasm::WasmCodePosition position,
                          IsReturnCall continuation);
503 504 505
  Node* BuildIndirectCall(uint32_t table_index, uint32_t sig_index, Node** args,
                          Node*** rets, wasm::WasmCodePosition position,
                          IsReturnCall continuation);
506
  Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
507 508
                      wasm::WasmCodePosition position, Node* instance_node,
                      UseRetpoline use_retpoline);
509 510 511
  Node* BuildWasmReturnCall(wasm::FunctionSig* sig, Node** args,
                            wasm::WasmCodePosition position,
                            Node* instance_node, UseRetpoline use_retpoline);
512
  Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
513 514
                        wasm::WasmCodePosition position, int func_index,
                        IsReturnCall continuation);
515
  Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
516 517
                        wasm::WasmCodePosition position, Node* func_index,
                        IsReturnCall continuation);
518

519 520
  Node* BuildF32CopySign(Node* left, Node* right);
  Node* BuildF64CopySign(Node* left, Node* right);
521

522 523
  Node* BuildIntConvertFloat(Node* input, wasm::WasmCodePosition position,
                             wasm::WasmOpcode);
524 525 526 527
  Node* BuildI32Ctz(Node* input);
  Node* BuildI32Popcnt(Node* input);
  Node* BuildI64Ctz(Node* input);
  Node* BuildI64Popcnt(Node* input);
528 529 530
  Node* BuildBitCountingCall(Node* input, ExternalReference ref,
                             MachineRepresentation input_type);

531 532
  Node* BuildCFuncInstruction(ExternalReference ref, MachineType type,
                              Node* input0, Node* input1 = nullptr);
533
  Node* BuildF32Trunc(Node* input);
534 535 536
  Node* BuildF32Floor(Node* input);
  Node* BuildF32Ceil(Node* input);
  Node* BuildF32NearestInt(Node* input);
537
  Node* BuildF64Trunc(Node* input);
538 539 540
  Node* BuildF64Floor(Node* input);
  Node* BuildF64Ceil(Node* input);
  Node* BuildF64NearestInt(Node* input);
541 542
  Node* BuildI32Rol(Node* left, Node* right);
  Node* BuildI64Rol(Node* left, Node* right);
543

544 545
  Node* BuildF64Acos(Node* input);
  Node* BuildF64Asin(Node* input);
546
  Node* BuildF64Pow(Node* left, Node* right);
547 548
  Node* BuildF64Mod(Node* left, Node* right);

549
  Node* BuildIntToFloatConversionInstruction(
550 551 552 553 554 555 556 557
      Node* input, ExternalReference ref,
      MachineRepresentation parameter_representation,
      const MachineType result_type);
  Node* BuildF32SConvertI64(Node* input);
  Node* BuildF32UConvertI64(Node* input);
  Node* BuildF64SConvertI64(Node* input);
  Node* BuildF64UConvertI64(Node* input);

558 559
  Node* BuildCcallConvertFloat(Node* input, wasm::WasmCodePosition position,
                               wasm::WasmOpcode opcode);
560 561 562 563 564 565 566 567 568 569

  Node* BuildI32DivS(Node* left, Node* right, wasm::WasmCodePosition position);
  Node* BuildI32RemS(Node* left, Node* right, wasm::WasmCodePosition position);
  Node* BuildI32DivU(Node* left, Node* right, wasm::WasmCodePosition position);
  Node* BuildI32RemU(Node* left, Node* right, wasm::WasmCodePosition position);

  Node* BuildI64DivS(Node* left, Node* right, wasm::WasmCodePosition position);
  Node* BuildI64RemS(Node* left, Node* right, wasm::WasmCodePosition position);
  Node* BuildI64DivU(Node* left, Node* right, wasm::WasmCodePosition position);
  Node* BuildI64RemU(Node* left, Node* right, wasm::WasmCodePosition position);
570
  Node* BuildDiv64Call(Node* left, Node* right, ExternalReference ref,
571
                       MachineType result_type, wasm::TrapReason trap_zero,
572
                       wasm::WasmCodePosition position);
573

574
  Node* BuildChangeInt32ToIntPtr(Node* value);
575
  Node* BuildChangeInt32ToSmi(Node* value);
576
  Node* BuildChangeUint31ToSmi(Node* value);
577
  Node* BuildSmiShiftBitsConstant();
578
  Node* BuildChangeSmiToInt32(Node* value);
579 580
  // generates {index > max ? Smi(max) : Smi(index)}
  Node* BuildConvertUint32ToSmiWithSaturation(Node* index, uint32_t maxval);
581

582 583 584 585 586 587 588 589 590
  // Asm.js specific functionality.
  Node* BuildI32AsmjsSConvertF32(Node* input);
  Node* BuildI32AsmjsSConvertF64(Node* input);
  Node* BuildI32AsmjsUConvertF32(Node* input);
  Node* BuildI32AsmjsUConvertF64(Node* input);
  Node* BuildI32AsmjsDivS(Node* left, Node* right);
  Node* BuildI32AsmjsRemS(Node* left, Node* right);
  Node* BuildI32AsmjsDivU(Node* left, Node* right);
  Node* BuildI32AsmjsRemU(Node* left, Node* right);
591 592
  Node* BuildAsmjsLoadMem(MachineType type, Node* index);
  Node* BuildAsmjsStoreMem(MachineType type, Node* index, Node* val);
593

594
  void BuildEncodeException32BitValue(Node* values_array, uint32_t* index,
595
                                      Node* value);
596 597
  Node* BuildDecodeException32BitValue(Node* values_array, uint32_t* index);
  Node* BuildDecodeException64BitValue(Node* values_array, uint32_t* index);
598

599
  Node** Realloc(Node* const* buffer, size_t old_count, size_t new_count) {
600 601
    Node** buf = Buffer(new_count);
    if (buf != buffer) memcpy(buf, buffer, old_count * sizeof(Node*));
602 603
    return buf;
  }
604

605 606
  Node* BuildLoadBuiltinFromInstance(int builtin_index);

607
  //-----------------------------------------------------------------------
608
  // Operations involving the CEntry, a dependency we want to remove
609 610 611 612 613
  // to get off the GC heap.
  //-----------------------------------------------------------------------
  Node* BuildCallToRuntime(Runtime::FunctionId f, Node** parameters,
                           int parameter_count);

614
  Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, Node* js_context,
615 616
                                      Node** parameters, int parameter_count,
                                      Node** effect, Node* control);
617
  TrapId GetTrapIdForTrap(wasm::TrapReason reason);
618
};
619

620
V8_EXPORT_PRIVATE CallDescriptor* GetWasmCallDescriptor(
621 622
    Zone* zone, wasm::FunctionSig* signature,
    WasmGraphBuilder::UseRetpoline use_retpoline =
623 624 625
        WasmGraphBuilder::kNoRetpoline,
    WasmGraphBuilder::ExtraCallableParam callable_param =
        WasmGraphBuilder::kNoExtraCallableParam);
626

627
V8_EXPORT_PRIVATE CallDescriptor* GetI32WasmCallDescriptor(
628
    Zone* zone, CallDescriptor* call_descriptor);
629

630
V8_EXPORT_PRIVATE CallDescriptor* GetI32WasmCallDescriptorForSimd(
631
    Zone* zone, CallDescriptor* call_descriptor);
632

633
AssemblerOptions WasmAssemblerOptions();
634
AssemblerOptions WasmStubAssemblerOptions();
635

636 637 638 639 640
}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_WASM_COMPILER_H_