blob: 79af44bbbbf1f91d6b24571e27ca4bc0f360f24b [file]
// 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