github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/cc/pswt.c (about)

     1  // Inferno utils/6c/swt.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  #include "gc.h"
    32  
    33  int
    34  swcmp(const void *a1, const void *a2)
    35  {
    36  	C1 *p1, *p2;
    37  
    38  	p1 = (C1*)a1;
    39  	p2 = (C1*)a2;
    40  	if(p1->val < p2->val)
    41  		return -1;
    42  	return p1->val > p2->val;
    43  }
    44  
    45  void
    46  doswit(Node *n)
    47  {
    48  	Case *c;
    49  	C1 *q, *iq;
    50  	int32 def, nc, i, isv;
    51  
    52  	def = 0;
    53  	nc = 0;
    54  	isv = 0;
    55  	for(c = cases; c->link != C; c = c->link) {
    56  		if(c->def) {
    57  			if(def)
    58  				diag(n, "more than one default in switch");
    59  			def = c->label;
    60  			continue;
    61  		}
    62  		isv |= c->isv;
    63  		nc++;
    64  	}
    65  	if(isv && !typev[n->type->etype])
    66  		warn(n, "32-bit switch expression with 64-bit case constant");
    67  
    68  	iq = alloc(nc*sizeof(C1));
    69  	q = iq;
    70  	for(c = cases; c->link != C; c = c->link) {
    71  		if(c->def)
    72  			continue;
    73  		q->label = c->label;
    74  		if(isv)
    75  			q->val = c->val;
    76  		else
    77  			q->val = (int32)c->val;	/* cast ensures correct value for 32-bit switch on 64-bit architecture */
    78  		q++;
    79  	}
    80  	qsort(iq, nc, sizeof(C1), swcmp);
    81  	if(debug['W'])
    82  	for(i=0; i<nc; i++)
    83  		print("case %2d: = %.8llux\n", i, (vlong)iq[i].val);
    84  	for(i=0; i<nc-1; i++)
    85  		if(iq[i].val == iq[i+1].val)
    86  			diag(n, "duplicate cases in switch %lld", (vlong)iq[i].val);
    87  	if(def == 0) {
    88  		def = breakpc;
    89  		nbreak++;
    90  	}
    91  	swit1(iq, nc, def, n);
    92  }
    93  
    94  void
    95  newcase(void)
    96  {
    97  	Case *c;
    98  
    99  	c = alloc(sizeof(*c));
   100  	c->link = cases;
   101  	cases = c;
   102  }
   103  
   104  int32
   105  outlstring(ushort *s, int32 n)
   106  {
   107  	char buf[2];
   108  	int c;
   109  	int32 r;
   110  
   111  	if(suppress)
   112  		return nstring;
   113  	while(nstring & 1)
   114  		outstring("", 1);
   115  	r = nstring;
   116  	while(n > 0) {
   117  		c = *s++;
   118  		if(align(0, types[TCHAR], Aarg1, nil)) {
   119  			buf[0] = c>>8;
   120  			buf[1] = c;
   121  		} else {
   122  			buf[0] = c;
   123  			buf[1] = c>>8;
   124  		}
   125  		outstring(buf, 2);
   126  		n -= sizeof(ushort);
   127  	}
   128  	return r;
   129  }
   130  
   131  void
   132  nullwarn(Node *l, Node *r)
   133  {
   134  	warn(Z, "result of operation not used");
   135  	if(l != Z)
   136  		cgen(l, Z);
   137  	if(r != Z)
   138  		cgen(r, Z);
   139  }
   140  
   141  void
   142  ieeedtod(Ieee *ieee, double native)
   143  {
   144  	double fr, ho, f;
   145  	int exp;
   146  
   147  	if(native < 0) {
   148  		ieeedtod(ieee, -native);
   149  		ieee->h |= 0x80000000L;
   150  		return;
   151  	}
   152  	if(native == 0) {
   153  		ieee->l = 0;
   154  		ieee->h = 0;
   155  		return;
   156  	}
   157  	fr = frexp(native, &exp);
   158  	f = 2097152L;		/* shouldnt use fp constants here */
   159  	fr = modf(fr*f, &ho);
   160  	ieee->h = ho;
   161  	ieee->h &= 0xfffffL;
   162  	ieee->h |= (exp+1022L) << 20;
   163  	f = 65536L;
   164  	fr = modf(fr*f, &ho);
   165  	ieee->l = ho;
   166  	ieee->l <<= 16;
   167  	ieee->l |= (int32)(fr*f);
   168  }