]> Cypherpunks repositories - gostls13.git/commitdiff
mp constants
authorKen Thompson <ken@golang.org>
Sat, 9 Aug 2008 00:13:31 +0000 (17:13 -0700)
committerKen Thompson <ken@golang.org>
Sat, 9 Aug 2008 00:13:31 +0000 (17:13 -0700)
R=r
DELTA=381  (142 added, 26 deleted, 213 changed)
OCL=14011
CL=14016

12 files changed:
src/cmd/6g/cgen.c
src/cmd/6g/gen.c
src/cmd/6g/gsubr.c
src/cmd/6g/obj.c
src/cmd/gc/Makefile
src/cmd/gc/const.c
src/cmd/gc/export.c
src/cmd/gc/go.h
src/cmd/gc/go.y
src/cmd/gc/lex.c
src/cmd/gc/subr.c
src/cmd/gc/walk.c

index 412d3fa09b0cfacd949b12f958293fd4c90f11aa..7b054dfb3f543a3bc7dcf7a9d13756411e85d9e7 100644 (file)
@@ -454,7 +454,8 @@ bgen(Node *n, int true, Prog *to)
                goto ret;
 
        case OLITERAL:
-               if(!true == !n->val.vval)
+// need to ask if it is bool?
+               if(!true == !n->val.u.bval)
                        patch(gbranch(AJMP, T), to);
                goto ret;
 
index c0d2b9df6cd99392dfe77a829f8de828e7c7fecf..e15a9e20acd5814f928cc1315fcff16757733e56 100644 (file)
@@ -312,7 +312,7 @@ agen_inter(Node *n, Node *res)
        // stack offset
        memset(&nodo, 0, sizeof(nodo));
        nodo.op = OINDREG;
-       nodo.val.vval = D_SP;
+       nodo.val.u.reg = D_SP;
        nodo.addable = 1;
        nodo.type = types[tptr];
 
@@ -745,7 +745,7 @@ cgen_callret(Node *n, Node *res)
 
        memset(&nod, 0, sizeof(nod));
        nod.op = OINDREG;
-       nod.val.vval = D_SP;
+       nod.val.u.reg = D_SP;
        nod.addable = 1;
 
        nod.xoffset = fp->width;
@@ -770,7 +770,7 @@ cgen_aret(Node *n, Node *res)
 
        memset(&nod1, 0, sizeof(nod1));
        nod1.op = OINDREG;
-       nod1.val.vval = D_SP;
+       nod1.val.u.reg = D_SP;
        nod1.addable = 1;
 
        nod1.xoffset = fp->width;
@@ -894,31 +894,32 @@ cgen_as(Node *nl, Node *nr, int op)
                case TUINT32:
                case TINT64:
                case TUINT64:
+                       nr->val.u.xval = mal(sizeof(*nr->val.u.xval));
+                       mpmovecfix(nr->val.u.xval, 0);
                        nr->val.ctype = CTINT;
-                       nr->val.vval = 0;
                        break;
 
                case TFLOAT32:
                case TFLOAT64:
                case TFLOAT80:
+                       nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
+                       mpmovecflt(nr->val.u.fval, 0.0);
                        nr->val.ctype = CTFLT;
-                       nr->val.dval = 0.0;
                        break;
 
                case TBOOL:
+                       nr->val.u.bval = 0;
                        nr->val.ctype = CTBOOL;
-                       nr->val.vval = 0;
                        break;
 
                case TPTR32:
                case TPTR64:
                        if(isptrto(tl, TSTRING)) {
-                               nr->val.sval = mal(8);
+                               nr->val.u.sval = mal(8);
                                nr->val.ctype = CTSTR;
                                break;
                        }
                        nr->val.ctype = CTNIL;
-                       nr->val.vval = 0;
                        break;
 
 //             case TINTER:
@@ -954,7 +955,7 @@ samereg(Node *a, Node *b)
                return 0;
        if(b->op != OREGISTER)
                return 0;
-       if(a->val.vval != b->val.vval)
+       if(a->val.u.reg != b->val.u.reg)
                return 0;
        return 1;
 }
index 7a08556393baf2b610c6d04722937556bb53a64b..ba12c77515dbf06498b5850324fa125a56a55b2d 100644 (file)
@@ -151,7 +151,7 @@ regalloc(Node *n, Type *t, Node *o)
        case TPTR64:
        case TBOOL:
                if(o != N && o->op == OREGISTER) {
-                       i = o->val.vval;
+                       i = o->val.u.reg;
                        if(i >= D_AX && i <= D_R15)
                                goto out;
                }
@@ -166,7 +166,7 @@ regalloc(Node *n, Type *t, Node *o)
        case TFLOAT64:
        case TFLOAT80:
                if(o != N && o->op == OREGISTER) {
-                       i = o->val.vval;
+                       i = o->val.u.reg;
                        if(i >= D_X0 && i <= D_X7)
                                goto out;
                }
@@ -194,7 +194,7 @@ regfree(Node *n)
 
        if(n->op != OREGISTER && n->op != OINDREG)
                fatal("regfree: not a register");
-       i = n->val.vval;
+       i = n->val.u.reg;
        if(i < 0 || i >= sizeof(reg))
                fatal("regfree: reg out of range");
        if(reg[i] <= 0)
@@ -220,7 +220,7 @@ nodreg(Node *n, Type *t, int r)
        n->op = OREGISTER;
        n->addable = 1;
        ullmancalc(n);
-       n->val.vval = r;
+       n->val.u.reg = r;
        n->type = t;
 }
 
@@ -248,7 +248,7 @@ nodarg(Type *t, int fp)
        switch(fp) {
        case 0:         // output arg
                n->op = OINDREG;
-               n->val.vval = D_SP;
+               n->val.u.reg = D_SP;
                break;
 
        case 1:         // input arg
@@ -258,7 +258,7 @@ nodarg(Type *t, int fp)
        case 2:         // offset output arg
 fatal("shpuldnt be used");
                n->op = OINDREG;
-               n->val.vval = D_SP;
+               n->val.u.reg = D_SP;
                n->xoffset += types[tptr]->width;
                break;
        }
@@ -272,7 +272,8 @@ nodconst(Node *n, Type *t, vlong v)
        n->op = OLITERAL;
        n->addable = 1;
        ullmancalc(n);
