// 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_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_
#define V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_

#include <memory>

#include "src/codegen/register-configuration.h"
#include "src/compiler/backend/instruction.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace v8 {
namespace internal {
namespace compiler {

class InstructionSequenceTest : public TestWithIsolateAndZone {
 public:
  static constexpr int kNoValue = kMinInt;
  static constexpr MachineRepresentation kNoRep = MachineRepresentation::kNone;
  static constexpr MachineRepresentation kFloat32 =
      MachineRepresentation::kFloat32;
  static constexpr MachineRepresentation kFloat64 =
      MachineRepresentation::kFloat64;
  static constexpr MachineRepresentation kSimd128 =
      MachineRepresentation::kSimd128;

  using Rpo = RpoNumber;

  struct VReg {
    VReg() : value_(kNoValue) {}
    VReg(PhiInstruction* phi) : value_(phi->virtual_register()) {}  // NOLINT
    explicit VReg(int value, MachineRepresentation rep = kNoRep)
        : value_(value), rep_(rep) {}
    int value_;
    MachineRepresentation rep_ = kNoRep;
  };

  using VRegPair = std::pair<VReg, VReg>;

  enum TestOperandType {
    kInvalid,
    kSameAsFirst,
    kRegister,
    kFixedRegister,
    kSlot,
    kFixedSlot,
    kExplicit,
    kImmediate,
    kNone,
    kConstant,
    kUnique,
    kUniqueRegister
  };

  struct TestOperand {
    TestOperand() : type_(kInvalid), vreg_(), value_(kNoValue), rep_(kNoRep) {}
    explicit TestOperand(TestOperandType type)
        : type_(type), vreg_(), value_(kNoValue), rep_(kNoRep) {}
    // For tests that do register allocation.
    TestOperand(TestOperandType type, VReg vreg, int value = kNoValue)
        : type_(type), vreg_(vreg), value_(value), rep_(vreg.rep_) {}
    // For immediates, constants, and tests that don't do register allocation.
    TestOperand(TestOperandType type, int value,
                MachineRepresentation rep = kNoRep)
        : type_(type), vreg_(), value_(value), rep_(rep) {}

    TestOperandType type_;
    VReg vreg_;
    int value_;
    MachineRepresentation rep_;
  };

  static TestOperand Same() { return TestOperand(kSameAsFirst); }

  static TestOperand ExplicitReg(int index) {
    TestOperandType type = kExplicit;
    return TestOperand(type, index);
  }

  static TestOperand ExplicitFPReg(int index,
                                   MachineRepresentation rep = kFloat64) {
    TestOperandType type = kExplicit;
    return TestOperand(type, index, rep);
  }

  static TestOperand Reg(VReg vreg, int index = kNoValue) {
    TestOperandType type = (index == kNoValue) ? kRegister : kFixedRegister;
    return TestOperand(type, vreg, index);
  }

  static TestOperand Reg(int index = kNoValue,
                         MachineRepresentation rep = kNoRep) {
    return Reg(VReg(kNoValue, rep), index);
  }

  static TestOperand FPReg(int index = kNoValue,
                           MachineRepresentation rep = kFloat64) {
    return Reg(index, rep);
  }

  static TestOperand Slot(VReg vreg, int index = kNoValue) {
    TestOperandType type = (index == kNoValue) ? kSlot : kFixedSlot;
    return TestOperand(type, vreg, index);
  }

  static TestOperand Slot(int index = kNoValue,
                          MachineRepresentation rep = kNoRep) {
    return Slot(VReg(kNoValue, rep), index);
  }

  static TestOperand Const(int index) {
    CHECK_NE(kNoValue, index);
    return TestOperand(kConstant, index);
  }

  static TestOperand Use(VReg vreg) { return TestOperand(kNone, vreg); }

  static TestOperand Use() { return Use(VReg()); }

  static TestOperand Unique(VReg vreg) { return TestOperand(kUnique, vreg); }

  static TestOperand UniqueReg(VReg vreg) {
    return TestOperand(kUniqueRegister, vreg);
  }

  enum BlockCompletionType { kBlockEnd, kFallThrough, kBranch, kJump };

  struct BlockCompletion {
    BlockCompletionType type_;
    TestOperand op_;
    int offset_0_;
    int offset_1_;
  };

  static BlockCompletion FallThrough() {
    BlockCompletion completion = {kFallThrough, TestOperand(), 1, kNoValue};
    return completion;
  }

  static BlockCompletion Jump(int offset) {
    BlockCompletion completion = {kJump, TestOperand(), offset, kNoValue};
    return completion;
  }

  static BlockCompletion Branch(TestOperand op, int left_offset,
                                int right_offset) {
    BlockCompletion completion = {kBranch, op, left_offset, right_offset};
    return completion;
  }

  static BlockCompletion Last() {
    BlockCompletion completion = {kBlockEnd, TestOperand(), kNoValue, kNoValue};
    return completion;
  }

  InstructionSequenceTest();

  void SetNumRegs(int num_general_registers, int num_double_registers);
  int GetNumRegs(MachineRepresentation rep);
  int GetAllocatableCode(int index, MachineRepresentation rep = kNoRep);
  const RegisterConfiguration* config();
  InstructionSequence* sequence();

  void StartLoop(int loop_blocks);
  void EndLoop();
  void StartBlock(bool deferred = false);
  Instruction* EndBlock(BlockCompletion completion = FallThrough());

