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;
// 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];
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;
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;
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:
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;
}
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;
}
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;
}
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)
n->op = OREGISTER;
n->addable = 1;
ullmancalc(n);
- n->val.vval = r;
+ n->val.u.reg = r;
n->type = t;
}
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
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;
}
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;
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);
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):
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):
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):
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):
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;
/*
switch(f->op) {
case OREGISTER:
- if(f->val.vval != t->val.vval)
+ if(f->val.u.reg != t->val.u.reg)
break;
return 1;
}
break;
case OREGISTER:
- a->type = n->val.vval;
+ a->type = n->val.u.reg;
a->sym = S;
break;
// 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;
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;
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:
p = mal(sizeof(*p));
- p->sval = n->val.sval;
+ p->sval = n->val.u.sval;
p->link = nil;
if(poolist == nil)
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);
export.$O\
walk.$O\
const.$O\
- mpatof.$O\
+ mparith.$O\
sysimport.$O\
compat.$O\
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;
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;
}
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;
}
int32 len;
String *str;
int wl, wr;
+ Mpint *xval;
+ Mpflt *fval;
nl = n->left;
if(nl == 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;
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:
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;
}
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)
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;
}
}
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;
t->outtuple = importcount(t->type->down);
t->intuple = importcount(t->type->down->down);
+ dowidth(t);
importfuncnam(t);
importaddtyp(ss, t);
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);
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);
todo:
1. dyn arrays
2. multi
- 3. block 0
tothinkabout:
2. argument in import
*/
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;
// func
Node* nname;
- // OLITERAL
+ // OLITERAL/OREGISTER
Val val;
Sym* osym; // import
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;
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
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
}
| '=' expr
{
- $$ = $2;
- lastconst = treecopy($$);
+ lastconst = $2;
+ $$ = treecopy(lastconst);
iota += 1;
}
| expr LASOP expr
{
$$ = nod(OASOP, $1, $3);
- $$->etype = $2.vval; // rathole to pass opcode
+ $$->etype = $2; // rathole to pass opcode
}
| expr_list '=' expr_list
{
{
$$ = nod(OLITERAL, N, N);
$$->val.ctype = CTNIL;
- $$->val.vval = 0;
}
| LTRUE
{
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);
continue;
return;
}
- yyerror("no import in: %Z", f->sval);
+ yyerror("no import in: %Z", f->u.sval);
unimportfile();
}
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;
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;
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;
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");
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");
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:
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
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;
}
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);
break;
case Wlitint: // fixed lb
- r->bound = b->val.vval;
+ r->bound = mpgetfix(b->val.u.xval);
break;
}
return r;
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");
case OLITERAL:
if(n->iota) {
m = literal(iota);
- m->iota = 1; // flag to reevaluate on copy
break;
}
m = nod(OXXX, N, N);
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;
}
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;
a = c->left; // nil elem
a = nod(OLITERAL, N, N);
a->val.ctype = CTNIL;
- a->val.vval = 0;
r = a;
a = c->left; // chan
if(a == N) {
a = nod(OLITERAL, N, N);
a->val.ctype = CTNIL;
- a->val.vval = 0;
} else
a = nod(OADDR, a, N);