From d6c448af87b144a9fae3a9a4f5accc48d84214bc Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Wed, 5 Aug 2026 19:17:15 +1000 Subject: [PATCH] starting work on codegen, need to work on reg allocation to progress --- include/gravity/core.h | 3 ++ src/generators/arch/x86_64.c | 56 ++++++++++++++++++++++++++++++------ src/generators/arch/x86_64.h | 8 +----- src/generators/generator.c | 31 ++++++++++++++++++++ src/generators/generator.h | 17 +++++++++++ src/ir/type.c | 11 +++++++ src/ir/type.h | 3 ++ test.c | 10 +++++-- 8 files changed, 121 insertions(+), 18 deletions(-) diff --git a/include/gravity/core.h b/include/gravity/core.h index ed4d900..bbb5dc6 100644 --- a/include/gravity/core.h +++ b/include/gravity/core.h @@ -28,7 +28,10 @@ GravityBuilder gravityCreateBuilder(void); GravityFunction gravityNewFunction(GravityModule module, const char* name, GravityType functionType); GravityBlock gravityStartBlock(const char* name, GravityFunction function); +int gravityGetTypeSize(GravityType type); + GravityValue gravityBuildIntConstant(GravityBuilder builder, GravityType intType, int64_t value, const char* name); +GravityValue gravityNewIntConstant(GravityType intType, int64_t value); GravityType gravityCreateFunctionType(int numArgs, GravityType* argTypes, GravityType returnType); GravityType gravityCreateIntegerType(uint8_t width, bool isSigned); diff --git a/src/generators/arch/x86_64.c b/src/generators/arch/x86_64.c index 4a5f4de..c713b4d 100644 --- a/src/generators/arch/x86_64.c +++ b/src/generators/arch/x86_64.c @@ -16,45 +16,83 @@ void emitValue(GravityTargetArch self, GravityValue value) { } case GravityLocalValueKind: { + GravityVarSlot* slot; + HASH_FIND(hh, self->vars, value, sizeof(void*), slot); + assert(slot != NULL); + switch (slot->sizeBytes) { + case 1: sbAppend(self->outputBuffer, "byte [rbp - %d]", slot->stackPos + slot->sizeBytes); break; + case 2: sbAppend(self->outputBuffer, "word [rbp - %d]", slot->stackPos + slot->sizeBytes); break; + case 4: sbAppend(self->outputBuffer, "dword [rbp - %d]", slot->stackPos + slot->sizeBytes); break; + case 8: sbAppend(self->outputBuffer, "qword [rbp - %d]", slot->stackPos + slot->sizeBytes); break; + } + + break; } default: assert(false); } } +void emitInst(GravityTargetArch self, GravityInstruction inst) { +} + void emitRet(GravityTargetArch self, GravityValue value) { sbAppend(self->outputBuffer, "mov eax, "); emitValue(self, value); sbAppend(self->outputBuffer, "\nret"); } +void emitAlloc(GravityTargetArch self, GravityType type, GravityValue result) { + GravityVarSlot* varSlot = malloc(sizeof(GravityVarSlot)); + varSlot->stackPos = self->stackPos; + varSlot->sizeBytes = gravityGetTypeSize(type); + varSlot->type = type; + self->stackPos += varSlot->sizeBytes; + + HASH_ADD_KEYPTR(hh, self->vars, result, sizeof(void*), varSlot); +} + +void emitStore(GravityTargetArch self, GravityValue pointer, GravityValue value) { + sbAppend(self->outputBuffer, "mov "); + emitValue(self, pointer); + sbAppend(self->outputBuffer, ", "); + emitValue(self, value); + sbAppend(self->outputBuffer, "\n"); +} + +void emitLoad(GravityTargetArch self, GravityValue pointer, GravityValue result) { + sbAppend(self->outputBuffer, "mov "); + emitValue(self, result); + sbAppend(self->outputBuffer, ", "); + emitValue(self, pointer); + sbAppend(self->outputBuffer, "\n"); +} + GravityValue emitIntConst(GravityTargetArch self, GravityValue constVal) { return constVal; } void emitFunction(GravityTargetArch self, GravityFunction function) { - sbAppend(self->outputBuffer, "%s:\n", function->name); + sbAppend(self->outputBuffer, "%s:\npush rbp\nmov rbp, rsp\n", function->name); } void emitBlock(GravityTargetArch self, GravityBlock block) { sbAppend(self->outputBuffer, ".%s:\n", block->name); } -GravityTargetArch_x86_64 gravityCreate_x86_64Target(void) { +GravityTargetArch gravityCreate_x86_64Target(void) { GravityTargetArch baseArch = gravityNewTargetArch("x86_64"); baseArch->emitFunction = emitFunction; baseArch->emitBlock = emitBlock; + baseArch->emitInst = emitInst; baseArch->emitIntConst = emitIntConst; baseArch->emitRet = emitRet; + baseArch->emitAlloc = emitAlloc; + baseArch->emitStore = emitStore; + baseArch->emitLoad = emitLoad; - GravityTargetArch_x86_64 targetArch = { - .baseArch = baseArch, - - .stackPos = 0 - }; - - return targetArch; + return baseArch; } \ No newline at end of file diff --git a/src/generators/arch/x86_64.h b/src/generators/arch/x86_64.h index 2b75243..6a4473d 100644 --- a/src/generators/arch/x86_64.h +++ b/src/generators/arch/x86_64.h @@ -3,12 +3,6 @@ #include "../generator.h" -typedef struct { - GravityTargetArch baseArch; - - uint32_t stackPos; -} GravityTargetArch_x86_64; - -GravityTargetArch_x86_64 gravityCreate_x86_64Target(void); +GravityTargetArch gravityCreate_x86_64Target(void); #endif \ No newline at end of file diff --git a/src/generators/generator.c b/src/generators/generator.c index 3e68354..3c6ec40 100644 --- a/src/generators/generator.c +++ b/src/generators/generator.c @@ -13,14 +13,20 @@ GravityTargetArch gravityNewTargetArch(const char* name) { initStringBuff(outputBuff); targetArch->outputBuffer = outputBuff; targetArch->name = strdup(name); + targetArch->vars = NULL; return targetArch; } void gravityTargetEmitInst(GravityTargetArch arch, GravityInstruction inst) { + arch->emitInst(arch, inst); + switch (inst.opcode) { case GravityOpcodeIntConst: arch->emitIntConst(arch, inst.operands[0]); break; case GravityOpcodeRet: arch->emitRet(arch, inst.operands[0]); break; + case GravityOpcodeAlloc: arch->emitAlloc(arch, inst.operands[0]->type->typeData, inst.result); break; + case GravityOpcodeStore: arch->emitStore(arch, inst.operands[0], inst.operands[1]); break; + case GravityOpcodeLoad: arch->emitLoad(arch, inst.operands[0], inst.result); break; default: assert(false); } @@ -50,4 +56,29 @@ char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module) { } return arch->outputBuffer->data; +} + +GravityType gravityResolveInstructionResult(GravityTargetArch arch, GravityInstruction inst) { + switch (inst.opcode) { + case GravityOpcodeAlloc: { + GravityType outType = gravityCreateType(); + outType->typeKind = GravityPointerTypeKind; + outType->ptrType = inst.operands[0]->type->typeData; + return outType; + } + + case GravityOpcodeLoad: { + + GravityVarSlot* var; + HASH_FIND(hh, arch->vars, inst.operands[0], sizeof(void*), var); + + if (!var) assert(false); + + return var->type->ptrType; + } + + default: assert(false); + } + + } \ No newline at end of file diff --git a/src/generators/generator.h b/src/generators/generator.h index 95701b2..ec44d0e 100644 --- a/src/generators/generator.h +++ b/src/generators/generator.h @@ -3,23 +3,40 @@ #include "../ir/module.h" #include "../ir/type.h" +#include typedef struct GravityOpaqueTargetArch* GravityTargetArch; +typedef struct { + uint32_t stackPos; + uint32_t sizeBytes; + GravityType type; + UT_hash_handle hh; +} GravityVarSlot; + struct GravityOpaqueTargetArch { const char* name; StringBuffer* outputBuffer; GravityFunction currentFunction; + uint32_t stackPos; + GravityVarSlot* vars; + void (*emitFunction)(GravityTargetArch self, GravityFunction function); void (*emitBlock)(GravityTargetArch self, GravityBlock block); void (*emitValue)(GravityTargetArch self, GravityValue value); + void (*emitInst)(GravityTargetArch self, GravityInstruction inst); GravityValue (*emitIntConst)(GravityTargetArch self, GravityValue constVal); void (*emitRet)(GravityTargetArch self, GravityValue returnValue); + void (*emitAlloc)(GravityTargetArch self, GravityType type, GravityValue result); + void (*emitStore)(GravityTargetArch self, GravityValue pointer, GravityValue value); + void (*emitLoad)(GravityTargetArch self, GravityValue pointer, GravityValue result); }; +GravityType gravityResolveInstructionResult(GravityTargetArch arch, GravityInstruction inst); + GravityTargetArch gravityNewTargetArch(const char* name); char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module); diff --git a/src/ir/type.c b/src/ir/type.c index 97ff886..337dae9 100644 --- a/src/ir/type.c +++ b/src/ir/type.c @@ -68,4 +68,15 @@ char* gravityTypeToCStr(GravityType type) { } return buff.data; +} + +int gravityGetTypeSize(GravityType type) { + printf("%d\n", type->typeKind); + switch (type->typeKind) { + case GravityIntTypeKind: return type->integer.width / 8; + case GravityPointerTypeKind: return sizeof(void*); + case GravityFloatTypeKind: return 4; + + default: assert(false); + } } \ No newline at end of file diff --git a/src/ir/type.h b/src/ir/type.h index 1465bb6..46e910c 100644 --- a/src/ir/type.h +++ b/src/ir/type.h @@ -36,6 +36,7 @@ struct GravityOpaqueType { GravityFunctionType function; GravityIntType integer; GravityType typeData; + GravityType ptrType; }; }; @@ -48,4 +49,6 @@ GravityType gravityCreatePointerType(void); char* gravityTypeToCStr(GravityType type); +int gravityGetTypeSize(GravityType type); + #endif \ No newline at end of file diff --git a/test.c b/test.c index 772bbac..ed86450 100644 --- a/test.c +++ b/test.c @@ -51,8 +51,14 @@ int main(void) { gravityBuildRet(builder, xValue);*/ gravityBuilderSwitchToBlock(builder, entryBlock); - GravityValue returnVal = gravityBuildIntConstant(builder, charType, 123, NULL); - gravityBuildRet(builder, returnVal); + + GravityValue variable = gravityBuildAlloc(builder, charType, NULL); + GravityValue returnVal = gravityNewIntConstant(charType, 123);//gravityBuildIntConstant(builder, charType, 123, NULL); + gravityBuildStore(builder, variable, returnVal); + + + GravityValue varValue = gravityBuildLoad(builder, variable, NULL); + gravityBuildRet(builder, varValue); printf("%s\n", gravityFunctionToCStr(mainFunc));