// Copyright 2014 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_CCTEST_COMPILER_CODEGEN_TESTER_H_
#define V8_CCTEST_COMPILER_CODEGEN_TESTER_H_

#include "src/compilation-info.h"
#include "src/compiler/instruction-selector.h"
#include "src/compiler/pipeline.h"
#include "src/compiler/raw-machine-assembler.h"
#include "src/simulator.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/call-tester.h"

namespace v8 {
namespace internal {
namespace compiler {

template <typename ReturnType>
class RawMachineAssemblerTester : public HandleAndZoneScope,
                                  public CallHelper<ReturnType>,
                                  public RawMachineAssembler {
 public:
  RawMachineAssemblerTester(MachineType p0 = MachineType::None(),
                            MachineType p1 = MachineType::None(),
                            MachineType p2 = MachineType::None(),
                            MachineType p3 = MachineType::None(),
                            MachineType p4 = MachineType::None())
      : HandleAndZoneScope(),
        CallHelper<ReturnType>(
            main_isolate(),
            CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
                            p2, p3, p4)),
        RawMachineAssembler(
            main_isolate(), new (main_zone()) Graph(main_zone()),
            Linkage::GetSimplifiedCDescriptor(
                main_zone(),
                CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0,
                                p1, p2, p3, p4),
                true),
            MachineType::PointerRepresentation(),
            InstructionSelector::SupportedMachineOperatorFlags(),
            InstructionSelector::AlignmentRequirements()) {}

  virtual ~RawMachineAssemblerTester() {}

  void CheckNumber(double expected, Object* number) {
    CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
  }

  void CheckString(const char* expected, Object* string) {
    CHECK(
        this->isolate()->factory()->InternalizeUtf8String(expected)->SameValue(
            string));
  }

  void GenerateCode() { Generate(); }

  Handle<Code> GetCode() {
    Generate();
    return code_.ToHandleChecked();
  }

 protected:
  virtual byte* Generate() {
    if (code_.is_null()) {
      Schedule* schedule = this->Export();
      CallDescriptor* call_descriptor = this->call_descriptor();
      Graph* graph = this->graph();
      CompilationInfo info(ArrayVector("testing"), main_isolate(), main_zone(),
                           Code::STUB);
      code_ = Pipeline::GenerateCodeForTesting(&info, call_descriptor, graph,
                                               schedule);
    }
    return this->code_.ToHandleChecked()->entry();
  }

 private:
  MaybeHandle<Code> code_;
};


template <typename ReturnType>
class BufferedRawMachineAssemblerTester
    : public RawMachineAssemblerTester<int32_t> {
 public:
  BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(),
                                    MachineType p1 = MachineType::None(),
                                    MachineType p2 = MachineType::None(),
                                    MachineType p3 = MachineType::None())
      : BufferedRawMachineAssemblerTester(ComputeParameterCount(p0, p1, p2, p3),
                                          p0, p1, p2, p3) {}

  virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }

  // The BufferedRawMachineAssemblerTester does not pass parameters directly
  // to the constructed IR graph. Instead it passes a pointer to the parameter
  // to the IR graph, and adds Load nodes to the IR graph to load the
  // parameters from memory. Thereby it is possible to pass 64 bit parameters
  // to the IR graph.
  Node* Parameter(size_t index) {
    CHECK_GT(4, index);
    return parameter_nodes_[index];
  }

  // The BufferedRawMachineAssemblerTester adds a Store node to the IR graph
  // to store the graph's return value in memory. The memory address for the
  // Store node is provided as a parameter. By storing the return value in
  // memory it is possible to return 64 bit values.
  void Return(Node* input) {
    Store(MachineTypeForC<ReturnType>().representation(),
          RawMachineAssembler::Parameter(return_parameter_index_), input,
          kNoWriteBarrier);
    RawMachineAssembler::Return(Int32Constant(1234));
  }

  ReturnType Call() {
    ReturnType return_value;
    CSignature::VerifyParams(test_graph_signature_);
    CallHelper<int32_t>::Call(reinterpret_cast<void*>(&return_value));
    return return_value;
  }

  template <typename P0>
  ReturnType Call(P0 p0) {
    ReturnType return_value;
    CSignature::VerifyParams<P0>(test_graph_signature_);
    CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
                              reinterpret_cast<void*>(&return_value));
    return return_value;
  }

  template <typename P0, typename P1>
  ReturnType Call(P0 p0, P1 p1) {
    ReturnType return_value;
    CSignature::VerifyParams<P0, P1>(test_graph_signature_);
    CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
                              reinterpret_cast<void*>(&p1),
                              reinterpret_cast<void*>(&return_value));
    return return_value;
  }

  template <typename P0, typename P1, typename P2>
  ReturnType Call(P0 p0, P1 p1, P2 p2) {
    ReturnType return_value;
    CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
    CallHelper<int32_t>::Call(
        reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
        reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&return_value));
    return return_value;
  }

  template <typename P0, typename P1, typename P2, typename P3>
  ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
    ReturnType return_value;
    CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
    CallHelper<int32_t>::Call(
        reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
        reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3),
        reinterpret_cast<void*>(&return_value));
    return return_value;
  }

 private:
  BufferedRawMachineAssemblerTester(uint32_t return_parameter_index,
                                    MachineType p0, MachineType p1,
                                    MachineType p2, MachineType p3)
      : RawMachineAssemblerTester<int32_t>(
            MachineType::Pointer(),
            p0 == MachineType::None() ? MachineType::None()
                                      : MachineType::Pointer(),
            p1 == MachineType::None() ? MachineType::None()
                                      : MachineType::Pointer(),
            p2 == MachineType::None() ? MachineType::None()
                                      : MachineType::Pointer(),
            p3 == MachineType::None() ? MachineType::None()
                                      : MachineType::Pointer()),
        test_graph_signature_(
            CSignature::New(main_zone(), MachineType::Int32(), p0, p1, p2, p3)),
        return_parameter_index_(return_parameter_index) {
    parameter_nodes_[0] = p0 == MachineType::None()
                              ? nullptr
                              : Load(p0, RawMachineAssembler::Parameter(0));
    parameter_nodes_[1] = p1 == MachineType::None()
                              ? nullptr
                              : Load(p1, RawMachineAssembler::Parameter(1));
    parameter_nodes_[2] = p2 == MachineType::None()
                              ? nullptr
                              : Load(p2, RawMachineAssembler::Parameter(2));
    parameter_nodes_[3] = p3 == MachineType::None()
                              ? nullptr
                              : Load(p3, RawMachineAssembler::Parameter(3));
  }


  static uint32_t ComputeParameterCount(MachineType p0, MachineType p1,
                                        MachineType p2, MachineType p3) {
    if (p0 == MachineType::None()) {
      return 0;
    }
    if (p1 == MachineType::None()) {
      return 1;
    }
    if (p2 == MachineType::None()) {
      return 2;
    }
    if (p3 == MachineType::None()) {
      return 3;
    }
    return 4;
  }


  CSignature* test_graph_signature_;
  Node* parameter_nodes_[4];
  uint32_t return_parameter_index_;
};


template <>
class BufferedRawMachineAssemblerTester<void>
    : public RawMachineAssemblerTester<void> {
 public:
  BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(),
                                    MachineType p1 = MachineType::None(),
                                    MachineType p2 = MachineType::None(),
                                    MachineType p3 = MachineType::None())
      : RawMachineAssemblerTester<void>(
            p0 == MachineType::None() ? MachineType::None()
                                      : MachineType::Pointer(),
            p1 == MachineType::None() ? MachineType::None()
                                      : MachineType::Pointer(),
            p2 == MachineType::None() ? MachineType::None()
                                      : MachineType::Pointer(),
            p3 == MachineType::None() ? MachineType::None()
                                      : MachineType::Pointer()),
        test_graph_signature_(
            CSignature::New(RawMachineAssemblerTester<void>::main_zone(),
                            MachineType::None(), p0, p1, p2, p3)) {
    parameter_nodes_[0] = p0 == MachineType::None()
                              ? nullptr
                              : Load(p0, RawMachineAssembler::Parameter(0));
    parameter_nodes_[1] = p1 == MachineType::None()
                              ? nullptr
                              : Load(p1, RawMachineAssembler::Parameter(1));
    parameter_nodes_[2] = p2 == MachineType::None()
                              ? nullptr
                              : Load(p2, RawMachineAssembler::Parameter(2));
    parameter_nodes_[3] = p3 == MachineType::None()
                              ? nullptr
                              : Load(p3, RawMachineAssembler::Parameter(3));
  }

  virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }

  // The BufferedRawMachineAssemblerTester does not pass parameters directly
  // to the constructed IR graph. Instead it passes a pointer to the parameter
  // to the IR graph, and adds Load nodes to the IR graph to load the
  // parameters from memory. Thereby it is possible to pass 64 bit parameters
  // to the IR graph.
  Node* Parameter(size_t index) {
    CHECK_GT(4, index);
    return parameter_nodes_[index];
  }


  void Call() {
    CSignature::VerifyParams(test_graph_signature_);
    CallHelper<void>::Call();
  }

  template <typename P0>
  void Call(P0 p0) {
    CSignature::VerifyParams<P0>(test_graph_signature_);
    CallHelper<void>::Call(reinterpret_cast<void*>(&p0));
  }

  template <typename P0, typename P1>
  void Call(P0 p0, P1 p1) {
    CSignature::VerifyParams<P0, P1>(test_graph_signature_);
    CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
                           reinterpret_cast<void*>(&p1));
  }

  template <typename P0, typename P1, typename P2>
  void Call(P0 p0, P1 p1, P2 p2) {
    CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
    CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
                           reinterpret_cast<void*>(&p1),
                           reinterpret_cast<void*>(&p2));
  }

  template <typename P0, typename P1, typename P2, typename P3>
  void Call(P0 p0, P1 p1, P2 p2, P3 p3) {
    CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
    CallHelper<void>::Call(
        reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
        reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3));
  }

 private:
  CSignature* test_graph_signature_;
  Node* parameter_nodes_[4];
};
static const bool USE_RESULT_BUFFER = true;
static const bool USE_RETURN_REGISTER = false;
static const int32_t CHECK_VALUE = 0x99BEEDCE;


