// 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/template-utils.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/runtime/runtime.h"
#include "src/zone/zone-containers.h"

namespace v8 {
namespace internal {

class Callable;
class CallInterfaceDescriptor;
class Isolate;
class Factory;
class Zone;

struct UntaggedT {};

struct IntegralT : UntaggedT {};

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

struct IntPtrT : WordT {};
struct UintPtrT : WordT {};

struct RawPtrT : WordT {};

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

struct Word64T : IntegralT {
  static const MachineRepresentation kMachineRepresentation =
      MachineRepresentation::kWord64;
};

struct Int64T : Word64T {};

struct Word32T : IntegralT {
  static const MachineRepresentation kMachineRepresentation =
      MachineRepresentation::kWord32;
};

struct Int32T : Word32T {};

struct Uint32T : Word32T {};

struct Float32T : UntaggedT {
  static const MachineRepresentation kMachineRepresentation =
      MachineRepresentation::kFloat32;
};

struct Float64T : UntaggedT {
  static const MachineRepresentation kMachineRepresentation =
      MachineRepresentation::kFloat64;
};

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

template <class Type, class Enable = void>
struct MachineRepresentationOf {
  static const MachineRepresentation value = Type::kMachineRepresentation;
};
template <>
struct MachineRepresentationOf<Object> {
  static const MachineRepresentation value = MachineRepresentation::kTagged;
};
template <>
struct MachineRepresentationOf<Smi> {
  static const MachineRepresentation value =
      MachineRepresentation::kTaggedSigned;
};
template <class HeapObjectSubtype>
struct MachineRepresentationOf<
    HeapObjectSubtype, typename std::enable_if<std::is_base_of<
                           HeapObject, HeapObjectSubtype>::value>::type> {
  static const MachineRepresentation value =
      MachineRepresentation::kTaggedPointer;
};

#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 CompilationCacheTable;
class Constructor;
class Filler;
class InternalizedString;
class JSArgumentsObject;
class JSContextExtensionObject;
class JSError;
class JSSloppyArgumentsObject;
class MapCache;
class MutableHeapNumber;
class NativeContext;
class SloppyArgumentsElements;
class StringWrapper;
class Undetectable;
class UniqueName;
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 ZoneList<CodeAssemblerVariable*> CodeAssemblerVariableList;

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

// TNode<A> is an SSA value with the static type tag A, which is either a
// subclass of internal::Object or of internal::UntaggedT or it is
// ExternalReference.
template <class A>
class TNode {
 public:
  static_assert(std::is_base_of<Object, A>::value ||
                    std::is_base_of<UntaggedT, A>::value ||
                    std::is_same<ExternalReference, A>::value,
                "type tag must be ExternalReference or a subclass of Object or "
                "UntaggedT");

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

