// 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_CODE_ASSEMBLER_H_
#define V8_COMPILER_CODE_ASSEMBLER_H_

#include <map>
#include <memory>

// Clients of this interface shouldn't depend on lots of compiler internals.
// Do not include anything from src/compiler here!
#include "src/allocation.h"
#include "src/base/macros.h"
#include "src/builtins/builtins.h"
#include "src/code-factory.h"
#include "src/globals.h"
#include "src/heap/heap.h"
#include "src/machine-type.h"
#include "src/objects.h"
#include "src/objects/data-handler.h"
#include "src/objects/map.h"
#include "src/objects/maybe-object.h"
#include "src/runtime/runtime.h"
#include "src/zone/zone-containers.h"

namespace v8 {
namespace internal {

// Forward declarations.
class CallInterfaceDescriptor;
class Callable;
class Factory;
class InterpreterData;
class Isolate;
class JSAsyncFunctionObject;
class JSAsyncGeneratorObject;
class JSCollator;
class JSCollection;
class JSDateTimeFormat;
class JSListFormat;
class JSLocale;
class JSNumberFormat;
class JSPluralRules;
class JSRegExpStringIterator;
class JSRelativeTimeFormat;
class JSSegmentIterator;
class JSSegmenter;
class JSV8BreakIterator;
class JSWeakCell;
class JSWeakCollection;
class JSWeakFactory;
class JSWeakFactoryCleanupIterator;
class JSWeakMap;
class JSWeakSet;
class MaybeObject;
class PromiseCapability;
class PromiseFulfillReactionJobTask;
class PromiseReaction;
class PromiseReactionJobTask;
class PromiseRejectReactionJobTask;
class TorqueAssembler;
class Zone;

template <typename T>
class Signature;

struct UntaggedT {};

struct IntegralT : UntaggedT {};

struct WordT : IntegralT {
  static const MachineRepresentation kMachineRepresentation =
      (kPointerSize == 4) ? MachineRepresentation::kWord32
                          : MachineRepresentation::kWord64;
};

struct RawPtrT : WordT {
  static constexpr MachineType kMachineType = MachineType::Pointer();
};

template <class To>
struct RawPtr : RawPtrT {};

struct Word32T : IntegralT {
  static const MachineRepresentation kMachineRepresentation =
      MachineRepresentation::kWord32;
};
struct Int32T : Word32T {
  static constexpr MachineType kMachineType = MachineType::Int32();
};
struct Uint32T : Word32T {
  static constexpr MachineType kMachineType = MachineType::Uint32();
};

struct Word64T : IntegralT {
  static const MachineRepresentation kMachineRepresentation =
      MachineRepresentation::kWord64;
};
struct Int64T : Word64T {
  static constexpr MachineType kMachineType = MachineType::Int64();
};
struct Uint64T : Word64T {
  static constexpr MachineType kMachineType = MachineType::Uint64();
};

struct IntPtrT : WordT {
  static constexpr MachineType kMachineType = MachineType::IntPtr();
};
struct UintPtrT : WordT {
  static constexpr MachineType kMachineType = MachineType::UintPtr();
};

struct Float32T : UntaggedT {
  static const MachineRepresentation kMachineRepresentation =
      MachineRepresentation::kFloat32;
  static constexpr MachineType kMachineType = MachineType::Float32();
};

struct Float64T : UntaggedT {
  static const MachineRepresentation kMachineRepresentation =
      MachineRepresentation::kFloat64;
  static constexpr MachineType kMachineType = MachineType::Float64();
};

// Result of a comparison operation.
struct BoolT : Word32T {};

// Value type of a Turbofan node with two results.
template <class T1, class T2>
struct PairT {};

inline constexpr MachineType CommonMachineType(MachineType type1,
                                               MachineType type2) {
  return (type1 == type2) ? type1
                          : ((type1.IsTagged() && type2.IsTagged())
                                 ? MachineType::AnyTagged()
                                 : MachineType::None());
}

template <class Type, class Enable = void>
struct MachineTypeOf {
  static constexpr MachineType value = Type::kMachineType;
};

template <class Type, class Enable>
constexpr MachineType MachineTypeOf<Type, Enable>::value;

template <>
struct MachineTypeOf<Object> {
  static constexpr MachineType value = MachineType::AnyTagged();
};
template <>
struct MachineTypeOf<MaybeObject> {
  static constexpr MachineType value = MachineType::AnyTagged();
};
template <>
struct MachineTypeOf<Smi> {
  static constexpr MachineType value = MachineType::TaggedSigned();
};
template <class HeapObjectSubtype>
struct MachineTypeOf<HeapObjectSubtype,
                     typename std::enable_if<std::is_base_of<
                         HeapObject, HeapObjectSubtype>::value>::type> {
  static constexpr MachineType value = MachineType::TaggedPointer();
};

template <class HeapObjectSubtype>
constexpr MachineType MachineTypeOf<
    HeapObjectSubtype, typename std::enable_if<std::is_base_of<
                           HeapObject, HeapObjectSubtype>::value>::type>::value;

template <class Type, class Enable = void>
struct MachineRepresentationOf {
  static const MachineRepresentation value = Type::kMachineRepresentation;
};
template <class T>
struct MachineRepresentationOf<
    T, typename std::enable_if<std::is_base_of<Object, T>::value>::type> {
  static const MachineRepresentation value =
      MachineTypeOf<T>::value.representation();
};
template <class T>
struct MachineRepresentationOf<
    T, typename std::enable_if<std::is_base_of<MaybeObject, T>::value>::type> {
  static const MachineRepresentation value =
      MachineTypeOf<T>::value.representation();
};

template <class T>
struct is_valid_type_tag {
  static const bool value = std::is_base_of<Object, T>::value ||
                            std::is_base_of<ObjectPtr, T>::value ||
                            std::is_base_of<UntaggedT, T>::value ||
                            std::is_base_of<MaybeObject, T>::value ||
                            std::is_same<ExternalReference, T>::value;
  static const bool is_tagged = std::is_base_of<Object, T>::value ||
                                std::is_base_of<MaybeObject, T>::value;
};

template <class T1, class T2>
struct is_valid_type_tag<PairT<T1, T2>> {
  static const bool value =
      is_valid_type_tag<T1>::value && is_valid_type_tag<T2>::value;
  static const bool is_tagged = false;
};

template <class T1, class T2>
struct UnionT;

template <class T1, class T2>
struct is_valid_type_tag<UnionT<T1, T2>> {
  static const bool is_tagged =
      is_valid_type_tag<T1>::is_tagged && is_valid_type_tag<T2>::is_tagged;
  static const bool value = is_tagged;
};

template <class T1, class T2>
struct UnionT {
  static constexpr MachineType kMachineType =
      CommonMachineType(MachineTypeOf<T1>::value, MachineTypeOf<T2>::value);
  static const MachineRepresentation kMachineRepresentation =
      kMachineType.representation();
  static_assert(kMachineRepresentation != MachineRepresentation::kNone,
                "no common representation");
  static_assert(is_valid_type_tag<T1>::is_tagged &&
                    is_valid_type_tag<T2>::is_tagged,
                "union types are only possible for tagged values");
};

using Number = UnionT<Smi, HeapNumber>;
using Numeric = UnionT<Number, BigInt>;

#define ENUM_ELEMENT(Name) k##Name,
#define ENUM_STRUCT_ELEMENT(NAME, Name, name) k##Name,
enum class ObjectType {
  kObject,
  OBJECT_TYPE_LIST(ENUM_ELEMENT) HEAP_OBJECT_TYPE_LIST(ENUM_ELEMENT)
      STRUCT_LIST(ENUM_STRUCT_ELEMENT)
};
#undef ENUM_ELEMENT
#undef ENUM_STRUCT_ELEMENT

class AccessCheckNeeded;
class BigIntWrapper;
class ClassBoilerplate;
class BooleanWrapper;
class CompilationCacheTable;
class Constructor;
class Filler;
class InternalizedString;
class JSArgumentsObject;
class JSContextExtensionObject;
class JSError;
class JSSloppyArgumentsObject;
class MapCache;
class MutableHeapNumber;
class NativeContext;
class NumberWrapper;
class ScriptWrapper;
class SloppyArgumentsElements;
class StringWrapper;
class SymbolWrapper;
class Undetectable;
class UniqueName;
class WasmExceptionObject;
class WasmExportedFunctionData;
class WasmGlobalObject;
class WasmMemoryObject;
class WasmModuleObject;
class WasmTableObject;

template <class T>
struct ObjectTypeOf {};

#define OBJECT_TYPE_CASE(Name)                           \
  template <>                                            \
  struct ObjectTypeOf<Name> {                            \
    static const ObjectType value = ObjectType::k##Name; \
  };
#define OBJECT_TYPE_STRUCT_CASE(NAME, Name, name)        \
  template <>                                            \
  struct ObjectTypeOf<Name> {                            \
    static const ObjectType value = ObjectType::k##Name; \
  };
#define OBJECT_TYPE_TEMPLATE_CASE(Name)                  \
  template <class... Args>                               \
  struct ObjectTypeOf<Name<Args...>> {                   \
    static const ObjectType value = ObjectType::k##Name; \
  };
OBJECT_TYPE_CASE(Object)
OBJECT_TYPE_LIST(OBJECT_TYPE_CASE)
HEAP_OBJECT_ORDINARY_TYPE_LIST(OBJECT_TYPE_CASE)
STRUCT_LIST(OBJECT_TYPE_STRUCT_CASE)
HEAP_OBJECT_TEMPLATE_TYPE_LIST(OBJECT_TYPE_TEMPLATE_CASE)
#undef OBJECT_TYPE_CASE
#undef OBJECT_TYPE_STRUCT_CASE
#undef OBJECT_TYPE_TEMPLATE_CASE

Smi* CheckObjectType(Object* value, Smi* type, String* location);

namespace compiler {

class CallDescriptor;
class CodeAssemblerLabel;
class CodeAssemblerVariable;
template <class T>
class TypedCodeAssemblerVariable;
class CodeAssemblerState;
class Node;
class RawMachineAssembler;
class RawMachineLabel;

typedef ZoneVector<CodeAssemblerVariable*> CodeAssemblerVariableList;

typedef std::function<void()> CodeAssemblerCallback;

// TODO(3770): The HeapObject/HeapObjectPtr dance is temporary (while the
// incremental transition is in progress, we want to pretend that subclasses
// of HeapObjectPtr are also subclasses of Object/HeapObject); it can be
// removed when the migration is complete.
template <class T, class U>
struct is_subtype {
  static const bool value = std::is_base_of<U, T>::value ||
                            (std::is_base_of<U, HeapObject>::value &&
                             std::is_base_of<HeapObjectPtr, T>::value);
};
template <class T1, class T2, class U>
struct is_subtype<UnionT<T1, T2>, U> {
  static const bool value =
      is_subtype<T1, U>::value && is_subtype<T2, U>::value;
};
template <class T, class U1, class U2>
struct is_subtype<T, UnionT<U1, U2>> {
  static const bool value =
      is_subtype<T, U1>::value || is_subtype<T, U2>::value;
};
template <class T1, class T2, class U1, class U2>
struct is_subtype<UnionT<T1, T2>, UnionT<U1, U2>> {
  static const bool value =
      (is_subtype<T1, U1>::value || is_subtype<T1, U2>::value) &&
      (is_subtype<T2, U1>::value || is_subtype<T2, U2>::value);
};

template <class T, class U>
struct types_have_common_values {
  static const bool value = is_subtype<T, U>::value || is_subtype<U, T>::value;
};
template <class U>
struct types_have_common_values<Uint32T, U> {
  static const bool value = types_have_common_values<Word32T, U>::value;
};
template <class U>
struct types_have_common_values<Int32T, U> {
  static const bool value = types_have_common_values<Word32T, U>::value;
};
template <class U>
struct types_have_common_values<Uint64T, U> {
  static const bool value = types_have_common_values<Word64T, U>::value;
};
template <class U>
struct types_have_common_values<Int64T, U> {
  static const bool value = types_have_common_values<Word64T, U>::value;
};
template <class U>
struct types_have_common_values<IntPtrT, U> {
  static const bool value = types_have_common_values<WordT, U>::value;
};
template <class U>
struct types_have_common_values<UintPtrT, U> {
  static const bool value = types_have_common_values<WordT, U>::value;
};
template <class T1, class T2, class U>
struct types_have_common_values<UnionT<T1, T2>, U> {
  static const bool value = types_have_common_values<T1, U>::value ||
                            types_have_common_values<T2, U>::value;
};

template <class T, class U1, class U2>
struct types_have_common_values<T, UnionT<U1, U2>> {
  static const bool value = types_have_common_values<T, U1>::value ||
                            types_have_common_values<T, U2>::value;
};
template <class T1, class T2, class U1, class U2>
struct types_have_common_values<UnionT<T1, T2>, UnionT<U1, U2>> {
  static const bool value = types_have_common_values<T1, U1>::value ||
                            types_have_common_values<T1, U2>::value ||
                            types_have_common_values<T2, U1>::value ||
                            types_have_common_values<T2, U2>::value;
};

template <class T>
struct types_have_common_values<T, MaybeObject> {
  static const bool value = types_have_common_values<T, Object>::value;
};

template <class T>
struct types_have_common_values<MaybeObject, T> {
  static const bool value = types_have_common_values<Object, T>::value;
};

// TNode<T> is an SSA value with the static type tag T, which is one of the
// following:
//   - a subclass of internal::Object represents a tagged type
//   - a subclass of internal::ObjectPtr represents a tagged type
//   - a subclass of internal::UntaggedT represents an untagged type
//   - ExternalReference
//   - PairT<T1, T2> for an operation returning two values, with types T1
//     and T2
//   - UnionT<T1, T2> represents either a value of type T1 or of type T2.
template <class T>
class TNode {
 public:
  static_assert(is_valid_type_tag<T>::value, "invalid type tag");