// TODO(titzer): use the C-style calling convention, or any register-based
// calling convention for binop tests.
template <typename CType, bool use_result_buffer>
class BinopTester {
 public:
  explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester,
                       MachineType rep)
      : T(tester),
        param0(T->LoadFromPointer(&p0, rep)),
        param1(T->LoadFromPointer(&p1, rep)),
        rep(rep),
        p0(static_cast<CType>(0)),
        p1(static_cast<CType>(0)),
        result(static_cast<CType>(0)) {}

  RawMachineAssemblerTester<int32_t>* T;
  Node* param0;
  Node* param1;

  CType call(CType a0, CType a1) {
    p0 = a0;
    p1 = a1;
    if (use_result_buffer) {
      CHECK_EQ(CHECK_VALUE, T->Call());
      return result;
    } else {
      return static_cast<CType>(T->Call());
    }
  }

  void AddReturn(Node* val) {
    if (use_result_buffer) {
      T->Store(rep.representation(), T->PointerConstant(&result),
               T->Int32Constant(0), val, kNoWriteBarrier);
      T->Return(T->Int32Constant(CHECK_VALUE));
    } else {
      T->Return(val);
    }
  }

  template <typename Ci, typename Cj, typename Fn>
  void Run(const Ci& ci, const Cj& cj, const Fn& fn) {
    typename Ci::const_iterator i;
    typename Cj::const_iterator j;
    for (i = ci.begin(); i != ci.end(); ++i) {
      for (j = cj.begin(); j != cj.end(); ++j) {
        CHECK_EQ(fn(*i, *j), this->call(*i, *j));
      }
    }
  }

 protected:
  MachineType rep;
  CType p0;
  CType p1;
  CType result;
};


// A helper class for testing code sequences that take two int parameters and
// return an int value.
class Int32BinopTester : public BinopTester<int32_t, USE_RETURN_REGISTER> {
 public:
  explicit Int32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
      : BinopTester<int32_t, USE_RETURN_REGISTER>(tester,
                                                  MachineType::Int32()) {}
};


// A helper class for testing code sequences that take two int parameters and
// return an int value.
class Int64BinopTester : public BinopTester<int64_t, USE_RETURN_REGISTER> {
 public:
  explicit Int64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
      : BinopTester<int64_t, USE_RETURN_REGISTER>(tester,
                                                  MachineType::Int64()) {}
};


// A helper class for testing code sequences that take two uint parameters and
// return an uint value.
class Uint32BinopTester : public BinopTester<uint32_t, USE_RETURN_REGISTER> {
 public:
  explicit Uint32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
      : BinopTester<uint32_t, USE_RETURN_REGISTER>(tester,
                                                   MachineType::Uint32()) {}

  uint32_t call(uint32_t a0, uint32_t a1) {
    p0 = a0;
    p1 = a1;
    return static_cast<uint32_t>(T->Call());
  }
};


