Compare commits
3 Commits
6f4ab269e2
...
8a2d98e69e
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a2d98e69e | |||
| ad17a59d65 | |||
| 7995dd2bdf |
32
TODO.md
32
TODO.md
@@ -1,6 +1,33 @@
|
||||
|
||||
0. Define how many physical regs are available, which are caller-saved and callee-saved
|
||||
1. Implement if-else and while statements
|
||||
# Milestones
|
||||
|
||||
## Clean codebase structure
|
||||
|
||||
0. Prelude classes like FileIO, strings null-termination etc.
|
||||
1. Diagnostic helper class for logging
|
||||
2. Remove "void" valuehandle class and use it as ValueHandle::Type instead
|
||||
3. Function multiple arguments support
|
||||
4. Implement if-else and while statements
|
||||
|
||||
## Types support in language
|
||||
|
||||
## Stack based code generation
|
||||
|
||||
0. Stack based codegen, i.e. for fasm x86_64
|
||||
|
||||
## IR Optimizations aka const folding, deadcode elimination
|
||||
|
||||
## Register allocation
|
||||
|
||||
## First beta assembly code generation with registers
|
||||
|
||||
## ...
|
||||
|
||||
-------------------------------------------------
|
||||
|
||||
|
||||
# References for IR optimizations
|
||||
|
||||
2. Find out what use[B] and def[B] are for each block
|
||||
3. Define successors and predecessors of each block and make them accessible
|
||||
4. Compute liveIn[B] and liveOut[B] for each block
|
||||
@@ -19,6 +46,7 @@
|
||||
- Spill to stack slots
|
||||
- Add “CALL clobbers regs” rule
|
||||
|
||||
# References for register allocation
|
||||
|
||||
function's reserved registers:
|
||||
EAX, ECX, EDX
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
#pragma once
|
||||
#include "prelude/string.hpp"
|
||||
#include "ir/slot.hpp"
|
||||
#include "codegen/slot.hpp"
|
||||
|
||||
#define AVAILABLE_REGISTERS 4
|
||||
#define AVAILABLE_STACK_SIZE 4096
|
||||
|
||||
template<typename Slot, typename SlotAddr = const StringView&>
|
||||
template <typename Slot, typename SlotAddr = const StringView &>
|
||||
class Allocator
|
||||
{
|
||||
public:
|
||||
virtual ~Allocator() {};
|
||||
|
||||
public:
|
||||
virtual const Slot& Allocate(SlotAddr addr) = 0;
|
||||
virtual const Slot& Resolve(SlotAddr addr) = 0;
|
||||
virtual const Slot &Allocate(SlotAddr addr) = 0;
|
||||
virtual const Slot &Resolve(SlotAddr addr) = 0;
|
||||
};
|
||||
|
||||
class SlotAllocator : public Allocator<IR::IRSlot>
|
||||
@@ -20,8 +21,9 @@ class SlotAllocator : public Allocator<IR::IRSlot>
|
||||
public:
|
||||
SlotAllocator() = default;
|
||||
~SlotAllocator() = default;
|
||||
|
||||
public:
|
||||
const IR::IRSlot& Allocate(const StringView& addr) override
|
||||
const IR::IRSlot &Allocate(const StringView &addr) override
|
||||
{
|
||||
if (m_regs < AVAILABLE_REGISTERS)
|
||||
{
|
||||
@@ -38,7 +40,7 @@ public:
|
||||
assert(0 && "failed to allocate local");
|
||||
}
|
||||
|
||||
const IR::IRSlot& Resolve(const StringView& addr) override
|
||||
const IR::IRSlot &Resolve(const StringView &addr) override
|
||||
{
|
||||
for (size_t i = 0; i < m_slots.size; ++i)
|
||||
{
|
||||
@@ -50,10 +52,13 @@ public:
|
||||
|
||||
assert(0 && "could not resolve stack offset for specified address");
|
||||
}
|
||||
|
||||
public:
|
||||
View<IR::IRSlot> slots() const { return m_slots.view(); }
|
||||
|
||||
public:
|
||||
unsigned int GetStackSize() const { return m_offset_counter; }
|
||||
|
||||
public:
|
||||
int m_regs = 0;
|
||||
unsigned int m_offset_counter = 0;
|
||||
@@ -2,8 +2,6 @@
|
||||
#include <unordered_map>
|
||||
#include "prelude/string.hpp"
|
||||
#include "parser/ast.hpp"
|
||||
#include "ir/slot.hpp"
|
||||
#include "ir/allocator.hpp"
|
||||
#include "ir/value.hpp"
|
||||
#include "ir/ops.hpp"
|
||||
|
||||
@@ -158,7 +156,6 @@ namespace IR
|
||||
}
|
||||
|
||||
public:
|
||||
// TODO: think about safety (copying m_ops->data before giving)
|
||||
OpView ops() const { return OpView(m_ops->data, m_ops->size); }
|
||||
|
||||
private:
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace IR
|
||||
StringView m_symbol;
|
||||
};
|
||||
|
||||
// TODO: Make function return value (i.e. inhreit the OpValued class instead)
|
||||
// TODO: Make function return value (i.e. inherit the OpValued class instead)
|
||||
class FnOp : public Op
|
||||
{
|
||||
public:
|
||||
@@ -87,30 +87,6 @@ namespace IR
|
||||
ValueHandle::Type *m_typ;
|
||||
};
|
||||
|
||||
// class LoadConstOp : public OpValued
|
||||
// {
|
||||
// public:
|
||||
// LoadConstOp(ValueHandle *dest, long value)
|
||||
// : OpValued(dest), m_value(value) {}
|
||||
// ~LoadConstOp() {}
|
||||
|
||||
// OP_TYPE(LOAD_CONST)
|
||||
// public:
|
||||
// StringView Format(int indent) const override
|
||||
// {
|
||||
// StringBuilder sb;
|
||||
// sb.AppendIndent(indent);
|
||||
// sb << result()->Format() << " = LOAD_CONST " << m_value;
|
||||
// return sb.view();
|
||||
// }
|
||||
|
||||
// public:
|
||||
// long value() const { return m_value; }
|
||||
|
||||
// private:
|
||||
// long m_value;
|
||||
// };
|
||||
|
||||
class LoadOp : public OpValued
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user