  TNode operator=(TNode other) {
    DCHECK_NULL(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<A> is a variant of TNode<A> 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 A>
class SloppyTNode : public TNode<A> {
 public:
  SloppyTNode(compiler::Node* node)  // NOLINT(runtime/explicit)
      : TNode<A>(node) {}
  template <class B, typename std::enable_if<std::is_base_of<A, B>::value,
                                             int>::type = 0>
  SloppyTNode(const TNode<B>& other)  // NOLINT(runtime/explicit)
      : TNode<A>(other) {}
};

#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(Float64LessThan, BoolT, Float64T, Float64T)           \
  V(Float64LessThanOrEqual, BoolT, Float64T, Float64T)    \
  V(Float64GreaterThan, BoolT, Float64T, Float64T)        \
  V(Float64GreaterThanOrEqual, BoolT, Float64T, Float64T) \
  V(Int32GreaterThan, BoolT, Word32T, Word32T)            \
  V(Int32GreaterThanOrEqual, BoolT, Word32T, Word32T)     \
  V(Int32LessThan, BoolT, Word32T, Word32T)               \
  V(Int32LessThanOrEqual, BoolT, Word32T, Word32T)        \
  V(IntPtrLessThan, BoolT, WordT, WordT)                  \
  V(IntPtrLessThanOrEqual, BoolT, WordT, WordT)           \
  V(IntPtrGreaterThan, BoolT, WordT, WordT)               \
  V(IntPtrGreaterThanOrEqual, BoolT, WordT, WordT)        \
  V(IntPtrEqual, BoolT, WordT, WordT)                     \
  V(Uint32LessThan, BoolT, Word32T, Word32T)              \
  V(Uint32LessThanOrEqual, BoolT, Word32T, Word32T)       \
  V(Uint32GreaterThanOrEqual, BoolT, Word32T, Word32T)    \
  V(UintPtrLessThan, BoolT, WordT, WordT)                 \
  V(UintPtrLessThanOrEqual, BoolT, WordT, WordT)          \
  V(UintPtrGreaterThan, BoolT, WordT, WordT)              \
  V(UintPtrGreaterThanOrEqual, BoolT, WordT, WordT)       \
  V(WordEqual, BoolT, WordT, WordT)                       \
  V(WordNotEqual, BoolT, WordT, WordT)                    \
  V(Word32Equal, BoolT, Word32T, Word32T)                 \
  V(Word32NotEqual, BoolT, Word32T, Word32T)              \
  V(Word64Equal, BoolT, Word64T, Word64T)                 \
  V(Word64NotEqual, BoolT, Word64T, Word64T)

#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, IntPtrT, IntPtrT, IntPtrT)     \
  V(IntPtrSubWithOverflow, IntPtrT, IntPtrT, IntPtrT)     \
  V(Int32Add, Word32T, Word32T, Word32T)                  \
  V(Int32AddWithOverflow, Int32T, Int32T, Int32T)         \
  V(Int32Sub, Word32T, Word32T, Word32T)                  \
  V(Int32Mul, Word32T, Word32T, Word32T)                  \
  V(Int32MulWithOverflow, Int32T, 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(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, Int32T, Float64T)      \
  V(ChangeFloat64ToUint64, Word64T, Float64T)     \
  V(ChangeInt32ToFloat64, Float64T, Int32T)       \
  V(ChangeInt32ToInt64, Int64T, Int32T)           \
  V(ChangeUint32ToFloat64, Float64T, Word32T)     \
  V(ChangeUint32ToUint64, Word64T, Word32T)       \
  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(Word32Not, Word32T, Word32T)                  \
  V(Int32AbsWithOverflow, Int32T, Int32T)         \
  V(Int64AbsWithOverflow, Int64T, Int64T)         \
  V(IntPtrAbsWithOverflow, IntPtrT, IntPtrT)      \
  V(Word32BinaryNot, Word32T, 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);

  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
  // ===========================================================================

  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_base_of<Object, A>::value,
                    "Coercion to untagged values cannot be checked.");
#ifdef DEBUG
      if (FLAG_debug_code) {
        Node* function = code_assembler_->ExternalConstant(
            ExternalReference::check_object_type(code_assembler_->isolate()));
        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 base::implicit_cast<TNode<A>>(*this);
    }

    Node* node() const { return node_; }

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

  CheckedNode Cast(Node* value, const char* location) {
    return CheckedNode(value, this, location);
  }
  template <class A>
  TNode<A> UncheckedCast(Node* value) {
    return TNode<A>::UncheckedCast(value);
  }

#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

  // Constants.
  TNode<Int32T> Int32Constant(int32_t value);
  TNode<Int64T> Int64Constant(int64_t value);
  TNode<IntPtrT> IntPtrConstant(intptr_t value);
  TNode<Object> NumberConstant(double value);
  TNode<Smi> SmiConstant(Smi* value);
  TNode<Smi> SmiConstant(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();

  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);

  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);
  }

  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 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 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();

  // Load raw memory location.
  Node* Load(MachineType rep, Node* base);
  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);
  Node* AtomicLoad(MachineType rep, Node* base, Node* offset);

  // Load a value from the root array.
  TNode<Object> LoadRoot(Heap::RootListIndex 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);
  Node* AtomicStore(MachineRepresentation rep, Node* base, Node* offset,
                    Node* value);

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

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

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

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

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

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

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

