1 #include "gc.h" 2 3 int 4 swcmp(void *a1, void *a2) 5 { 6 C1 *p1, *p2; 7 8 p1 = (C1*)a1; 9 p2 = (C1*)a2; 10 if(p1->val < p2->val) 11 return -1; 12 return p1->val > p2->val; 13 } 14 15 void 16 doswit(Node *n) 17 { 18 Case *c; 19 C1 *q, *iq, *iqh, *iql; 20 long def, nc, i, j, isv, nh; 21 Prog *hsb; 22 Node *vr[2]; 23 int dup; 24 25 def = 0; 26 nc = 0; 27 isv = 0; 28 for(c = cases; c->link != C; c = c->link) { 29 if(c->def) { 30 if(def) 31 diag(n, "more than one default in switch"); 32 def = c->label; 33 continue; 34 } 35 isv |= c->isv; 36 nc++; 37 } 38 if(typev[n->type->etype]) 39 isv = 1; 40 else if(isv){ 41 warn(n, "32-bit switch expression with 64-bit case constant"); 42 isv = 0; 43 } 44 45 iq = alloc(nc*sizeof(C1)); 46 q = iq; 47 for(c = cases; c->link != C; c = c->link) { 48 if(c->def) 49 continue; 50 if(c->isv && !isv) 51 continue; /* can never match */ 52 q->label = c->label; 53 if(isv) 54 q->val = c->val; 55 else 56 q->val = (long)c->val; /* cast ensures correct value for 32-bit switch on 64-bit architecture */ 57 q++; 58 } 59 qsort(iq, nc, sizeof(C1), swcmp); 60 if(debug['K']) 61 for(i=0; i<nc; i++) 62 print("case %2ld: = %.8llux\n", i, (vlong)iq[i].val); 63 dup = 0; 64 for(i=0; i<nc-1; i++) 65 if(iq[i].val == iq[i+1].val) { 66 diag(n, "duplicate cases in switch %lld", (vlong)iq[i].val); 67 dup = 1; 68 } 69 if(dup) 70 return; 71 if(def == 0) { 72 def = breakpc; 73 nbreak++; 74 } 75 if(!isv || ewidth[TIND] > ewidth[TLONG] || n->op == OREGISTER) { 76 swit1(iq, nc, def, n); 77 return; 78 } 79 80 /* 81 * 64-bit case on 32-bit machine: 82 * switch on high-order words, and 83 * in each of those, switch on low-order words 84 */ 85 if(n->op != OREGPAIR) 86 fatal(n, "internal: expected register pair"); 87 if(thechar == '8'){ /* TO DO: need an enquiry function */ 88 vr[0] = n->left; /* low */ 89 vr[1] = n->right; /* high */ 90 }else{ 91 vr[0] = n->right; 92 vr[1] = n->left; 93 } 94 vr[0]->type = types[TLONG]; 95 vr[1]->type = types[TLONG]; 96 gbranch(OGOTO); 97 hsb = p; 98 iqh = alloc(nc*sizeof(C1)); 99 iql = alloc(nc*sizeof(C1)); 100 nh = 0; 101 for(i=0; i<nc;){ 102 iqh[nh].val = iq[i].val >> 32; 103 q = iql; 104 /* iq is sorted, so equal top halves are adjacent */ 105 for(j = i; j < nc; j++){ 106 if((iq[j].val>>32) != iqh[nh].val) 107 break; 108 q->val = (long)iq[j].val; 109 q->label = iq[j].label; 110 q++; 111 } 112 qsort(iql, q-iql, sizeof(C1), swcmp); 113 iqh[nh].label = pc; 114 nh++; 115 swit1(iql, q-iql, def, vr[0]); 116 i = j; 117 } 118 patch(hsb, pc); 119 swit1(iqh, nh, def, vr[1]); 120 } 121 122 void 123 casf(void) 124 { 125 Case *c; 126 127 c = alloc(sizeof(*c)); 128 c->link = cases; 129 cases = c; 130 } 131 132 long 133 outlstring(TRune *s, long n) 134 { 135 char buf[sizeof(TRune)]; 136 uint c; 137 int i; 138 long r; 139 140 if(suppress) 141 return nstring; 142 while(nstring & (sizeof(TRune)-1)) 143 outstring("", 1); 144 r = nstring; 145 while(n > 0) { 146 c = *s++; 147 if(align(0, types[TCHAR], Aarg1)) { 148 for(i = 0; i < sizeof(TRune); i++) 149 buf[i] = c>>(8*(sizeof(TRune) - i - 1)); 150 } else { 151 for(i = 0; i < sizeof(TRune); i++) 152 buf[i] = c>>(8*i); 153 } 154 outstring(buf, sizeof(TRune)); 155 n -= sizeof(TRune); 156 } 157 return r; 158 } 159 160 void 161 nullwarn(Node *l, Node *r) 162 { 163 warn(Z, "result of operation not used"); 164 if(l != Z) 165 cgen(l, Z); 166 if(r != Z) 167 cgen(r, Z); 168 } 169 170 void 171 ieeedtod(Ieee *ieee, double native) 172 { 173 double fr, ho, f; 174 int exp; 175 176 if(native < 0) { 177 ieeedtod(ieee, -native); 178 ieee->h |= 0x80000000L; 179 return; 180 } 181 if(native == 0) { 182 ieee->l = 0; 183 ieee->h = 0; 184 return; 185 } 186 fr = frexp(native, &exp); 187 f = 2097152L; /* shouldnt use fp constants here */ 188 fr = modf(fr*f, &ho); 189 ieee->h = ho; 190 ieee->h &= 0xfffffL; 191 ieee->h |= (exp+1022L) << 20; 192 f = 65536L; 193 fr = modf(fr*f, &ho); 194 ieee->l = ho; 195 ieee->l <<= 16; 196 ieee->l |= (long)(fr*f); 197 } 198