/*----------------------------------------------- | expr_to_ir +---------------------------------------------*/ struct irinfo *expr_to_ir(struct ast *subtree) { struct irinfo *left; struct irinfo *right; /* vars for dealing with loops */ struct flow *tflow; struct ast *cond; struct ast *thendo; struct ast *elsedo; struct ast *forinit; struct ast *forupdate; char elselabel[25]= "else"; char thenlabel[25]= "then"; char endlabel[25]= "end"; char testcondlabel[25]= "test"; struct ast *dstat; struct decostat_list *dlist; int i; int tmpreg; struct irinfo *tcresult= emalloc(sizeof(struct irinfo)); if(subtree == NULL) { printf("received a null subtree...\n"); return NULL; } else { printf("DEBUG: expr_to_ir: ENTERED with NON NULL subtree...\n"); } /* figure out what type of node i'm looking at */ printf("\texpr_to_ir called with expr type: %d\n", subtree->nodetype); switch(subtree->nodetype) { case DECL: break; case DECOSTAT_LIST: printf("found a decostat_list...\n\n\n"); i=0; dlist= (struct decostat_list *)subtree; do { dstat= dlist->decostat; printf("calling expr_to_ir from expr_to_ir\n"); left= expr_to_ir(dstat); printf("dstat_list_element_%d\n", ++i); }while( (dlist= dlist->next) != NULL); tcresult->nodetype= left->nodetype; tcresult->regnum= left->regnum; return tcresult; break; case PARENTHESIZED_EXPR: printf("found parenthsized expr... type of subtree->l: %d\n\n\n", subtree->l->nodetype); left= expr_to_ir(subtree->l); tcresult->nodetype= left->nodetype; tcresult->regnum= left->regnum; printf("DEBUG: PARENTHESIZED_EXPR returning tcresult nodetype %d and regnum %d\n", tcresult->nodetype, tcresult->regnum ); return tcresult; break; case INTEGER_CONSTANT: tcresult->nodetype= RVALUE; tcresult->regnum= ++regnum; irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= LOADCONSTANT; irlist->oprnd1= tcresult->regnum; printf("DEBUG: loading constant: %d\n", (int)(long)((struct constant *)subtree)->value); irlist->oprnd2= (int)(long)((struct constant *)subtree)->value; return tcresult; break; case SIMPLE_DECLARATOR: tcresult->nodetype= LVALUE; tcresult->regnum= ++regnum; printf("DEBUG: dealing with simple declarator, context clue is: %d\n", context_clue); irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; if(context_clue != 0) { irlist->ircode= LOADWORD; printf("DEBUG: since context clue is %d, doing loadword...\n", context_clue); } else { irlist->ircode= LOADADDRESS; printf("DEBUG: since context clue is %d, doing loadaddress...\n", context_clue); } irlist->oprnd1= tcresult->regnum; irlist->symptr= (struct declarator *)subtree; return tcresult; break; case OP_ASSIGNMENT: printf("DEBUG: found an OP_ASSIGNMENT...\n\n\n"); left= expr_to_ir(subtree->l); right= expr_to_ir(subtree->r); if((left->nodetype == LVALUE) && (right->nodetype == RVALUE)) { irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* add node for storewordindirect */ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= STOREWORDINDIRECT; irlist->oprnd1= right->regnum; irlist->oprnd2= left->regnum; } else if((left->nodetype == LVALUE) && (right->nodetype == LVALUE)) { irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* add nodes for load/storewordindirect */ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= LOADWORDINDIRECT; irlist->oprnd1= ++regnum; irlist->oprnd2= right->regnum; irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= STOREWORDINDIRECT; irlist->oprnd1= regnum; irlist->oprnd2= left->regnum; } break; case PLUS_SIGN: context_clue= PLUS_SIGN; printf("DEBUG: found an PLUS_SIGN...\n\n\n"); left= expr_to_ir(subtree->l); right= expr_to_ir(subtree->r); { irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= ADD; irlist->oprnd1= ++regnum; irlist->oprnd2= left->regnum; irlist->oprnd3= right->regnum; tcresult->nodetype= RVALUE; tcresult->regnum= irlist->oprnd1; } context_clue= 0; return tcresult; break; case MINUS_SIGN: context_clue= MINUS_SIGN; printf("DEBUG: found a MINUS_SIGN...\n\n\n"); left= expr_to_ir(subtree->l); right= expr_to_ir(subtree->r); { irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= SUBTRACT; irlist->oprnd1= ++regnum; irlist->oprnd2= left->regnum; irlist->oprnd3= right->regnum; tcresult->nodetype= RVALUE; tcresult->regnum= irlist->oprnd1; } context_clue= 0; return tcresult; break; case OP_REMAINDER: context_clue= OP_REMAINDER; printf("DEBUG: found an OP_REMAINDER...\n\n\n"); left= expr_to_ir(subtree->l); right= expr_to_ir(subtree->r); { irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= REMAINDER; irlist->oprnd1= ++regnum; irlist->oprnd2= left->regnum; irlist->oprnd3= right->regnum; tcresult->nodetype= RVALUE; tcresult->regnum= irlist->oprnd1; } context_clue= 0; return tcresult; break; case POSTINCREMENT_EXPR: context_clue= POSTINCREMENT_EXPR; printf("DEBUG: found a POSTINCREMENT_EXPR...\n\n\n"); printf("\tDEBUG: subtree->l type: %d\n", subtree->l->nodetype); left= expr_to_ir(subtree->l); { irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= ADD1; tmpreg= ++regnum; irlist->oprnd1= tmpreg; irlist->oprnd2= left->regnum; tcresult->nodetype= RVALUE; tcresult->regnum= irlist->oprnd1; context_clue= 0; /* store result */ left= expr_to_ir(subtree->l); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= STOREWORDINDIRECT; irlist->oprnd1= tmpreg; irlist->oprnd2= left->regnum; } return tcresult; break; case POSTDECREMENT_EXPR: context_clue= POSTDECREMENT_EXPR; printf("DEBUG: found a POSTDECREMENT_EXPR...\n\n\n"); printf("\tDEBUG: subtree->l type: %d\n", subtree->l->nodetype); left= expr_to_ir(subtree->l); { irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= SUB1; tmpreg= ++regnum; irlist->oprnd1= tmpreg; irlist->oprnd2= left->regnum; tcresult->nodetype= RVALUE; tcresult->regnum= irlist->oprnd1; context_clue= 0; /* store result */ left= expr_to_ir(subtree->l); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= STOREWORDINDIRECT; irlist->oprnd1= tmpreg; irlist->oprnd2= left->regnum; } return tcresult; break; case IF_STATEMENT: irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* retrieve if statement components +-----------------------------------*/ tflow= (struct flow *)subtree; cond= tflow->cond; thendo= tflow->thendo; /* print C code to IR file. +---------------------------*/ printf("DEBUG: cond type: %d\n", cond->nodetype); printf("DEBUG: thendo type: %d\n", thendo->nodetype); clearstr(tmpstr); sprintf(tmpstr,"#"); indent(tmpstr); sprintf(&tmpstr[strlen(tmpstr)], "if("); print_expr(cond->l,tmpstr); sprintf(&tmpstr[strlen(tmpstr)], ")\n"); fprintf(irout,tmpstr); clearstr(tmpstr); /* Generate necessary labels +----------------------------*/ sprintf(&elselabel[strlen(elselabel)], "%d", ++labelnum); sprintf(&endlabel[strlen(endlabel)], "%d", ++labelnum); printf("\t\tDEBUG: type of condition: %d\n", cond->l->nodetype); printf("\t\tDEBUG: type of thendo: %d\n", thendo->nodetype); /* create node for conditional statement +-----------------------------------------*/ expr_to_ir(cond->l); sprintf(&thenlabel[strlen(thenlabel)], "%d", labelnum); /* create node for empty else block +-----------------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, elselabel); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= JUMP; strcpy(irlist->label, endlabel); /* create nodes for then block */ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, thenlabel); expr_to_ir(thendo); /* create node for end block +-----------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, endlabel); break; case IF_ELSE_STATEMENT: irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* retrieve if statement components +-----------------------------------*/ tflow= (struct flow *)subtree; cond= tflow->cond; thendo= tflow->thendo; elsedo= tflow->elsedo; /* Generate necessary labels +----------------------------*/ sprintf(&elselabel[strlen(elselabel)], "%d", ++labelnum); sprintf(&endlabel[strlen(endlabel)], "%d", ++labelnum); printf("\t\tDEBUG: type of condition: %d\n", cond->l->nodetype); printf("\t\tDEBUG: type of thendo: %d\n", thendo->nodetype); /* create node for conditional statement +-----------------------------------------*/ expr_to_ir(cond->l); sprintf(&thenlabel[strlen(thenlabel)], "%d", labelnum); /* create nodes for else block +------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, elselabel); expr_to_ir(elsedo); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= JUMP; strcpy(irlist->label, endlabel); /* create nodes for then block */ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, thenlabel); expr_to_ir(thendo); /* create node for end block +-----------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, endlabel); break; case FOR_STATEMENT: irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* retrieve for statement components +-----------------------------------*/ tflow = (struct flow *)subtree; forinit = tflow->forinit; cond = tflow->cond; forupdate = tflow->forupdate; thendo = tflow->thendo; /* Generate necessary labels +----------------------------*/ sprintf(elselabel, "forelse%d", ++labelnum); sprintf(&thenlabel[strlen(thenlabel)], "%d", ++labelnum); sprintf(&endlabel[strlen(endlabel)], "%d", ++labelnum); sprintf(&testcondlabel[strlen(testcondlabel)], "%d", ++labelnum); /* printf("\t\tDEBUG: type of forinit: %d\n", forinit->l->nodetype); printf("\t\tDEBUG: type of condition: %d\n", cond->l->nodetype); printf("\t\tDEBUG: type of thendo: %d\n", thendo->nodetype); printf("\t\tDEBUG: type of forupdate: %d\n", forupdate->l->nodetype); */ /* create nodes for init statement +-----------------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= COMMENT; strncpy(irlist->label, "For Loop Initialization",49); if(forinit != NULL) { expr_to_ir(forinit->l); } /* create nodes for conditional statement +-----------------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= COMMENT; strncpy(irlist->label, "For Loop Test Condition",49); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, testcondlabel); forjump= atoi(&thenlabel[strlen(thenlabel)-1]); if(cond != NULL) { expr_to_ir(cond->l); } forjump= 0; /* create node for empty else block +-----------------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, elselabel); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= JUMP; strcpy(irlist->label, endlabel); /* create nodes for then block +--------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, thenlabel); if(thendo != NULL) { expr_to_ir(thendo); } /* create nodes for for loop update +-----------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= COMMENT; strncpy(irlist->label, "For Loop Update Statement",49); if(forupdate != NULL) { expr_to_ir(forupdate->l); } /* jump back to test condition +-------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= JUMP; strcpy(irlist->label, testcondlabel); /* create node for end block +-----------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, endlabel); break; case WHILE_STATEMENT: irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* retrieve for statement components +-----------------------------------*/ tflow = (struct flow *)subtree; cond = tflow->cond; thendo = tflow->thendo; /* Generate necessary labels +----------------------------*/ sprintf(elselabel, "whileelse%d", ++labelnum); sprintf(&thenlabel[strlen(thenlabel)], "%d", ++labelnum); sprintf(&endlabel[strlen(endlabel)], "%d", ++labelnum); sprintf(&testcondlabel[strlen(testcondlabel)], "%d", ++labelnum); /* create nodes for conditional statement +-----------------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= COMMENT; strncpy(irlist->label, "WHILE Loop Test Condition",49); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, testcondlabel); forjump= atoi(&thenlabel[strlen(thenlabel)-1]); if(cond != NULL) { expr_to_ir(cond->l); } forjump= 0; /* create node for empty else block +-----------------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, elselabel); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= JUMP; strcpy(irlist->label, endlabel); /* create nodes for then block +--------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, thenlabel); if(thendo != NULL) { expr_to_ir(thendo); } /* jump back to test condition +-------------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= JUMP; strcpy(irlist->label, testcondlabel); /* create node for end block +-----------------------------*/ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= MIPSLABEL; strcpy(irlist->label, endlabel); break; case RW_BREAK: printf("DEBUG: found a RW_BREAK...\n\n\n"); ; char tlabel[50]; { irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } while( (strstr(irlist->label,"forelse")) == NULL && (irlist != NULL)) { irlist=irlist->prev; printf("rewinding from irnode %d\n", irlist->sid); } if(irlist != NULL) { strcpy(tlabel,irlist->label); printf("tlabel set to: %s\n", tlabel); } irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= JUMP; strcpy(irlist->label,tlabel); } break; case OP_EQUALITY: printf("DEBUG: found a OP_EQUALITY...\n\n\n"); context_clue= OP_EQUALITY; irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } left = expr_to_ir(subtree->l); right = expr_to_ir(subtree->r); printf("DEBUG: expr_to_ir(): left regnum: %d\n", left->regnum); printf("DEBUG: expr_to_ir(): right regnum: %d\n", right->regnum); char eqthenlabel[25]= "then"; sprintf(&eqthenlabel[strlen(eqthenlabel)], "%d", ++labelnum); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= BRANCH_EQ; irlist->oprnd1= left->regnum; irlist->oprnd2= right->regnum; strcpy(irlist->label, eqthenlabel); context_clue= 0; tcresult->nodetype= RVALUE; tcresult->regnum= irlist->oprnd1; return tcresult; break; case GREATER_THAN_SYMBOL: context_clue= CONDITIONAL_STATEMENT; irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } printf("DEBUG: expr_to_ir(): received a greater than symbol....\n"); left = expr_to_ir(subtree->l); right = expr_to_ir(subtree->r); char gtthenlabel[25]= "then"; sprintf(>thenlabel[strlen(gtthenlabel)], "%d", (forjump > 0)? forjump : ++labelnum); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= BRANCH_GT; irlist->oprnd1= left->regnum; irlist->oprnd2= right->regnum; strcpy(irlist->label, gtthenlabel); context_clue= 0; break; case OP_RELATIONAL_GTE: context_clue= CONDITIONAL_STATEMENT; irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } printf("DEBUG: expr_to_ir(): received a greater than symbol....\n"); left = expr_to_ir(subtree->l); right = expr_to_ir(subtree->r); char gtethenlabel[25]= "then"; sprintf(>ethenlabel[strlen(gtethenlabel)], "%d", (forjump > 0)? forjump : ++labelnum); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= BRANCH_GTE; irlist->oprnd1= left->regnum; irlist->oprnd2= right->regnum; strcpy(irlist->label, gtethenlabel); context_clue= 0; break; case OP_RELATIONAL_LT: context_clue= OP_RELATIONAL_LT; irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } printf("DEBUG: expr_to_ir(): received a greater than symbol....\n"); left = expr_to_ir(subtree->l); right = expr_to_ir(subtree->r); char ltthenlabel[25]= "then"; sprintf(<thenlabel[strlen(ltthenlabel)], "%d", (forjump > 0)? forjump : ++labelnum); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= BRANCH_LT; irlist->oprnd1= left->regnum; irlist->oprnd2= right->regnum; strcpy(irlist->label, ltthenlabel); context_clue= 0; break; case OP_RELATIONAL_LTE: context_clue= OP_RELATIONAL_LTE; irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } printf("DEBUG: expr_to_ir(): received a greater than symbol....\n"); left = expr_to_ir(subtree->l); right = expr_to_ir(subtree->r); char ltethenlabel[25]= "then"; sprintf(<ethenlabel[strlen(ltethenlabel)], "%d", (forjump > 0)? forjump : ++labelnum); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= BRANCH_LTE; irlist->oprnd1= left->regnum; irlist->oprnd2= right->regnum; strcpy(irlist->label, ltethenlabel); context_clue= 0; break; case COMPOUND_STATEMENT: printf("DEBUG: expr_to_ir() called with compound statement ...\n"); printf("\tDEBUG: subtree type: %d\n", subtree->nodetype); compound_to_ir(subtree); break; case FUNCTION_CALL: ; char funcname[40]; struct declarator *d= (struct declarator *)subtree->l; struct parameter_list *plist; plist=d->plist; if(d->nodetype == SIMPLE_DECLARATOR) { strcpy(funcname,d->id); } else { strcpy(funcname,d->adeclarator->id); } printf("DEBUG: expr_to_ir FUNCTION CALL: %s\n", funcname); /* If this is a built-in function... +-----------------------------------------*/ if( (!strcmp(funcname,"printint")) || (!strcmp(funcname,"printstring")) || (!strcmp(funcname,"readint")) ) { /* printint function... +-------------------------*/ if(! strcmp(funcname,"printint")) { printf("printint invoked...\n"); irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* add nodes for printint */ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= PRINTINT; irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= LOADWORD; irlist->oprnd1= SYSCALL_ARG_REG; irlist->symptr= (struct declarator *)subtree->r->l; irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= SYSCALL; } /* printstring function... +--------------------------*/ if(! strcmp(funcname,"printstring")) { /* Retrieve parameter +----------------------*/ struct constant *k= (struct constant *)subtree->r->l; char *param= k->value; printf("param: %s (%ld)\n", param, param); irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* add nodes for printstring */ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= PRINTSTRING; irlist->oprnd1= ++regnum; irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= CREATE_STRINGVAR; irlist->symptr= (struct declarator *)param; sprintf(irlist->label,"stringvar%d", ++stringvarnum); irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= SYSCALL; } /* readint function... +--------------------------*/ if(! strcmp(funcname,"readint")) { irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* add nodes for readint */ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= READINT; irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= SYSCALL; /* add nodes for result storage */ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= LOADADDRESS; irlist->oprnd1= ++regnum; irlist->symptr= (struct declarator *)subtree->r->l; irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= STOREWORDINDIRECT; irlist->oprnd1= SYSCALL_REG; irlist->oprnd2= regnum; irlist->symptr= (struct declarator *)subtree->r->l; } } /* If it's not a builtin function +---------------------------------*/ else { printf("function '%s' has been called...\n",funcname); irlist= irlist_front; while(irlist->next != NULL) { irlist= irlist->next; } /* add nodes for printint */ irlist->next= emalloc(sizeof(struct irnode)); irlist->next->prev= irlist; irlist= irlist->next; irlist->sid= ++irnodenum; irlist->ircode= FUNCTIONCALL; strcpy(irlist->label,"_VAR_"); strcat(irlist->label,funcname); irlist->symptr= d; } break; default: printf("DEBUG: expr_to_ir: NOT SURE WHAT TO DO WITH TYPE: %d\n", subtree->nodetype); break; } return tcresult; }
Instruction *expr_to_ir(Env *env, ExpNode *expr, char **result_sym) { if (!expr) return NULL; //printf("NODE TYPE : %d\n", expr->node_type); switch (expr->node_type) { case CONSTANT_EXPNODE: { // leaf //printf("CONST EXPR!\n"); Instruction *inst; if (expr->return_type == TYPE_INT) inst = load_int_instruction_new(expr->int_val); else inst = load_float_instruction_new(expr->float_val); char **ret_sym = &((LoadIntInstruction *) inst->value)->return_symbol; *ret_sym = next_tmp_symbol(env); if (result_sym) *result_sym = *ret_sym; //printf("Printing const expnode\n"); //print_ir_list(inst); return inst; break; } case BOOLEAN_EXPNODE: { //printf("Entering boolean expnode\n"); // truth_val = 0 // evaluate shit, jump to true if true // goto end // true: // truth_val = 1 // end: char *truth_var = next_tmp_symbol(env); Instruction *init = load_int_instruction_new(0); ((LoadIntInstruction *) init->value)->return_symbol = truth_var; Instruction *true_label = label_instruction_new(next_tmp_symbol(env)); Instruction *end_label = label_instruction_new(next_tmp_symbol(env)); char *lhs_sym, *rhs_sym; Instruction *lhs = expr_to_ir(env, expr->lhs, &lhs_sym); Instruction *rhs = NULL; if (expr->rhs) rhs = expr_to_ir(env, expr->rhs, &rhs_sym); Instruction *evaluate; //printf("Before evaluate\n"); if (!strcmp(expr->op, "||")) { // do first // if first, jump to true // do second // if second, jump to true Instruction *jump1 = cond_jump_instruction_new(lhs_sym, true_label); Instruction *jump2 = cond_jump_instruction_new(rhs_sym, true_label); evaluate = concat_inst(4, lhs, jump1, rhs, jump2); } else if (!strcmp(expr->op, "&&")) { // do first // if first, jump to maybe // goto end // maybe: // do second // if second, jump to true // (goto end) Instruction *maybe_label = label_instruction_new(next_tmp_symbol(env)); Instruction *jump_to_maybe = cond_jump_instruction_new(lhs_sym, maybe_label); Instruction *jump_to_end = uncond_jump_instruction_new(end_label); Instruction *jump_to_true = cond_jump_instruction_new(rhs_sym, true_label); evaluate = concat_inst(6, lhs, jump_to_maybe, jump_to_end, maybe_label, rhs, jump_to_true); } else { //printf("NEGATION\n"); // (boolean negation) // do first // if first, jump to end // jump to true Instruction *jump_to_end = cond_jump_instruction_new(lhs_sym, end_label); Instruction *jump_to_true = uncond_jump_instruction_new(true_label); //printf("CONCAT %p %p %p\n", lhs, jump_to_end, jump_to_true); evaluate = concat_inst(3, lhs, jump_to_end, jump_to_true); } //printf("After evaluate\n"); Instruction *goto_end = uncond_jump_instruction_new(end_label); char *load_one_var = next_tmp_symbol(env); Instruction *load_one = load_int_instruction_new(1); ((LoadIntInstruction *) load_one->value)->return_symbol = load_one_var; Instruction *set_true = copy_instruction_new(truth_var, load_one_var, NULL); if (result_sym) *result_sym = truth_var; // init // evaluate // goto end // true: // set_to_1 // end: //printf("Entering boolean expnode\n"); return concat_inst( 7, init, evaluate, goto_end, true_label, load_one, set_true, end_label ); break; } case COMP_EXPNODE: { // return value should be 0 or 1 //printf("Entering comp expnode\n"); //assert(0); char *truth_var = next_tmp_symbol(env); Instruction *init = load_int_instruction_new(0); ((LoadIntInstruction *) init->value)->return_symbol = truth_var; Instruction *true_label = label_instruction_new(next_tmp_symbol(env)); Instruction *end_label = label_instruction_new(next_tmp_symbol(env)); char *return_symbol = next_tmp_symbol(env); if (result_sym) *result_sym = return_symbol; char *lhs_sym, *rhs_sym; Instruction *lhs = expr_to_ir(env, expr->lhs, &lhs_sym); Instruction *rhs = expr_to_ir(env, expr->rhs, &rhs_sym); Instruction *jump_to_end = uncond_jump_instruction_new(end_label); Instruction *jump_to_true = cond_comp_jump_instruction_new( expr->op, lhs_sym, rhs_sym, true_label); char *load_one_var = next_tmp_symbol(env); Instruction *load_one = load_int_instruction_new(1); ((LoadIntInstruction *) load_one->value)->return_symbol = load_one_var; Instruction *set_true = copy_instruction_new(truth_var, load_one_var, NULL); if (result_sym) *result_sym = truth_var; //printf("Exiting comp expnode\n"); return concat_inst(9, lhs, rhs, init, jump_to_true, jump_to_end, true_label, load_one, set_true, end_label); break; } case ARITHMETIC_EXPNODE: { //printf("Entering math expnode\n"); char *lhs_sym, *rhs_sym; rhs_sym = NULL; Instruction *lhs = expr_to_ir(env, expr->lhs, &lhs_sym); Instruction *rhs = NULL; if (expr->rhs) rhs = expr_to_ir(env, expr->rhs, &rhs_sym); char *return_sym = next_tmp_symbol(env); Instruction *inst_cont = arithmetic_instruction_new(expr->op, lhs_sym, rhs_sym, return_sym); if (result_sym) *result_sym = return_sym; // prepend lhs and rhs and inst_cont //printf("%p %p %p\n", lhs, rhs, inst_cont); Instruction *result = concat_inst(3, lhs, rhs, inst_cont); //print_ir_list(result); //printf("Exiting math expnode\n"); return result; break; } case INVOCATION_EXPNODE: { Array *sym_list = array_new(0, sizeof(char **)); Instruction *param_eval = NULL; int i; //printf("count: %d\n", expr->expns->length); for (i = 0; i < expr->expns->length; i++) { char *sym_name; ExpNode *exp = *((ExpNode **) array_get(expr->expns, i)); param_eval = concat_inst(2, param_eval, expr_to_ir(env, exp, &sym_name)); //printf("INVOC: %s\n", sym_name); array_append(sym_list, &sym_name); } char *return_symbol = NULL; if (result_sym) { return_symbol = next_tmp_symbol(env); *result_sym = return_symbol; } Instruction *invocation = invocation_instruction_new(return_symbol, expr->op, sym_list); return concat_inst(2, param_eval, invocation); break; } case ID_EXPNODE: // leaf //printf("ID_EXPNODE: %s\n", expr->op); if (expr->index == NULL) { if (result_sym) *result_sym = expr->op; } else { char *return_symbol = next_tmp_symbol(env); if (result_sym) *result_sym = return_symbol; char *index_sym = NULL; Instruction *index_code = expr_to_ir(env, expr->index, &index_sym); return concat_inst(2, index_code, array_element_instruction_new(expr->op, index_sym, return_symbol) ); } return NULL; break; case ASSIGNMENT_EXPNODE: { //printf("Entering assignment expnode\n"); char *lhs_sym, *rhs_sym, *index_sym; lhs_sym = rhs_sym = index_sym = NULL; assert(expr->lhs->node_type == ID_EXPNODE); Instruction *index_inst = NULL; if (expr->lhs->index != NULL) index_inst = expr_to_ir(env, expr->lhs->index, &index_sym); lhs_sym = expr->lhs->op; Instruction *rhs = expr_to_ir(env, expr->rhs, &rhs_sym); //printf("LHS: %p, RHS: %p\n", lhs_sym, rhs_sym); Instruction *cpy_inst = copy_instruction_new(lhs_sym, rhs_sym, index_sym); Instruction *result = concat_inst(3, index_inst, rhs, cpy_inst); return result; break; } default: break; } return NULL; }
/*----------------------------------------------- | compound_to_ir +---------------------------------------------*/ void compound_to_ir(struct ast *cstmt) { char genstr[TMPSTRSZ]; struct ast *decostat; struct decostat_list *dlist= (struct decostat_list *) cstmt->l; struct flow *tflow; struct ast *cond; struct ast *thendo; printf("DEBUG: compound_to_ir called with nodetype: %d\n", cstmt->nodetype); sprintf(&genstr[strlen(genstr)],"#"); indent(genstr); sprintf(&genstr[strlen(genstr)],"{\n"); fprintf(irout,"%s",genstr); clearstr(genstr); ++indent_count; do { decostat= dlist->decostat; /* Generate IR node +--------------------*/ regnum=0; /* reset register count to 0 */ printf("c2ir calling e2ir...\n"); expr_to_ir(decostat); /* write C statement to file +----------------------------*/ clearstr(genstr); sprintf(genstr,"#"); indent(genstr); if(decostat->nodetype == COMPOUND_STATEMENT) { clearstr(genstr); compound_to_ir(decostat); } else { print_expr(dlist->decostat,genstr); } /* no semicolons after compound statements */ if( (dlist->decostat->nodetype == COMPOUND_STATEMENT) || ( (dlist->decostat->nodetype == LABELED_STATEMENT) && (dlist->decostat->r->nodetype == COMPOUND_STATEMENT) ) ) { fprintf(irout,"\n\n"); } else { fprintf(irout,"%s;\n",genstr); clearstr(genstr); } fprintf(irout,"%s",genstr); clearstr(genstr); /* write IR nodes to file +----------------------------*/ statement_end_sid= irnodenum; print_irnode_sids(statement_begin_sid,statement_end_sid); statement_begin_sid= ++statement_end_sid; fprintf(irout,"\n\n\n"); } while( (dlist= dlist->next) != NULL); --indent_count; sprintf(&genstr[strlen(genstr)],"#"); indent(genstr); sprintf(&genstr[strlen(genstr)],"}\n\n\n"); fprintf(irout,"%s",genstr); clearstr(genstr); }