  TestOperand Imm(int32_t imm = 0);
  VReg Define(TestOperand output_op);
  VReg Parameter(TestOperand output_op = Reg()) { return Define(output_op); }
  VReg FPParameter(MachineRepresentation rep = kFloat64) {
    return Parameter(FPReg(kNoValue, rep));
  }

  MachineRepresentation GetCanonicalRep(TestOperand op) {
    return IsFloatingPoint(op.rep_) ? op.rep_
                                    : sequence()->DefaultRepresentation();
  }

  Instruction* Return(TestOperand input_op_0);
  Instruction* Return(VReg vreg) { return Return(Reg(vreg, 0)); }

  PhiInstruction* Phi(VReg incoming_vreg_0 = VReg(),
                      VReg incoming_vreg_1 = VReg(),
                      VReg incoming_vreg_2 = VReg(),
                      VReg incoming_vreg_3 = VReg());
  PhiInstruction* Phi(VReg incoming_vreg_0, size_t input_count);
  void SetInput(PhiInstruction* phi, size_t input, VReg vreg);

  VReg DefineConstant(int32_t imm = 0);
  Instruction* EmitNop();
  Instruction* EmitI(size_t input_size, TestOperand* inputs);
  Instruction* EmitI(TestOperand input_op_0 = TestOperand(),
                     TestOperand input_op_1 = TestOperand(),
                     TestOperand input_op_2 = TestOperand(),
                     TestOperand input_op_3 = TestOperand());
  VReg EmitOI(TestOperand output_op, size_t input_size, TestOperand* inputs);
  VReg EmitOI(TestOperand output_op, TestOperand input_op_0 = TestOperand(),
              TestOperand input_op_1 = TestOperand(),
              TestOperand input_op_2 = TestOperand(),
              TestOperand input_op_3 = TestOperand());
  VRegPair EmitOOI(TestOperand output_op_0, TestOperand output_op_1,
                   size_t input_size, TestOperand* inputs);
  VRegPair EmitOOI(TestOperand output_op_0, TestOperand output_op_1,
                   TestOperand input_op_0 = TestOperand(),
                   TestOperand input_op_1 = TestOperand(),
                   TestOperand input_op_2 = TestOperand(),
                   TestOperand input_op_3 = TestOperand());
  VReg EmitCall(TestOperand output_op, size_t input_size, TestOperand* inputs);
  VReg EmitCall(TestOperand output_op, TestOperand input_op_0 = TestOperand(),
                TestOperand input_op_1 = TestOperand(),
                TestOperand input_op_2 = TestOperand(),
                TestOperand input_op_3 = TestOperand());

  InstructionBlock* current_block() const { return current_block_; }

  // Called after all instructions have been inserted.
  void WireBlocks();

 private:
  virtual bool DoesRegisterAllocation() const { return true; }

  VReg NewReg(TestOperand op = TestOperand()) {
    int vreg = sequence()->NextVirtualRegister();
    if (IsFloatingPoint(op.rep_))
      sequence()->MarkAsRepresentation(op.rep_, vreg);
    return VReg(vreg, op.rep_);
  }

  static TestOperand Invalid() { return TestOperand(kInvalid); }

  Instruction* EmitBranch(TestOperand input_op);
  Instruction* EmitFallThrough();
  Instruction* EmitJump();
  Instruction* NewInstruction(InstructionCode code, size_t outputs_size,
                              InstructionOperand* outputs,
                              size_t inputs_size = 0,
                              InstructionOperand* inputs = nullptr,
                              size_t temps_size = 0,
                              InstructionOperand* temps = nullptr);
  InstructionOperand Unallocated(TestOperand op,
                                 UnallocatedOperand::ExtendedPolicy policy);
  InstructionOperand Unallocated(TestOperand op,
                                 UnallocatedOperand::ExtendedPolicy policy,
                                 UnallocatedOperand::Lifetime lifetime);
  InstructionOperand Unallocated(TestOperand op,
                                 UnallocatedOperand::ExtendedPolicy policy,
                                 int index);
  InstructionOperand Unallocated(TestOperand op,
                                 UnallocatedOperand::BasicPolicy policy,
                                 int index);
  InstructionOperand* ConvertInputs(size_t input_size, TestOperand* inputs);
  InstructionOperand ConvertInputOp(TestOperand op);
  InstructionOperand ConvertOutputOp(VReg vreg, TestOperand op);
  InstructionBlock* NewBlock(bool deferred = false);
  void WireBlock(size_t block_offset, int jump_offset);

  Instruction* Emit(InstructionCode code, size_t outputs_size = 0,
                    InstructionOperand* outputs = nullptr,
                    size_t inputs_size = 0,
                    InstructionOperand* inputs = nullptr, size_t temps_size = 0,
                    InstructionOperand* temps = nullptr, bool is_call = false);

  Instruction* AddInstruction(Instruction* instruction);

  struct LoopData {
    Rpo loop_header_;
    int expected_blocks_;
  };

  using LoopBlocks = std::vector<LoopData>;
  using Instructions = std::map<int, const Instruction*>;
  using Completions = std::vector<BlockCompletion>;

  std::unique_ptr<RegisterConfiguration> config_;
  InstructionSequence* sequence_;
  int num_general_registers_;
  int num_double_registers_;

  // Block building state.
  InstructionBlocks instruction_blocks_;
  Instructions instructions_;
  Completions completions_;
  LoopBlocks loop_blocks_;
  InstructionBlock* current_block_;
  bool block_returns_;

  DISALLOW_COPY_AND_ASSIGN(InstructionSequenceTest);
};

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

#endif  // V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_