  template <class U,
            typename std::enable_if<is_subtype<U, T>::value, int>::type = 0>
  TNode(const TNode<U>& other) : node_(other) {}
  TNode() : node_(nullptr) {}

  TNode operator=(TNode other) {
    DCHECK_NOT_NULL(other.node_);
    node_ = other.node_;
    return *this;
  }

  operator compiler::Node*() const { return node_; }

  static TNode UncheckedCast(compiler::Node* node) { return TNode(node); }

 protected:
  explicit TNode(compiler::Node* node) : node_(node) {}

 private:
  compiler::Node* node_;
};

// SloppyTNode<T> is a variant of TNode<T> and allows implicit casts from
// Node*. It is intended for function arguments as long as some call sites
// still use untyped Node* arguments.
// TODO(tebbi): Delete this class once transition is finished.
template <class T>
class SloppyTNode : public TNode<T> {
 public:
  SloppyTNode(compiler::Node* node)  // NOLINT(runtime/explicit)
      : TNode<T>(node) {}
  template <class U, typename std::enable_if<is_subtype<U, T>::value,
                                             int>::type = 0>
  SloppyTNode(const TNode<U>& other)  // NOLINT(runtime/explicit)
      : TNode<T>(other) {}
};

// This macro alias allows to use PairT<T1, T2> as a macro argument.
#define PAIR_TYPE(T1, T2) PairT<T1, T2>

#define CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V)          \
  V(Float32Equal, BoolT, Float32T, Float32T)              \
  V(Float32LessThan, BoolT, Float32T, Float32T)           \
  V(Float32LessThanOrEqual, BoolT, Float32T, Float32T)    \
  V(Float32GreaterThan, BoolT, Float32T, Float32T)        \
  V(Float32GreaterThanOrEqual, BoolT, Float32T, Float32T) \
  V(Float64Equal, BoolT, Float64T, Float64T)              \
  V(Float64NotEqual, BoolT, Float64T, Float64T)           \
  V(Float64LessThan, BoolT, Float64T, Float64T)           \
  V(Float64LessThanOrEqual, BoolT, Float64T, Float64T)    \
  V(Float64GreaterThan, BoolT, Float64T, Float64T)        \
  V(Float64GreaterThanOrEqual, BoolT, Float64T, Float64T) \
  /* Use Word32Equal if you need Int32Equal */            \
  V(Int32GreaterThan, BoolT, Word32T, Word32T)            \
  V(Int32GreaterThanOrEqual, BoolT, Word32T, Word32T)     \
  V(Int32LessThan, BoolT, Word32T, Word32T)               \
  V(Int32LessThanOrEqual, BoolT, Word32T, Word32T)        \
  /* Use WordEqual if you need IntPtrEqual */             \
  V(IntPtrLessThan, BoolT, WordT, WordT)                  \
  V(IntPtrLessThanOrEqual, BoolT, WordT, WordT)           \
  V(IntPtrGreaterThan, BoolT, WordT, WordT)               \
  V(IntPtrGreaterThanOrEqual, BoolT, WordT, WordT)        \
  /* Use Word32Equal if you need Uint32Equal */           \
  V(Uint32LessThan, BoolT, Word32T, Word32T)              \
  V(Uint32LessThanOrEqual, BoolT, Word32T, Word32T)       \
  V(Uint32GreaterThan, BoolT, Word32T, Word32T)           \
  V(Uint32GreaterThanOrEqual, BoolT, Word32T, Word32T)    \
  /* Use WordEqual if you need UintPtrEqual */            \
  V(UintPtrLessThan, BoolT, WordT, WordT)                 \
  V(UintPtrLessThanOrEqual, BoolT, WordT, WordT)          \
  V(UintPtrGreaterThan, BoolT, WordT, WordT)              \
  V(UintPtrGreaterThanOrEqual, BoolT, WordT, WordT)

#define CODE_ASSEMBLER_BINARY_OP_LIST(V)                                \
  CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V)                              \
  V(Float64Add, Float64T, Float64T, Float64T)                           \
  V(Float64Sub, Float64T, Float64T, Float64T)                           \
  V(Float64Mul, Float64T, Float64T, Float64T)                           \
  V(Float64Div, Float64T, Float64T, Float64T)                           \
  V(Float64Mod, Float64T, Float64T, Float64T)                           \
  V(Float64Atan2, Float64T, Float64T, Float64T)                         \
  V(Float64Pow, Float64T, Float64T, Float64T)                           \
  V(Float64Max, Float64T, Float64T, Float64T)                           \
  V(Float64Min, Float64T, Float64T, Float64T)                           \
  V(Float64InsertLowWord32, Float64T, Float64T, Word32T)                \
  V(Float64InsertHighWord32, Float64T, Float64T, Word32T)               \
  V(IntPtrAddWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT, IntPtrT) \
  V(IntPtrSubWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT, IntPtrT) \
  V(Int32Add, Word32T, Word32T, Word32T)                                \
  V(Int32AddWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T)     \
  V(Int32Sub, Word32T, Word32T, Word32T)                                \
  V(Int32SubWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T)     \
  V(Int32Mul, Word32T, Word32T, Word32T)                                \
  V(Int32MulWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T)     \
  V(Int32Div, Int32T, Int32T, Int32T)                                   \
  V(Int32Mod, Int32T, Int32T, Int32T)                                   \
  V(WordRor, WordT, WordT, IntegralT)                                   \
  V(Word32Ror, Word32T, Word32T, Word32T)                               \
  V(Word64Ror, Word64T, Word64T, Word64T)

TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);

#define CODE_ASSEMBLER_UNARY_OP_LIST(V)                        \
  V(Float64Abs, Float64T, Float64T)                            \
  V(Float64Acos, Float64T, Float64T)                           \
  V(Float64Acosh, Float64T, Float64T)                          \
  V(Float64Asin, Float64T, Float64T)                           \
  V(Float64Asinh, Float64T, Float64T)                          \
  V(Float64Atan, Float64T, Float64T)                           \
  V(Float64Atanh, Float64T, Float64T)                          \
  V(Float64Cos, Float64T, Float64T)                            \
  V(Float64Cosh, Float64T, Float64T)                           \
  V(Float64Exp, Float64T, Float64T)                            \
  V(Float64Expm1, Float64T, Float64T)                          \
  V(Float64Log, Float64T, Float64T)                            \
  V(Float64Log1p, Float64T, Float64T)                          \
  V(Float64Log2, Float64T, Float64T)                           \
  V(Float64Log10, Float64T, Float64T)                          \
  V(Float64Cbrt, Float64T, Float64T)                           \
  V(Float64Neg, Float64T, Float64T)                            \
  V(Float64Sin, Float64T, Float64T)                            \
  V(Float64Sinh, Float64T, Float64T)                           \
  V(Float64Sqrt, Float64T, Float64T)                           \
  V(Float64Tan, Float64T, Float64T)                            \
  V(Float64Tanh, Float64T, Float64T)                           \
  V(Float64ExtractLowWord32, Word32T, Float64T)                \
  V(Float64ExtractHighWord32, Word32T, Float64T)               \
  V(BitcastTaggedToWord, IntPtrT, Object)                      \
  V(BitcastMaybeObjectToWord, IntPtrT, MaybeObject)            \
  V(BitcastWordToTagged, Object, WordT)                        \
  V(BitcastWordToTaggedSigned, Smi, WordT)                     \
  V(TruncateFloat64ToFloat32, Float32T, Float64T)              \
  V(TruncateFloat64ToWord32, Word32T, Float64T)                \
  V(TruncateInt64ToInt32, Int32T, Int64T)                      \
  V(ChangeFloat32ToFloat64, Float64T, Float32T)                \
  V(ChangeFloat64ToUint32, Uint32T, Float64T)                  \
  V(ChangeFloat64ToUint64, Uint64T, Float64T)                  \
  V(ChangeInt32ToFloat64, Float64T, Int32T)                    \
  V(ChangeInt32ToInt64, Int64T, Int32T)                        \
  V(ChangeUint32ToFloat64, Float64T, Word32T)                  \
  V(ChangeUint32ToUint64, Uint64T, Word32T)                    \
  V(BitcastInt32ToFloat32, Float32T, Word32T)                  \
  V(BitcastFloat32ToInt32, Word32T, Float32T)                  \
  V(RoundFloat64ToInt32, Int32T, Float64T)                     \
  V(RoundInt32ToFloat32, Int32T, Float32T)                     \
  V(Float64SilenceNaN, Float64T, Float64T)                     \
  V(Float64RoundDown, Float64T, Float64T)                      \
  V(Float64RoundUp, Float64T, Float64T)                        \
  V(Float64RoundTiesEven, Float64T, Float64T)                  \
  V(Float64RoundTruncate, Float64T, Float64T)                  \
  V(Word32Clz, Int32T, Word32T)                                \
  V(Word32BitwiseNot, Word32T, Word32T)                        \
  V(WordNot, WordT, WordT)                                     \
  V(Int32AbsWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T)    \
  V(Int64AbsWithOverflow, PAIR_TYPE(Int64T, BoolT), Int64T)    \
  V(IntPtrAbsWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT) \
  V(Word32BinaryNot, BoolT, Word32T)

// A "public" interface used by components outside of compiler directory to
// create code objects with TurboFan's backend. This class is mostly a thin
// shim around the RawMachineAssembler, and its primary job is to ensure that
// the innards of the RawMachineAssembler and other compiler implementation
// details don't leak outside of the the compiler directory..
//
// V8 components that need to generate low-level code using this interface
// should include this header--and this header only--from the compiler
// directory (this is actually enforced). Since all interesting data
// structures are forward declared, it's not possible for clients to peek
// inside the compiler internals.
//
// In addition to providing isolation between TurboFan and code generation
// clients, CodeAssembler also provides an abstraction for creating variables
// and enhanced Label functionality to merge variable values along paths where
// they have differing values, including loops.
//
// The CodeAssembler itself is stateless (and instances are expected to be
// temporary-scoped and short-lived); all its state is encapsulated into
// a CodeAssemblerState instance.
class V8_EXPORT_PRIVATE CodeAssembler {
 public:
  explicit CodeAssembler(CodeAssemblerState* state) : state_(state) {}
  ~CodeAssembler();

