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); GravityFunction gravityNewFunction(GravityModule module, const char* name, GravityType functionType);
GravityBlock gravityStartBlock(const char* name, GravityFunction function); GravityBlock gravityStartBlock(const char* name, GravityFunction function);
int gravityGetTypeSize(GravityType type);
GravityValue gravityBuildIntConstant(GravityBuilder builder, GravityType intType, int64_t value, const char* name); 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 gravityCreateFunctionType(int numArgs, GravityType* argTypes, GravityType returnType);
GravityType gravityCreateIntegerType(uint8_t width, bool isSigned); GravityType gravityCreateIntegerType(uint8_t width, bool isSigned);

View File

@@ -16,45 +16,83 @@ void emitValue(GravityTargetArch self, GravityValue value) {
} }
case GravityLocalValueKind: { 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); default: assert(false);
} }
} }
void emitInst(GravityTargetArch self, GravityInstruction inst) {
}
void emitRet(GravityTargetArch self, GravityValue value) { void emitRet(GravityTargetArch self, GravityValue value) {
sbAppend(self->outputBuffer, "mov eax, "); sbAppend(self->outputBuffer, "mov eax, ");
emitValue(self, value); emitValue(self, value);
sbAppend(self->outputBuffer, "\nret"); 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) { GravityValue emitIntConst(GravityTargetArch self, GravityValue constVal) {
return constVal; return constVal;
} }
void emitFunction(GravityTargetArch self, GravityFunction function) { 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) { void emitBlock(GravityTargetArch self, GravityBlock block) {
sbAppend(self->outputBuffer, ".%s:\n", block->name); sbAppend(self->outputBuffer, ".%s:\n", block->name);
} }
GravityTargetArch_x86_64 gravityCreate_x86_64Target(void) { GravityTargetArch gravityCreate_x86_64Target(void) {
GravityTargetArch baseArch = gravityNewTargetArch("x86_64"); GravityTargetArch baseArch = gravityNewTargetArch("x86_64");
baseArch->emitFunction = emitFunction; baseArch->emitFunction = emitFunction;
baseArch->emitBlock = emitBlock; baseArch->emitBlock = emitBlock;
baseArch->emitInst = emitInst;
baseArch->emitIntConst = emitIntConst; baseArch->emitIntConst = emitIntConst;
baseArch->emitRet = emitRet; baseArch->emitRet = emitRet;
baseArch->emitAlloc = emitAlloc;
baseArch->emitStore = emitStore;
baseArch->emitLoad = emitLoad;
GravityTargetArch_x86_64 targetArch = { return baseArch;
.baseArch = baseArch,
.stackPos = 0
};
return targetArch;
} }

View File

@@ -3,12 +3,6 @@
#include "../generator.h" #include "../generator.h"
typedef struct { GravityTargetArch gravityCreate_x86_64Target(void);
GravityTargetArch baseArch;
uint32_t stackPos;
} GravityTargetArch_x86_64;
GravityTargetArch_x86_64 gravityCreate_x86_64Target(void);
#endif #endif

View File

@@ -13,14 +13,20 @@ GravityTargetArch gravityNewTargetArch(const char* name) {
initStringBuff(outputBuff); initStringBuff(outputBuff);
targetArch->outputBuffer = outputBuff; targetArch->outputBuffer = outputBuff;
targetArch->name = strdup(name); targetArch->name = strdup(name);
targetArch->vars = NULL;
return targetArch; return targetArch;
} }
void gravityTargetEmitInst(GravityTargetArch arch, GravityInstruction inst) { void gravityTargetEmitInst(GravityTargetArch arch, GravityInstruction inst) {
arch->emitInst(arch, inst);
switch (inst.opcode) { switch (inst.opcode) {
case GravityOpcodeIntConst: arch->emitIntConst(arch, inst.operands[0]); break; case GravityOpcodeIntConst: arch->emitIntConst(arch, inst.operands[0]); break;
case GravityOpcodeRet: arch->emitRet(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); default: assert(false);
} }
@@ -51,3 +57,28 @@ char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module) {
return arch->outputBuffer->data; 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/module.h"
#include "../ir/type.h" #include "../ir/type.h"
#include <uthash.h>
typedef struct GravityOpaqueTargetArch* GravityTargetArch; typedef struct GravityOpaqueTargetArch* GravityTargetArch;
typedef struct {
uint32_t stackPos;
uint32_t sizeBytes;
GravityType type;
UT_hash_handle hh;
} GravityVarSlot;
struct GravityOpaqueTargetArch { struct GravityOpaqueTargetArch {
const char* name; const char* name;
StringBuffer* outputBuffer; StringBuffer* outputBuffer;
GravityFunction currentFunction; GravityFunction currentFunction;
uint32_t stackPos;
GravityVarSlot* vars;
void (*emitFunction)(GravityTargetArch self, GravityFunction function); void (*emitFunction)(GravityTargetArch self, GravityFunction function);
void (*emitBlock)(GravityTargetArch self, GravityBlock block); void (*emitBlock)(GravityTargetArch self, GravityBlock block);
void (*emitValue)(GravityTargetArch self, GravityValue value); void (*emitValue)(GravityTargetArch self, GravityValue value);
void (*emitInst)(GravityTargetArch self, GravityInstruction inst);
GravityValue (*emitIntConst)(GravityTargetArch self, GravityValue constVal); GravityValue (*emitIntConst)(GravityTargetArch self, GravityValue constVal);
void (*emitRet)(GravityTargetArch self, GravityValue returnValue); 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); GravityTargetArch gravityNewTargetArch(const char* name);
char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module); char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module);

View File

@@ -69,3 +69,14 @@ char* gravityTypeToCStr(GravityType type) {
return buff.data; 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; GravityFunctionType function;
GravityIntType integer; GravityIntType integer;
GravityType typeData; GravityType typeData;
GravityType ptrType;
}; };
}; };
@@ -48,4 +49,6 @@ GravityType gravityCreatePointerType(void);
char* gravityTypeToCStr(GravityType type); char* gravityTypeToCStr(GravityType type);
int gravityGetTypeSize(GravityType type);
#endif #endif

10
test.c
View File

@@ -51,8 +51,14 @@ int main(void) {
gravityBuildRet(builder, xValue);*/ gravityBuildRet(builder, xValue);*/
gravityBuilderSwitchToBlock(builder, entryBlock); 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)); printf("%s\n", gravityFunctionToCStr(mainFunc));