// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cstdint>
#include <cstring>
#include <string>
#include <tuple>
#include <vector>

#include "absl/strings/string_view.h"
#include "googlemock/include/gmock/gmock.h"
#include "mpact/sim/generic/immediate_operand.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/util/memory/flat_demand_memory.h"
#include "riscv/riscv_register.h"
#include "riscv/riscv_state.h"
#include "riscv/riscv_zc_instructions.h"

// This file contains the unit tests for the 64 bit Zcmp* instructions that
// are not covered elsewhere.

namespace {

using ::mpact::sim::generic::ImmediateOperand;
using ::mpact::sim::generic::Instruction;
using ::mpact::sim::riscv::RiscVState;
using ::mpact::sim::riscv::RiscVXlen;
using ::mpact::sim::riscv::RV64Register;
using ::mpact::sim::util::FlatDemandMemory;

constexpr uint64_t kInstAddress = 0x2468;
constexpr char kX1[] = "x1";
constexpr char kX2[] = "x2";
constexpr char kX8[] = "x8";
constexpr char kX9[] = "x9";
constexpr char kX10[] = "x10";
constexpr char kX11[] = "x11";
constexpr char kX18[] = "x18";
constexpr char kX19[] = "x19";
constexpr char kX20[] = "x20";
constexpr char kX21[] = "x21";
constexpr char kX22[] = "x22";
constexpr char kX23[] = "x23";
constexpr char kX24[] = "x24";
constexpr char kX25[] = "x25";
constexpr char kX26[] = "x26";
constexpr char kX27[] = "x27";
constexpr char kX30[] = "x30";
constexpr char kX31[] = "x31";
constexpr uint64_t kMemAddress = 0x1000;

// The test fixture allocates a machine state object and an instruction object.
// It also contains convenience methods for interacting with the instruction
// object in a more short hand form.
class RV64ZcInstructionTest : public testing::Test {
 public:
  RV64ZcInstructionTest() {
    memory_ = new FlatDemandMemory();
    state_ = new RiscVState("test", RiscVXlen::RV64, memory_);
    instruction_ = new Instruction(kInstAddress, state_);
    instruction_->set_size(4);
    // Set the jump table address to 0x4000.
    state_->jvt()->Set(static_cast<uint64_t>(0x4000));
    auto *db = state_->db_factory()->Allocate<uint64_t>(256);
    auto db_span = db->Get<uint64_t>();
    for (auto i = 0; i < 256; ++i) {
      db_span[i] = 0x8000 + i * sizeof(uint64_t);
    }
    state_->StoreMemory(nullptr, 0x4000, db);
    db->DecRef();
  }

  ~RV64ZcInstructionTest() override {
    delete memory_;
    delete state_;
    instruction_->DecRef();
  }

  // Appends the source and destination operands for the register names
  // given in the two vectors.
  void AppendRegisterOperands(Instruction *inst,
                              const std::vector<std::string> &sources,
                              const std::vector<std::string> &destinations) {
    for (auto &reg_name : sources) {
      auto *reg = state_->GetRegister<RV64Register>(reg_name).first;
      inst->AppendSource(reg->CreateSourceOperand());
    }
    for (auto &reg_name : destinations) {
      auto *reg = state_->GetRegister<RV64Register>(reg_name).first;
      inst->AppendDestination(reg->CreateDestinationOperand(0));
    }
  }

  void AppendRegisterOperands(const std::vector<std::string> &sources,
                              const std::vector<std::string> &destinations) {
    AppendRegisterOperands(instruction_, sources, destinations);
  }

  // Appends immediate source operands with the given values.
  template <typename T>
  void AppendImmediateOperands(const std::vector<T> &values) {
    for (auto value : values) {
      auto *src = new ImmediateOperand<T>(value);
      instruction_->AppendSource(src);
    }
  }

  // Takes a vector of tuples of register names and values. Fetches each
  // named register and sets it to the corresponding value.
  template <typename T>
  void SetRegisterValues(const std::vector<std::tuple<std::string, T>> values) {
    for (auto &[reg_name, value] : values) {
      auto *reg = state_->GetRegister<RV64Register>(reg_name).first;
      reg->data_buffer()->template Set<T>(0, value);
    }
  }

