1 #include "gc.h" 2 3 void 4 noretval(int n) 5 { 6 7 if(n & 1) { 8 gins(ANOP, Z, Z); 9 p->to.type = REGRET; 10 } 11 if(n & 2) { 12 gins(ANOP, Z, Z); 13 p->to.type = FREGRET; 14 } 15 if((n&3) == 3) 16 if(thisfn && thisfn->link && typefd[thisfn->link->etype]) 17 gins(AFLDZ, Z, Z); 18 } 19 20 /* welcome to commute */ 21 static void 22 commute(Node *n) 23 { 24 Node *l, *r; 25 26 l = n->left; 27 r = n->right; 28 if(r->complex > l->complex) { 29 n->left = r; 30 n->right = l; 31 } 32 } 33 34 void 35 indexshift(Node *n) 36 { 37 int g; 38 39 if(!typechlp[n->type->etype]) 40 return; 41 simplifyshift(n); 42 if(n->op == OASHL && n->right->op == OCONST){ 43 g = vconst(n->right); 44 if(g >= 0 && g < 4) 45 n->addable = 7; 46 } 47 } 48 49 /* 50 * calculate addressability as follows 51 * NAME ==> 10/11 name+value(SB/SP) 52 * REGISTER ==> 12 register 53 * CONST ==> 20 $value 54 * *(20) ==> 21 value 55 * &(10) ==> 13 $name+value(SB) 56 * &(11) ==> 1 $name+value(SP) 57 * (13) + (20) ==> 13 fold constants 58 * (1) + (20) ==> 1 fold constants 59 * *(13) ==> 10 back to name 60 * *(1) ==> 11 back to name 61 * 62 * (20) * (X) ==> 7 multiplier in indexing 63 * (X,7) + (13,1) ==> 8 adder in indexing (addresses) 64 * (8) ==> &9(OINDEX) index, almost addressable 65 * 66 * calculate complexity (number of registers) 67 */ 68 void 69 xcom(Node *n) 70 { 71 Node *l, *r; 72 int g; 73 74 if(n == Z) 75 return; 76 l = n->left; 77 r = n->right; 78 n->complex = 0; 79 n->addable = 0; 80 switch(n->op) { 81 case OCONST: 82 n->addable = 20; 83 break; 84 85 case ONAME: 86 n->addable = 10; 87 if(n->class == CPARAM || n->class == CAUTO) 88 n->addable = 11; 89 break; 90 91 case OREGISTER: 92 n->addable = 12; 93 break; 94 95 case OINDREG: 96 n->addable = 12; 97 break; 98 99 case OADDR: 100 xcom(l); 101 if(l->addable == 10) 102 n->addable = 13; 103 else 104 if(l->addable == 11) 105 n->addable = 1; 106 break; 107 108 case OADD: 109 xcom(l); 110 xcom(r); 111 if(n->type->etype != TIND) 112 break; 113 114 switch(r->addable) { 115 case 20: 116 switch(l->addable) { 117 case 1: 118 case 13: 119 commadd: 120 l->type = n->type; 121 *n = *l; 122 l = new(0, Z, Z); 123 *l = *(n->left); 124 l->xoffset += r->vconst; 125 n->left = l; 126 r = n->right; 127 goto brk; 128 } 129 break; 130 131 case 1: 132 case 13: 133 case 10: 134 case 11: 135 /* l is the base, r is the index */ 136 if(l->addable != 20) 137 n->addable = 8; 138 break; 139 } 140 switch(l->addable) { 141 case 20: 142 switch(r->addable) { 143 case 13: 144 case 1: 145 r = n->left; 146 l = n->right; 147 n->left = l; 148 n->right = r; 149 goto commadd; 150 } 151 break; 152 153 case 13: 154 case 1: 155 case 10: 156 case 11: 157 /* r is the base, l is the index */ 158 if(r->addable != 20) 159 n->addable = 8; 160 break; 161 } 162 if(n->addable == 8 && !side(n)) { 163 indx(n); 164 l = new1(OINDEX, idx.basetree, idx.regtree); 165 l->scale = idx.scale; 166 l->addable = 9; 167 l->complex = l->right->complex; 168 l->type = l->left->type; 169 n->op = OADDR; 170 n->left = l; 171 n->right = Z; 172 n->addable = 8; 173 break; 174 } 175 break; 176 177 case OINDEX: 178 xcom(l); 179 xcom(r); 180 n->addable = 9; 181 break; 182 183 case OIND: 184 xcom(l); 185 if(l->op == OADDR) { 186 l = l->left; 187 l->type = n->type; 188 *n = *l; 189 return; 190 } 191 switch(l->addable) { 192 case 20: 193 n->addable = 21; 194 break; 195 case 1: 196 n->addable = 11; 197 break; 198 case 13: 199 n->addable = 10; 200 break; 201 } 202 break; 203 204 case OASHL: 205 xcom(l); 206 xcom(r); 207 indexshift(n); 208 break; 209 210 case OMUL: 211 case OLMUL: 212 xcom(l); 213 xcom(r); 214 g = vlog(l); 215 if(g >= 0) { 216 n->left = r; 217 n->right = l; 218 l = r; 219 r = n->right; 220 } 221 g = vlog(r); 222 if(g >= 0) { 223 n->op = OASHL; 224 r->vconst = g; 225 r->type = types[TINT]; 226 indexshift(n); 227 break; 228 } 229 commute(n); 230 break; 231 232 case OASLDIV: 233 xcom(l); 234 xcom(r); 235 g = vlog(r); 236 if(g >= 0) { 237 n->op = OASLSHR; 238 r->vconst = g; 239 r->type = types[TINT]; 240 } 241 break; 242 243 case OLDIV: 244 xcom(l); 245 xcom(r); 246 g = vlog(r); 247 if(g >= 0) { 248 n->op = OLSHR; 249 r->vconst = g; 250 r->type = types[TINT]; 251 indexshift(n); 252 break; 253 } 254 break; 255 256 case OASLMOD: 257 xcom(l); 258 xcom(r); 259 g = vlog(r); 260 if(g >= 0) { 261 n->op = OASAND; 262 r->vconst--; 263 } 264 break; 265 266 case OLMOD: 267 xcom(l); 268 xcom(r); 269 g = vlog(r); 270 if(g >= 0) { 271 n->op = OAND; 272 r->vconst--; 273 } 274 break; 275 276 case OASMUL: 277 case OASLMUL: 278 xcom(l); 279 xcom(r); 280 g = vlog(r); 281 if(g >= 0) { 282 n->op = OASASHL; 283 r->vconst = g; 284 } 285 break; 286 287 case OLSHR: 288 case OASHR: 289 xcom(l); 290 xcom(r); 291 indexshift(n); 292 break; 293 294 default: 295 if(l != Z) 296 xcom(l); 297 if(r != Z) 298 xcom(r); 299 break; 300 } 301 brk: 302 if(n->addable >= 10) 303 return; 304 if(l != Z) 305 n->complex = l->complex; 306 if(r != Z) { 307 if(r->complex == n->complex) 308 n->complex = r->complex+1; 309 else 310 if(r->complex > n->complex) 311 n->complex = r->complex; 312 } 313 if(n->complex == 0) 314 n->complex++; 315 316 if(com64(n)) 317 return; 318 319 switch(n->op) { 320 321 case OFUNC: 322 n->complex = FNX; 323 break; 324 325 case OLMOD: 326 case OMOD: 327 case OLMUL: 328 case OLDIV: 329 case OMUL: 330 case ODIV: 331 case OASLMUL: 332 case OASLDIV: 333 case OASLMOD: 334 case OASMUL: 335 case OASDIV: 336 case OASMOD: 337 if(r->complex >= l->complex) { 338 n->complex = l->complex + 3; 339 if(r->complex > n->complex) 340 n->complex = r->complex; 341 } else { 342 n->complex = r->complex + 3; 343 if(l->complex > n->complex) 344 n->complex = l->complex; 345 } 346 break; 347 348 case OLSHR: 349 case OASHL: 350 case OASHR: 351 case OASLSHR: 352 case OASASHL: 353 case OASASHR: 354 if(r->complex >= l->complex) { 355 n->complex = l->complex + 2; 356 if(r->complex > n->complex) 357 n->complex = r->complex; 358 } else { 359 n->complex = r->complex + 2; 360 if(l->complex > n->complex) 361 n->complex = l->complex; 362 } 363 break; 364 365 case OADD: 366 case OXOR: 367 case OAND: 368 case OOR: 369 /* 370 * immediate operators, make const on right 371 */ 372 if(l->op == OCONST) { 373 n->left = r; 374 n->right = l; 375 } 376 break; 377 378 case OEQ: 379 case ONE: 380 case OLE: 381 case OLT: 382 case OGE: 383 case OGT: 384 case OHI: 385 case OHS: 386 case OLO: 387 case OLS: 388 /* 389 * compare operators, make const on left 390 */ 391 if(r->op == OCONST) { 392 n->left = r; 393 n->right = l; 394 n->op = invrel[relindex(n->op)]; 395 } 396 break; 397 } 398 } 399 400 void 401 indx(Node *n) 402 { 403 Node *l, *r; 404 405 if(debug['x']) 406 prtree(n, "indx"); 407 408 l = n->left; 409 r = n->right; 410 if(l->addable == 1 || l->addable == 13 || r->complex > l->complex) { 411 n->right = l; 412 n->left = r; 413 l = r; 414 r = n->right; 415 } 416 if(l->addable != 7) { 417 idx.regtree = l; 418 idx.scale = 1; 419 } else 420 if(l->right->addable == 20) { 421 idx.regtree = l->left; 422 idx.scale = 1 << l->right->vconst; 423 } else 424 if(l->left->addable == 20) { 425 idx.regtree = l->right; 426 idx.scale = 1 << l->left->vconst; 427 } else 428 diag(n, "bad index"); 429 430 idx.basetree = r; 431 if(debug['x']) { 432 print("scale = %d\n", idx.scale); 433 prtree(idx.regtree, "index"); 434 prtree(idx.basetree, "base"); 435 } 436 } 437