void genwhile(SNODE *stmt) /* * generate code to evaluate a while statement. */ { int lab1, lab2, lab3; initstack(); /* initialize temp registers */ lab1 = contlab; /* save old continue label */ contlab = nextlabel++; /* new continue label */ if( stmt->s1 != 0 ) /* has block */ { lab2 = breaklab; /* save old break label */ breaklab = nextlabel++; gen_code(op_jmp,0,make_label(contlab),0); lab3 = nextlabel++; gen_label(lab3); genstmt(stmt->s1); gen_label(contlab); if (stmt->lst) gen_line(stmt->lst); initstack(); truejp(stmt->exp,lab3); gen_label(breaklab); breaklab = lab2; /* restore old break label */ } else /* no loop code */ { if (stmt->lst) gen_line(stmt->lst); gen_label(contlab); initstack(); truejp(stmt->exp,contlab); } contlab = lab1; /* restore old continue label */ }
static void bhv_setTag(struct Behavior *bhv) { if (bhv->Object.Any._id) { // generics case struct Generic *gen = CAST(struct Generic*, bhv); if (bhv->id) cos_abort("generic '%s' at (%s,%d) has already an id", gen_name(gen), gen_file(gen), gen_line(gen)); if ( (bhv->Object.Any._id & COS_ID_TAGMSK) ) cos_abort("generic '%s' at (%s,%d) has invalid initialization", gen_name(gen), gen_file(gen), gen_line(gen)); bhv->id = bhv->Object.Any._id | bhv_tag(); bhv->Object.Any._id = 0; } else { // classes case
int shift_int_star(t_terrain *terr, t_board *board, int r, int size) { if (r + size + 1 < board->height) { board->map[r + size + 1] = board->map[r]; return (gen_line(terr, board->map[r + size + 1], r + size + 1 , board->width - 1)); } return (0); }
void gen_for(SNODE *stmt) /* * generate code to evaluate a for loop */ { int old_break, old_cont, exit_label, loop_label, start_label; int areg, sreg; old_break = breaklab; old_cont = contlab; loop_label = nextlabel++; contlab = nextlabel++; start_label = nextlabel++; exit_label = nextlabel++; InitRegs(); if (stmt->label != 0) { gen_void_external(stmt->label); } gen_codes(op_jmp, 0, make_label(start_label), 0); gen_label(loop_label); if (stmt->s1 != 0) { breaklab = exit_label; genstmt(stmt->s1); } if (stmt->lst) gen_line(stmt->lst); gen_label(contlab); InitRegs(); if (stmt->s2 != 0) { gen_void_external(stmt->s2); } gen_label(start_label); InitRegs(); ChooseRegs(&areg, &sreg); if (stmt->exp != 0) truejp(stmt->exp, areg, sreg, loop_label); else gen_codes(op_jmp, 0, make_label(loop_label), 0); gen_label(exit_label); breaklab = old_break; contlab = old_cont; }
void genfunc(SNODE *stmt) /* * generate a function body. */ { retlab = contlab = breaklab = -1; funcfloat = 0; init_muldivval(); stackdepth = 0; if (stmt->stype == st_line) { gen_line(stmt); stmt = stmt->next; } gen_codelab(currentfunc); /* name of function */ opt1(stmt); /* push args & also subtracts SP */ #ifdef CPLUSPLUS if (prm_cplusplus) scppinit(); #endif genstmt(stmt); genreturn(0,1); }
void gen_for(SNODE *stmt) /* * generate code to evaluate a for loop */ { int old_break, old_cont, exit_label, loop_label; old_break = breaklab; old_cont = contlab; loop_label = nextlabel++; exit_label = nextlabel++; contlab = nextlabel++; initstack(); if( stmt->label != 0 ) gen_expr(stmt->label,F_ALL | F_NOVALUE ,natural_size(stmt->label)); gen_code(op_jmp,0,make_label(contlab),0); gen_label(loop_label); if( stmt->s1 != 0 ) { breaklab = exit_label; genstmt(stmt->s1); } initstack(); if( stmt->s2 != 0 ) gen_expr(stmt->s2,F_ALL | F_NOVALUE,natural_size(stmt->s2)); gen_label(contlab); if (stmt->lst) gen_line(stmt->lst); initstack(); if( stmt->exp != 0 ) truejp(stmt->exp,loop_label); else gen_code(op_jmp,0,make_label(loop_label),0); gen_label(exit_label); breaklab = old_break; contlab = old_cont; }
void genfunc(SYMBOL *funcsp) /* * generate a function body and dump the icode */ { IMODE *allocaAP = NULL; SYMBOL *oldCurrentFunc; EXPRESSION *funcexp = varNode(en_global, funcsp); if (total_errors) return; // //printf("%s\n", funcsp->name); contlab = breaklab = - 1; structret_imode = 0 ; tempCount = 0; blockCount = 0; blockMax = 0; exitBlock = 0; oldCurrentFunc = theCurrentFunc; theCurrentFunc = funcsp; iexpr_func_init(); /* firstlabel = nextLabel;*/ cseg(); gen_line(funcsp->linedata); gen_func(funcexp, 1); /* in C99 inlines can clash if declared 'extern' in multiple modules */ /* in C++ we introduce virtual functions that get coalesced at link time */ if (cparams.prm_cplusplus && funcsp->linkage == lk_inline) gen_virtual(funcsp, FALSE); else { if (funcsp->storage_class == sc_global) globaldef(funcsp); else localdef(funcsp); gen_strlab(funcsp); /* name of function */ } addblock( - 1); if (funcsp->linkage == lk_interrupt || funcsp->linkage == lk_fault) { gen_icode(i_pushcontext, 0,0,0); /* if (funcsp->loadds) */ /* gen_icode(i_loadcontext, 0,0,0); */ } gen_icode(i_prologue,0,0,0); gen_label(startlab); /* if (funcsp->loadds && funcsp->farproc) */ /* gen_icode(i_loadcontext, 0,0,0); */ AllocateLocalContext(NULL, funcsp); if (funcsp->allocaUsed) { EXPRESSION *allocaExp = varNode(en_auto, anonymousVar(sc_auto, &stdpointer)); allocaAP = gen_expr(funcsp, allocaExp, 0, ISZ_ADDR); gen_icode(i_savestack, 0, allocaAP, 0); } /* Generate the icode */ /* LCSE is done while code is generated */ genstmt(funcsp->inlineFunc.stmt->lower, funcsp); if (funcsp->inlineFunc.stmt->blockTail) { gen_icode(i_functailstart, 0, 0, 0); genstmt(funcsp->inlineFunc.stmt->blockTail, funcsp); gen_icode(i_functailend, 0, 0, 0); } genreturn(0, funcsp, 1, 0, allocaAP); gen_func(funcexp, 0); tFree(); InsertParameterThunks(funcsp, blockArray[1]); optimize(funcsp); FreeLocalContext(NULL, funcsp); AllocateStackSpace(funcsp); FillInPrologue(intermed_head, funcsp); /* Code gen from icode */ rewrite_icode(); /* Translate to machine code & dump */ if (chosenAssembler->gen->post_function_gen) chosenAssembler->gen->post_function_gen(funcsp, intermed_head); if (cparams.prm_cplusplus && funcsp->linkage == lk_inline) gen_endvirtual(funcsp); intermed_head = NULL; dag_rundown(); oFree(); theCurrentFunc = oldCurrentFunc; if (blockCount > maxBlocks) maxBlocks = blockCount; if (tempCount > maxTemps) maxTemps = tempCount; }
void genstmt(STATEMENT *stmt, SYMBOL *funcsp) /* * genstmt will generate a statement and follow the next pointer * until the block is generated. */ { while (stmt != 0) { switch (stmt->type) { case st_varstart: gen_varstart(stmt->select); break; case st_dbgblock: gen_dbgblock(stmt->label); break; case st_tryblock: /* gen_tryblock(stmt->label); */ break; case st_block: genstmt(stmt->lower, funcsp); genstmt(stmt->blockTail, funcsp); break; case st_label: gen_label((int)stmt->label); break; case st_goto: gen_igoto(i_goto, (int)stmt->label); break; case st_asmgoto: gen_igoto(i_asmgoto, (int)stmt->label); break; case st_asmcond: gen_igoto(i_asmcond, (int)stmt->label); break; case st_throw: /* gen_throw((TYPE *)stmt->lst, stmt->select);*/ break; /* case st_functailexpr: gen_icode(i_functailstart, 0, 0, 0); gen_expr(funcsp, stmt->select, F_NOVALUE, natural_size(stmt->select)); * gen_icode(i_functailend, 0, 0, 0); break; */ case st_expr: case st_declare: gen_expr(funcsp, stmt->select, F_NOVALUE, natural_size(stmt->select)); break; case st_return: genreturn(stmt, funcsp, 0, 0, NULL); break; case st_line: gen_line(stmt->lineData); break; case st_select: genselect(stmt, funcsp, TRUE); break; case st_notselect: genselect(stmt, funcsp, FALSE); break; case st_switch: genxswitch(stmt, funcsp); break; case st__genword: gen_genword(stmt, funcsp); break; case st_passthrough: gen_asm(stmt); break; case st_datapassthrough: gen_asmdata(stmt); break; default: diag("unknown statement."); break; } stmt = stmt->next; } }
void genstmt(SNODE *stmt) /* * genstmt will generate a statement and follow the next pointer * until the block is generated. */ { while( stmt != 0 ) { switch( stmt->stype ) { case st_block: genstmt(stmt->exp); break; case st_label: gen_label((int)stmt->label); break; case st_goto: gen_code(op_jmp,0,make_label((int)stmt->label),0); break; case st_expr: initstack(); gen_expr(stmt->exp,F_ALL | F_NOVALUE, natural_size(stmt->exp)); break; case st_return: genreturn(stmt,0); break; case st_if: genif(stmt); break; case st_while: genwhile(stmt); break; case st_do: gendo(stmt); break; case st_for: gen_for(stmt); break; case st_continue: gen_code(op_jmp,0,make_label(contlab),0); break; case st_break: gen_code(op_jmp,0,make_label(breaklab),0); break; case st_switch: genxswitch(stmt); break; case st_line: gen_line(stmt); break; case st_asm: if (stmt->exp) add_peep(stmt->exp); break; case st__genword: gen_code(op_genword,0,make_immed((int)stmt->exp),0); break; default: diag("unknown statement."); break; } stmt = stmt->next; } }
IMODE *genstmt(STATEMENT *stmt, SYMBOL *funcsp) /* * genstmt will generate a statement and follow the next pointer * until the block is generated. */ { IMODE *rv = NULL; while (stmt != 0) { STATEMENT *last = stmt; switch (stmt->type) { case st_varstart: gen_varstart(stmt->select); break; case st_dbgblock: gen_dbgblock(stmt->label); break; break; case st_block: rv = genstmt(stmt->lower, funcsp); genstmt(stmt->blockTail, funcsp); break; case st_label: gen_label((int)stmt->label); break; case st_goto: gen_igoto(i_goto, (int)stmt->label); break; case st_asmgoto: gen_igoto(i_asmgoto, (int)stmt->label); break; case st_asmcond: gen_igoto(i_asmcond, (int)stmt->label); break; case st_try: gen_try(funcsp, stmt, stmt->label, stmt->endlabel, stmt->breaklabel, stmt->lower); break; case st_catch: { STATEMENT *last; while (stmt && stmt->type == st_catch) { gen_catch(funcsp, stmt, stmt->altlabel, stmt->breaklabel, stmt->lower); last = stmt; stmt = stmt->next; } stmt = last; gen_label(stmt->breaklabel); } break; case st_expr: case st_declare: if (stmt->select) rv = gen_expr(funcsp, stmt->select, F_NOVALUE, natural_size(stmt->select)); break; case st_return: genreturn(stmt, funcsp, 0, 0, NULL); break; case st_line: gen_line(stmt->lineData); break; case st_select: genselect(stmt, funcsp, TRUE); break; case st_notselect: genselect(stmt, funcsp, FALSE); break; case st_switch: genxswitch(stmt, funcsp); break; case st__genword: gen_genword(stmt, funcsp); break; case st_passthrough: gen_asm(stmt); break; case st_datapassthrough: gen_asmdata(stmt); break; default: diag("unknown statement."); break; } if (last->type != st_return && last->destexp) { gen_expr(funcsp, last->destexp, F_NOVALUE, ISZ_ADDR); } stmt = stmt->next; } return rv; }