-       n->val.vval = v;
+       n->val.u.xval = mal(sizeof(*n->val.u.xval));
+       mpmovecfix(n->val.u.xval, v);
        n->val.ctype = CTINT;
        n->type = t;
 
@@ -373,7 +374,7 @@ gmove(Node *f, Node *t)
                        f->op, ft, t->op, tt);
        if(isfloat[ft] && f->op == OCONST) {
                /* TO DO: pick up special constants, possibly preloaded */
-               if(f->val.dval == 0.0){
+               if(mpgetflt(f->val.u.fval) == 0.0) {
                        regalloc(&nod, t->type, t);
                        gins(AXORPD, &nod, &nod);
                        gmove(&nod, t);
@@ -582,22 +583,22 @@ gmove(Node *f, Node *t)
        case CASE(TINT32, TINT64):
        case CASE(TINT32, TPTR64):
                a = AMOVLQSX;
-               if(f->op == OCONST) {
-                       f->val.vval &= (uvlong)0xffffffffU;
-                       if(f->val.vval & 0x80000000)
-                               f->val.vval |= (vlong)0xffffffff << 32;
-                       a = AMOVQ;
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= (uvlong)0xffffffffU;
+//                     if(f->val.vval & 0x80000000)
+//                             f->val.vval |= (vlong)0xffffffff << 32;
+//                     a = AMOVQ;
+//             }
                break;
 
        case CASE(TUINT32, TINT64):
        case CASE(TUINT32, TUINT64):
        case CASE(TUINT32, TPTR64):
                a = AMOVL;      /* same effect as AMOVLQZX */
-               if(f->op == OCONST) {
-                       f->val.vval &= (uvlong)0xffffffffU;
-                       a = AMOVQ;
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= (uvlong)0xffffffffU;
+//                     a = AMOVQ;
+//             }
                break;
 
        case CASE(TPTR64, TINT64):
@@ -615,45 +616,45 @@ gmove(Node *f, Node *t)
        case CASE(TINT16, TINT32):
        case CASE(TINT16, TUINT32):
                a = AMOVWLSX;
-               if(f->op == OCONST) {
-                       f->val.vval &= 0xffff;
-                       if(f->val.vval & 0x8000)
-                               f->val.vval |= 0xffff0000;
-                       a = AMOVL;
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= 0xffff;
+//                     if(f->val.vval & 0x8000)
+//                             f->val.vval |= 0xffff0000;
+//                     a = AMOVL;
+//             }
                break;
 
        case CASE(TINT16, TINT64):
        case CASE(TINT16, TUINT64):
        case CASE(TINT16, TPTR64):
                a = AMOVWQSX;
-               if(f->op == OCONST) {
-                       f->val.vval &= 0xffff;
-                       if(f->val.vval & 0x8000){
-                               f->val.vval |= 0xffff0000;
-                               f->val.vval |= (vlong)~0 << 32;
-                       }
-                       a = AMOVL;
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= 0xffff;
+//                     if(f->val.vval & 0x8000){
+//                             f->val.vval |= 0xffff0000;
+//                             f->val.vval |= (vlong)~0 << 32;
+//                     }
+//                     a = AMOVL;
+//             }
                break;
 
        case CASE(TUINT16, TINT32):
        case CASE(TUINT16, TUINT32):
                a = AMOVWLZX;
-               if(f->op == OCONST) {
-                       f->val.vval &= 0xffff;
-                       a = AMOVL;
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= 0xffff;
+//                     a = AMOVL;
+//             }
                break;
 
        case CASE(TUINT16, TINT64):
        case CASE(TUINT16, TUINT64):
        case CASE(TUINT16, TPTR64):
                a = AMOVWQZX;
-               if(f->op == OCONST) {
-                       f->val.vval &= 0xffff;
-                       a = AMOVL;      /* MOVL also zero-extends to 64 bits */
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= 0xffff;
+//                     a = AMOVL;      /* MOVL also zero-extends to 64 bits */
+//             }
                break;
 
        case CASE(TINT8, TINT16):
@@ -661,26 +662,26 @@ gmove(Node *f, Node *t)
        case CASE(TINT8, TINT32):
        case CASE(TINT8, TUINT32):
                a = AMOVBLSX;
-               if(f->op == OCONST) {
-                       f->val.vval &= 0xff;
-                       if(f->val.vval & 0x80)
-                               f->val.vval |= 0xffffff00;
-                       a = AMOVL;
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= 0xff;
+//                     if(f->val.vval & 0x80)
+//                             f->val.vval |= 0xffffff00;
+//                     a = AMOVL;
+//             }
                break;
 
        case CASE(TINT8, TINT64):
        case CASE(TINT8, TUINT64):
        case CASE(TINT8, TPTR64):
                a = AMOVBQSX;
-               if(f->op == OCONST) {
-                       f->val.vval &= 0xff;
-                       if(f->val.vval & 0x80){
-                               f->val.vval |= 0xffffff00;
-                               f->val.vval |= (vlong)~0 << 32;
-                       }
-                       a = AMOVQ;
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= 0xff;
+//                     if(f->val.vval & 0x80){
+//                             f->val.vval |= 0xffffff00;
+//                             f->val.vval |= (vlong)~0 << 32;
+//                     }
+//                     a = AMOVQ;
+//             }
                break;
 
        case CASE(TBOOL, TINT16):
@@ -692,10 +693,10 @@ gmove(Node *f, Node *t)
        case CASE(TUINT8, TINT32):
        case CASE(TUINT8, TUINT32):
                a = AMOVBLZX;
-               if(f->op == OCONST) {
-                       f->val.vval &= 0xff;
-                       a = AMOVL;
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= 0xff;
+//                     a = AMOVL;
+//             }
                break;
 
        case CASE(TBOOL, TINT64):
@@ -705,10 +706,10 @@ gmove(Node *f, Node *t)
        case CASE(TUINT8, TUINT64):
        case CASE(TUINT8, TPTR64):
                a = AMOVBQZX;
-               if(f->op == OCONST) {
-                       f->val.vval &= 0xff;
-                       a = AMOVL;      /* zero-extends to 64-bits */
-               }
+//             if(f->op == OCONST) {
+//                     f->val.vval &= 0xff;
+//                     a = AMOVL;      /* zero-extends to 64-bits */
+//             }
                break;
 
 /*
@@ -961,7 +962,7 @@ samaddr(Node *f, Node *t)
 
        switch(f->op) {
        case OREGISTER:
-               if(f->val.vval != t->val.vval)
+               if(f->val.u.reg != t->val.u.reg)
                        break;
                return 1;
        }
@@ -1016,7 +1017,7 @@ naddr(Node *n, Addr *a)
                break;
 
        case OREGISTER:
-               a->type = n->val.vval;
+               a->type = n->val.u.reg;
                a->sym = S;
                break;
 
@@ -1041,7 +1042,7 @@ naddr(Node *n, Addr *a)
 //             break;
 
        case OINDREG:
-               a->type = n->val.vval+D_INDIR;
+               a->type = n->val.u.reg+D_INDIR;
                a->sym = n->sym;
                a->offset = n->xoffset;
                break;
@@ -1078,12 +1079,22 @@ naddr(Node *n, Addr *a)
                break;
 
        case OLITERAL:
-               if(isfloat[n->type->etype]) {
+               switch(n->val.ctype) {
+               default:
+                       fatal("naddr: const %lT", n->type);
+                       break;
+               case CTFLT:
                        a->type = D_FCONST;
-                       a->dval = n->val.dval;
+                       a->dval = mpgetflt(n->val.u.fval);
                        break;
-               }
-               if(isptrto(n->type, TSTRING)) {
+               case CTINT:
+               case CTSINT:
+               case CTUINT:
+                       a->sym = S;
+                       a->type = D_CONST;
+                       a->offset = mpgetfix(n->val.u.xval);
+                       break;
+               case CTSTR:
                        a->etype = n->etype;
                        a->sym = symstringo;
                        a->type = D_ADDR;
@@ -1091,16 +1102,17 @@ naddr(Node *n, Addr *a)
                        a->offset = symstringo->offset;
                        stringpool(n);
                        break;
-               }
-               if(isint[n->type->etype] ||
-                  isptr[n->type->etype] ||
-                  n->type->etype == TBOOL) {
+               case CTBOOL:
+                       a->sym = S;
+                       a->type = D_CONST;
+                       a->offset = n->val.u.bval;
+                       break;
+               case CTNIL:
                        a->sym = S;
                        a->type = D_CONST;
-                       a->offset = n->val.vval;
+                       a->offset = 0;
                        break;
                }
-               fatal("naddr: const %lT", n->type);
                break;
 
        case OADDR:
@@ -1699,7 +1711,7 @@ stringpool(Node *n)
 
        p = mal(sizeof(*p));
 
-       p->sval = n->val.sval;
+       p->sval = n->val.u.sval;
        p->link = nil;
 
        if(poolist == nil)
index a915f11326c7bf4cea990f2f9fb7962755f64c51..709ece3c3809a79fcb6c37b7ea2110791d8ef202 100644 (file)
@@ -74,7 +74,7 @@ dumpobj(void)
                        continue;
 
                dowidth(n->type);
-               n1.val.vval = n->type->width;
+               mpmovecfix(n1.val.u.xval, n->type->width);
 
                p = pc;
                gins(AGLOBL, s->oname, &n1);
index d5db24fe2f16e4005544e9d2a68c0438c487caf9..e3adaef769cab391a87608cfca6c345bbe9b6912 100644 (file)
@@ -22,7 +22,7 @@ OFILES=\
        export.$O\
        walk.$O\
        const.$O\
-       mpatof.$O\
+       mparith.$O\
        sysimport.$O\
        compat.$O\
 
index 2ee03c98a582b99bbaae971cce23bb5c175f5985..fff0e0c4a356876056eacb39d6e25687c36714f8 100644 (file)
@@ -23,7 +23,7 @@ convlit(Node *n, Type *t)
                if(!isptr[et] && et != TINTER)
                        goto bad1;
                if(isptrto(t, TSTRING)) {
-                       n->val.sval = mal(8);
+                       n->val.u.sval = mal(8);
                        n->val.ctype = CTSTR;
                }
                break;
@@ -44,29 +44,31 @@ convlit(Node *n, Type *t)
                        int l;
                        String *s;
 
-                       rune = n->val.vval;
+                       rune = mpgetfix(n->val.u.xval);
                        l = runelen(rune);
                        s = mal(sizeof(*s)+l);
                        s->len = l;
                        runetochar((char*)(s->s), &rune);
 
-                       n->val.sval = s;
+                       n->val.u.sval = s;
                        n->val.ctype = CTSTR;
                        break;
                }
                if(isint[et]) {
-                       if(n->val.vval < minintval[et])
+                       // int to int
+                       if(mpcmpfixfix(n->val.u.xval, minintval[et]) < 0)
                                goto bad2;
-                       if(n->val.vval > maxintval[et])
+                       if(mpcmpfixfix(n->val.u.xval, maxintval[et]) > 0)
                                goto bad2;
                        break;
                }
                if(isfloat[et]) {
-                       if(n->val.vval < minfloatval[et])
+                       // int to float
+                       if(mpcmpfltflt(n->val.u.fval, minfltval[et]) < 0)
                                goto bad2;
-                       if(n->val.vval > maxfloatval[et])
+                       if(mpcmpfltflt(n->val.u.fval, maxfltval[et]) > 0)
                                goto bad2;
-                       n->val.dval = n->val.vval;
+                       mpmovefixflt(n->val.u.fval, n->val.u.xval);
                        n->val.ctype = CTFLT;
                        break;
                }
@@ -74,18 +76,20 @@ convlit(Node *n, Type *t)
 
        case Wlitfloat:
                if(isint[et]) {
-                       if(n->val.dval < minintval[et])
+                       // float to int
+                       if(mpcmpfixfix(n->val.u.xval, minintval[et]) < 0)
                                goto bad2;
-                       if(n->val.dval > maxintval[et])
+                       if(mpcmpfixfix(n->val.u.xval, maxintval[et]) > 0)
                                goto bad2;
-                       n->val.vval = n->val.dval;
+                       mpmovefltfix(n->val.u.xval, n->val.u.fval);
                        n->val.ctype = CTINT;
                        break;
                }
                if(isfloat[et]) {
-                       if(n->val.dval < minfloatval[et])
+                       // float to float
+                       if(mpcmpfltflt(n->val.u.fval, minfltval[et]) < 0)
                                goto bad2;
-                       if(n->val.dval > maxfloatval[et])
+                       if(mpcmpfltflt(n->val.u.fval, maxfltval[et]) > 0)
                                goto bad2;
                        break;
                }
@@ -110,6 +114,8 @@ evconst(Node *n)
        int32 len;
        String *str;
        int wl, wr;
+       Mpint *xval;
+       Mpflt *fval;
 
        nl = n->left;
        if(nl == N)
@@ -145,120 +151,135 @@ evconst(Node *n)
 
        if(wl != wr) {
                if(wl == Wlitfloat && wr == Wlitint) {
-                       nr->val.dval = nr->val.vval;
+                       xval = nr->val.u.xval;
+                       nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
+                       mpmovefixflt(nr->val.u.fval, xval);
                        nr->val.ctype = CTFLT;
                        wr = whatis(nr);
                } else
                if(wl == Wlitint && wr == Wlitfloat) {
-                       nl->val.dval = nl->val.vval;
+                       xval = nl->val.u.xval;
+                       nl->val.u.fval = mal(sizeof(*nl->val.u.fval));
+                       mpmovefixflt(nl->val.u.fval, xval);
                        nl->val.ctype = CTFLT;
                        wl = whatis(nl);
                } else {
-                       yyerror("illegal combination of literals %d %d", nl->etype, nr->etype);
+                       yyerror("illegal combination of literals %E %E", nl->etype, nr->etype);
                        return;
                }
        }
 
+       // dance to not modify left side
+       // this is because iota will reuse it
+       if(wl == Wlitint) {
+               xval = mal(sizeof(*xval));
+               mpmovefixfix(xval, nl->val.u.xval);
+       } else
+       if(wl == Wlitfloat) {
+               fval = mal(sizeof(*fval));
+               mpmovefltflt(fval, nl->val.u.fval);
+       }
+
        switch(TUP(n->op, wl)) {
        default:
-               yyerror("illegal combination of literals %O %d", n->op, wl);
+               yyerror("illegal combination of literals %O %E", n->op, nl->etype);
                return;
 
        case TUP(OADD, Wlitint):
-               nl->val.vval += nr->val.vval;
+               mpaddfixfix(xval, nr->val.u.xval);
                break;
        case TUP(OSUB, Wlitint):
-               nl->val.vval -= nr->val.vval;
+               mpsubfixfix(xval, nr->val.u.xval);
                break;
        case TUP(OMUL, Wlitint):
-               nl->val.vval *= nr->val.vval;
+               mpmulfixfix(xval, nr->val.u.xval);
                break;
        case TUP(ODIV, Wlitint):
-               nl->val.vval /= nr->val.vval;
+               mpdivfixfix(xval, nr->val.u.xval);
                break;
        case TUP(OMOD, Wlitint):
-               nl->val.vval %= nr->val.vval;
+               mpmodfixfix(xval, nr->val.u.xval);
                break;
+
        case TUP(OLSH, Wlitint):
-               nl->val.vval <<= nr->val.vval;
+               mplshfixfix(xval, nr->val.u.xval);
                break;
        case TUP(ORSH, Wlitint):
-               nl->val.vval >>= nr->val.vval;
+               mprshfixfix(xval, nr->val.u.xval);
                break;
        case TUP(OOR, Wlitint):
-               nl->val.vval |= nr->val.vval;
+               mporfixfix(xval, nr->val.u.xval);
                break;
        case TUP(OAND, Wlitint):
-               nl->val.vval &= nr->val.vval;
+               mpandfixfix(xval, nr->val.u.xval);
                break;
        case TUP(OXOR, Wlitint):
-               nl->val.vval ^= nr->val.vval;
+               mpxorfixfix(xval, nr->val.u.xval);
                break;
 
        case TUP(OADD, Wlitfloat):
-               nl->val.dval += nr->val.dval;
+               mpaddfltflt(fval, nr->val.u.fval);
                break;
        case TUP(OSUB, Wlitfloat):
-               nl->val.dval -= nr->val.dval;
+               mpsubfltflt(fval, nr->val.u.fval);
                break;
        case TUP(OMUL, Wlitfloat):
-               nl->val.dval *= nr->val.dval;
+               mpmulfltflt(fval, nr->val.u.fval);
                break;
        case TUP(ODIV, Wlitfloat):
-               nl->val.dval /= nr->val.dval;
+               mpdivfltflt(fval, nr->val.u.fval);
                break;
 
        case TUP(OEQ, Wlitint):
-               if(nl->val.vval == nr->val.vval)
+               if(mpcmpfixfix(xval, nr->val.u.xval) == 0)
                        goto settrue;
                goto setfalse;
        case TUP(ONE, Wlitint):
-               if(nl->val.vval != nr->val.vval)
+               if(mpcmpfixfix(xval, nr->val.u.xval) != 0)
                        goto settrue;
                goto setfalse;
        case TUP(OLT, Wlitint):
-               if(nl->val.vval < nr->val.vval)
+               if(mpcmpfixfix(xval, nr->val.u.xval) < 0)
                        goto settrue;
                goto setfalse;
        case TUP(OLE, Wlitint):
-               if(nl->val.vval <= nr->val.vval)
+               if(mpcmpfixfix(xval, nr->val.u.xval) <= 0)
                        goto settrue;
                goto setfalse;
        case TUP(OGE, Wlitint):
-               if(nl->val.vval >= nr->val.vval)
+               if(mpcmpfixfix(xval, nr->val.u.xval) >= 0)
                        goto settrue;
                goto setfalse;
        case TUP(OGT, Wlitint):
-               if(nl->val.vval > nr->val.vval)
+               if(mpcmpfixfix(xval, nr->val.u.xval) > 0)
                        goto settrue;
                goto setfalse;
 
        case TUP(OEQ, Wlitfloat):
-               if(nl->val.dval == nr->val.dval)
+               if(mpcmpfltflt(fval, nr->val.u.fval) == 0)
                        goto settrue;
                goto setfalse;
        case TUP(ONE, Wlitfloat):
-               if(nl->val.dval != nr->val.dval)
+               if(mpcmpfltflt(fval, nr->val.u.fval) != 0)
                        goto settrue;
                goto setfalse;
        case TUP(OLT, Wlitfloat):
-               if(nl->val.dval < nr->val.dval)
+               if(mpcmpfltflt(fval, nr->val.u.fval) < 0)
                        goto settrue;
                goto setfalse;
        case TUP(OLE, Wlitfloat):
-               if(nl->val.dval <= nr->val.dval)
+               if(mpcmpfltflt(fval, nr->val.u.fval) <= 0)
                        goto settrue;
                goto setfalse;
        case TUP(OGE, Wlitfloat):
-               if(nl->val.dval >= nr->val.dval)
+               if(mpcmpfltflt(fval, nr->val.u.fval) >= 0)
                        goto settrue;
                goto setfalse;
        case TUP(OGT, Wlitfloat):
-               if(nl->val.dval > nr->val.dval)
+               if(mpcmpfltflt(fval, nr->val.u.fval) > 0)
                        goto settrue;
                goto setfalse;
 
-
        case TUP(OEQ, Wlitstr):
                if(cmpslit(nl, nr) == 0)
                        goto settrue;
@@ -284,25 +305,33 @@ evconst(Node *n)
                        goto settrue;
                goto setfalse;
        case TUP(OADD, Wlitstr):
-               len = nl->val.sval->len + nr->val.sval->len;
+               len = nl->val.u.sval->len + nr->val.u.sval->len;
                str = mal(sizeof(*str) + len);
                str->len = len;
-               memcpy(str->s, nl->val.sval->s, nl->val.sval->len);
-               memcpy(str->s+nl->val.sval->len, nr->val.sval->s, nr->val.sval->len);
+               memcpy(str->s, nl->val.u.sval->s, nl->val.u.sval->len);
+               memcpy(str->s+nl->val.u.sval->len, nr->val.u.sval->s, nr->val.u.sval->len);
                str->len = len;
-               nl->val.sval = str;
+               nl->val.u.sval = str;
                break;
 
        case TUP(OOROR, Wlitbool):
-               if(nl->val.vval || nr->val.vval)
+               if(nl->val.u.bval || nr->val.u.bval)
                        goto settrue;
                goto setfalse;
        case TUP(OANDAND, Wlitbool):
-               if(nl->val.vval && nr->val.vval)
+               if(nl->val.u.bval && nr->val.u.bval)
                        goto settrue;
                goto setfalse;
        }
        *n = *nl;
+
+       // second half of dance
+       if(wl == Wlitint) {
+               n->val.u.xval = xval;
+       } else
+       if(wl == Wlitfloat) {
+               n->val.u.fval = fval;
+       }
        return;
 
 settrue:
@@ -320,24 +349,22 @@ unary:
                return;
 
        case TUP(OPLUS, Wlitint):
-               nl->val.vval = +nl->val.vval;
                break;
        case TUP(OMINUS, Wlitint):
-               nl->val.vval = -nl->val.vval;
+               mpnegfix(nl->val.u.xval);
                break;
        case TUP(OCOM, Wlitint):
-               nl->val.vval = ~nl->val.vval;
+               mpcomfix(nl->val.u.xval);
                break;
 
        case TUP(OPLUS, Wlitfloat):
-               nl->val.dval = +nl->val.dval;
                break;
        case TUP(OMINUS, Wlitfloat):
-               nl->val.dval = -nl->val.dval;
+               mpnegflt(nl->val.u.fval);
                break;
 
        case TUP(ONOT, Wlitbool):
-               if(nl->val.vval)
+               if(nl->val.u.bval)
                        goto settrue;
                goto setfalse;
        }
@@ -381,10 +408,10 @@ cmpslit(Node *l, Node *r)
        int32 l1, l2, i, m;
        char *s1, *s2;
 
-       l1 = l->val.sval->len;
-       l2 = r->val.sval->len;
-       s1 = l->val.sval->s;
-       s2 = r->val.sval->s;
+       l1 = l->val.u.sval->len;
+       l2 = r->val.u.sval->len;
+       s1 = l->val.u.sval->s;
+       s2 = r->val.u.sval->s;
 
        m = l1;
        if(l2 < m)
index 01ce962828d60326dc2a97c99b75fa066ae37b35..427f649f2c2cffe431450e1df184503ceda707aa 100644 (file)
@@ -78,14 +78,16 @@ dumpexportconst(Sym *s)
        case CTINT:
        case CTSINT:
        case CTUINT:
+               Bprint(bout, "0x%llux\n", mpgetfix(n->val.u.xval));
+               break;
        case CTBOOL:
-               Bprint(bout, "0x%llux\n", n->val.vval);
+               Bprint(bout, "0x%llux\n", n->val.u.bval);
                break;
        case CTFLT:
-               Bprint(bout, "%.17e\n", n->val.dval);
+               Bprint(bout, "%.17e\n", mpgetflt(n->val.u.fval));
                break;
        case CTSTR:
-               Bprint(bout, "\"%Z\"\n", n->val.sval);
+               Bprint(bout, "\"%Z\"\n", n->val.u.sval);
                break;
        }
 }
@@ -516,7 +518,7 @@ doimport2(Node *ss, Val *b, Node *st)
        Sym *s;
 
        t = typ(TARRAY);
-       t->bound = b->vval;
+       t->bound = mpgetfix(b->u.xval);
        s = pkglookup(st->sym->name, st->psym->name);
        t->type = s->otype;
 
@@ -542,6 +544,7 @@ doimport3(Node *ss, Node *n)
        t->outtuple = importcount(t->type->down);
        t->intuple = importcount(t->type->down->down);
 
+       dowidth(t);
        importfuncnam(t);
 
        importaddtyp(ss, t);
@@ -573,7 +576,7 @@ doimport5(Node *ss, Val *v)
        int et;
        Type *t;
 
-       et = v->vval;
+       et = mpgetfix(v->u.xval);
        if(et <= 0 || et >= nelem(types) || types[et] == T)
                fatal("doimport5: bad type index: %E", et);
 
@@ -631,7 +634,7 @@ doimport8(Node *ss, Val *v, Node *st)
        int dir;
 
        s = pkglookup(st->sym->name, st->psym->name);
-       dir = v->vval;
+       dir = mpgetfix(v->u.xval);
 
        t = typ(TCHAN);
        s = pkglookup(st->sym->name, st->psym->name);
index b775b32e1803943847f9a02246d74af05ed35795..636856e19902794c822974f029ac2e13765825c9 100644 (file)
@@ -6,7 +6,6 @@
 todo:
        1. dyn arrays
        2. multi
-       3. block 0
 tothinkabout:
        2. argument in import
 */
@@ -56,13 +55,46 @@ struct      String
        char    s[3];   // variable
 };
 
+enum
+{
+       Mpscale = 29,           /* safely smaller than bits in a long */
+       Mpprec  = 10,           /* Mpscale*Mpprec is max number of bits */
+       Mpbase  = 1L<<Mpscale,
+       Mpsign  = Mpbase >> 1,
+       Mpmask  = Mpbase -1,
+       Debug   = 1,
+};
+
+typedef        struct  Mpint   Mpint;
+struct Mpint
+{
+       vlong   val;
+       long    a[Mpprec];
+       uchar   neg;
+       uchar   ovf;
+};
+
+typedef        struct  Mpflt   Mpflt;
+struct Mpflt
+{
+       double  val;
+       long    a[Mpprec];
+       uchar   neg;
+       uchar   ovf;
+};
+
 typedef        struct  Val     Val;
 struct Val
 {
-       int     ctype;
-       double  dval;
-       vlong   vval;
-       String* sval;
+       short   ctype;
+       union
+       {
+               short   reg;            // OREGISTER
+               short   bval;           // bool value CTBOOL
+               Mpint*  xval;           // int CTINT
+               Mpflt*  fval;           // float CTFLT
+               String* sval;           // string CTSTR
+       } u;
 };
 
 typedef        struct  Sym     Sym;
@@ -135,7 +167,7 @@ struct      Node
        // func
        Node*   nname;
 
-       // OLITERAL
+       // OLITERAL/OREGISTER
        Val     val;
 
        Sym*    osym;           // import
@@ -380,10 +412,11 @@ EXTERN    uchar   issimple[NTYPE];
 EXTERN uchar   okforeq[NTYPE];
 EXTERN uchar   okforadd[NTYPE];
 EXTERN uchar   okforand[NTYPE];
-EXTERN double  minfloatval[NTYPE];
-EXTERN double  maxfloatval[NTYPE];
-EXTERN vlong   minintval[NTYPE];
-EXTERN vlong   maxintval[NTYPE];
+
+EXTERN Mpint*  minintval[NTYPE];
+EXTERN Mpint*  maxintval[NTYPE];
+EXTERN Mpflt*  minfltval[NTYPE];
+EXTERN Mpflt*  maxfltval[NTYPE];
 
 EXTERN Dcl*    autodcl;
 EXTERN Dcl*    paramdcl;
@@ -438,10 +471,46 @@ void      ungetc(int);
 void   mkpackage(char*);
 
 /*
- *     mpatof.c
+ *     mparith.c
  */
-int    mpatof(char*, double*);
-int    mpatov(char*, vlong*);
+void   mpmovefixfix(Mpint *a, Mpint *b);
+void   mpmovefixflt(Mpflt *a, Mpint *b);
+void   mpmovefltfix(Mpint *a, Mpflt *b);
+void   mpmovefltflt(Mpflt *a, Mpflt *b);
+void   mpmovecfix(Mpint *a, vlong v);
+void   mpmovecflt(Mpflt *a, double f);
+
+int    mpcmpfixfix(Mpint *a, Mpint *b);
+int    mpcmpfltflt(Mpflt *a, Mpflt *b);
+int    mpcmpfixc(Mpint *b, vlong c);
+int    mpcmpfltc(Mpint *b, double c);
+int    mptestfixfix(Mpint *a);
+int    mptestfltflt(Mpflt *a);
+
+void   mpaddfixfix(Mpint *a, Mpint *b);
+void   mpaddfltflt(Mpflt *a, Mpflt *b);
+void   mpsubfixfix(Mpint *a, Mpint *b);
+void   mpsubfltflt(Mpflt *a, Mpflt *b);
+void   mpmulfixfix(Mpint *a, Mpint *b);
+void   mpmulfltflt(Mpflt *a, Mpflt *b);
+void   mpdivfixfix(Mpint *a, Mpint *b);
+void   mpdivfltflt(Mpflt *a, Mpflt *b);
+void   mpnegfix(Mpint *a);
+void   mpnegflt(Mpflt *a);
+
+void   mpandfixfix(Mpint *a, Mpint *b);
+void   mplshfixfix(Mpint *a, Mpint *b);
+void   mpmodfixfix(Mpint *a, Mpint *b);
+void   mporfixfix(Mpint *a, Mpint *b);
+void   mprshfixfix(Mpint *a, Mpint *b);
+void   mpxorfixfix(Mpint *a, Mpint *b);
+void   mpcomfix(Mpint *a);
+
+double mpgetflt(Mpflt *a);
+vlong  mpgetfix(Mpint *a);
+
+void   mpatofix(Mpint *a, char *s);
+void   mpatoflt(Mpflt *a, char *s);
 
 /*
  *     subr.c
index 3fd75b1b5738fc6fa0c3f390e741527cc19909d3..2fe3cc08325fa28d1c98e8263ade7967cd8704ee 100644 (file)
@@ -13,7 +13,8 @@
        int             lint;
 }
 %token <sym>           LNAME LBASETYPE LATYPE LPACK LACONST
-%token <val>           LLITERAL LASOP
+%token <val>           LLITERAL
+%token <lint>          LASOP
 %token                 LPACKAGE LIMPORT LEXPORT
 %token                 LMAP LCHAN LINTERFACE LFUNC LSTRUCT
 %token                 LCOLAS LFALL LRETURN
@@ -269,8 +270,8 @@ conexpr:
        }
 |      '=' expr
        {
-               $$ = $2;
-               lastconst = treecopy($$);
+               lastconst = $2;
+               $$ = treecopy(lastconst);
                iota += 1;
        }
 
@@ -314,7 +315,7 @@ noninc_stmt:
 |      expr LASOP expr
        {
                $$ = nod(OASOP, $1, $3);
-               $$->etype = $2.vval;    // rathole to pass opcode
+               $$->etype = $2;                 // rathole to pass opcode
        }
 |      expr_list '=' expr_list
        {
@@ -687,7 +688,6 @@ pexpr:
        {
                $$ = nod(OLITERAL, N, N);
                $$->val.ctype = CTNIL;
-               $$->val.vval = 0;
        }
 |      LTRUE
        {
index 567e441620bea487e7775660656950640f6e35e8..deb61c36a9ede4fd58fa1f2f45c61baf1fec2228 100644 (file)
@@ -207,11 +207,11 @@ importfile(Val *f)
                return;
        }
 
-       if(!findpkg(f->sval))
-               fatal("can't find import: %Z", f->sval);
+       if(!findpkg(f->u.sval))
+               fatal("can't find import: %Z", f->u.sval);
        imp = Bopen(namebuf, OREAD);
        if(imp == nil)
-               fatal("can't open import: %Z", f->sval);
+               fatal("can't open import: %Z", f->u.sval);
        file = strdup(namebuf);
 
        len = strlen(namebuf);
@@ -245,7 +245,7 @@ importfile(Val *f)
                        continue;
                return;
        }
-       yyerror("no import in: %Z", f->sval);
+       yyerror("no import in: %Z", f->u.sval);
        unimportfile();
 }
 
@@ -390,7 +390,7 @@ l0:
                        cp = remal(cp, c1, 1);
                        cp[c1++] = 0;
                } while(c1 & MAXALIGN);
-               yylval.val.sval = (String*)cp;
+               yylval.val.u.sval = (String*)cp;
                yylval.val.ctype = CTSTR;
                DBG("lex: string literal\n");
                return LLITERAL;
@@ -403,7 +403,8 @@ l0:
                        yyerror("missing '");
                        ungetc(v);
                }
-               yylval.val.vval = v;
+               yylval.val.u.xval = mal(sizeof(*yylval.val.u.xval));
+               mpmovecfix(yylval.val.u.xval, v);
                yylval.val.ctype = CTINT;
                DBG("lex: codepoint literal\n");
                return LLITERAL;
@@ -594,7 +595,7 @@ lx:
        return c;
 
 asop:
-       yylval.val.vval = c;    // rathole to hold which asop
+       yylval.lint = c;        // rathole to hold which asop
        DBG("lex: TOKEN ASOP %c\n", c);
        return LASOP;
 
@@ -695,9 +696,12 @@ dc:
 ncu:
        *cp = 0;
        ungetc(c);
-       if(mpatov(namebuf, &yylval.val.vval)) {
+
+       yylval.val.u.xval = mal(sizeof(*yylval.val.u.xval));
+       mpatofix(yylval.val.u.xval, namebuf);
+       if(yylval.val.u.xval->ovf) {
                yyerror("overflow in constant");
-               yylval.val.vval = 0;
+               mpmovecfix(yylval.val.u.xval, 0);
        }
        yylval.val.ctype = CTINT;
        DBG("lex: integer literal\n");
@@ -730,9 +734,12 @@ casee:
 caseout:
        *cp = 0;
        ungetc(c);
-       if(mpatof(namebuf, &yylval.val.dval)) {
+
+       yylval.val.u.fval = mal(sizeof(*yylval.val.u.fval));
+       mpatoflt(yylval.val.u.fval, namebuf);
+       if(yylval.val.u.fval->ovf) {
                yyerror("overflow in float constant");
-               yylval.val.dval = 0;
+               mpmovecflt(yylval.val.u.fval, 0.0);
        }
        yylval.val.ctype = CTFLT;
        DBG("lex: floating literal\n");
@@ -1040,11 +1047,15 @@ lexinit(void)
                        okforadd[i] = 1;
                        okforand[i] = 1;
                        issimple[i] = 1;
+                       minintval[i] = mal(sizeof(*minintval[i]));
+                       maxintval[i] = mal(sizeof(*maxintval[i]));
                }
                if(isfloat[i]) {
                        okforeq[i] = 1;
                        okforadd[i] = 1;
                        issimple[i] = 1;
+                       minfltval[i] = mal(sizeof(*minfltval[i]));
+                       maxfltval[i] = mal(sizeof(*maxfltval[i]));
                }
                switch(i) {
                case TBOOL:
@@ -1055,35 +1066,27 @@ lexinit(void)
                        okforeq[i] = 1;
                        break;
                }
-               minfloatval[i] = 0.0;
-               maxfloatval[i] = 0.0;
-               minintval[i] = 0;
-               maxintval[i] = 0;
        }
 
-// this stuff smells - really need to do constants
-// in multi precision arithmetic
-
-       maxintval[TINT8] = 0x7f;
-       minintval[TINT8] = -maxintval[TINT8]-1;
-       maxintval[TINT16] = 0x7fff;
-       minintval[TINT16] = -maxintval[TINT16]-1;
-       maxintval[TINT32] = 0x7fffffffL;
-       minintval[TINT32] = -maxintval[TINT32]-1;
-       maxintval[TINT64] = 0x7fffffffffffffffLL;
-       minintval[TINT64] = -maxintval[TINT64]-1;
-       maxintval[TUINT8] = 0xff;
-       maxintval[TUINT16] = 0xffff;
-       maxintval[TUINT32] = 0xffffffffL;
-
-       /* special case until we got to multiple precision */
-       maxintval[TUINT64] = 0x7fffffffffffffffLL;
-       minintval[TUINT64] = -maxintval[TUINT64]-1;
-
-       maxfloatval[TFLOAT32] = 3.40282347e+38;
-       minfloatval[TFLOAT32] = -maxfloatval[TFLOAT32];
-       maxfloatval[TFLOAT64] = 1.7976931348623157e+308;
-       minfloatval[TFLOAT64] = -maxfloatval[TFLOAT64]-1;
+       mpatofix(maxintval[TINT8], "0x7f");
+       mpatofix(minintval[TINT8], "-0x80");
+       mpatofix(maxintval[TINT16], "0x7fff");
+       mpatofix(minintval[TINT16], "-0x8000");
+       mpatofix(maxintval[TINT32], "0x7fffffff");
+       mpatofix(minintval[TINT32], "-0x80000000");
+       mpatofix(maxintval[TINT64], "0x7fffffffffffffff");
+       mpatofix(minintval[TINT64], "-0x8000000000000000");
+       mpatofix(maxintval[TUINT8], "0xff");
+       mpatofix(maxintval[TUINT16], "0xffff");
+       mpatofix(maxintval[TUINT32], "0xffffffff");
+       mpatofix(maxintval[TUINT64], "0x7fffffffffffffff");
+       mpatofix(minintval[TUINT64], "-0x8000000000000000");
+
+       mpatoflt(maxfltval[TFLOAT32], "3.40282347e+38");
+       mpatoflt(minfltval[TFLOAT32], "-3.40282347e+38");
+       mpatoflt(maxfltval[TFLOAT64], "1.7976931348623157e+308");
+       mpatoflt(minfltval[TFLOAT64], "-1.7976931348623157e+308");
+
 
        /*
         * initialize basic types array
@@ -1126,14 +1129,14 @@ lexinit(void)
        belexinit(LBASETYPE);
 
        booltrue = nod(OLITERAL, N, N);
+       booltrue->val.u.bval = 1;
        booltrue->val.ctype = CTBOOL;
-       booltrue->val.vval = 1;
        booltrue->type = types[TBOOL];
        booltrue->addable = 1;
 
        boolfalse = nod(OLITERAL, N, N);
+       boolfalse->val.u.bval = 0;
        boolfalse->val.ctype = CTBOOL;
-       boolfalse->val.vval = 0;
        boolfalse->type = types[TBOOL];
        boolfalse->addable = 1;
 }
index 22e4a4315135b3b73f504440fb68e46b2abe0242..1f9043a442701855f0fe6c0f8a0fa67abbf19bb5 100644 (file)
@@ -313,7 +313,8 @@ nodintconst(int32 v)
 
        c = nod(OLITERAL, N, N);
        c->addable = 1;
-       c->val.vval = v;
+       c->val.u.xval = mal(sizeof(*c->val.u.xval));
+       mpmovecfix(c->val.u.xval, v);
        c->val.ctype = CTINT;
        c->type = types[TINT32];
        ullmancalc(c);
@@ -391,7 +392,7 @@ aindex(Node *b, Type *t)
                break;
 
        case Wlitint:   // fixed lb
-               r->bound = b->val.vval;
+               r->bound = mpgetfix(b->val.u.xval);
                break;
        }
        return r;
@@ -1043,31 +1044,31 @@ Nconv(Fmt *fp)
                goto ptyp;
 
        case OREGISTER:
-               snprint(buf, sizeof(buf), "%O-%R%J", n->op, (int)n->val.vval, n);
+               snprint(buf, sizeof(buf), "%O-%R%J", n->op, n->val.u.reg, n);
                break;
 
        case OLITERAL:
                switch(n->val.ctype) {
                default:
-                       snprint(buf1, sizeof(buf1), "LITERAL-ctype=%d%lld", n->val.ctype, n->val.vval);
+                       snprint(buf1, sizeof(buf1), "LITERAL-ctype=%d", n->val.ctype);
                        break;
                case CTINT:
-                       snprint(buf1, sizeof(buf1), "I%lld", n->val.vval);
+                       snprint(buf1, sizeof(buf1), "I%lld", mpgetfix(n->val.u.xval));
                        break;
                case CTSINT:
-                       snprint(buf1, sizeof(buf1), "S%lld", n->val.vval);
+                       snprint(buf1, sizeof(buf1), "S%lld", mpgetfix(n->val.u.xval));
                        break;
                case CTUINT:
-                       snprint(buf1, sizeof(buf1), "U%lld", n->val.vval);
+                       snprint(buf1, sizeof(buf1), "U%lld", mpgetfix(n->val.u.xval));
                        break;
                case CTFLT:
-                       snprint(buf1, sizeof(buf1), "F%g", n->val.dval);
+                       snprint(buf1, sizeof(buf1), "F%g", mpgetflt(n->val.u.fval));
                        break;
                case CTSTR:
-                       snprint(buf1, sizeof(buf1), "S\"%Z\"", n->val.sval);
+                       snprint(buf1, sizeof(buf1), "S\"%Z\"", n->val.u.sval);
                        break;
                case CTBOOL:
-                       snprint(buf1, sizeof(buf1), "B%lld", n->val.vval);
+                       snprint(buf1, sizeof(buf1), "B%lld", n->val.u.bval);
                        break;
                case CTNIL:
                        snprint(buf1, sizeof(buf1), "N");
@@ -1118,7 +1119,6 @@ treecopy(Node *n)
        case OLITERAL:
                if(n->iota) {
                        m = literal(iota);
-                       m->iota = 1;    // flag to reevaluate on copy
                        break;
                }
                m = nod(OXXX, N, N);
@@ -1528,8 +1528,9 @@ literal(int32 v)
        Node *n;
 
        n = nod(OLITERAL, N, N);
+       n->val.u.xval = mal(sizeof(*n->val.u.xval));
        n->val.ctype = CTINT;
-       n->val.vval = v;
+       mpmovecfix(n->val.u.xval, v);
        return n;
 }
 
index 329d10cedaecf62162668b96c88722e313ed85a0..56d1b01b119403159689bcb1ade2488a97dffb88 100644 (file)
@@ -762,8 +762,9 @@ loop:
                        break;
 
                l = nod(OLITERAL, N, N);
+               l->val.u.fval = mal(sizeof(*l->val.u.fval));
                l->val.ctype = CTFLT;
-               l->val.dval = 0;
+               mpmovecflt(l->val.u.fval, 0.0);
 
                l = nod(OSUB, l, n->left);
                *n = *l;
@@ -991,7 +992,6 @@ recv:
        a = c->left;                    // nil elem
        a = nod(OLITERAL, N, N);
        a->val.ctype = CTNIL;
-       a->val.vval = 0;
 
        r = a;
        a = c->left;                    // chan
@@ -1987,7 +1987,6 @@ chanop(Node *n, int top)
                if(a == N) {
                        a = nod(OLITERAL, N, N);
                        a->val.ctype = CTNIL;
-                       a->val.vval = 0;
                } else
                        a = nod(OADDR, a, N);