generators set up

This commit is contained in:
2026-08-04 11:30:30 +10:00
parent 9eab7ffbda
commit 6de562b7c3
9 changed files with 162 additions and 10 deletions

View File

@@ -1,2 +1,2 @@
CompileFlags: CompileFlags:
Add: [-Wall, -Wextra, -pedantic, -O3] Add: [-Wall, -Wextra, -O3]

View File

@@ -2,7 +2,7 @@ SRC=src
OBJ=obj OBJ=obj
CC=gcc CC=gcc
CFLAGS=-Wall -Wextra -fPIC -O3 CFLAGS=-Wall -Wextra -fPIC -O3# -fsanitize=address -g
TARGET=libgravity.so TARGET=libgravity.so
TEST_TARGET=testapp TEST_TARGET=testapp

View File

@@ -10,6 +10,7 @@ typedef struct GravityOpaqueValue* GravityValue;
typedef struct GravityOpaqueBuilder* GravityBuilder; typedef struct GravityOpaqueBuilder* GravityBuilder;
typedef struct GravityOpaqueFunction* GravityFunction; typedef struct GravityOpaqueFunction* GravityFunction;
typedef struct GravityOpaqueBlock* GravityBlock; typedef struct GravityOpaqueBlock* GravityBlock;
typedef struct GravityOpaqueTargetArch* GravityTargetArch;
typedef struct GravityOpaqueType* GravityType; typedef struct GravityOpaqueType* GravityType;
typedef enum { 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 gravityBuildBr(GravityBuilder builder, GravityValue condition, GravityBlock thenBranch, GravityValue* thenParams, GravityBlock elseBranch, GravityValue* elseParams);
void gravityBuildJump(GravityBuilder builder, GravityBlock block, GravityValue* params); void gravityBuildJump(GravityBuilder builder, GravityBlock block, GravityValue* params);
// targets
char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module);
GravityTargetArch gravityCreate_x86_64Target(void);
// ============================ // // ============================ //
#endif #endif

View File

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

View File

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

View File

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

View File

@@ -2,13 +2,25 @@
#define __GRAVITY__GENERATOR_H #define __GRAVITY__GENERATOR_H
#include "../ir/module.h" #include "../ir/module.h"
#include "../ir/type.h"
typedef struct GravityOpaqueGenerator* GravityGenerator; typedef struct GravityOpaqueTargetArch* GravityTargetArch;
struct GravityOpaqueGenerator {
GravityModule module; struct GravityOpaqueTargetArch {
char* (*generateAssembly)(GravityGenerator self); 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 #endif

View File

@@ -1 +0,0 @@
#include "generator.h"

12
test.c
View File

@@ -7,12 +7,12 @@ int main(void) {
GravityBuilder builder = gravityCreateBuilder(); GravityBuilder builder = gravityCreateBuilder();
GravityType charType = gravityCreateIntegerType(8, false); GravityType charType = gravityCreateIntegerType(8, false);
GravityType ptrType = gravityCreatePointerType();
GravityType mainFuncType = gravityCreateFunctionType(0, NULL, charType); GravityType mainFuncType = gravityCreateFunctionType(0, NULL, charType);
GravityFunction mainFunc = gravityNewFunction(module, "main", mainFuncType); GravityFunction mainFunc = gravityNewFunction(module, "main", mainFuncType);
GravityBlock entryBlock = gravityStartBlock("entry", mainFunc); GravityBlock entryBlock = gravityStartBlock("entry", mainFunc);
/*
// define blocks // define blocks
GravityBlock thenBlock = gravityStartBlock("then", mainFunc); GravityBlock thenBlock = gravityStartBlock("then", mainFunc);
gravityAppendBlockArgument(thenBlock, ptrType); gravityAppendBlockArgument(thenBlock, ptrType);
@@ -48,9 +48,17 @@ int main(void) {
gravityBuilderSwitchToBlock(builder, mergeBlock); gravityBuilderSwitchToBlock(builder, mergeBlock);
GravityValue xVar = gravityGetBlockArg(mergeBlock, 0); GravityValue xVar = gravityGetBlockArg(mergeBlock, 0);
GravityValue xValue = gravityBuildLoad(builder, xVar, "xValue"); 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)); printf("%s\n", gravityFunctionToCStr(mainFunc));
GravityTargetArch target = gravityCreate_x86_64Target();
char* outputASM = gravityTargetEmitModule(target, module);
printf("%s\n", outputASM);
return 0; return 0;
} }