2008-06-04 15:37:38 -06:00
|
|
|
// 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;
|
2008-08-03 18:25:15 -06:00
|
|
|
int32 def, nc, i, isv;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
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
|
2008-08-03 18:25:15 -06:00
|
|
|
q->val = (int32)c->val; /* cast ensures correct value for 32-bit switch on 64-bit architecture */
|
2008-06-04 15:37:38 -06:00
|
|
|
q++;
|
|
|
|
}
|
|
|
|
qsort(iq, nc, sizeof(C1), swcmp);
|
|
|
|
if(debug['W'])
|
|
|
|
for(i=0; i<nc; i++)
|
|
|
|
print("case %2ld: = %.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;
|
|
|
|
}
|
|
|
|
|
2008-08-03 18:25:15 -06:00
|
|
|
int32
|
|
|
|
outlstring(ushort *s, int32 n)
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
|
|
|
char buf[2];
|
|
|
|
int c;
|
2008-08-03 18:25:15 -06:00
|
|
|
int32 r;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
if(suppress)
|
|
|
|
return nstring;
|
|
|
|
while(nstring & 1)
|
|
|
|
outstring("", 1);
|
|
|
|
r = nstring;
|
|
|
|
while(n > 0) {
|
|
|
|
c = *s++;
|
|
|
|
if(align(0, types[TCHAR], Aarg1)) {
|
|
|
|
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;
|
2008-08-03 18:25:15 -06:00
|
|
|
ieee->l |= (int32)(fr*f);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|