  // Initializes the semantic function of the instruction object.
  void SetSemanticFunction(Instruction::SemanticFunction fcn) {
    instruction_->set_semantic_function(fcn);
  }

  // Returns the value of the named register.
  template <typename T>
  T GetRegisterValue(absl::string_view reg_name) {
    auto *reg = state_->GetRegister<RV64Register>(reg_name).first;
    return reg->data_buffer()->Get<T>(0);
  }

  std::vector<std::string> GetRlistRegisters(int rlist) {
    std::vector<std::string> rlist_regs;
    if (rlist < 4) return rlist_regs;
    rlist_regs.push_back(kX1);
    if (rlist == 4) return rlist_regs;
    rlist_regs.push_back(kX8);
    if (rlist == 5) return rlist_regs;
    rlist_regs.push_back(kX9);
    if (rlist == 6) return rlist_regs;
    rlist_regs.push_back(kX18);
    if (rlist == 7) return rlist_regs;
    rlist_regs.push_back(kX19);
    if (rlist == 8) return rlist_regs;
    rlist_regs.push_back(kX20);
    if (rlist == 9) return rlist_regs;
    rlist_regs.push_back(kX21);
    if (rlist == 10) return rlist_regs;
    rlist_regs.push_back(kX22);
    if (rlist == 11) return rlist_regs;
    rlist_regs.push_back(kX23);
    if (rlist == 12) return rlist_regs;
    rlist_regs.push_back(kX24);
    if (rlist == 13) return rlist_regs;
    rlist_regs.push_back(kX25);
    if (rlist == 14) return rlist_regs;
    rlist_regs.push_back(kX26);
    rlist_regs.push_back(kX27);
    return rlist_regs;
  }

  void ResetInstruction() {
    instruction_->DecRef();
    instruction_ = new Instruction(kInstAddress, state_);
    instruction_->set_size(4);
  }

  void ResetMemory() {
    auto *db = state_->db_factory()->Allocate<uint8_t>(0x2000);
    std::memset(db->raw_ptr(), 0, 0x2000);
    state_->StoreMemory(instruction_, 0, db);
    db->DecRef();
  }

  FlatDemandMemory *memory_;
  RiscVState *state_;
  Instruction *instruction_;
};

constexpr int kNumReg[] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13};
constexpr char const *kRegMap[] = {kX1,  kX8,  kX9,  kX18, kX19, kX20, kX21,
                                   kX22, kX23, kX24, kX25, kX26, kX27};
constexpr int kStackAdjBase[] = {
    0, 0, 0, 0, 16, 16, 32, 32, 48, 48, 64, 64, 80, 80, 96, 112,
};

// The push instruction pushes a set of up to 13 registers to the stack and
// updates the stack pointer according to a combination of the rlist and spimm6
// fields.
TEST_F(RV64ZcInstructionTest, RV64ZCmpPush) {
  // Initialize the registers that will be pushed to known value.
  SetRegisterValues<uint64_t>({{kX1, 1},
                               {kX8, 2},
                               {kX9, 3},
                               {kX18, 4},
                               {kX19, 5},
                               {kX20, 6},
                               {kX21, 7},
                               {kX22, 8},
                               {kX23, 9},
                               {kX24, 10},
                               {kX25, 11},
                               {kX26, 12},
                               {kX27, 13}});
  // Test each combination of rlist and spimm6.
  for (int rlist = 4; rlist < 16; ++rlist) {
    for (int spimm6 = 0; spimm6 < 64; spimm6 += 16) {
      // Use x30 and x31 in place of spimm6 and rlist. This allows us to modify
      // the values.
      AppendRegisterOperands({kX2, kX30, kX31}, {kX2});
      // Set the registers to the values we want.
      SetRegisterValues<uint64_t>(
          {{kX2, kMemAddress}, {kX30, spimm6}, {kX31, rlist}});
      // Append the [rlist] registers.
      AppendRegisterOperands(GetRlistRegisters(rlist), {});
      SetSemanticFunction(&::mpact::sim::riscv::RV64::RiscVZCmpPush);
      instruction_->Execute(nullptr);

      // Fetch memory content.
      auto *db = state_->db_factory()->Allocate<uint64_t>(13);
      state_->LoadMemory(instruction_,
                         kMemAddress - kNumReg[rlist] * sizeof(uint64_t), db,
                         nullptr, nullptr);
      auto db_span = db->Get<uint64_t>();
      // Verify the values.
      for (int i = 0; i < 13; ++i) {
        if (i < kNumReg[rlist]) {
          EXPECT_EQ(db_span[i], i + 1)
              << "i: " << i << " rlist:" << rlist << " spimm6:" << spimm6;
        } else {
          EXPECT_EQ(db_span[i], 0)
              << "i: " << i << " rlist:" << rlist << " spimm6:" << spimm6;
        }
      }
      db->DecRef();
      // Verify the stack pointer modification.
      auto adjustment = kStackAdjBase[rlist] + spimm6;
      EXPECT_EQ(GetRegisterValue<uint64_t>(kX2), kMemAddress - adjustment)
          << "rlist: " << rlist << " spimm6: " << spimm6;

      // Clear the instruction and memory.
      ResetInstruction();
      ResetMemory();
    }
  }
}