  static Handle<Code> GenerateCode(CodeAssemblerState* state,
                                   const AssemblerOptions& options);

  bool Is64() const;
  bool IsFloat64RoundUpSupported() const;
  bool IsFloat64RoundDownSupported() const;
  bool IsFloat64RoundTiesEvenSupported() const;
  bool IsFloat64RoundTruncateSupported() const;
  bool IsInt32AbsWithOverflowSupported() const;
  bool IsInt64AbsWithOverflowSupported() const;
  bool IsIntPtrAbsWithOverflowSupported() const;

  // Shortened aliases for use in CodeAssembler subclasses.
  using Label = CodeAssemblerLabel;
  using Variable = CodeAssemblerVariable;
  template <class T>
  using TVariable = TypedCodeAssemblerVariable<T>;
  using VariableList = CodeAssemblerVariableList;

  // ===========================================================================
  // Base Assembler
  // ===========================================================================

  template <class PreviousType, bool FromTyped>
  class CheckedNode {
   public:
#ifdef DEBUG
    CheckedNode(Node* node, CodeAssembler* code_assembler, const char* location)
        : node_(node), code_assembler_(code_assembler), location_(location) {}
#else
    CheckedNode(compiler::Node* node, CodeAssembler*, const char*)
        : node_(node) {}
#endif

