// 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/util/memory/atomic_memory.h"

#include <cstdint>
#include <type_traits>
#include <utility>

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "mpact/sim/util/memory/memory_interface.h"

namespace mpact {
namespace sim {
namespace util {

// Helper function that writes the value to the data buffer.
template <typename I>
static absl::Status WriteDb(DataBuffer* db, I value) {
  switch (db->size<uint8_t>()) {
    case 1:
      db->Set<uint8_t>(0, static_cast<uint8_t>(value));
      break;
    case 2:
      db->Set<uint16_t>(0, static_cast<uint16_t>(value));
      break;
    case 4:
      db->Set<uint32_t>(0, static_cast<uint32_t>(value));
      break;
    case 8:
      db->Set<uint64_t>(0, static_cast<uint64_t>(value));
      break;
    default:
      return absl::InternalError(
          absl::StrCat("Illegal element size (", db->size<uint8_t>(), ")"));
  }
  return absl::OkStatus();
}

// Helper function that performs the given atomic memory operation on the data
// buffers.
template <typename T>
static void PerformOp(AtomicMemoryOpInterface::Operation op,
                      const DataBuffer* db_lhs, const DataBuffer* db_rhs,
                      DataBuffer* db_res) {
  using UT = typename std::make_unsigned<T>::type;
  using ST = typename std::make_signed<T>::type;
  switch (op) {
    case AtomicMemoryOpInterface::Operation::kAtomicAdd:
      db_res->Set<T>(0, db_lhs->Get<T>(0) + db_rhs->Get<T>(0));
      break;
    case AtomicMemoryOpInterface::Operation::kAtomicSub:
      db_res->Set<T>(0, db_lhs->Get<T>(0) - db_rhs->Get<T>(0));
      break;
    case AtomicMemoryOpInterface::Operation::kAtomicAnd:
      db_res->Set<T>(0, db_lhs->Get<T>(0) & db_rhs->Get<T>(0));
      break;
    case AtomicMemoryOpInterface::Operation::kAtomicOr:
      db_res->Set<T>(0, db_lhs->Get<T>(0) | db_rhs->Get<T>(0));
      break;
    case AtomicMemoryOpInterface::Operation::kAtomicXor:
      db_res->Set<T>(0, db_lhs->Get<T>(0) ^ db_rhs->Get<T>(0));
      break;
    case AtomicMemoryOpInterface::Operation::kAtomicMax:
      db_res->Set<T>(0, std::max(db_lhs->Get<ST>(0), db_rhs->Get<ST>(0)));
      break;
    case AtomicMemoryOpInterface::Operation::kAtomicMaxu:
      db_res->Set<T>(0, std::max(db_lhs->Get<UT>(0), db_rhs->Get<UT>(0)));
      break;
    case AtomicMemoryOpInterface::Operation::kAtomicMin:
      db_res->Set<T>(0, std::min(db_lhs->Get<ST>(0), db_rhs->Get<ST>(0)));
      break;
    case AtomicMemoryOpInterface::Operation::kAtomicMinu:
      db_res->Set<T>(0, std::min(db_lhs->Get<UT>(0), db_rhs->Get<UT>(0)));
      break;
    default:
      LOG(ERROR) << absl::StrCat("Unhandled case in PerformOp (",
                                 static_cast<int>(op), ")");
  }
}

// Constructor.
AtomicMemory::AtomicMemory(MemoryInterface* memory) : memory_(memory) {
  // Construct and initialize the local data buffers.
  db1_ = db_factory_.Allocate<uint8_t>(1);
  db1_->set_latency(0);
  db1_->set_destination(nullptr);
  db2_ = db_factory_.Allocate<uint16_t>(1);
  db2_->set_latency(0);
  db2_->set_destination(nullptr);
  db4_ = db_factory_.Allocate<uint32_t>(1);
  db4_->set_latency(0);
  db4_->set_destination(nullptr);
  db8_ = db_factory_.Allocate<uint64_t>(1);
  db8_->set_latency(0);
  db8_->set_destination(nullptr);
}

// Destructor.
AtomicMemory::~AtomicMemory() {
  db1_->DecRef();
  db2_->DecRef();
  db4_->DecRef();
  db8_->DecRef();
}

// Forward the load call.
void AtomicMemory::Load(uint64_t address, DataBuffer* db, Instruction* inst,
                        ReferenceCount* context) {
  memory_->Load(address, db, inst, context);
}

// Forward the load call.
void AtomicMemory::Load(DataBuffer* address_db, DataBuffer* mask_db,
                        int el_size, DataBuffer* db, Instruction* inst,
                        ReferenceCount* context) {
  memory_->Load(address_db, mask_db, el_size, db, inst, context);
}

// Store the value to memory, but remove any matching tag from the tag set.
void AtomicMemory::Store(uint64_t address, DataBuffer* db) {
  // If the address matches a tag, remove the tag.
  auto ptr = ll_tag_set_.find(address >> kTagShift);
  if (ptr != ll_tag_set_.end()) {
    ll_tag_set_.erase(ptr);
  }
  memory_->Store(address, db);
}

// Store the value to memory, but remove any matching tag from the tag set.
void AtomicMemory::Store(DataBuffer* address_db, DataBuffer* mask_db,
                         int el_size, DataBuffer* db) {
  // If the address matches a tag, remove the tag.
  for (uint64_t address : address_db->Get<uint64_t>()) {
    auto ptr = ll_tag_set_.find(address >> kTagShift);
    if (ptr != ll_tag_set_.end()) {
      ll_tag_set_.erase(ptr);
    }
  }
  memory_->Store(address_db, mask_db, el_size, db);
}

// Perform the atomic memory operation.
absl::Status AtomicMemory::PerformMemoryOp(uint64_t address, Operation op,
                                           DataBuffer* db, Instruction* inst,
                                           ReferenceCount* context) {
  int el_size = db->size<uint8_t>();
  db->set_latency(0);
  // Load-linked.
  if (op == Operation::kLoadLinked) {
    uint64_t tag = address >> kTagShift;
    if (ll_tag_set_.find(tag) == ll_tag_set_.end()) {
      ll_tag_set_.insert(tag);
    }
    memory_->Load(address, db, inst, context);
    return absl::OkStatus();
  }
  // Store-conditional.
  if (op == Operation::kStoreConditional) {
    uint64_t tag = address >> kTagShift;
    int value = 1;
    // Determine if the store is successful.
    if (ll_tag_set_.find(tag) != ll_tag_set_.end()) {
      // Successful SC. Store the value and set result to 0.
      memory_->Store(address, db);
      ll_tag_set_.erase(tag);
      value = 0;
    }
    auto res = WriteDb(db, value);
    if (!res.ok()) return res;
    WriteBack(inst, context, db);
    return absl::OkStatus();
  }

  // Load the data from memory.
  auto* tmp_db = GetDb(el_size);
  if (tmp_db == nullptr)
    return absl::InternalError(
        absl::StrCat("Illegal element size (", el_size, ")"));

  memory_->Load(address, tmp_db, nullptr, nullptr);

  // Swap with store data - this way the data from the memory is in the right
  // data buffer (i.e., being written back to the register).
  switch (db->size<uint8_t>()) {
    case 1:
      std::swap(tmp_db->Get<uint8_t>()[0], db->Get<uint8_t>()[0]);
      break;
    case 2:
      std::swap(tmp_db->Get<uint16_t>()[0], db->Get<uint16_t>()[0]);
      break;
    case 4:
      std::swap(tmp_db->Get<uint32_t>()[0], db->Get<uint32_t>()[0]);
      break;
    case 8:
      std::swap(tmp_db->Get<uint64_t>()[0], db->Get<uint64_t>()[0]);
      break;
  }
  if (op == Operation::kAtomicSwap) {
    memory_->Store(address, tmp_db);
    WriteBack(inst, context, db);
    return absl::OkStatus();
  }

  // Other atomic operations on memory and load/store data. Notice that the
  // memory value is in db, and the load/store data is in tmp_db.
  switch (db->size<uint8_t>()) {
    case 1:
      PerformOp<uint8_t>(op, /*db_lhs*/ db, /*db_rhs*/ tmp_db,
                         /*db_res*/ tmp_db);
      break;
    case 2:
      PerformOp<uint16_t>(op, /*db_lhs*/ db, /*db_rhs*/ tmp_db,
                          /*db_res*/ tmp_db);
      break;
    case 4:
      PerformOp<uint32_t>(op, /*db_lhs*/ db, /*db_rhs*/ tmp_db,
                          /*db_res*/ tmp_db);
      break;
    case 8:
      PerformOp<uint64_t>(op, /*db_lhs*/ db, /*db_rhs*/ tmp_db,
                          /*db_res*/ tmp_db);
      break;
  }
  // Store the new value to memory, the other value will be written back to the
  // instruction destination.
  memory_->Store(address, tmp_db);
  WriteBack(inst, context, db);
  return absl::OkStatus();
}

void AtomicMemory::WriteBack(Instruction* inst, ReferenceCount* context,
                             DataBuffer* db) {
  if (inst != nullptr) {
    if (db->latency() > 0) {
      inst->IncRef();
      if (context != nullptr) context->IncRef();
      inst->state()->function_delay_line()->Add(db->latency(),
                                                [inst, context]() {
                                                  inst->Execute(context);
                                                  if (context != nullptr)
                                                    context->DecRef();
                                                  inst->DecRef();
                                                });
    } else {
      inst->Execute(context);
    }
  }
}

DataBuffer* AtomicMemory::GetDb(int size) const {
  switch (size) {
    case 1:
      return db1_;
    case 2:
      return db2_;
    case 4:
      return db4_;
    case 8:
      return db8_;
    default:
      return nullptr;
  }
}

}  // namespace util
}  // namespace sim
}  // namespace mpact
