implemented annies and meyers stuff
This commit is contained in:
355
src/codegen.c
355
src/codegen.c
@ -3,78 +3,79 @@
|
||||
|
||||
#include "codegen.h"
|
||||
|
||||
int generate() {
|
||||
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:;
|
||||
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;
|
||||
}
|
||||
@ -117,13 +118,14 @@ CGNode *findCG(TableNode *tn) {
|
||||
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
|
||||
offset += getPrimSize(getTypeEntry(tn));
|
||||
cg->address = offset;
|
||||
cg->next = cgList;
|
||||
cgList = cg;
|
||||
return cg;
|
||||
}
|
||||
|
||||
|
||||
int generateLabel(Instruction *inst) {
|
||||
fprintf(cg_flag, ".L%d:\n", getLabel(inst));
|
||||
return 0;
|
||||
@ -137,7 +139,7 @@ int generateAdd(Instruction *inst) {
|
||||
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;
|
||||
@ -146,7 +148,8 @@ int generateAdd(Instruction *inst) {
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op1));
|
||||
if (op1CG == NULL) {
|
||||
@ -158,15 +161,15 @@ int generateAdd(Instruction *inst) {
|
||||
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));
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#addition start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\taddl\t%%edx, %%eax\n");
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#addition end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateSub(Instruction *instruction) {
|
||||
/*
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
@ -174,7 +177,7 @@ int generateSub(Instruction *instruction) {
|
||||
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;
|
||||
@ -183,7 +186,7 @@ int generateSub(Instruction *instruction) {
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(instruction), offset);
|
||||
}
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
@ -196,14 +199,14 @@ int generateSub(Instruction *instruction) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#subtraction start\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));
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#subtraction end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateMult(Instruction *inst) {
|
||||
/*
|
||||
int generateMult(Instruction *inst){
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
@ -211,7 +214,7 @@ int generateMult(Instruction *inst) {
|
||||
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;
|
||||
@ -232,14 +235,14 @@ int generateMult(Instruction *inst) {
|
||||
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));
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#multiplication start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\timull\t%d(%%rbp), %%eax\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#multiplication end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateDiv(Instruction *inst) {
|
||||
/*
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
@ -247,7 +250,7 @@ int generateDiv(Instruction *inst) {
|
||||
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;
|
||||
@ -256,7 +259,7 @@ int generateDiv(Instruction *inst) {
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
@ -269,10 +272,10 @@ int generateDiv(Instruction *inst) {
|
||||
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
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#division start\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)\t#division end\n", getAddress(cg)); //stores result
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -285,7 +288,7 @@ int generateMod(Instruction *inst) {
|
||||
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;
|
||||
@ -300,21 +303,21 @@ int generateMod(Instruction *inst) {
|
||||
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)
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#mod start\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)\t#mod end\n", getAddress(cg)); //stores result from edx (remainder)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateOr(Instruction *inst) {
|
||||
/*
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
@ -322,7 +325,7 @@ int generateOr(Instruction *inst) {
|
||||
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;
|
||||
@ -331,7 +334,7 @@ int generateOr(Instruction *inst) {
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
@ -344,9 +347,24 @@ int generateOr(Instruction *inst) {
|
||||
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
|
||||
int label = label_gen();
|
||||
|
||||
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start or\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tjne\t.L%dor2\n", label);
|
||||
|
||||
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tje\t.L%dor3\n", label);
|
||||
|
||||
fprintf(cg_flag, ".L%dor2:\n", label);
|
||||
fprintf(cg_flag, "\tmovl\t$1, %%eax\n");
|
||||
fprintf(cg_flag, "\tjmp\t.L%dor4\n", label);
|
||||
|
||||
fprintf(cg_flag, ".L%dor3:\n", label);
|
||||
fprintf(cg_flag, "\tmovl\t$0, %%eax\n");
|
||||
|
||||
fprintf(cg_flag, ".L%dor4:\n", label);
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
|
||||
fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#or end\n", getAddress(cg)); //stores result
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -359,7 +377,7 @@ int generateAnd(Instruction *inst) {
|
||||
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;
|
||||
@ -368,7 +386,7 @@ int generateAnd(Instruction *inst) {
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
@ -380,18 +398,30 @@ int generateAnd(Instruction *inst) {
|
||||
printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
int label = label_gen();
|
||||
|
||||
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));
|
||||
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start and\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tje\t.L%dor2\n", label);
|
||||
|
||||
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tje\t.L%dor2\n", label);
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t$1, %%eax\n");
|
||||
fprintf(cg_flag, "\tjmp\t.L%dor3\n", label);
|
||||
|
||||
fprintf(cg_flag, ".L%dor2:\n", label);
|
||||
fprintf(cg_flag, "\tmovl\t$0, %%eax\n");
|
||||
|
||||
fprintf(cg_flag, ".L%dor3:\n", label);
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
|
||||
fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#and end\n", getAddress(cg)); //stores result
|
||||
return 0;
|
||||
}
|
||||
int generateNeg(Instruction *inst) {
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
|
||||
if (op1 == NULL) {
|
||||
printdebug("generateNeg failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
@ -399,30 +429,23 @@ int generateNeg(Instruction *inst) {
|
||||
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));
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#negation start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tnegl\t%%eax\n");
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#negation end\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) {
|
||||
|
||||
if (op1 == NULL) {
|
||||
printdebug("generateNot failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
@ -430,22 +453,20 @@ int generateNot(Instruction *inst) {
|
||||
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));
|
||||
fprintf(cg_flag, "\tmovzbl\t%d(%%rbp), %%eax\t#not start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\ttestl\t%%eax, %%eax\n");
|
||||
fprintf(cg_flag, "\tsetne\t%%al\n");
|
||||
fprintf(cg_flag, "\txorl\t$1, %%eax\n");
|
||||
fprintf(cg_flag, "\tmovzbl\t%%al, %%eax\n");
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
|
||||
fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#not end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -453,6 +474,7 @@ int generateAssign(Instruction *inst) {
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
|
||||
if (op1 == NULL) {
|
||||
printdebug("generateAssign failed, NULL operand");
|
||||
return -1;
|
||||
@ -462,23 +484,26 @@ int generateAssign(Instruction *inst) {
|
||||
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));
|
||||
fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\t#constant assign\n", getConst(op1), getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
if (op1CG == NULL) {
|
||||
printf("failed here\n");
|
||||
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));
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#assign start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#assign end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateGoto(Instruction *instruction) {
|
||||
int generateGoto(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -486,17 +511,17 @@ int generateCondGoto(Instruction *instruction) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int generateIfTrue(Instruction *instruction) {
|
||||
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) {
|
||||
int generateIfFalse(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int generateLessThan(Instruction *inst) {
|
||||
/*
|
||||
int generateLessThan(Instruction *inst){
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
@ -504,7 +529,7 @@ int generateLessThan(Instruction *inst) {
|
||||
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;
|
||||
@ -513,7 +538,7 @@ int generateLessThan(Instruction *inst) {
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
@ -526,15 +551,15 @@ int generateLessThan(Instruction *inst) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#less than start\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));
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#less than end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateEqualTo(Instruction *inst) {
|
||||
/*
|
||||
int generateEqualTo(Instruction *inst){
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
@ -542,7 +567,7 @@ int generateEqualTo(Instruction *inst) {
|
||||
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;
|
||||
@ -551,7 +576,7 @@ int generateEqualTo(Instruction *inst) {
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
@ -564,30 +589,30 @@ int generateEqualTo(Instruction *inst) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#equal to start\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));
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
int generateCall(Instruction *instruction) {
|
||||
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) {
|
||||
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) {
|
||||
int generateCopyRight(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateCopyLeft(Instruction *instruction) {
|
||||
int generateCopyLeft(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateAddressOf(Instruction *instruction) {
|
||||
int generateAddressOf(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateParam(Instruction *instruction) {
|
||||
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;
|
||||
}
|
@ -577,7 +577,7 @@ simple_statement:
|
||||
|
||||
|
||||
if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){
|
||||
//EMIT ASSIGN INSTRUCTION HERE
|
||||
emit_assignment($1, tn_or_const(NODE, $3));
|
||||
printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3));
|
||||
} else {
|
||||
throw_error(ERROR_TYPE, "%s != %s", getName(node), getName((TableNode*)$3));
|
||||
|
@ -278,11 +278,11 @@ void emit_conditional_jump(Op condition, int label, ...) {
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void emit_function_start(int name) {
|
||||
void emit_function_start(TNodeOrConst * name) {
|
||||
emit_helper();
|
||||
current->opcode = E_LABEL; // I think this is right TODO: ask
|
||||
current->label = name;
|
||||
// this is probabaly a func decleration
|
||||
current->operand1 = name;
|
||||
// this is probabaly a func declaration
|
||||
}
|
||||
|
||||
void emit_parameter(TNodeOrConst* param) {
|
||||
@ -380,11 +380,9 @@ char * temp_var_gen(){
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
char* label_gen() {
|
||||
char* ret = calloc(9, sizeof(*ret));
|
||||
sprintf(ret, "L_%d", label_count);
|
||||
int label_gen(){
|
||||
label_count++;
|
||||
return ret;
|
||||
return label_count;
|
||||
}
|
||||
|
||||
TableNode* getTN(TNodeOrConst* tnc) {
|
||||
@ -393,7 +391,7 @@ TableNode* getTN(TNodeOrConst* tnc) {
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//we must fix this
|
||||
|
||||
int getConst(TNodeOrConst* tnc) {
|
||||
if (tnc->d == INTEGER) {
|
||||
return tnc->tnc_union->integer;
|
||||
|
@ -100,7 +100,7 @@ void emit_as_file(FILE* out_file, Instruction* i);
|
||||
void emit_label(int label);
|
||||
void emit_jump(int label);
|
||||
void emit_conditional_jump(Op condition, int label, ...);
|
||||
void emit_function_start(int name);
|
||||
void emit_function_start(TNodeOrConst * name);
|
||||
void emit_parameter(TNodeOrConst* param);
|
||||
void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name);
|
||||
void emit_return(TNodeOrConst* value);
|
||||
@ -111,7 +111,7 @@ void emit_deref_left();
|
||||
void emit_field_access(char* result, char* record, char* field);
|
||||
void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index);
|
||||
void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr);
|
||||
char* label_gen();
|
||||
int label_gen();
|
||||
TableNode* getTN(TNodeOrConst* tnc);
|
||||
int getConst(TNodeOrConst* tnc);
|
||||
|
||||
|
Reference in New Issue
Block a user