    template <class A>
    operator TNode<A>() {
      static_assert(
          !std::is_same<A, MaybeObject>::value,
          "Can't cast to MaybeObject, use explicit conversion functions. ");

      static_assert(types_have_common_values<A, PreviousType>::value,
                    "Incompatible types: this cast can never succeed.");
      static_assert(std::is_convertible<TNode<A>, TNode<Object>>::value ||
                        std::is_convertible<TNode<A>, TNode<ObjectPtr>>::value,
                    "Coercion to untagged values cannot be "
                    "checked.");
      static_assert(
          !FromTyped ||
              !std::is_convertible<TNode<PreviousType>, TNode<A>>::value,
          "Unnecessary CAST: types are convertible.");
#ifdef DEBUG
      if (FLAG_debug_code) {
        if (std::is_same<PreviousType, MaybeObject>::value) {
          code_assembler_->GenerateCheckMaybeObjectIsObject(node_, location_);
        }
        Node* function = code_assembler_->ExternalConstant(
            ExternalReference::check_object_type());
        code_assembler_->CallCFunction3(
            MachineType::AnyTagged(), MachineType::AnyTagged(),
            MachineType::TaggedSigned(), MachineType::AnyTagged(), function,
            node_,
            code_assembler_->SmiConstant(
                static_cast<int>(ObjectTypeOf<A>::value)),
            code_assembler_->StringConstant(location_));
      }
#endif
      return TNode<A>::UncheckedCast(node_);
    }

    template <class A>
    operator SloppyTNode<A>() {
      return implicit_cast<TNode<A>>(*this);
    }

    Node* node() const { return node_; }

   private:
    Node* node_;
#ifdef DEBUG
    CodeAssembler* code_assembler_;
    const char* location_;
#endif
  };

  template <class T>
  TNode<T> UncheckedCast(Node* value) {
    return TNode<T>::UncheckedCast(value);
  }
  template <class T, class U>
  TNode<T> UncheckedCast(TNode<U> value) {
    static_assert(types_have_common_values<T, U>::value,
                  "Incompatible types: this cast can never succeed.");
    return TNode<T>::UncheckedCast(value);
  }

  // ReinterpretCast<T>(v) has the power to cast even when the type of v is
  // unrelated to T. Use with care.
  template <class T>
  TNode<T> ReinterpretCast(Node* value) {
    return TNode<T>::UncheckedCast(value);
  }

  CheckedNode<Object, false> Cast(Node* value, const char* location = "") {
    return {value, this, location};
  }

