diff options
Diffstat (limited to 'src/cmd/gc/cplx.c')
-rw-r--r-- | src/cmd/gc/cplx.c | 494 |
1 files changed, 0 insertions, 494 deletions
diff --git a/src/cmd/gc/cplx.c b/src/cmd/gc/cplx.c deleted file mode 100644 index 26c21df82a..0000000000 --- a/src/cmd/gc/cplx.c +++ /dev/null @@ -1,494 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include <u.h> -#include <libc.h> -#include "go.h" - -static void subnode(Node *nr, Node *ni, Node *nc); -static void minus(Node *nl, Node *res); - void complexminus(Node*, Node*); - void complexadd(int op, Node*, Node*, Node*); - void complexmul(Node*, Node*, Node*); - -#define CASE(a,b) (((a)<<16)|((b)<<0)) - -/*c2go -static int -CASE(int a, int b) -{ - return a<<16 | b; -} -*/ - -static int -overlap(Node *f, Node *t) -{ - // check whether f and t could be overlapping stack references. - // not exact, because it's hard to check for the stack register - // in portable code. close enough: worst case we will allocate - // an extra temporary and the registerizer will clean it up. - return f->op == OINDREG && - t->op == OINDREG && - f->xoffset+f->type->width >= t->xoffset && - t->xoffset+t->type->width >= f->xoffset; -} - -/* - * generate: - * res = n; - * simplifies and calls gmove. - */ -void -complexmove(Node *f, Node *t) -{ - int ft, tt; - Node n1, n2, n3, n4, tmp; - - if(debug['g']) { - dump("\ncomplexmove-f", f); - dump("complexmove-t", t); - } - - if(!t->addable) - fatal("complexmove: to not addable"); - - ft = simsimtype(f->type); - tt = simsimtype(t->type); - switch(CASE(ft,tt)) { - - default: - fatal("complexmove: unknown conversion: %T -> %T\n", - f->type, t->type); - - case CASE(TCOMPLEX64,TCOMPLEX64): - case CASE(TCOMPLEX64,TCOMPLEX128): - case CASE(TCOMPLEX128,TCOMPLEX64): - case CASE(TCOMPLEX128,TCOMPLEX128): - // complex to complex move/convert. - // make f addable. - // also use temporary if possible stack overlap. - if(!f->addable || overlap(f, t)) { - tempname(&tmp, f->type); - complexmove(f, &tmp); - f = &tmp; - } - - subnode(&n1, &n2, f); - subnode(&n3, &n4, t); - - thearch.cgen(&n1, &n3); - thearch.cgen(&n2, &n4); - break; - } -} - -int -complexop(Node *n, Node *res) -{ - if(n != N && n->type != T) - if(iscomplex[n->type->etype]) { - goto maybe; - } - if(res != N && res->type != T) - if(iscomplex[res->type->etype]) { - goto maybe; - } - - if(n->op == OREAL || n->op == OIMAG) - goto yes; - - goto no; - -maybe: - switch(n->op) { - case OCONV: // implemented ops - case OADD: - case OSUB: - case OMUL: - case OMINUS: - case OCOMPLEX: - case OREAL: - case OIMAG: - goto yes; - - case ODOT: - case ODOTPTR: - case OINDEX: - case OIND: - case ONAME: - goto yes; - } - -no: -//dump("\ncomplex-no", n); - return 0; -yes: -//dump("\ncomplex-yes", n); - return 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); - } - - while(n->op == OCONVNOP) - n = n->left; - - // pick off float/complex opcodes - switch(n->op) { - case OCOMPLEX: - if(res->addable) { - subnode(&n1, &n2, res); - tempname(&tmp, n1.type); - thearch.cgen(n->left, &tmp); - thearch.cgen(n->right, &n2); - thearch.cgen(&tmp, &n1); - return; - } - break; - - case OREAL: - case OIMAG: - nl = n->left; - if(!nl->addable) { - tempname(&tmp, nl->type); - complexgen(nl, &tmp); - nl = &tmp; - } - subnode(&n1, &n2, nl); - if(n->op == OREAL) { - thearch.cgen(&n1, res); - return; - } - thearch.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) { - thearch.igen(res, &n1, N); - thearch.cgen(n, &n1); - thearch.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 - case OCALLFUNC: - case OCALLMETH: - case OCALLINTER: - thearch.igen(n, &n1, res); - complexmove(&n1, res); - thearch.regfree(&n1); - return; - - case OCONV: - case OADD: - case OSUB: - case OMUL: - case OMINUS: - case OCOMPLEX: - 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); - thearch.cgen(nl, &tnl); - nl = &tnl; - } - if(!nr->addable) { - tempname(&tnr, nr->type); - thearch.cgen(nr, &tnr); - nr = &tnr; - } - } - if(!nl->addable) { - tempname(&tnl, nl->type); - thearch.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; - } -} - -void -complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to) -{ - Node tnl, tnr; - Node n1, n2, n3, n4; - Node na, nb, nc; - - // make both sides addable in ullman order - if(nr != N) { - if(nl->ullman > nr->ullman && !nl->addable) { - tempname(&tnl, nl->type); - thearch.cgen(nl, &tnl); - nl = &tnl; - } - if(!nr->addable) { - tempname(&tnr, nr->type); - thearch.cgen(nr, &tnr); - nr = &tnr; - } - } - if(!nl->addable) { - tempname(&tnl, nl->type); - thearch.cgen(nl, &tnl); - nl = &tnl; - } - - // build tree - // real(l) == real(r) && imag(l) == imag(r) - - subnode(&n1, &n2, nl); - subnode(&n3, &n4, nr); - - memset(&na, 0, sizeof(na)); - na.op = OANDAND; - na.left = &nb; - na.right = &nc; - na.type = types[TBOOL]; - - memset(&nb, 0, sizeof(nb)); - nb.op = OEQ; - nb.left = &n1; - nb.right = &n3; - nb.type = types[TBOOL]; - - memset(&nc, 0, sizeof(nc)); - nc.op = OEQ; - nc.left = &n2; - nc.right = &n4; - nc.type = types[TBOOL]; - - if(op == ONE) - true = !true; - - thearch.bgen(&na, true, likely, to); -} - -void -nodfconst(Node *n, Type *t, Mpflt* fval) -{ - memset(n, 0, sizeof(*n)); - n->op = OLITERAL; - n->addable = 1; - ullmancalc(n); - n->val.u.fval = fval; - n->val.ctype = CTFLT; - n->type = t; - - if(!isfloat[t->etype]) - fatal("nodfconst: bad type %T", t); -} - -// break addable nc-complex into nr-real and ni-imaginary -static void -subnode(Node *nr, Node *ni, Node *nc) -{ - int tc; - Type *t; - - if(!nc->addable) - fatal("subnode not addable"); - - tc = simsimtype(nc->type); - tc = cplxsubtype(tc); - t = types[tc]; - - if(nc->op == OLITERAL) { - nodfconst(nr, t, &nc->val.u.cval->real); - nodfconst(ni, t, &nc->val.u.cval->imag); - return; - } - - *nr = *nc; - nr->type = t; - - *ni = *nc; - ni->type = t; - ni->xoffset += t->width; -} - -// generate code res = -nl -static void -minus(Node *nl, Node *res) -{ - Node ra; - - memset(&ra, 0, sizeof(ra)); - ra.op = OMINUS; - ra.left = nl; - ra.type = nl->type; - thearch.cgen(&ra, res); -} - -// build and execute tree -// real(res) = -real(nl) -// imag(res) = -imag(nl) -void -complexminus(Node *nl, Node *res) -{ - Node n1, n2, n5, n6; - - subnode(&n1, &n2, nl); - subnode(&n5, &n6, res); - - minus(&n1, &n5); - minus(&n2, &n6); -} - - -// build and execute tree -// real(res) = real(nl) op real(nr) -// imag(res) = imag(nl) op imag(nr) -void -complexadd(int op, Node *nl, Node *nr, Node *res) -{ - Node n1, n2, n3, n4, n5, n6; - Node ra; - - subnode(&n1, &n2, nl); - subnode(&n3, &n4, nr); - subnode(&n5, &n6, res); - - memset(&ra, 0, sizeof(ra)); - ra.op = op; - ra.left = &n1; - ra.right = &n3; - ra.type = n1.type; - thearch.cgen(&ra, &n5); - - memset(&ra, 0, sizeof(ra)); - ra.op = op; - ra.left = &n2; - ra.right = &n4; - ra.type = n2.type; - thearch.cgen(&ra, &n6); -} - -// build and execute tree -// tmp = real(nl)*real(nr) - imag(nl)*imag(nr) -// imag(res) = real(nl)*imag(nr) + imag(nl)*real(nr) -// real(res) = tmp -void -complexmul(Node *nl, Node *nr, Node *res) -{ - Node n1, n2, n3, n4, n5, n6; - Node rm1, rm2, ra, tmp; - - subnode(&n1, &n2, nl); - subnode(&n3, &n4, nr); - subnode(&n5, &n6, res); - tempname(&tmp, n5.type); - - // real part -> tmp - memset(&rm1, 0, sizeof(rm1)); - rm1.op = OMUL; - rm1.left = &n1; - rm1.right = &n3; - rm1.type = n1.type; - - memset(&rm2, 0, sizeof(rm2)); - rm2.op = OMUL; - rm2.left = &n2; - rm2.right = &n4; - rm2.type = n2.type; - - memset(&ra, 0, sizeof(ra)); - ra.op = OSUB; - ra.left = &rm1; - ra.right = &rm2; - ra.type = rm1.type; - thearch.cgen(&ra, &tmp); - - // imag part - memset(&rm1, 0, sizeof(rm1)); - rm1.op = OMUL; - rm1.left = &n1; - rm1.right = &n4; - rm1.type = n1.type; - - memset(&rm2, 0, sizeof(rm2)); - rm2.op = OMUL; - rm2.left = &n2; - rm2.right = &n3; - rm2.type = n2.type; - - memset(&ra, 0, sizeof(ra)); - ra.op = OADD; - ra.left = &rm1; - ra.right = &rm2; - ra.type = rm1.type; - thearch.cgen(&ra, &n6); - - // tmp ->real part - thearch.cgen(&tmp, &n5); -} |