156 lines
3.9 KiB
C++
156 lines
3.9 KiB
C++
|
|
// TODO: store all of values, allocated registers, stack offsets in single allocator
|
|
// to be able to find out which kind a specific temp register represent
|
|
|
|
#pragma once
|
|
#include <cstddef>
|
|
#include "string.hpp"
|
|
#include "ir.hpp"
|
|
|
|
template<typename Slot>
|
|
class Allocator
|
|
{
|
|
public:
|
|
virtual ~Allocator() {};
|
|
public:
|
|
virtual const Slot& Allocate(const StringView& addr) = 0;
|
|
virtual const Slot& Resolve(const StringView& addr) = 0;
|
|
};
|
|
|
|
struct StackSlot
|
|
{
|
|
size_t offset;
|
|
StringView addr;
|
|
};
|
|
|
|
class StackAllocator : public Allocator<StackSlot>
|
|
{
|
|
public:
|
|
StackAllocator() = default;
|
|
~StackAllocator() override = default;
|
|
public:
|
|
const StackSlot& Allocate(const StringView& addr)
|
|
{
|
|
m_offset_counter += 4;
|
|
m_slots.Push(StackSlot { m_offset_counter, addr });
|
|
return m_slots.data[m_slots.size - 1];
|
|
}
|
|
|
|
const StackSlot& Resolve(const StringView& addr)
|
|
{
|
|
for (size_t i = 0; i < m_slots.size; ++i)
|
|
{
|
|
if (strcmp(m_slots.data[i].addr.c_str(), addr.c_str()) == 0)
|
|
{
|
|
return m_slots.data[i];
|
|
}
|
|
}
|
|
|
|
assert(0 && "could not resolve stack offset for specified address");
|
|
}
|
|
private:
|
|
size_t m_offset_counter = 0;
|
|
Builder<StackSlot> m_slots;
|
|
};
|
|
|
|
// struct ConstSlot
|
|
// {
|
|
// long value;
|
|
// StringView addr;
|
|
// };
|
|
|
|
// class ConstAllocator : public Allocator<ConstSlot>
|
|
// {
|
|
// public:
|
|
// ConstAllocator() = default;
|
|
// ~ConstAllocator() override = default;
|
|
// public:
|
|
// const ConstSlot& Allocate(const StringView& addr)
|
|
// {
|
|
// m_slots.Push(ConstSlot { 0, addr });
|
|
// return m_slots.data[m_slots.size - 1];
|
|
// }
|
|
|
|
// const ConstSlot& StoreValue(const StringView& addr, long value)
|
|
// {
|
|
// for (size_t i = 0; i < m_slots.size; ++i)
|
|
// {
|
|
// if (strcmp(m_slots.data[i].addr.c_str(), addr.c_str()) == 0)
|
|
// {
|
|
// m_slots.data[i].value = value;
|
|
// return m_slots.data[i];
|
|
// }
|
|
// }
|
|
|
|
// assert(0 && "could not resolve const under specified address");
|
|
// }
|
|
|
|
// const ConstSlot& Resolve(const StringView& addr)
|
|
// {
|
|
// for (size_t i = 0; i < m_slots.size; ++i)
|
|
// {
|
|
// if (strcmp(m_slots.data[i].addr.c_str(), addr.c_str()) == 0)
|
|
// {
|
|
// return m_slots.data[i];
|
|
// }
|
|
// }
|
|
|
|
// assert(0 && "could not resolve const under specified address");
|
|
// }
|
|
// private:
|
|
// Builder<ConstSlot> m_slots;
|
|
// };
|
|
|
|
// struct RegisterSlot
|
|
// {
|
|
// const StringView& reg;
|
|
// StringView addr;
|
|
// };
|
|
|
|
// class RegisterAllocator : public Allocator<RegisterSlot>
|
|
// {
|
|
// public:
|
|
// RegisterAllocator()
|
|
// {
|
|
// m_regs.Push(std::move(StringView("eax")));
|
|
// m_regs.Push(std::move(StringView("ecx")));
|
|
// }
|
|
// ~RegisterAllocator() override = default;
|
|
// public:
|
|
// const RegisterSlot& Allocate(const StringView& addr)
|
|
// {
|
|
// assert(m_slots.size < m_regs.size && "no space available for allocating to register");
|
|
// m_slots.Push(RegisterSlot { m_regs.data[m_slots.size], addr });
|
|
// return m_slots.data[m_slots.size - 1];
|
|
// }
|
|
|
|
// const RegisterSlot& Resolve(const StringView& addr)
|
|
// {
|
|
// for (size_t i = 0; i < m_slots.size; ++i)
|
|
// {
|
|
// if (strcmp(m_slots.data[i].addr.c_str(), addr.c_str()) == 0)
|
|
// {
|
|
// return m_slots.data[i];
|
|
// }
|
|
// }
|
|
|
|
// assert(0 && "could not resolve register for specified address");
|
|
// }
|
|
|
|
// void Clear()
|
|
// {
|
|
// m_slots.size = 0;
|
|
// }
|
|
// private:
|
|
// Builder<RegisterSlot> m_slots;
|
|
// Builder<StringView> m_regs;
|
|
// };
|
|
|
|
class CodeGenerator
|
|
{
|
|
public:
|
|
virtual ~CodeGenerator() {};
|
|
|
|
virtual void Generate(const char* filename, View<IR::Op*> ops) = 0;
|
|
};
|