trying to get annie's to work
This commit is contained in:
@ -10,6 +10,9 @@ char* temp = NULL;
|
||||
int label_count=0;
|
||||
Instruction* begin = NULL;
|
||||
Instruction* current = NULL;
|
||||
int offset = 0;
|
||||
int currentsp = 0;
|
||||
CGNode *cgList = NULL;
|
||||
|
||||
void printdebug_impl(char *file, int line, const char *format, ...) {
|
||||
if (DEBUG) {
|
||||
@ -1574,7 +1577,7 @@ TNodeOrConst * getOperand2(Instruction * i){
|
||||
return i->operand2;
|
||||
}
|
||||
|
||||
TableNode * get_result(Instruction * i){
|
||||
TableNode * getResult(Instruction * i){
|
||||
return i->result;
|
||||
}
|
||||
|
||||
@ -1672,12 +1675,10 @@ char * get_string(TNodeOrConst * tc){
|
||||
case STRING:
|
||||
return tc->tnc_union->string;
|
||||
case INTEGER:
|
||||
return getName(integ);
|
||||
s = calloc(10, sizeof(char));
|
||||
sprintf(s, "%d", tc->tnc_union->integer);
|
||||
return s;
|
||||
case CHARACTER:
|
||||
return getName(chara);
|
||||
s = calloc(2, sizeof(char));
|
||||
sprintf(s, "%c", tc->tnc_union->character);
|
||||
return s;
|
||||
@ -1690,11 +1691,12 @@ char * get_string(TNodeOrConst * tc){
|
||||
}
|
||||
|
||||
void emit_as_file(FILE * out_file, Instruction * i){
|
||||
if(!i){
|
||||
if(i == NULL){
|
||||
return;
|
||||
}
|
||||
switch(i->opcode){
|
||||
case E_LABEL:
|
||||
break;
|
||||
// this is a terrible one to start with
|
||||
// fprintf(out_file, "%04.d: %d ", i->index, i->label);
|
||||
case E_ADD:
|
||||
@ -1752,7 +1754,7 @@ void emit_as_file(FILE * out_file, Instruction * i){
|
||||
case E_ASSIGN:
|
||||
fprintf(out_file, "%4.d: %s = %s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand2));
|
||||
get_string(i->operand1));
|
||||
break;
|
||||
case E_GOTO:
|
||||
// are we ever going to use this?
|
||||
@ -1945,4 +1947,524 @@ char * label_gen(){
|
||||
sprintf(ret, "L_%d", label_count);
|
||||
label_count++;
|
||||
return ret;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------
|
||||
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:
|
||||
;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
/*
|
||||
movl $1, -4(%rbp)
|
||||
add -4(%rbp), $2
|
||||
*/
|
||||
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 *result = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateAdd failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(op1);
|
||||
CGNode *op2CG = findCG(op2);
|
||||
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(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *result = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateSub failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(op1);
|
||||
CGNode *op2CG = findCG(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 *instruction){
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *result = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateMult failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
CGNode *op1CG = findCG(op1);
|
||||
CGNode *op2CG = findCG(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 *instruction) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *result = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateDiv failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(op1);
|
||||
CGNode *op2CG = findCG(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 *instruction) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *result = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateMod failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
CGNode *op1CG = findCG(op1);
|
||||
CGNode *op2CG = findCG(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 *instruction) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *result = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateOr failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(op1);
|
||||
CGNode *op2CG = findCG(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 *instruction) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *result = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(op1);
|
||||
CGNode *op2CG = findCG(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, "\tandl\t%d(\%rbp), %eax\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
int generateNeg(Instruction *instruction) {
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *result = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateNeg failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(op1);
|
||||
CGNode *op2CG = findCG(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 *instruction) {
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *result = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateNot failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(op1);
|
||||
CGNode *op2CG = findCG(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 *instruction) {
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
CGNode *result = findCG(getResult(inst));
|
||||
|
||||
|
||||
if (op1 == NULL) {
|
||||
printdebug("generateAssign failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
//add option for constant assignment (should be easy)
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(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(Instruciton *instruction) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int generateIfTrue(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int generateIfFalse(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int generateLessThan(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateEqualTo(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateCall(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateReturn(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateCopyRight(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateCopyLeft(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateAddressOf(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateParam(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
Reference in New Issue
Block a user