Unified · Split
| @@ -9,7 +9,9 @@ · 8 unmodified lines | ||
| 9 | 9 | #define REGRET 0 |
| 10 | 10 | #define REGARG 0 |
| 11 | 11 | /* compiler allocates R1 up as temps */ |
| 12 | −/* compiler allocates register variables R3 up */ | |
| 12 | +/* compiler allocates register variables R2 up */ | |
| 13 | +#define REGMIN 2 | |
| 14 | +#define REGMAX 8 | |
| 13 | 15 | #define REGEXT 10 |
| 14 | 16 | /* compiler allocates external registers R10 down */ |
| 15 | 17 | #define REGTMP 11 |
| @@ -1,7 +1,13 @@ | ||
| 1 | 1 | #include "gc.h" |
| 2 | 2 | |
| 3 | 3 | void |
| 4 | −cgen(Node *n, Node *nn, int inrel) | |
| 4 | +cgen(Node *n, Node *nn) | |
| 5 | +{ | |
| 6 | + cgenrel(n, nn, 0); | |
| 7 | +} | |
| 8 | + | |
| 9 | +void | |
| 10 | +cgenrel(Node *n, Node *nn, int inrel) | |
| 5 | 11 | { |
| 6 | 12 | Node *l, *r; |
| 7 | 13 | Prog *p1; |
| @@ -45,7 +51,7 @@ cgen(Node *n, Node *nn, int inrel) · 37 unmodified lines | ||
| 45 | 51 | switch(o) { |
| 46 | 52 | default: |
| 47 | 53 | regret(&nod, r); |
| 48 | − cgen(r, &nod, 0); | |
| 54 | + cgen(r, &nod); | |
| 49 | 55 | |
| 50 | 56 | regsalloc(&nod1, r); |
| 51 | 57 | gopcode(OAS, &nod, Z, &nod1); |
| @@ -53,7 +59,7 @@ cgen(Node *n, Node *nn, int inrel) · 1 unmodified line | ||
| 53 | 59 | regfree(&nod); |
| 54 | 60 | nod = *n; |
| 55 | 61 | nod.right = &nod1; |
| 56 | − cgen(&nod, nn, 0); | |
| 62 | + cgen(&nod, nn); | |
| 57 | 63 | return; |
| 58 | 64 | |
| 59 | 65 | case OFUNC: |
| @@ -79,7 +85,7 @@ cgen(Node *n, Node *nn, int inrel) · 19 unmodified lines | ||
| 79 | 85 | regret(&nod, r); |
| 80 | 86 | else |
| 81 | 87 | regalloc(&nod, r, nn); |
| 82 | − cgen(r, &nod, 0); | |
| 88 | + cgen(r, &nod); | |
| 83 | 89 | gmove(&nod, l); |
| 84 | 90 | if(nn != Z) |
| 85 | 91 | gmove(&nod, nn); |
| @@ -98,10 +104,10 @@ cgen(Node *n, Node *nn, int inrel) · 12 unmodified lines | ||
| 98 | 104 | break; |
| 99 | 105 | } |
| 100 | 106 | regalloc(&nod, r, nn); |
| 101 | − cgen(r, &nod, 0); | |
| 107 | + cgen(r, &nod); | |
| 102 | 108 | } else { |
| 103 | 109 | regalloc(&nod, r, nn); |
| 104 | − cgen(r, &nod, 0); | |
| 110 | + cgen(r, &nod); | |
| 105 | 111 | reglcgen(&nod1, l, Z); |
| 106 | 112 | } |
| 107 | 113 | gmove(&nod, &nod1); |
| @@ -114,9 +120,9 @@ cgen(Node *n, Node *nn, int inrel) · 6 unmodified lines | ||
| 114 | 120 | regalloc(&nod, r, nn); |
| 115 | 121 | if(l->complex >= r->complex) { |
| 116 | 122 | reglcgen(&nod1, n, Z); |
| 117 | − cgen(r, &nod, 0); | |
| 123 | + cgen(r, &nod); | |
| 118 | 124 | } else { |
| 119 | − cgen(r, &nod, 0); | |
| 125 | + cgen(r, &nod); | |
| 120 | 126 | reglcgen(&nod1, n, Z); |
| 121 | 127 | } |
| 122 | 128 | regalloc(&nod2, n, Z); |
| @@ -139,7 +145,7 @@ cgen(Node *n, Node *nn, int inrel) · 16 unmodified lines | ||
| 139 | 145 | if(nn != Z) |
| 140 | 146 | if((t = vlog(r)) >= 0) { |
| 141 | 147 | /* signed div/mod by constant power of 2 */ |
| 142 | − cgen(l, nn, 0); | |
| 148 | + cgen(l, nn); | |
| 143 | 149 | gopcode(OGE, nodconst(0), nn, Z); |
| 144 | 150 | p1 = p; |
| 145 | 151 | if(o == ODIV) { |
| @@ -164,7 +170,7 @@ cgen(Node *n, Node *nn, int inrel) · 18 unmodified lines | ||
| 164 | 170 | if(nn != Z) |
| 165 | 171 | if(l->op == OCONST) |
| 166 | 172 | if(!typefd[n->type->etype]) { |
| 167 | − cgen(r, nn, 0); | |
| 173 | + cgen(r, nn); | |
| 168 | 174 | gopcode(o, Z, l, nn); |
| 169 | 175 | break; |
| 170 | 176 | } |
| @@ -181,7 +187,7 @@ cgen(Node *n, Node *nn, int inrel) · 10 unmodified lines | ||
| 181 | 187 | if(nn != Z) |
| 182 | 188 | if(r->op == OCONST) |
| 183 | 189 | if(!typefd[n->type->etype]) { |
| 184 | − cgen(l, nn, 0); | |
| 190 | + cgen(l, nn); | |
| 185 | 191 | if(r->vconst == 0) |
| 186 | 192 | if(o != OAND) |
| 187 | 193 | break; |
| @@ -205,15 +211,15 @@ cgen(Node *n, Node *nn, int inrel) · 17 unmodified lines | ||
| 205 | 211 | } |
| 206 | 212 | if(l->complex >= r->complex) { |
| 207 | 213 | regalloc(&nod, l, nn); |
| 208 | − cgen(l, &nod, 0); | |
| 214 | + cgen(l, &nod); | |
| 209 | 215 | regalloc(&nod1, r, Z); |
| 210 | − cgen(r, &nod1, 0); | |
| 216 | + cgen(r, &nod1); | |
| 211 | 217 | gopcode(o, &nod1, Z, &nod); |
| 212 | 218 | } else { |
| 213 | 219 | regalloc(&nod, r, nn); |
| 214 | − cgen(r, &nod, 0); | |
| 220 | + cgen(r, &nod); | |
| 215 | 221 | regalloc(&nod1, l, Z); |
| 216 | − cgen(l, &nod1, 0); | |
| 222 | + cgen(l, &nod1); | |
| 217 | 223 | gopcode(o, &nod, &nod1, &nod); |
| 218 | 224 | } |
| 219 | 225 | gopcode(OAS, &nod, Z, nn); |
| @@ -263,10 +269,10 @@ cgen(Node *n, Node *nn, int inrel) · 43 unmodified lines | ||
| 263 | 269 | else |
| 264 | 270 | nod2 = *l; |
| 265 | 271 | regalloc(&nod1, r, Z); |
| 266 | − cgen(r, &nod1, 0); | |
| 272 | + cgen(r, &nod1); | |
| 267 | 273 | } else { |
| 268 | 274 | regalloc(&nod1, r, Z); |
| 269 | − cgen(r, &nod1, 0); | |
| 275 | + cgen(r, &nod1); | |
| 270 | 276 | if(l->addable < INDEXED) |
| 271 | 277 | reglcgen(&nod2, l, Z); |
| 272 | 278 | else |
| @@ -290,10 +296,10 @@ cgen(Node *n, Node *nn, int inrel) · 17 unmodified lines | ||
| 290 | 296 | if(l->complex >= r->complex) { |
| 291 | 297 | bitload(l, &nod, &nod1, &nod2, &nod4); |
| 292 | 298 | regalloc(&nod3, r, Z); |
| 293 | − cgen(r, &nod3, 0); | |
| 299 | + cgen(r, &nod3); | |
| 294 | 300 | } else { |
| 295 | 301 | regalloc(&nod3, r, Z); |
| 296 | − cgen(r, &nod3, 0); | |
| 302 | + cgen(r, &nod3); | |
| 297 | 303 | bitload(l, &nod, &nod1, &nod2, &nod4); |
| 298 | 304 | } |
| 299 | 305 | gmove(&nod, &nod4); |
| @@ -318,7 +324,7 @@ cgen(Node *n, Node *nn, int inrel) · 18 unmodified lines | ||
| 318 | 324 | diag(n, "bad function call"); |
| 319 | 325 | |
| 320 | 326 | regret(&nod, l->left); |
| 321 | − cgen(l->left, &nod, 0); | |
| 327 | + cgen(l->left, &nod); | |
| 322 | 328 | regsalloc(&nod1, l->left); |
| 323 | 329 | gopcode(OAS, &nod, Z, &nod1); |
| 324 | 330 | regfree(&nod); |
| @@ -328,7 +334,7 @@ cgen(Node *n, Node *nn, int inrel) · 3 unmodified lines | ||
| 328 | 334 | nod2 = *l; |
| 329 | 335 | nod2.left = &nod1; |
| 330 | 336 | nod2.complex = 1; |
| 331 | − cgen(&nod, nn, 0); | |
| 337 | + cgen(&nod, nn); | |
| 332 | 338 | |
| 333 | 339 | return; |
| 334 | 340 | } |
| @@ -363,11 +369,11 @@ cgen(Node *n, Node *nn, int inrel) · 28 unmodified lines | ||
| 363 | 369 | if(sconst(r) && (v = r->vconst+nod.xoffset) > -4096 && v < 4096) { |
| 364 | 370 | v = r->vconst; |
| 365 | 371 | r->vconst = 0; |
| 366 | − cgen(l, &nod, 0); | |
| 372 | + cgen(l, &nod); | |
| 367 | 373 | nod.xoffset += v; |
| 368 | 374 | r->vconst = v; |
| 369 | 375 | } else |
| 370 | − cgen(l, &nod, 0); | |
| 376 | + cgen(l, &nod); | |
| 371 | 377 | regind(&nod, n); |
| 372 | 378 | gopcode(OAS, &nod, Z, nn); |
| 373 | 379 | regfree(&nod); |
| @@ -406,8 +412,8 @@ cgen(Node *n, Node *nn, int inrel) · 32 unmodified lines | ||
| 406 | 412 | break; |
| 407 | 413 | |
| 408 | 414 | case OCOMMA: |
| 409 | − cgen(l, Z, 0); | |
| 410 | − cgen(r, nn, 0); | |
| 415 | + cgen(l, Z); | |
| 416 | + cgen(r, nn); | |
| 411 | 417 | break; |
| 412 | 418 | |
| 413 | 419 | case OCAST: |
| @@ -420,12 +426,12 @@ cgen(Node *n, Node *nn, int inrel) · 6 unmodified lines | ||
| 420 | 426 | */ |
| 421 | 427 | if(nocast(l->type, n->type)) { |
| 422 | 428 | if(nocast(n->type, nn->type)) { |
| 423 | − cgen(l, nn, 0); | |
| 429 | + cgen(l, nn); | |
| 424 | 430 | break; |
| 425 | 431 | } |
| 426 | 432 | } |
| 427 | 433 | regalloc(&nod, l, nn); |
| 428 | − cgen(l, &nod, 0); | |
| 434 | + cgen(l, &nod); | |
| 429 | 435 | regalloc(&nod1, n, &nod); |
| 430 | 436 | if(inrel) |
| 431 | 437 | gmover(&nod, &nod1); |
| @@ -447,18 +453,18 @@ cgen(Node *n, Node *nn, int inrel) · 15 unmodified lines | ||
| 447 | 453 | } |
| 448 | 454 | nod.xoffset += (long)r->vconst; |
| 449 | 455 | nod.type = n->type; |
| 450 | − cgen(&nod, nn, 0); | |
| 456 | + cgen(&nod, nn); | |
| 451 | 457 | } |
| 452 | 458 | break; |
| 453 | 459 | |
| 454 | 460 | case OCOND: |
| 455 | 461 | bcgen(l, 1); |
| 456 | 462 | p1 = p; |
| 457 | − cgen(r->left, nn, 0); | |
| 463 | + cgen(r->left, nn); | |
| 458 | 464 | gbranch(OGOTO); |
| 459 | 465 | patch(p1, pc); |
| 460 | 466 | p1 = p; |
| 461 | − cgen(r->right, nn, 0); | |
| 467 | + cgen(r->right, nn); | |
| 462 | 468 | patch(p1, pc); |
| 463 | 469 | break; |
| 464 | 470 | |
| @@ -533,6 +539,8 @@ cgen(Node *n, Node *nn, int inrel) · 68 unmodified lines | ||
| 533 | 539 | } else |
| 534 | 540 | gopcode(OADD, nodconst(v), Z, &nod); |
| 535 | 541 | gopcode(OAS, &nod, Z, &nod2); |
| 542 | + if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */ | |
| 543 | + gins(ANOP, l, Z); | |
| 536 | 544 | |
| 537 | 545 | regfree(&nod); |
| 538 | 546 | if(l->addable < INDEXED) |
| @@ -579,7 +587,7 @@ reglcgen(Node *t, Node *n, Node *nn) · 40 unmodified lines | ||
| 579 | 587 | } else if(n->op == OINDREG) { |
| 580 | 588 | if((v = n->xoffset) > -4096 && v < 4096) { |
| 581 | 589 | n->op = OREGISTER; |
| 582 | − cgen(n, t, 0); | |
| 590 | + cgen(n, t); | |
| 583 | 591 | t->xoffset += v; |
| 584 | 592 | n->op = OINDREG; |
| 585 | 593 | regind(t, n); |
| @@ -638,12 +646,12 @@ lcgen(Node *n, Node *nn) · 52 unmodified lines | ||
| 638 | 646 | break; |
| 639 | 647 | |
| 640 | 648 | case OCOMMA: |
| 641 | − cgen(n->left, n->left, 0); | |
| 649 | + cgen(n->left, n->left); | |
| 642 | 650 | lcgen(n->right, nn); |
| 643 | 651 | break; |
| 644 | 652 | |
| 645 | 653 | case OIND: |
| 646 | − cgen(n->left, nn, 0); | |
| 654 | + cgen(n->left, nn); | |
| 647 | 655 | break; |
| 648 | 656 | |
| 649 | 657 | case OCOND: |
| @@ -688,7 +696,7 @@ boolgen(Node *n, int true, Node *nn) · 38 unmodified lines | ||
| 688 | 696 | |
| 689 | 697 | default: |
| 690 | 698 | regalloc(&nod, n, nn); |
| 691 | − cgen(n, &nod, 0); | |
| 699 | + cgen(n, &nod); | |
| 692 | 700 | o = ONE; |
| 693 | 701 | if(true) |
| 694 | 702 | o = comrel[relindex(o)]; |
| @@ -712,7 +720,7 @@ boolgen(Node *n, int true, Node *nn) · 17 unmodified lines | ||
| 712 | 720 | goto com; |
| 713 | 721 | |
| 714 | 722 | case OCOMMA: |
| 715 | − cgen(l, Z, 0); | |
| 723 | + cgen(l, Z); | |
| 716 | 724 | boolgen(r, true, nn); |
| 717 | 725 | break; |
| 718 | 726 | |
| @@ -779,7 +787,7 @@ boolgen(Node *n, int true, Node *nn) · 60 unmodified lines | ||
| 779 | 787 | o = comrel[relindex(o)]; |
| 780 | 788 | if(l->complex >= FNX && r->complex >= FNX) { |
| 781 | 789 | regret(&nod, r); |
| 782 | − cgen(r, &nod, 1); | |
| 790 | + cgenrel(r, &nod, 1); | |
| 783 | 791 | regsalloc(&nod1, r); |
| 784 | 792 | gopcode(OAS, &nod, Z, &nod1); |
| 785 | 793 | regfree(&nod); |
| @@ -790,7 +798,7 @@ boolgen(Node *n, int true, Node *nn) · 4 unmodified lines | ||
| 790 | 798 | } |
| 791 | 799 | if(sconst(l)) { |
| 792 | 800 | regalloc(&nod, r, nn); |
| 793 | − cgen(r, &nod, 1); | |
| 801 | + cgenrel(r, &nod, 1); | |
| 794 | 802 | o = invrel[relindex(o)]; |
| 795 | 803 | gopcode(o, l, &nod, Z); |
| 796 | 804 | regfree(&nod); |
| @@ -798,21 +806,21 @@ boolgen(Node *n, int true, Node *nn) · 1 unmodified line | ||
| 798 | 806 | } |
| 799 | 807 | if(sconst(r)) { |
| 800 | 808 | regalloc(&nod, l, nn); |
| 801 | − cgen(l, &nod, 1); | |
| 809 | + cgenrel(l, &nod, 1); | |
| 802 | 810 | gopcode(o, r, &nod, Z); |
| 803 | 811 | regfree(&nod); |
| 804 | 812 | goto com; |
| 805 | 813 | } |
| 806 | 814 | if(l->complex >= r->complex) { |
| 807 | 815 | regalloc(&nod1, l, nn); |
| 808 | − cgen(l, &nod1, 1); | |
| 816 | + cgenrel(l, &nod1, 1); | |
| 809 | 817 | regalloc(&nod, r, Z); |
| 810 | − cgen(r, &nod, 1); | |
| 818 | + cgenrel(r, &nod, 1); | |
| 811 | 819 | } else { |
| 812 | 820 | regalloc(&nod, r, nn); |
| 813 | − cgen(r, &nod, 1); | |
| 821 | + cgenrel(r, &nod, 1); | |
| 814 | 822 | regalloc(&nod1, l, Z); |
| 815 | − cgen(l, &nod1, 1); | |
| 823 | + cgenrel(l, &nod1, 1); | |
| 816 | 824 | } |
| 817 | 825 | gopcode(o, &nod, &nod1, Z); |
| 818 | 826 | regfree(&nod); |
| @@ -936,7 +944,7 @@ sugen(Node *n, Node *nn, long w) · 117 unmodified lines | ||
| 936 | 944 | r = r->right; |
| 937 | 945 | } |
| 938 | 946 | if(nn == Z) { |
| 939 | − cgen(l, nn, 0); | |
| 947 | + cgen(l, nn); | |
| 940 | 948 | continue; |
| 941 | 949 | } |
| 942 | 950 | /* |
| @@ -974,7 +982,7 @@ sugen(Node *n, Node *nn, long w) · 31 unmodified lines | ||
| 974 | 982 | xcom(&nod0); |
| 975 | 983 | nod0.addable = 0; |
| 976 | 984 | |
| 977 | − cgen(&nod0, Z, 0); | |
| 985 | + cgen(&nod0, Z); | |
| 978 | 986 | } |
| 979 | 987 | break; |
| 980 | 988 | |
| @@ -1004,7 +1012,7 @@ sugen(Node *n, Node *nn, long w) · 23 unmodified lines | ||
| 1004 | 1012 | n = new(OFUNC, n->left, new(OLIST, nn, n->right)); |
| 1005 | 1013 | n->type = types[TVOID]; |
| 1006 | 1014 | n->left->type = types[TVOID]; |
| 1007 | − cgen(n, Z, 0); | |
| 1015 | + cgen(n, Z); | |
| 1008 | 1016 | break; |
| 1009 | 1017 | |
| 1010 | 1018 | case OCOND: |
| @@ -1019,7 +1027,7 @@ sugen(Node *n, Node *nn, long w) · 8 unmodified lines | ||
| 1019 | 1027 | break; |
| 1020 | 1028 | |
| 1021 | 1029 | case OCOMMA: |
| 1022 | − cgen(n->left, Z, 0); | |
| 1030 | + cgen(n->left, Z); | |
| 1023 | 1031 | sugen(n->right, nn, w); |
| 1024 | 1032 | break; |
| 1025 | 1033 | } |
| @@ -1063,6 +1071,10 @@ copy: · 37 unmodified lines | ||
| 1063 | 1071 | } |
| 1064 | 1072 | regalloc(&nod3, ®node, Z); |
| 1065 | 1073 | regalloc(&nod4, ®node, Z); |
| 1074 | + if(nod3.reg > nod4.reg){ | |
| 1075 | + /* code below assumes nod3 loaded first */ | |
| 1076 | + Node t = nod3; nod3 = nod4; nod4 = t; | |
| 1077 | + } | |
| 1066 | 1078 | nod0 = *nodconst((1<<nod3.reg)|(1<<nod4.reg)); |
| 1067 | 1079 | if(w == 2 && nod1.xoffset == 0) |
| 1068 | 1080 | gmovm(&nod1, &nod0, 0); |
| @@ -62,6 +62,7 @@ struct Case · 61 unmodified lines | ||
| 62 | 62 | long val; |
| 63 | 63 | long label; |
| 64 | 64 | char def; |
| 65 | + char isv; | |
| 65 | 66 | }; |
| 66 | 67 | #define C ((Case*)0) |
| 67 | 68 | |
| @@ -134,6 +135,7 @@ struct Rgn · 66 unmodified lines | ||
| 134 | 135 | }; |
| 135 | 136 | |
| 136 | 137 | EXTERN long breakpc; |
| 138 | +EXTERN long nbreak; | |
| 137 | 139 | EXTERN Case* cases; |
| 138 | 140 | EXTERN Node constnode; |
| 139 | 141 | EXTERN Node fconstnode; |
| @@ -145,7 +147,6 @@ EXTERN Prog* lastp; · 5 unmodified lines | ||
| 145 | 147 | EXTERN long maxargsafe; |
| 146 | 148 | EXTERN int mnstring; |
| 147 | 149 | EXTERN Multab multab[20]; |
| 148 | −EXTERN int retok; | |
| 149 | 150 | EXTERN int hintabsize; |
| 150 | 151 | EXTERN Node* nodrat; |
| 151 | 152 | EXTERN Node* nodret; |
| @@ -216,7 +217,8 @@ int bcomplex(Node*, Node*); · 64 unmodified lines | ||
| 216 | 217 | /* |
| 217 | 218 | * cgen.c |
| 218 | 219 | */ |
| 219 | −void cgen(Node*, Node*, int); | |
| 220 | +void cgen(Node*, Node*); | |
| 221 | +void cgenrel(Node*, Node*, int); | |
| 220 | 222 | void reglcgen(Node*, Node*, Node*); |
| 221 | 223 | void lcgen(Node*, Node*); |
| 222 | 224 | void bcgen(Node*, int); |
| @@ -265,7 +267,8 @@ void gpseudo(int, Sym*, Node*); · 42 unmodified lines | ||
| 265 | 267 | */ |
| 266 | 268 | int swcmp(const void*, const void*); |
| 267 | 269 | void doswit(Node*); |
| 268 | −void swit1(C1*, int, long, Node*, Node*); | |
| 270 | +void swit1(C1*, int, long, Node*); | |
| 271 | +void swit2(C1*, int, long, Node*, Node*); | |
| 269 | 272 | void casf(void); |
| 270 | 273 | void bitload(Node*, Node*, Node*, Node*, Node*); |
| 271 | 274 | void bitstore(Node*, Node*, Node*, Node*, Node*); |
| @@ -8,6 +8,8 @@ OFILES=\ · 7 unmodified lines | ||
| 8 | 8 | list.$O\ |
| 9 | 9 | mul.$O\ |
| 10 | 10 | peep.$O\ |
| 11 | + pgen.$O\ | |
| 12 | + pswt.$O\ | |
| 11 | 13 | reg.$O\ |
| 12 | 14 | sgen.$O\ |
| 13 | 15 | swt.$O\ |
| @@ -28,3 +30,9 @@ $ROOT/$OBJDIR/lib/libcc.a: · 14 unmodified lines | ||
| 28 | 30 | cd ../cc |
| 29 | 31 | mk $MKFLAGS install |
| 30 | 32 | mk $MKFLAGS clean |
| 33 | + | |
| 34 | +%.$O: ../cc/%.c | |
| 35 | + $CC $CFLAGS -I. ../cc/$stem.c | |
| 36 | + | |
| 37 | +#enam.c: 5.out.h | |
| 38 | +# rc mkenam | |
| @@ -789,6 +789,7 @@ loopit(Reg *r, long nr) · 788 unmodified lines | ||
| 789 | 789 | idom = alloc(nr * sizeof(long)); |
| 790 | 790 | maxnr = nr; |
| 791 | 791 | } |
| 792 | + | |
| 792 | 793 | d = postorder(r, rpo2r, 0); |
| 793 | 794 | if(d > nr) |
| 794 | 795 | fatal(Z, "too many reg nodes"); |
| @@ -1116,15 +1117,15 @@ long · 321 unmodified lines | ||
| 1116 | 1117 | RtoB(int r) |
| 1117 | 1118 | { |
| 1118 | 1119 | |
| 1119 | − if(r < 2 || r >= REGTMP) | |
| 1120 | − return 0; | |
| 1121 | − return 1L << r; | |
| 1120 | + if(r >= REGMIN && r <= REGMAX) | |
| 1121 | + return 1L << r; | |
| 1122 | + return 0; | |
| 1122 | 1123 | } |
| 1123 | 1124 | |
| 1124 | 1125 | int |
| 1125 | 1126 | BtoR(long b) |
| 1126 | 1127 | { |
| 1127 | − b &= 0x07fcL; | |
| 1128 | + b &= 0x01fcL; | |
| 1128 | 1129 | if(b == 0) |
| 1129 | 1130 | return 0; |
| 1130 | 1131 | return bitno(b); |
| @@ -1,381 +1,5 @@ | ||
| 1 | 1 | #include "gc.h" |
| 2 | 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 >= 0) { | |
| 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 | − | |
| 98 | − retok = 0; | |
| 99 | − switch(o) { | |
| 100 | − | |
| 101 | − default: | |
| 102 | − complex(n); | |
| 103 | − cgen(n, Z, 0); | |
| 104 | − break; | |
| 105 | − | |
| 106 | − case OLIST: | |
| 107 | − gen(n->left); | |
| 108 | − | |
| 109 | − rloop: | |
| 110 | − n = n->right; | |
| 111 | − goto loop; | |
| 112 | − | |
| 113 | − case ORETURN: | |
| 114 | − retok = 1; | |
| 115 | − complex(n); | |
| 116 | − if(n->type == T) | |
| 117 | − break; | |
| 118 | − l = n->left; | |
| 119 | − if(l == Z) { | |
| 120 | − noretval(3); | |
| 121 | − gbranch(ORETURN); | |
| 122 | − break; | |
| 123 | − } | |
| 124 | − if(typesuv[n->type->etype]) { | |
| 125 | − sugen(l, nodret, n->type->width); | |
| 126 | − noretval(3); | |
| 127 | − gbranch(ORETURN); | |
| 128 | − break; | |
| 129 | − } | |
| 130 | − regret(&nod, n); | |
| 131 | − cgen(l, &nod, 0); | |
| 132 | − regfree(&nod); | |
| 133 | − if(typefd[n->type->etype]) | |
| 134 | − noretval(1); | |
| 135 | − else | |
| 136 | − noretval(2); | |
| 137 | − gbranch(ORETURN); | |
| 138 | − break; | |
| 139 | − | |
| 140 | − case OLABEL: | |
| 141 | − l = n->left; | |
| 142 | − if(l) { | |
| 143 | − l->pc = pc; | |
| 144 | − if(l->label) | |
| 145 | − patch(l->label, pc); | |
| 146 | − } | |
| 147 | − gbranch(OGOTO); /* prevent self reference in reg */ | |
| 148 | − patch(p, pc); | |
| 149 | − goto rloop; | |
| 150 | − | |
| 151 | − case OGOTO: | |
| 152 | − retok = 1; | |
| 153 | − n = n->left; | |
| 154 | − if(n == Z) | |
| 155 | − return; | |
| 156 | − if(n->complex == 0) { | |
| 157 | − diag(Z, "label undefined: %s", n->sym->name); | |
| 158 | − return; | |
| 159 | − } | |
| 160 | − if(suppress) | |
| 161 | − return; | |
| 162 | − gbranch(OGOTO); | |
| 163 | − if(n->pc) { | |
| 164 | − patch(p, n->pc); | |
| 165 | − return; | |
| 166 | − } | |
| 167 | − if(n->label) | |
| 168 | − patch(n->label, pc-1); | |
| 169 | − n->label = p; | |
| 170 | − return; | |
| 171 | − | |
| 172 | − case OCASE: | |
| 173 | − l = n->left; | |
| 174 | − if(cases == C) | |
| 175 | − diag(n, "case/default outside a switch"); | |
| 176 | − if(l == Z) { | |
| 177 | − casf(); | |
| 178 | − cases->val = 0; | |
| 179 | − cases->def = 1; | |
| 180 | − cases->label = pc; | |
| 181 | − goto rloop; | |
| 182 | − } | |
| 183 | − complex(l); | |
| 184 | − if(l->type == T) | |
| 185 | − goto rloop; | |
| 186 | − if(l->op == OCONST) | |
| 187 | − if(typechl[l->type->etype]) { | |
| 188 | − casf(); | |
| 189 | − cases->val = l->vconst; | |
| 190 | − cases->def = 0; | |
| 191 | − cases->label = pc; | |
| 192 | − goto rloop; | |
| 193 | − } | |
| 194 | − diag(n, "case expression must be integer constant"); | |
| 195 | − goto rloop; | |
| 196 | − | |
| 197 | − case OSWITCH: | |
| 198 | − l = n->left; | |
| 199 | − complex(l); | |
| 200 | − if(l->type == T) | |
| 201 | − break; | |
| 202 | − if(!typechl[l->type->etype]) { | |
| 203 | − diag(n, "switch expression must be integer"); | |
| 204 | − break; | |
| 205 | − } | |
| 206 | − | |
| 207 | − gbranch(OGOTO); /* entry */ | |
| 208 | − sp = p; | |
| 209 | − | |
| 210 | − cn = cases; | |
| 211 | − cases = C; | |
| 212 | − casf(); | |
| 213 | − | |
| 214 | − sbc = breakpc; | |
| 215 | − breakpc = pc; | |
| 216 | − gbranch(OGOTO); | |
| 217 | − spb = p; | |
| 218 | − | |
| 219 | − gen(n->right); | |
| 220 | − gbranch(OGOTO); | |
| 221 | − patch(p, breakpc); | |
| 222 | − | |
| 223 | − patch(sp, pc); | |
| 224 | − regalloc(&nod, l, Z); | |
| 225 | − nod.type = types[TLONG]; | |
| 226 | − cgen(l, &nod, 0); | |
| 227 | − doswit(&nod); | |
| 228 | − regfree(&nod); | |
| 229 | − patch(spb, pc); | |
| 230 | − | |
| 231 | − cases = cn; | |
| 232 | − breakpc = sbc; | |
| 233 | − break; | |
| 234 | − | |
| 235 | − case OWHILE: | |
| 236 | − case ODWHILE: | |
| 237 | − l = n->left; | |
| 238 | − gbranch(OGOTO); /* entry */ | |
| 239 | − sp = p; | |
| 240 | − | |
| 241 | − scc = continpc; | |
| 242 | − continpc = pc; | |
| 243 | − gbranch(OGOTO); | |
| 244 | − spc = p; | |
| 245 | − | |
| 246 | − sbc = breakpc; | |
| 247 | − breakpc = pc; | |
| 248 | − gbranch(OGOTO); | |
| 249 | − spb = p; | |
| 250 | − | |
| 251 | − patch(spc, pc); | |
| 252 | − if(n->op == OWHILE) | |
| 253 | − patch(sp, pc); | |
| 254 | − bcomplex(l, Z); /* test */ | |
| 255 | − patch(p, breakpc); | |
| 256 | − | |
| 257 | − if(n->op == ODWHILE) | |
| 258 | − patch(sp, pc); | |
| 259 | − gen(n->right); /* body */ | |
| 260 | − gbranch(OGOTO); | |
| 261 | − patch(p, continpc); | |
| 262 | − | |
| 263 | − patch(spb, pc); | |
| 264 | − continpc = scc; | |
| 265 | − breakpc = sbc; | |
| 266 | − break; | |
| 267 | − | |
| 268 | − case OFOR: | |
| 269 | − l = n->left; | |
| 270 | − gen(l->right->left); /* init */ | |
| 271 | − gbranch(OGOTO); /* entry */ | |
| 272 | − sp = p; | |
| 273 | − | |
| 274 | − scc = continpc; | |
| 275 | − continpc = pc; | |
| 276 | − gbranch(OGOTO); | |
| 277 | − spc = p; | |
| 278 | − | |
| 279 | − sbc = breakpc; | |
| 280 | − breakpc = pc; | |
| 281 | − gbranch(OGOTO); | |
| 282 | − spb = p; | |
| 283 | − | |
| 284 | − patch(spc, pc); | |
| 285 | − gen(l->right->right); /* inc */ | |
| 286 | − patch(sp, pc); | |
| 287 | − if(l->left != Z) { /* test */ | |
| 288 | − bcomplex(l->left, Z); | |
| 289 | − patch(p, breakpc); | |
| 290 | − } | |
| 291 | − gen(n->right); /* body */ | |
| 292 | − gbranch(OGOTO); | |
| 293 | − patch(p, continpc); | |
| 294 | − | |
| 295 | − patch(spb, pc); | |
| 296 | − continpc = scc; | |
| 297 | − breakpc = sbc; | |
| 298 | − break; | |
| 299 | − | |
| 300 | − case OCONTINUE: | |
| 301 | − if(continpc < 0) { | |
| 302 | − diag(n, "continue not in a loop"); | |
| 303 | − break; | |
| 304 | − } | |
| 305 | − gbranch(OGOTO); | |
| 306 | − patch(p, continpc); | |
| 307 | − break; | |
| 308 | − | |
| 309 | − case OBREAK: | |
| 310 | − if(breakpc < 0) { | |
| 311 | − diag(n, "break not in a loop"); | |
| 312 | − break; | |
| 313 | − } | |
| 314 | − gbranch(OGOTO); | |
| 315 | − patch(p, breakpc); | |
| 316 | − break; | |
| 317 | − | |
| 318 | − case OIF: | |
| 319 | − l = n->left; | |
| 320 | − if(bcomplex(l, n->right)) { | |
| 321 | − if(typefd[l->type->etype]) | |
| 322 | − f = !l->fconst; | |
| 323 | − else | |
| 324 | − f = !l->vconst; | |
| 325 | − if(debug['c']) | |
| 326 | − print("%L const if %s\n", nearln, f ? "false" : "true"); | |
| 327 | − if(f) { | |
| 328 | − supgen(n->right->left); | |
| 329 | − gen(n->right->right); | |
| 330 | − } | |
| 331 | − else { | |
| 332 | − gen(n->right->left); | |
| 333 | − supgen(n->right->right); | |
| 334 | − } | |
| 335 | − } | |
| 336 | − else { | |
| 337 | − sp = p; | |
| 338 | − if(n->right->left != Z) | |
| 339 | − gen(n->right->left); | |
| 340 | − if(n->right->right != Z) { | |
| 341 | − gbranch(OGOTO); | |
| 342 | − patch(sp, pc); | |
| 343 | − sp = p; | |
| 344 | − gen(n->right->right); | |
| 345 | − } | |
| 346 | − patch(sp, pc); | |
| 347 | − } | |
| 348 | − break; | |
| 349 | − | |
| 350 | − case OSET: | |
| 351 | − case OUSED: | |
| 352 | − usedset(n->left, o); | |
| 353 | − break; | |
| 354 | − } | |
| 355 | −} | |
| 356 | − | |
| 357 | −void | |
| 358 | −usedset(Node *n, int o) | |
| 359 | −{ | |
| 360 | − if(n->op == OLIST) { | |
| 361 | − usedset(n->left, o); | |
| 362 | − usedset(n->right, o); | |
| 363 | − return; | |
| 364 | − } | |
| 365 | − complex(n); | |
| 366 | − switch(n->op) { | |
| 367 | − case OADDR: /* volatile */ | |
| 368 | − gins(ANOP, n, Z); | |
| 369 | − break; | |
| 370 | − case ONAME: | |
| 371 | − if(o == OSET) | |
| 372 | − gins(ANOP, Z, n); | |
| 373 | − else | |
| 374 | − gins(ANOP, n, Z); | |
| 375 | − break; | |
| 376 | − } | |
| 377 | −} | |
| 378 | − | |
| 379 | 3 | void |
| 380 | 4 | noretval(int n) |
| 381 | 5 | { |
| @@ -593,21 +217,3 @@ xcom(Node *n) · 211 unmodified lines | ||
| 593 | 217 | break; |
| 594 | 218 | } |
| 595 | 219 | } |
| 596 | − | |
| 597 | −int | |
| 598 | −bcomplex(Node *n, Node *c) | |
| 599 | −{ | |
| 600 | − | |
| 601 | − complex(n); | |
| 602 | − if(n->type != T) | |
| 603 | − if(tcompat(n, T, n->type, tnot)) | |
| 604 | − n->type = T; | |
| 605 | − if(n->type != T) { | |
| 606 | − if(c != Z && n->op == OCONST && deadheads(c)) | |
| 607 | − return 1; | |
| 608 | − bool64(n); | |
| 609 | − boolgen(n, 1, Z); | |
| 610 | − } else | |
| 611 | − gbranch(OGOTO); | |
| 612 | − return 0; | |
| 613 | −} | |
| @@ -1,62 +1,17 @@ | ||
| 1 | 1 | #include "gc.h" |
| 2 | 2 | |
| 3 | −int | |
| 4 | −swcmp(const void *a1, const 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 | 3 | void |
| 16 | −doswit(Node *n) | |
| 4 | +swit1(C1 *q, int nc, long def, Node *n) | |
| 17 | 5 | { |
| 18 | − Case *c; | |
| 19 | − C1 *q, *iq; | |
| 20 | − long def, nc, i; | |
| 21 | 6 | Node tn; |
| 22 | − | |
| 23 | − def = 0; | |
| 24 | − nc = 0; | |
| 25 | − for(c = cases; c->link != C; c = c->link) { | |
| 26 | − if(c->def) { | |
| 27 | − if(def) | |
| 28 | − diag(n, "more than one default in switch"); | |
| 29 | − def = c->label; | |
| 30 | − continue; | |
| 31 | − } | |
| 32 | − nc++; | |
| 33 | − } | |
| 34 | − | |
| 35 | − iq = alloc(nc*sizeof(C1)); | |
| 36 | − q = iq; | |
| 37 | − for(c = cases; c->link != C; c = c->link) { | |
| 38 | − if(c->def) | |
| 39 | − continue; | |
| 40 | − q->label = c->label; | |
| 41 | − q->val = c->val; | |
| 42 | − q++; | |
| 43 | − } | |
| 44 | − qsort(iq, nc, sizeof(C1), swcmp); | |
| 45 | − if(debug['W']) | |
| 46 | − for(i=0; i<nc; i++) | |
| 47 | − print("case %2ld: = %.8lux\n", i, iq[i].val); | |
| 48 | − if(def == 0) | |
| 49 | − def = breakpc; | |
| 50 | − for(i=0; i<nc-1; i++) | |
| 51 | − if(iq[i].val == iq[i+1].val) | |
| 52 | − diag(n, "duplicate cases in switch %ld", iq[i].val); | |
| 7 | + | |
| 53 | 8 | regalloc(&tn, ®node, Z); |
| 54 | − swit1(iq, nc, def, n, &tn); | |
| 9 | + swit2(q, nc, def, n, &tn); | |
| 55 | 10 | regfree(&tn); |
| 56 | 11 | } |
| 57 | 12 | |
| 58 | 13 | void |
| 59 | −swit1(C1 *q, int nc, long def, Node *n, Node *tn) | |
| 14 | +swit2(C1 *q, int nc, long def, Node *n, Node *tn) | |
| 60 | 15 | { |
| 61 | 16 | C1 *r; |
| 62 | 17 | int i; |
| @@ -89,12 +44,12 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn) · 26 unmodified lines | ||
| 89 | 44 | sp = p; |
| 90 | 45 | gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */ |
| 91 | 46 | patch(p, r->label); |
| 92 | − swit1(q, i, def, n, tn); | |
| 47 | + swit2(q, i, def, n, tn); | |
| 93 | 48 | |
| 94 | 49 | if(debug['W']) |
| 95 | 50 | print("case < %.8lux\n", r->val); |
| 96 | 51 | patch(sp, pc); |
| 97 | − swit1(r+1, nc-i-1, def, n, tn); | |
| 52 | + swit2(r+1, nc-i-1, def, n, tn); | |
| 98 | 53 | return; |
| 99 | 54 | |
| 100 | 55 | direct: |
| @@ -122,16 +77,6 @@ direct: · 21 unmodified lines | ||
| 122 | 77 | patch(p, def); |
| 123 | 78 | } |
| 124 | 79 | |
| 125 | −void | |
| 126 | −casf(void) | |
| 127 | −{ | |
| 128 | − Case *c; | |
| 129 | − | |
| 130 | − c = alloc(sizeof(*c)); | |
| 131 | − c->link = cases; | |
| 132 | − cases = c; | |
| 133 | −} | |
| 134 | − | |
| 135 | 80 | void |
| 136 | 81 | bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) |
| 137 | 82 | { |
| @@ -153,7 +98,7 @@ bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) · 15 unmodified lines | ||
| 153 | 98 | gopcode(OAS, n3, Z, n1); |
| 154 | 99 | } else { |
| 155 | 100 | regalloc(n1, l, nn); |
| 156 | − cgen(l, n1, 0); | |
| 101 | + cgen(l, n1); | |
| 157 | 102 | } |
| 158 | 103 | if(b->type->shift == 0 && typeu[b->type->etype]) { |
| 159 | 104 | v = ~0 + (1L << b->type->nbits); |
| @@ -229,33 +174,6 @@ outstring(char *s, long n) · 69 unmodified lines | ||
| 229 | 174 | return r; |
| 230 | 175 | } |
| 231 | 176 | |
| 232 | −long | |
| 233 | −outlstring(ushort *s, long n) | |
| 234 | −{ | |
| 235 | − char buf[2]; | |
| 236 | − int c; | |
| 237 | − long r; | |
| 238 | − | |
| 239 | − if(suppress) | |
| 240 | − return nstring; | |
| 241 | − while(nstring & 1) | |
| 242 | − outstring("", 1); | |
| 243 | − r = nstring; | |
| 244 | − while(n > 0) { | |
| 245 | − c = *s++; | |
| 246 | − if(align(0, types[TCHAR], Aarg1)) { | |
| 247 | − buf[0] = c>>8; | |
| 248 | − buf[1] = c; | |
| 249 | − } else { | |
| 250 | − buf[0] = c; | |
| 251 | − buf[1] = c>>8; | |
| 252 | − } | |
| 253 | − outstring(buf, 2); | |
| 254 | − n -= sizeof(ushort); | |
| 255 | − } | |
| 256 | − return r; | |
| 257 | −} | |
| 258 | − | |
| 259 | 177 | int |
| 260 | 178 | mulcon(Node *n, Node *nn) |
| 261 | 179 | { |
| @@ -297,7 +215,7 @@ mulcon(Node *n, Node *nn) · 35 unmodified lines | ||
| 297 | 215 | if(p[1] == 'i') |
| 298 | 216 | p += 2; |
| 299 | 217 | regalloc(&nod1, n, nn); |
| 300 | − cgen(l, &nod1, 0); | |
| 218 | + cgen(l, &nod1); | |
| 301 | 219 | vs = v; |
| 302 | 220 | regalloc(&nod2, n, Z); |
| 303 | 221 | |
| @@ -350,16 +268,6 @@ loop: · 46 unmodified lines | ||
| 350 | 268 | goto loop; |
| 351 | 269 | } |
| 352 | 270 | |
| 353 | −void | |
| 354 | −nullwarn(Node *l, Node *r) | |
| 355 | −{ | |
| 356 | − warn(Z, "result of operation not used"); | |
| 357 | − if(l != Z) | |
| 358 | − cgen(l, Z, 0); | |
| 359 | − if(r != Z) | |
| 360 | − cgen(r, Z, 0); | |
| 361 | −} | |
| 362 | − | |
| 363 | 271 | void |
| 364 | 272 | sextern(Sym *s, Node *a, long o, long w) |
| 365 | 273 | { |
| @@ -651,35 +559,6 @@ zaddr(char *bp, Adr *a, int s) · 285 unmodified lines | ||
| 651 | 559 | return bp; |
| 652 | 560 | } |
| 653 | 561 | |
| 654 | −void | |
| 655 | −ieeedtod(Ieee *ieee, double native) | |
| 656 | −{ | |
| 657 | − double fr, ho, f; | |
| 658 | − int exp; | |
| 659 | − | |
| 660 | − if(native < 0) { | |
| 661 | − ieeedtod(ieee, -native); | |
| 662 | − ieee->h |= 0x80000000L; | |
| 663 | − return; | |
| 664 | − } | |
| 665 | − if(native == 0) { | |
| 666 | − ieee->l = 0; | |
| 667 | − ieee->h = 0; | |
| 668 | − return; | |
| 669 | − } | |
| 670 | − fr = frexp(native, &exp); | |
| 671 | − f = 2097152L; /* shouldnt use fp constants here */ | |
| 672 | − fr = modf(fr*f, &ho); | |
| 673 | − ieee->h = ho; | |
| 674 | − ieee->h &= 0xfffffL; | |
| 675 | − ieee->h |= (exp+1022L) << 20; | |
| 676 | − f = 65536L; | |
| 677 | − fr = modf(fr*f, &ho); | |
| 678 | − ieee->l = ho; | |
| 679 | − ieee->l <<= 16; | |
| 680 | − ieee->l |= (long)(fr*f); | |
| 681 | −} | |
| 682 | − | |
| 683 | 562 | long |
| 684 | 563 | align(long i, Type *t, int op) |
| 685 | 564 | { |
| @@ -170,7 +170,7 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp) · 169 unmodified lines | ||
| 170 | 170 | nod.left = *fnxp; |
| 171 | 171 | nod.right = n; |
| 172 | 172 | nod.type = n->type; |
| 173 | − cgen(&nod, Z, 0); | |
| 173 | + cgen(&nod, Z); | |
| 174 | 174 | (*fnxp)++; |
| 175 | 175 | } |
| 176 | 176 | return; |
| @@ -187,18 +187,18 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp) · 10 unmodified lines | ||
| 187 | 187 | if(REGARG >= 0 && curarg == 0 && typechlp[n->type->etype]) { |
| 188 | 188 | regaalloc1(tn1, n); |
| 189 | 189 | if(n->complex >= FNX) { |
| 190 | − cgen(*fnxp, tn1, 0); | |
| 190 | + cgen(*fnxp, tn1); | |
| 191 | 191 | (*fnxp)++; |
| 192 | 192 | } else |
| 193 | − cgen(n, tn1, 0); | |
| 193 | + cgen(n, tn1); | |
| 194 | 194 | return; |
| 195 | 195 | } |
| 196 | 196 | regalloc(tn1, n, Z); |
| 197 | 197 | if(n->complex >= FNX) { |
| 198 | − cgen(*fnxp, tn1, 0); | |
| 198 | + cgen(*fnxp, tn1); | |
| 199 | 199 | (*fnxp)++; |
| 200 | 200 | } else |
| 201 | − cgen(n, tn1, 0); | |
| 201 | + cgen(n, tn1); | |
| 202 | 202 | regaalloc(tn2, n); |
| 203 | 203 | gopcode(OAS, tn1, Z, tn2); |
| 204 | 204 | regfree(tn1); |
| @@ -57,6 +57,7 @@ struct Case · 56 unmodified lines | ||
| 57 | 57 | long val; |
| 58 | 58 | long label; |
| 59 | 59 | char def; |
| 60 | + char isv; | |
| 60 | 61 | }; |
| 61 | 62 | #define C ((Case*)0) |
| 62 | 63 | |
| @@ -128,6 +129,7 @@ struct Rgn · 65 unmodified lines | ||
| 128 | 129 | }; |
| 129 | 130 | |
| 130 | 131 | EXTERN long breakpc; |
| 132 | +EXTERN long nbreak; | |
| 131 | 133 | EXTERN Case* cases; |
| 132 | 134 | EXTERN Node constnode; |
| 133 | 135 | EXTERN Node fconstnode; |
| @@ -140,7 +142,6 @@ EXTERN int hintabsize; · 6 unmodified lines | ||
| 140 | 142 | EXTERN long maxargsafe; |
| 141 | 143 | EXTERN Multab multab[20]; |
| 142 | 144 | EXTERN int mnstring; |
| 143 | −EXTERN int retok; | |
| 144 | 145 | EXTERN Node* nodrat; |
| 145 | 146 | EXTERN Node* nodret; |
| 146 | 147 | EXTERN Node* nodsafe; |
| @@ -183,6 +184,7 @@ EXTERN long regbits; · 36 unmodified lines | ||
| 183 | 184 | EXTERN long exregbits; |
| 184 | 185 | |
| 185 | 186 | EXTERN int change; |
| 187 | +EXTERN int suppress; | |
| 186 | 188 | |
| 187 | 189 | EXTERN Reg* firstr; |
| 188 | 190 | EXTERN Reg* lastr; |
| @@ -204,7 +206,7 @@ void gen(Node*); · 15 unmodified lines | ||
| 204 | 206 | void usedset(Node*, int); |
| 205 | 207 | void noretval(int); |
| 206 | 208 | void xcom(Node*); |
| 207 | −void bcomplex(Node*); | |
| 209 | +int bcomplex(Node*, Node*); | |
| 208 | 210 | |
| 209 | 211 | /* |
| 210 | 212 | * cgen.c |
| @@ -255,7 +257,8 @@ void gpseudo(int, Sym*, Node*); · 44 unmodified lines | ||
| 255 | 257 | */ |
| 256 | 258 | int swcmp(const void*, const void*); |
| 257 | 259 | void doswit(Node*); |
| 258 | −void swit1(C1*, int, long, Node*, Node*); | |
| 260 | +void swit1(C1*, int, long, Node*); | |
| 261 | +void swit2(C1*, int, long, Node*, Node*); | |
| 259 | 262 | void casf(void); |
| 260 | 263 | void bitload(Node*, Node*, Node*, Node*, Node*); |
| 261 | 264 | void bitstore(Node*, Node*, Node*, Node*, Node*); |
| @@ -4,6 +4,8 @@ TARG=kc · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | OFILES=\ |
| 6 | 6 | peep.$O\ |
| 7 | + pgen.$O\ | |
| 8 | + pswt.$O\ | |
| 7 | 9 | reg.$O\ |
| 8 | 10 | cgen.$O\ |
| 9 | 11 | enam.$O\ |
| @@ -30,3 +32,9 @@ $ROOT/$OBJDIR/lib/libcc.a: · 20 unmodified lines | ||
| 30 | 32 | cd ../cc |
| 31 | 33 | mk $MKFLAGS install |
| 32 | 34 | mk $MKFLAGS clean |
| 35 | + | |
| 36 | +%.$O: ../cc/%.c | |
| 37 | + $CC $CFLAGS -I. ../cc/$stem.c | |
| 38 | + | |
| 39 | +#enam.c: k.out.h | |
| 40 | +# rc mkenam | |
| @@ -1,343 +1,5 @@ | ||
| 1 | 1 | #include "gc.h" |
| 2 | 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 | −gen(Node *n) | |
| 64 | −{ | |
| 65 | − Node *l, nod; | |
| 66 | − Prog *sp, *spc, *spb; | |
| 67 | − Case *cn; | |
| 68 | − long sbc, scc; | |
| 69 | − int o; | |
| 70 | − | |
| 71 | −loop: | |
| 72 | − if(n == Z) | |
| 73 | − return; | |
| 74 | − nearln = n->lineno; | |
| 75 | − o = n->op; | |
| 76 | − if(debug['G']) | |
| 77 | − if(o != OLIST) | |
| 78 | − print("%L %O\n", nearln, o); | |
| 79 | − retok = 0; | |
| 80 | − switch(o) { | |
| 81 | − | |
| 82 | − default: | |
| 83 | − complex(n); | |
| 84 | − cgen(n, Z); | |
| 85 | − break; | |
| 86 | − | |
| 87 | − case OLIST: | |
| 88 | − gen(n->left); | |
| 89 | − | |
| 90 | − rloop: | |
| 91 | − n = n->right; | |
| 92 | − goto loop; | |
| 93 | − | |
| 94 | − case ORETURN: | |
| 95 | − retok = 1; | |
| 96 | − complex(n); | |
| 97 | − if(n->type == T) | |
| 98 | − break; | |
| 99 | − l = n->left; | |
| 100 | − if(l == Z) { | |
| 101 | − noretval(3); | |
| 102 | − gbranch(ORETURN); | |
| 103 | − break; | |
| 104 | − } | |
| 105 | − if(typesuv[n->type->etype]) { | |
| 106 | − sugen(l, nodret, n->type->width); | |
| 107 | − noretval(3); | |
| 108 | − gbranch(ORETURN); | |
| 109 | − break; | |
| 110 | − } | |
| 111 | − regret(&nod, n); | |
| 112 | − cgen(l, &nod); | |
| 113 | − regfree(&nod); | |
| 114 | − if(typefd[n->type->etype]) | |
| 115 | − noretval(1); | |
| 116 | − else | |
| 117 | − noretval(2); | |
| 118 | − gbranch(ORETURN); | |
| 119 | − break; | |
| 120 | − | |
| 121 | − case OLABEL: | |
| 122 | − l = n->left; | |
| 123 | − if(l) { | |
| 124 | − l->xoffset = pc; | |
| 125 | − if(l->label) | |
| 126 | − patch(l->label, pc); | |
| 127 | − } | |
| 128 | − gbranch(OGOTO); /* prevent self reference in reg */ | |
| 129 | − patch(p, pc); | |
| 130 | − goto rloop; | |
| 131 | − | |
| 132 | − case OGOTO: | |
| 133 | − retok = 1; | |
| 134 | − n = n->left; | |
| 135 | − if(n == Z) | |
| 136 | − return; | |
| 137 | − if(n->complex == 0) { | |
| 138 | − diag(Z, "label undefined: %s", n->sym->name); | |
| 139 | − return; | |
| 140 | − } | |
| 141 | − gbranch(OGOTO); | |
| 142 | − if(n->xoffset) { | |
| 143 | − patch(p, n->xoffset); | |
| 144 | − return; | |
| 145 | − } | |
| 146 | − if(n->label) | |
| 147 | − patch(n->label, pc-1); | |
| 148 | − n->label = p; | |
| 149 | − return; | |
| 150 | − | |
| 151 | − case OCASE: | |
| 152 | − l = n->left; | |
| 153 | − if(cases == C) | |
| 154 | − diag(n, "case/default outside a switch"); | |
| 155 | − if(l == Z) { | |
| 156 | − casf(); | |
| 157 | − cases->val = 0; | |
| 158 | − cases->def = 1; | |
| 159 | − cases->label = pc; | |
| 160 | − goto rloop; | |
| 161 | − } | |
| 162 | − complex(l); | |
| 163 | − if(l->type == T) | |
| 164 | − goto rloop; | |
| 165 | − if(l->op == OCONST) | |
| 166 | − if(typechl[l->type->etype]) { | |
| 167 | − casf(); | |
| 168 | − cases->val = l->vconst; | |
| 169 | − cases->def = 0; | |
| 170 | − cases->label = pc; | |
| 171 | − goto rloop; | |
| 172 | − } | |
| 173 | − diag(n, "case expression must be integer constant"); | |
| 174 | − goto rloop; | |
| 175 | − | |
| 176 | − case OSWITCH: | |
| 177 | − l = n->left; | |
| 178 | − complex(l); | |
| 179 | − if(l->type == T) | |
| 180 | − break; | |
| 181 | − if(!typechl[l->type->etype]) { | |
| 182 | − diag(n, "switch expression must be integer"); | |
| 183 | − break; | |
| 184 | − } | |
| 185 | − | |
| 186 | − gbranch(OGOTO); /* entry */ | |
| 187 | − sp = p; | |
| 188 | − | |
| 189 | − cn = cases; | |
| 190 | − cases = C; | |
| 191 | − casf(); | |
| 192 | − | |
| 193 | − sbc = breakpc; | |
| 194 | − breakpc = pc; | |
| 195 | − gbranch(OGOTO); | |
| 196 | − spb = p; | |
| 197 | − | |
| 198 | − gen(n->right); | |
| 199 | − gbranch(OGOTO); | |
| 200 | − patch(p, breakpc); | |
| 201 | − | |
| 202 | − patch(sp, pc); | |
| 203 | − regalloc(&nod, l, Z); | |
| 204 | − nod.type = types[TLONG]; | |
| 205 | − cgen(l, &nod); | |
| 206 | − doswit(&nod); | |
| 207 | − regfree(&nod); | |
| 208 | − patch(spb, pc); | |
| 209 | − | |
| 210 | − cases = cn; | |
| 211 | − breakpc = sbc; | |
| 212 | − break; | |
| 213 | − | |
| 214 | − case OWHILE: | |
| 215 | − case ODWHILE: | |
| 216 | − l = n->left; | |
| 217 | − gbranch(OGOTO); /* entry */ | |
| 218 | − sp = p; | |
| 219 | − | |
| 220 | − scc = continpc; | |
| 221 | − continpc = pc; | |
| 222 | − gbranch(OGOTO); | |
| 223 | − spc = p; | |
| 224 | − | |
| 225 | − sbc = breakpc; | |
| 226 | − breakpc = pc; | |
| 227 | − gbranch(OGOTO); | |
| 228 | − spb = p; | |
| 229 | − | |
| 230 | − patch(spc, pc); | |
| 231 | − if(n->op == OWHILE) | |
| 232 | − patch(sp, pc); | |
| 233 | − bcomplex(l); /* test */ | |
| 234 | − patch(p, breakpc); | |
| 235 | − | |
| 236 | − if(n->op == ODWHILE) | |
| 237 | − patch(sp, pc); | |
| 238 | − gen(n->right); /* body */ | |
| 239 | − gbranch(OGOTO); | |
| 240 | − patch(p, continpc); | |
| 241 | − | |
| 242 | − patch(spb, pc); | |
| 243 | − continpc = scc; | |
| 244 | − breakpc = sbc; | |
| 245 | − break; | |
| 246 | − | |
| 247 | − case OFOR: | |
| 248 | − l = n->left; | |
| 249 | − gen(l->right->left); /* init */ | |
| 250 | − gbranch(OGOTO); /* entry */ | |
| 251 | − sp = p; | |
| 252 | − | |
| 253 | − scc = continpc; | |
| 254 | − continpc = pc; | |
| 255 | − gbranch(OGOTO); | |
| 256 | − spc = p; | |
| 257 | − | |
| 258 | − sbc = breakpc; | |
| 259 | − breakpc = pc; | |
| 260 | − gbranch(OGOTO); | |
| 261 | − spb = p; | |
| 262 | − | |
| 263 | − patch(spc, pc); | |
| 264 | − gen(l->right->right); /* inc */ | |
| 265 | − patch(sp, pc); | |
| 266 | − if(l->left != Z) { /* test */ | |
| 267 | − bcomplex(l->left); | |
| 268 | − patch(p, breakpc); | |
| 269 | − } | |
| 270 | − gen(n->right); /* body */ | |
| 271 | − gbranch(OGOTO); | |
| 272 | − patch(p, continpc); | |
| 273 | − | |
| 274 | − patch(spb, pc); | |
| 275 | − continpc = scc; | |
| 276 | − breakpc = sbc; | |
| 277 | − break; | |
| 278 | − | |
| 279 | − case OCONTINUE: | |
| 280 | − if(continpc < 0) { | |
| 281 | − diag(n, "continue not in a loop"); | |
| 282 | − break; | |
| 283 | − } | |
| 284 | − gbranch(OGOTO); | |
| 285 | − patch(p, continpc); | |
| 286 | − break; | |
| 287 | − | |
| 288 | − case OBREAK: | |
| 289 | − if(breakpc < 0) { | |
| 290 | − diag(n, "break not in a loop"); | |
| 291 | − break; | |
| 292 | − } | |
| 293 | − gbranch(OGOTO); | |
| 294 | − patch(p, breakpc); | |
| 295 | − break; | |
| 296 | − | |
| 297 | − case OIF: | |
| 298 | − l = n->left; | |
| 299 | − bcomplex(l); | |
| 300 | − sp = p; | |
| 301 | − if(n->right->left != Z) | |
| 302 | − gen(n->right->left); | |
| 303 | − if(n->right->right != Z) { | |
| 304 | − gbranch(OGOTO); | |
| 305 | − patch(sp, pc); | |
| 306 | − sp = p; | |
| 307 | − gen(n->right->right); | |
| 308 | − } | |
| 309 | − patch(sp, pc); | |
| 310 | − break; | |
| 311 | − | |
| 312 | − case OSET: | |
| 313 | − case OUSED: | |
| 314 | − usedset(n->left, o); | |
| 315 | − break; | |
| 316 | − } | |
| 317 | −} | |
| 318 | − | |
| 319 | −void | |
| 320 | −usedset(Node *n, int o) | |
| 321 | −{ | |
| 322 | − if(n->op == OLIST) { | |
| 323 | − usedset(n->left, o); | |
| 324 | − usedset(n->right, o); | |
| 325 | − return; | |
| 326 | − } | |
| 327 | − complex(n); | |
| 328 | − switch(n->op) { | |
| 329 | − case OADDR: /* volatile */ | |
| 330 | − gins(ANOP, n, Z); | |
| 331 | − break; | |
| 332 | − case ONAME: | |
| 333 | − if(o == OSET) | |
| 334 | − gins(ANOP, Z, n); | |
| 335 | − else | |
| 336 | − gins(ANOP, n, Z); | |
| 337 | − break; | |
| 338 | − } | |
| 339 | −} | |
| 340 | − | |
| 341 | 3 | void |
| 342 | 4 | noretval(int n) |
| 343 | 5 | { |
| @@ -574,17 +236,3 @@ xcom(Node *n) · 230 unmodified lines | ||
| 574 | 236 | } |
| 575 | 237 | } |
| 576 | 238 | |
| 577 | −void | |
| 578 | −bcomplex(Node *n) | |
| 579 | −{ | |
| 580 | − | |
| 581 | − complex(n); | |
| 582 | − if(n->type != T) | |
| 583 | − if(tcompat(n, T, n->type, tnot)) | |
| 584 | − n->type = T; | |
| 585 | − if(n->type != T) { | |
| 586 | − bool64(n); | |
| 587 | − boolgen(n, 1, Z); | |
| 588 | − } else | |
| 589 | − gbranch(OGOTO); | |
| 590 | −} | |
| @@ -1,59 +1,17 @@ | ||
| 1 | 1 | #include "gc.h" |
| 2 | 2 | |
| 3 | −int | |
| 4 | −swcmp(const void *a1, const 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 | 3 | void |
| 16 | −doswit(Node *n) | |
| 4 | +swit1(C1 *q, int nc, long def, Node *n) | |
| 17 | 5 | { |
| 18 | − Case *c; | |
| 19 | − C1 *q, *iq; | |
| 20 | − long def, nc, i; | |
| 21 | 6 | Node tn; |
| 22 | − | |
| 23 | − def = 0; | |
| 24 | − nc = 0; | |
| 25 | − for(c = cases; c->link != C; c = c->link) { | |
| 26 | − if(c->def) { | |
| 27 | − if(def) | |
| 28 | − diag(n, "more than one default in switch"); | |
| 29 | − def = c->label; | |
| 30 | − continue; | |
| 31 | − } | |
| 32 | − nc++; | |
| 33 | − } | |
| 34 | − | |
| 35 | − iq = alloc(nc*sizeof(C1)); | |
| 36 | − q = iq; | |
| 37 | − for(c = cases; c->link != C; c = c->link) { | |
| 38 | − if(c->def) | |
| 39 | − continue; | |
| 40 | − q->label = c->label; | |
| 41 | − q->val = c->val; | |
| 42 | − q++; | |
| 43 | − } | |
| 44 | − qsort(iq, nc, sizeof(C1), swcmp); | |
| 45 | − if(def == 0) | |
| 46 | − def = breakpc; | |
| 47 | − for(i=0; i<nc-1; i++) | |
| 48 | − if(iq[i].val == iq[i+1].val) | |
| 49 | − diag(n, "duplicate cases in switch %ld", iq[i].val); | |
| 7 | + | |
| 50 | 8 | regalloc(&tn, ®node, Z); |
| 51 | − swit1(iq, nc, def, n, &tn); | |
| 9 | + swit2(q, nc, def, n, &tn); | |
| 52 | 10 | regfree(&tn); |
| 53 | 11 | } |
| 54 | 12 | |
| 55 | 13 | void |
| 56 | −swit1(C1 *q, int nc, long def, Node *n, Node *tn) | |
| 14 | +swit2(C1 *q, int nc, long def, Node *n, Node *tn) | |
| 57 | 15 | { |
| 58 | 16 | C1 *r; |
| 59 | 17 | int i; |
| @@ -87,20 +45,10 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn) · 27 unmodified lines | ||
| 87 | 45 | gbranch(OGOTO); |
| 88 | 46 | p->as = ABE; |
| 89 | 47 | patch(p, r->label); |
| 90 | − swit1(q, i, def, n, tn); | |
| 48 | + swit2(q, i, def, n, tn); | |
| 91 | 49 | |
| 92 | 50 | patch(sp, pc); |
| 93 | − swit1(r+1, nc-i-1, def, n, tn); | |
| 94 | −} | |
| 95 | − | |
| 96 | −void | |
| 97 | −casf(void) | |
| 98 | −{ | |
| 99 | − Case *c; | |
| 100 | − | |
| 101 | − c = alloc(sizeof(*c)); | |
| 102 | − c->link = cases; | |
| 103 | − cases = c; | |
| 51 | + swit2(r+1, nc-i-1, def, n, tn); | |
| 104 | 52 | } |
| 105 | 53 | |
| 106 | 54 | void |
| @@ -198,31 +146,6 @@ outstring(char *s, long n) · 91 unmodified lines | ||
| 198 | 146 | return r; |
| 199 | 147 | } |
| 200 | 148 | |
| 201 | −long | |
| 202 | −outlstring(ushort *s, long n) | |
| 203 | −{ | |
| 204 | − char buf[2]; | |
| 205 | − int c; | |
| 206 | − long r; | |
| 207 | − | |
| 208 | − while(nstring & 1) | |
| 209 | − outstring("", 1); | |
| 210 | − r = nstring; | |
| 211 | − while(n > 0) { | |
| 212 | − c = *s++; | |
| 213 | − if(align(0, types[TCHAR], Aarg1)) { | |
| 214 | − buf[0] = c>>8; | |
| 215 | − buf[1] = c; | |
| 216 | − } else { | |
| 217 | − buf[0] = c; | |
| 218 | − buf[1] = c>>8; | |
| 219 | − } | |
| 220 | − outstring(buf, 2); | |
| 221 | − n -= sizeof(ushort); | |
| 222 | − } | |
| 223 | − return r; | |
| 224 | −} | |
| 225 | − | |
| 226 | 149 | int |
| 227 | 150 | mulcon(Node *n, Node *nn) |
| 228 | 151 | { |
| @@ -312,16 +235,6 @@ loop: · 83 unmodified lines | ||
| 312 | 235 | goto loop; |
| 313 | 236 | } |
| 314 | 237 | |
| 315 | −void | |
| 316 | −nullwarn(Node *l, Node *r) | |
| 317 | −{ | |
| 318 | − warn(Z, "result of operation not used"); | |
| 319 | − if(l != Z) | |
| 320 | − cgen(l, Z); | |
| 321 | − if(r != Z) | |
| 322 | − cgen(r, Z); | |
| 323 | −} | |
| 324 | − | |
| 325 | 238 | void |
| 326 | 239 | sextern(Sym *s, Node *a, long o, long w) |
| 327 | 240 | { |
| @@ -609,35 +522,6 @@ zaddr(Biobuf *b, Adr *a, int s) · 281 unmodified lines | ||
| 609 | 522 | } |
| 610 | 523 | } |
| 611 | 524 | |
| 612 | −void | |
| 613 | −ieeedtod(Ieee *ieee, double native) | |
| 614 | −{ | |
| 615 | − double fr, ho, f; | |
| 616 | − int exp; | |
| 617 | − | |
| 618 | − if(native < 0) { | |
| 619 | − ieeedtod(ieee, -native); | |
| 620 | − ieee->h |= 0x80000000L; | |
| 621 | − return; | |
| 622 | − } | |
| 623 | − if(native == 0) { | |
| 624 | − ieee->l = 0; | |
| 625 | − ieee->h = 0; | |
| 626 | − return; | |
| 627 | − } | |
| 628 | − fr = frexp(native, &exp); | |
| 629 | − f = 2097152L; /* shouldnt use fp constants here */ | |
| 630 | − fr = modf(fr*f, &ho); | |
| 631 | − ieee->h = ho; | |
| 632 | − ieee->h &= 0xfffffL; | |
| 633 | − ieee->h |= (exp+1022L) << 20; | |
| 634 | − f = 65536L; | |
| 635 | − fr = modf(fr*f, &ho); | |
| 636 | − ieee->l = ho; | |
| 637 | − ieee->l <<= 16; | |
| 638 | − ieee->l |= (long)(fr*f); | |
| 639 | −} | |
| 640 | − | |
| 641 | 525 | long |
| 642 | 526 | align(long i, Type *t, int op) |
| 643 | 527 | { |
| @@ -497,6 +497,8 @@ cgen(Node *n, Node *nn) · 496 unmodified lines | ||
| 497 | 497 | } else |
| 498 | 498 | gopcode(OADD, nodconst(v), Z, &nod); |
| 499 | 499 | gopcode(OAS, &nod, Z, &nod2); |
| 500 | + if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */ | |
| 501 | + gins(ANOP, l, Z); | |
| 500 | 502 | |
| 501 | 503 | regfree(&nod); |
| 502 | 504 | if(l->addable < INDEXED) |
| @@ -58,6 +58,7 @@ struct Case · 57 unmodified lines | ||
| 58 | 58 | long val; |
| 59 | 59 | long label; |
| 60 | 60 | char def; |
| 61 | + char isv; | |
| 61 | 62 | }; |
| 62 | 63 | #define C ((Case*)0) |
| 63 | 64 | |
| @@ -129,6 +130,7 @@ struct Rgn · 65 unmodified lines | ||
| 129 | 130 | }; |
| 130 | 131 | |
| 131 | 132 | EXTERN long breakpc; |
| 133 | +EXTERN long nbreak; | |
| 132 | 134 | EXTERN Case* cases; |
| 133 | 135 | EXTERN Node constnode; |
| 134 | 136 | EXTERN Node fconstnode; |
| @@ -140,7 +142,6 @@ EXTERN Prog* lastp; · 5 unmodified lines | ||
| 140 | 142 | EXTERN long maxargsafe; |
| 141 | 143 | EXTERN int mnstring; |
| 142 | 144 | EXTERN Multab multab[20]; |
| 143 | −EXTERN int retok; | |
| 144 | 145 | EXTERN int hintabsize; |
| 145 | 146 | EXTERN Node* nodrat; |
| 146 | 147 | EXTERN Node* nodret; |
| @@ -184,6 +185,7 @@ EXTERN long regbits; · 37 unmodified lines | ||
| 184 | 185 | EXTERN long exregbits; |
| 185 | 186 | |
| 186 | 187 | EXTERN int change; |
| 188 | +EXTERN int suppress; | |
| 187 | 189 | |
| 188 | 190 | EXTERN Reg* firstr; |
| 189 | 191 | EXTERN Reg* lastr; |
| @@ -204,7 +206,7 @@ void codgen(Node*, Node*); · 14 unmodified lines | ||
| 204 | 206 | void gen(Node*); |
| 205 | 207 | void noretval(int); |
| 206 | 208 | void xcom(Node*); |
| 207 | −void bcomplex(Node*); | |
| 209 | +int bcomplex(Node*, Node*); | |
| 208 | 210 | void usedset(Node*, int); |
| 209 | 211 | |
| 210 | 212 | /* |
| @@ -256,7 +258,8 @@ void gpseudo(int, Sym*, Node*); · 45 unmodified lines | ||
| 256 | 258 | */ |
| 257 | 259 | int swcmp(const void*, const void*); |
| 258 | 260 | void doswit(Node*); |
| 259 | −void swit1(C1*, int, long, Node*, Node*); | |
| 261 | +void swit1(C1*, int, long, Node*); | |
| 262 | +void swit2(C1*, int, long, Node*, Node*); | |
| 260 | 263 | void casf(void); |
| 261 | 264 | void bitload(Node*, Node*, Node*, Node*, Node*); |
| 262 | 265 | void bitstore(Node*, Node*, Node*, Node*, Node*); |
| @@ -7,6 +7,8 @@ OFILES=\ · 6 unmodified lines | ||
| 7 | 7 | enam.$O\ |
| 8 | 8 | list.$O\ |
| 9 | 9 | peep.$O\ |
| 10 | + pgen.$O\ | |
| 11 | + pswt.$O\ | |
| 10 | 12 | reg.$O\ |
| 11 | 13 | sgen.$O\ |
| 12 | 14 | swt.$O\ |
| @@ -30,3 +32,9 @@ $ROOT/$OBJDIR/lib/libcc.a: · 17 unmodified lines | ||
| 30 | 32 | cd ../cc |
| 31 | 33 | mk $MKFLAGS install |
| 32 | 34 | mk $MKFLAGS clean |
| 35 | + | |
| 36 | +%.$O: ../cc/%.c | |
| 37 | + $CC $CFLAGS -I. ../cc/$stem.c | |
| 38 | + | |
| 39 | +#enam.c: v.out.h | |
| 40 | +# rc mkenam | |
| @@ -569,7 +569,7 @@ copyu(Prog *p, Adr *v, Adr *s) · 568 unmodified lines | ||
| 569 | 569 | return 3; |
| 570 | 570 | return 0; |
| 571 | 571 | } |
| 572 | − return 0; | |
| 572 | + /* not reached */ | |
| 573 | 573 | } |
| 574 | 574 | |
| 575 | 575 | int |
| @@ -1,344 +1,5 @@ | ||
| 1 | 1 | #include "gc.h" |
| 2 | 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 | −gen(Node *n) | |
| 64 | −{ | |
| 65 | − Node *l, nod; | |
| 66 | − Prog *sp, *spc, *spb; | |
| 67 | − Case *cn; | |
| 68 | − long sbc, scc; | |
| 69 | − int o; | |
| 70 | − | |
| 71 | −loop: | |
| 72 | − if(n == Z) | |
| 73 | − return; | |
| 74 | − nearln = n->lineno; | |
| 75 | − o = n->op; | |
| 76 | − if(debug['G']) | |
| 77 | − if(o != OLIST) | |
| 78 | − print("%L %O\n", nearln, o); | |
| 79 | − | |
| 80 | − retok = 0; | |
| 81 | − switch(o) { | |
| 82 | − | |
| 83 | − default: | |
| 84 | − complex(n); | |
| 85 | − cgen(n, Z); | |
| 86 | − break; | |
| 87 | − | |
| 88 | − case OLIST: | |
| 89 | − gen(n->left); | |
| 90 | − | |
| 91 | − rloop: | |
| 92 | − n = n->right; | |
| 93 | − goto loop; | |
| 94 | − | |
| 95 | − case ORETURN: | |
| 96 | − retok = 1; | |
| 97 | − complex(n); | |
| 98 | − if(n->type == T) | |
| 99 | − break; | |
| 100 | − l = n->left; | |
| 101 | − if(l == Z) { | |
| 102 | − noretval(3); | |
| 103 | − gbranch(ORETURN); | |
| 104 | − break; | |
| 105 | − } | |
| 106 | − if(typesuv[n->type->etype]) { | |
| 107 | − sugen(l, nodret, n->type->width); | |
| 108 | − noretval(3); | |
| 109 | − gbranch(ORETURN); | |
| 110 | − break; | |
| 111 | − } | |
| 112 | − regret(&nod, n); | |
| 113 | − cgen(l, &nod); | |
| 114 | − regfree(&nod); | |
| 115 | − if(typefd[n->type->etype]) | |
| 116 | − noretval(1); | |
| 117 | − else | |
| 118 | − noretval(2); | |
| 119 | − gbranch(ORETURN); | |
| 120 | − break; | |
| 121 | − | |
| 122 | − case OLABEL: | |
| 123 | − l = n->left; | |
| 124 | − if(l) { | |
| 125 | − l->pc = pc; | |
| 126 | − if(l->label) | |
| 127 | − patch(l->label, pc); | |
| 128 | − } | |
| 129 | − gbranch(OGOTO); /* prevent self reference in reg */ | |
| 130 | − patch(p, pc); | |
| 131 | − goto rloop; | |
| 132 | − | |
| 133 | − case OGOTO: | |
| 134 | − retok = 1; | |
| 135 | − n = n->left; | |
| 136 | − if(n == Z) | |
| 137 | − return; | |
| 138 | − if(n->complex == 0) { | |
| 139 | − diag(Z, "label undefined: %s", n->sym->name); | |
| 140 | − return; | |
| 141 | − } | |
| 142 | − gbranch(OGOTO); | |
| 143 | − if(n->pc) { | |
| 144 | − patch(p, n->pc); | |
| 145 | − return; | |
| 146 | − } | |
| 147 | − if(n->label) | |
| 148 | − patch(n->label, pc-1); | |
| 149 | − n->label = p; | |
| 150 | − return; | |
| 151 | − | |
| 152 | − case OCASE: | |
| 153 | − l = n->left; | |
| 154 | − if(cases == C) | |
| 155 | − diag(n, "case/default outside a switch"); | |
| 156 | − if(l == Z) { | |
| 157 | − casf(); | |
| 158 | − cases->val = 0; | |
| 159 | − cases->def = 1; | |
| 160 | − cases->label = pc; | |
| 161 | − goto rloop; | |
| 162 | − } | |
| 163 | − complex(l); | |
| 164 | − if(l->type == T) | |
| 165 | − goto rloop; | |
| 166 | − if(l->op == OCONST) | |
| 167 | − if(typechl[l->type->etype]) { | |
| 168 | − casf(); | |
| 169 | − cases->val = l->vconst; | |
| 170 | − cases->def = 0; | |
| 171 | − cases->label = pc; | |
| 172 | − goto rloop; | |
| 173 | − } | |
| 174 | − diag(n, "case expression must be integer constant"); | |
| 175 | − goto rloop; | |
| 176 | − | |
| 177 | − case OSWITCH: | |
| 178 | − l = n->left; | |
| 179 | − complex(l); | |
| 180 | − if(l->type == T) | |
| 181 | − break; | |
| 182 | − if(!typechl[l->type->etype]) { | |
| 183 | − diag(n, "switch expression must be integer"); | |
| 184 | − break; | |
| 185 | − } | |
| 186 | − | |
| 187 | − gbranch(OGOTO); /* entry */ | |
| 188 | − sp = p; | |
| 189 | − | |
| 190 | − cn = cases; | |
| 191 | − cases = C; | |
| 192 | − casf(); | |
| 193 | − | |
| 194 | − sbc = breakpc; | |
| 195 | − breakpc = pc; | |
| 196 | − gbranch(OGOTO); | |
| 197 | − spb = p; | |
| 198 | − | |
| 199 | − gen(n->right); | |
| 200 | − gbranch(OGOTO); | |
| 201 | − patch(p, breakpc); | |
| 202 | − | |
| 203 | − patch(sp, pc); | |
| 204 | − regalloc(&nod, l, Z); | |
| 205 | − nod.type = types[TLONG]; | |
| 206 | − cgen(l, &nod); | |
| 207 | − doswit(&nod); | |
| 208 | − regfree(&nod); | |
| 209 | − patch(spb, pc); | |
| 210 | − | |
| 211 | − cases = cn; | |
| 212 | − breakpc = sbc; | |
| 213 | − break; | |
| 214 | − | |
| 215 | − case OWHILE: | |
| 216 | − case ODWHILE: | |
| 217 | − l = n->left; | |
| 218 | − gbranch(OGOTO); /* entry */ | |
| 219 | − sp = p; | |
| 220 | − | |
| 221 | − scc = continpc; | |
| 222 | − continpc = pc; | |
| 223 | − gbranch(OGOTO); | |
| 224 | − spc = p; | |
| 225 | − | |
| 226 | − sbc = breakpc; | |
| 227 | − breakpc = pc; | |
| 228 | − gbranch(OGOTO); | |
| 229 | − spb = p; | |
| 230 | − | |
| 231 | − patch(spc, pc); | |
| 232 | − if(n->op == OWHILE) | |
| 233 | − patch(sp, pc); | |
| 234 | − bcomplex(l); /* test */ | |
| 235 | − patch(p, breakpc); | |
| 236 | − | |
| 237 | − if(n->op == ODWHILE) | |
| 238 | − patch(sp, pc); | |
| 239 | − gen(n->right); /* body */ | |
| 240 | − gbranch(OGOTO); | |
| 241 | − patch(p, continpc); | |
| 242 | − | |
| 243 | − patch(spb, pc); | |
| 244 | − continpc = scc; | |
| 245 | − breakpc = sbc; | |
| 246 | − break; | |
| 247 | − | |
| 248 | − case OFOR: | |
| 249 | − l = n->left; | |
| 250 | − gen(l->right->left); /* init */ | |
| 251 | − gbranch(OGOTO); /* entry */ | |
| 252 | − sp = p; | |
| 253 | − | |
| 254 | − scc = continpc; | |
| 255 | − continpc = pc; | |
| 256 | − gbranch(OGOTO); | |
| 257 | − spc = p; | |
| 258 | − | |
| 259 | − sbc = breakpc; | |
| 260 | − breakpc = pc; | |
| 261 | − gbranch(OGOTO); | |
| 262 | − spb = p; | |
| 263 | − | |
| 264 | − patch(spc, pc); | |
| 265 | − gen(l->right->right); /* inc */ | |
| 266 | − patch(sp, pc); | |
| 267 | − if(l->left != Z) { /* test */ | |
| 268 | − bcomplex(l->left); | |
| 269 | − patch(p, breakpc); | |
| 270 | − } | |
| 271 | − gen(n->right); /* body */ | |
| 272 | − gbranch(OGOTO); | |
| 273 | − patch(p, continpc); | |
| 274 | − | |
| 275 | − patch(spb, pc); | |
| 276 | − continpc = scc; | |
| 277 | − breakpc = sbc; | |
| 278 | − break; | |
| 279 | − | |
| 280 | − case OCONTINUE: | |
| 281 | − if(continpc < 0) { | |
| 282 | − diag(n, "continue not in a loop"); | |
| 283 | − break; | |
| 284 | − } | |
| 285 | − gbranch(OGOTO); | |
| 286 | − patch(p, continpc); | |
| 287 | − break; | |
| 288 | − | |
| 289 | − case OBREAK: | |
| 290 | − if(breakpc < 0) { | |
| 291 | − diag(n, "break not in a loop"); | |
| 292 | − break; | |
| 293 | − } | |
| 294 | − gbranch(OGOTO); | |
| 295 | − patch(p, breakpc); | |
| 296 | − break; | |
| 297 | − | |
| 298 | − case OIF: | |
| 299 | − l = n->left; | |
| 300 | − bcomplex(l); | |
| 301 | − sp = p; | |
| 302 | − if(n->right->left != Z) | |
| 303 | − gen(n->right->left); | |
| 304 | − if(n->right->right != Z) { | |
| 305 | − gbranch(OGOTO); | |
| 306 | − patch(sp, pc); | |
| 307 | − sp = p; | |
| 308 | − gen(n->right->right); | |
| 309 | − } | |
| 310 | − patch(sp, pc); | |
| 311 | − break; | |
| 312 | − | |
| 313 | − case OSET: | |
| 314 | − case OUSED: | |
| 315 | − usedset(n->left, o); | |
| 316 | − break; | |
| 317 | − } | |
| 318 | −} | |
| 319 | − | |
| 320 | −void | |
| 321 | −usedset(Node *n, int o) | |
| 322 | −{ | |
| 323 | − if(n->op == OLIST) { | |
| 324 | − usedset(n->left, o); | |
| 325 | − usedset(n->right, o); | |
| 326 | − return; | |
| 327 | − } | |
| 328 | − complex(n); | |
| 329 | − switch(n->op) { | |
| 330 | − case OADDR: /* volatile */ | |
| 331 | − gins(ANOP, n, Z); | |
| 332 | − break; | |
| 333 | − case ONAME: | |
| 334 | − if(o == OSET) | |
| 335 | − gins(ANOP, Z, n); | |
| 336 | − else | |
| 337 | − gins(ANOP, n, Z); | |
| 338 | − break; | |
| 339 | − } | |
| 340 | −} | |
| 341 | − | |
| 342 | 3 | void |
| 343 | 4 | noretval(int n) |
| 344 | 5 | { |
| @@ -564,17 +225,3 @@ xcom(Node *n) · 219 unmodified lines | ||
| 564 | 225 | } |
| 565 | 226 | } |
| 566 | 227 | |
| 567 | −void | |
| 568 | −bcomplex(Node *n) | |
| 569 | −{ | |
| 570 | − | |
| 571 | − complex(n); | |
| 572 | − if(n->type != T) | |
| 573 | − if(tcompat(n, T, n->type, tnot)) | |
| 574 | − n->type = T; | |
| 575 | − if(n->type != T) { | |
| 576 | − bool64(n); | |
| 577 | − boolgen(n, 1, Z); | |
| 578 | − } else | |
| 579 | − gbranch(OGOTO); | |
| 580 | −} | |
| @@ -1,62 +1,17 @@ | ||
| 1 | 1 | #include "gc.h" |
| 2 | 2 | |
| 3 | −int | |
| 4 | −swcmp(const void *a1, const 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 | 3 | void |
| 16 | −doswit(Node *n) | |
| 4 | +swit1(C1 *q, int nc, long def, Node *n) | |
| 17 | 5 | { |
| 18 | − Case *c; | |
| 19 | − C1 *q, *iq; | |
| 20 | − long def, nc, i; | |
| 21 | 6 | Node tn; |
| 22 | − | |
| 23 | − def = 0; | |
| 24 | − nc = 0; | |
| 25 | − for(c = cases; c->link != C; c = c->link) { | |
| 26 | − if(c->def) { | |
| 27 | − if(def) | |
| 28 | − diag(n, "more than one default in switch"); | |
| 29 | − def = c->label; | |
| 30 | − continue; | |
| 31 | − } | |
| 32 | − nc++; | |
| 33 | − } | |
| 34 | − | |
| 35 | − iq = alloc(nc*sizeof(C1)); | |
| 36 | − q = iq; | |
| 37 | − for(c = cases; c->link != C; c = c->link) { | |
| 38 | − if(c->def) | |
| 39 | − continue; | |
| 40 | − q->label = c->label; | |
| 41 | − q->val = c->val; | |
| 42 | − q++; | |
| 43 | − } | |
| 44 | − qsort(iq, nc, sizeof(C1), swcmp); | |
| 45 | − if(debug['W']) | |
| 46 | − for(i=0; i<nc; i++) | |
| 47 | − print("case %2ld: = %.8lux\n", i, iq[i].val); | |
| 48 | − if(def == 0) | |
| 49 | − def = breakpc; | |
| 50 | − for(i=0; i<nc-1; i++) | |
| 51 | − if(iq[i].val == iq[i+1].val) | |
| 52 | − diag(n, "duplicate cases in switch %ld", iq[i].val); | |
| 7 | + | |
| 53 | 8 | regalloc(&tn, ®node, Z); |
| 54 | − swit1(iq, nc, def, n, &tn); | |
| 9 | + swit2(q, nc, def, n, &tn); | |
| 55 | 10 | regfree(&tn); |
| 56 | 11 | } |
| 57 | 12 | |
| 58 | 13 | void |
| 59 | −swit1(C1 *q, int nc, long def, Node *n, Node *tn) | |
| 14 | +swit2(C1 *q, int nc, long def, Node *n, Node *tn) | |
| 60 | 15 | { |
| 61 | 16 | C1 *r; |
| 62 | 17 | int i; |
| @@ -84,22 +39,12 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn) · 21 unmodified lines | ||
| 84 | 39 | sp = p; |
| 85 | 40 | gopcode(OEQ, n, tn, Z); |
| 86 | 41 | patch(p, r->label); |
| 87 | − swit1(q, i, def, n, tn); | |
| 42 | + swit2(q, i, def, n, tn); | |
| 88 | 43 | |
| 89 | 44 | if(debug['W']) |
| 90 | 45 | print("case < %.8lux\n", r->val); |
| 91 | 46 | patch(sp, pc); |
| 92 | − swit1(r+1, nc-i-1, def, n, tn); | |
| 93 | −} | |
| 94 | − | |
| 95 | −void | |
| 96 | −casf(void) | |
| 97 | −{ | |
| 98 | − Case *c; | |
| 99 | − | |
| 100 | − c = alloc(sizeof(*c)); | |
| 101 | − c->link = cases; | |
| 102 | − cases = c; | |
| 47 | + swit2(r+1, nc-i-1, def, n, tn); | |
| 103 | 48 | } |
| 104 | 49 | |
| 105 | 50 | void |
| @@ -197,31 +142,6 @@ outstring(char *s, long n) · 91 unmodified lines | ||
| 197 | 142 | return r; |
| 198 | 143 | } |
| 199 | 144 | |
| 200 | −long | |
| 201 | −outlstring(ushort *s, long n) | |
| 202 | −{ | |
| 203 | − char buf[2]; | |
| 204 | − int c; | |
| 205 | − long r; | |
| 206 | − | |
| 207 | − while(nstring & 1) | |
| 208 | − outstring("", 1); | |
| 209 | − r = nstring; | |
| 210 | − while(n > 0) { | |
| 211 | − c = *s++; | |
| 212 | − if(align(0, types[TCHAR], Aarg1)) { | |
| 213 | − buf[0] = c>>8; | |
| 214 | − buf[1] = c; | |
| 215 | − } else { | |
| 216 | − buf[0] = c; | |
| 217 | − buf[1] = c>>8; | |
| 218 | − } | |
| 219 | − outstring(buf, 2); | |
| 220 | − n -= sizeof(ushort); | |
| 221 | − } | |
| 222 | − return r; | |
| 223 | −} | |
| 224 | − | |
| 225 | 145 | int |
| 226 | 146 | mulcon(Node *n, Node *nn) |
| 227 | 147 | { |
| @@ -313,16 +233,6 @@ loop: · 85 unmodified lines | ||
| 313 | 233 | goto loop; |
| 314 | 234 | } |
| 315 | 235 | |
| 316 | −void | |
| 317 | −nullwarn(Node *l, Node *r) | |
| 318 | −{ | |
| 319 | − warn(Z, "result of operation not used"); | |
| 320 | − if(l != Z) | |
| 321 | − cgen(l, Z); | |
| 322 | − if(r != Z) | |
| 323 | − cgen(r, Z); | |
| 324 | −} | |
| 325 | − | |
| 326 | 236 | void |
| 327 | 237 | sextern(Sym *s, Node *a, long o, long w) |
| 328 | 238 | { |
| @@ -615,35 +525,6 @@ zaddr(char *bp, Adr *a, int s) · 286 unmodified lines | ||
| 615 | 525 | return bp; |
| 616 | 526 | } |
| 617 | 527 | |
| 618 | −void | |
| 619 | −ieeedtod(Ieee *ieee, double native) | |
| 620 | −{ | |
| 621 | − double fr, ho, f; | |
| 622 | − int exp; | |
| 623 | − | |
| 624 | − if(native < 0) { | |
| 625 | − ieeedtod(ieee, -native); | |
| 626 | − ieee->h |= 0x80000000L; | |
| 627 | − return; | |
| 628 | − } | |
| 629 | − if(native == 0) { | |
| 630 | − ieee->l = 0; | |
| 631 | − ieee->h = 0; | |
| 632 | − return; | |
| 633 | − } | |
| 634 | − fr = frexp(native, &exp); | |
| 635 | − f = 2097152L; /* shouldnt use fp constants here */ | |
| 636 | − fr = modf(fr*f, &ho); | |
| 637 | − ieee->h = ho; | |
| 638 | − ieee->h &= 0xfffffL; | |
| 639 | − ieee->h |= (exp+1022L) << 20; | |
| 640 | − f = 65536L; | |
| 641 | − fr = modf(fr*f, &ho); | |
| 642 | − ieee->l = ho; | |
| 643 | − ieee->l <<= 16; | |
| 644 | − ieee->l |= (long)(fr*f); | |
| 645 | −} | |
| 646 | − | |
| 647 | 528 | long |
| 648 | 529 | align(long i, Type *t, int op) |
| 649 | 530 | { |
| @@ -660,6 +541,8 @@ align(long i, Type *t, int op) · 10 unmodified lines | ||
| 660 | 541 | |
| 661 | 542 | case Asu2: /* padding at end of a struct */ |
| 662 | 543 | w = SZ_LONG; |
| 544 | + if(packflg) | |
| 545 | + w = packflg; | |
| 663 | 546 | break; |
| 664 | 547 | |
| 665 | 548 | case Ael1: /* initial allign of struct element */ |
| @@ -668,6 +551,8 @@ align(long i, Type *t, int op) · 2 unmodified lines | ||
| 668 | 551 | w = ewidth[v->etype]; |
| 669 | 552 | if(w <= 0 || w >= SZ_LONG) |
| 670 | 553 | w = SZ_LONG; |
| 554 | + if(packflg) | |
| 555 | + w = packflg; | |
| 671 | 556 | break; |
| 672 | 557 | |
| 673 | 558 | case Ael2: /* width of a struct element */ |
| @@ -687,7 +572,8 @@ align(long i, Type *t, int op) · 13 unmodified lines | ||
| 687 | 572 | w = SZ_LONG; |
| 688 | 573 | break; |
| 689 | 574 | } |
| 690 | − o += SZ_LONG - w; /* big endian adjustment */ | |
| 575 | + if(thechar == 'v') | |
| 576 | + o += SZ_LONG - w; /* big endian adjustment */ | |
| 691 | 577 | w = 1; |
| 692 | 578 | break; |
| 693 | 579 | |