generators set up
This commit is contained in:
2
.clangd
2
.clangd
@@ -1,2 +1,2 @@
|
||||
CompileFlags:
|
||||
Add: [-Wall, -Wextra, -pedantic, -O3]
|
||||
Add: [-Wall, -Wextra, -O3]
|
||||
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@ SRC=src
|
||||
OBJ=obj
|
||||
|
||||
CC=gcc
|
||||
CFLAGS=-Wall -Wextra -fPIC -O3
|
||||
CFLAGS=-Wall -Wextra -fPIC -O3# -fsanitize=address -g
|
||||
|
||||
TARGET=libgravity.so
|
||||
TEST_TARGET=testapp
|
||||
|
||||
@@ -10,6 +10,7 @@ typedef struct GravityOpaqueValue* GravityValue;
|
||||
typedef struct GravityOpaqueBuilder* GravityBuilder;
|
||||
typedef struct GravityOpaqueFunction* GravityFunction;
|
||||
typedef struct GravityOpaqueBlock* GravityBlock;
|
||||
typedef struct GravityOpaqueTargetArch* GravityTargetArch;
|
||||
|
||||
typedef struct GravityOpaqueType* GravityType;
|
||||
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 gravityBuildJump(GravityBuilder builder, GravityBlock block, GravityValue* params);
|
||||
|
||||
// targets
|
||||
char* gravityTargetEmitModule(GravityTargetArch arch, GravityModule module);
|
||||
|
||||
GravityTargetArch gravityCreate_x86_64Target(void);
|
||||
|
||||
// ============================ //
|
||||
|
||||
#endif
|
||||
60
src/generators/arch/x86_64.c
Normal file
60
src/generators/arch/x86_64.c
Normal 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;
|
||||
}
|
||||
14
src/generators/arch/x86_64.h
Normal file
14
src/generators/arch/x86_64.h
Normal 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
|
||||
53
src/generators/generator.c
Normal file
53
src/generators/generator.c
Normal 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;
|
||||
}
|
||||
@@ -2,13 +2,25 @@
|
||||
#define __GRAVITY__GENERATOR_H
|
||||
|
||||
#include "../ir/module.h"
|
||||
#include "../ir/type.h"
|
||||
|
||||
typedef struct GravityOpaqueGenerator* GravityGenerator;
|
||||
struct GravityOpaqueGenerator {
|
||||
GravityModule module;
|
||||
char* (*generateAssembly)(GravityGenerator self);
|
||||
typedef struct GravityOpaqueTargetArch* GravityTargetArch;
|
||||
|
||||
struct GravityOpaqueTargetArch {
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
#include "generator.h"
|
||||
12
test.c
12
test.c
@@ -7,12 +7,12 @@ int main(void) {
|
||||
GravityBuilder builder = gravityCreateBuilder();
|
||||
|
||||
GravityType charType = gravityCreateIntegerType(8, false);
|
||||
GravityType ptrType = gravityCreatePointerType();
|
||||
|
||||
GravityType mainFuncType = gravityCreateFunctionType(0, NULL, charType);
|
||||
GravityFunction mainFunc = gravityNewFunction(module, "main", mainFuncType);
|
||||
GravityBlock entryBlock = gravityStartBlock("entry", mainFunc);
|
||||
|
||||
/*
|
||||
// define blocks
|
||||
GravityBlock thenBlock = gravityStartBlock("then", mainFunc);
|
||||
gravityAppendBlockArgument(thenBlock, ptrType);
|
||||
@@ -48,9 +48,17 @@ int main(void) {
|
||||
gravityBuilderSwitchToBlock(builder, mergeBlock);
|
||||
GravityValue xVar = gravityGetBlockArg(mergeBlock, 0);
|
||||
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));
|
||||
|
||||
GravityTargetArch target = gravityCreate_x86_64Target();
|
||||
char* outputASM = gravityTargetEmitModule(target, module);
|
||||
printf("%s\n", outputASM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user