Project restucture with IR and CG

This commit is contained in:
Scarlett
2025-04-25 19:29:05 -04:00
parent bac8cb53bb
commit 086c8ba170
15 changed files with 1262 additions and 1270 deletions

View File

@ -0,0 +1,590 @@
#include "codegen.h"
int generate() {
offset = 0;
Instruction *i = begin;
while (i != NULL) {
switch (getOp(i)) {
case E_LABEL:
generateLabel(i);
break;
case E_ADD:
generateAdd(i);
break;
case E_SUB:
generateSub(i);
break;
case E_MUL:
generateMult(i);
break;
case E_DIV:
generateDiv(i);
break;
case E_MOD:
generateMod(i);
break;
case E_OR:
generateOr(i);
break;
case E_AND:
generateAnd(i);
break;
case E_NEG:
generateNeg(i);
break;
case E_NOT:
generateNot(i);
break;
case E_ASSIGN:
generateAssign(i);
break;
case E_GOTO:
generateGoto(i);
break;
case E_IF_X_TRUE:
generateIfTrue(i);
break;
case E_IF_X_FALSE:
generateIfFalse(i);
break;
case E_LESS_THAN:
generateLessThan(i);
break;
case E_EQUAL_TO:
generateEqualTo(i);
break;
case E_CALL:
generateCall(i);
break;
case E_PARAM:
generateParam(i);
break;
case E_RETURN:
generateReturn(i);
break;
case E_INDEX_COPY_RIGHT:
generateCopyRight(i);
break;
case E_INDEX_COPY_LEFT:
generateCopyLeft(i);
break;
case E_ADDRESS_OF:
generateAddressOf(i);
break;
default:;
}
i = i->next;
}
return -1;
}
CGNode *getNextCG(CGNode *cg) {
if (cg == NULL) {
return NULL;
}
return cg->next;
}
int getAddress(CGNode *cg) {
if (cg == NULL) {
return -1;
}
return currentsp - cg->address;
}
TableNode *getTNofCG(CGNode *cg) {
if (cg == NULL) {
return NULL;
}
return cg->tn;
}
CGNode *findCG(TableNode *tn) {
CGNode *cg = cgList;
while (cg != NULL) {
if (getTNofCG(cg) == tn) {
return cg;
}
cg = getNextCG(cg);
}
return NULL;
}
CGNode *addCG(TableNode *tn, int sp) {
CGNode *cg = calloc(1, sizeof(CGNode));
cg->tn = tn;
cg->address = sp;
offset += getPrimSize(tn); //not sure if this is the correct amount to add to the offset
cg->next = cgList;
cgList = cg;
return cg;
}
int generateLabel(Instruction *inst) {
fprintf(cg_flag, ".L%d:\n", getLabel(inst));
return 0;
}
int generateAdd(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateAdd failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op1));
if (op1CG == NULL) {
printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1)));
return -1;
}
if (op2CG == NULL) {
printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\taddl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg));
return 0;
}
int generateSub(Instruction *instruction) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(instruction);
TNodeOrConst *op2 = getOperand2(instruction);
CGNode *cg = findCG(getResult(instruction));
if (op1 == NULL || op2 == NULL) {
printdebug("generateSub failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(instruction), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateSub failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg));
return 0;
}
int generateMult(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateMult failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateMult failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateMult failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg));
return 0;
}
int generateDiv(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateDiv failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateDiv failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateDiv failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax
fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax
fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG)); //divides edx by value accessed from stack
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result
return 0;
}
int generateMod(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateMod failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateMod failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax
fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax
fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG)); //divides edx by value accessed from stack
fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\n", getAddress(cg)); //stores result from edx (remainder)
return 0;
}
int generateOr(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateOr failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateOr failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateOr failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\torll\t%d(%%rbp), %%eax\n", getAddress(op2CG)); //divides edx by value accessed from stack
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result
return 0;
}
int generateAnd(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED);
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateAnd failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\tandl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg));
return 0;
}
int generateNeg(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateNeg failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateNeg failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\tnegl\t%d %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg));
return 0;
}
int generateNot(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateNot failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateNot failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateNot failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\tnotl\t%%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg));
return 0;
}
int generateAssign(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) {
printdebug("generateAssign failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
//add option for constant assignment (should be easy)
if (isConst(op1) == true) {
fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\n", getConst(op1), getAddress(cg));
}
CGNode *op1CG = findCG(getTN(op1));
if (op1CG == NULL) {
printdebug("generateAssign failed, op1 is not constant but not in CGlist");
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg));
return 0;
}
int generateGoto(Instruction *instruction) {
return -1;
}
int generateCondGoto(Instruction *instruction) {
return -1;
}
int generateIfTrue(Instruction *instruction) {
return -1;
// might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case
}
int generateIfFalse(Instruction *instruction) {
return -1;
}
int generateLessThan(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED);
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateLessThan failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tsetl\t%%al\n");
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
return 0;
}
int generateEqualTo(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED);
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateLessThan failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tsete\t%%al\n");
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
return 0;
}
int generateCall(Instruction *instruction) {
return -1;
//will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg
}
int generateReturn(Instruction *instruction) {
return -1;
//will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value
}
int generateCopyRight(Instruction *instruction) {
return -1;
}
int generateCopyLeft(Instruction *instruction) {
return -1;
}
int generateAddressOf(Instruction *instruction) {
return -1;
}
int generateParam(Instruction *instruction) {
//need to check if op1 is null, then add it to the appropriate register/cg node. need a way to keep track of this, maybe just have global count of params generated
return -1;
}