  template <class T>
  CheckedNode<T, true> Cast(TNode<T> value, const char* location = "") {
    return {value, this, location};
  }

#ifdef DEBUG
#define STRINGIFY(x) #x
#define TO_STRING_LITERAL(x) STRINGIFY(x)
#define CAST(x) \
  Cast(x, "CAST(" #x ") at " __FILE__ ":" TO_STRING_LITERAL(__LINE__))
#else
#define CAST(x) Cast(x)
#endif

#ifdef DEBUG
  void GenerateCheckMaybeObjectIsObject(Node* node, const char* location);
#endif

  // Constants.
  TNode<Int32T> Int32Constant(int32_t value);
  TNode<Int64T> Int64Constant(int64_t value);
  TNode<IntPtrT> IntPtrConstant(intptr_t value);
  TNode<Uint32T> Uint32Constant(uint32_t value) {
    return Unsigned(Int32Constant(bit_cast<int32_t>(value)));
  }
  TNode<UintPtrT> UintPtrConstant(uintptr_t value) {
    return Unsigned(IntPtrConstant(bit_cast<intptr_t>(value)));
  }
  TNode<Number> NumberConstant(double value);
  TNode<Smi> SmiConstant(Smi* value);
  TNode<Smi> SmiConstant(int value);
  template <typename E,
            typename = typename std::enable_if<std::is_enum<E>::value>::type>
  TNode<Smi> SmiConstant(E value) {
    STATIC_ASSERT(sizeof(E) <= sizeof(int));
    return SmiConstant(static_cast<int>(value));
  }
  TNode<HeapObject> UntypedHeapConstant(Handle<HeapObject> object);
  template <class Type>
  TNode<Type> HeapConstant(Handle<Type> object) {
    return UncheckedCast<Type>(UntypedHeapConstant(object));
  }
  TNode<String> StringConstant(const char* str);
  TNode<Oddball> BooleanConstant(bool value);
  TNode<ExternalReference> ExternalConstant(ExternalReference address);
  TNode<Float64T> Float64Constant(double value);
  TNode<HeapNumber> NaNConstant();
  TNode<BoolT> Int32TrueConstant() {
    return ReinterpretCast<BoolT>(Int32Constant(1));
  }
  TNode<BoolT> Int32FalseConstant() {
    return ReinterpretCast<BoolT>(Int32Constant(0));
  }
  TNode<BoolT> BoolConstant(bool value) {
    return value ? Int32TrueConstant() : Int32FalseConstant();
  }

  bool ToInt32Constant(Node* node, int32_t& out_value);
  bool ToInt64Constant(Node* node, int64_t& out_value);
  bool ToSmiConstant(Node* node, Smi*& out_value);
  bool ToIntPtrConstant(Node* node, intptr_t& out_value);

  bool IsUndefinedConstant(TNode<Object> node);
  bool IsNullConstant(TNode<Object> node);

  TNode<Int32T> Signed(TNode<Word32T> x) { return UncheckedCast<Int32T>(x); }
  TNode<IntPtrT> Signed(TNode<WordT> x) { return UncheckedCast<IntPtrT>(x); }
  TNode<Uint32T> Unsigned(TNode<Word32T> x) {
    return UncheckedCast<Uint32T>(x);
  }
  TNode<UintPtrT> Unsigned(TNode<WordT> x) {
    return UncheckedCast<UintPtrT>(x);
  }

  static constexpr int kTargetParameterIndex = -1;

  Node* Parameter(int value);

  TNode<Context> GetJSContextParameter();
  void Return(SloppyTNode<Object> value);
  void Return(SloppyTNode<Object> value1, SloppyTNode<Object> value2);
  void Return(SloppyTNode<Object> value1, SloppyTNode<Object> value2,
              SloppyTNode<Object> value3);
  void PopAndReturn(Node* pop, Node* value);

  void ReturnIf(Node* condition, Node* value);

  void ReturnRaw(Node* value);

  void DebugAbort(Node* message);
  void DebugBreak();
  void Unreachable();
  void Comment(const char* format, ...);

  void Bind(Label* label);
#if DEBUG
  void Bind(Label* label, AssemblerDebugInfo debug_info);
#endif  // DEBUG
  void Goto(Label* label);
  void GotoIf(SloppyTNode<IntegralT> condition, Label* true_label);
  void GotoIfNot(SloppyTNode<IntegralT> condition, Label* false_label);
  void Branch(SloppyTNode<IntegralT> condition, Label* true_label,
              Label* false_label);

  void Branch(TNode<BoolT> condition, const std::function<void()>& true_body,
              const std::function<void()>& false_body);
  void Branch(TNode<BoolT> condition, Label* true_label,
              const std::function<void()>& false_body);
  void Branch(TNode<BoolT> condition, const std::function<void()>& true_body,
              Label* false_label);

  void Switch(Node* index, Label* default_label, const int32_t* case_values,
              Label** case_labels, size_t case_count);

  // Access to the frame pointer
  Node* LoadFramePointer();
  Node* LoadParentFramePointer();

  // Access to the stack pointer
  Node* LoadStackPointer();

  // Poison |value| on speculative paths.
  TNode<Object> TaggedPoisonOnSpeculation(SloppyTNode<Object> value);
  TNode<WordT> WordPoisonOnSpeculation(SloppyTNode<WordT> value);

  // Load raw memory location.
  Node* Load(MachineType rep, Node* base,
             LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
  template <class Type>
  TNode<Type> Load(MachineType rep, TNode<RawPtr<Type>> base) {
    DCHECK(
        IsSubtype(rep.representation(), MachineRepresentationOf<Type>::value));
    return UncheckedCast<Type>(Load(rep, static_cast<Node*>(base)));
  }
  Node* Load(MachineType rep, Node* base, Node* offset,
             LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
  Node* AtomicLoad(MachineType rep, Node* base, Node* offset);

  // Load a value from the root array.
  TNode<Object> LoadRoot(RootIndex root_index);

  // Store value to raw memory location.
  Node* Store(Node* base, Node* value);
  Node* Store(Node* base, Node* offset, Node* value);
  Node* StoreWithMapWriteBarrier(Node* base, Node* offset, Node* value);
  Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
  Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* offset,
                            Node* value);
  // {value_high} is used for 64-bit stores on 32-bit platforms, must be
  // nullptr in other cases.
  Node* AtomicStore(MachineRepresentation rep, Node* base, Node* offset,
                    Node* value, Node* value_high = nullptr);

  // Exchange value at raw memory location
  Node* AtomicExchange(MachineType type, Node* base, Node* offset, Node* value,
                       Node* value_high = nullptr);

  // Compare and Exchange value at raw memory location
  Node* AtomicCompareExchange(MachineType type, Node* base, Node* offset,
                              Node* old_value, Node* new_value,
                              Node* old_value_high = nullptr,
                              Node* new_value_high = nullptr);

  Node* AtomicAdd(MachineType type, Node* base, Node* offset, Node* value,
                  Node* value_high = nullptr);

  Node* AtomicSub(MachineType type, Node* base, Node* offset, Node* value,
                  Node* value_high = nullptr);

  Node* AtomicAnd(MachineType type, Node* base, Node* offset, Node* value,
                  Node* value_high = nullptr);

  Node* AtomicOr(MachineType type, Node* base, Node* offset, Node* value,
                 Node* value_high = nullptr);

  Node* AtomicXor(MachineType type, Node* base, Node* offset, Node* value,
                  Node* value_high = nullptr);

  // Store a value to the root array.
  Node* StoreRoot(RootIndex root_index, Node* value);

// Basic arithmetic operations.
#define DECLARE_CODE_ASSEMBLER_BINARY_OP(name, ResType, Arg1Type, Arg2Type) \
  TNode<ResType> name(SloppyTNode<Arg1Type> a, SloppyTNode<Arg2Type> b);
  CODE_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_ASSEMBLER_BINARY_OP)
#undef DECLARE_CODE_ASSEMBLER_BINARY_OP

  TNode<IntPtrT> WordShr(TNode<IntPtrT> left, TNode<IntegralT> right) {
    return UncheckedCast<IntPtrT>(
        WordShr(static_cast<Node*>(left), static_cast<Node*>(right)));
  }
  TNode<IntPtrT> WordSar(TNode<IntPtrT> left, TNode<IntegralT> right) {
    return UncheckedCast<IntPtrT>(
        WordSar(static_cast<Node*>(left), static_cast<Node*>(right)));
  }

  TNode<IntPtrT> WordAnd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
    return UncheckedCast<IntPtrT>(
        WordAnd(static_cast<Node*>(left), static_cast<Node*>(right)));
  }

  template <class Left, class Right,
            class = typename std::enable_if<
                std::is_base_of<Object, Left>::value &&
                std::is_base_of<Object, Right>::value>::type>
  TNode<BoolT> WordEqual(TNode<Left> left, TNode<Right> right) {
    return WordEqual(ReinterpretCast<WordT>(left),
                     ReinterpretCast<WordT>(right));
  }
  TNode<BoolT> WordEqual(TNode<Object> left, Node* right) {
    return WordEqual(ReinterpretCast<WordT>(left),
                     ReinterpretCast<WordT>(right));
  }
  TNode<BoolT> WordEqual(Node* left, TNode<Object> right) {
    return WordEqual(ReinterpretCast<WordT>(left),
                     ReinterpretCast<WordT>(right));
  }
  template <class Left, class Right,
            class = typename std::enable_if<
                std::is_base_of<Object, Left>::value &&
                std::is_base_of<Object, Right>::value>::type>
  TNode<BoolT> WordNotEqual(TNode<Left> left, TNode<Right> right) {
    return WordNotEqual(ReinterpretCast<WordT>(left),
                        ReinterpretCast<WordT>(right));
  }
  TNode<BoolT> WordNotEqual(TNode<Object> left, Node* right) {
    return WordNotEqual(ReinterpretCast<WordT>(left),
                        ReinterpretCast<WordT>(right));
  }
  TNode<BoolT> WordNotEqual(Node* left, TNode<Object> right) {
    return WordNotEqual(ReinterpretCast<WordT>(left),
                        ReinterpretCast<WordT>(right));
  }

