// note: ComplexPower_bn() returns need to be +shiftfactor'ed BNComplex *ComplexPower_bn(BNComplex *t, BNComplex *xx, BNComplex *yy) { BNComplex tmp; bn_t e2x, siny, cosy; int saved; saved = save_stack(); e2x = alloc_stack(bnlength); siny = alloc_stack(bnlength); cosy = alloc_stack(bnlength); tmp.x = alloc_stack(rlength); tmp.y = alloc_stack(rlength); // 0 raised to anything is 0 if (is_bn_zero(xx->x) && is_bn_zero(xx->y)) { clear_bn(t->x); clear_bn(t->y); return (t); } cmplxlog_bn(t, xx); cplxmul_bn(&tmp, t, yy); exp_bn(e2x, tmp.x); sincos_bn(siny, cosy, tmp.y); mult_bn(t->x, e2x, cosy); mult_bn(t->y, e2x, siny); restore_stack(saved); return (t); }
static void process_function_graph_exit(struct pevent *pevent, struct pevent_record *record) { unsigned long long depth; unsigned long long val; int pid; int ret; ret = pevent_read_number_field(common_pid_field, record->data, &val); if (ret < 0) die("no pid field for function graph exit?"); ret = pevent_read_number_field(function_graph_exit_depth_field, record->data, &depth); if (ret < 0) die("no parent ip field for function?"); pid = val; if (current_pid >= 0 && pid != current_pid) { save_stack(); restore_stack(pid); } current_pid = pid; if (ips_idx != depth) { save_call_chain(pid, ips, ips_idx, 0); while (ips_idx > depth) pop_stack_func(); } func_depth = depth - 1; }
bool Lua_table::valid()const { int const init_stack_top = initail_stack_size(); bool result = get_table(); restore_stack(init_stack_top); return result; }
static void save_stored_stacks(void) { while (saved_stacks) { restore_stack(saved_stacks->pid); save_call_chain(current_pid, ips, ips_idx, 0); } }
void zoomoutbf(void) /* for ctl-enter, calc corners for zooming out */ { /* (xxmin,yymax), etc, are already set to zoombox corners; (sxmin,symax), etc, are still the screen's corners; use the same logic as plot_orbit stuff to first calculate current screen corners relative to the zoombox, as if the zoombox were a square with upper left (0,0) and width/depth 1; ie calc the current screen corners as if plotting them from the zoombox; then extend these co-ords from current real screen corners to get new actual corners */ bf_t savbfxmin,savbfymax,bfftemp; bf_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6,bfplotmx1,bfplotmx2,bfplotmy1,bfplotmy2; int saved; saved = save_stack(); savbfxmin = alloc_stack(rbflength+2); savbfymax = alloc_stack(rbflength+2); bfftemp = alloc_stack(rbflength+2); tmp1 = alloc_stack(rbflength+2); tmp2 = alloc_stack(rbflength+2); tmp3 = alloc_stack(rbflength+2); tmp4 = alloc_stack(rbflength+2); tmp5 = alloc_stack(rbflength+2); tmp6 = alloc_stack(rbflength+2); bfplotmx1 = alloc_stack(rbflength+2); bfplotmx2 = alloc_stack(rbflength+2); bfplotmy1 = alloc_stack(rbflength+2); bfplotmy2 = alloc_stack(rbflength+2); /* ftemp = (yymin-yy3rd)*(xx3rd-xxmin) - (xxmax-xx3rd)*(yy3rd-yymax); */ sub_bf(tmp1,bfymin,bfy3rd); sub_bf(tmp2,bfx3rd,bfxmin); sub_bf(tmp3,bfxmax,bfx3rd); sub_bf(tmp4,bfy3rd,bfymax); mult_bf(tmp5,tmp1,tmp2); mult_bf(tmp6,tmp3,tmp4); sub_bf(bfftemp,tmp5,tmp6); /* plotmx1 = (xx3rd-xxmin); */ ; /* reuse the plotxxx vars is safe */ copy_bf(bfplotmx1,tmp2); /* plotmx2 = (yy3rd-yymax); */ copy_bf(bfplotmx2,tmp4); /* plotmy1 = (yymin-yy3rd); */ copy_bf(bfplotmy1,tmp1); /* plotmy2 = (xxmax-xx3rd); */; copy_bf(bfplotmy2,tmp3); /* savxxmin = xxmin; savyymax = yymax; */ copy_bf(savbfxmin,bfxmin); copy_bf(savbfymax,bfymax); sub_bf(tmp1,bfsxmin,savbfxmin); sub_bf(tmp2,bfsymax,savbfymax); zmo_calcbf(tmp1,tmp2,bfxmin,bfymax,bfplotmx1,bfplotmx2,bfplotmy1, bfplotmy2,bfftemp); sub_bf(tmp1,bfsxmax,savbfxmin); sub_bf(tmp2,bfsymin,savbfymax); zmo_calcbf(tmp1,tmp2,bfxmax,bfymin,bfplotmx1,bfplotmx2,bfplotmy1, bfplotmy2,bfftemp); sub_bf(tmp1,bfsx3rd,savbfxmin); sub_bf(tmp2,bfsy3rd,savbfymax); zmo_calcbf(tmp1,tmp2,bfx3rd,bfy3rd,bfplotmx1,bfplotmx2,bfplotmy1, bfplotmy2,bfftemp); restore_stack(saved); }
void restore_stack(int once_more) { long padding[12]; long tos; int i,tempn; // Make sure there's enough room on the stack if (pbos-n < &tos) { restore_stack(1); } if (once_more) { restore_stack(0); } tempn = n; //Copy stack back out from continuation for (i = 0; i<n; ++i) { pbos[-i] = stack[i]; } longjmp(registers,1); }
static void process_function(struct pevent *pevent, struct pevent_record *record) { unsigned long long parent_ip; unsigned long long ip; unsigned long long val; const char *parent; const char *func; int pid; int ret; ret = pevent_read_number_field(common_pid_field, record->data, &val); if (ret < 0) die("no pid field for function?"); ret = pevent_read_number_field(function_ip_field, record->data, &ip); if (ret < 0) die("no ip field for function?"); ret = pevent_read_number_field(function_parent_ip_field, record->data, &parent_ip); if (ret < 0) die("no parent ip field for function?"); pid = val; func = pevent_find_function(pevent, ip); parent = pevent_find_function(pevent, parent_ip); if (current_pid >= 0 && pid != current_pid) { save_stack(); restore_stack(pid); } current_pid = pid; if (ips_idx) { if (ips[ips_idx - 1] == parent) push_stack_func(func); else { save_call_chain(pid, ips, ips_idx, 0); while (ips_idx) { pop_stack_func(); if (ips[ips_idx - 1] == parent) { push_stack_func(func); break; } } } } /* The above check can set ips_idx to zero again */ if (!ips_idx) { push_stack_func(parent); push_stack_func(func); } }
/* Special hack to workaround the fact that the * when the SEH handler is called the stack is * to small to recover. * * Stack walking part of this method is from mono_handle_exception * * The idea is simple; * - walk the stack to free some space (64k) * - set esp to new stack location * - call mono_arch_handle_exception with stack overflow exception * - set esp to SEH handlers stack * - done */ static void win32_handle_stack_overflow (EXCEPTION_POINTERS* ep, struct sigcontext *sctx) { SYSTEM_INFO si; DWORD page_size; MonoDomain *domain = mono_domain_get (); MonoJitInfo rji; MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); MonoLMF *lmf = jit_tls->lmf; MonoContext initial_ctx; MonoContext ctx; guint32 free_stack = 0; StackFrameInfo frame; /* convert sigcontext to MonoContext (due to reuse of stack walking helpers */ mono_arch_sigctx_to_monoctx (sctx, &ctx); /* get our os page size */ GetSystemInfo(&si); page_size = si.dwPageSize; /* Let's walk the stack to recover * the needed stack space (if possible) */ memset (&rji, 0, sizeof (rji)); initial_ctx = ctx; free_stack = (guint8*)(MONO_CONTEXT_GET_BP (&ctx)) - (guint8*)(MONO_CONTEXT_GET_BP (&initial_ctx)); /* try to free 64kb from our stack */ do { MonoContext new_ctx; mono_arch_find_jit_info (domain, jit_tls, &rji, &ctx, &new_ctx, &lmf, NULL, &frame); if (!frame.ji) { g_warning ("Exception inside function without unwind info"); g_assert_not_reached (); } if (frame.ji != (gpointer)-1) { free_stack = (guint8*)(MONO_CONTEXT_GET_BP (&ctx)) - (guint8*)(MONO_CONTEXT_GET_BP (&initial_ctx)); } /* todo: we should call abort if ji is -1 */ ctx = new_ctx; } while (free_stack < 64 * 1024 && frame.ji != (gpointer) -1); /* convert into sigcontext to be used in mono_arch_handle_exception */ mono_arch_monoctx_to_sigctx (&ctx, sctx); /* todo: install new stack-guard page */ /* use the new stack and call mono_arch_handle_exception () */ restore_stack (sctx); }
static void _fastcall zmo_calcbf(bf_t bfdx, bf_t bfdy, bf_t bfnewx, bf_t bfnewy,bf_t bfplotmx1, bf_t bfplotmx2, bf_t bfplotmy1, bf_t bfplotmy2, bf_t bfftemp) { bf_t btmp1, btmp2, btmp3, btmp4, btempx, btempy ; bf_t btmp2a, btmp4a; int saved; saved = save_stack(); btmp1 = alloc_stack(rbflength+2); btmp2 = alloc_stack(rbflength+2); btmp3 = alloc_stack(rbflength+2); btmp4 = alloc_stack(rbflength+2); btmp2a = alloc_stack(rbflength+2); btmp4a = alloc_stack(rbflength+2); btempx = alloc_stack(rbflength+2); btempy = alloc_stack(rbflength+2); /* calc cur screen corner relative to zoombox, when zoombox co-ords are taken as (0,0) topleft thru (1,1) bottom right */ /* tempx = dy * plotmx1 - dx * plotmx2; */ mult_bf(btmp1,bfdy,bfplotmx1); mult_bf(btmp2,bfdx,bfplotmx2); sub_bf(btempx,btmp1,btmp2); /* tempy = dx * plotmy1 - dy * plotmy2; */ mult_bf(btmp1,bfdx,bfplotmy1); mult_bf(btmp2,bfdy,bfplotmy2); sub_bf(btempy,btmp1,btmp2); /* calc new corner by extending from current screen corners */ /* *newx = sxmin + tempx*(sxmax-sx3rd)/ftemp + tempy*(sx3rd-sxmin)/ftemp; */ sub_bf(btmp1,bfsxmax,bfsx3rd); mult_bf(btmp2,btempx,btmp1); /* show_three_bf("fact1",btempx,"fact2",btmp1,"prod ",btmp2,70); */ div_bf(btmp2a,btmp2,bfftemp); /* show_three_bf("num ",btmp2,"denom",bfftemp,"quot ",btmp2a,70); */ sub_bf(btmp3,bfsx3rd,bfsxmin); mult_bf(btmp4,btempy,btmp3); div_bf(btmp4a,btmp4,bfftemp); add_bf(bfnewx,bfsxmin,btmp2a); add_a_bf(bfnewx,btmp4a); /* *newy = symax + tempy*(sy3rd-symax)/ftemp + tempx*(symin-sy3rd)/ftemp; */ sub_bf(btmp1,bfsy3rd,bfsymax); mult_bf(btmp2,btempy,btmp1); div_bf(btmp2a,btmp2,bfftemp); sub_bf(btmp3,bfsymin,bfsy3rd); mult_bf(btmp4,btempx,btmp3); div_bf(btmp4a,btmp4,bfftemp); add_bf(bfnewy,bfsymax,btmp2a); add_a_bf(bfnewy,btmp4a); restore_stack(saved); }
void restore_stack(cont *c,int once_more) { long padding[12]; long tos; int i,n; /* * Make sure there's enough room on the stack */ if (pbos-c->n<&tos) { restore_stack(c,1); } if (once_more) { restore_stack(c,0); } /* * Copy stack back out from continuation */ n = c->n; for (i = 0; i<n; ++i) { pbos[-i] = c->stack[i]; } longjmp(c->registers,1); }
BNComplex *cplxmul_bn(BNComplex *t, BNComplex *x, BNComplex *y) { bn_t tmp1; int saved; saved = save_stack(); tmp1 = alloc_stack(rlength); mult_bn(t->x, x->x, y->x); mult_bn(t->y, x->y, y->y); sub_bn(t->x, t->x+shiftfactor, t->y+shiftfactor); mult_bn(tmp1, x->x, y->y); mult_bn(t->y, x->y, y->x); add_bn(t->y, tmp1+shiftfactor, t->y+shiftfactor); restore_stack(saved); return (t); }
BFComplex *cplxmul_bf(BFComplex *t, BFComplex *x, BFComplex *y) { bf_t tmp1; int saved; saved = save_stack(); tmp1 = alloc_stack(rbflength+2); mult_bf(t->x, x->x, y->x); mult_bf(t->y, x->y, y->y); sub_bf(t->x, t->x, t->y); mult_bf(tmp1, x->x, y->y); mult_bf(t->y, x->y, y->x); add_bf(t->y, tmp1, t->y); restore_stack(saved); return (t); }
/* big number declarations */ void calc_corner(bf_t target,bf_t p1,double p2,bf_t p3,double p4,bf_t p5) { bf_t btmp1, btmp2 ,btmp3; int saved; saved = save_stack(); btmp1 = alloc_stack(rbflength+2); btmp2 = alloc_stack(rbflength+2); btmp3 = alloc_stack(rbflength+2); /* use target as temporary variable */ floattobf(btmp3, p2); mult_bf(btmp1,btmp3,p3); mult_bf(btmp2,floattobf(target, p4),p5); add_bf(target,btmp1,btmp2); add_a_bf(target,p1); restore_stack(saved); }
static void process_function_graph_entry(struct pevent *pevent, struct pevent_record *record) { unsigned long long depth; unsigned long long ip; unsigned long long val; const char *func; int pid; int ret; ret = pevent_read_number_field(common_pid_field, record->data, &val); if (ret < 0) die("no pid field for function graph entry?"); ret = pevent_read_number_field(function_graph_entry_func_field, record->data, &ip); if (ret < 0) die("no ip field for function graph entry?"); ret = pevent_read_number_field(function_graph_entry_depth_field, record->data, &depth); if (ret < 0) die("no parent ip field for function entry?"); pid = val; func = pevent_find_function(pevent, ip); if (current_pid >= 0 && pid != current_pid) { save_stack(); restore_stack(pid); } current_pid = pid; if (depth != ips_idx) { save_call_chain(pid, ips, ips_idx, 0); while (ips_idx > depth) pop_stack_func(); } func_depth = depth; push_stack_func(func); }
int JuliaZpowerbfFractal() { BFComplex parm2; int saved; saved = save_stack(); parm2.x = alloc_stack(bflength+2); parm2.y = alloc_stack(bflength+2); floattobf(parm2.x, param[2]); floattobf(parm2.y, param[3]); ComplexPower_bf(&bfnew, &bfold, &parm2); add_bf(bfnew.x, bfparm.x, bfnew.x); add_bf(bfnew.y, bfparm.y, bfnew.y); restore_stack(saved); return bigfltbailout(); }
int JuliaZpowerbnFractal() { BNComplex parm2; int saved; saved = save_stack(); parm2.x = alloc_stack(bnlength); parm2.y = alloc_stack(bnlength); floattobn(parm2.x, param[2]); floattobn(parm2.y, param[3]); ComplexPower_bn(&bnnew, &bnold, &parm2); add_bn(bnnew.x, bnparm.x, bnnew.x+shiftfactor); add_bn(bnnew.y, bnparm.y, bnnew.y+shiftfactor); restore_stack(saved); return bignumbailout(); }
// for aspect ratio debugging void showaspect(char *s) { bf_t bt1, bt2, aspect; char msg[100], str[100]; int saved; saved = save_stack(); bt1 = alloc_stack(rbflength+2); bt2 = alloc_stack(rbflength+2); aspect = alloc_stack(rbflength+2); sub_bf(bt1, bfxmax, bfxmin); sub_bf(bt2, bfymax, bfymin); div_bf(aspect, bt2, bt1); bftostr(str, 10, aspect); sprintf(msg, "aspect %s\nfloat %13.10f\nbf %s\n\n", s, (yymax-yymin)/(xxmax-xxmin), str); if (stopmsg(STOPMSG_NONE, msg) == -1) goodbye(); restore_stack(saved); }
void drawbox(int drawit) { struct coords tl,bl,tr,br; /* dot addr of topleft, botleft, etc */ double tmpx,tmpy,dx,dy,rotcos,rotsin,ftemp1,ftemp2; double fxwidth,fxskew,fydepth,fyskew,fxadj; bf_t bffxwidth, bffxskew, bffydepth, bffyskew, bffxadj; int saved; if (zwidth==0) { /* no box to draw */ if (boxcount!=0) { /* remove the old box from display */ clearbox(); /* asm routine */ boxcount = 0; } reset_zoom_corners(); return; } if(bf_math) { saved = save_stack(); bffxwidth = alloc_stack(rbflength+2); bffxskew = alloc_stack(rbflength+2); bffydepth = alloc_stack(rbflength+2); bffyskew = alloc_stack(rbflength+2); bffxadj = alloc_stack(rbflength+2); } ftemp1 = PI*zrotate/72; /* convert to radians */ rotcos = cos(ftemp1); /* sin & cos of rotation */ rotsin = sin(ftemp1); /* do some calcs just once here to reduce fp work a bit */ fxwidth = sxmax-sx3rd; fxskew = sx3rd-sxmin; fydepth = sy3rd-symax; fyskew = symin-sy3rd; fxadj = zwidth*zskew; if(bf_math) { /* do some calcs just once here to reduce fp work a bit */ sub_bf(bffxwidth,bfsxmax,bfsx3rd); sub_bf(bffxskew,bfsx3rd,bfsxmin); sub_bf(bffydepth,bfsy3rd,bfsymax); sub_bf(bffyskew,bfsymin,bfsy3rd); floattobf(bffxadj, fxadj); } /* calc co-ords of topleft & botright corners of box */ tmpx = zwidth/-2+fxadj; /* from zoombox center as origin, on xdots scale */ tmpy = zdepth*finalaspectratio/2; dx = (rotcos*tmpx - rotsin*tmpy) - tmpx; /* delta x to rotate topleft */ dy = tmpy - (rotsin*tmpx + rotcos*tmpy); /* delta y to rotate topleft */ /* calc co-ords of topleft */ ftemp1 = zbx + dx + fxadj; ftemp2 = zby + dy/finalaspectratio; tl.x = (int)(ftemp1*(dxsize+PIXELROUND)); /* screen co-ords */ tl.y = (int)(ftemp2*(dysize+PIXELROUND)); xxmin = sxmin + ftemp1*fxwidth + ftemp2*fxskew; /* real co-ords */ yymax = symax + ftemp2*fydepth + ftemp1*fyskew; if(bf_math) { calc_corner(bfxmin,bfsxmin,ftemp1,bffxwidth,ftemp2,bffxskew); calc_corner(bfymax,bfsymax,ftemp2,bffydepth,ftemp1,bffyskew); } /* calc co-ords of bottom right */ ftemp1 = zbx + zwidth - dx - fxadj; ftemp2 = zby - dy/finalaspectratio + zdepth; br.x = (int)(ftemp1*(dxsize+PIXELROUND)); br.y = (int)(ftemp2*(dysize+PIXELROUND)); xxmax = sxmin + ftemp1*fxwidth + ftemp2*fxskew; yymin = symax + ftemp2*fydepth + ftemp1*fyskew; if(bf_math) { calc_corner(bfxmax,bfsxmin,ftemp1,bffxwidth,ftemp2,bffxskew); calc_corner(bfymin,bfsymax,ftemp2,bffydepth,ftemp1,bffyskew); } /* do the same for botleft & topright */ tmpx = zwidth/-2 - fxadj; tmpy = 0.0-tmpy; dx = (rotcos*tmpx - rotsin*tmpy) - tmpx; dy = tmpy - (rotsin*tmpx + rotcos*tmpy); ftemp1 = zbx + dx - fxadj; ftemp2 = zby + dy/finalaspectratio + zdepth; bl.x = (int)(ftemp1*(dxsize+PIXELROUND)); bl.y = (int)(ftemp2*(dysize+PIXELROUND)); xx3rd = sxmin + ftemp1*fxwidth + ftemp2*fxskew; yy3rd = symax + ftemp2*fydepth + ftemp1*fyskew; if(bf_math) { calc_corner(bfx3rd,bfsxmin,ftemp1,bffxwidth,ftemp2,bffxskew); calc_corner(bfy3rd,bfsymax,ftemp2,bffydepth,ftemp1,bffyskew); restore_stack(saved); } ftemp1 = zbx + zwidth - dx + fxadj; ftemp2 = zby - dy/finalaspectratio; tr.x = (int)(ftemp1*(dxsize+PIXELROUND)); tr.y = (int)(ftemp2*(dysize+PIXELROUND)); if (boxcount!=0) { /* remove the old box from display */ clearbox(); /* asm routine */ boxcount = 0; } if (drawit) { /* caller wants box drawn as well as co-ords calc'd */ #ifndef XFRACT /* build the list of zoom box pixels */ addbox(tl); addbox(tr); /* corner pixels */ addbox(bl); addbox(br); drawlines(tl,tr,bl.x-tl.x,bl.y-tl.y); /* top & bottom lines */ drawlines(tl,bl,tr.x-tl.x,tr.y-tl.y); /* left & right lines */ #else boxx[0] = tl.x + sxoffs; boxy[0] = tl.y + syoffs; boxx[1] = tr.x + sxoffs; boxy[1] = tr.y + syoffs; boxx[2] = br.x + sxoffs; boxy[2] = br.y + syoffs; boxx[3] = bl.x + sxoffs; boxy[3] = bl.y + syoffs; boxcount = 1; #endif dispbox(); /* asm routine to paint it */ } }
static void process_kernel_stack(struct pevent *pevent, struct pevent_record *record) { struct format_field *field = kernel_stack_caller_field; unsigned long long val; void *data = record->data; int do_restore = 0; int pid; int ret; ret = pevent_read_number_field(common_pid_field, record->data, &val); if (ret < 0) die("no pid field for function?"); pid = val; if (pending_pid >= 0 && pid != pending_pid) { reset_pending_stack(); return; } if (!field) die("no caller field for kernel stack?"); if (pending_pid >= 0) { if (current_pid >= 0) { save_stack(); do_restore = 1; } } else { /* function stack trace? */ if (current_pid >= 0) { copy_stack_to_pending(current_pid); free(ips); reset_stack(); } } current_pid = pid; /* Need to start at the end of the callers and work up */ for (data += field->offset; data < record->data + record->size; data += long_size) { unsigned long long addr; addr = pevent_read_number(pevent, data, long_size); if ((long_size == 8 && addr == (unsigned long long)-1) || ((int)addr == -1)) break; } for (data -= long_size; data >= record->data + field->offset; data -= long_size) { unsigned long long addr; const char *func; addr = pevent_read_number(pevent, data, long_size); func = pevent_find_function(pevent, addr); if (func) push_stack_func(func); } if (pending_pid >= 0) { push_stack_func(pending_ips[pending_ips_idx - 1]); reset_pending_stack(); } save_call_chain(current_pid, ips, ips_idx, 1); if (do_restore) restore_stack(current_pid); }
bool MandelbfSetup() { // this should be set up dynamically based on corners bf_t bftemp1, bftemp2; int saved; saved = save_stack(); bftemp1 = alloc_stack(bflength+2); bftemp2 = alloc_stack(bflength+2); bf_math = bf_math_type::BIGFLT; // bfxdel = (bfxmax - bfx3rd)/(xdots-1) sub_bf(bfxdel, bfxmax, bfx3rd); div_a_bf_int(bfxdel, (U16)(xdots - 1)); // bfydel = (bfymax - bfy3rd)/(ydots-1) sub_bf(bfydel, bfymax, bfy3rd); div_a_bf_int(bfydel, (U16)(ydots - 1)); // bfxdel2 = (bfx3rd - bfxmin)/(ydots-1) sub_bf(bfxdel2, bfx3rd, bfxmin); div_a_bf_int(bfxdel2, (U16)(ydots - 1)); // bfydel2 = (bfy3rd - bfymin)/(xdots-1) sub_bf(bfydel2, bfy3rd, bfymin); div_a_bf_int(bfydel2, (U16)(xdots - 1)); abs_bf(bfclosenuff, bfxdel); if (cmp_bf(abs_bf(bftemp1, bfxdel2), bfclosenuff) > 0) copy_bf(bfclosenuff, bftemp1); if (cmp_bf(abs_bf(bftemp1, bfydel), abs_bf(bftemp2, bfydel2)) > 0) { if (cmp_bf(bftemp1, bfclosenuff) > 0) copy_bf(bfclosenuff, bftemp1); } else if (cmp_bf(bftemp2, bfclosenuff) > 0) copy_bf(bfclosenuff, bftemp2); { int t; t = abs(periodicitycheck); while (t--) half_a_bf(bfclosenuff); } c_exp = (int)param[2]; switch (fractype) { case fractal_type::JULIAFP: copy_bf(bfparm.x, bfparms[0]); copy_bf(bfparm.y, bfparms[1]); break; case fractal_type::FPMANDELZPOWER: init_big_pi(); if ((double)c_exp == param[2] && (c_exp & 1)) // odd exponents symmetry = symmetry_type::XY_AXIS_NO_PARAM; if (param[3] != 0) symmetry = symmetry_type::NONE; break; case fractal_type::FPJULIAZPOWER: init_big_pi(); copy_bf(bfparm.x, bfparms[0]); copy_bf(bfparm.y, bfparms[1]); if ((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2]) symmetry = symmetry_type::NONE; break; default: break; } restore_stack(saved); return true; }
void exec_context() { restore_stack(1); //Restore stack }
void load(int r, SValue* sv) { int fr,ft,fc; int length; int align; int v,sign,t; SValue v1; pr("; load %d\n",r); pr("; type %d reg 0x%x extra 0x%x\n",sv->type.t,sv->r,sv->type.extra); fr = sv->r; ft = sv->type.t; fc = sv->c.ul; length = type_size(&sv->type, &align); if((ft & VT_BTYPE) == VT_LLONG) length = 2; // long longs are handled word-wise if(ll_workaround) length = 4; //pr("; load r 0x%x fr 0x%x ft 0x%x fc 0x%x\n",r,fr,ft,fc); #if 0 // FIXME: Does that make sense? if(fc>0) sign=0; else { sign = 1; fc = -fc; } #endif int base = -1; v = fr & VT_VALMASK; if(fr & VT_LVAL) { if(v == VT_LLOCAL) { v1.type.t = VT_PTR; v1.r = VT_LOCAL | VT_LVAL; v1.c.ul = sv->c.ul; load(base=10 /* lr */, &v1); fc=sign=0; v=VT_LOCAL; } else if(v == VT_CONST) { if(fr & VT_SYM) { // deref symbol + displacement char* sy = get_sym_str(sv->sym); if(is_float(ft)) { pr("; fld%d [%s + %d], tcc__f%d\n", length, sy, fc, r - TREG_F0); switch(length) { case 4: pr("lda.l %s + %d\nsta.b tcc__f%d\nlda.l %s + %d + 2\nsta.b tcc__f%dh\n", sy, fc, r - TREG_F0, sy, fc, r - TREG_F0); break; default: error("ICE 1"); } } else { pr("; ld%d [%s + %d], tcc__r%d\n", length, sy, fc, r); // FIXME: This implementation is moronic if(fc > 65535) error("index too big"); switch(length) { case 1: pr("lda.w #0\nsep #$20\nlda.l %s + %d\nrep #$20\n", sy, fc); if(!(ft & VT_UNSIGNED)) pr("xba\nxba\nbpl +\nora.w #$ff00\n+\n"); pr("sta.b tcc__r%d\n", r); break; //case 2: pr("stz.b tcc__r%dh\nldx #%d\nlda.l %s,x\nsta.b tcc__r%d\n", r, fc, sy, r); break; case 2: pr("lda.l %s + %d\nsta.b tcc__r%d\n", sy, fc, r); break; case 4: pr("lda.l %s + %d\nsta.b tcc__r%d\nlda.l %s + %d + 2\nsta.b tcc__r%dh\n", sy, fc, r, sy, fc, r); break; default: error("ICE 1"); } } } else { // deref constant pointer //error("ld [%d],tcc__r%d\n",fc,r); pr("; deref constant ptr ld [%d],tcc__r%d\n", fc, r); if(is_float(ft)) { error("dereferencing constant float pointers unimplemented\n"); } else { switch(length) { case 1: pr("lda.w #0\nsep #$20\nlda.l %d\nrep #$20\n", fc); if(!(ft & VT_UNSIGNED)) pr("xba\nxba\nbpl +\nora.w #$ff00\n+\n"); pr("sta.b tcc__r%d\n", r); break; case 2: pr("lda.l %d\nsta.b tcc__r%d\n", fc, r); break; case 4: pr("lda.l %d\nsta.b tcc__r%d\nlda.l %d + 2\nsta.b tcc__r%dh\n", fc, r, fc, r); break; default: error("ICE 1"); } } } return; } else if(v < VT_CONST) { // deref pointer in register base = v; fc = sign = 0; v = VT_LOCAL; } if(v == VT_LOCAL) { if(is_float(ft)) { if(base == -1) { pr("; fld%d [sp,%d],tcc__f%d\n", length, fc, r - TREG_F0); if(length != 4) error("ICE 2f"); fc = adjust_stack(fc, args_size + 2); pr("lda %d + __%s_locals + 1,s\nsta.b tcc__f%d\nlda %d + __%s_locals + 1,s\nsta.b tcc__f%dh\n", fc+args_size, current_fn, r - TREG_F0, fc+args_size+2, current_fn, r - TREG_F0); fc = restore_stack(fc); } else { pr("; fld%d [tcc__r%d,%d],tcc__f%d\n", length, base, fc, r - TREG_F0); if(length != 4) error("ICE 3f"); pr("ldy #%d\nlda.b [tcc__r%d],y\nsta.b tcc__f%d\niny\niny\nlda.b [tcc__r%d], y\nsta.b tcc__f%dh\n", fc, base, r - TREG_F0, base, r - TREG_F0); } } else { if(base == -1) { // value of local at fc pr("; ld%d [sp,%d],tcc__r%d\n",length,fc,r); //if(length == 2 && fc == -88 && r == 0) asm("int $3"); fc = adjust_stack(fc, args_size + 2); switch(length) { case 1: pr("lda.w #0\nsep #$20\nlda %d + __%s_locals + 1,s\nrep #$20\n", fc+args_size, current_fn); if(!(ft & VT_UNSIGNED)) pr("xba\nxba\nbpl +\nora.w #$ff00\n+\n"); pr("sta.b tcc__r%d\n", r); break; //case 2: pr("stz.b tcc__r%dh\nlda %d + __%s_locals + 1,s\nsta.b tcc__r%d\n", r, fc+args_size, current_fn, r); break; case 2: pr("lda %d + __%s_locals + 1,s\nsta.b tcc__r%d\n", fc+args_size, current_fn, r); break; case 4: pr("lda %d + __%s_locals + 1,s\nsta.b tcc__r%d\nlda %d + __%s_locals + 1,s\nsta.b tcc__r%dh\n", fc+args_size, current_fn, r, fc+args_size + 2, current_fn, r); break; default: error("ICE 2"); break; } fc = restore_stack(fc); } else { // value of array member r[fc] pr("; ld%d [tcc__r%d,%d],tcc__r%d\n",length, base, fc, r); switch(length) { case 1: pr("lda.w #0\n"); if(!fc) pr("sep #$20\nlda.b [tcc__r%d]\nrep #$20\n", base); else pr("ldy #%d\nsep #$20\nlda.b [tcc__r%d],y\nrep #$20\n", fc, base); if(!(ft & VT_UNSIGNED)) pr("xba\nxba\nbpl +\nora.w #$ff00\n+\n"); pr("sta.b tcc__r%d\n", r); break; //case 2: pr("stz.b tcc__r%dh\nldy #%d\nlda.b [tcc__r%d],y\nsta.b tcc__r%d\n", r, fc, base, r); break; case 2: if(!fc) pr("lda.b [tcc__r%d]\nsta.b tcc__r%d\n", base, r); else pr("ldy #%d\nlda.b [tcc__r%d],y\nsta.b tcc__r%d\n", fc, base, r); break; case 4: pr("ldy #%d\nlda.b [tcc__r%d],y\nsta.b tcc__r%d\niny\niny\nlda.b [tcc__r%d],y\nsta.b tcc__r%dh\n", fc, base, r, base, r); break; default: error("ICE 3"); break; } } } return; } } else { // VT_LVAL if(v == VT_CONST) { if(fr & VT_SYM) { // symbolic constant //greloc(cur_text_section, sv->sym, ind, R_DATA_32); char* sy = get_sym_str(sv->sym); pr("; ld%d #%s + %d, tcc__r%d (type 0x%x)\n", length,sy, fc, r, ft); if(length != PTR_SIZE) pr("; FISHY! length <> PTR_SIZE! (may be an array)\n"); pr("lda.w #:%s\nsta.b tcc__r%dh\nlda.w #%s + %d\nsta.b tcc__r%d\n", sy, r, sy, fc, r); } else { // numeric constant pr("; ld%d #%d,tcc__r%d\n",length,sv->c.ul,r); if((ft & VT_BTYPE) == VT_BOOL) { sv->c.ul = sv->c.ul? 1: 0; } switch(length) { case 1: if (ft & VT_UNSIGNED) { pr("lda.w #%d\n", sv->c.ul & 0xff); } else { pr("lda.w #%d\n", ((short)((sv->c.ul & 0xff) << 8)) >> 8); } pr("sta.b tcc__r%d\n", r); break; //case 2: pr("stz.b tcc__r%dh\nlda.w #%d\nsta.b tcc__r%d\n", r, sv->c.ul & 0xffff, r); break; case 2: pr("lda.w #%d\nsta.b tcc__r%d\n", sv->c.ul & 0xffff, r); break; case 4: pr("lda.w #%d\nsta.b tcc__r%d\nlda.w #%d\nsta.b tcc__r%dh\n", sv->c.ul & 0xffff, r, sv->c.ul >> 16, r); break; default: error("ICE 4"); } } return; } else if(v == VT_LOCAL) { if(fr & VT_SYM) { error("symbol"); char* sy = get_sym_str(sv->sym); pr("; LOCAL ld%d #%s, tcc__r%d (type 0x%x)\n", length,sy, r, ft); } else { // local pointer pr("; ld%d #(sp) + %d,tcc__r%d (fr 0x%x ft 0x%x fc 0x%x)\n",length,sv->c.ul,r,fr,ft,fc); // pointer; have to ensure the upper word is correct (page 0) pr("stz.b tcc__r%dh\ntsa\nclc\nadc #(%d + __%s_locals + 1)\nsta.b tcc__r%d\n", r, sv->c.ul + args_size, current_fn, r); } return; } else if(v == VT_CMP) { error("cmp"); return; } else if(v == VT_JMP || v == VT_JMPI) { t = v & 1; // inverted or not pr("; jmpr(i) v 0x%x r 0x%x fc 0x%x\n",v,r,fc); pr("lda #%d\nbra +\n", t); gsym(fc); //pr("lda #%d\n+ stz tcc__r%dh\nsta tcc__r%d\n", t^1, r,r); pr("lda #%d\n+\nsta.b tcc__r%d\n", t^1, r); // stz rXh seems to be unnecessary (we only look at the lower word) return; } else if(v < VT_CONST) { // register value if(is_float(ft)) { //error("float 1"); v -= TREG_F0; r -= TREG_F0; pr("; fmov tcc__f%d, tcc__f%d\n", v, r); pr("lda.b tcc__f%d\nsta.b tcc__f%d\nlda.b tcc__f%dh\nsta.b tcc__f%dh\n", v, r, v, r); } else { pr("; mov tcc__r%d, tcc__r%d\n",v,r); pr("lda.b tcc__r%d\nsta.b tcc__r%d\nlda.b tcc__r%dh\nsta.b tcc__r%dh\n", v, r, v, r); } return; } }
void exec_context(cont *c) { /* * Restore stack */ restore_stack(c,1); }