generators set up
This commit is contained in:
2
.clangd
2
.clangd
@@ -1,2 +1,2 @@
|
|||||||
CompileFlags:
|
CompileFlags:
|
||||||
Add: [-Wall, -Wextra, -pedantic, -O3]
|
Add: [-Wall, -Wextra, -O3]
|
||||||
2
Makefile
2
Makefile
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
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
|
#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
|
||||||
@@ -1 +0,0 @@
|
|||||||
#include "generator.h"
|
|
||||||
12
test.c
12
test.c
@@ -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;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user