  TNode<BoolT> IntPtrEqual(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
  TNode<BoolT> WordEqual(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
  TNode<BoolT> WordNotEqual(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
  TNode<BoolT> Word32Equal(SloppyTNode<Word32T> left,
                           SloppyTNode<Word32T> right);
  TNode<BoolT> Word32NotEqual(SloppyTNode<Word32T> left,
                              SloppyTNode<Word32T> right);
  TNode<BoolT> Word64Equal(SloppyTNode<Word64T> left,
                           SloppyTNode<Word64T> right);
  TNode<BoolT> Word64NotEqual(SloppyTNode<Word64T> left,
                              SloppyTNode<Word64T> right);

  TNode<Int32T> Int32Add(TNode<Int32T> left, TNode<Int32T> right) {
    return Signed(
        Int32Add(static_cast<Node*>(left), static_cast<Node*>(right)));
  }

  TNode<Uint32T> Uint32Add(TNode<Uint32T> left, TNode<Uint32T> right) {
    return Unsigned(
        Int32Add(static_cast<Node*>(left), static_cast<Node*>(right)));
  }

  TNode<WordT> IntPtrAdd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
  TNode<IntPtrT> IntPtrDiv(TNode<IntPtrT> left, TNode<IntPtrT> right);
  TNode<WordT> IntPtrSub(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
  TNode<WordT> IntPtrMul(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
  TNode<IntPtrT> IntPtrAdd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
    return Signed(
        IntPtrAdd(static_cast<Node*>(left), static_cast<Node*>(right)));
  }
  TNode<IntPtrT> IntPtrSub(TNode<IntPtrT> left, TNode<IntPtrT> right) {
    return Signed(
        IntPtrSub(static_cast<Node*>(left), static_cast<Node*>(right)));
  }
  TNode<IntPtrT> IntPtrMul(TNode<IntPtrT> left, TNode<IntPtrT> right) {
    return Signed(
        IntPtrMul(static_cast<Node*>(left), static_cast<Node*>(right)));
  }
  TNode<UintPtrT> UintPtrAdd(TNode<UintPtrT> left, TNode<UintPtrT> right) {
    return Unsigned(
        IntPtrAdd(static_cast<Node*>(left), static_cast<Node*>(right)));
  }
  TNode<UintPtrT> UintPtrSub(TNode<UintPtrT> left, TNode<UintPtrT> right) {
    return Unsigned(
        IntPtrSub(static_cast<Node*>(left), static_cast<Node*>(right)));
  }

  TNode<WordT> WordShl(SloppyTNode<WordT> value, int shift);
  TNode<WordT> WordShr(SloppyTNode<WordT> value, int shift);
  TNode<WordT> WordSar(SloppyTNode<WordT> value, int shift);
  TNode<IntPtrT> WordShr(TNode<IntPtrT> value, int shift) {
    return UncheckedCast<IntPtrT>(WordShr(static_cast<Node*>(value), shift));
  }
  TNode<IntPtrT> WordSar(TNode<IntPtrT> value, int shift) {
    return UncheckedCast<IntPtrT>(WordSar(static_cast<Node*>(value), shift));
  }
  TNode<Word32T> Word32Shr(SloppyTNode<Word32T> value, int shift);

  TNode<WordT> WordOr(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
  TNode<WordT> WordAnd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
  TNode<WordT> WordXor(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
  TNode<WordT> WordShl(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
  TNode<WordT> WordShr(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
  TNode<WordT> WordSar(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
  TNode<Word32T> Word32Or(SloppyTNode<Word32T> left,
                          SloppyTNode<Word32T> right);
  TNode<Word32T> Word32And(SloppyTNode<Word32T> left,
                           SloppyTNode<Word32T> right);
  TNode<Word32T> Word32Xor(SloppyTNode<Word32T> left,
                           SloppyTNode<Word32T> right);
  TNode<Word32T> Word32Shl(SloppyTNode<Word32T> left,
                           SloppyTNode<Word32T> right);
  TNode<Word32T> Word32Shr(SloppyTNode<Word32T> left,
                           SloppyTNode<Word32T> right);
  TNode<Word32T> Word32Sar(SloppyTNode<Word32T> left,
                           SloppyTNode<Word32T> right);
  TNode<Word64T> Word64Or(SloppyTNode<Word64T> left,
                          SloppyTNode<Word64T> right);
  TNode<Word64T> Word64And(SloppyTNode<Word64T> left,
                           SloppyTNode<Word64T> right);
  TNode<Word64T> Word64Xor(SloppyTNode<Word64T> left,
                           SloppyTNode<Word64T> right);
  TNode<Word64T> Word64Shl(SloppyTNode<Word64T> left,
                           SloppyTNode<Word64T> right);
  TNode<Word64T> Word64Shr(SloppyTNode<Word64T> left,
                           SloppyTNode<Word64T> right);
  TNode<Word64T> Word64Sar(SloppyTNode<Word64T> left,
                           SloppyTNode<Word64T> right);

// Unary
#define DECLARE_CODE_ASSEMBLER_UNARY_OP(name, ResType, ArgType) \
  TNode<ResType> name(SloppyTNode<ArgType> a);
  CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
#undef DECLARE_CODE_ASSEMBLER_UNARY_OP

  // Changes a double to an inptr_t for pointer arithmetic outside of Smi range.
  // Assumes that the double can be exactly represented as an int.
  TNode<UintPtrT> ChangeFloat64ToUintPtr(SloppyTNode<Float64T> value);
  // Same in the opposite direction.
  TNode<Float64T> ChangeUintPtrToFloat64(TNode<UintPtrT> value);

  // Changes an intptr_t to a double, e.g. for storing an element index
  // outside Smi range in a HeapNumber. Lossless on 32-bit,
  // rounds on 64-bit (which doesn't affect valid element indices).
  Node* RoundIntPtrToFloat64(Node* value);
  // No-op on 32-bit, otherwise zero extend.
  TNode<UintPtrT> ChangeUint32ToWord(SloppyTNode<Word32T> value);
  // No-op on 32-bit, otherwise sign extend.
  TNode<IntPtrT> ChangeInt32ToIntPtr(SloppyTNode<Word32T> value);

  // No-op that guarantees that the value is kept alive till this point even
  // if GC happens.
  Node* Retain(Node* value);

  // Projections
  Node* Projection(int index, Node* value);

  template <int index, class T1, class T2>
  TNode<typename std::tuple_element<index, std::tuple<T1, T2>>::type>
  Projection(TNode<PairT<T1, T2>> value) {
    return UncheckedCast<
        typename std::tuple_element<index, std::tuple<T1, T2>>::type>(
        Projection(index, value));
  }

  // Calls
  template <class... TArgs>
  TNode<Object> CallRuntime(Runtime::FunctionId function,
                            SloppyTNode<Object> context, TArgs... args) {
    return CallRuntimeImpl(function, context,
                           {implicit_cast<SloppyTNode<Object>>(args)...});
  }

  template <class... TArgs>
  TNode<Object> CallRuntimeWithCEntry(Runtime::FunctionId function,
                                      TNode<Code> centry,
                                      SloppyTNode<Object> context,
                                      TArgs... args) {
    return CallRuntimeWithCEntryImpl(function, centry, context, {args...});
  }

  template <class... TArgs>
  void TailCallRuntime(Runtime::FunctionId function,
                       SloppyTNode<Object> context, TArgs... args) {
    int argc = static_cast<int>(sizeof...(args));
    TNode<Int32T> arity = Int32Constant(argc);
    return TailCallRuntimeImpl(function, arity, context,
                               {implicit_cast<SloppyTNode<Object>>(args)...});
  }

  template <class... TArgs>
  void TailCallRuntime(Runtime::FunctionId function, TNode<Int32T> arity,
                       SloppyTNode<Object> context, TArgs... args) {
    return TailCallRuntimeImpl(function, arity, context,
                               {implicit_cast<SloppyTNode<Object>>(args)...});
  }

  template <class... TArgs>
  void TailCallRuntimeWithCEntry(Runtime::FunctionId function,
                                 TNode<Code> centry, TNode<Object> context,
                                 TArgs... args) {
    int argc = sizeof...(args);
    TNode<Int32T> arity = Int32Constant(argc);
    return TailCallRuntimeWithCEntryImpl(
        function, arity, centry, context,
        {implicit_cast<SloppyTNode<Object>>(args)...});
  }

  //
  // If context passed to CallStub is nullptr, it won't be passed to the stub.
  //

  template <class T = Object, class... TArgs>
  TNode<T> CallStub(Callable const& callable, SloppyTNode<Object> context,
                    TArgs... args) {
    TNode<Code> target = HeapConstant(callable.code());
    return CallStub<T>(callable.descriptor(), target, context, args...);
  }

  template <class T = Object, class... TArgs>
  TNode<T> CallStub(const CallInterfaceDescriptor& descriptor,
                    SloppyTNode<Code> target, SloppyTNode<Object> context,
                    TArgs... args) {
    return UncheckedCast<T>(CallStubR(descriptor, 1, target, context, args...));
  }

  template <class... TArgs>
  Node* CallStubR(const CallInterfaceDescriptor& descriptor, size_t result_size,
                  SloppyTNode<Code> target, SloppyTNode<Object> context,
                  TArgs... args) {
    return CallStubRImpl(descriptor, result_size, target, context, {args...});
  }

  Node* CallStubN(const CallInterfaceDescriptor& descriptor, size_t result_size,
                  int input_count, Node* const* inputs);

  template <class... TArgs>
  void TailCallStub(Callable const& callable, SloppyTNode<Object> context,
                    TArgs... args) {
    TNode<Code> target = HeapConstant(callable.code());
    return TailCallStub(callable.descriptor(), target, context, args...);
  }

  template <class... TArgs>
  void TailCallStub(const CallInterfaceDescriptor& descriptor,
                    SloppyTNode<Code> target, SloppyTNode<Object> context,
                    TArgs... args) {
    return TailCallStubImpl(descriptor, target, context, {args...});
  }

  template <class... TArgs>
  Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
                                 Node* target, TArgs... args);

  template <class... TArgs>
  Node* TailCallStubThenBytecodeDispatch(
      const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
      TArgs... args) {
    return TailCallStubThenBytecodeDispatchImpl(descriptor, target, context,
                                                {args...});
  }

  // Tailcalls to the given code object with JSCall linkage. The JS arguments
  // (including receiver) are supposed to be already on the stack.
  // This is a building block for implementing trampoline stubs that are
  // installed instead of code objects with JSCall linkage.
  // Note that no arguments adaption is going on here - all the JavaScript
  // arguments are left on the stack unmodified. Therefore, this tail call can
  // only be used after arguments adaptation has been performed already.
  TNode<Object> TailCallJSCode(TNode<Code> code, TNode<Context> context,
                               TNode<JSFunction> function,
                               TNode<Object> new_target,
                               TNode<Int32T> arg_count);

  template <class... TArgs>
  Node* CallJS(Callable const& callable, Node* context, Node* function,
               Node* receiver, TArgs... args) {
    int argc = static_cast<int>(sizeof...(args));
    Node* arity = Int32Constant(argc);
    return CallStub(callable, context, function, arity, receiver, args...);
  }

  template <class... TArgs>
  Node* ConstructJS(Callable const& callable, Node* context, Node* new_target,
                    TArgs... args) {
    int argc = static_cast<int>(sizeof...(args));
    Node* arity = Int32Constant(argc);
    Node* receiver = LoadRoot(RootIndex::kUndefinedValue);

    // Construct(target, new_target, arity, receiver, arguments...)
    return CallStub(callable, context, new_target, new_target, arity, receiver,
                    args...);
  }

  Node* CallCFunctionN(Signature<MachineType>* signature, int input_count,
                       Node* const* inputs);

  // Call to a C function with one argument.
  Node* CallCFunction1(MachineType return_type, MachineType arg0_type,
                       Node* function, Node* arg0);

  // Call to a C function with one argument, while saving/restoring caller
  // registers except the register used for return value.
  Node* CallCFunction1WithCallerSavedRegisters(MachineType return_type,
                                               MachineType arg0_type,
                                               Node* function, Node* arg0,
                                               SaveFPRegsMode mode);

  // Call to a C function with two arguments.
  Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
                       MachineType arg1_type, Node* function, Node* arg0,
                       Node* arg1);

  // Call to a C function with three arguments.
  Node* CallCFunction3(MachineType return_type, MachineType arg0_type,
                       MachineType arg1_type, MachineType arg2_type,
                       Node* function, Node* arg0, Node* arg1, Node* arg2);

  // Call to a C function with three arguments, while saving/restoring caller
  // registers except the register used for return value.
  Node* CallCFunction3WithCallerSavedRegisters(
      MachineType return_type, MachineType arg0_type, MachineType arg1_type,
      MachineType arg2_type, Node* function, Node* arg0, Node* arg1, Node* arg2,
      SaveFPRegsMode mode);

  // Call to a C function with four arguments.
  Node* CallCFunction4(MachineType return_type, MachineType arg0_type,
                       MachineType arg1_type, MachineType arg2_type,
                       MachineType arg3_type, Node* function, Node* arg0,
                       Node* arg1, Node* arg2, Node* arg3);

  // Call to a C function with five arguments.
  Node* CallCFunction5(MachineType return_type, MachineType arg0_type,
                       MachineType arg1_type, MachineType arg2_type,
                       MachineType arg3_type, MachineType arg4_type,
                       Node* function, Node* arg0, Node* arg1, Node* arg2,
                       Node* arg3, Node* arg4);

  // Call to a C function with six arguments.
  Node* CallCFunction6(MachineType return_type, MachineType arg0_type,
                       MachineType arg1_type, MachineType arg2_type,
                       MachineType arg3_type, MachineType arg4_type,
                       MachineType arg5_type, Node* function, Node* arg0,
                       Node* arg1, Node* arg2, Node* arg3, Node* arg4,
                       Node* arg5);

  // Call to a C function with nine arguments.
  Node* CallCFunction9(MachineType return_type, MachineType arg0_type,
                       MachineType arg1_type, MachineType arg2_type,
                       MachineType arg3_type, MachineType arg4_type,
                       MachineType arg5_type, MachineType arg6_type,
                       MachineType arg7_type, MachineType arg8_type,
                       Node* function, Node* arg0, Node* arg1, Node* arg2,
                       Node* arg3, Node* arg4, Node* arg5, Node* arg6,
                       Node* arg7, Node* arg8);

  // Exception handling support.
  void GotoIfException(Node* node, Label* if_exception,
                       Variable* exception_var = nullptr);

  // Helpers which delegate to RawMachineAssembler.
  Factory* factory() const;
  Isolate* isolate() const;
  Zone* zone() const;

  CodeAssemblerState* state() { return state_; }

  void BreakOnNode(int node_id);

  bool UnalignedLoadSupported(MachineRepresentation rep) const;
  bool UnalignedStoreSupported(MachineRepresentation rep) const;

 protected:
  void RegisterCallGenerationCallbacks(
      const CodeAssemblerCallback& call_prologue,
      const CodeAssemblerCallback& call_epilogue);
  void UnregisterCallGenerationCallbacks();

  bool Word32ShiftIsSafe() const;
  PoisoningMitigationLevel poisoning_level() const;

  bool IsJSFunctionCall() const;

 private:
  TNode<Object> CallRuntimeImpl(Runtime::FunctionId function,
                                TNode<Object> context,
                                std::initializer_list<TNode<Object>> args);

  TNode<Object> CallRuntimeWithCEntryImpl(
      Runtime::FunctionId function, TNode<Code> centry, TNode<Object> context,
      std::initializer_list<TNode<Object>> args);

  void TailCallRuntimeImpl(Runtime::FunctionId function, TNode<Int32T> arity,
                           TNode<Object> context,
                           std::initializer_list<TNode<Object>> args);

  void TailCallRuntimeWithCEntryImpl(Runtime::FunctionId function,
                                     TNode<Int32T> arity, TNode<Code> centry,
                                     TNode<Object> context,
                                     std::initializer_list<TNode<Object>> args);

  void TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
                        TNode<Code> target, TNode<Object> context,
                        std::initializer_list<Node*> args);

  Node* TailCallStubThenBytecodeDispatchImpl(
      const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
      std::initializer_list<Node*> args);

  Node* CallStubRImpl(const CallInterfaceDescriptor& descriptor,
                      size_t result_size, SloppyTNode<Code> target,
                      SloppyTNode<Object> context,
                      std::initializer_list<Node*> args);

  // These two don't have definitions and are here only for catching use cases
  // where the cast is not necessary.
  TNode<Int32T> Signed(TNode<Int32T> x);
  TNode<Uint32T> Unsigned(TNode<Uint32T> x);

  RawMachineAssembler* raw_assembler() const;

  // Calls respective callback registered in the state.
  void CallPrologue();
  void CallEpilogue();

  CodeAssemblerState* state_;

  DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
};

class CodeAssemblerVariable {
 public:
  explicit CodeAssemblerVariable(CodeAssembler* assembler,
                                 MachineRepresentation rep);
  CodeAssemblerVariable(CodeAssembler* assembler, MachineRepresentation rep,
                        Node* initial_value);
#if DEBUG
  CodeAssemblerVariable(CodeAssembler* assembler, AssemblerDebugInfo debug_info,
                        MachineRepresentation rep);
  CodeAssemblerVariable(CodeAssembler* assembler, AssemblerDebugInfo debug_info,
                        MachineRepresentation rep, Node* initial_value);
#endif  // DEBUG

  ~CodeAssemblerVariable();
  void Bind(Node* value);
  Node* value() const;
  MachineRepresentation rep() const;
  bool IsBound() const;

 private:
  class Impl;
  friend class CodeAssemblerLabel;
  friend class CodeAssemblerState;
  friend std::ostream& operator<<(std::ostream&, const Impl&);
  friend std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable&);
  Impl* impl_;
  CodeAssemblerState* state_;
  DISALLOW_COPY_AND_ASSIGN(CodeAssemblerVariable);
};

std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable&);
std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable::Impl&);

template <class T>
class TypedCodeAssemblerVariable : public CodeAssemblerVariable {
 public:
  TypedCodeAssemblerVariable(TNode<T> initial_value, CodeAssembler* assembler)
      : CodeAssemblerVariable(assembler, MachineRepresentationOf<T>::value,
                              initial_value) {}
  explicit TypedCodeAssemblerVariable(CodeAssembler* assembler)
      : CodeAssemblerVariable(assembler, MachineRepresentationOf<T>::value) {}
#if DEBUG
  TypedCodeAssemblerVariable(AssemblerDebugInfo debug_info,
                             CodeAssembler* assembler)
      : CodeAssemblerVariable(assembler, debug_info,
                              MachineRepresentationOf<T>::value) {}
  TypedCodeAssemblerVariable(AssemblerDebugInfo debug_info,
                             TNode<T> initial_value, CodeAssembler* assembler)
      : CodeAssemblerVariable(assembler, debug_info,
                              MachineRepresentationOf<T>::value,
                              initial_value) {}
#endif  // DEBUG

  TNode<T> value() const {
    return TNode<T>::UncheckedCast(CodeAssemblerVariable::value());
  }

  void operator=(TNode<T> value) { Bind(value); }
  void operator=(const TypedCodeAssemblerVariable<T>& variable) {
    Bind(variable.value());
  }

 private:
  using CodeAssemblerVariable::Bind;
};

class CodeAssemblerLabel {
 public:
  enum Type { kDeferred, kNonDeferred };

  explicit CodeAssemblerLabel(
      CodeAssembler* assembler,
      CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
      : CodeAssemblerLabel(assembler, 0, nullptr, type) {}
  CodeAssemblerLabel(
      CodeAssembler* assembler,
      const CodeAssemblerVariableList& merged_variables,
      CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
      : CodeAssemblerLabel(assembler, merged_variables.size(),
                           &(merged_variables[0]), type) {}
  CodeAssemblerLabel(
      CodeAssembler* assembler, size_t count,
      CodeAssemblerVariable* const* vars,
      CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred);
  CodeAssemblerLabel(
      CodeAssembler* assembler,
      std::initializer_list<CodeAssemblerVariable*> vars,
      CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
      : CodeAssemblerLabel(assembler, vars.size(), vars.begin(), type) {}
  CodeAssemblerLabel(
      CodeAssembler* assembler, CodeAssemblerVariable* merged_variable,
      CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
      : CodeAssemblerLabel(assembler, 1, &merged_variable, type) {}
  ~CodeAssemblerLabel();

  inline bool is_bound() const { return bound_; }
  inline bool is_used() const { return merge_count_ != 0; }

 private:
  friend class CodeAssembler;

  void Bind();
#if DEBUG
  void Bind(AssemblerDebugInfo debug_info);
#endif  // DEBUG
  void UpdateVariablesAfterBind();
  void MergeVariables();

  bool bound_;
  size_t merge_count_;
  CodeAssemblerState* state_;
  RawMachineLabel* label_;
  // Map of variables that need to be merged to their phi nodes (or placeholders
  // for those phis).
  std::map<CodeAssemblerVariable::Impl*, Node*> variable_phis_;
  // Map of variables to the list of value nodes that have been added from each
  // merge path in their order of merging.
  std::map<CodeAssemblerVariable::Impl*, std::vector<Node*>> variable_merges_;
};

class CodeAssemblerParameterizedLabelBase {
 public:
  bool is_used() const { return plain_label_.is_used(); }
  explicit CodeAssemblerParameterizedLabelBase(CodeAssembler* assembler,
                                               size_t arity,
                                               CodeAssemblerLabel::Type type)
      : state_(assembler->state()),
        phi_inputs_(arity),
        plain_label_(assembler, type) {}

 protected:
  CodeAssemblerLabel* plain_label() { return &plain_label_; }
  void AddInputs(std::vector<Node*> inputs);
  Node* CreatePhi(MachineRepresentation rep, const std::vector<Node*>& inputs);
  const std::vector<Node*>& CreatePhis(
      std::vector<MachineRepresentation> representations);

 private:
  CodeAssemblerState* state_;
  std::vector<std::vector<Node*>> phi_inputs_;
  std::vector<Node*> phi_nodes_;
  CodeAssemblerLabel plain_label_;
};

template <class... Types>
class CodeAssemblerParameterizedLabel
    : public CodeAssemblerParameterizedLabelBase {
 public:
  static constexpr size_t kArity = sizeof...(Types);
  explicit CodeAssemblerParameterizedLabel(CodeAssembler* assembler,
                                           CodeAssemblerLabel::Type type)
      : CodeAssemblerParameterizedLabelBase(assembler, kArity, type) {}

 private:
  friend class internal::TorqueAssembler;

  void AddInputs(TNode<Types>... inputs) {
    CodeAssemblerParameterizedLabelBase::AddInputs(
        std::vector<Node*>{inputs...});
  }
  void CreatePhis(TNode<Types>*... results) {
    const std::vector<Node*>& phi_nodes =
        CodeAssemblerParameterizedLabelBase::CreatePhis(
            {MachineRepresentationOf<Types>::value...});
    auto it = phi_nodes.begin();
    USE(it);
    ITERATE_PACK(AssignPhi(results, *(it++)));
  }
  template <class T>
  static void AssignPhi(TNode<T>* result, Node* phi) {
    if (phi != nullptr) *result = TNode<T>::UncheckedCast(phi);
  }
};

class V8_EXPORT_PRIVATE CodeAssemblerState {
 public:
  // Create with CallStub linkage.
  // |result_size| specifies the number of results returned by the stub.
  // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
  CodeAssemblerState(Isolate* isolate, Zone* zone,
                     const CallInterfaceDescriptor& descriptor, Code::Kind kind,
                     const char* name, PoisoningMitigationLevel poisoning_level,
                     uint32_t stub_key = 0,
                     int32_t builtin_index = Builtins::kNoBuiltinId);

  // Create with JSCall linkage.
  CodeAssemblerState(Isolate* isolate, Zone* zone, int parameter_count,
                     Code::Kind kind, const char* name,
                     PoisoningMitigationLevel poisoning_level,
                     int32_t builtin_index = Builtins::kNoBuiltinId);

  ~CodeAssemblerState();

  const char* name() const { return name_; }
  int parameter_count() const;

#if DEBUG
  void PrintCurrentBlock(std::ostream& os);
  bool InsideBlock();
#endif  // DEBUG
  void SetInitialDebugInformation(const char* msg, const char* file, int line);

 private:
  friend class CodeAssembler;
  friend class CodeAssemblerLabel;
  friend class CodeAssemblerVariable;
  friend class CodeAssemblerTester;
  friend class CodeAssemblerParameterizedLabelBase;

  CodeAssemblerState(Isolate* isolate, Zone* zone,
                     CallDescriptor* call_descriptor, Code::Kind kind,
                     const char* name, PoisoningMitigationLevel poisoning_level,
                     uint32_t stub_key, int32_t builtin_index);

  std::unique_ptr<RawMachineAssembler> raw_assembler_;
  Code::Kind kind_;
  const char* name_;
  uint32_t stub_key_;
  int32_t builtin_index_;
  bool code_generated_;
  ZoneSet<CodeAssemblerVariable::Impl*> variables_;
  CodeAssemblerCallback call_prologue_;
  CodeAssemblerCallback call_epilogue_;

  DISALLOW_COPY_AND_ASSIGN(CodeAssemblerState);
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_CODE_ASSEMBLER_H_
