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

#include <cstdint>
#include <cstring>
#include <string>

#include "mpact/sim/generic/resource_operand_interface.h"

namespace mpact {
namespace sim {
namespace generic {

void Instruction::AppendChild(Instruction *inst) {
  if (nullptr == inst) return;
  inst->parent_ = this;
  if (nullptr == child_) {
    inst->IncRef();
    child_ = inst;
  } else {
    child_->Append(inst);
  }
}

void Instruction::Append(Instruction *inst) {
  if (nullptr == inst) return;
  if (nullptr == next_) {
    inst->IncRef();
    next_ = inst;
  } else {
    next_->Append(inst);
  }
}

void Instruction::SetPredicate(PredicateOperandInterface *predicate) {
  predicate_ = predicate;
}

void Instruction::AppendSource(SourceOperandInterface *op) {
  sources_.push_back(op);
}

int Instruction::SourcesSize() const { return sources_.size(); }

void Instruction::AppendDestination(DestinationOperandInterface *op) {
  dests_.push_back(op);
}

int Instruction::DestinationsSize() const { return dests_.size(); }

Instruction::Instruction(uint64_t address, ArchState *state)
    : predicate_(nullptr),
      address_(address),
      state_(state),
      context_(nullptr),
      child_(nullptr),
      parent_(nullptr),
      next_(nullptr) {}

Instruction::Instruction(ArchState *state) : Instruction(0, state) {}

Instruction::~Instruction() {
  delete[] attribute_array_;
  delete predicate_;
  for (auto *op : sources_) {
    delete op;
  }
  sources_.clear();
  for (auto *op : dests_) {
    delete op;
  }
  dests_.clear();
  for (auto *op : resource_hold_) {
    delete op;
  }
  resource_hold_.clear();
  for (auto *op : resource_acquire_) {
    delete op;
  }
  resource_acquire_.clear();
  if (parent_ != nullptr) {
    // remove reference to this from the parent
    parent_->child_ = nullptr;
  }
  if (next_ != nullptr) {
    next_->DecRef();
    next_ = nullptr;
  }
  if (child_ != nullptr) {
    child_->parent_ = nullptr;
    child_->DecRef();
    child_ = nullptr;
  }
}

std::string Instruction::AsString() const { return disasm_string_; }

void Instruction::SetAttributes(absl::Span<const int> attributes) {
  delete attribute_array_;
  attribute_array_ = new int[attributes.size()];
  std::memcpy(attribute_array_, attributes.data(),
              attributes.size() * sizeof(int));
  attributes_ = absl::Span<const int>(attribute_array_, attributes.size());
}

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