first codegen prototype
This commit is contained in:
70
include/codegen/targets/fasm_x86_64_linux.hpp
Normal file
70
include/codegen/targets/fasm_x86_64_linux.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
#include "codegen/codegen.hpp"
|
||||
#include "ir/op.hpp"
|
||||
#include "ir/ops.hpp"
|
||||
#include "prelude/linkedlist.hpp"
|
||||
|
||||
class FasmX86_64Generator : public CodeGenerator
|
||||
{
|
||||
public:
|
||||
FasmX86_64Generator() = default;
|
||||
|
||||
public:
|
||||
bool Generate(const IR::OpView* ops) override
|
||||
{
|
||||
output().Extend("format ELF64\n");
|
||||
output().Extend("section '.text' executable\n");
|
||||
|
||||
for (size_t i = 0; i < ops->size; ++i)
|
||||
{
|
||||
GenerateStatement(ops->data[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void GenerateExtern(IR::ExternOp* extrn)
|
||||
{
|
||||
// TODO: instead of __<symbol, use some random UID or hash string
|
||||
// for safety and collision considerations
|
||||
output().AppendFormat("extrn '%s' as __%s\n", extrn->symbol().c_str(), extrn->symbol().c_str());
|
||||
output().AppendFormat("%s = PLT __%s\n", extrn->symbol().c_str(), extrn->symbol().c_str());
|
||||
}
|
||||
|
||||
void GenerateFunction(IR::FnOp* fn)
|
||||
{
|
||||
output().AppendFormat("public %s\n", fn->name().c_str());
|
||||
output().AppendFormat("%s:\n", fn->name().c_str());
|
||||
output().Extend(" push rbp\n");
|
||||
output().Extend(" mov rbp, rsp\n");
|
||||
|
||||
for (auto cur = fn->body().ops().Begin(); cur != nullptr; cur = cur->next)
|
||||
{
|
||||
GenerateStatement(cur->value);
|
||||
}
|
||||
|
||||
output().Extend(" leave\n");
|
||||
output().Extend(" ret\n");
|
||||
}
|
||||
|
||||
void GenerateCall(IR::CallOp* call)
|
||||
{
|
||||
output().AppendFormat(" call %s\n", call->callee().c_str());
|
||||
}
|
||||
|
||||
void GenerateStatement(IR::Op* op)
|
||||
{
|
||||
switch(op->GetType())
|
||||
{
|
||||
case IR::OpType::EXTERN:
|
||||
return GenerateExtern(reinterpret_cast<IR::ExternOp*>(op));
|
||||
case IR::OpType::FN:
|
||||
return GenerateFunction(reinterpret_cast<IR::FnOp*>(op));
|
||||
case IR::OpType::CALL:
|
||||
return GenerateCall(reinterpret_cast<IR::CallOp*>(op));
|
||||
// TODO:
|
||||
default: output().AppendFormat(" ; %d not implemented\n", op->GetType());
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user