2021-04-04 21:04:12 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
2021-06-22 23:52:31 +01:00
|
|
|
#include <utility>
|
2021-04-04 21:04:12 +01:00
|
|
|
#include <vector>
|
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
|
|
namespace Bloom::Targets
|
|
|
|
|
{
|
|
|
|
|
enum class TargetRegisterType: int
|
|
|
|
|
{
|
|
|
|
|
GENERAL_PURPOSE_REGISTER,
|
|
|
|
|
PROGRAM_COUNTER,
|
|
|
|
|
STACK_POINTER,
|
|
|
|
|
STATUS_REGISTER,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct TargetRegisterDescriptor
|
|
|
|
|
{
|
|
|
|
|
using IdType = size_t;
|
|
|
|
|
std::optional<IdType> id;
|
|
|
|
|
TargetRegisterType type = TargetRegisterType::GENERAL_PURPOSE_REGISTER;
|
|
|
|
|
|
2021-06-22 23:52:31 +01:00
|
|
|
TargetRegisterDescriptor() = default;
|
|
|
|
|
explicit TargetRegisterDescriptor(TargetRegisterType type): type(type) {};
|
2021-04-04 21:04:12 +01:00
|
|
|
TargetRegisterDescriptor(IdType id, TargetRegisterType type): id(id), type(type) {};
|
|
|
|
|
|
|
|
|
|
bool operator==(const TargetRegisterDescriptor& other) const {
|
|
|
|
|
return this->id == other.id && this->type == other.type;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct TargetRegister
|
|
|
|
|
{
|
2021-06-22 23:52:31 +01:00
|
|
|
std::optional<size_t> id;
|
|
|
|
|
std::vector<unsigned char> value;
|
2021-04-04 21:04:12 +01:00
|
|
|
TargetRegisterDescriptor descriptor;
|
|
|
|
|
|
2021-06-22 23:52:31 +01:00
|
|
|
explicit TargetRegister(std::vector<unsigned char> value): value(std::move(value)) {};
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2021-06-22 23:52:31 +01:00
|
|
|
TargetRegister(TargetRegisterDescriptor descriptor, std::vector<unsigned char> value): value(std::move(value)),
|
2021-04-04 21:04:12 +01:00
|
|
|
descriptor(descriptor) {};
|
|
|
|
|
|
2021-06-22 23:52:31 +01:00
|
|
|
TargetRegister(size_t id, std::vector<unsigned char> value): id(id), value(std::move(value)) {
|
2021-04-04 21:04:12 +01:00
|
|
|
this->descriptor.id = id;
|
|
|
|
|
};
|
|
|
|
|
|
2021-06-22 23:52:31 +01:00
|
|
|
[[nodiscard]] size_t size() const {
|
2021-04-04 21:04:12 +01:00
|
|
|
return this->value.size();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2021-06-22 23:52:31 +01:00
|
|
|
using TargetRegisterMap = std::map<size_t, TargetRegister>;
|
2021-04-04 21:04:12 +01:00
|
|
|
using TargetRegisters = std::vector<TargetRegister>;
|
|
|
|
|
using TargetRegisterDescriptors = std::vector<TargetRegisterDescriptor>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace std {
|
2021-05-24 20:58:49 +01:00
|
|
|
/**
|
|
|
|
|
* Hashing function for TargetRegisterDescriptor type.
|
|
|
|
|
*
|
|
|
|
|
* This is required in order to use TargetRegisterDescriptor as a key in an std::unordered_map (see the BiMap
|
|
|
|
|
* class)
|
|
|
|
|
*/
|
2021-04-04 21:04:12 +01:00
|
|
|
template<>
|
2021-05-24 20:58:49 +01:00
|
|
|
class hash<Bloom::Targets::TargetRegisterDescriptor> {
|
2021-04-04 21:04:12 +01:00
|
|
|
public:
|
2021-05-24 20:58:49 +01:00
|
|
|
size_t operator()(const Bloom::Targets::TargetRegisterDescriptor& descriptor) const {
|
2021-04-04 21:04:12 +01:00
|
|
|
return descriptor.id.value_or(0) + static_cast<size_t>(descriptor.type);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|