1 #include "gc.h" 2 3 void 4 codgen(Node *n, Node *nn) 5 { 6 Prog *sp; 7 Node *n1, nod, nod1; 8 9 cursafe = 0; 10 curarg = 0; 11 maxargsafe = 0; 12 13 /* 14 * isolate name 15 */ 16 for(n1 = nn;; n1 = n1->left) { 17 if(n1 == Z) { 18 diag(nn, "cant find function name"); 19 return; 20 } 21 if(n1->op == ONAME) 22 break; 23 } 24 nearln = nn->lineno; 25 gpseudo(ATEXT, n1->sym, nodconst(stkoff)); 26 sp = p; 27 28 /* 29 * isolate first argument 30 */ 31 if(REGARG) { 32 if(typesuv[thisfn->link->etype]) { 33 nod1 = *nodret->left; 34 nodreg(&nod, &nod1, REGARG); 35 gopcode(OAS, &nod, Z, &nod1); 36 } else 37 if(firstarg && typechlp[firstargtype->etype]) { 38 nod1 = *nodret->left; 39 nod1.sym = firstarg; 40 nod1.type = firstargtype; 41 nod1.xoffset = align(0, firstargtype, Aarg1); 42 nod1.etype = firstargtype->etype; 43 nodreg(&nod, &nod1, REGARG); 44 gopcode(OAS, &nod, Z, &nod1); 45 } 46 } 47 48 retok = 0; 49 gen(n); 50 if(!retok) 51 if(thisfn->link->etype != TVOID) 52 warn(Z, "no return at end of function: %s", n1->sym->name); 53 noretval(3); 54 gbranch(ORETURN); 55 56 if(!debug['N'] || debug['R'] || debug['P']) 57 regopt(sp); 58 59 sp->to.offset += maxargsafe; 60 } 61 62 void 63 supgen(Node *n) 64 { 65 long spc; 66 Prog *sp; 67 68 if(n == Z) 69 return; 70 suppress++; 71 spc = pc; 72 sp = lastp; 73 gen(n); 74 lastp = sp; 75 pc = spc; 76 sp->link = nil; 77 suppress--; 78 } 79 80 void 81 gen(Node *n) 82 { 83 Node *l, nod; 84 Prog *sp, *spc, *spb; 85 Case *cn; 86 long sbc, scc; 87 int o, f; 88 89 loop: 90 if(n == Z) 91 return; 92 nearln = n->lineno; 93 o = n->op; 94 if(debug['G']) 95 if(o != OLIST) 96 print("%L %O\n", nearln, o); 97 retok = 0; 98 switch(o) { 99 100 default: 101 complex(n); 102 cgen(n, Z); 103 break; 104 105 case OLIST: 106 gen(n->left); 107 108 rloop: 109 n = n->right; 110 goto loop; 111 112 case ORETURN: 113 retok = 1; 114 complex(n); 115 if(n->type == T) 116 break; 117 l = n->left; 118 if(l == Z) { 119 noretval(3); 120 gbranch(ORETURN); 121 break; 122 } 123 if(typesuv[n->type->etype]) { 124 sugen(l, nodret, n->type->width); 125 noretval(3); 126 gbranch(ORETURN); 127 break; 128 } 129 regret(&nod, n); 130 cgen(l, &nod); 131 regfree(&nod); 132 if(typefd[n->type->etype]) 133 noretval(1); 134 else 135 noretval(2); 136 gbranch(ORETURN); 137 break; 138 139 case OLABEL: 140 l = n->left; 141 if(l) { 142 l->xoffset = pc; 143 if(l->label) 144 patch(l->label, pc); 145 } 146 gbranch(OGOTO); /* prevent self reference in reg */ 147 patch(p, pc); 148 goto rloop; 149 150 case OGOTO: 151 retok = 1; 152 n = n->left; 153 if(n == Z) 154 return; 155 if(n->complex == 0) { 156 diag(Z, "label undefined: %s", n->sym->name); 157 return; 158 } 159 if(suppress) 160 return; 161 gbranch(OGOTO); 162 if(n->xoffset) { 163 patch(p, n->xoffset); 164 return; 165 } 166 if(n->label) 167 patch(n->label, pc-1); 168 n->label = p; 169 return; 170 171 case OCASE: 172 l = n->left; 173 if(cases == C) 174 diag(n, "case/default outside a switch"); 175 if(l == Z) { 176 cas(); 177 cases->val = 0; 178 cases->def = 1; 179 cases->label = pc; 180 goto rloop; 181 } 182 complex(l); 183 if(l->type == T) 184 goto rloop; 185 if(l->op == OCONST) 186 if(typechl[l->type->etype]) { 187 cas(); 188 cases->val = l->vconst; 189 cases->def = 0; 190 cases->label = pc; 191 goto rloop; 192 } 193 diag(n, "case expression must be integer constant"); 194 goto rloop; 195 196 case OSWITCH: 197 l = n->left; 198 complex(l); 199 if(l->type == T) 200 break; 201 if(!typechl[l->type->etype]) { 202 diag(n, "switch expression must be integer"); 203 break; 204 } 205 206 gbranch(OGOTO); /* entry */ 207 sp = p; 208 209 cn = cases; 210 cases = C; 211 cas(); 212 213 sbc = breakpc; 214 breakpc = pc; 215 gbranch(OGOTO); 216 spb = p; 217 218 gen(n->right); 219 gbranch(OGOTO); 220 patch(p, breakpc); 221 222 patch(sp, pc); 223 regalloc(&nod, l, Z); 224 nod.type = types[TLONG]; 225 cgen(l, &nod); 226 doswit(&nod); 227 regfree(&nod); 228 patch(spb, pc); 229 230 cases = cn; 231 breakpc = sbc; 232 break; 233 234 case OWHILE: 235 case ODWHILE: 236 l = n->left; 237 gbranch(OGOTO); /* entry */ 238 sp = p; 239 240 scc = continpc; 241 continpc = pc; 242 gbranch(OGOTO); 243 spc = p; 244 245 sbc = breakpc; 246 breakpc = pc; 247 gbranch(OGOTO); 248 spb = p; 249 250 patch(spc, pc); 251 if(n->op == OWHILE) 252 patch(sp, pc); 253 bcomplex(l, Z); /* test */ 254 patch(p, breakpc); 255 256 if(n->op == ODWHILE) 257 patch(sp, pc); 258 gen(n->right); /* body */ 259 gbranch(OGOTO); 260 patch(p, continpc); 261 262 patch(spb, pc); 263 continpc = scc; 264 breakpc = sbc; 265 break; 266 267 case OFOR: 268 l = n->left; 269 gen(l->right->left); /* init */ 270 gbranch(OGOTO); /* entry */ 271 sp = p; 272 273 scc = continpc; 274 continpc = pc; 275 gbranch(OGOTO); 276 spc = p; 277 278 sbc = breakpc; 279 breakpc = pc; 280 gbranch(OGOTO); 281 spb = p; 282 283 patch(spc, pc); 284 gen(l->right->right); /* inc */ 285 patch(sp, pc); 286 if(l->left != Z) { /* test */ 287 bcomplex(l->left, Z); 288 patch(p, breakpc); 289 } 290 gen(n->right); /* body */ 291 gbranch(OGOTO); 292 patch(p, continpc); 293 294 patch(spb, pc); 295 continpc = scc; 296 breakpc = sbc; 297 break; 298 299 case OCONTINUE: 300 if(continpc < 0) { 301 diag(n, "continue not in a loop"); 302 break; 303 } 304 gbranch(OGOTO); 305 patch(p, continpc); 306 break; 307 308 case OBREAK: 309 if(breakpc < 0) { 310 diag(n, "break not in a loop"); 311 break; 312 } 313 gbranch(OGOTO); 314 patch(p, breakpc); 315 break; 316 317 case OIF: 318 l = n->left; 319 if(bcomplex(l, n->right)) { 320 if(typefd[l->type->etype]) 321 f = !l->fconst; 322 else 323 f = !l->vconst; 324 if(debug['c']) 325 print("%L const if %s\n", nearln, f ? "false" : "true"); 326 if(f) { 327 supgen(n->right->left); 328 gen(n->right->right); 329 } 330 else { 331 gen(n->right->left); 332 supgen(n->right->right); 333 } 334 } 335 else { 336 sp = p; 337 if(n->right->left != Z) 338 gen(n->right->left); 339 if(n->right->right != Z) { 340 gbranch(OGOTO); 341 patch(sp, pc); 342 sp = p; 343 gen(n->right->right); 344 } 345 patch(sp, pc); 346 } 347 break; 348 349 case OSET: 350 case OUSED: 351 usedset(n->left, o); 352 break; 353 } 354 } 355 356 void 357 usedset(Node *n, int o) 358 { 359 if(n->op == OLIST) { 360 usedset(n->left, o); 361 usedset(n->right, o); 362 return; 363 } 364 complex(n); 365 switch(n->op) { 366 case OADDR: /* volatile */ 367 gins(ANOP, n, Z); 368 break; 369 case ONAME: 370 if(o == OSET) 371 gins(ANOP, Z, n); 372 else 373 gins(ANOP, n, Z); 374 break; 375 } 376 } 377 378 void 379 noretval(int n) 380 { 381 382 if(n & 1) { 383 gins(ANOP, Z, Z); 384 p->to.type = D_REG; 385 p->to.reg = REGRET; 386 } 387 if(n & 2) { 388 gins(ANOP, Z, Z); 389 p->to.type = D_FREG; 390 p->to.reg = FREGRET; 391 } 392 } 393 394 /* 395 * calculate addressability as follows 396 * CONST ==> 20 $value 397 * NAME ==> 10 name 398 * REGISTER ==> 11 register 399 * INDREG ==> 12 *[(reg)+offset] 400 * &10 ==> 2 $name 401 * ADD(2, 20) ==> 2 $name+offset 402 * ADD(3, 20) ==> 3 $(reg)+offset 403 * &12 ==> 3 $(reg)+offset 404 * *11 ==> 11 ?? 405 * *2 ==> 10 name 406 * *3 ==> 12 *(reg)+offset 407 * calculate complexity (number of registers) 408 */ 409 void 410 xcom(Node *n) 411 { 412 Node *l, *r; 413 int v; 414 415 if(n == Z) 416 return; 417 l = n->left; 418 r = n->right; 419 n->addable = 0; 420 n->complex = 0; 421 switch(n->op) { 422 case OCONST: 423 n->addable = 20; 424 return; 425 426 case OREGISTER: 427 n->addable = 11; 428 return; 429 430 case OINDREG: 431 n->addable = 12; 432 return; 433 434 case ONAME: 435 n->addable = 10; 436 return; 437 438 case OADDR: 439 xcom(l); 440 if(l->addable == 10) 441 n->addable = 2; 442 if(l->addable == 12) 443 n->addable = 3; 444 break; 445 446 case OIND: 447 xcom(l); 448 if(l->addable == 11) 449 n->addable = 12; 450 if(l->addable == 3) 451 n->addable = 12; 452 if(l->addable == 2) 453 n->addable = 10; 454 break; 455 456 case OADD: 457 xcom(l); 458 xcom(r); 459 if(l->addable == 20) { 460 if(r->addable == 2) 461 n->addable = 2; 462 if(r->addable == 3) 463 n->addable = 3; 464 } 465 if(r->addable == 20) { 466 if(l->addable == 2) 467 n->addable = 2; 468 if(l->addable == 3) 469 n->addable = 3; 470 } 471 break; 472 473 case OASMUL: 474 case OASLMUL: 475 xcom(l); 476 xcom(r); 477 v = vlog(r); 478 if(v >= 0) { 479 n->op = OASASHL; 480 r->vconst = v; 481 r->type = types[TINT]; 482 } 483 break; 484 485 case OMUL: 486 case OLMUL: 487 xcom(l); 488 xcom(r); 489 v = vlog(r); 490 if(v >= 0) { 491 n->op = OASHL; 492 r->vconst = v; 493 r->type = types[TINT]; 494 } 495 v = vlog(l); 496 if(v >= 0) { 497 n->op = OASHL; 498 n->left = r; 499 n->right = l; 500 r = l; 501 l = n->left; 502 r->vconst = v; 503 r->type = types[TINT]; 504 simplifyshift(n); 505 } 506 break; 507 508 case OASLDIV: 509 xcom(l); 510 xcom(r); 511 v = vlog(r); 512 if(v >= 0) { 513 n->op = OASLSHR; 514 r->vconst = v; 515 r->type = types[TINT]; 516 } 517 break; 518 519 case OLDIV: 520 xcom(l); 521 xcom(r); 522 v = vlog(r); 523 if(v >= 0) { 524 n->op = OLSHR; 525 r->vconst = v; 526 r->type = types[TINT]; 527 simplifyshift(n); 528 } 529 break; 530 531 case OASLMOD: 532 xcom(l); 533 xcom(r); 534 v = vlog(r); 535 if(v >= 0) { 536 n->op = OASAND; 537 r->vconst--; 538 } 539 break; 540 541 case OLMOD: 542 xcom(l); 543 xcom(r); 544 v = vlog(r); 545 if(v >= 0) { 546 n->op = OAND; 547 r->vconst--; 548 } 549 break; 550 551 case OLSHR: 552 case OASHL: 553 case OASHR: 554 xcom(l); 555 xcom(r); 556 simplifyshift(n); 557 break; 558 559 default: 560 if(l != Z) 561 xcom(l); 562 if(r != Z) 563 xcom(r); 564 break; 565 } 566 if(n->addable >= 10) 567 return; 568 if(l != Z) 569 n->complex = l->complex; 570 if(r != Z) { 571 if(r->complex == n->complex) 572 n->complex = r->complex+1; 573 else 574 if(r->complex > n->complex) 575 n->complex = r->complex; 576 } 577 if(n->complex == 0) 578 n->complex++; 579 580 if(com64(n)) 581 return; 582 583 switch(n->op) { 584 585 case OFUNC: 586 n->complex = FNX; 587 break; 588 589 case OEQ: 590 case ONE: 591 case OLE: 592 case OLT: 593 case OGE: 594 case OGT: 595 case OHI: 596 case OHS: 597 case OLO: 598 case OLS: 599 /* 600 * immediate operators, make const on right 601 */ 602 if(l->op == OCONST) { 603 n->left = r; 604 n->right = l; 605 n->op = invrel[relindex(n->op)]; 606 } 607 break; 608 609 case OADD: 610 case OXOR: 611 case OAND: 612 case OOR: 613 /* 614 * immediate operators, make const on right 615 */ 616 if(l->op == OCONST) { 617 n->left = r; 618 n->right = l; 619 } 620 break; 621 } 622 } 623 624 int 625 bcomplex(Node *n, Node *c) 626 { 627 628 complex(n); 629 if(n->type != T) 630 if(tcompat(n, T, n->type, tnot)) 631 n->type = T; 632 if(n->type != T) { 633 if(c != Z && n->op == OCONST && deadheads(c)) 634 return 1; 635 bool64(n); 636 boolgen(n, 1, Z); 637 } else 638 gbranch(OGOTO); 639 return 0; 640 } 641