starting work on codegen, need to work on reg allocation to progress

This commit is contained in:
2026-08-05 19:17:15 +10:00
parent 6de562b7c3
commit d6c448af87
8 changed files with 121 additions and 18 deletions

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -3,23 +3,40 @@
#include "../ir/module.h"
#include "../ir/type.h"
#include <uthash.h>
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);

View File

@@ -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);
}
}

View File

@@ -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

10
test.c
View File

@@ -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));