  // Store a value to the root array.
  Node* StoreRoot(Heap::RootListIndex 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> 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(UncheckedCast<WordT>(left), UncheckedCast<WordT>(right));
  }
  TNode<BoolT> WordEqual(TNode<Object> left, Node* right) {
    return WordEqual(UncheckedCast<WordT>(left), UncheckedCast<WordT>(right));
  }
  TNode<BoolT> WordEqual(Node* left, TNode<Object> right) {
    return WordEqual(UncheckedCast<WordT>(left), UncheckedCast<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(UncheckedCast<WordT>(left),
                        UncheckedCast<WordT>(right));
  }
  TNode<BoolT> WordNotEqual(TNode<Object> left, Node* right) {
    return WordNotEqual(UncheckedCast<WordT>(left),
                        UncheckedCast<WordT>(right));
  }
  TNode<BoolT> WordNotEqual(Node* left, TNode<Object> right) {
    return WordNotEqual(UncheckedCast<WordT>(left),
                        UncheckedCast<WordT>(right));
  }

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

  TNode<WordT> IntPtrAdd(SloppyTNode<WordT> left, SloppyTNode<WordT> 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<WordT> WordShl(SloppyTNode<WordT> value, int shift);
  TNode<WordT> WordShr(SloppyTNode<WordT> value, int shift);
  TNode<IntPtrT> WordShr(TNode<IntPtrT> value, int shift) {
    return UncheckedCast<IntPtrT>(WordShr(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.
  Node* ChangeFloat64ToUintPtr(Node* 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);

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

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

  template <class... TArgs>
  Node* CallStub(Callable const& callable, Node* context, TArgs... args) {
    Node* target = HeapConstant(callable.code());
    return CallStub(callable.descriptor(), target, context,
                    base::implicit_cast<Node*>(args)...);
  }

  template <class... TArgs>
  Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
                 Node* context, TArgs... args) {
    return CallStubR(descriptor, 1, target, context,
                     base::implicit_cast<Node*>(args)...);
  }

  template <class... TArgs>
  Node* CallStubR(const CallInterfaceDescriptor& descriptor, size_t result_size,
                  Node* target, Node* context, TArgs... args);

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

  template <class... TArgs>
  Node* TailCallStub(Callable const& callable, Node* context, TArgs... args) {
    Node* target = HeapConstant(callable.code());
    return TailCallStub(callable.descriptor(), target, context, args...);
  }

  template <class... TArgs>
  Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
                     Node* context, TArgs... args) {
    return TailCallStubImpl(descriptor, target, context,
                            base::implicit_cast<Node*>(args)...);
  }
  template <class... TArgs>
  Node* TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
                         Node* target, Node* context, TArgs... args);

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

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

  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(Heap::kUndefinedValueRootIndex);

    // 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 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();

 private:
  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

  template <class A,
            class = typename std::enable_if<std::is_base_of<A, T>::value>::type>
  operator TNode<A>() const {
    return TNode<T>::UncheckedCast(value());
  }
  template <class A,
            class = typename std::enable_if<std::is_base_of<A, T>::value>::type>
  operator SloppyTNode<A>() const {
    return value();
  }
  operator Node*() const { return value(); }

  void operator=(TNode<T> value) { Bind(value); }

 private:
  using CodeAssemblerVariable::Bind;
  using CodeAssemblerVariable::value;
};

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.length(),
                           &(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_; }

 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 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, size_t result_size = 1);

  // Create with JSCall linkage.
  CodeAssemblerState(Isolate* isolate, Zone* zone, int parameter_count,
                     Code::Kind kind, const char* name);

  ~CodeAssemblerState();

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

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

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

  CodeAssemblerState(Isolate* isolate, Zone* zone,
                     CallDescriptor* call_descriptor, Code::Kind kind,
                     const char* name);

  std::unique_ptr<RawMachineAssembler> raw_assembler_;
  Code::Kind kind_;
  const char* name_;
  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_