TEST_F(RV64ZcInstructionTest, RV64ZCmpPop) {
  auto *db = state_->db_factory()->Allocate<uint64_t>(13);
  // Test each combination of rlist and spimm6.
  for (int rlist = 4; rlist < 16; ++rlist) {
    for (int spimm6 = 0; spimm6 < 64; spimm6 += 16) {
      // Append the [rlist] registers.
      AppendRegisterOperands({}, GetRlistRegisters(rlist));
      // Use x30 and x31 in place of spimm6 and rlist. This allows us to modify
      // the values.
      AppendRegisterOperands({kX2, kX30, kX31}, {kX2});
      // Set the registers to the values we want.
      SetRegisterValues<uint64_t>(
          {{kX2, kMemAddress}, {kX30, spimm6}, {kX31, rlist}});
      // Clear the registers that will be popped.
      SetRegisterValues<uint64_t>({{kX1, 0},
                                   {kX8, 0},
                                   {kX9, 0},
                                   {kX10, 0xdeadbeef},
                                   {kX18, 0},
                                   {kX19, 0},
                                   {kX20, 0},
                                   {kX21, 0},
                                   {kX22, 0},
                                   {kX23, 0},
                                   {kX24, 0},
                                   {kX25, 0},
                                   {kX26, 0},
                                   {kX27, 0}});
      // Initialize memory. Write to the memory at addresses lower than the
      // adjusted stack pointer (based on the adjustment for current rlist and
      // spimm6).
      auto adjusted_sp = kMemAddress + kStackAdjBase[rlist] + spimm6;
      auto db_span = db->Get<uint64_t>();
      for (int i = 0; i < 13; ++i) {
        db_span[i] = i + 1;
      }
      state_->StoreMemory(instruction_,
                          adjusted_sp - sizeof(uint64_t) * kNumReg[rlist], db);
      SetSemanticFunction(&::mpact::sim::riscv::RV64::RiscVZCmpPop);
      // Execute the instruction.
      instruction_->Execute(nullptr);

      // Iterate over the registers and verify the expected values.
      for (int i = 0; i < 13; ++i) {
        uint64_t value = GetRegisterValue<uint64_t>(kRegMap[i]);
        if (i < kNumReg[rlist]) {
          EXPECT_EQ(value, i + 1)
              << "i: " << i << " rlist:" << rlist << " spimm6:" << spimm6;
        } else {
          EXPECT_EQ(value, 0)
              << "i: " << i << " rlist:" << rlist << " spimm6:" << spimm6;
        }
      }
      // Verify the stack pointer modification.
      EXPECT_EQ(GetRegisterValue<uint64_t>(kX2), adjusted_sp)
          << "rlist: " << rlist << " spimm6: " << spimm6;
      // Verify that x10 is unchanged.
      EXPECT_EQ(GetRegisterValue<uint64_t>(kX10), 0xdeadbeef)
          << "rlist: " << rlist << " spimm6: " << spimm6;

      // Clear the instruction.
      ResetInstruction();
    }
  }
  db->DecRef();
}

