int mandlebrot(complex c, int i) { complex tmp, z; z = c; while(i --> 0) { //square z & store in tmp, add c and store in z complexmult(&tmp, z, z); complexadd(&z, tmp, c); } float ret = complexabs(z); if(!isfinite(ret)) ret = 0xff; return ret >= 2.0F ? 0 : 1; }
void complexgen(Node *n, Node *res) { Node *nl, *nr; Node tnl, tnr; Node n1, n2, tmp; int tl, tr; if(debug['g']) { dump("\ncomplexgen-n", n); dump("complexgen-res", res); } // pick off float/complex opcodes switch(n->op) { case OCMPLX: subnode(&n1, &n2, res); tempname(&tmp, n1.type); cgen(n->left, &tmp); cgen(n->right, &n2); cgen(&tmp, &n1); return; case OREAL: subnode(&n1, &n2, n->left); cgen(&n1, res); return; case OIMAG: subnode(&n1, &n2, n->left); cgen(&n2, res); return; } // perform conversion from n to res tl = simsimtype(res->type); tl = cplxsubtype(tl); tr = simsimtype(n->type); tr = cplxsubtype(tr); if(tl != tr) { if(!n->addable) { tempname(&n1, n->type); complexmove(n, &n1); n = &n1; } complexmove(n, res); return; } if(!res->addable) { igen(res, &n1, N); cgen(n, &n1); regfree(&n1); return; } if(n->addable) { complexmove(n, res); return; } switch(n->op) { default: dump("complexgen: unknown op", n); fatal("complexgen: unknown op %O", n->op); case ODOT: case ODOTPTR: case OINDEX: case OIND: case ONAME: // PHEAP or PPARAMREF var igen(n, &n1, res); complexmove(&n1, res); regfree(&n1); return; case OCONV: case OADD: case OSUB: case OMUL: case OMINUS: case OCMPLX: case OREAL: case OIMAG: break; } nl = n->left; if(nl == N) return; nr = n->right; // make both sides addable in ullman order if(nr != N) { if(nl->ullman > nr->ullman && !nl->addable) { tempname(&tnl, nl->type); cgen(nl, &tnl); nl = &tnl; } if(!nr->addable) { tempname(&tnr, nr->type); cgen(nr, &tnr); nr = &tnr; } } if(!nl->addable) { tempname(&tnl, nl->type); cgen(nl, &tnl); nl = &tnl; } switch(n->op) { default: fatal("complexgen: unknown op %O", n->op); break; case OCONV: complexmove(nl, res); break; case OMINUS: complexminus(nl, res); break; case OADD: case OSUB: complexadd(n->op, nl, nr, res); break; case OMUL: complexmul(nl, nr, res); break; // ODIV call a runtime function } }
inline hmc_complex operator+=(hmc_complex& left, const hmc_complex& right) { left = complexadd(left, right); return left; }
inline hmc_complex operator+(const hmc_complex& left, const hmc_complex& right) { return complexadd(left, right); }