// Copyright 2023 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 "mpact/sim/generic/decode_cache.h"

#include <cstdint>

#include "googlemock/include/gmock/gmock.h"
#include "googletest/include/gtest/gtest.h"
#include "mpact/sim/generic/decoder_interface.h"
#include "mpact/sim/generic/instruction.h"

namespace mpact {
namespace sim {
namespace generic {
namespace {

// Simple decoder class.
class MockDecoder : public DecoderInterface {
 public:
  MockDecoder() : num_decoded_(0) {}
  ~MockDecoder() override {}
  Instruction *DecodeInstruction(uint64_t address) override {
    num_decoded_++;
    Instruction *inst = new Instruction(address, nullptr);
    return inst;
  }
  void set_num_decoded(int val) { num_decoded_ = val; }
  int num_decoded() const { return num_decoded_; }

 private:
  int num_decoded_;
};

// Test fixture for DecodeCacheTest.
class DecodeCacheTest : public testing::Test {
 protected:
  DecodeCacheTest() { decoder_ = new MockDecoder(); }

  ~DecodeCacheTest() override { delete decoder_; }

  MockDecoder *decoder_;
};

// Test creation and verify basic properties.
TEST_F(DecodeCacheTest, BasicProperties) {
  DecodeCacheProperties props;

  props.num_entries = 1000;
  props.minimum_pc_increment = 4;
  DecodeCache *dc = DecodeCache::Create(props, decoder_);
  EXPECT_EQ(dc->num_entries(), 1024);
  EXPECT_EQ(dc->address_mask(), 0xFFC);
  EXPECT_EQ(dc->address_shift(), 2);
  EXPECT_EQ(dc->address_inc(), 4);
  delete dc;

  props.num_entries = 500;
  props.minimum_pc_increment = 1;
  dc = DecodeCache::Create(props, decoder_);
  EXPECT_EQ(dc->num_entries(), 512);
  EXPECT_EQ(dc->address_mask(), 0x1FF);
  EXPECT_EQ(dc->address_shift(), 0);
  EXPECT_EQ(dc->address_inc(), 1);
  delete dc;
}

// Test that the decode cache caches a decoded instruction.
TEST_F(DecodeCacheTest, CacheOne) {
  DecodeCacheProperties props;
  props.num_entries = 1000;
  props.minimum_pc_increment = 4;
  DecodeCache *dc = DecodeCache::Create(props, decoder_);

  Instruction *inst;
  EXPECT_EQ(decoder_->num_decoded(), 0);
  // Not in cache, decoder will be called.
  inst = dc->GetDecodedInstruction(0x1000);
  EXPECT_EQ(decoder_->num_decoded(), 1);
  // In cache. No call to decoder.
  inst = dc->GetDecodedInstruction(0x1000);
  EXPECT_EQ(decoder_->num_decoded(), 1);
  // Not in cache, decoder will be called.
  inst = dc->GetDecodedInstruction(0x1004);
  EXPECT_EQ(decoder_->num_decoded(), 2);
  inst = dc->GetDecodedInstruction(0x1000);
  EXPECT_EQ(decoder_->num_decoded(), 2);
  // This will kick out the instruction with address 0x1000.
  inst = dc->GetDecodedInstruction(0x2000);
  EXPECT_EQ(decoder_->num_decoded(), 3);
  // This will need to be re-decoded.
  inst = dc->GetDecodedInstruction(0x1000);
  EXPECT_EQ(decoder_->num_decoded(), 4);
  // This is still in the cache.
  inst = dc->GetDecodedInstruction(0x1004);
  EXPECT_EQ(decoder_->num_decoded(), 4);
  (void)inst;
  delete dc;
}

// Test invalidation of single instruction.
TEST_F(DecodeCacheTest, InvalidateOne) {
  DecodeCacheProperties props;
  props.num_entries = 1000;
  props.minimum_pc_increment = 4;
  DecodeCache *dc = DecodeCache::Create(props, decoder_);

  Instruction *inst;
  inst = dc->GetDecodedInstruction(0x1000);
  inst = dc->GetDecodedInstruction(0x1004);
  inst = dc->GetDecodedInstruction(0x1008);
  inst = dc->GetDecodedInstruction(0x100c);
  EXPECT_EQ(decoder_->num_decoded(), 4);
  dc->Invalidate(0x1008);
  inst = dc->GetDecodedInstruction(0x1000);
  inst = dc->GetDecodedInstruction(0x1004);
  inst = dc->GetDecodedInstruction(0x1008);
  inst = dc->GetDecodedInstruction(0x100c);
  EXPECT_EQ(decoder_->num_decoded(), 5);
  (void)inst;
  delete dc;
}

// Test invalidation of range.
TEST_F(DecodeCacheTest, InvalidateRange) {
  DecodeCacheProperties props;
  props.num_entries = 1000;
  props.minimum_pc_increment = 4;
  DecodeCache *dc = DecodeCache::Create(props, decoder_);

  Instruction *inst;
  inst = dc->GetDecodedInstruction(0x1000);
  inst = dc->GetDecodedInstruction(0x1004);
  inst = dc->GetDecodedInstruction(0x1008);
  inst = dc->GetDecodedInstruction(0x100c);
  EXPECT_EQ(decoder_->num_decoded(), 4);
  dc->InvalidateRange(0x1004, 0x100c);
  inst = dc->GetDecodedInstruction(0x1000);
  inst = dc->GetDecodedInstruction(0x1004);
  inst = dc->GetDecodedInstruction(0x1008);
  inst = dc->GetDecodedInstruction(0x100c);
  EXPECT_EQ(decoder_->num_decoded(), 6);
  (void)inst;
  delete dc;
}

// Test invalidate all.
TEST_F(DecodeCacheTest, InvalidateAll) {
  DecodeCacheProperties props;
  props.num_entries = 1000;
  props.minimum_pc_increment = 4;
  DecodeCache *dc = DecodeCache::Create(props, decoder_);

  Instruction *inst;
  inst = dc->GetDecodedInstruction(0x1000);
  inst = dc->GetDecodedInstruction(0x1004);
  inst = dc->GetDecodedInstruction(0x1008);
  inst = dc->GetDecodedInstruction(0x100c);
  EXPECT_EQ(decoder_->num_decoded(), 4);
  dc->InvalidateAll();
  inst = dc->GetDecodedInstruction(0x1000);
  inst = dc->GetDecodedInstruction(0x1004);
  inst = dc->GetDecodedInstruction(0x1008);
  inst = dc->GetDecodedInstruction(0x100c);
  EXPECT_EQ(decoder_->num_decoded(), 8);
  (void)inst;
  delete dc;
}

}  // namespace
}  // namespace generic
}  // namespace sim
}  // namespace mpact
