diff options
Diffstat (limited to 'src/cmd/5c/txt.c')
-rw-r--r-- | src/cmd/5c/txt.c | 1361 |
1 files changed, 0 insertions, 1361 deletions
diff --git a/src/cmd/5c/txt.c b/src/cmd/5c/txt.c deleted file mode 100644 index af40220cc..000000000 --- a/src/cmd/5c/txt.c +++ /dev/null @@ -1,1361 +0,0 @@ -// Inferno utils/5c/txt.c -// http://code.google.com/p/inferno-os/source/browse/utils/5c/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 = '5'; -char *thestring = "arm"; - -LinkArch *thelinkarch = &linkarm; - -void -linkarchinit(void) -{ -} - -void -ginit(void) -{ - Type *t; - - exregoffset = REGEXT; - exfregoffset = FREGEXT; - 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.reg = NREG; - zprog.from.type = D_NONE; - zprog.from.name = D_NONE; - zprog.from.reg = NREG; - zprog.to = zprog.from; - zprog.scond = 0xE; - - regnode.op = OREGISTER; - regnode.class = CEXREG; - regnode.reg = REGTMP; - regnode.complex = 0; - regnode.addable = 11; - regnode.type = types[TLONG]; - - 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(); - - memset(reg, 0, sizeof(reg)); -} - -void -gclean(void) -{ - int i; - Sym *s; - - for(i=0; i<NREG; i++) - if(reg[i]) - diag(Z, "reg %d left allocated", i); - for(i=NREG; i<NREG+NFREG; i++) - if(reg[i]) - diag(Z, "freg %d left allocated", i-NREG); - 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; - 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; -} - -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(typesuv[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 && typechlp[n->type->etype]) { - regaalloc1(tn1, n); - if(n->complex >= FNX) { - cgen(*fnxp, tn1); - (*fnxp)++; - } else - cgen(n, tn1); - return; - } - regalloc(tn1, n, Z); - if(n->complex >= FNX) { - cgen(*fnxp, tn1); - (*fnxp)++; - } else - cgen(n, tn1); - regaalloc(tn2, n); - gopcode(OAS, tn1, Z, tn2); - regfree(tn1); -} - -Node* -nodconst(int32 v) -{ - constnode.vconst = v; - return &constnode; -} - -Node* -nod32const(vlong v) -{ - constnode.vconst = v & MASK(32); - return &constnode; -} - -Node* -nodfconst(double d) -{ - fconstnode.fconst = d; - return &fconstnode; -} - -void -nodreg(Node *n, Node *nn, int reg) -{ - *n = regnode; - n->reg = reg; - n->type = nn->type; - n->lineno = nn->lineno; -} - -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+NREG; - 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(".ret"); - n->complex = nodret->complex; - n->xoffset = argsize(0); - n->addable = 20; - return; - } - - fatal(Z, "bad regret"); -} - -int -tmpreg(void) -{ - int i; - - for(i=REGRET+1; i<NREG; i++) - if(reg[i] == 0) - return i; - diag(Z, "out of fixed registers"); - return 0; -} - -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 >= 0 && i < NREG) - goto out; - } - for(i=REGRET+1; i<=REGEXT-2; i++) - if(reg[i] == 0) - goto out; - diag(tn, "out of fixed registers"); - goto err; - - case TFLOAT: - case TDOUBLE: - case TVLONG: - if(o != Z && o->op == OREGISTER) { - i = o->reg; - if(i >= NREG && i < NREG+NFREG) - goto out; - } - for(i=NREG; i<NREG+NFREG; i++) - if(reg[i] == 0) - goto out; - diag(tn, "out of float registers"); - goto err; - } - diag(tn, "unknown type in regalloc: %T", tn->type); -err: - nodreg(n, tn, 0); - return; -out: - 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: %d", 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 + SZ_LONG; - 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 -raddr(Node *n, Prog *p) -{ - Addr a; - - naddr(n, &a); - if(R0ISZERO && a.type == D_CONST && a.offset == 0) { - a.type = D_REG; - a.reg = 0; - } - if(a.type != D_REG && a.type != D_FREG) { - if(n) - diag(n, "bad in raddr: %O", n->op); - else - diag(n, "bad in raddr: <null>"); - p->reg = NREG; - } else - p->reg = a.reg; -} - -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", n->op); - break; - - case OREGISTER: - a->type = D_REG; - a->sym = nil; - a->reg = n->reg; - if(a->reg >= NREG) { - a->type = D_FREG; - a->reg -= NREG; - } - break; - - case OIND: - naddr(n->left, a); - if(a->type == D_REG) { - a->type = D_OREG; - break; - } - if(a->type == D_CONST) { - a->type = D_OREG; - break; - } - goto bad; - - case OINDREG: - a->type = D_OREG; - a->sym = nil; - a->offset = n->xoffset; - a->reg = n->reg; - break; - - case ONAME: - a->etype = n->etype; - a->type = D_OREG; - a->name = D_STATIC; - a->sym = linksym(n->sym); - a->offset = n->xoffset; - if(n->class == CSTATIC) - break; - if(n->class == CEXTERN || n->class == CGLOBL) { - a->name = D_EXTERN; - break; - } - if(n->class == CAUTO) { - a->name = D_AUTO; - break; - } - if(n->class == CPARAM) { - a->name = D_PARAM; - break; - } - goto bad; - - case OCONST: - a->sym = nil; - a->reg = NREG; - if(typefd[n->type->etype]) { - a->type = D_FCONST; - a->u.dval = n->fconst; - } else { - a->type = D_CONST; - a->offset = n->vconst; - } - break; - - case OADDR: - naddr(n->left, a); - if(a->type == D_OREG) { - a->type = D_CONST; - break; - } - goto bad; - - case OADD: - if(n->left->op == OCONST) { - naddr(n->left, a); - v = a->offset; - naddr(n->right, a); - } else { - naddr(n->right, a); - v = a->offset; - naddr(n->left, a); - } - a->offset += v; - break; - - } -} - -void -fop(int as, int f1, int f2, Node *t) -{ - Node nod1, nod2, nod3; - - nodreg(&nod1, t, NREG+f1); - nodreg(&nod2, t, NREG+f2); - regalloc(&nod3, t, t); - gopcode(as, &nod1, &nod2, &nod3); - gmove(&nod3, t); - regfree(&nod3); -} - -void -gmovm(Node *f, Node *t, int w) -{ - gins(AMOVM, f, t); - p->scond |= C_UBIT; - if(w) - p->scond |= C_WBIT; -} - -void -gmove(Node *f, Node *t) -{ - int ft, tt, a; - Node nod, nod1; - Prog *p1; - - ft = f->type->etype; - tt = t->type->etype; - - if(ft == TDOUBLE && f->op == OCONST) { - } - if(ft == TFLOAT && f->op == OCONST) { - } - - /* - * a load -- - * put it into a register then - * worry what to do with it. - */ - if(f->op == ONAME || f->op == OINDREG || f->op == OIND) { - switch(ft) { - default: - a = AMOVW; - break; - case TFLOAT: - a = AMOVF; - break; - case TDOUBLE: - a = AMOVD; - break; - case TCHAR: - a = AMOVBS; - break; - case TUCHAR: - a = AMOVBU; - break; - case TSHORT: - a = AMOVHS; - break; - case TUSHORT: - a = AMOVHU; - break; - } - if(typechlp[ft] && typeilp[tt]) - regalloc(&nod, t, t); - else - regalloc(&nod, f, t); - gins(a, f, &nod); - gmove(&nod, t); - regfree(&nod); - return; - } - - /* - * a store -- - * put it into a register then - * store it. - */ - if(t->op == ONAME || t->op == OINDREG || t->op == OIND) { - switch(tt) { - default: - a = AMOVW; - break; - case TUCHAR: - a = AMOVBU; - break; - case TCHAR: - a = AMOVBS; - break; - case TUSHORT: - a = AMOVHU; - break; - case TSHORT: - a = AMOVHS; - break; - case TFLOAT: - a = AMOVF; - break; - case TVLONG: - case TDOUBLE: - a = AMOVD; - break; - } - if(ft == tt) - regalloc(&nod, t, f); - else - regalloc(&nod, t, Z); - gmove(f, &nod); - gins(a, &nod, t); - regfree(&nod); - return; - } - - /* - * type x type cross table - */ - a = AGOK; - switch(ft) { - case TDOUBLE: - case TVLONG: - case TFLOAT: - switch(tt) { - case TDOUBLE: - case TVLONG: - a = AMOVD; - if(ft == TFLOAT) - a = AMOVFD; - break; - case TFLOAT: - a = AMOVDF; - if(ft == TFLOAT) - a = AMOVF; - break; - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - a = AMOVDW; - if(ft == TFLOAT) - a = AMOVFW; - break; - case TSHORT: - case TUSHORT: - case TCHAR: - case TUCHAR: - a = AMOVDW; - if(ft == TFLOAT) - a = AMOVFW; - break; - } - break; - case TUINT: - case TULONG: - if(tt == TFLOAT || tt == TDOUBLE) { - // ugly and probably longer than necessary, - // but vfp has a single instruction for this, - // so hopefully it won't last long. - // - // tmp = f - // tmp1 = tmp & 0x80000000 - // tmp ^= tmp1 - // t = float(int32(tmp)) - // if(tmp1) - // t += 2147483648. - // - regalloc(&nod, f, Z); - regalloc(&nod1, f, Z); - gins(AMOVW, f, &nod); - gins(AMOVW, &nod, &nod1); - gins(AAND, nodconst(0x80000000), &nod1); - gins(AEOR, &nod1, &nod); - if(tt == TFLOAT) - gins(AMOVWF, &nod, t); - else - gins(AMOVWD, &nod, t); - gins(ACMP, nodconst(0), Z); - raddr(&nod1, p); - gins(ABEQ, Z, Z); - regfree(&nod); - regfree(&nod1); - p1 = p; - regalloc(&nod, t, Z); - gins(AMOVF, nodfconst(2147483648.), &nod); - gins(AADDF, &nod, t); - regfree(&nod); - patch(p1, pc); - return; - } - // fall through - - case TINT: - case TLONG: - case TIND: - switch(tt) { - case TDOUBLE: - gins(AMOVWD, f, t); - return; - case TFLOAT: - gins(AMOVWF, f, t); - return; - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - case TSHORT: - case TUSHORT: - case TCHAR: - case TUCHAR: - a = AMOVW; - break; - } - break; - case TSHORT: - switch(tt) { - case TDOUBLE: - regalloc(&nod, f, Z); - gins(AMOVHS, f, &nod); - gins(AMOVWD, &nod, t); - regfree(&nod); - return; - case TFLOAT: - regalloc(&nod, f, Z); - gins(AMOVHS, f, &nod); - gins(AMOVWF, &nod, t); - regfree(&nod); - return; - case TUINT: - case TINT: - case TULONG: - case TLONG: - case TIND: - a = AMOVHS; - break; - case TSHORT: - case TUSHORT: - case TCHAR: - case TUCHAR: - a = AMOVW; - break; - } - break; - case TUSHORT: - switch(tt) { - case TDOUBLE: - regalloc(&nod, f, Z); - gins(AMOVHU, f, &nod); - gins(AMOVWD, &nod, t); - regfree(&nod); - return; - case TFLOAT: - regalloc(&nod, f, Z); - gins(AMOVHU, f, &nod); - gins(AMOVWF, &nod, t); - regfree(&nod); - return; - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - a = AMOVHU; - break; - case TSHORT: - case TUSHORT: - case TCHAR: - case TUCHAR: - a = AMOVW; - break; - } - break; - case TCHAR: - switch(tt) { - case TDOUBLE: - regalloc(&nod, f, Z); - gins(AMOVBS, f, &nod); - gins(AMOVWD, &nod, t); - regfree(&nod); - return; - case TFLOAT: - regalloc(&nod, f, Z); - gins(AMOVBS, f, &nod); - gins(AMOVWF, &nod, t); - regfree(&nod); - return; - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - case TSHORT: - case TUSHORT: - a = AMOVBS; - break; - case TCHAR: - case TUCHAR: - a = AMOVW; - break; - } - break; - case TUCHAR: - switch(tt) { - case TDOUBLE: - regalloc(&nod, f, Z); - gins(AMOVBU, f, &nod); - gins(AMOVWD, &nod, t); - regfree(&nod); - return; - case TFLOAT: - regalloc(&nod, f, Z); - gins(AMOVBU, f, &nod); - gins(AMOVWF, &nod, t); - regfree(&nod); - return; - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - case TSHORT: - case TUSHORT: - a = AMOVBU; - break; - case TCHAR: - case TUCHAR: - a = AMOVW; - break; - } - break; - } - if(a == AGOK) - diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type); - if(a == AMOVW || a == AMOVF || a == AMOVD) - if(samaddr(f, t)) - return; - gins(a, f, t); -} - -void -gmover(Node *f, Node *t) -{ - int ft, tt, a; - - ft = f->type->etype; - tt = t->type->etype; - a = AGOK; - if(typechlp[ft] && typechlp[tt] && ewidth[ft] >= ewidth[tt]){ - switch(tt){ - case TSHORT: - a = AMOVHS; - break; - case TUSHORT: - a = AMOVHU; - break; - case TCHAR: - a = AMOVBS; - break; - case TUCHAR: - a = AMOVBU; - break; - } - } - if(a == AGOK) - gmove(f, t); - else - gins(a, f, t); -} - -void -gins(int a, Node *f, Node *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 -gopcode(int o, Node *f1, Node *f2, Node *t) -{ - int a, et; - Addr ta; - - et = TLONG; - if(f1 != Z && f1->type != T) - et = f1->type->etype; - a = AGOK; - switch(o) { - case OAS: - gmove(f1, t); - return; - - case OASADD: - case OADD: - a = AADD; - if(et == TFLOAT) - a = AADDF; - else - if(et == TDOUBLE || et == TVLONG) - a = AADDD; - break; - - case OASSUB: - case OSUB: - if(f2 && f2->op == OCONST) { - Node *t = f1; - f1 = f2; - f2 = t; - a = ARSB; - } else - a = ASUB; - if(et == TFLOAT) - a = ASUBF; - else - if(et == TDOUBLE || et == TVLONG) - a = ASUBD; - break; - - case OASOR: - case OOR: - a = AORR; - break; - - case OASAND: - case OAND: - a = AAND; - break; - - case OASXOR: - case OXOR: - a = AEOR; - break; - - case OASLSHR: - case OLSHR: - a = ASRL; - break; - - case OASASHR: - case OASHR: - a = ASRA; - break; - - case OASASHL: - case OASHL: - a = ASLL; - break; - - case OFUNC: - a = ABL; - break; - - case OASMUL: - case OMUL: - a = AMUL; - if(et == TFLOAT) - a = AMULF; - else - if(et == TDOUBLE || et == TVLONG) - a = AMULD; - break; - - case OASDIV: - case ODIV: - a = ADIV; - if(et == TFLOAT) - a = ADIVF; - else - if(et == TDOUBLE || et == TVLONG) - a = ADIVD; - break; - - case OASMOD: - case OMOD: - a = AMOD; - break; - - case OASLMUL: - case OLMUL: - a = AMULU; - break; - - case OASLMOD: - case OLMOD: - a = AMODU; - break; - - case OASLDIV: - case OLDIV: - a = ADIVU; - break; - - case OCASE: - case OEQ: - case ONE: - case OLT: - case OLE: - case OGE: - case OGT: - case OLO: - case OLS: - case OHS: - case OHI: - a = ACMP; - if(et == TFLOAT) - a = ACMPF; - else - if(et == TDOUBLE || et == TVLONG) - a = ACMPD; - nextpc(); - p->as = a; - naddr(f1, &p->from); - if(a == ACMP && f1->op == OCONST && p->from.offset < 0) { - p->as = ACMN; - p->from.offset = -p->from.offset; - } - raddr(f2, p); - switch(o) { - case OEQ: - a = ABEQ; - break; - case ONE: - a = ABNE; - break; - case OLT: - a = ABLT; - break; - case OLE: - a = ABLE; - break; - case OGE: - a = ABGE; - break; - case OGT: - a = ABGT; - break; - case OLO: - a = ABLO; - break; - case OLS: - a = ABLS; - break; - case OHS: - a = ABHS; - break; - case OHI: - a = ABHI; - break; - case OCASE: - nextpc(); - p->as = ACASE; - p->scond = 0x9; - naddr(f2, &p->from); - a = ABHI; - break; - } - f1 = Z; - f2 = Z; - break; - } - if(a == AGOK) - diag(Z, "bad in gopcode %O", o); - nextpc(); - p->as = a; - if(f1 != Z) - naddr(f1, &p->from); - if(f2 != Z) { - naddr(f2, &ta); - p->reg = ta.reg; - } - if(t != Z) - naddr(t, &p->to); - if(debug['g']) - print("%P\n", p); -} - -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 = AB; - 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; -} - -void -gpseudo(int a, Sym *s, Node *n) -{ - nextpc(); - p->as = a; - p->from.type = D_OREG; - p->from.sym = linksym(s); - p->from.name = D_EXTERN; - - switch(a) { - case ATEXT: - p->reg = textflag; - textflag = 0; - break; - case AGLOBL: - p->reg = s->dataflag; - break; - } - - if(s->class == CSTATIC) - p->from.name = 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; - - regalloc(&n1, n, Z); - gmove(n, &n1); - n1.op = OINDREG; - gins(APLD, &n1, Z); - regfree(&n1); -} - -int -sconst(Node *n) -{ - vlong vv; - - if(n->op == OCONST) { - if(!typefd[n->type->etype]) { - vv = n->vconst; - if(vv >= (vlong)(-32766) && vv < (vlong)32766) - return 1; - /* - * should be specialised for constant values which will - * fit in different instructionsl; for now, let 5l - * sort it out - */ - return 1; - } - } - return 0; -} - -int -sval(int32 v) -{ - int i; - - for(i=0; i<16; i++) { - if((v & ~0xff) == 0) - return 1; - if((~v & ~0xff) == 0) - return 1; - v = (v<<2) | ((uint32)v>>30); - } - return 0; -} - -int32 -exreg(Type *t) -{ - int32 o; - - if(typechlp[t->etype]) { - if(exregoffset <= REGEXT-4) - return 0; - o = exregoffset; - exregoffset--; - return o; - } - if(typefd[t->etype]) { - if(exfregoffset <= NFREG-1) - return 0; - o = exfregoffset + NREG; - exfregoffset--; - return o; - } - 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] */ -}; |