]> Cypherpunks repositories - gostls13.git/commitdiff
complex constant multiply and divide
authorKen Thompson <ken@golang.org>
Fri, 19 Feb 2010 01:55:11 +0000 (17:55 -0800)
committerKen Thompson <ken@golang.org>
Fri, 19 Feb 2010 01:55:11 +0000 (17:55 -0800)
R=rsc
CC=golang-dev
https://golang.org/cl/217041

src/cmd/gc/builtin.c.boot
src/cmd/gc/const.c
src/cmd/gc/runtime.go
src/cmd/gc/typecheck.c
src/cmd/gc/walk.c

index 1d881c9d8ea6cdbf895ee2b64945592d2ec0b69b..6eed40230d4fc9f0821f43497c21f64a0b2f73d5 100644 (file)
@@ -9,6 +9,7 @@ char *runtimeimport =
        "func \"\".printfloat (? float64)\n"
        "func \"\".printint (? int64)\n"
        "func \"\".printuint (? uint64)\n"
+       "func \"\".printcomplex (? complex128)\n"
        "func \"\".printstring (? string)\n"
        "func \"\".printpointer (? any)\n"
        "func \"\".printiface (? any)\n"
index 1727e775a2b5ee4fac0d719241ca68dfc05e77c1..f16c52d58cf92cc389da9a374df3c4b47dd4bf2f 100644 (file)
@@ -5,10 +5,12 @@
 #include       "go.h"
 #define        TUP(x,y)        (((x)<<16)|(y))
 
