84 lines
2.6 KiB
C
84 lines
2.6 KiB
C
#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);
|
|
targetArch->vars = NULL;
|
|
|
|
return targetArch;
|
|
}
|
|
|
|
void gravityTargetEmitInst(GravityTargetArch arch, GravityInstruction inst) {
|
|
arch->emitInst(arch, inst);
|
|
|
|
switch (inst.opcode) {
|
|
case GravityOpcodeIntConst: arch->emitIntConst(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);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
} |