// 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 "riscv/riscv_test_mem_watcher.h"

#include "absl/strings/str_cat.h"

namespace mpact {
namespace sim {
namespace riscv {

// For now, the loads/and stores are assumed to be scalar loads/stores. Tracing
// support for vector loads/stores will be added later as necessary, when full
// support for RiscV vector instructions 1.0 is added to the RiscV torture test.

void RiscVTestMemWatcher::Load(uint64_t address, generic::DataBuffer *db,
                               generic::Instruction *inst,
                               generic::ReferenceCount *context) {
  absl::StrAppend(&trace_str_, " mem 0x", absl::Hex(address, absl::kZeroPad16));
  memory_->Load(address, db, inst, context);
}

void RiscVTestMemWatcher::Load(generic::DataBuffer *address_db,
                               generic::DataBuffer *mask_db, int el_size,
                               generic::DataBuffer *db,
                               generic::Instruction *inst,
                               generic::ReferenceCount *context) {
  for (auto const &address : address_db->Get<uint64_t>()) {
    absl::StrAppend(&trace_str_, " mem 0x",
                    absl::Hex(address, absl::kZeroPad16));
  }
  memory_->Load(address_db, mask_db, el_size, db, inst, context);
}

void RiscVTestMemWatcher::Store(uint64_t address, generic::DataBuffer *db) {
  absl::StrAppend(&trace_str_, " mem 0x", absl::Hex(address, absl::kZeroPad16));
  switch (db->size<uint8_t>()) {
    case 1:
      absl::StrAppend(&trace_str_, " 0x",
                      absl::Hex(db->Get<uint8_t>(0), absl::kZeroPad2));
      break;
    case 2:
      absl::StrAppend(&trace_str_, " 0x",
                      absl::Hex(db->Get<uint16_t>(0), absl::kZeroPad4));
      break;
    case 4:
      absl::StrAppend(&trace_str_, " 0x",
                      absl::Hex(db->Get<uint32_t>(0), absl::kZeroPad8));
      break;
    case 8:
      absl::StrAppend(&trace_str_, " 0x",
                      absl::Hex(db->Get<uint64_t>(0), absl::kZeroPad16));
      break;
    default:
      break;
  }
  memory_->Store(address, db);
}

void RiscVTestMemWatcher::Store(generic::DataBuffer *address_db,
                                generic::DataBuffer *mask_db, int el_size,
                                generic::DataBuffer *db) {
  for (auto const &address : address_db->Get<uint64_t>()) {
    absl::StrAppend(&trace_str_, " mem 0x",
                    absl::Hex(address, absl::kZeroPad16));
    switch (el_size) {
      case 1:
        absl::StrAppend(&trace_str_, " 0x",
                        absl::Hex(db->Get<uint8_t>(0), absl::kZeroPad2));
        break;
      case 2:
        absl::StrAppend(&trace_str_, " 0x",
                        absl::Hex(db->Get<uint16_t>(0), absl::kZeroPad4));
        break;
      case 4:
        absl::StrAppend(&trace_str_, " 0x",
                        absl::Hex(db->Get<uint32_t>(0), absl::kZeroPad8));
        break;
      case 8:
        absl::StrAppend(&trace_str_, " 0x",
                        absl::Hex(db->Get<uint64_t>(0), absl::kZeroPad16));
        break;
      default:
        break;
    }
  }
  memory_->Store(address_db, mask_db, el_size, db);
}

}  // namespace riscv
}  // namespace sim
}  // namespace mpact
