aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/gc/cplx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/cplx.c')
-rw-r--r--src/cmd/gc/cplx.c494
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);
-}