1 #include "cc.h" 2 3 static Node* 4 acast(Type *t, Node *n) 5 { 6 if(n->type->etype != t->etype || n->op == OBIT) { 7 n = new1(OCAST, n, Z); 8 if(nocast(n->left->type, t)) 9 *n = *n->left; 10 n->type = t; 11 } 12 return n; 13 } 14 15 16 void 17 evconst(Node *n) 18 { 19 Node *l, *r; 20 int et, isf; 21 vlong v; 22 double d; 23 24 if(n == Z || n->type == T) 25 return; 26 27 et = n->type->etype; 28 isf = typefd[et]; 29 30 l = n->left; 31 r = n->right; 32 33 d = 0; 34 v = 0; 35 36 switch(n->op) { 37 default: 38 return; 39 40 case ONEG: 41 if(isf) 42 d = -l->fconst; 43 else 44 v = -l->vconst; 45 break; 46 47 case OCOM: 48 v = ~l->vconst; 49 break; 50 51 case OCAST: 52 if(et == TVOID) 53 return; 54 et = l->type->etype; 55 if(isf) { 56 if(typefd[et]) 57 d = l->fconst; 58 else 59 d = l->vconst; 60 } else { 61 if(typefd[et]) 62 v = l->fconst; 63 else 64 v = convvtox(l->vconst, n->type->etype); 65 } 66 break; 67 68 case OCONST: 69 break; 70 71 case OADD: 72 if(isf) 73 d = l->fconst + r->fconst; 74 else { 75 v = l->vconst + r->vconst; 76 } 77 break; 78 79 case OSUB: 80 if(isf) 81 d = l->fconst - r->fconst; 82 else 83 v = l->vconst - r->vconst; 84 break; 85 86 case OMUL: 87 if(isf) 88 d = l->fconst * r->fconst; 89 else { 90 v = l->vconst * r->vconst; 91 } 92 break; 93 94 case OLMUL: 95 v = (uvlong)l->vconst * (uvlong)r->vconst; 96 break; 97 98 99 case ODIV: 100 if(vconst(r) == 0) { 101 warn(n, "divide by zero"); 102 return; 103 } 104 if(isf) 105 d = l->fconst / r->fconst; 106 else 107 v = l->vconst / r->vconst; 108 break; 109 110 case OLDIV: 111 if(vconst(r) == 0) { 112 warn(n, "divide by zero"); 113 return; 114 } 115 v = (uvlong)l->vconst / (uvlong)r->vconst; 116 break; 117 118 case OMOD: 119 if(vconst(r) == 0) { 120 warn(n, "modulo by zero"); 121 return; 122 } 123 v = l->vconst % r->vconst; 124 break; 125 126 case OLMOD: 127 if(vconst(r) == 0) { 128 warn(n, "modulo by zero"); 129 return; 130 } 131 v = (uvlong)l->vconst % (uvlong)r->vconst; 132 break; 133 134 case OAND: 135 v = l->vconst & r->vconst; 136 break; 137 138 case OOR: 139 v = l->vconst | r->vconst; 140 break; 141 142 case OXOR: 143 v = l->vconst ^ r->vconst; 144 break; 145 146 case OLSHR: 147 v = (uvlong)l->vconst >> r->vconst; 148 break; 149 150 case OASHR: 151 v = l->vconst >> r->vconst; 152 break; 153 154 case OASHL: 155 v = l->vconst << r->vconst; 156 break; 157 158 case OLO: 159 v = (uvlong)l->vconst < (uvlong)r->vconst; 160 break; 161 162 case OLT: 163 if(typefd[l->type->etype]) 164 v = l->fconst < r->fconst; 165 else 166 v = l->vconst < r->vconst; 167 break; 168 169 case OHI: 170 v = (uvlong)l->vconst > (uvlong)r->vconst; 171 break; 172 173 case OGT: 174 if(typefd[l->type->etype]) 175 v = l->fconst > r->fconst; 176 else 177 v = l->vconst > r->vconst; 178 break; 179 180 case OLS: 181 v = (uvlong)l->vconst <= (uvlong)r->vconst; 182 break; 183 184 case OLE: 185 if(typefd[l->type->etype]) 186 v = l->fconst <= r->fconst; 187 else 188 v = l->vconst <= r->vconst; 189 break; 190 191 case OHS: 192 v = (uvlong)l->vconst >= (uvlong)r->vconst; 193 break; 194 195 case OGE: 196 if(typefd[l->type->etype]) 197 v = l->fconst >= r->fconst; 198 else 199 v = l->vconst >= r->vconst; 200 break; 201 202 case OEQ: 203 if(typefd[l->type->etype]) 204 v = l->fconst == r->fconst; 205 else 206 v = l->vconst == r->vconst; 207 break; 208 209 case ONE: 210 if(typefd[l->type->etype]) 211 v = l->fconst != r->fconst; 212 else 213 v = l->vconst != r->vconst; 214 break; 215 216 case ONOT: 217 if(typefd[l->type->etype]) 218 v = !l->fconst; 219 else 220 v = !l->vconst; 221 break; 222 223 case OANDAND: 224 if(typefd[l->type->etype]) 225 v = l->fconst && r->fconst; 226 else 227 v = l->vconst && r->vconst; 228 break; 229 230 case OOROR: 231 if(typefd[l->type->etype]) 232 v = l->fconst || r->fconst; 233 else 234 v = l->vconst || r->vconst; 235 break; 236 } 237 if(isf) { 238 n->fconst = d; 239 } else { 240 n->vconst = convvtox(v, n->type->etype); 241 } 242 n->oldop = n->op; 243 n->op = OCONST; 244 } 245 246 void 247 acom(Node *n) 248 { 249 Type *t; 250 Node *l, *r; 251 int i; 252 253 switch(n->op) 254 { 255 256 case ONAME: 257 case OCONST: 258 case OSTRING: 259 case OINDREG: 260 case OREGISTER: 261 return; 262 263 case ONEG: 264 l = n->left; 265 if(addo(n) && addo(l)) 266 break; 267 acom(l); 268 return; 269 270 case OADD: 271 case OSUB: 272 case OMUL: 273 l = n->left; 274 r = n->right; 275 if(addo(n)) { 276 if(addo(r)) 277 break; 278 if(addo(l)) 279 break; 280 } 281 acom(l); 282 acom(r); 283 return; 284 285 default: 286 l = n->left; 287 r = n->right; 288 if(l != Z) 289 acom(l); 290 if(r != Z) 291 acom(r); 292 return; 293 } 294 295 /* bust terms out */ 296 t = n->type; 297 term[0].mult = 0; 298 term[0].node = Z; 299 nterm = 1; 300 acom1(1, n); 301 if(debug['m']) 302 for(i=0; i<nterm; i++) { 303 print("%d %3lld ", i, term[i].mult); 304 prtree1(term[i].node, 1, 0); 305 } 306 if(nterm < NTERM) 307 acom2(n, t); 308 n->type = t; 309 } 310 311 int 312 acomcmp1(const void *a1, const void *a2) 313 { 314 vlong c1, c2; 315 Term *t1, *t2; 316 317 t1 = (Term*)a1; 318 t2 = (Term*)a2; 319 c1 = t1->mult; 320 if(c1 < 0) 321 c1 = -c1; 322 c2 = t2->mult; 323 if(c2 < 0) 324 c2 = -c2; 325 if(c1 > c2) 326 return 1; 327 if(c1 < c2) 328 return -1; 329 c1 = 1; 330 if(t1->mult < 0) 331 c1 = 0; 332 c2 = 1; 333 if(t2->mult < 0) 334 c2 = 0; 335 if(c2 -= c1) 336 return c2; 337 if(t2 > t1) 338 return 1; 339 return -1; 340 } 341 342 int 343 acomcmp2(const void *a1, const void *a2) 344 { 345 vlong c1, c2; 346 Term *t1, *t2; 347 348 t1 = (Term*)a1; 349 t2 = (Term*)a2; 350 c1 = t1->mult; 351 c2 = t2->mult; 352 if(c1 > c2) 353 return 1; 354 if(c1 < c2) 355 return -1; 356 if(t2 > t1) 357 return 1; 358 return -1; 359 } 360 361 void 362 acom2(Node *n, Type *t) 363 { 364 Node *l, *r; 365 Term trm[NTERM]; 366 int et, nt, i, j; 367 vlong c1, c2; 368 369 /* 370 * copy into automatic 371 */ 372 c2 = 0; 373 nt = nterm; 374 for(i=0; i<nt; i++) 375 trm[i] = term[i]; 376 /* 377 * recur on subtrees 378 */ 379 j = 0; 380 for(i=1; i<nt; i++) { 381 c1 = trm[i].mult; 382 if(c1 == 0) 383 continue; 384 l = trm[i].node; 385 if(l != Z) { 386 j = 1; 387 acom(l); 388 } 389 } 390 c1 = trm[0].mult; 391 if(j == 0) { 392 n->oldop = n->op; 393 n->op = OCONST; 394 n->vconst = c1; 395 return; 396 } 397 et = t->etype; 398 399 /* 400 * prepare constant term, 401 * combine it with an addressing term 402 */ 403 if(c1 != 0) { 404 l = new1(OCONST, Z, Z); 405 l->type = t; 406 l->vconst = c1; 407 trm[0].mult = 1; 408 for(i=1; i<nt; i++) { 409 if(trm[i].mult != 1) 410 continue; 411 r = trm[i].node; 412 if(r->op != OADDR) 413 continue; 414 r->type = t; 415 l = new1(OADD, r, l); 416 l->type = t; 417 trm[i].mult = 0; 418 break; 419 } 420 trm[0].node = l; 421 } 422 /* 423 * look for factorable terms 424 * c1*i + c1*c2*j -> c1*(i + c2*j) 425 */ 426 qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp1); 427 for(i=nt-1; i>=0; i--) { 428 c1 = trm[i].mult; 429 if(c1 < 0) 430 c1 = -c1; 431 if(c1 <= 1) 432 continue; 433 for(j=i+1; j<nt; j++) { 434 c2 = trm[j].mult; 435 if(c2 < 0) 436 c2 = -c2; 437 if(c2 <= 1) 438 continue; 439 if(c2 % c1) 440 continue; 441 r = trm[j].node; 442 if(r->type->etype != et) 443 r = acast(t, r); 444 c2 = trm[j].mult/trm[i].mult; 445 if(c2 != 1 && c2 != -1) { 446 r = new1(OMUL, r, new(OCONST, Z, Z)); 447 r->type = t; 448 r->right->type = t; 449 r->right->vconst = c2; 450 } 451 l = trm[i].node; 452 if(l->type->etype != et) 453 l = acast(t, l); 454 r = new1(OADD, l, r); 455 r->type = t; 456 if(c2 == -1) 457 r->op = OSUB; 458 trm[i].node = r; 459 trm[j].mult = 0; 460 } 461 } 462 if(debug['m']) { 463 print("\n"); 464 for(i=0; i<nt; i++) { 465 print("%d %3lld ", i, trm[i].mult); 466 prtree1(trm[i].node, 1, 0); 467 } 468 } 469 470 /* 471 * put it all back together 472 */ 473 qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp2); 474 l = Z; 475 for(i=nt-1; i>=0; i--) { 476 c1 = trm[i].mult; 477 if(c1 == 0) 478 continue; 479 r = trm[i].node; 480 if(r->type->etype != et || r->op == OBIT) 481 r = acast(t, r); 482 if(c1 != 1 && c1 != -1) { 483 r = new1(OMUL, r, new(OCONST, Z, Z)); 484 r->type = t; 485 r->right->type = t; 486 if(c1 < 0) { 487 r->right->vconst = -c1; 488 c1 = -1; 489 } else { 490 r->right->vconst = c1; 491 c1 = 1; 492 } 493 } 494 if(l == Z) { 495 l = r; 496 c2 = c1; 497 continue; 498 } 499 if(c1 < 0) 500 if(c2 < 0) 501 l = new1(OADD, l, r); 502 else 503 l = new1(OSUB, l, r); 504 else 505 if(c2 < 0) { 506 l = new1(OSUB, r, l); 507 c2 = 1; 508 } else 509 l = new1(OADD, l, r); 510 l->type = t; 511 } 512 if(c2 < 0) { 513 r = new1(OCONST, 0, 0); 514 r->vconst = 0; 515 r->type = t; 516 l = new1(OSUB, r, l); 517 l->type = t; 518 } 519 *n = *l; 520 } 521 522 void 523 acom1(vlong v, Node *n) 524 { 525 Node *l, *r; 526 527 if(v == 0 || nterm >= NTERM) 528 return; 529 if(!addo(n)) { 530 if(n->op == OCONST) 531 if(!typefd[n->type->etype]) { 532 term[0].mult += v*n->vconst; 533 return; 534 } 535 term[nterm].mult = v; 536 term[nterm].node = n; 537 nterm++; 538 return; 539 } 540 switch(n->op) { 541 542 case OCAST: 543 acom1(v, n->left); 544 break; 545 546 case ONEG: 547 acom1(-v, n->left); 548 break; 549 550 case OADD: 551 acom1(v, n->left); 552 acom1(v, n->right); 553 break; 554 555 case OSUB: 556 acom1(v, n->left); 557 acom1(-v, n->right); 558 break; 559 560 case OMUL: 561 l = n->left; 562 r = n->right; 563 if(l->op == OCONST) 564 if(!typefd[n->type->etype]) { 565 acom1(v*l->vconst, r); 566 break; 567 } 568 if(r->op == OCONST) 569 if(!typefd[n->type->etype]) { 570 acom1(v*r->vconst, l); 571 break; 572 } 573 break; 574 575 default: 576 diag(n, "not addo"); 577 } 578 } 579 580 int 581 addo(Node *n) 582 { 583 584 if(n != Z) 585 if(!typefd[n->type->etype]) 586 if(!typev[n->type->etype] || ewidth[TVLONG] == ewidth[TIND]) 587 switch(n->op) { 588 589 case OCAST: 590 if(nilcast(n->left->type, n->type)) 591 return 1; 592 break; 593 594 case ONEG: 595 case OADD: 596 case OSUB: 597 return 1; 598 599 case OMUL: 600 if(n->left->op == OCONST) 601 return 1; 602 if(n->right->op == OCONST) 603 return 1; 604 } 605 return 0; 606 } 607