changeset 7179: | b3b84087ac92 |
parent: | 3dd7e5a4f49a |
child: | e91d6e59da67 |
author: | cinap_lenrek@felloff.net |
date: | Wed, 01 May 2019 08:55:24 +0200 |
permissions: | -rw-r--r-- |
description: | [5678vq]c: fix .safe node type for *FUNC() = *FUNC() sugen |
1 #include "gc.h"3 /* ,x/^(print|prtree)\(/i/\/\/ */4 int castup(Type*, Type*);6 void7 cgen(Node *n, Node *nn)8 {9 Node *l, *r, *t;10 Prog *p1;11 Node nod, nod1, nod2, nod3, nod4;12 int o, hardleft;13 long v, curs;14 vlong c;16 if(debug['g']) {17 prtree(nn, "cgen lhs");18 prtree(n, "cgen");19 }20 if(n == Z || n->type == T)21 return;22 if(typesu[n->type->etype]) {23 sugen(n, nn, n->type->width);24 return;25 }26 l = n->left;27 r = n->right;28 o = n->op;29 if(n->addable >= INDEXED) {30 if(nn == Z) {31 switch(o) {32 default:33 nullwarn(Z, Z);34 break;35 case OINDEX:36 nullwarn(l, r);37 break;38 }39 return;40 }41 gmove(n, nn);42 return;43 }44 curs = cursafe;46 if(l->complex >= FNX)47 if(r != Z && r->complex >= FNX)48 switch(o) {49 default:50 if(cond(o) && typesu[l->type->etype])51 break;53 regret(&nod, r);54 cgen(r, &nod);56 regsalloc(&nod1, r);57 gmove(&nod, &nod1);59 regfree(&nod);60 nod = *n;61 nod.right = &nod1;63 cgen(&nod, nn);64 return;66 case OFUNC:67 case OCOMMA:68 case OANDAND:69 case OOROR:70 case OCOND:71 case ODOT:72 break;73 }75 hardleft = l->addable < INDEXED || l->complex >= FNX;76 switch(o) {77 default:78 diag(n, "unknown op in cgen: %O", o);79 break;81 case ONEG:82 case OCOM:83 if(nn == Z) {84 nullwarn(l, Z);85 break;86 }87 regalloc(&nod, l, nn);88 cgen(l, &nod);89 gopcode(o, n->type, Z, &nod);90 gmove(&nod, nn);91 regfree(&nod);92 break;94 case OAS:95 if(l->op == OBIT)96 goto bitas;97 if(!hardleft) {98 if(nn != Z || r->addable < INDEXED || hardconst(r)) {99 if(r->complex >= FNX && nn == Z)100 regret(&nod, r);101 else102 regalloc(&nod, r, nn);103 cgen(r, &nod);104 gmove(&nod, l);105 if(nn != Z)106 gmove(&nod, nn);107 regfree(&nod);108 } else109 gmove(r, l);110 break;111 }112 if(l->complex >= r->complex) {113 if(l->op == OINDEX && immconst(r)) {114 gmove(r, l);115 break;116 }117 reglcgen(&nod1, l, Z);118 if(r->addable >= INDEXED && !hardconst(r)) {119 gmove(r, &nod1);120 if(nn != Z)121 gmove(r, nn);122 regfree(&nod1);123 break;124 }125 regalloc(&nod, r, nn);126 cgen(r, &nod);127 } else {128 regalloc(&nod, r, nn);129 cgen(r, &nod);130 reglcgen(&nod1, l, Z);131 }132 gmove(&nod, &nod1);133 regfree(&nod);134 regfree(&nod1);135 break;137 bitas:138 n = l->left;139 regalloc(&nod, r, nn);140 if(l->complex >= r->complex) {141 reglcgen(&nod1, n, Z);142 cgen(r, &nod);143 } else {144 cgen(r, &nod);145 reglcgen(&nod1, n, Z);146 }147 regalloc(&nod2, n, Z);148 gmove(&nod1, &nod2);149 bitstore(l, &nod, &nod1, &nod2, nn);150 break;152 case OBIT:153 if(nn == Z) {154 nullwarn(l, Z);155 break;156 }157 bitload(n, &nod, Z, Z, nn);158 gmove(&nod, nn);159 regfree(&nod);160 break;162 case OROL:163 case OLSHR:164 case OASHL:165 case OASHR:166 if(nn == Z) {167 nullwarn(l, r);168 break;169 }170 if(r->op == OCONST) {171 if(r->vconst == 0) {172 cgen(l, nn);173 break;174 }175 regalloc(&nod, l, nn);176 cgen(l, &nod);177 if(o == OASHL && r->vconst == 1)178 gopcode(OADD, n->type, &nod, &nod);179 else180 gopcode(o, n->type, r, &nod);181 gmove(&nod, nn);182 regfree(&nod);183 break;184 }186 /*187 * get nod to be D_CX188 */189 if(nodreg(&nod, nn, D_CX)) {190 regsalloc(&nod1, n);191 gmove(&nod, &nod1);192 cgen(n, &nod); /* probably a bug */193 gmove(&nod, nn);194 gmove(&nod1, &nod);195 break;196 }197 reg[D_CX]++;198 if(nn->op == OREGISTER && nn->reg == D_CX)199 regalloc(&nod1, l, Z);200 else201 regalloc(&nod1, l, nn);202 if(r->complex >= l->complex) {203 cgen(r, &nod);204 cgen(l, &nod1);205 } else {206 cgen(l, &nod1);207 cgen(r, &nod);208 }209 gopcode(o, n->type, &nod, &nod1);210 gmove(&nod1, nn);211 regfree(&nod);212 regfree(&nod1);213 break;215 case OADD:216 case OSUB:217 case OOR:218 case OXOR:219 case OAND:220 if(nn == Z) {221 nullwarn(l, r);222 break;223 }224 if(typefd[n->type->etype])225 goto fop;226 if(r->op == OCONST) {227 if(r->vconst == 0 && o != OAND) {228 cgen(l, nn);229 break;230 }231 }232 if(n->op == OADD && l->op == OASHL && l->right->op == OCONST233 && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {234 c = l->right->vconst;235 if(c > 0 && c <= 3) {236 if(l->left->complex >= r->complex) {237 regalloc(&nod, l->left, nn);238 cgen(l->left, &nod);239 if(r->addable < INDEXED) {240 regalloc(&nod1, r, Z);241 cgen(r, &nod1);242 genmuladd(&nod, &nod, 1 << c, &nod1);243 regfree(&nod1);244 }245 else246 genmuladd(&nod, &nod, 1 << c, r);247 }248 else {249 regalloc(&nod, r, nn);250 cgen(r, &nod);251 regalloc(&nod1, l->left, Z);252 cgen(l->left, &nod1);253 genmuladd(&nod, &nod1, 1 << c, &nod);254 regfree(&nod1);255 }256 gmove(&nod, nn);257 regfree(&nod);258 break;259 }260 }261 if(r->addable >= INDEXED && !hardconst(r)) {262 regalloc(&nod, l, nn);263 cgen(l, &nod);264 gopcode(o, n->type, r, &nod);265 gmove(&nod, nn);266 regfree(&nod);267 break;268 }269 if(l->complex >= r->complex) {270 regalloc(&nod, l, nn);271 cgen(l, &nod);272 regalloc(&nod1, r, Z);273 cgen(r, &nod1);274 gopcode(o, n->type, &nod1, &nod);275 } else {276 regalloc(&nod1, r, nn);277 cgen(r, &nod1);278 regalloc(&nod, l, Z);279 cgen(l, &nod);280 gopcode(o, n->type, &nod1, &nod);281 }282 gmove(&nod, nn);283 regfree(&nod);284 regfree(&nod1);285 break;287 case OLMOD:288 case OMOD:289 case OLMUL:290 case OLDIV:291 case OMUL:292 case ODIV:293 if(nn == Z) {294 nullwarn(l, r);295 break;296 }297 if(typefd[n->type->etype])298 goto fop;299 if(r->op == OCONST && typechl[n->type->etype]) { /* TO DO */300 SET(v);301 switch(o) {302 case ODIV:303 case OMOD:304 c = r->vconst;305 if(c < 0)306 c = -c;307 v = log2(c);308 if(v < 0)309 break;310 /* fall thru */311 case OMUL:312 case OLMUL:313 regalloc(&nod, l, nn);314 cgen(l, &nod);315 switch(o) {316 case OMUL:317 case OLMUL:318 mulgen(n->type, r, &nod);319 break;320 case ODIV:321 sdiv2(r->vconst, v, l, &nod);322 break;323 case OMOD:324 smod2(r->vconst, v, l, &nod);325 break;326 }327 gmove(&nod, nn);328 regfree(&nod);329 goto done;330 case OLDIV:331 c = r->vconst;332 if((c & 0x80000000) == 0)333 break;334 regalloc(&nod1, l, Z);335 cgen(l, &nod1);336 regalloc(&nod, l, nn);337 zeroregm(&nod);338 gins(ACMPL, &nod1, nodconst(c));339 gins(ASBBL, nodconst(-1), &nod);340 regfree(&nod1);341 gmove(&nod, nn);342 regfree(&nod);343 goto done;344 }345 }347 if(o == OMUL) {348 if(l->addable >= INDEXED) {349 t = l;350 l = r;351 r = t;352 }353 /* should favour AX */354 regalloc(&nod, l, nn);355 cgen(l, &nod);356 if(r->addable < INDEXED || hardconst(r)) {357 regalloc(&nod1, r, Z);358 cgen(r, &nod1);359 gopcode(OMUL, n->type, &nod1, &nod);360 regfree(&nod1);361 }else362 gopcode(OMUL, n->type, r, &nod); /* addressible */363 gmove(&nod, nn);364 regfree(&nod);365 break;366 }368 /*369 * get nod to be D_AX370 * get nod1 to be D_DX371 */372 if(nodreg(&nod, nn, D_AX)) {373 regsalloc(&nod2, n);374 gmove(&nod, &nod2);375 v = reg[D_AX];376 reg[D_AX] = 0;378 if(isreg(l, D_AX)) {379 nod3 = *n;380 nod3.left = &nod2;381 cgen(&nod3, nn);382 } else383 if(isreg(r, D_AX)) {384 nod3 = *n;385 nod3.right = &nod2;386 cgen(&nod3, nn);387 } else388 cgen(n, nn);390 gmove(&nod2, &nod);391 reg[D_AX] = v;392 break;393 }394 if(nodreg(&nod1, nn, D_DX)) {395 regsalloc(&nod2, n);396 gmove(&nod1, &nod2);397 v = reg[D_DX];398 reg[D_DX] = 0;400 if(isreg(l, D_DX)) {401 nod3 = *n;402 nod3.left = &nod2;403 cgen(&nod3, nn);404 } else405 if(isreg(r, D_DX)) {406 nod3 = *n;407 nod3.right = &nod2;408 cgen(&nod3, nn);409 } else410 cgen(n, nn);412 gmove(&nod2, &nod1);413 reg[D_DX] = v;414 break;415 }416 reg[D_AX]++;418 if(r->op == OCONST && (o == ODIV || o == OLDIV) && immconst(r) && typechl[r->type->etype]) {419 reg[D_DX]++;420 if(l->addable < INDEXED) {421 regalloc(&nod2, l, Z);422 cgen(l, &nod2);423 l = &nod2;424 }425 if(o == ODIV)426 sdivgen(l, r, &nod, &nod1);427 else428 udivgen(l, r, &nod, &nod1);429 gmove(&nod1, nn);430 if(l == &nod2)431 regfree(l);432 goto freeaxdx;433 }435 if(l->complex >= r->complex) {436 cgen(l, &nod);437 reg[D_DX]++;438 if(o == ODIV || o == OMOD)439 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);440 if(o == OLDIV || o == OLMOD)441 zeroregm(&nod1);442 if(r->addable < INDEXED || r->op == OCONST) {443 regalloc(&nod3, r, Z);444 cgen(r, &nod3);445 gopcode(o, n->type, &nod3, Z);446 regfree(&nod3);447 } else448 gopcode(o, n->type, r, Z);449 } else {450 regsalloc(&nod3, r);451 cgen(r, &nod3);452 cgen(l, &nod);453 reg[D_DX]++;454 if(o == ODIV || o == OMOD)455 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);456 if(o == OLDIV || o == OLMOD)457 zeroregm(&nod1);458 gopcode(o, n->type, &nod3, Z);459 }460 if(o == OMOD || o == OLMOD)461 gmove(&nod1, nn);462 else463 gmove(&nod, nn);464 freeaxdx:465 regfree(&nod);466 regfree(&nod1);467 break;469 case OASLSHR:470 case OASASHL:471 case OASASHR:472 if(r->op == OCONST)473 goto asand;474 if(l->op == OBIT)475 goto asbitop;476 if(typefd[n->type->etype])477 goto asand; /* can this happen? */479 /*480 * get nod to be D_CX481 */482 if(nodreg(&nod, nn, D_CX)) {483 regsalloc(&nod1, n);484 gmove(&nod, &nod1);485 cgen(n, &nod);486 if(nn != Z)487 gmove(&nod, nn);488 gmove(&nod1, &nod);489 break;490 }491 reg[D_CX]++;493 if(r->complex >= l->complex) {494 cgen(r, &nod);495 if(hardleft)496 reglcgen(&nod1, l, Z);497 else498 nod1 = *l;499 } else {500 if(hardleft)501 reglcgen(&nod1, l, Z);502 else503 nod1 = *l;504 cgen(r, &nod);505 }507 gopcode(o, l->type, &nod, &nod1);508 regfree(&nod);509 if(nn != Z)510 gmove(&nod1, nn);511 if(hardleft)512 regfree(&nod1);513 break;515 case OASAND:516 case OASADD:517 case OASSUB:518 case OASXOR:519 case OASOR:520 asand:521 if(l->op == OBIT)522 goto asbitop;523 if(typefd[l->type->etype] || typefd[r->type->etype])524 goto asfop;525 if(l->complex >= r->complex) {526 if(hardleft)527 reglcgen(&nod, l, Z);528 else529 nod = *l;530 if(!immconst(r)) {531 regalloc(&nod1, r, nn);532 cgen(r, &nod1);533 gopcode(o, l->type, &nod1, &nod);534 regfree(&nod1);535 } else536 gopcode(o, l->type, r, &nod);537 } else {538 regalloc(&nod1, r, nn);539 cgen(r, &nod1);540 if(hardleft)541 reglcgen(&nod, l, Z);542 else543 nod = *l;544 gopcode(o, l->type, &nod1, &nod);545 regfree(&nod1);546 }547 if(nn != Z)548 gmove(&nod, nn);549 if(hardleft)550 regfree(&nod);551 break;553 asfop:554 if(l->complex >= r->complex) {555 if(hardleft)556 reglcgen(&nod, l, Z);557 else558 nod = *l;559 if(r->addable < INDEXED){560 regalloc(&nod1, r, nn);561 cgen(r, &nod1);562 }else563 nod1 = *r;564 regalloc(&nod2, r, Z);565 gmove(&nod, &nod2);566 gopcode(o, r->type, &nod1, &nod2);567 gmove(&nod2, &nod);568 regfree(&nod2);569 if(r->addable < INDEXED)570 regfree(&nod1);571 } else {572 regalloc(&nod1, r, nn);573 cgen(r, &nod1);574 if(hardleft)575 reglcgen(&nod, l, Z);576 else577 nod = *l;578 if(o != OASMUL && o != OASADD || !typefd[l->type->etype]) {579 regalloc(&nod2, r, Z);580 gmove(&nod, &nod2);581 gopcode(o, r->type, &nod1, &nod2);582 regfree(&nod1);583 gmove(&nod2, &nod);584 regfree(&nod2);585 } else {586 gopcode(o, r->type, &nod, &nod1);587 gmove(&nod1, &nod);588 regfree(&nod1);589 }590 }591 if(nn != Z)592 gmove(&nod, nn);593 if(hardleft)594 regfree(&nod);595 break;597 case OASLMUL:598 case OASLDIV:599 case OASLMOD:600 case OASMUL:601 case OASDIV:602 case OASMOD:603 if(l->op == OBIT)604 goto asbitop;605 if(typefd[n->type->etype] || typefd[r->type->etype])606 goto asfop;607 if(r->op == OCONST && typechl[n->type->etype]) {608 SET(v);609 switch(o) {610 case OASDIV:611 case OASMOD:612 c = r->vconst;613 if(c < 0)614 c = -c;615 v = log2(c);616 if(v < 0)617 break;618 /* fall thru */619 case OASMUL:620 case OASLMUL:621 if(hardleft)622 reglcgen(&nod2, l, Z);623 else624 nod2 = *l;625 regalloc(&nod, l, nn);626 cgen(&nod2, &nod);627 switch(o) {628 case OASMUL:629 case OASLMUL:630 mulgen(n->type, r, &nod);631 break;632 case OASDIV:633 sdiv2(r->vconst, v, l, &nod);634 break;635 case OASMOD:636 smod2(r->vconst, v, l, &nod);637 break;638 }639 havev:640 gmove(&nod, &nod2);641 if(nn != Z)642 gmove(&nod, nn);643 if(hardleft)644 regfree(&nod2);645 regfree(&nod);646 goto done;647 case OASLDIV:648 c = r->vconst;649 if((c & 0x80000000) == 0)650 break;651 if(hardleft)652 reglcgen(&nod2, l, Z);653 else654 nod2 = *l;655 regalloc(&nod1, l, nn);656 cgen(&nod2, &nod1);657 regalloc(&nod, l, nn);658 zeroregm(&nod);659 gins(ACMPL, &nod1, nodconst(c));660 gins(ASBBL, nodconst(-1), &nod);661 regfree(&nod1);662 goto havev;663 }664 }666 if(o == OASMUL) {667 /* should favour AX */668 regalloc(&nod, l, nn);669 if(r->complex >= FNX) {670 regalloc(&nod1, r, Z);671 cgen(r, &nod1);672 r = &nod1;673 }674 if(hardleft)675 reglcgen(&nod2, l, Z);676 else677 nod2 = *l;678 cgen(&nod2, &nod);679 if(r->addable < INDEXED || hardconst(r)) {680 if(r->complex < FNX) {681 regalloc(&nod1, r, Z);682 cgen(r, &nod1);683 }684 gopcode(OASMUL, n->type, &nod1, &nod);685 regfree(&nod1);686 }687 else688 gopcode(OASMUL, n->type, r, &nod);689 if(r == &nod1)690 regfree(r);691 gmove(&nod, &nod2);692 if(nn != Z)693 gmove(&nod, nn);694 regfree(&nod);695 if(hardleft)696 regfree(&nod2);697 break;698 }700 /*701 * get nod to be D_AX702 * get nod1 to be D_DX703 */704 if(nodreg(&nod, nn, D_AX)) {705 regsalloc(&nod2, n);706 gmove(&nod, &nod2);707 v = reg[D_AX];708 reg[D_AX] = 0;710 if(isreg(l, D_AX)) {711 nod3 = *n;712 nod3.left = &nod2;713 cgen(&nod3, nn);714 } else715 if(isreg(r, D_AX)) {716 nod3 = *n;717 nod3.right = &nod2;718 cgen(&nod3, nn);719 } else720 cgen(n, nn);722 gmove(&nod2, &nod);723 reg[D_AX] = v;724 break;725 }726 if(nodreg(&nod1, nn, D_DX)) {727 regsalloc(&nod2, n);728 gmove(&nod1, &nod2);729 v = reg[D_DX];730 reg[D_DX] = 0;732 if(isreg(l, D_DX)) {733 nod3 = *n;734 nod3.left = &nod2;735 cgen(&nod3, nn);736 } else737 if(isreg(r, D_DX)) {738 nod3 = *n;739 nod3.right = &nod2;740 cgen(&nod3, nn);741 } else742 cgen(n, nn);744 gmove(&nod2, &nod1);745 reg[D_DX] = v;746 break;747 }748 reg[D_AX]++;749 reg[D_DX]++;751 if(l->complex >= r->complex) {752 if(hardleft)753 reglcgen(&nod2, l, Z);754 else755 nod2 = *l;756 cgen(&nod2, &nod);757 if(r->op == OCONST && typechl[r->type->etype]) {758 switch(o) {759 case OASDIV:760 sdivgen(&nod2, r, &nod, &nod1);761 goto divdone;762 case OASLDIV:763 udivgen(&nod2, r, &nod, &nod1);764 divdone:765 gmove(&nod1, &nod2);766 if(nn != Z)767 gmove(&nod1, nn);768 goto freelxaxdx;769 }770 }771 if(o == OASDIV || o == OASMOD)772 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);773 if(o == OASLDIV || o == OASLMOD)774 zeroregm(&nod1);775 if(r->addable < INDEXED || r->op == OCONST ||776 !typeil[r->type->etype]) {777 regalloc(&nod3, r, Z);778 cgen(r, &nod3);779 gopcode(o, l->type, &nod3, Z);780 regfree(&nod3);781 } else782 gopcode(o, n->type, r, Z);783 } else {784 regalloc(&nod3, r, Z);785 cgen(r, &nod3);786 if(hardleft)787 reglcgen(&nod2, l, Z);788 else789 nod2 = *l;790 cgen(&nod2, &nod);791 if(o == OASDIV || o == OASMOD)792 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);793 if(o == OASLDIV || o == OASLMOD)794 zeroregm(&nod1);795 gopcode(o, l->type, &nod3, Z);796 regfree(&nod3);797 }798 if(o == OASMOD || o == OASLMOD) {799 gmove(&nod1, &nod2);800 if(nn != Z)801 gmove(&nod1, nn);802 } else {803 gmove(&nod, &nod2);804 if(nn != Z)805 gmove(&nod, nn);806 }807 freelxaxdx:808 if(hardleft)809 regfree(&nod2);810 regfree(&nod);811 regfree(&nod1);812 break;814 fop:815 if(l->complex >= r->complex) {816 regalloc(&nod, l, nn);817 cgen(l, &nod);818 if(r->addable < INDEXED) {819 regalloc(&nod1, r, Z);820 cgen(r, &nod1);821 gopcode(o, n->type, &nod1, &nod);822 regfree(&nod1);823 } else824 gopcode(o, n->type, r, &nod);825 } else {826 /* TO DO: could do better with r->addable >= INDEXED */827 regalloc(&nod1, r, Z);828 cgen(r, &nod1);829 regalloc(&nod, l, nn);830 cgen(l, &nod);831 gopcode(o, n->type, &nod1, &nod);832 regfree(&nod1);833 }834 gmove(&nod, nn);835 regfree(&nod);836 break;838 asbitop:839 regalloc(&nod4, n, nn);840 if(l->complex >= r->complex) {841 bitload(l, &nod, &nod1, &nod2, &nod4);842 regalloc(&nod3, r, Z);843 cgen(r, &nod3);844 } else {845 regalloc(&nod3, r, Z);846 cgen(r, &nod3);847 bitload(l, &nod, &nod1, &nod2, &nod4);848 }849 gmove(&nod, &nod4);851 { /* TO DO: check floating point source */852 Node onod;854 /* incredible grot ... */855 onod = nod3;856 onod.op = o;857 onod.complex = 2;858 onod.addable = 0;859 onod.type = tfield;860 onod.left = &nod4;861 onod.right = &nod3;862 cgen(&onod, Z);863 }864 regfree(&nod3);865 gmove(&nod4, &nod);866 regfree(&nod4);867 bitstore(l, &nod, &nod1, &nod2, nn);868 break;870 case OADDR:871 if(nn == Z) {872 nullwarn(l, Z);873 break;874 }875 lcgen(l, nn);876 break;878 case OFUNC:879 l = uncomma(l);880 if(l->complex >= FNX) {881 if(l->op != OIND)882 diag(n, "bad function call");884 regret(&nod, l->left);885 cgen(l->left, &nod);886 regsalloc(&nod1, l->left);887 gmove(&nod, &nod1);888 regfree(&nod);890 nod = *n;891 nod.left = &nod2;892 nod2 = *l;893 nod2.left = &nod1;894 nod2.complex = 1;895 cgen(&nod, nn);897 return;898 }899 o = reg[REGARG];900 gargs(r, &nod, &nod1);901 if(l->addable < INDEXED) {902 reglcgen(&nod, l, nn);903 nod.op = OREGISTER;904 gopcode(OFUNC, n->type, Z, &nod);905 regfree(&nod);906 } else907 gopcode(OFUNC, n->type, Z, l);908 if(REGARG)909 if(o != reg[REGARG])910 reg[REGARG]--;911 if(nn != Z) {912 regret(&nod, n);913 gmove(&nod, nn);914 regfree(&nod);915 }916 break;918 case OIND:919 if(nn == Z) {920 nullwarn(l, Z);921 break;922 }923 regialloc(&nod, n, nn);924 r = l;925 while(r->op == OADD)926 r = r->right;927 if(sconst(r)) {928 v = r->vconst;929 r->vconst = 0;930 cgen(l, &nod);931 nod.xoffset += v;932 r->vconst = v;933 } else934 cgen(l, &nod);935 regind(&nod, n);936 gmove(&nod, nn);937 regfree(&nod);938 break;940 case OEQ:941 case ONE:942 case OLE:943 case OLT:944 case OGE:945 case OGT:946 case OLO:947 case OLS:948 case OHI:949 case OHS:950 if(nn == Z) {951 nullwarn(l, r);952 break;953 }954 boolgen(n, 1, nn);955 break;957 case OANDAND:958 case OOROR:959 boolgen(n, 1, nn);960 if(nn == Z)961 patch(p, pc);962 break;964 case ONOT:965 if(nn == Z) {966 nullwarn(l, Z);967 break;968 }969 boolgen(n, 1, nn);970 break;972 case OCOMMA:973 cgen(l, Z);974 cgen(r, nn);975 break;977 case OCAST:978 if(nn == Z) {979 if(n->type != types[TVOID])980 nullwarn(l, Z);981 else982 cgen(l, Z);983 break;984 }985 /*986 * convert from types l->n->nn987 */988 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {989 /* both null, gen l->nn */990 cgen(l, nn);991 break;992 }993 if(ewidth[n->type->etype] < ewidth[l->type->etype]){994 if(l->type->etype == TIND && typechlp[n->type->etype])995 warn(n, "conversion of pointer to shorter integer");996 }else if(0){997 if(nocast(n->type, nn->type) || castup(n->type, nn->type)){998 if(typefd[l->type->etype] != typefd[nn->type->etype])999 regalloc(&nod, l, nn);1000 else1001 regalloc(&nod, nn, nn);1002 cgen(l, &nod);1003 gmove(&nod, nn);1004 regfree(&nod);1005 break;1006 }1007 }1008 regalloc(&nod, l, nn);1009 cgen(l, &nod);1010 regalloc(&nod1, n, &nod);1011 gmove(&nod, &nod1);1012 gmove(&nod1, nn);1013 regfree(&nod1);1014 regfree(&nod);1015 break;1017 case ODOT:1018 sugen(l, nodrat, l->type->width);1019 if(nn == Z)1020 break;1021 warn(n, "non-interruptable temporary");1022 nod = *nodrat;1023 if(!r || r->op != OCONST) {1024 diag(n, "DOT and no offset");1025 break;1026 }1027 nod.xoffset += (long)r->vconst;1028 nod.type = n->type;1029 cgen(&nod, nn);1030 break;1032 case OCOND:1033 bcgen(l, 1);1034 p1 = p;1035 cgen(r->left, nn);1036 gbranch(OGOTO);1037 patch(p1, pc);1038 p1 = p;1039 cgen(r->right, nn);1040 patch(p1, pc);1041 break;1043 case OPOSTINC:1044 case OPOSTDEC:1045 v = 1;1046 if(l->type->etype == TIND)1047 v = l->type->link->width;1048 if(o == OPOSTDEC)1049 v = -v;1050 if(l->op == OBIT)1051 goto bitinc;1052 if(nn == Z)1053 goto pre;1055 if(hardleft)1056 reglcgen(&nod, l, Z);1057 else1058 nod = *l;1060 gmove(&nod, nn);1061 if(typefd[n->type->etype]) {1062 regalloc(&nod1, l, Z);1063 gmove(&nod, &nod1);1064 if(v < 0)1065 gopcode(OSUB, n->type, nodfconst(-v), &nod1);1066 else1067 gopcode(OADD, n->type, nodfconst(v), &nod1);1068 gmove(&nod1, &nod);1069 regfree(&nod1);1070 } else1071 gopcode(OADD, n->type, nodconst(v), &nod);1072 if(hardleft)1073 regfree(&nod);1074 break;1076 case OPREINC:1077 case OPREDEC:1078 v = 1;1079 if(l->type->etype == TIND)1080 v = l->type->link->width;1081 if(o == OPREDEC)1082 v = -v;1083 if(l->op == OBIT)1084 goto bitinc;1086 pre:1087 if(hardleft)1088 reglcgen(&nod, l, Z);1089 else1090 nod = *l;1091 if(typefd[n->type->etype]) {1092 regalloc(&nod1, l, Z);1093 gmove(&nod, &nod1);1094 if(v < 0)1095 gopcode(OSUB, n->type, nodfconst(-v), &nod1);1096 else1097 gopcode(OADD, n->type, nodfconst(v), &nod1);1098 gmove(&nod1, &nod);1099 regfree(&nod1);1100 } else1101 gopcode(OADD, n->type, nodconst(v), &nod);1102 if(nn != Z)1103 gmove(&nod, nn);1104 if(hardleft)1105 regfree(&nod);1106 break;1108 bitinc:1109 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {1110 bitload(l, &nod, &nod1, &nod2, Z);1111 gmove(&nod, nn);1112 gopcode(OADD, tfield, nodconst(v), &nod);1113 bitstore(l, &nod, &nod1, &nod2, Z);1114 break;1115 }1116 bitload(l, &nod, &nod1, &nod2, nn);1117 gopcode(OADD, tfield, nodconst(v), &nod);1118 bitstore(l, &nod, &nod1, &nod2, nn);1119 break;1120 }1121 done:1122 cursafe = curs;1123 }1125 void1126 reglcgen(Node *t, Node *n, Node *nn)1127 {1128 Node *r;1129 long v;1131 regialloc(t, n, nn);1132 if(n->op == OIND) {1133 r = n->left;1134 while(r->op == OADD)1135 r = r->right;1136 if(sconst(r)) {1137 v = r->vconst;1138 r->vconst = 0;1139 lcgen(n, t);1140 t->xoffset += v;1141 r->vconst = v;1142 regind(t, n);1143 return;1144 }1145 }1146 lcgen(n, t);1147 regind(t, n);1148 }1150 void1151 lcgen(Node *n, Node *nn)1152 {1153 Prog *p1;1154 Node nod;1156 if(debug['g']) {1157 prtree(nn, "lcgen lhs");1158 prtree(n, "lcgen");1159 }1160 if(n == Z || n->type == T)1161 return;1162 if(nn == Z) {1163 nn = &nod;1164 regalloc(&nod, n, Z);1165 }1166 switch(n->op) {1167 default:1168 if(n->addable < INDEXED) {1169 diag(n, "unknown op in lcgen: %O", n->op);1170 break;1171 }1172 gopcode(OADDR, n->type, n, nn);1173 break;1175 case OCOMMA:1176 cgen(n->left, n->left);1177 lcgen(n->right, nn);1178 break;1180 case OIND:1181 cgen(n->left, nn);1182 break;1184 case OCOND:1185 bcgen(n->left, 1);1186 p1 = p;1187 lcgen(n->right->left, nn);1188 gbranch(OGOTO);1189 patch(p1, pc);1190 p1 = p;1191 lcgen(n->right->right, nn);1192 patch(p1, pc);1193 break;1194 }1195 }1197 void1198 bcgen(Node *n, int true)1199 {1201 if(n->type == T)1202 gbranch(OGOTO);1203 else1204 boolgen(n, true, Z);1205 }1207 void1208 boolgen(Node *n, int true, Node *nn)1209 {1210 int o;1211 Prog *p1, *p2;1212 Node *l, *r, nod, nod1;1213 long curs;1215 if(debug['g']) {1216 prtree(nn, "boolgen lhs");1217 prtree(n, "boolgen");1218 }1219 curs = cursafe;1220 l = n->left;1221 r = n->right;1222 switch(n->op) {1224 default:1225 o = ONE;1226 if(true)1227 o = OEQ;1228 /* bad, 13 is address of external that becomes constant */1229 if(n->addable >= INDEXED && n->addable != 13) {1230 if(typefd[n->type->etype]) {1231 regalloc(&nod1, n, Z);1232 gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */1233 gopcode(o, n->type, n, &nod1);1234 regfree(&nod1);1235 } else1236 gopcode(o, n->type, n, nodconst(0));1237 goto com;1238 }1239 regalloc(&nod, n, nn);1240 cgen(n, &nod);1241 if(typefd[n->type->etype]) {1242 regalloc(&nod1, n, Z);1243 gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */1244 gopcode(o, n->type, &nod, &nod1);1245 regfree(&nod1);1246 } else1247 gopcode(o, n->type, &nod, nodconst(0));1248 regfree(&nod);1249 goto com;1251 case OCONST:1252 o = vconst(n);1253 if(!true)1254 o = !o;1255 gbranch(OGOTO);1256 if(o) {1257 p1 = p;1258 gbranch(OGOTO);1259 patch(p1, pc);1260 }1261 goto com;1263 case OCOMMA:1264 cgen(l, Z);1265 boolgen(r, true, nn);1266 break;1268 case ONOT:1269 boolgen(l, !true, nn);1270 break;1272 case OCOND:1273 bcgen(l, 1);1274 p1 = p;1275 bcgen(r->left, true);1276 p2 = p;1277 gbranch(OGOTO);1278 patch(p1, pc);1279 p1 = p;1280 bcgen(r->right, !true);1281 patch(p2, pc);1282 p2 = p;1283 gbranch(OGOTO);1284 patch(p1, pc);1285 patch(p2, pc);1286 goto com;1288 case OANDAND:1289 if(!true)1290 goto caseor;1292 caseand:1293 bcgen(l, true);1294 p1 = p;1295 bcgen(r, !true);1296 p2 = p;1297 patch(p1, pc);1298 gbranch(OGOTO);1299 patch(p2, pc);1300 goto com;1302 case OOROR:1303 if(!true)1304 goto caseand;1306 caseor:1307 bcgen(l, !true);1308 p1 = p;1309 bcgen(r, !true);1310 p2 = p;1311 gbranch(OGOTO);1312 patch(p1, pc);1313 patch(p2, pc);1314 goto com;1316 case OEQ:1317 case ONE:1318 case OLE:1319 case OLT:1320 case OGE:1321 case OGT:1322 case OHI:1323 case OHS:1324 case OLO:1325 case OLS:1326 o = n->op;1327 if(true)1328 o = comrel[relindex(o)];1329 if(l->complex >= FNX && r->complex >= FNX) {1330 regret(&nod, r);1331 cgen(r, &nod);1332 regsalloc(&nod1, r);1333 gmove(&nod, &nod1);1334 regfree(&nod);1335 nod = *n;1336 nod.right = &nod1;1337 boolgen(&nod, true, nn);1338 break;1339 }1340 if(immconst(l)) {1341 o = invrel[relindex(o)];1342 /* bad, 13 is address of external that becomes constant */1343 if(r->addable < INDEXED || r->addable == 13) {1344 regalloc(&nod, r, nn);1345 cgen(r, &nod);1346 gopcode(o, l->type, &nod, l);1347 regfree(&nod);1348 } else1349 gopcode(o, l->type, r, l);1350 goto com;1351 }1352 if(typefd[l->type->etype])1353 o = invrel[relindex(logrel[relindex(o)])];1354 if(l->complex >= r->complex) {1355 regalloc(&nod, l, nn);1356 cgen(l, &nod);1357 if(r->addable < INDEXED || hardconst(r) || typefd[l->type->etype]) {1358 regalloc(&nod1, r, Z);1359 cgen(r, &nod1);1360 gopcode(o, l->type, &nod, &nod1);1361 regfree(&nod1);1362 } else1363 gopcode(o, l->type, &nod, r);1364 regfree(&nod);1365 goto com;1366 }1367 regalloc(&nod, r, nn);1368 cgen(r, &nod);1369 if(l->addable < INDEXED || l->addable == 13 || hardconst(l)) {1370 regalloc(&nod1, l, Z);1371 cgen(l, &nod1);1372 if(typechl[l->type->etype] && ewidth[l->type->etype] <= ewidth[TINT])1373 gopcode(o, types[TINT], &nod1, &nod);1374 else1375 gopcode(o, l->type, &nod1, &nod);1376 regfree(&nod1);1377 } else1378 gopcode(o, l->type, l, &nod);1379 regfree(&nod);1381 com:1382 if(nn != Z) {1383 p1 = p;1384 gmove(nodconst(1L), nn);1385 gbranch(OGOTO);1386 p2 = p;1387 patch(p1, pc);1388 gmove(nodconst(0L), nn);1389 patch(p2, pc);1390 }1391 break;1392 }1393 cursafe = curs;1394 }1396 void1397 sugen(Node *n, Node *nn, long w)1398 {1399 Prog *p1;1400 Node nod0, nod1, nod2, nod3, nod4, *l, *r;1401 Type *t;1402 int v, c, mt, mo;1403 vlong o0, o1;1405 if(n == Z || n->type == T)1406 return;1407 if(debug['g']) {1408 prtree(nn, "sugen lhs");1409 prtree(n, "sugen");1410 }1411 if(nn == nodrat)1412 if(w > nrathole)1413 nrathole = w;1414 switch(n->op) {1415 case OIND:1416 if(nn == Z) {1417 nullwarn(n->left, Z);1418 break;1419 }1421 default:1422 goto copy;1424 case OCONST:1425 goto copy;1427 case ODOT:1428 l = n->left;1429 sugen(l, nodrat, l->type->width);1430 if(nn == Z)1431 break;1432 warn(n, "non-interruptable temporary");1433 nod1 = *nodrat;1434 r = n->right;1435 if(!r || r->op != OCONST) {1436 diag(n, "DOT and no offset");1437 break;1438 }1439 nod1.xoffset += (long)r->vconst;1440 nod1.type = n->type;1441 sugen(&nod1, nn, w);1442 break;1444 case OSTRUCT:1445 /*1446 * rewrite so lhs has no fn call1447 */1448 if(nn != Z && side(nn)) {1449 nod1 = *n;1450 nod1.type = typ(TIND, n->type);1451 regret(&nod2, &nod1);1452 lcgen(nn, &nod2);1453 regsalloc(&nod0, &nod1);1454 cgen(&nod2, &nod0);1455 regfree(&nod2);1457 nod1 = *n;1458 nod1.op = OIND;1459 nod1.left = &nod0;1460 nod1.right = Z;1461 nod1.complex = 1;1463 sugen(n, &nod1, w);1464 return;1465 }1467 r = n->left;1468 for(t = n->type->link; t != T; t = t->down) {1469 l = r;1470 if(r->op == OLIST) {1471 l = r->left;1472 r = r->right;1473 }1474 if(nn == Z) {1475 cgen(l, nn);1476 continue;1477 }1478 /*1479 * hand craft *(&nn + o) = l1480 */1481 nod0 = znode;1482 nod0.op = OAS;1483 nod0.type = t;1484 nod0.left = &nod1;1485 nod0.right = nil;1487 nod1 = znode;1488 nod1.op = OIND;1489 nod1.type = t;1490 nod1.left = &nod2;1492 nod2 = znode;1493 nod2.op = OADD;1494 nod2.type = typ(TIND, t);1495 nod2.left = &nod3;1496 nod2.right = &nod4;1498 nod3 = znode;1499 nod3.op = OADDR;1500 nod3.type = nod2.type;1501 nod3.left = nn;1503 nod4 = znode;1504 nod4.op = OCONST;1505 nod4.type = nod2.type;1506 nod4.vconst = t->offset;1508 ccom(&nod0);1509 acom(&nod0);1510 xcom(&nod0);1511 nod0.addable = 0;1512 nod0.right = l;1514 /* prtree(&nod0, "hand craft"); /* */1515 cgen(&nod0, Z);1516 }1517 break;1519 case OAS:1520 if(nn == Z) {1521 if(n->addable < INDEXED)1522 sugen(n->right, n->left, w);1523 break;1524 }1526 sugen(n->right, nodrat, w);1527 warn(n, "non-interruptable temporary");1528 sugen(nodrat, n->left, w);1529 sugen(nodrat, nn, w);1530 break;1532 case OFUNC:1533 if(nn == Z) {1534 sugen(n, nodrat, w);1535 break;1536 }1537 if(nn->op != OIND) {1538 nn = new1(OADDR, nn, Z);1539 nn->type = types[TIND];1540 nn->addable = 0;1541 } else1542 nn = nn->left;1543 n = new(OFUNC, n->left, new(OLIST, nn, n->right));1544 n->complex = FNX;1545 n->type = types[TVOID];1546 n->left->type = types[TVOID];1547 cgen(n, Z);1548 break;1550 case OCOND:1551 bcgen(n->left, 1);1552 p1 = p;1553 sugen(n->right->left, nn, w);1554 gbranch(OGOTO);1555 patch(p1, pc);1556 p1 = p;1557 sugen(n->right->right, nn, w);1558 patch(p1, pc);1559 break;1561 case OCOMMA:1562 cgen(n->left, Z);1563 sugen(n->right, nn, w);1564 break;1565 }1566 return;1568 copy:1569 if(nn == Z) {1570 switch(n->op) {1571 case OASADD:1572 case OASSUB:1573 case OASAND:1574 case OASOR:1575 case OASXOR:1577 case OASMUL:1578 case OASLMUL:1581 case OASASHL:1582 case OASASHR:1583 case OASLSHR:1584 break;1586 case OPOSTINC:1587 case OPOSTDEC:1588 case OPREINC:1589 case OPREDEC:1590 break;1592 default:1593 return;1594 }1595 }1597 if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {1598 t = nn->type;1599 nn->type = types[TLONG];1600 regialloc(&nod1, nn, Z);1601 lcgen(nn, &nod1);1602 regsalloc(&nod2, &nod1);1603 nn->type = t;1605 gins(AMOVQ, &nod1, &nod2);1606 regfree(&nod1);1608 nod2.type = typ(TIND, t);1610 nod1 = nod2;1611 nod1.op = OIND;1612 nod1.left = &nod2;1613 nod1.right = Z;1614 nod1.complex = 1;1615 nod1.type = t;1617 sugen(n, &nod1, w);1618 return;1619 }1621 c = cursafe;1622 if(w <= 32) {1623 if(n->left != Z && n->left->complex >= FNX1624 && n->right != Z && n->right->complex >= FNX) {1625 regsalloc(&nod1, n->right);1626 cgen(n->right, &nod1);1627 nod2 = *n;1628 nod2.right = &nod1;1629 cgen(&nod2, nn);1630 cursafe = c;1631 return;1632 }1633 if(w & 7) {1634 mt = TLONG;1635 mo = AMOVL;1636 } else {1637 mt = TVLONG;1638 mo = AMOVQ;1639 }1640 if(n->complex > nn->complex) {1641 t = n->type;1642 n->type = types[mt];1643 regalloc(&nod0, n, Z);1644 if(!vaddr(n, 0)) {1645 reglcgen(&nod1, n, Z);1646 n->type = t;1647 n = &nod1;1648 }1649 else1650 n->type = t;1652 t = nn->type;1653 nn->type = types[mt];1654 if(!vaddr(nn, 0)) {1655 reglcgen(&nod2, nn, Z);1656 nn->type = t;1657 nn = &nod2;1658 }1659 else1660 nn->type = t;1661 } else {1662 t = nn->type;1663 nn->type = types[mt];1664 regalloc(&nod0, nn, Z);1665 if(!vaddr(nn, 0)) {1666 reglcgen(&nod2, nn, Z);1667 nn->type = t;1668 nn = &nod2;1669 }1670 else1671 nn->type = t;1673 t = n->type;1674 n->type = types[mt];1675 if(!vaddr(n, 0)) {1676 reglcgen(&nod1, n, Z);1677 n->type = t;1678 n = &nod1;1679 }1680 else1681 n->type = t;1682 }1683 o0 = n->xoffset;1684 o1 = nn->xoffset;1685 w /= ewidth[mt];1686 while(--w >= 0) {1687 gins(mo, n, &nod0);1688 gins(mo, &nod0, nn);1689 n->xoffset += ewidth[mt];1690 nn->xoffset += ewidth[mt];1691 }1692 n->xoffset = o0;1693 nn->xoffset = o1;1694 if(nn == &nod2)1695 regfree(&nod2);1696 if(n == &nod1)1697 regfree(&nod1);1698 regfree(&nod0);1699 return;1700 }1702 t = n->type;1703 if(t != types[TIND]){1704 n->type = types[TIND];1705 sugen(n, nn, w);1706 n->type = t;1707 return;1708 }1709 t = nn->type;1710 if(t != types[TIND]){1711 nn->type = types[TIND];1712 sugen(n, nn, w);1713 nn->type = t;1714 return;1715 }1717 if(nodreg(&nod1, n, D_SI)) {1718 regsalloc(&nod4, &nod1);1719 gmove(&nod1, &nod4);1720 v = reg[D_SI];1721 reg[D_SI] = 0;1722 sugen(n, nn, w);1723 reg[D_SI] = v;1724 gmove(&nod4, &nod1);1725 cursafe = c;1726 return;1727 }1728 if(nodreg(&nod2, nn, D_DI)) {1729 regsalloc(&nod4, &nod2);1730 gmove(&nod2, &nod4);1731 v = reg[D_DI];1732 reg[D_DI] = 0;1733 sugen(n, nn, w);1734 reg[D_DI] = v;1735 gmove(&nod4, &nod2);1736 cursafe = c;1737 return;1738 }1739 if(nodreg(&nod3, Z, D_CX)) {1740 regsalloc(&nod4, &nod3);1741 gmove(&nod3, &nod4);1742 v = reg[D_CX];1743 reg[D_CX] = 0;1744 sugen(n, nn, w);1745 reg[D_CX] = v;1746 gmove(&nod4, &nod3);1747 cursafe = c;1748 return;1749 }1751 if(n->complex > nn->complex){1752 reg[nod1.reg]++;1753 lcgen(n, &nod1);1755 reg[nod2.reg]++;1756 lcgen(nn, &nod2);1757 } else {1758 reg[nod2.reg]++;1759 lcgen(nn, &nod2);1761 reg[nod1.reg]++;1762 lcgen(n, &nod1);1763 }1764 reg[nod3.reg]++;1766 gins(AMOVL, nodconst(w/SZ_LONG), &nod3);1767 gins(ACLD, Z, Z);1768 gins(AREP, Z, Z);1769 gins(AMOVSL, Z, Z);1770 if(w & (SZ_LONG-1)) {1771 /* odd length of packed structure */1772 gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3);1773 gins(AREP, Z, Z);1774 gins(AMOVSB, Z, Z);1775 }1777 reg[nod3.reg]--;1778 reg[nod2.reg]--;1779 reg[nod1.reg]--;1780 }1782 /*1783 * TO DO1784 */1785 void1786 layout(Node *f, Node *t, int c, int cv, Node *cn)1787 {1788 Node t1, t2;1790 while(c > 3) {1791 layout(f, t, 2, 0, Z);1792 c -= 2;1793 }1795 regalloc(&t1, &lregnode, Z);1796 regalloc(&t2, &lregnode, Z);1797 if(c > 0) {1798 gmove(f, &t1);1799 f->xoffset += SZ_INT;1800 }1801 if(cn != Z)1802 gmove(nodconst(cv), cn);1803 if(c > 1) {1804 gmove(f, &t2);1805 f->xoffset += SZ_INT;1806 }1807 if(c > 0) {1808 gmove(&t1, t);1809 t->xoffset += SZ_INT;1810 }1811 if(c > 2) {1812 gmove(f, &t1);1813 f->xoffset += SZ_INT;1814 }1815 if(c > 1) {1816 gmove(&t2, t);1817 t->xoffset += SZ_INT;1818 }1819 if(c > 2) {1820 gmove(&t1, t);1821 t->xoffset += SZ_INT;1822 }1823 regfree(&t1);1824 regfree(&t2);1825 }1827 /*1828 * constant is not vlong or fits as 32-bit signed immediate1829 */1830 int1831 immconst(Node *n)1832 {1833 long v;1835 if(n->op != OCONST || !typechlpv[n->type->etype])1836 return 0;1837 if(typechl[n->type->etype])1838 return 1;1839 v = n->vconst;1840 return n->vconst == (vlong)v;1841 }1843 /*1844 * if a constant and vlong, doesn't fit as 32-bit signed immediate1845 */1846 int1847 hardconst(Node *n)1848 {1849 return n->op == OCONST && !immconst(n);1850 }1852 /*1853 * casting up to t2 covers an intermediate cast to t11854 */1855 int1856 castup(Type *t1, Type *t2)1857 {1858 int ft;1860 if(!nilcast(t1, t2))1861 return 0;1862 /* known to be small to large */1863 ft = t1->etype;1864 switch(t2->etype){1865 case TINT:1866 case TLONG:1867 return ft == TLONG || ft == TINT || ft == TSHORT || ft == TCHAR;1868 case TUINT:1869 case TULONG:1870 return ft == TULONG || ft == TUINT || ft == TUSHORT || ft == TUCHAR;1871 case TVLONG:1872 return ft == TLONG || ft == TINT || ft == TSHORT;1873 case TUVLONG:1874 return ft == TULONG || ft == TUINT || ft == TUSHORT;1875 }1876 return 0;1877 }1879 void1880 zeroregm(Node *n)1881 {1882 gins(AMOVL, nodconst(0), n);1883 }1885 /* do we need to load the address of a vlong? */1886 int1887 vaddr(Node *n, int a)1888 {1889 switch(n->op) {1890 case ONAME:1891 if(a)1892 return 1;1893 return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);1895 case OCONST:1896 case OREGISTER:1897 case OINDREG:1898 return 1;1899 }1900 return 0;1901 }1903 long1904 hi64v(Node *n)1905 {1906 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */1907 return (long)(n->vconst) & ~0L;1908 else1909 return (long)((uvlong)n->vconst>>32) & ~0L;1910 }1912 long1913 lo64v(Node *n)1914 {1915 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */1916 return (long)((uvlong)n->vconst>>32) & ~0L;1917 else1918 return (long)(n->vconst) & ~0L;1919 }1921 Node *1922 hi64(Node *n)1923 {1924 return nodconst(hi64v(n));1925 }1927 Node *1928 lo64(Node *n)1929 {1930 return nodconst(lo64v(n));1931 }1933 int1934 cond(int op)1935 {1936 switch(op) {1937 case OANDAND:1938 case OOROR:1939 case ONOT:1940 return 1;1942 case OEQ:1943 case ONE:1944 case OLE:1945 case OLT:1946 case OGE:1947 case OGT:1948 case OHI:1949 case OHS:1950 case OLO:1951 case OLS:1952 return 1;1953 }1954 return 0;1955 }