TEST_F(RV64ZcInstructionTest, RV64ZCmpPopRet) {
  auto *db = state_->db_factory()->Allocate<uint64_t>(13);
  // Test each combination of rlist and spimm6.
  for (int rlist = 4; rlist < 16; ++rlist) {
    for (int spimm6 = 0; spimm6 < 64; spimm6 += 16) {
      // Append the [rlist] registers.
      AppendRegisterOperands({}, GetRlistRegisters(rlist));
      // Use x30 and x31 in place of spimm6 and rlist. This allows us to modify
      // the values.
      AppendRegisterOperands({kX2, kX30, kX31, kX1},
                             {kX2, RiscVState::kPcName});
      // Set the registers to the values we want.
      SetRegisterValues<uint64_t>(
          {{kX2, kMemAddress}, {kX30, spimm6}, {kX31, rlist}});
      // Clear the registers that will be popped.
      SetRegisterValues<uint64_t>({{kX1, 0},
                                   {kX8, 0},
                                   {kX9, 0},
                                   {kX10, 0xdeadbeef},
                                   {kX18, 0},
                                   {kX19, 0},
                                   {kX20, 0},
                                   {kX21, 0},
                                   {kX22, 0},
                                   {kX23, 0},
                                   {kX24, 0},
                                   {kX25, 0},
                                   {kX26, 0},
                                   {kX27, 0}});
      // Initialize memory. Write to the memory at addresses lower than the
      // adjusted stack pointer (based on the adjustment for current rlist and
      // spimm6).
      auto adjusted_sp = kMemAddress + kStackAdjBase[rlist] + spimm6;
      auto db_span = db->Get<uint64_t>();
      for (int i = 0; i < 13; ++i) {
        db_span[i] = i + 1;
      }
      state_->StoreMemory(instruction_,
                          adjusted_sp - sizeof(uint64_t) * kNumReg[rlist], db);
      SetSemanticFunction(&::mpact::sim::riscv::RV64::RiscVZCmpPopRet);
      // Execute the instruction.
      instruction_->Execute(nullptr);

      // Iterate over the registers and verify the expected values.
      for (int i = 0; i < 13; ++i) {
        uint64_t value = GetRegisterValue<uint64_t>(kRegMap[i]);
        if (i < kNumReg[rlist]) {
          EXPECT_EQ(value, i + 1)
              << "i: " << i << " rlist:" << rlist << " spimm6:" << spimm6;
        } else {
          EXPECT_EQ(value, 0)
              << "i: " << i << " rlist:" << rlist << " spimm6:" << spimm6;
        }
      }
      // Verify the stack pointer modification.
      EXPECT_EQ(GetRegisterValue<uint64_t>(kX2), adjusted_sp)
          << "rlist: " << rlist << " spimm6: " << spimm6;
      // Verify that x10 is unchanged.
      EXPECT_EQ(GetRegisterValue<uint64_t>(kX10), 0xdeadbeef)
          << "rlist: " << rlist << " spimm6: " << spimm6;
      // Verify that the PC is set to ra (X1), i.e., 1.
      EXPECT_EQ(GetRegisterValue<uint64_t>(RiscVState::kPcName), 1);
      // Clear the instruction.
      ResetInstruction();
    }
  }
  db->DecRef();
}