-static Val tocplx(Val);
-static Val toflt(Val);
-static Val tostr(Val);
-static Val copyval(Val);
+static Val     tocplx(Val);
+static Val     toflt(Val);
+static Val     tostr(Val);
+static Val     copyval(Val);
+static void    cmplxmpy(Mpcplx *v, Mpcplx *rv);
+static void    cmplxdiv(Mpcplx *v, Mpcplx *rv);
 
 /*
  * truncate float literal fv to 32-bit or 64-bit precision
@@ -614,9 +616,10 @@ evconst(Node *n)
                mpsubfltflt(&v.u.cval->imag, &rv.u.cval->imag);
                break;
        case TUP(OMUL, CTCPLX):
-               goto illegal;   // TODO
+               cmplxmpy(v.u.cval, rv.u.cval);
+               break;
        case TUP(ODIV, CTCPLX):
-               goto illegal;   // TODO
+               cmplxdiv(v.u.cval, rv.u.cval);
                break;
 
        case TUP(OEQ, CTNIL):
@@ -793,6 +796,13 @@ unary:
                mpnegflt(v.u.fval);
                break;
 
+       case TUP(OPLUS, CTCPLX):
+               break;
+       case TUP(OMINUS, CTCPLX):
+               mpnegflt(&v.u.cval->real);
+               mpnegflt(&v.u.cval->imag);
+               break;
+
        case TUP(ONOT, CTBOOL):
                if(!v.u.bval)
                        goto settrue;
@@ -1187,3 +1197,65 @@ convconst(Node *con, Type *t, Val *val)
        fatal("convconst %lT constant", t);
 
 }
+
+// complex multiply v *= rv
+//     (a, b) * (c, d) = (a*c - b*d, b*c + a*d)
+static void
+cmplxmpy(Mpcplx *v, Mpcplx *rv)
+{
+       Mpflt ac, bd, bc, ad;
+
+       mpmovefltflt(&ac, &v->real);
+       mpmulfltflt(&ac, &rv->real);    // ac
+
+       mpmovefltflt(&bd, &v->imag);
+       mpmulfltflt(&bd, &rv->imag);    // bd
+
+       mpmovefltflt(&bc, &v->imag);
+       mpmulfltflt(&bc, &rv->real);    // bc
+
+       mpmovefltflt(&ad, &v->real);
+       mpmulfltflt(&ad, &rv->imag);    // ad
+
+       mpmovefltflt(&v->real, &ac);
+       mpsubfltflt(&v->real, &bd);     // ac-bd
+
+       mpmovefltflt(&v->imag, &bc);
+       mpaddfltflt(&v->imag, &ad);     // bc+ad
+}
+
+// complex divide v /= rv
+//     (a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d)
+static void
+cmplxdiv(Mpcplx *v, Mpcplx *rv)
+{
+       Mpflt ac, bd, bc, ad, cc_plus_dd;
+
+       mpmovefltflt(&cc_plus_dd, &rv->real);
+       mpmulfltflt(&cc_plus_dd, &rv->real);    // cc
+
+       mpmovefltflt(&ac, &rv->imag);
+       mpmulfltflt(&ac, &rv->imag);            // dd
+
+       mpaddfltflt(&cc_plus_dd, &ac);          // cc+dd
+
+       mpmovefltflt(&ac, &v->real);
+       mpmulfltflt(&ac, &rv->real);            // ac
+
+       mpmovefltflt(&bd, &v->imag);
+       mpmulfltflt(&bd, &rv->imag);            // bd
+
+       mpmovefltflt(&bc, &v->imag);
+       mpmulfltflt(&bc, &rv->real);            // bc
+
+       mpmovefltflt(&ad, &v->real);
+       mpmulfltflt(&ad, &rv->imag);            // ad
+
+       mpmovefltflt(&v->real, &ac);
+       mpaddfltflt(&v->real, &bd);             // ac+bd
+       mpdivfltflt(&v->real, &cc_plus_dd);     // (ac+bd)/(cc+dd)
+
+       mpmovefltflt(&v->imag, &bc);
+       mpsubfltflt(&v->imag, &ad);             // bc-ad
+       mpdivfltflt(&v->imag, &cc_plus_dd);     // (bc+ad)/(cc+dd)
+}
index 4b9b97136b3b9797fca66f77aed52cd4637c403a..e350c282dd08d7574aeb04878b9a20a66b8cf7c8 100644 (file)
@@ -20,6 +20,7 @@ func printbool(bool)
 func printfloat(float64)
 func printint(int64)
 func printuint(uint64)
+func printcomplex(complex128)
 func printstring(string)
 func printpointer(any)
 func printiface(any)
index d36775b02854828cd1bf0577871bb625986802ca..9804220d1d48d9d84c93fdf9ab6ddc4eaadb6b24 100644 (file)
@@ -1370,6 +1370,10 @@ checkconv(Type *nt, Type *t, int explicit, int *op, int *et, char *desc)
        if(isint[nt->etype] || isfloat[nt->etype])
                return 1;
 
+       // between versions of complex
+       if(iscomplex[t->etype] || iscomplex[nt->etype])
+               return 1;
+
        // to string
        if(istype(t, TSTRING)) {
                // integer rune
index e528e3f6c000319b26591f0a0f7961868261fcbc..e28cf288fc1d898d20d786cca440360820fc8b29 100644 (file)
@@ -794,11 +794,13 @@ walkexpr(Node **np, NodeList **init)
        case OCONV:
        case OCONVNOP:
                if(thechar == '5') {
-                       if(isfloat[n->left->type->etype] && (n->type->etype == TINT64 || n->type->etype == TUINT64)) {
+                       if(isfloat[n->left->type->etype] &&
+                          (n->type->etype == TINT64 || n->type->etype == TUINT64)) {
                                n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
                                goto ret;
                        }
-                       if((n->left->type->etype == TINT64 || n->left->type->etype == TUINT64) && isfloat[n->type->etype]) {
+                       if((n->left->type->etype == TINT64 || n->left->type->etype == TUINT64) &&
+                          isfloat[n->type->etype]) {
                                n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64]));
                                goto ret;
                        }
@@ -1727,7 +1729,7 @@ walkprint(Node *nn, NodeList **init, int defer)
                } else if(iscomplex[et]) {
                        if(defer) {
                                fmtprint(&fmt, "%%f");
-                               t = types[TFLOAT64];
+                               t = types[TCOMPLEX128];
                        } else
                                on = syslook("printcomplex", 0);
                } else if(et == TBOOL) {
@@ -2036,8 +2038,10 @@ convas(Node *n, NodeList **init)
        if(lt == T || rt == T)
                goto out;
 
-       if(isblank(n->left))
+       if(isblank(n->left)) {
+               defaultlit(&n->right, T);
                goto out;
+       }
 
        if(n->left->op == OINDEXMAP) {
                n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init,