From 6de562b7c3a9b63e40cd379230a398d09b824a80 Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Tue, 4 Aug 2026 11:30:30 +1000 Subject: [PATCH] generators set up --- .clangd | 2 +- Makefile | 2 +- include/gravity/core.h | 6 ++++ src/generators/arch/x86_64.c | 60 +++++++++++++++++++++++++++++++++++ src/generators/arch/x86_64.h | 14 ++++++++ src/generators/generator.c | 53 +++++++++++++++++++++++++++++++ src/generators/generator.h | 22 ++++++++++--- src/generators/linux_x86-64.c | 1 - test.c | 12 +++++-- 9 files changed, 162 insertions(+), 10 deletions(-) create mode 100644 src/generators/arch/x86_64.c create mode 100644 src/generators/arch/x86_64.h create mode 100644 src/generators/generator.c delete mode 100644 src/generators/linux_x86-64.c diff --git a/.clangd b/.clangd index 8e70209..5f3616d 100644 --- a/.clangd +++ b/.clangd @@ -1,2 +1,2 @@ CompileFlags: - Add: [-Wall, -Wextra, -pedantic, -O3] \ No newline at end of file + Add: [-Wall, -Wextra, -O3] \ No newline at end of file diff --git a/Makefile b/Makefile index ac5339c..8b89b60 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ SRC=src OBJ=obj CC=gcc -CFLAGS=-Wall -Wextra -fPIC -O3 +CFLAGS=-Wall -Wextra -fPIC -O3# -fsanitize=address -g TARGET=libgravity.so TEST_TARGET=testapp diff --git a/include/gravity/core.h b/include/gravity/core.h index f0300ec..ed4d900 100644 --- a/include/gravity/core.h +++ b/include/gravity/core.h @@ -10,6 +10,7 @@ typedef struct GravityOpaqueValue* GravityValue; typedef struct GravityOpaqueBuilder* GravityBuilder; typedef struct GravityOpaqueFunction* GravityFunction; typedef struct GravityOpaqueBlock* GravityBlock; +typedef struct GravityOpaqueTargetArch* GravityTargetArch; typedef struct GravityOpaqueType* GravityType; typedef enum { @@ -50,6 +51,11 @@ void gravityBuildRet(GravityBuilder builder, GravityValue returnValue); void gravityBuildBr(GravityBuilder builder, GravityValue condition, GravityBlock thenBranch, GravityValue* thenParams, GravityBlock elseBranch, GravityValue* elseParams); void gravityBuildJump(GravityBuilder builder, GravityBlock block, GravityValue* params); +// targets +char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module); + +GravityTargetArch gravityCreate_x86_64Target(void); + // ============================ // #endif \ No newline at end of file diff --git a/src/generators/arch/x86_64.c b/src/generators/arch/x86_64.c new file mode 100644 index 0000000..4a5f4de --- /dev/null +++ b/src/generators/arch/x86_64.c @@ -0,0 +1,60 @@ +#include "x86_64.h" + +void emitValue(GravityTargetArch self, GravityValue value) { + switch (value->kind) { + case GravityConstantValueKind: { + switch (value->type->typeKind) { + case GravityIntTypeKind: { + sbAppend(self->outputBuffer, "%ld", value->constant.intValue); + break; + } + + default: assert(false); + } + + break; + } + + case GravityLocalValueKind: { + + } + + default: assert(false); + } +} + +void emitRet(GravityTargetArch self, GravityValue value) { + sbAppend(self->outputBuffer, "mov eax, "); + emitValue(self, value); + sbAppend(self->outputBuffer, "\nret"); +} + +GravityValue emitIntConst(GravityTargetArch self, GravityValue constVal) { + return constVal; +} + +void emitFunction(GravityTargetArch self, GravityFunction function) { + sbAppend(self->outputBuffer, "%s:\n", function->name); +} + +void emitBlock(GravityTargetArch self, GravityBlock block) { + sbAppend(self->outputBuffer, ".%s:\n", block->name); +} + +GravityTargetArch_x86_64 gravityCreate_x86_64Target(void) { + GravityTargetArch baseArch = gravityNewTargetArch("x86_64"); + + baseArch->emitFunction = emitFunction; + baseArch->emitBlock = emitBlock; + + baseArch->emitIntConst = emitIntConst; + baseArch->emitRet = emitRet; + + GravityTargetArch_x86_64 targetArch = { + .baseArch = baseArch, + + .stackPos = 0 + }; + + return targetArch; +} \ No newline at end of file diff --git a/src/generators/arch/x86_64.h b/src/generators/arch/x86_64.h new file mode 100644 index 0000000..2b75243 --- /dev/null +++ b/src/generators/arch/x86_64.h @@ -0,0 +1,14 @@ +#ifndef __GRAVITY__X86_64_H +#define __GRAVITY__X86_64_H + +#include "../generator.h" + +typedef struct { + GravityTargetArch baseArch; + + uint32_t stackPos; +} GravityTargetArch_x86_64; + +GravityTargetArch_x86_64 gravityCreate_x86_64Target(void); + +#endif \ No newline at end of file diff --git a/src/generators/generator.c b/src/generators/generator.c new file mode 100644 index 0000000..3e68354 --- /dev/null +++ b/src/generators/generator.c @@ -0,0 +1,53 @@ +#include "generator.h" + +GravityTargetArch gravityNewTargetArch(const char* name) { + GravityTargetArch targetArch = malloc(sizeof(struct GravityOpaqueTargetArch)); + if (targetArch == NULL) return targetArch; + + StringBuffer* outputBuff = malloc(sizeof(StringBuffer)); + if (outputBuff == NULL) { + free(targetArch); + return NULL; + } + + initStringBuff(outputBuff); + targetArch->outputBuffer = outputBuff; + targetArch->name = strdup(name); + + return targetArch; +} + +void gravityTargetEmitInst(GravityTargetArch arch, GravityInstruction inst) { + switch (inst.opcode) { + case GravityOpcodeIntConst: arch->emitIntConst(arch, inst.operands[0]); break; + case GravityOpcodeRet: arch->emitRet(arch, inst.operands[0]); break; + + default: assert(false); + } +} + +void gravityTargetEmitBlock(GravityTargetArch arch, GravityBlock block) { + arch->emitBlock(arch, block); + + for (unsigned int i = 0; i < block->instructions.count; i++) { + gravityTargetEmitInst(arch, *get(block->instructions, i)); + } +} + +void gravityTargetEmitFunction(GravityTargetArch arch, GravityFunction function) { + arch->currentFunction = function; + + arch->emitFunction(arch, function); + + for (unsigned int i = 0; i < function->blocks.count; i++) { + gravityTargetEmitBlock(arch, *get(function->blocks, i)); + } +} + +char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module) { + for (unsigned int i = 0; i < module->functions.count; i++) { + gravityTargetEmitFunction(arch, *get(module->functions, i)); + } + + return arch->outputBuffer->data; +} \ No newline at end of file diff --git a/src/generators/generator.h b/src/generators/generator.h index 335c1e5..95701b2 100644 --- a/src/generators/generator.h +++ b/src/generators/generator.h @@ -2,13 +2,25 @@ #define __GRAVITY__GENERATOR_H #include "../ir/module.h" +#include "../ir/type.h" -typedef struct GravityOpaqueGenerator* GravityGenerator; -struct GravityOpaqueGenerator { - GravityModule module; - char* (*generateAssembly)(GravityGenerator self); +typedef struct GravityOpaqueTargetArch* GravityTargetArch; + +struct GravityOpaqueTargetArch { + const char* name; + StringBuffer* outputBuffer; + + GravityFunction currentFunction; + + void (*emitFunction)(GravityTargetArch self, GravityFunction function); + void (*emitBlock)(GravityTargetArch self, GravityBlock block); + void (*emitValue)(GravityTargetArch self, GravityValue value); + + GravityValue (*emitIntConst)(GravityTargetArch self, GravityValue constVal); + void (*emitRet)(GravityTargetArch self, GravityValue returnValue); }; - +GravityTargetArch gravityNewTargetArch(const char* name); +char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module); #endif \ No newline at end of file diff --git a/src/generators/linux_x86-64.c b/src/generators/linux_x86-64.c deleted file mode 100644 index 811bc03..0000000 --- a/src/generators/linux_x86-64.c +++ /dev/null @@ -1 +0,0 @@ -#include "generator.h" \ No newline at end of file diff --git a/test.c b/test.c index c135573..772bbac 100644 --- a/test.c +++ b/test.c @@ -7,12 +7,12 @@ int main(void) { GravityBuilder builder = gravityCreateBuilder(); GravityType charType = gravityCreateIntegerType(8, false); - GravityType ptrType = gravityCreatePointerType(); GravityType mainFuncType = gravityCreateFunctionType(0, NULL, charType); GravityFunction mainFunc = gravityNewFunction(module, "main", mainFuncType); GravityBlock entryBlock = gravityStartBlock("entry", mainFunc); + /* // define blocks GravityBlock thenBlock = gravityStartBlock("then", mainFunc); gravityAppendBlockArgument(thenBlock, ptrType); @@ -48,9 +48,17 @@ int main(void) { gravityBuilderSwitchToBlock(builder, mergeBlock); GravityValue xVar = gravityGetBlockArg(mergeBlock, 0); GravityValue xValue = gravityBuildLoad(builder, xVar, "xValue"); - gravityBuildRet(builder, xValue); + gravityBuildRet(builder, xValue);*/ + + gravityBuilderSwitchToBlock(builder, entryBlock); + GravityValue returnVal = gravityBuildIntConstant(builder, charType, 123, NULL); + gravityBuildRet(builder, returnVal); printf("%s\n", gravityFunctionToCStr(mainFunc)); + GravityTargetArch target = gravityCreate_x86_64Target(); + char* outputASM = gravityTargetEmitModule(target, module); + printf("%s\n", outputASM); + return 0; } \ No newline at end of file