TEST_F(RV64ZcInstructionTest, RV64ZCmpPopRetz) {
  auto *db = state_->db_factory()->Allocate<uint64_t>(13);
  // Test each combination of rlist and spimm6.
  for (int rlist = 4; rlist < 16; ++rlist) {
    for (int spimm6 = 0; spimm6 < 64; spimm6 += 16) {
      // Append the [rlist] registers.
      AppendRegisterOperands({}, GetRlistRegisters(rlist));
      // Use x30 and x31 in place of spimm6 and rlist. This allows us to modify
      // the values.
      AppendRegisterOperands({kX2, kX30, kX31, kX1},
                             {kX2, kX10, RiscVState::kPcName});
      // Set the registers to the values we want.
      SetRegisterValues<uint64_t>(
          {{kX2, kMemAddress}, {kX30, spimm6}, {kX31, rlist}});
      // Clear the registers that will be popped.
      SetRegisterValues<uint64_t>({{kX1, 0},
                                   {kX8, 0},
                                   {kX9, 0},
                                   {kX10, 0xdeadbeef},
                                   {kX18, 0},
                                   {kX19, 0},
                                   {kX20, 0},
                                   {kX21, 0},
                                   {kX22, 0},
                                   {kX23, 0},
                                   {kX24, 0},
                                   {kX25, 0},
                                   {kX26, 0},
                                   {kX27, 0}});
      // Initialize memory. Write to the memory at addresses lower than the
      // adjusted stack pointer (based on the adjustment for current rlist and
      // spimm6).
      auto adjusted_sp = kMemAddress + kStackAdjBase[rlist] + spimm6;
      auto db_span = db->Get<uint64_t>();
      for (int i = 0; i < 13; ++i) {
        db_span[i] = i + 1;
      }
      state_->StoreMemory(instruction_,
                          adjusted_sp - sizeof(uint64_t) * kNumReg[rlist], db);
      SetSemanticFunction(&::mpact::sim::riscv::RV64::RiscVZCmpPopRetz);
      // Execute the instruction.
      instruction_->Execute(nullptr);

      // Iterate over the registers and verify the expected values.
      for (int i = 0; i < 13; ++i) {
        uint64_t value = GetRegisterValue<uint64_t>(kRegMap[i]);
        if (i < kNumReg[rlist]) {
          EXPECT_EQ(value, i + 1)
              << "i: " << i << " rlist:" << rlist << " spimm6:" << spimm6;
        } else {
          EXPECT_EQ(value, 0)
              << "i: " << i << " rlist:" << rlist << " spimm6:" << spimm6;
        }
      }
      // Verify the stack pointer modification.
      EXPECT_EQ(GetRegisterValue<uint64_t>(kX2), adjusted_sp)
          << "rlist: " << rlist << " spimm6: " << spimm6;
      // Verify that x10 is zeroed.
      EXPECT_EQ(GetRegisterValue<uint64_t>(kX10), 0x0)
          << "rlist: " << rlist << " spimm6: " << spimm6;
      // Verify that the PC is set to ra (X1), i.e., 1.
      EXPECT_EQ(GetRegisterValue<uint64_t>(RiscVState::kPcName), 1);
      // Clear the instruction.
      ResetInstruction();
    }
  }
  db->DecRef();
}

TEST_F(RV64ZcInstructionTest, RV64ZMvTwoRegs) {
  AppendRegisterOperands({kX1, kX2}, {kX10, kX11});
  SetRegisterValues<uint64_t>({{kX1, 1}, {kX2, 2}, {kX10, 10}, {kX11, 11}});
  SetSemanticFunction(&::mpact::sim::riscv::RV64::RiscVZCmpMvTwoRegs);
  instruction_->Execute(nullptr);

  EXPECT_EQ(GetRegisterValue<uint64_t>(kX10), 1);
  EXPECT_EQ(GetRegisterValue<uint64_t>(kX11), 2);
}

TEST_F(RV64ZcInstructionTest, RV64ZCmtJt) {
  // Use a register instead of the immediate for the index.
  AppendRegisterOperands({kX10}, {RiscVState::kPcName});
  SetSemanticFunction(&::mpact::sim::riscv::RV64::RiscVZCmtJt);
  // Indices have to be less than 32.
  for (int i = 0; i < 16; ++i) {
    SetRegisterValues<uint64_t>({{kX10, i}});
    instruction_->Execute(nullptr);
    EXPECT_EQ(GetRegisterValue<uint64_t>(RiscVState::kPcName),
              0x8000 + i * sizeof(uint64_t))
        << "i: " << i;
  }
}

TEST_F(RV64ZcInstructionTest, RV64ZCmtJalt) {
  // Use a register instead of the immediate for the index.
  AppendRegisterOperands({kX10}, {RiscVState::kPcName, kX1});
  SetSemanticFunction(&::mpact::sim::riscv::RV64::RiscVZCmtJalt);
  // Indices have to be greater or equal to 32.
  for (int i = 32; i < 48; ++i) {
    SetRegisterValues<uint64_t>({{kX10, i}, {kX1, 0}});
    instruction_->Execute(nullptr);
    EXPECT_EQ(GetRegisterValue<uint64_t>(RiscVState::kPcName),
              0x8000 + i * sizeof(uint64_t))
        << "i: " << i;
    EXPECT_EQ(GetRegisterValue<uint64_t>(kX1),
              instruction_->address() + instruction_->size());
  }
}

}  // namespace
