diff options
Diffstat (limited to 'src/cmd/cc/pswt.c')
-rw-r--r-- | src/cmd/cc/pswt.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/cmd/cc/pswt.c b/src/cmd/cc/pswt.c new file mode 100644 index 000000000..0e402dea7 --- /dev/null +++ b/src/cmd/cc/pswt.c @@ -0,0 +1,168 @@ +// Inferno utils/6c/swt.c +// http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.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 +swcmp(const void *a1, const void *a2) +{ + C1 *p1, *p2; + + p1 = (C1*)a1; + p2 = (C1*)a2; + if(p1->val < p2->val) + return -1; + return p1->val > p2->val; +} + +void +doswit(Node *n) +{ + Case *c; + C1 *q, *iq; + int32 def, nc, i, isv; + + def = 0; + nc = 0; + isv = 0; + for(c = cases; c->link != C; c = c->link) { + if(c->def) { + if(def) + diag(n, "more than one default in switch"); + def = c->label; + continue; + } + isv |= c->isv; + nc++; + } + if(isv && !typev[n->type->etype]) + warn(n, "32-bit switch expression with 64-bit case constant"); + + iq = alloc(nc*sizeof(C1)); + q = iq; + for(c = cases; c->link != C; c = c->link) { + if(c->def) + continue; + q->label = c->label; + if(isv) + q->val = c->val; + else + q->val = (int32)c->val; /* cast ensures correct value for 32-bit switch on 64-bit architecture */ + q++; + } + qsort(iq, nc, sizeof(C1), swcmp); + if(debug['W']) + for(i=0; i<nc; i++) + print("case %2d: = %.8llux\n", i, (vlong)iq[i].val); + for(i=0; i<nc-1; i++) + if(iq[i].val == iq[i+1].val) + diag(n, "duplicate cases in switch %lld", (vlong)iq[i].val); + if(def == 0) { + def = breakpc; + nbreak++; + } + swit1(iq, nc, def, n); +} + +void +cas(void) +{ + Case *c; + + c = alloc(sizeof(*c)); + c->link = cases; + cases = c; +} + +int32 +outlstring(ushort *s, int32 n) +{ + char buf[2]; + int c; + int32 r; + + if(suppress) + return nstring; + while(nstring & 1) + outstring("", 1); + r = nstring; + while(n > 0) { + c = *s++; + if(align(0, types[TCHAR], Aarg1, nil)) { + buf[0] = c>>8; + buf[1] = c; + } else { + buf[0] = c; + buf[1] = c>>8; + } + outstring(buf, 2); + n -= sizeof(ushort); + } + return r; +} + +void +nullwarn(Node *l, Node *r) +{ + warn(Z, "result of operation not used"); + if(l != Z) + cgen(l, Z); + if(r != Z) + cgen(r, Z); +} + +void +ieeedtod(Ieee *ieee, double native) +{ + double fr, ho, f; + int exp; + + if(native < 0) { + ieeedtod(ieee, -native); + ieee->h |= 0x80000000L; + return; + } + if(native == 0) { + ieee->l = 0; + ieee->h = 0; + return; + } + fr = frexp(native, &exp); + f = 2097152L; /* shouldnt use fp constants here */ + fr = modf(fr*f, &ho); + ieee->h = ho; + ieee->h &= 0xfffffL; + ieee->h |= (exp+1022L) << 20; + f = 65536L; + fr = modf(fr*f, &ho); + ieee->l = ho; + ieee->l <<= 16; + ieee->l |= (int32)(fr*f); +} |