SYMBOL *gen_mp_virtual_thunk(SYMBOL *vsp) { QUAD *oi = intermed_head, *ot = intermed_tail; LIST *v = mpthunklist; SYMBOL *sp; IMODE *ap1, *ap2; char buf[256]; while (v) { sp = (SYMBOL*)v->data; if (sp->value.i == vsp->value.classdata.vtabindex) if (isstructured(vsp->tp->btp) == isstructured(sp->tp->btp)) return sp; v = v->link; } intermed_head = intermed_tail = NULL; blockMax = 0; blockCount = tempCount = 0; exitBlock = 0; IncGlobalFlag(); sp = Alloc(sizeof(SYMBOL)); sp->storage_class = sc_static; sp->tp = vsp->tp; sp->value.i = vsp->value.classdata.vtabindex; //sprintf(buf, "@$mpt$%d$%d", sp->value.i, isstructured(sp->tp->btp)); sp->name = sp->decoratedName = litlate(buf); sp->errname = sp->decoratedName; sp->staticlabel = FALSE; sp->gennedvirtfunc = TRUE; v = (LIST *)Alloc(sizeof(LIST)); v->data = sp; v->link = mpthunklist; mpthunklist = v; DecGlobalFlag(); gen_virtual(sp, FALSE); addblock(i_goto); gen_icode(i_substack, NULL, ap2 = tempreg(ISZ_ADDR, 0), NULL); gen_icode(i_add, ap2, ap2 , make_immed(ISZ_NONE, isstructured(sp->tp->btp) ? ISZ_ADDR * 2 : ISZ_ADDR)); ap1 = indnode(ap2, ISZ_ADDR); gen_icode(i_assn, ap2 = tempreg(ISZ_ADDR, 0), ap1, 0); if (sp->value.classdata.baseofs) gen_icode(i_add, ap2, ap2, make_immed(ISZ_NONE, sp->value.classdata.baseofs)); ap1 = indnode(ap2, ISZ_ADDR); gen_icode(i_assn, ap2 = tempreg(ISZ_ADDR, 0), ap1, 0); gen_icode(i_add, ap2, ap2, make_immed(ISZ_NONE, sp->value.i)); ap1 = indnode(ap2, ISZ_ADDR); gen_icode(i_directbranch, 0, ap1, 0); addblock(i_ret); optimize(); rewrite_icode(); /* Translate to machine code & dump */ if (chosenAssembler->gen->post_function_gen) chosenAssembler->gen->post_function_gen(intermed_head); gen_endvirtual(sp); intermed_head = oi; intermed_tail = ot; return sp; }
/*-------------------------------------------------------------------------*/ static void InsertParameterThunks(SYMBOL *funcsp, BLOCK *b) { HASHREC *hr = basetype(funcsp->tp)->syms->table[0]; QUAD *old , *oldit; BLOCK *ocb = currentBlock; old = b->head->fwd; while (old != b->tail && old->dc.opcode != i_label) old = old->fwd; old = old->fwd; oldit = intermed_tail; intermed_tail = old->back; intermed_tail->fwd = NULL; currentBlock = b; while (hr) { SYMBOL *sp = (SYMBOL *)hr->p; if (sp->tp->type == bt_void || sp->tp->type == bt_ellipse || isstructured(sp->tp)) { hr = hr->next; continue; } if (!sp->imvalue || sp->imaddress) { hr = hr->next; continue; } if (funcsp->oldstyle && sp->tp->type == bt_float) { IMODE *right = (IMODE *)Alloc(sizeof(IMODE)); *right = *sp->imvalue; right->size = ISZ_DOUBLE; if (!chosenAssembler->arch->hasFloatRegs) { IMODE *dp = tempreg(ISZ_DOUBLE, 0); IMODE *fp = tempreg(ISZ_FLOAT, 0); /* oldstyle float gets promoted from double */ gen_icode(i_assn, dp, right, 0); gen_icode(i_assn, fp, dp, 0); gen_icode(i_assn, sp->imvalue, fp, 0); } } hr = hr->next; } currentBlock = ocb; if (old->back == b->tail) { b->tail = intermed_tail; } old->back = intermed_tail; intermed_tail->fwd = old; intermed_tail = oldit; }
void mainloop(Screen &screen) { setcolor(EGERGB(255,255,255)); int temp1,temp2,temp3,temp4; MyRectangle tempreg(0,0,0,0,&screen); cleardevice(); int i,j; j =getInteger("How many rectangle?"); MyRectangle *rectangle=new MyRectangle[j]; for(i=0;i<j;i++) { rectangle[i] =tempreg; } for(i=0;i<j;i++) { temp1 =getInteger("Set x1"); temp2 =getInteger("Set y1"); temp3 =getInteger("Set x2"); temp4 =getInteger("Set y2"); (rectangle+i)->setCoordinations(temp1,temp2,temp3,temp4); } for ( ; is_run(); delay_fps(60) ) { cleardevice(); for(i=0;i<j;i++) { (rectangle+i)->Draw(); } } delete[] rectangle; }
SYMBOL *gen_vsn_virtual_thunk(SYMBOL *func, int ofs) { QUAD *oi = intermed_head, *ot = intermed_tail; SYMBOL *sp; IMODE *ap1, *ap2; char buf[256]; //sprintf(buf, "@$vsn%s$%d", func->decoratedName, ofs); sp = search(buf, gsyms); if (sp) return sp; intermed_head = intermed_tail = NULL; blockMax = 0; blockCount = tempCount = 0; exitBlock = 0; IncGlobalFlag(); sp = Alloc(sizeof(SYMBOL)); sp->storage_class = sc_static; sp->value.i = ofs; sp->name = sp->decoratedName = litlate(buf); sp->errname = sp->decoratedName; sp->staticlabel = FALSE; sp->tp = func->tp; sp->gennedvirtfunc = TRUE; insert(sp, gsyms); DecGlobalFlag(); gen_virtual(sp, FALSE); addblock(i_goto); gen_icode(i_substack, NULL, ap2 = tempreg(ISZ_ADDR, 0), NULL ); gen_icode(i_add, ap1 = tempreg(ISZ_ADDR, 0), ap2, make_immed(ISZ_NONE, getSize(bt_pointer))); ap1 = indnode(ap1, ISZ_ADDR); gen_icode(i_add, ap1, ap1 , make_immed(ISZ_NONE, - ofs)); ap1 = make_imaddress(varNode(en_napccon, func), ISZ_ADDR); gen_icode(i_directbranch, 0, ap1, 0); addblock(i_ret); optimize(); rewrite_icode(); /* Translate to machine code & dump */ if (chosenAssembler->gen->post_function_gen) chosenAssembler->gen->post_function_gen(intermed_head); gen_endvirtual(sp); intermed_head = oi; intermed_tail = ot; return sp; }
static int AllocTempOpt(int size1) { // int n = nextTemp; int t; int i; /* for (i= nextTemp; i < tempCount; i++) if (!tempInfo[i]->inUse && tempInfo[i]->enode) { EXPRESSION *rv = tempInfo[i]->enode; rv->v.sp->imvalue->size = size1; rv->v.sp->imind = NULL; memset(tempInfo[i], 0, sizeof(TEMP_INFO)); tempInfo[i]->enode = rv; t = i; break; } if (i == tempCount) { for (i=0; i < nextTemp; i++) if (!tempInfo[i]->inUse && tempInfo[i]->enode) { EXPRESSION *rv = tempInfo[i]->enode; rv->v.sp->imvalue->size = size1; rv->v.sp->imind = NULL; memset(tempInfo[i], 0, sizeof(TEMP_INFO)); tempInfo[i]->enode = rv; t = i; break; } if (i == nextTemp) {*/ IMODE *rv = tempreg(size1, FALSE); t = rv->offset->v.sp->value.i; if (t >= tempSize) { TEMP_INFO **temp = oAlloc((tempSize + 1000) * sizeof(TEMP_INFO *)); memcpy(temp, tempInfo, sizeof(TEMP_INFO *) * tempSize); tempSize += 1000; tempInfo = temp; } if (!tempInfo[t]) tempInfo[t] = (TEMP_INFO *)oAlloc(sizeof(TEMP_INFO)); tempInfo[t]->enode = rv->offset; // } // } nextTemp = t; tempInfo[t]-> partition = t; tempInfo[t]->color = -1; tempInfo[t]->inUse = TRUE; return t; }
IMODE *call_library(char *lib_name, int size) /* * generate a call to a library routine. */ { IMODE *result; result = set_symbol(lib_name, 1); gen_icode(i_gosub, 0, result, 0); gen_icode(i_parmadj, 0, make_parmadj(size), make_parmadj(size)); result = tempreg(ISZ_UINT, 0); result->retval = TRUE; return result; }
void genreturn(STATEMENT *stmt, SYMBOL *funcsp, int flag, int noepilogue, IMODE *allocaAP) /* * generate a return statement. */ { IMODE *ap, *ap1, *ap3; EXPRESSION ep; /* returns a value? */ if (stmt != 0 && stmt->select != 0) { if (basetype(funcsp->tp)->btp && (isstructured(basetype(funcsp->tp)->btp) || basetype(basetype(funcsp->tp)->btp)->type == bt_memberptr)) { SYMBOL *sp = anonymousVar(sc_parameter, &stdpointer); EXPRESSION *en = varNode(en_auto, sp); IMODE *ap3 = gen_expr(funcsp, stmt->select, 0, ISZ_ADDR), *ap2, *ap1; DumpIncDec(funcsp); if (!ap3->retval) { ap1 = LookupLoadTemp(NULL, ap3); if (ap1 != ap3) { IMODE *barrier; if (stmt->select->isatomic) { barrier = doatomicFence(funcsp, stmt->select, NULL); } gen_icode(i_assn, ap1, ap3, NULL); if (stmt->select->isatomic) { doatomicFence(funcsp, stmt->select, barrier); } } } else { ap1 = ap3; } if ((funcsp->linkage == lk_pascal) && basetype(funcsp->tp)->syms->table[0] && ((SYMBOL *)basetype(funcsp->tp)->syms->table[0])->tp->type != bt_void) { sp->offset = funcsp->paramsize; } else { sp->offset = chosenAssembler->arch->retblocksize+(funcsp->farproc *getSize(bt_pointer)); if (funcsp->storage_class == sc_member || funcsp->storage_class == sc_virtual) sp->offset += getSize(bt_pointer); } en = exprNode(en_l_p, en, NULL); ap3 = gen_expr(funcsp, en, 0, ISZ_ADDR); ap = LookupLoadTemp(NULL, ap3); if (ap != ap3) { IMODE *barrier; if (en->isatomic) { barrier = doatomicFence(funcsp, en, NULL); } gen_icode(i_assn, ap, ap3, NULL); if (en->isatomic) { doatomicFence(funcsp, en, barrier); } } gen_icode(i_assnblock, make_immed(ISZ_NONE, basetype(funcsp->tp)->btp->size), ap, ap1); ap1 = tempreg(ISZ_ADDR, 0); ap1->retval = TRUE; gen_icode(i_assn, ap1, ap, NULL); } else if (basetype(funcsp->tp)->btp && basetype(funcsp->tp)->btp->type == bt_memberptr) { ap3 = gen_expr(funcsp, stmt->select, F_VOL, ISZ_ADDR); DumpIncDec(funcsp); ap = LookupLoadTemp(NULL, ap3); if (ap != ap3) { IMODE *barrier; if (stmt->select->isatomic) { barrier = doatomicFence(funcsp, stmt->select, NULL); } gen_icode(i_assn, ap, ap3, NULL); if (stmt->select->isatomic) { doatomicFence(funcsp, stmt->select, barrier); } } ap1 = tempreg(ISZ_ADDR, 0); ap1->retval = TRUE; gen_icode(i_assn, ap1, ap, 0); } else { int size = natural_size(stmt->select); ap3 = gen_expr(funcsp, stmt->select, 0, size); DumpIncDec(funcsp); ap = LookupLoadTemp(NULL, ap3); if (ap != ap3) { IMODE *barrier; if (stmt->select->isatomic) { barrier = doatomicFence(funcsp, stmt->select, NULL); } gen_icode(i_assn, ap, ap3, NULL); if (stmt->select->isatomic) { doatomicFence(funcsp, stmt->select, barrier); } } if (abs(size) < ISZ_UINT) size = -ISZ_UINT; ap1 = tempreg(size, 0); ap1->retval = TRUE; gen_icode(i_assn, ap1, ap, 0); } } else { DumpIncDec(funcsp); } /* create the return or a branch to the return * return is put at end of function... */ if (flag) { int retsize = 0; if (funcsp->linkage == lk_pascal || funcsp->linkage == lk_stdcall) { retsize = funcsp->paramsize ; } gen_label(retlab); if (!noepilogue) { if (allocaAP) { gen_icode(i_loadstack, 0, allocaAP, 0); } /* if (funcsp->loadds && funcsp->farproc) gen_icode(i_unloadcontext,0,0,0); */ gen_icode(i_epilogue,0,0,0); if (funcsp->linkage == lk_interrupt || funcsp->linkage == lk_fault) { /* if (funcsp->loadds) gen_icode(i_unloadcontext,0,0,0); */ gen_icode(i_popcontext, 0,0,0); gen_icode(i_rett, 0, make_immed(ISZ_NONE,funcsp->linkage == lk_interrupt), 0); } else { gen_icode(i_ret, 0, make_immed(ISZ_NONE,retsize), 0); } } } else { /* not using gen_igoto because it will make a new block */ gen_icode(i_goto, NULL, NULL, NULL); intermed_tail->dc.v.label = retlab; } }
void genreturn(STATEMENT *stmt, SYMBOL *funcsp, int flag, int noepilogue, IMODE *allocaAP) /* * generate a return statement. */ { IMODE *ap = NULL, *ap1, *ap3; EXPRESSION ep; int size; /* returns a value? */ if (stmt != 0 && stmt->select != 0) { if (basetype(funcsp->tp)->btp && (isstructured(basetype(funcsp->tp)->btp) || basetype(basetype(funcsp->tp)->btp)->type == bt_memberptr)) { EXPRESSION *en = anonymousVar(sc_parameter, &stdpointer); SYMBOL *sp = en->v.sp; gen_expr(funcsp, stmt->select, 0, ISZ_ADDR); DumpIncDec(funcsp); sp->offset = chosenAssembler->arch->retblocksize; sp->allocate = FALSE; if ((funcsp->linkage == lk_pascal) && basetype(funcsp->tp)->syms->table[0] && ((SYMBOL *)basetype(funcsp->tp)->syms->table[0])->tp->type != bt_void) sp->offset = funcsp->paramsize; deref(&stdpointer, &en); ap = gen_expr(funcsp, en, 0, ISZ_ADDR); size = ISZ_ADDR; } else { size = natural_size(stmt->select); ap3 = gen_expr(funcsp, stmt->select, 0, size); DumpIncDec(funcsp); ap = LookupLoadTemp(NULL, ap3); if (ap != ap3) { IMODE *barrier; if (stmt->select->isatomic) { barrier = doatomicFence(funcsp, stmt->select, NULL); } gen_icode(i_assn, ap, ap3, NULL); if (stmt->select->isatomic) { doatomicFence(funcsp, stmt->select, barrier); } } if (abs(size) < ISZ_UINT) size = -ISZ_UINT; } } else { DumpIncDec(funcsp); } if (ap) { ap1 = tempreg(size, 0); ap1->retval = TRUE; gen_icode(i_assn, ap1, ap, 0); } if (stmt && stmt->destexp) { gen_expr(funcsp, stmt->destexp, F_NOVALUE, ISZ_ADDR); } /* create the return or a branch to the return * return is put at end of function... */ if (flag) { int retsize = 0; if (funcsp->linkage == lk_pascal || funcsp->linkage == lk_stdcall) { retsize = funcsp->paramsize ; } gen_label(retlab); if (!noepilogue) { if (allocaAP) { gen_icode(i_loadstack, 0, allocaAP, 0); } /* if (funcsp->loadds && funcsp->farproc) gen_icode(i_unloadcontext,0,0,0); */ if (cparams.prm_xcept && funcsp->xc && funcsp->xc->xcRundownFunc) gen_expr(funcsp, funcsp->xc->xcRundownFunc, F_NOVALUE, ISZ_UINT); gen_icode(i_epilogue,0,0,0); if (funcsp->linkage == lk_interrupt || funcsp->linkage == lk_fault) { /* if (funcsp->loadds) gen_icode(i_unloadcontext,0,0,0); */ gen_icode(i_popcontext, 0,0,0); gen_icode(i_rett, 0, make_immed(ISZ_UINT,funcsp->linkage == lk_interrupt), 0); } else { gen_icode(i_ret, 0, make_immed(ISZ_UINT,retsize), 0); } } } else { /* not using gen_igoto because it will make a new block */ gen_icode(i_goto, NULL, NULL, NULL); intermed_tail->dc.v.label = retlab; } }
static void renameToTemps(SYMBOL *funcsp) { HASHTABLE *temp = funcsp->inlineFunc.syms; if (!cparams.prm_optimize || functionHasAssembly) return; /* if there is a setjmp in the function, no variable gets moved into a reg */ if (setjmp_used) return; while (temp) { HASHREC *hr = temp->table[0]; while (hr) { SYMBOL *sp = (SYMBOL *)hr->p; TYPE *tp; /* needed for pointer aliasing */ if (!sp->imvalue && basetype(sp->tp)->type != bt_memberptr && !isstructured(sp->tp) && sp->tp->type != bt_ellipse && sp->tp->type != bt_aggregate) { if (sp->storage_class != sc_auto && sp->storage_class != sc_register) { IncGlobalFlag(); } if (sp->imaddress) { IMODE *im = Alloc(sizeof(IMODE)); *im = *sp->imaddress; im->size = sizeFromType(sp->tp); im->mode = i_direct; sp->imvalue = im; } else if (sp->imind) { IMODE *im = Alloc(sizeof(IMODE)); *im = *sp->imind->im; im-> size = ISZ_ADDR; im->mode = i_direct; sp->imvalue = im; } else sp->imvalue = tempreg(sizeFromType(sp->tp), FALSE); if (sp->storage_class != sc_auto && sp->storage_class != sc_register) { DecGlobalFlag(); } } tp = sp->tp; if (tp->type == bt_typedef) tp = tp->btp; if (!sp->pushedtotemp && sp->storage_class != sc_parameter && !sp->imaddress && !sp->inasm && ((chosenAssembler->arch->hasFloatRegs || tp->type < bt_float) && tp->type < bt_void || basetype(tp)->type == bt_pointer && basetype(tp)->btp->type != bt_func || isref(tp)) && (sp->storage_class == sc_auto || sp->storage_class == sc_register) && !sp->usedasbit) { /* this works because all IMODES refering to the same * variable are the same, at least until this point * that will change when we start inserting temps */ EXPRESSION *ep = tempenode(); ep->v.sp->tp = sp->tp; ep->right = (EXPRESSION *)sp; /* marking both the orignal var and the new temp as pushed to temp*/ sp->pushedtotemp = TRUE ; ep->v.sp->pushedtotemp = TRUE; sp->allocate = FALSE; if (sp->imvalue) { ep->isvolatile = sp->imvalue->offset->isvolatile; ep->isrestrict = sp->imvalue->offset->isrestrict; sp->imvalue->offset = ep ; } if (sp->imind) { IMODELIST *iml = sp->imind; ep->isvolatile = sp->imind->im->offset->isvolatile; ep->isrestrict = sp->imind->im->offset->isrestrict; while (iml) { iml->im->offset = ep; iml = iml->next; } } ep->v.sp->imvalue = sp->imvalue; } hr = hr->next; } temp = temp->next; } }