starting work on codegen, need to work on reg allocation to progress
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -50,4 +56,29 @@ 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -68,4 +68,15 @@ 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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
10
test.c
@@ -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));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user