diff options
Diffstat (limited to 'src/cmd/6c/mul.c')
-rw-r--r-- | src/cmd/6c/mul.c | 458 |
1 files changed, 0 insertions, 458 deletions
diff --git a/src/cmd/6c/mul.c b/src/cmd/6c/mul.c deleted file mode 100644 index 510edc05c..000000000 --- a/src/cmd/6c/mul.c +++ /dev/null @@ -1,458 +0,0 @@ -// Inferno utils/6c/mul.c -// http://code.google.com/p/inferno-os/source/browse/utils/6c/mul.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" - -typedef struct Malg Malg; -typedef struct Mparam Mparam; - -struct Malg -{ - schar vals[10]; -}; - -struct Mparam -{ - uint32 value; - schar alg; - char neg; - char shift; - char arg; - schar off; -}; - -static Mparam multab[32]; -static int mulptr; - -static Malg malgs[] = -{ - {0, 100}, - {-1, 1, 100}, - {-9, -5, -3, 3, 5, 9, 100}, - {6, 10, 12, 18, 20, 24, 36, 40, 72, 100}, - {-8, -4, -2, 2, 4, 8, 100}, -}; - -/* - * return position of lowest 1 - */ -int -lowbit(uint32 v) -{ - int s, i; - uint32 m; - - s = 0; - m = 0xFFFFFFFFUL; - for(i = 16; i > 0; i >>= 1) { - m >>= i; - if((v & m) == 0) { - v >>= i; - s += i; - } - } - return s; -} - -void -genmuladd(Node *d, Node *s, int m, Node *a) -{ - Node nod; - - nod.op = OINDEX; - nod.left = a; - nod.right = s; - nod.scale = m; - nod.type = types[TIND]; - nod.xoffset = 0; - xcom(&nod); - gopcode(OADDR, d->type, &nod, d); -} - -void -mulparam(uint32 m, Mparam *mp) -{ - int c, i, j, n, o, q, s; - int bc, bi, bn, bo, bq, bs, bt; - schar *p; - int32 u; - uint32 t; - - bc = bq = 10; - bi = bn = bo = bs = bt = 0; - for(i = 0; i < nelem(malgs); i++) { - for(p = malgs[i].vals, j = 0; (o = p[j]) < 100; j++) - for(s = 0; s < 2; s++) { - c = 10; - q = 10; - u = m - o; - if(u == 0) - continue; - if(s) { - o = -o; - if(o > 0) - continue; - u = -u; - } - n = lowbit(u); - t = (uint32)u >> n; - switch(i) { - case 0: - if(t == 1) { - c = s + 1; - q = 0; - break; - } - switch(t) { - case 3: - case 5: - case 9: - c = s + 1; - if(n) - c++; - q = 0; - break; - } - if(s) - break; - switch(t) { - case 15: - case 25: - case 27: - case 45: - case 81: - c = 2; - if(n) - c++; - q = 1; - break; - } - break; - case 1: - if(t == 1) { - c = 3; - q = 3; - break; - } - switch(t) { - case 3: - case 5: - case 9: - c = 3; - q = 2; - break; - } - break; - case 2: - if(t == 1) { - c = 3; - q = 2; - break; - } - break; - case 3: - if(s) - break; - if(t == 1) { - c = 3; - q = 1; - break; - } - break; - case 4: - if(t == 1) { - c = 3; - q = 0; - break; - } - break; - } - if(c < bc || (c == bc && q > bq)) { - bc = c; - bi = i; - bn = n; - bo = o; - bq = q; - bs = s; - bt = t; - } - } - } - mp->value = m; - if(bc <= 3) { - mp->alg = bi; - mp->shift = bn; - mp->off = bo; - mp->neg = bs; - mp->arg = bt; - } - else - mp->alg = -1; -} - -int -m0(int a) -{ - switch(a) { - case -2: - case 2: - return 2; - case -3: - case 3: - return 2; - case -4: - case 4: - return 4; - case -5: - case 5: - return 4; - case 6: - return 2; - case -8: - case 8: - return 8; - case -9: - case 9: - return 8; - case 10: - return 4; - case 12: - return 2; - case 15: - return 2; - case 18: - return 8; - case 20: - return 4; - case 24: - return 2; - case 25: - return 4; - case 27: - return 2; - case 36: - return 8; - case 40: - return 4; - case 45: - return 4; - case 72: - return 8; - case 81: - return 8; - } - diag(Z, "bad m0"); - return 0; -} - -int -m1(int a) -{ - switch(a) { - case 15: - return 4; - case 25: - return 4; - case 27: - return 8; - case 45: - return 8; - case 81: - return 8; - } - diag(Z, "bad m1"); - return 0; -} - -int -m2(int a) -{ - switch(a) { - case 6: - return 2; - case 10: - return 2; - case 12: - return 4; - case 18: - return 2; - case 20: - return 4; - case 24: - return 8; - case 36: - return 4; - case 40: - return 8; - case 72: - return 8; - } - diag(Z, "bad m2"); - return 0; -} - -void -shiftit(Type *t, Node *s, Node *d) -{ - int32 c; - - c = (int32)s->vconst & 31; - switch(c) { - case 0: - break; - case 1: - gopcode(OADD, t, d, d); - break; - default: - gopcode(OASHL, t, s, d); - } -} - -static int -mulgen1(uint32 v, Node *n) -{ - int i, o; - Mparam *p; - Node nod, nods; - - for(i = 0; i < nelem(multab); i++) { - p = &multab[i]; - if(p->value == v) - goto found; - } - - p = &multab[mulptr]; - if(++mulptr == nelem(multab)) - mulptr = 0; - - mulparam(v, p); - -found: -// print("v=%.x a=%d n=%d s=%d g=%d o=%d \n", p->value, p->alg, p->neg, p->shift, p->arg, p->off); - if(p->alg < 0) - return 0; - - nods = *nodconst(p->shift); - - o = OADD; - if(p->alg > 0) { - regalloc(&nod, n, Z); - if(p->off < 0) - o = OSUB; - } - - switch(p->alg) { - case 0: - switch(p->arg) { - case 1: - shiftit(n->type, &nods, n); - break; - case 15: - case 25: - case 27: - case 45: - case 81: - genmuladd(n, n, m1(p->arg), n); - /* fall thru */ - case 3: - case 5: - case 9: - genmuladd(n, n, m0(p->arg), n); - shiftit(n->type, &nods, n); - break; - default: - goto bad; - } - if(p->neg == 1) - gins(ANEGL, Z, n); - break; - case 1: - switch(p->arg) { - case 1: - gmove(n, &nod); - shiftit(n->type, &nods, &nod); - break; - case 3: - case 5: - case 9: - genmuladd(&nod, n, m0(p->arg), n); - shiftit(n->type, &nods, &nod); - break; - default: - goto bad; - } - if(p->neg) - gopcode(o, n->type, &nod, n); - else { - gopcode(o, n->type, n, &nod); - gmove(&nod, n); - } - break; - case 2: - genmuladd(&nod, n, m0(p->off), n); - shiftit(n->type, &nods, n); - goto comop; - case 3: - genmuladd(&nod, n, m0(p->off), n); - shiftit(n->type, &nods, n); - genmuladd(n, &nod, m2(p->off), n); - break; - case 4: - genmuladd(&nod, n, m0(p->off), nodconst(0)); - shiftit(n->type, &nods, n); - goto comop; - default: - diag(Z, "bad mul alg"); - break; - comop: - if(p->neg) { - gopcode(o, n->type, n, &nod); - gmove(&nod, n); - } - else - gopcode(o, n->type, &nod, n); - } - - if(p->alg > 0) - regfree(&nod); - - return 1; - -bad: - diag(Z, "mulgen botch"); - return 1; -} - -void -mulgen(Type *t, Node *r, Node *n) -{ - if(!mulgen1(r->vconst, n)) - gopcode(OMUL, t, r, n); -} |