diff options
Diffstat (limited to 'src/cmd/8c/txt.c')
-rw-r--r-- | src/cmd/8c/txt.c | 1537 |
1 files changed, 0 insertions, 1537 deletions
diff --git a/src/cmd/8c/txt.c b/src/cmd/8c/txt.c deleted file mode 100644 index 7f87a0a0d..000000000 --- a/src/cmd/8c/txt.c +++ /dev/null @@ -1,1537 +0,0 @@ -// Inferno utils/8c/txt.c -// http://code.google.com/p/inferno-os/source/browse/utils/8c/txt.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "gc.h" - - -int thechar = '8'; -char *thestring = "386"; - -LinkArch *thelinkarch = &link386; - -void -linkarchinit(void) -{ -} - -void -ginit(void) -{ - int i; - Type *t; - - exregoffset = 0; - exfregoffset = 0; - listinit(); - nstring = 0; - mnstring = 0; - nrathole = 0; - pc = 0; - breakpc = -1; - continpc = -1; - cases = C; - lastp = P; - tfield = types[TLONG]; - - zprog.link = P; - zprog.as = AGOK; - zprog.from.type = D_NONE; - zprog.from.index = D_NONE; - zprog.from.scale = 0; - zprog.to = zprog.from; - - regnode.op = OREGISTER; - regnode.class = CEXREG; - regnode.reg = REGTMP; - regnode.complex = 0; - regnode.addable = 11; - regnode.type = types[TLONG]; - - fregnode0 = regnode; - fregnode0.reg = D_F0; - fregnode0.type = types[TDOUBLE]; - - fregnode1 = fregnode0; - fregnode1.reg = D_F0+1; - - constnode.op = OCONST; - constnode.class = CXXX; - constnode.complex = 0; - constnode.addable = 20; - constnode.type = types[TLONG]; - - fconstnode.op = OCONST; - fconstnode.class = CXXX; - fconstnode.complex = 0; - fconstnode.addable = 20; - fconstnode.type = types[TDOUBLE]; - - nodsafe = new(ONAME, Z, Z); - nodsafe->sym = slookup(".safe"); - nodsafe->type = types[TINT]; - nodsafe->etype = types[TINT]->etype; - nodsafe->class = CAUTO; - complex(nodsafe); - - t = typ(TARRAY, types[TCHAR]); - symrathole = slookup(".rathole"); - symrathole->class = CGLOBL; - symrathole->type = t; - - nodrat = new(ONAME, Z, Z); - nodrat->sym = symrathole; - nodrat->type = types[TIND]; - nodrat->etype = TVOID; - nodrat->class = CGLOBL; - complex(nodrat); - nodrat->type = t; - - nodret = new(ONAME, Z, Z); - nodret->sym = slookup(".ret"); - nodret->type = types[TIND]; - nodret->etype = TIND; - nodret->class = CPARAM; - nodret = new(OIND, nodret, Z); - complex(nodret); - - com64init(); - - for(i=0; i<nelem(reg); i++) { - reg[i] = 1; - if(i >= D_AX && i <= D_DI && i != D_SP) - reg[i] = 0; - } -} - -void -gclean(void) -{ - int i; - Sym *s; - - reg[D_SP]--; - for(i=D_AX; i<=D_DI; i++) - if(reg[i]) - diag(Z, "reg %R left allocated", i); - while(mnstring) - outstring("", 1L); - symstring->type->width = nstring; - symrathole->type->width = nrathole; - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) { - if(s->type == T) - continue; - if(s->type->width == 0) - continue; - if(s->class != CGLOBL && s->class != CSTATIC) - continue; - if(s->type == types[TENUM]) - continue; - gpseudo(AGLOBL, s, nodconst(s->type->width)); - } - nextpc(); - p->as = AEND; - outcode(); -} - -void -nextpc(void) -{ - Plist *pl; - - p = alloc(sizeof(*p)); - *p = zprog; - p->lineno = nearln; - p->pc = pc; - pc++; - if(lastp == nil) { - pl = linknewplist(ctxt); - pl->firstpc = p; - } else - lastp->link = p; - lastp = p; -} - -void -gargs(Node *n, Node *tn1, Node *tn2) -{ - int32 regs; - Node fnxargs[20], *fnxp; - - regs = cursafe; - - fnxp = fnxargs; - garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */ - - curarg = 0; - fnxp = fnxargs; - garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */ - - cursafe = regs; -} - -int -nareg(void) -{ - int i, n; - - n = 0; - for(i=D_AX; i<=D_DI; i++) - if(reg[i] == 0) - n++; - return n; -} - -void -garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp) -{ - Node nod; - - if(n == Z) - return; - if(n->op == OLIST) { - garg1(n->left, tn1, tn2, f, fnxp); - garg1(n->right, tn1, tn2, f, fnxp); - return; - } - if(f == 0) { - if(n->complex >= FNX) { - regsalloc(*fnxp, n); - nod = znode; - nod.op = OAS; - nod.left = *fnxp; - nod.right = n; - nod.type = n->type; - cgen(&nod, Z); - (*fnxp)++; - } - return; - } - if(typesu[n->type->etype] || typev[n->type->etype]) { - regaalloc(tn2, n); - if(n->complex >= FNX) { - sugen(*fnxp, tn2, n->type->width); - (*fnxp)++; - } else - sugen(n, tn2, n->type->width); - return; - } - if(REGARG >= 0 && curarg == 0 && typeilp[n->type->etype]) { - regaalloc1(tn1, n); - if(n->complex >= FNX) { - cgen(*fnxp, tn1); - (*fnxp)++; - } else - cgen(n, tn1); - return; - } - if(vconst(n) == 0) { - regaalloc(tn2, n); - gmove(n, tn2); - return; - } - regalloc(tn1, n, Z); - if(n->complex >= FNX) { - cgen(*fnxp, tn1); - (*fnxp)++; - } else - cgen(n, tn1); - regaalloc(tn2, n); - gmove(tn1, tn2); - regfree(tn1); -} - -Node* -nodconst(int32 v) -{ - constnode.vconst = v; - return &constnode; -} - -Node* -nodfconst(double d) -{ - fconstnode.fconst = d; - return &fconstnode; -} - -int -isreg(Node *n, int r) -{ - - if(n->op == OREGISTER) - if(n->reg == r) - return 1; - return 0; -} - -int -nodreg(Node *n, Node *nn, int r) -{ - - *n = regnode; - n->reg = r; - if(reg[r] == 0) - return 0; - if(nn != Z) { - n->type = nn->type; - n->lineno = nn->lineno; - if(nn->op == OREGISTER) - if(nn->reg == r) - return 0; - } - return 1; -} - -void -regret(Node *n, Node *nn, Type *t, int mode) -{ - int r; - - if(mode == 0 || hasdotdotdot(t) || nn->type->width == 0) { - r = REGRET; - if(typefd[nn->type->etype]) - r = FREGRET; - nodreg(n, nn, r); - reg[r]++; - return; - } - - if(mode == 1) { - // fetch returned value after call. - // already called gargs, so curarg is set. - curarg = (curarg+3) & ~3; - regaalloc(n, nn); - return; - } - - if(mode == 2) { - // store value to be returned. - // must compute arg offset. - if(t->etype != TFUNC) - fatal(Z, "bad regret func %T", t); - *n = *nn; - n->op = ONAME; - n->class = CPARAM; - n->sym = slookup(".retx"); - n->complex = 0; - n->addable = 20; - n->xoffset = argsize(0); - return; - } - - fatal(Z, "bad regret"); -} - -void -regalloc(Node *n, Node *tn, Node *o) -{ - int i; - - switch(tn->type->etype) { - case TCHAR: - case TUCHAR: - case TSHORT: - case TUSHORT: - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - if(o != Z && o->op == OREGISTER) { - i = o->reg; - if(i >= D_AX && i <= D_DI) - goto out; - } - for(i=D_AX; i<=D_DI; i++) - if(reg[i] == 0) - goto out; - diag(tn, "out of fixed registers"); - goto err; - - case TFLOAT: - case TDOUBLE: - case TVLONG: - i = D_F0; - goto out; - } - diag(tn, "unknown type in regalloc: %T", tn->type); -err: - i = 0; -out: - if(i) - reg[i]++; - nodreg(n, tn, i); -} - -void -regialloc(Node *n, Node *tn, Node *o) -{ - Node nod; - - nod = *tn; - nod.type = types[TIND]; - regalloc(n, &nod, o); -} - -void -regfree(Node *n) -{ - int i; - - i = 0; - if(n->op != OREGISTER && n->op != OINDREG) - goto err; - i = n->reg; - if(i < 0 || i >= nelem(reg)) - goto err; - if(reg[i] <= 0) - goto err; - reg[i]--; - return; -err: - diag(n, "error in regfree: %R", i); -} - -void -regsalloc(Node *n, Node *nn) -{ - cursafe = align(cursafe, nn->type, Aaut3, nil); - maxargsafe = maxround(maxargsafe, cursafe+curarg); - *n = *nodsafe; - n->xoffset = -(stkoff + cursafe); - n->type = nn->type; - n->etype = nn->type->etype; - n->lineno = nn->lineno; -} - -void -regaalloc1(Node *n, Node *nn) -{ - if(REGARG < 0) { - fatal(n, "regaalloc1 and REGARG<0"); - return; - } - nodreg(n, nn, REGARG); - reg[REGARG]++; - curarg = align(curarg, nn->type, Aarg1, nil); - curarg = align(curarg, nn->type, Aarg2, nil); - maxargsafe = maxround(maxargsafe, cursafe+curarg); -} - -void -regaalloc(Node *n, Node *nn) -{ - curarg = align(curarg, nn->type, Aarg1, nil); - *n = *nn; - n->op = OINDREG; - n->reg = REGSP; - n->xoffset = curarg; - n->complex = 0; - n->addable = 20; - curarg = align(curarg, nn->type, Aarg2, nil); - maxargsafe = maxround(maxargsafe, cursafe+curarg); -} - -void -regind(Node *n, Node *nn) -{ - - if(n->op != OREGISTER) { - diag(n, "regind not OREGISTER"); - return; - } - n->op = OINDREG; - n->type = nn->type; -} - -void -naddr(Node *n, Addr *a) -{ - int32 v; - - a->type = D_NONE; - if(n == Z) - return; - switch(n->op) { - default: - bad: - diag(n, "bad in naddr: %O %D", n->op, a); - break; - - case OREGISTER: - a->type = n->reg; - a->sym = nil; - break; - - case OEXREG: - a->type = D_INDIR + D_TLS; - a->offset = n->reg - 1; - break; - - case OIND: - naddr(n->left, a); - if(a->type >= D_AX && a->type <= D_DI) - a->type += D_INDIR; - else - if(a->type == D_CONST) - a->type = D_NONE+D_INDIR; - else - if(a->type == D_ADDR) { - a->type = a->index; - a->index = D_NONE; - } else - goto bad; - break; - - case OINDEX: - a->type = idx.ptr; - if(n->left->op == OADDR || n->left->op == OCONST) - naddr(n->left, a); - if(a->type >= D_AX && a->type <= D_DI) - a->type += D_INDIR; - else - if(a->type == D_CONST) - a->type = D_NONE+D_INDIR; - else - if(a->type == D_ADDR) { - a->type = a->index; - a->index = D_NONE; - } else - goto bad; - a->index = idx.reg; - a->scale = n->scale; - a->offset += n->xoffset; - break; - - case OINDREG: - a->type = n->reg+D_INDIR; - a->sym = nil; - a->offset = n->xoffset; - break; - - case ONAME: - a->etype = n->etype; - a->type = D_STATIC; - a->sym = linksym(n->sym); - a->offset = n->xoffset; - if(n->class == CSTATIC) - break; - if(n->class == CEXTERN || n->class == CGLOBL) { - a->type = D_EXTERN; - break; - } - if(n->class == CAUTO) { - a->type = D_AUTO; - break; - } - if(n->class == CPARAM) { - a->type = D_PARAM; - break; - } - goto bad; - - case OCONST: - if(typefd[n->type->etype]) { - a->type = D_FCONST; - a->u.dval = n->fconst; - break; - } - a->sym = nil; - a->type = D_CONST; - a->offset = n->vconst; - break; - - case OADDR: - naddr(n->left, a); - if(a->type >= D_INDIR) { - a->type -= D_INDIR; - break; - } - if(a->type == D_EXTERN || a->type == D_STATIC || - a->type == D_AUTO || a->type == D_PARAM) - if(a->index == D_NONE) { - a->index = a->type; - a->type = D_ADDR; - break; - } - goto bad; - - case OADD: - if(n->right->op == OCONST) { - v = n->right->vconst; - naddr(n->left, a); - } else - if(n->left->op == OCONST) { - v = n->left->vconst; - naddr(n->right, a); - } else - goto bad; - a->offset += v; - break; - - } -} - -#define CASE(a,b) ((a<<8)|(b<<0)) - -void -gmove(Node *f, Node *t) -{ - int ft, tt, a; - Node nod, nod1; - Prog *p1; - - ft = f->type->etype; - tt = t->type->etype; - if(debug['M']) - print("gop: %O %O[%s],%O[%s]\n", OAS, - f->op, tnames[ft], t->op, tnames[tt]); - if(typefd[ft] && f->op == OCONST) { - if(f->fconst == 0) - gins(AFLDZ, Z, Z); - else - if(f->fconst == 1) - gins(AFLD1, Z, Z); - else - gins(AFMOVD, f, &fregnode0); - gmove(&fregnode0, t); - return; - } -/* - * load - */ - if(f->op == ONAME || f->op == OINDREG || - f->op == OIND || f->op == OINDEX) - switch(ft) { - case TCHAR: - a = AMOVBLSX; - goto ld; - case TUCHAR: - a = AMOVBLZX; - goto ld; - case TSHORT: - if(typefd[tt]) { - gins(AFMOVW, f, &fregnode0); - gmove(&fregnode0, t); - return; - } - a = AMOVWLSX; - goto ld; - case TUSHORT: - a = AMOVWLZX; - goto ld; - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - if(typefd[tt]) { - gins(AFMOVL, f, &fregnode0); - gmove(&fregnode0, t); - return; - } - a = AMOVL; - - ld: - regalloc(&nod, f, t); - nod.type = types[TLONG]; - gins(a, f, &nod); - gmove(&nod, t); - regfree(&nod); - return; - - case TFLOAT: - gins(AFMOVF, f, t); - return; - case TDOUBLE: - gins(AFMOVD, f, t); - return; - case TVLONG: - gins(AFMOVV, f, t); - return; - } - -/* - * store - */ - if(t->op == ONAME || t->op == OINDREG || - t->op == OIND || t->op == OINDEX) - switch(tt) { - case TCHAR: - case TUCHAR: - a = AMOVB; goto st; - case TSHORT: - case TUSHORT: - a = AMOVW; goto st; - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - a = AMOVL; goto st; - - st: - if(f->op == OCONST) { - gins(a, f, t); - return; - } - regalloc(&nod, t, f); - gmove(f, &nod); - gins(a, &nod, t); - regfree(&nod); - return; - - case TFLOAT: - gins(AFMOVFP, f, t); - return; - case TDOUBLE: - gins(AFMOVDP, f, t); - return; - case TVLONG: - gins(AFMOVVP, f, t); - return; - } - -/* - * convert - */ - switch(CASE(ft,tt)) { - default: -/* - * integer to integer - ******** - a = AGOK; break; - - case CASE( TCHAR, TCHAR): - case CASE( TUCHAR, TCHAR): - case CASE( TSHORT, TCHAR): - case CASE( TUSHORT,TCHAR): - case CASE( TINT, TCHAR): - case CASE( TUINT, TCHAR): - case CASE( TLONG, TCHAR): - case CASE( TULONG, TCHAR): - case CASE( TIND, TCHAR): - - case CASE( TCHAR, TUCHAR): - case CASE( TUCHAR, TUCHAR): - case CASE( TSHORT, TUCHAR): - case CASE( TUSHORT,TUCHAR): - case CASE( TINT, TUCHAR): - case CASE( TUINT, TUCHAR): - case CASE( TLONG, TUCHAR): - case CASE( TULONG, TUCHAR): - case CASE( TIND, TUCHAR): - - case CASE( TSHORT, TSHORT): - case CASE( TUSHORT,TSHORT): - case CASE( TINT, TSHORT): - case CASE( TUINT, TSHORT): - case CASE( TLONG, TSHORT): - case CASE( TULONG, TSHORT): - case CASE( TIND, TSHORT): - - case CASE( TSHORT, TUSHORT): - case CASE( TUSHORT,TUSHORT): - case CASE( TINT, TUSHORT): - case CASE( TUINT, TUSHORT): - case CASE( TLONG, TUSHORT): - case CASE( TULONG, TUSHORT): - case CASE( TIND, TUSHORT): - - case CASE( TINT, TINT): - case CASE( TUINT, TINT): - case CASE( TLONG, TINT): - case CASE( TULONG, TINT): - case CASE( TIND, TINT): - - case CASE( TINT, TUINT): - case CASE( TUINT, TUINT): - case CASE( TLONG, TUINT): - case CASE( TULONG, TUINT): - case CASE( TIND, TUINT): - - case CASE( TINT, TLONG): - case CASE( TUINT, TLONG): - case CASE( TLONG, TLONG): - case CASE( TULONG, TLONG): - case CASE( TIND, TLONG): - - case CASE( TINT, TULONG): - case CASE( TUINT, TULONG): - case CASE( TLONG, TULONG): - case CASE( TULONG, TULONG): - case CASE( TIND, TULONG): - - case CASE( TINT, TIND): - case CASE( TUINT, TIND): - case CASE( TLONG, TIND): - case CASE( TULONG, TIND): - case CASE( TIND, TIND): - *****/ - a = AMOVL; - break; - - case CASE( TSHORT, TINT): - case CASE( TSHORT, TUINT): - case CASE( TSHORT, TLONG): - case CASE( TSHORT, TULONG): - case CASE( TSHORT, TIND): - a = AMOVWLSX; - if(f->op == OCONST) { - f->vconst &= 0xffff; - if(f->vconst & 0x8000) - f->vconst |= 0xffff0000; - a = AMOVL; - } - break; - - case CASE( TUSHORT,TINT): - case CASE( TUSHORT,TUINT): - case CASE( TUSHORT,TLONG): - case CASE( TUSHORT,TULONG): - case CASE( TUSHORT,TIND): - a = AMOVWLZX; - if(f->op == OCONST) { - f->vconst &= 0xffff; - a = AMOVL; - } - break; - - case CASE( TCHAR, TSHORT): - case CASE( TCHAR, TUSHORT): - case CASE( TCHAR, TINT): - case CASE( TCHAR, TUINT): - case CASE( TCHAR, TLONG): - case CASE( TCHAR, TULONG): - case CASE( TCHAR, TIND): - a = AMOVBLSX; - if(f->op == OCONST) { - f->vconst &= 0xff; - if(f->vconst & 0x80) - f->vconst |= 0xffffff00; - a = AMOVL; - } - break; - - case CASE( TUCHAR, TSHORT): - case CASE( TUCHAR, TUSHORT): - case CASE( TUCHAR, TINT): - case CASE( TUCHAR, TUINT): - case CASE( TUCHAR, TLONG): - case CASE( TUCHAR, TULONG): - case CASE( TUCHAR, TIND): - a = AMOVBLZX; - if(f->op == OCONST) { - f->vconst &= 0xff; - a = AMOVL; - } - break; - -/* - * float to fix - */ - case CASE( TFLOAT, TCHAR): - case CASE( TFLOAT, TUCHAR): - case CASE( TFLOAT, TSHORT): - case CASE( TFLOAT, TUSHORT): - case CASE( TFLOAT, TINT): - case CASE( TFLOAT, TUINT): - case CASE( TFLOAT, TLONG): - case CASE( TFLOAT, TULONG): - case CASE( TFLOAT, TIND): - - case CASE( TDOUBLE,TCHAR): - case CASE( TDOUBLE,TUCHAR): - case CASE( TDOUBLE,TSHORT): - case CASE( TDOUBLE,TUSHORT): - case CASE( TDOUBLE,TINT): - case CASE( TDOUBLE,TUINT): - case CASE( TDOUBLE,TLONG): - case CASE( TDOUBLE,TULONG): - case CASE( TDOUBLE,TIND): - - case CASE( TVLONG, TCHAR): - case CASE( TVLONG, TUCHAR): - case CASE( TVLONG, TSHORT): - case CASE( TVLONG, TUSHORT): - case CASE( TVLONG, TINT): - case CASE( TVLONG, TUINT): - case CASE( TVLONG, TLONG): - case CASE( TVLONG, TULONG): - case CASE( TVLONG, TIND): - if(fproundflg) { - regsalloc(&nod, ®node); - gins(AFMOVLP, f, &nod); - gmove(&nod, t); - return; - } - regsalloc(&nod, ®node); - regsalloc(&nod1, ®node); - gins(AFSTCW, Z, &nod1); - nod1.xoffset += 2; - gins(AMOVW, nodconst(0xf7f), &nod1); - gins(AFLDCW, &nod1, Z); - gins(AFMOVLP, f, &nod); - nod1.xoffset -= 2; - gins(AFLDCW, &nod1, Z); - gmove(&nod, t); - return; - -/* - * ulong to float - */ - case CASE( TULONG, TDOUBLE): - case CASE( TULONG, TVLONG): - case CASE( TULONG, TFLOAT): - case CASE( TUINT, TDOUBLE): - case CASE( TUINT, TVLONG): - case CASE( TUINT, TFLOAT): - regalloc(&nod, f, f); - gmove(f, &nod); - regsalloc(&nod1, ®node); - gmove(&nod, &nod1); - gins(AFMOVL, &nod1, &fregnode0); - gins(ACMPL, &nod, nodconst(0)); - gins(AJGE, Z, Z); - p1 = p; - gins(AFADDD, nodfconst(4294967296.), &fregnode0); - patch(p1, pc); - regfree(&nod); - return; - -/* - * fix to float - */ - case CASE( TCHAR, TFLOAT): - case CASE( TUCHAR, TFLOAT): - case CASE( TSHORT, TFLOAT): - case CASE( TUSHORT,TFLOAT): - case CASE( TINT, TFLOAT): - case CASE( TLONG, TFLOAT): - case CASE( TIND, TFLOAT): - - case CASE( TCHAR, TDOUBLE): - case CASE( TUCHAR, TDOUBLE): - case CASE( TSHORT, TDOUBLE): - case CASE( TUSHORT,TDOUBLE): - case CASE( TINT, TDOUBLE): - case CASE( TLONG, TDOUBLE): - case CASE( TIND, TDOUBLE): - - case CASE( TCHAR, TVLONG): - case CASE( TUCHAR, TVLONG): - case CASE( TSHORT, TVLONG): - case CASE( TUSHORT,TVLONG): - case CASE( TINT, TVLONG): - case CASE( TLONG, TVLONG): - case CASE( TIND, TVLONG): - regsalloc(&nod, ®node); - gmove(f, &nod); - gins(AFMOVL, &nod, &fregnode0); - return; - -/* - * float to float - */ - case CASE( TFLOAT, TFLOAT): - case CASE( TDOUBLE,TFLOAT): - case CASE( TVLONG, TFLOAT): - - case CASE( TFLOAT, TDOUBLE): - case CASE( TDOUBLE,TDOUBLE): - case CASE( TVLONG, TDOUBLE): - - case CASE( TFLOAT, TVLONG): - case CASE( TDOUBLE,TVLONG): - case CASE( TVLONG, TVLONG): - a = AFMOVD; break; - } - if(a == AMOVL || a == AFMOVD) - if(samaddr(f, t)) - return; - gins(a, f, t); -} - -void -doindex(Node *n) -{ - Node nod, nod1; - int32 v; - -if(debug['Y']) -prtree(n, "index"); - -if(n->left->complex >= FNX) -print("botch in doindex\n"); - - regalloc(&nod, ®node, Z); - v = constnode.vconst; - cgen(n->right, &nod); - idx.ptr = D_NONE; - if(n->left->op == OCONST) - idx.ptr = D_CONST; - else if(n->left->op == OREGISTER) - idx.ptr = n->left->reg; - else if(n->left->op != OADDR) { - reg[D_BP]++; // can't be used as a base - regalloc(&nod1, ®node, Z); - cgen(n->left, &nod1); - idx.ptr = nod1.reg; - regfree(&nod1); - reg[D_BP]--; - } - idx.reg = nod.reg; - regfree(&nod); - constnode.vconst = v; -} - -void -gins(int a, Node *f, Node *t) -{ - - if(f != Z && f->op == OINDEX) - doindex(f); - if(t != Z && t->op == OINDEX) - doindex(t); - nextpc(); - p->as = a; - if(f != Z) - naddr(f, &p->from); - if(t != Z) - naddr(t, &p->to); - if(debug['g']) - print("%P\n", p); -} - -void -fgopcode(int o, Node *f, Node *t, int pop, int rev) -{ - int a, et; - Node nod; - - et = TLONG; - if(f != Z && f->type != T) - et = f->type->etype; - if(!typefd[et]) { - diag(f, "fop: integer %O", o); - return; - } - if(debug['M']) { - if(t != Z && t->type != T) - print("gop: %O %O-%s Z\n", o, f->op, tnames[et]); - else - print("gop: %O %O-%s %O-%s\n", o, - f->op, tnames[et], t->op, tnames[t->type->etype]); - } - a = AGOK; - switch(o) { - - case OASADD: - case OADD: - if(et == TFLOAT) - a = AFADDF; - else - if(et == TDOUBLE || et == TVLONG) { - a = AFADDD; - if(pop) - a = AFADDDP; - } - break; - - case OASSUB: - case OSUB: - if(et == TFLOAT) { - a = AFSUBF; - if(rev) - a = AFSUBRF; - } else - if(et == TDOUBLE || et == TVLONG) { - a = AFSUBD; - if(pop) - a = AFSUBDP; - if(rev) { - a = AFSUBRD; - if(pop) - a = AFSUBRDP; - } - } - break; - - case OASMUL: - case OMUL: - if(et == TFLOAT) - a = AFMULF; - else - if(et == TDOUBLE || et == TVLONG) { - a = AFMULD; - if(pop) - a = AFMULDP; - } - break; - - case OASMOD: - case OMOD: - case OASDIV: - case ODIV: - if(et == TFLOAT) { - a = AFDIVF; - if(rev) - a = AFDIVRF; - } else - if(et == TDOUBLE || et == TVLONG) { - a = AFDIVD; - if(pop) - a = AFDIVDP; - if(rev) { - a = AFDIVRD; - if(pop) - a = AFDIVRDP; - } - } - break; - - case OEQ: - case ONE: - case OLT: - case OLE: - case OGE: - case OGT: - pop += rev; - if(et == TFLOAT) { - a = AFCOMF; - if(pop) { - a = AFCOMFP; - if(pop > 1) - a = AGOK; - } - } else - if(et == TDOUBLE || et == TVLONG) { - a = AFCOMF; - if(pop) { - a = AFCOMDP; - if(pop > 1) - a = AFCOMDPP; - } - } - gins(a, f, t); - regalloc(&nod, ®node, Z); - if(nod.reg != D_AX) { - regfree(&nod); - nod.reg = D_AX; - gins(APUSHL, &nod, Z); - gins(AWAIT, Z, Z); - gins(AFSTSW, Z, &nod); - gins(ASAHF, Z, Z); - gins(APOPL, Z, &nod); - } else { - gins(AWAIT, Z, Z); - gins(AFSTSW, Z, &nod); - gins(ASAHF, Z, Z); - regfree(&nod); - } - switch(o) { - case OEQ: a = AJEQ; break; - case ONE: a = AJNE; break; - case OLT: a = AJCS; break; - case OLE: a = AJLS; break; - case OGE: a = AJCC; break; - case OGT: a = AJHI; break; - } - gins(a, Z, Z); - return; - } - if(a == AGOK) - diag(Z, "bad in gopcode %O", o); - gins(a, f, t); -} - -void -gopcode(int o, Type *ty, Node *f, Node *t) -{ - int a, et; - - et = TLONG; - if(ty != T) - et = ty->etype; - if(typefd[et] && o != OADDR && o != OFUNC) { - diag(f, "gop: float %O", o); - return; - } - if(debug['M']) { - if(f != Z && f->type != T) - print("gop: %O %O[%s],", o, f->op, tnames[et]); - else - print("gop: %O Z,", o); - if(t != Z && t->type != T) - print("%O[%s]\n", t->op, tnames[t->type->etype]); - else - print("Z\n"); - } - a = AGOK; - switch(o) { - case OCOM: - a = ANOTL; - if(et == TCHAR || et == TUCHAR) - a = ANOTB; - if(et == TSHORT || et == TUSHORT) - a = ANOTW; - break; - - case ONEG: - a = ANEGL; - if(et == TCHAR || et == TUCHAR) - a = ANEGB; - if(et == TSHORT || et == TUSHORT) - a = ANEGW; - break; - - case OADDR: - a = ALEAL; - break; - - case OASADD: - case OADD: - a = AADDL; - if(et == TCHAR || et == TUCHAR) - a = AADDB; - if(et == TSHORT || et == TUSHORT) - a = AADDW; - break; - - case OASSUB: - case OSUB: - a = ASUBL; - if(et == TCHAR || et == TUCHAR) - a = ASUBB; - if(et == TSHORT || et == TUSHORT) - a = ASUBW; - break; - - case OASOR: - case OOR: - a = AORL; - if(et == TCHAR || et == TUCHAR) - a = AORB; - if(et == TSHORT || et == TUSHORT) - a = AORW; - break; - - case OASAND: - case OAND: - a = AANDL; - if(et == TCHAR || et == TUCHAR) - a = AANDB; - if(et == TSHORT || et == TUSHORT) - a = AANDW; - break; - - case OASXOR: - case OXOR: - a = AXORL; - if(et == TCHAR || et == TUCHAR) - a = AXORB; - if(et == TSHORT || et == TUSHORT) - a = AXORW; - break; - - case OASLSHR: - case OLSHR: - a = ASHRL; - if(et == TCHAR || et == TUCHAR) - a = ASHRB; - if(et == TSHORT || et == TUSHORT) - a = ASHRW; - break; - - case OASASHR: - case OASHR: - a = ASARL; - if(et == TCHAR || et == TUCHAR) - a = ASARB; - if(et == TSHORT || et == TUSHORT) - a = ASARW; - break; - - case OASASHL: - case OASHL: - a = ASALL; - if(et == TCHAR || et == TUCHAR) - a = ASALB; - if(et == TSHORT || et == TUSHORT) - a = ASALW; - break; - - case OROTL: - a = AROLL; - if(et == TCHAR || et == TUCHAR) - a = AROLB; - if(et == TSHORT || et == TUSHORT) - a = AROLW; - break; - - case OFUNC: - a = ACALL; - break; - - case OASMUL: - case OMUL: - if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0) - t = Z; - a = AIMULL; - break; - - case OASMOD: - case OMOD: - case OASDIV: - case ODIV: - a = AIDIVL; - break; - - case OASLMUL: - case OLMUL: - a = AMULL; - break; - - case OASLMOD: - case OLMOD: - case OASLDIV: - case OLDIV: - a = ADIVL; - break; - - case OEQ: - case ONE: - case OLT: - case OLE: - case OGE: - case OGT: - case OLO: - case OLS: - case OHS: - case OHI: - a = ACMPL; - if(et == TCHAR || et == TUCHAR) - a = ACMPB; - if(et == TSHORT || et == TUSHORT) - a = ACMPW; - gins(a, f, t); - switch(o) { - case OEQ: a = AJEQ; break; - case ONE: a = AJNE; break; - case OLT: a = AJLT; break; - case OLE: a = AJLE; break; - case OGE: a = AJGE; break; - case OGT: a = AJGT; break; - case OLO: a = AJCS; break; - case OLS: a = AJLS; break; - case OHS: a = AJCC; break; - case OHI: a = AJHI; break; - } - gins(a, Z, Z); - return; - } - if(a == AGOK) - diag(Z, "bad in gopcode %O", o); - gins(a, f, t); -} - -int -samaddr(Node *f, Node *t) -{ - - if(f->op != t->op) - return 0; - switch(f->op) { - - case OREGISTER: - if(f->reg != t->reg) - break; - return 1; - } - return 0; -} - -void -gbranch(int o) -{ - int a; - - a = AGOK; - switch(o) { - case ORETURN: - a = ARET; - break; - case OGOTO: - a = AJMP; - break; - } - nextpc(); - if(a == AGOK) { - diag(Z, "bad in gbranch %O", o); - nextpc(); - } - p->as = a; -} - -void -patch(Prog *op, int32 pc) -{ - op->to.offset = pc; - op->to.type = D_BRANCH; - op->to.u.branch = nil; - op->pcond = nil; -} - -void -gpseudo(int a, Sym *s, Node *n) -{ - - nextpc(); - p->as = a; - p->from.type = D_EXTERN; - p->from.sym = linksym(s); - - switch(a) { - case ATEXT: - p->from.scale = textflag; - textflag = 0; - break; - case AGLOBL: - p->from.scale = s->dataflag; - break; - } - - if(s->class == CSTATIC) - p->from.type = D_STATIC; - naddr(n, &p->to); - if(a == ADATA || a == AGLOBL) - pc--; -} - -void -gpcdata(int index, int value) -{ - Node n1; - - n1 = *nodconst(index); - gins(APCDATA, &n1, nodconst(value)); -} - -void -gprefetch(Node *n) -{ - Node n1; - - if(strcmp(getgo386(), "sse2") != 0) // assume no prefetch on old machines - return; - - regalloc(&n1, n, Z); - gmove(n, &n1); - n1.op = OINDREG; - gins(APREFETCHNTA, &n1, Z); - regfree(&n1); -} - -int -sconst(Node *n) -{ - int32 v; - - if(n->op == OCONST && !typefd[n->type->etype]) { - v = n->vconst; - if(v >= -32766L && v < 32766L) - return 1; - } - return 0; -} - -int32 -exreg(Type *t) -{ - int32 o; - - if(typechlp[t->etype]){ - if(exregoffset >= 32) - return 0; - o = exregoffset; - exregoffset += 4; - return o+1; // +1 to avoid 0 == failure; naddr case OEXREG will -1. - } - - return 0; -} - -schar ewidth[NTYPE] = -{ - -1, /*[TXXX]*/ - SZ_CHAR, /*[TCHAR]*/ - SZ_CHAR, /*[TUCHAR]*/ - SZ_SHORT, /*[TSHORT]*/ - SZ_SHORT, /*[TUSHORT]*/ - SZ_INT, /*[TINT]*/ - SZ_INT, /*[TUINT]*/ - SZ_LONG, /*[TLONG]*/ - SZ_LONG, /*[TULONG]*/ - SZ_VLONG, /*[TVLONG]*/ - SZ_VLONG, /*[TUVLONG]*/ - SZ_FLOAT, /*[TFLOAT]*/ - SZ_DOUBLE, /*[TDOUBLE]*/ - SZ_IND, /*[TIND]*/ - 0, /*[TFUNC]*/ - -1, /*[TARRAY]*/ - 0, /*[TVOID]*/ - -1, /*[TSTRUCT]*/ - -1, /*[TUNION]*/ - SZ_INT, /*[TENUM]*/ -}; -int32 ncast[NTYPE] = -{ - 0, /*[TXXX]*/ - BCHAR|BUCHAR, /*[TCHAR]*/ - BCHAR|BUCHAR, /*[TUCHAR]*/ - BSHORT|BUSHORT, /*[TSHORT]*/ - BSHORT|BUSHORT, /*[TUSHORT]*/ - BINT|BUINT|BLONG|BULONG|BIND, /*[TINT]*/ - BINT|BUINT|BLONG|BULONG|BIND, /*[TUINT]*/ - BINT|BUINT|BLONG|BULONG|BIND, /*[TLONG]*/ - BINT|BUINT|BLONG|BULONG|BIND, /*[TULONG]*/ - BVLONG|BUVLONG, /*[TVLONG]*/ - BVLONG|BUVLONG, /*[TUVLONG]*/ - BFLOAT, /*[TFLOAT]*/ - BDOUBLE, /*[TDOUBLE]*/ - BLONG|BULONG|BIND, /*[TIND]*/ - 0, /*[TFUNC]*/ - 0, /*[TARRAY]*/ - 0, /*[TVOID]*/ - BSTRUCT, /*[TSTRUCT]*/ - BUNION, /*[TUNION]*/ - 0, /*[TENUM]*/ -}; |