// A helper class for testing code sequences that take two float parameters and
// return a float value.
class Float32BinopTester : public BinopTester<float, USE_RESULT_BUFFER> {
 public:
  explicit Float32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
      : BinopTester<float, USE_RESULT_BUFFER>(tester, MachineType::Float32()) {}
};


// A helper class for testing code sequences that take two double parameters and
// return a double value.
class Float64BinopTester : public BinopTester<double, USE_RESULT_BUFFER> {
 public:
  explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
      : BinopTester<double, USE_RESULT_BUFFER>(tester, MachineType::Float64()) {
  }
};


// A helper class for testing code sequences that take two pointer parameters
// and return a pointer value.
// TODO(titzer): pick word size of pointers based on V8_TARGET.
template <typename Type>
class PointerBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> {
 public:
  explicit PointerBinopTester(RawMachineAssemblerTester<int32_t>* tester)
      : BinopTester<Type*, USE_RETURN_REGISTER>(tester,
                                                MachineType::Pointer()) {}
};


// A helper class for testing code sequences that take two tagged parameters and
// return a tagged value.
template <typename Type>
class TaggedBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> {
 public:
  explicit TaggedBinopTester(RawMachineAssemblerTester<int32_t>* tester)
      : BinopTester<Type*, USE_RETURN_REGISTER>(tester,
                                                MachineType::AnyTagged()) {}
};

// A helper class for testing compares. Wraps a machine opcode and provides
// evaluation routines and the operators.
class CompareWrapper {
 public:
  explicit CompareWrapper(IrOpcode::Value op) : opcode(op) {}

  Node* MakeNode(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
    return m->AddNode(op(m->machine()), a, b);
  }

  const Operator* op(MachineOperatorBuilder* machine) {
    switch (opcode) {
      case IrOpcode::kWord32Equal:
        return machine->Word32Equal();
      case IrOpcode::kInt32LessThan:
        return machine->Int32LessThan();
      case IrOpcode::kInt32LessThanOrEqual:
        return machine->Int32LessThanOrEqual();
      case IrOpcode::kUint32LessThan:
        return machine->Uint32LessThan();
      case IrOpcode::kUint32LessThanOrEqual:
        return machine->Uint32LessThanOrEqual();
      case IrOpcode::kFloat64Equal:
        return machine->Float64Equal();
      case IrOpcode::kFloat64LessThan:
        return machine->Float64LessThan();
      case IrOpcode::kFloat64LessThanOrEqual:
        return machine->Float64LessThanOrEqual();
      default:
        UNREACHABLE();
    }
    return NULL;
  }

  bool Int32Compare(int32_t a, int32_t b) {
    switch (opcode) {
      case IrOpcode::kWord32Equal:
        return a == b;
      case IrOpcode::kInt32LessThan:
        return a < b;
      case IrOpcode::kInt32LessThanOrEqual:
        return a <= b;
      case IrOpcode::kUint32LessThan:
        return static_cast<uint32_t>(a) < static_cast<uint32_t>(b);
      case IrOpcode::kUint32LessThanOrEqual:
        return static_cast<uint32_t>(a) <= static_cast<uint32_t>(b);
      default:
        UNREACHABLE();
    }
    return false;
  }

  bool Float64Compare(double a, double b) {
    switch (opcode) {
      case IrOpcode::kFloat64Equal:
        return a == b;
      case IrOpcode::kFloat64LessThan:
        return a < b;
      case IrOpcode::kFloat64LessThanOrEqual:
        return a <= b;
      default:
        UNREACHABLE();
    }
    return false;
  }

  IrOpcode::Value opcode;
};


// A small closure class to generate code for a function of two inputs that
// produces a single output so that it can be used in many different contexts.
// The {expected()} method should compute the expected output for a given
// pair of inputs.
template <typename T>
class BinopGen {
 public:
  virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) = 0;
  virtual T expected(T a, T b) = 0;
  virtual ~BinopGen() {}
};

// A helper class to generate various combination of input shape combinations
// and run the generated code to ensure it produces the correct results.
class Int32BinopInputShapeTester {
 public:
  explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g)
      : gen(g), input_a(0), input_b(0) {}

  void TestAllInputShapes();

 private:
  BinopGen<int32_t>* gen;
  int32_t input_a;
  int32_t input_b;

  void Run(RawMachineAssemblerTester<int32_t>* m);
  void RunLeft(RawMachineAssemblerTester<int32_t>* m);
  void RunRight(RawMachineAssemblerTester<int32_t>* m);
};
}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_CCTEST_COMPILER_CODEGEN_TESTER_H_
