17dd7cddfSDavid du Colombier #include "gc.h"
27dd7cddfSDavid du Colombier
37dd7cddfSDavid du Colombier void
cgen(Node * n,Node * nn)44ac975e2SDavid du Colombier cgen(Node *n, Node *nn)
54ac975e2SDavid du Colombier {
64ac975e2SDavid du Colombier cgenrel(n, nn, 0);
74ac975e2SDavid du Colombier }
84ac975e2SDavid du Colombier
94ac975e2SDavid du Colombier void
cgenrel(Node * n,Node * nn,int inrel)104ac975e2SDavid du Colombier cgenrel(Node *n, Node *nn, int inrel)
117dd7cddfSDavid du Colombier {
127dd7cddfSDavid du Colombier Node *l, *r;
137dd7cddfSDavid du Colombier Prog *p1;
147dd7cddfSDavid du Colombier Node nod, nod1, nod2, nod3, nod4;
1559cc4ca5SDavid du Colombier int o, t;
167dd7cddfSDavid du Colombier long v, curs;
177dd7cddfSDavid du Colombier
187dd7cddfSDavid du Colombier if(debug['g']) {
197dd7cddfSDavid du Colombier prtree(nn, "cgen lhs");
207dd7cddfSDavid du Colombier prtree(n, "cgen");
217dd7cddfSDavid du Colombier }
227dd7cddfSDavid du Colombier if(n == Z || n->type == T)
237dd7cddfSDavid du Colombier return;
247dd7cddfSDavid du Colombier if(typesuv[n->type->etype]) {
257dd7cddfSDavid du Colombier sugen(n, nn, n->type->width);
267dd7cddfSDavid du Colombier return;
277dd7cddfSDavid du Colombier }
287dd7cddfSDavid du Colombier l = n->left;
297dd7cddfSDavid du Colombier r = n->right;
307dd7cddfSDavid du Colombier o = n->op;
317dd7cddfSDavid du Colombier if(n->addable >= INDEXED) {
327dd7cddfSDavid du Colombier if(nn == Z) {
337dd7cddfSDavid du Colombier switch(o) {
347dd7cddfSDavid du Colombier default:
357dd7cddfSDavid du Colombier nullwarn(Z, Z);
367dd7cddfSDavid du Colombier break;
377dd7cddfSDavid du Colombier case OINDEX:
387dd7cddfSDavid du Colombier nullwarn(l, r);
397dd7cddfSDavid du Colombier break;
407dd7cddfSDavid du Colombier }
417dd7cddfSDavid du Colombier return;
427dd7cddfSDavid du Colombier }
437dd7cddfSDavid du Colombier gmove(n, nn);
447dd7cddfSDavid du Colombier return;
457dd7cddfSDavid du Colombier }
467dd7cddfSDavid du Colombier curs = cursafe;
477dd7cddfSDavid du Colombier
487dd7cddfSDavid du Colombier if(n->complex >= FNX)
497dd7cddfSDavid du Colombier if(l->complex >= FNX)
507dd7cddfSDavid du Colombier if(r != Z && r->complex >= FNX)
517dd7cddfSDavid du Colombier switch(o) {
527dd7cddfSDavid du Colombier default:
537dd7cddfSDavid du Colombier regret(&nod, r);
544ac975e2SDavid du Colombier cgen(r, &nod);
557dd7cddfSDavid du Colombier
567dd7cddfSDavid du Colombier regsalloc(&nod1, r);
577dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, &nod1);
587dd7cddfSDavid du Colombier
597dd7cddfSDavid du Colombier regfree(&nod);
607dd7cddfSDavid du Colombier nod = *n;
617dd7cddfSDavid du Colombier nod.right = &nod1;
624ac975e2SDavid du Colombier cgen(&nod, nn);
637dd7cddfSDavid du Colombier return;
647dd7cddfSDavid du Colombier
657dd7cddfSDavid du Colombier case OFUNC:
667dd7cddfSDavid du Colombier case OCOMMA:
677dd7cddfSDavid du Colombier case OANDAND:
687dd7cddfSDavid du Colombier case OOROR:
697dd7cddfSDavid du Colombier case OCOND:
707dd7cddfSDavid du Colombier case ODOT:
717dd7cddfSDavid du Colombier break;
727dd7cddfSDavid du Colombier }
737dd7cddfSDavid du Colombier
747dd7cddfSDavid du Colombier switch(o) {
757dd7cddfSDavid du Colombier default:
767dd7cddfSDavid du Colombier diag(n, "unknown op in cgen: %O", o);
777dd7cddfSDavid du Colombier break;
787dd7cddfSDavid du Colombier
797dd7cddfSDavid du Colombier case OAS:
807dd7cddfSDavid du Colombier if(l->op == OBIT)
817dd7cddfSDavid du Colombier goto bitas;
827dd7cddfSDavid du Colombier if(l->addable >= INDEXED && l->complex < FNX) {
837dd7cddfSDavid du Colombier if(nn != Z || r->addable < INDEXED) {
847dd7cddfSDavid du Colombier if(r->complex >= FNX && nn == Z)
857dd7cddfSDavid du Colombier regret(&nod, r);
867dd7cddfSDavid du Colombier else
877dd7cddfSDavid du Colombier regalloc(&nod, r, nn);
884ac975e2SDavid du Colombier cgen(r, &nod);
897dd7cddfSDavid du Colombier gmove(&nod, l);
907dd7cddfSDavid du Colombier if(nn != Z)
917dd7cddfSDavid du Colombier gmove(&nod, nn);
927dd7cddfSDavid du Colombier regfree(&nod);
937dd7cddfSDavid du Colombier } else
947dd7cddfSDavid du Colombier gmove(r, l);
957dd7cddfSDavid du Colombier break;
967dd7cddfSDavid du Colombier }
977dd7cddfSDavid du Colombier if(l->complex >= r->complex) {
987dd7cddfSDavid du Colombier reglcgen(&nod1, l, Z);
997dd7cddfSDavid du Colombier if(r->addable >= INDEXED) {
1007dd7cddfSDavid du Colombier gmove(r, &nod1);
1017dd7cddfSDavid du Colombier if(nn != Z)
1027dd7cddfSDavid du Colombier gmove(r, nn);
1037dd7cddfSDavid du Colombier regfree(&nod1);
1047dd7cddfSDavid du Colombier break;
1057dd7cddfSDavid du Colombier }
1067dd7cddfSDavid du Colombier regalloc(&nod, r, nn);
1074ac975e2SDavid du Colombier cgen(r, &nod);
1087dd7cddfSDavid du Colombier } else {
1097dd7cddfSDavid du Colombier regalloc(&nod, r, nn);
1104ac975e2SDavid du Colombier cgen(r, &nod);
1117dd7cddfSDavid du Colombier reglcgen(&nod1, l, Z);
1127dd7cddfSDavid du Colombier }
1137dd7cddfSDavid du Colombier gmove(&nod, &nod1);
1147dd7cddfSDavid du Colombier regfree(&nod);
1157dd7cddfSDavid du Colombier regfree(&nod1);
1167dd7cddfSDavid du Colombier break;
1177dd7cddfSDavid du Colombier
1187dd7cddfSDavid du Colombier bitas:
1197dd7cddfSDavid du Colombier n = l->left;
1207dd7cddfSDavid du Colombier regalloc(&nod, r, nn);
1217dd7cddfSDavid du Colombier if(l->complex >= r->complex) {
1227dd7cddfSDavid du Colombier reglcgen(&nod1, n, Z);
1234ac975e2SDavid du Colombier cgen(r, &nod);
1247dd7cddfSDavid du Colombier } else {
1254ac975e2SDavid du Colombier cgen(r, &nod);
1267dd7cddfSDavid du Colombier reglcgen(&nod1, n, Z);
1277dd7cddfSDavid du Colombier }
1287dd7cddfSDavid du Colombier regalloc(&nod2, n, Z);
1297dd7cddfSDavid du Colombier gopcode(OAS, &nod1, Z, &nod2);
1307dd7cddfSDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
1317dd7cddfSDavid du Colombier break;
1327dd7cddfSDavid du Colombier
1337dd7cddfSDavid du Colombier case OBIT:
1347dd7cddfSDavid du Colombier if(nn == Z) {
1357dd7cddfSDavid du Colombier nullwarn(l, Z);
1367dd7cddfSDavid du Colombier break;
1377dd7cddfSDavid du Colombier }
1387dd7cddfSDavid du Colombier bitload(n, &nod, Z, Z, nn);
1397dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, nn);
1407dd7cddfSDavid du Colombier regfree(&nod);
1417dd7cddfSDavid du Colombier break;
1427dd7cddfSDavid du Colombier
14359cc4ca5SDavid du Colombier case ODIV:
14459cc4ca5SDavid du Colombier case OMOD:
14559cc4ca5SDavid du Colombier if(nn != Z)
14659cc4ca5SDavid du Colombier if((t = vlog(r)) >= 0) {
14759cc4ca5SDavid du Colombier /* signed div/mod by constant power of 2 */
1484ac975e2SDavid du Colombier cgen(l, nn);
14959cc4ca5SDavid du Colombier gopcode(OGE, nodconst(0), nn, Z);
15059cc4ca5SDavid du Colombier p1 = p;
15159cc4ca5SDavid du Colombier if(o == ODIV) {
15259cc4ca5SDavid du Colombier gopcode(OADD, nodconst((1<<t)-1), Z, nn);
15359cc4ca5SDavid du Colombier patch(p1, pc);
15459cc4ca5SDavid du Colombier gopcode(OASHR, nodconst(t), Z, nn);
15559cc4ca5SDavid du Colombier } else {
15659cc4ca5SDavid du Colombier gopcode(OSUB, nn, nodconst(0), nn);
15759cc4ca5SDavid du Colombier gopcode(OAND, nodconst((1<<t)-1), Z, nn);
15859cc4ca5SDavid du Colombier gopcode(OSUB, nn, nodconst(0), nn);
15959cc4ca5SDavid du Colombier gbranch(OGOTO);
16059cc4ca5SDavid du Colombier patch(p1, pc);
16159cc4ca5SDavid du Colombier p1 = p;
16259cc4ca5SDavid du Colombier gopcode(OAND, nodconst((1<<t)-1), Z, nn);
16359cc4ca5SDavid du Colombier patch(p1, pc);
16459cc4ca5SDavid du Colombier }
16559cc4ca5SDavid du Colombier break;
16659cc4ca5SDavid du Colombier }
16759cc4ca5SDavid du Colombier goto muldiv;
16859cc4ca5SDavid du Colombier
1697dd7cddfSDavid du Colombier case OSUB:
17059cc4ca5SDavid du Colombier if(nn != Z)
17159cc4ca5SDavid du Colombier if(l->op == OCONST)
17259cc4ca5SDavid du Colombier if(!typefd[n->type->etype]) {
1734ac975e2SDavid du Colombier cgen(r, nn);
17459cc4ca5SDavid du Colombier gopcode(o, Z, l, nn);
17559cc4ca5SDavid du Colombier break;
17659cc4ca5SDavid du Colombier }
17759cc4ca5SDavid du Colombier case OADD:
1787dd7cddfSDavid du Colombier case OAND:
1797dd7cddfSDavid du Colombier case OOR:
1807dd7cddfSDavid du Colombier case OXOR:
1817dd7cddfSDavid du Colombier case OLSHR:
1827dd7cddfSDavid du Colombier case OASHL:
1837dd7cddfSDavid du Colombier case OASHR:
1847dd7cddfSDavid du Colombier /*
1857dd7cddfSDavid du Colombier * immediate operands
1867dd7cddfSDavid du Colombier */
1877dd7cddfSDavid du Colombier if(nn != Z)
1887dd7cddfSDavid du Colombier if(r->op == OCONST)
1897dd7cddfSDavid du Colombier if(!typefd[n->type->etype]) {
1904ac975e2SDavid du Colombier cgen(l, nn);
1917dd7cddfSDavid du Colombier if(r->vconst == 0)
1927dd7cddfSDavid du Colombier if(o != OAND)
1937dd7cddfSDavid du Colombier break;
1947dd7cddfSDavid du Colombier if(nn != Z)
1957dd7cddfSDavid du Colombier gopcode(o, r, Z, nn);
1967dd7cddfSDavid du Colombier break;
1977dd7cddfSDavid du Colombier }
1987dd7cddfSDavid du Colombier
1997dd7cddfSDavid du Colombier case OLMUL:
2007dd7cddfSDavid du Colombier case OLDIV:
2017dd7cddfSDavid du Colombier case OLMOD:
2027dd7cddfSDavid du Colombier case OMUL:
20359cc4ca5SDavid du Colombier muldiv:
2047dd7cddfSDavid du Colombier if(nn == Z) {
2057dd7cddfSDavid du Colombier nullwarn(l, r);
2067dd7cddfSDavid du Colombier break;
2077dd7cddfSDavid du Colombier }
2087dd7cddfSDavid du Colombier if(o == OMUL || o == OLMUL) {
2097dd7cddfSDavid du Colombier if(mulcon(n, nn))
2107dd7cddfSDavid du Colombier break;
2117dd7cddfSDavid du Colombier }
2127dd7cddfSDavid du Colombier if(l->complex >= r->complex) {
2137dd7cddfSDavid du Colombier regalloc(&nod, l, nn);
2144ac975e2SDavid du Colombier cgen(l, &nod);
2157dd7cddfSDavid du Colombier regalloc(&nod1, r, Z);
2164ac975e2SDavid du Colombier cgen(r, &nod1);
2177dd7cddfSDavid du Colombier gopcode(o, &nod1, Z, &nod);
2187dd7cddfSDavid du Colombier } else {
2197dd7cddfSDavid du Colombier regalloc(&nod, r, nn);
2204ac975e2SDavid du Colombier cgen(r, &nod);
2217dd7cddfSDavid du Colombier regalloc(&nod1, l, Z);
2224ac975e2SDavid du Colombier cgen(l, &nod1);
2237dd7cddfSDavid du Colombier gopcode(o, &nod, &nod1, &nod);
2247dd7cddfSDavid du Colombier }
2257dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, nn);
2267dd7cddfSDavid du Colombier regfree(&nod);
2277dd7cddfSDavid du Colombier regfree(&nod1);
2287dd7cddfSDavid du Colombier break;
2297dd7cddfSDavid du Colombier
2307dd7cddfSDavid du Colombier case OASLSHR:
2317dd7cddfSDavid du Colombier case OASASHL:
2327dd7cddfSDavid du Colombier case OASASHR:
2337dd7cddfSDavid du Colombier case OASAND:
2347dd7cddfSDavid du Colombier case OASADD:
2357dd7cddfSDavid du Colombier case OASSUB:
2367dd7cddfSDavid du Colombier case OASXOR:
2377dd7cddfSDavid du Colombier case OASOR:
2387dd7cddfSDavid du Colombier if(l->op == OBIT)
2397dd7cddfSDavid du Colombier goto asbitop;
2407dd7cddfSDavid du Colombier if(r->op == OCONST)
241fc375d71SDavid du Colombier if(!typefd[r->type->etype])
2427dd7cddfSDavid du Colombier if(!typefd[n->type->etype]) {
2437dd7cddfSDavid du Colombier if(l->addable < INDEXED)
2447dd7cddfSDavid du Colombier reglcgen(&nod2, l, Z);
2457dd7cddfSDavid du Colombier else
2467dd7cddfSDavid du Colombier nod2 = *l;
2477dd7cddfSDavid du Colombier regalloc(&nod, r, nn);
2487dd7cddfSDavid du Colombier gopcode(OAS, &nod2, Z, &nod);
2497dd7cddfSDavid du Colombier gopcode(o, r, Z, &nod);
2507dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, &nod2);
2517dd7cddfSDavid du Colombier
2527dd7cddfSDavid du Colombier regfree(&nod);
2537dd7cddfSDavid du Colombier if(l->addable < INDEXED)
2547dd7cddfSDavid du Colombier regfree(&nod2);
2557dd7cddfSDavid du Colombier break;
2567dd7cddfSDavid du Colombier }
2577dd7cddfSDavid du Colombier
2587dd7cddfSDavid du Colombier case OASLMUL:
2597dd7cddfSDavid du Colombier case OASLDIV:
2607dd7cddfSDavid du Colombier case OASLMOD:
2617dd7cddfSDavid du Colombier case OASMUL:
2627dd7cddfSDavid du Colombier case OASDIV:
2637dd7cddfSDavid du Colombier case OASMOD:
2647dd7cddfSDavid du Colombier if(l->op == OBIT)
2657dd7cddfSDavid du Colombier goto asbitop;
2667dd7cddfSDavid du Colombier if(l->complex >= r->complex) {
2677dd7cddfSDavid du Colombier if(l->addable < INDEXED)
2687dd7cddfSDavid du Colombier reglcgen(&nod2, l, Z);
2697dd7cddfSDavid du Colombier else
2707dd7cddfSDavid du Colombier nod2 = *l;
2717dd7cddfSDavid du Colombier regalloc(&nod1, r, Z);
2724ac975e2SDavid du Colombier cgen(r, &nod1);
2737dd7cddfSDavid du Colombier } else {
2747dd7cddfSDavid du Colombier regalloc(&nod1, r, Z);
2754ac975e2SDavid du Colombier cgen(r, &nod1);
2767dd7cddfSDavid du Colombier if(l->addable < INDEXED)
2777dd7cddfSDavid du Colombier reglcgen(&nod2, l, Z);
2787dd7cddfSDavid du Colombier else
2797dd7cddfSDavid du Colombier nod2 = *l;
2807dd7cddfSDavid du Colombier }
2817dd7cddfSDavid du Colombier
2827dd7cddfSDavid du Colombier regalloc(&nod, n, nn);
2837dd7cddfSDavid du Colombier gmove(&nod2, &nod);
2847dd7cddfSDavid du Colombier gopcode(o, &nod1, Z, &nod);
2857dd7cddfSDavid du Colombier gmove(&nod, &nod2);
2867dd7cddfSDavid du Colombier if(nn != Z)
2877dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, nn);
2887dd7cddfSDavid du Colombier regfree(&nod);
2897dd7cddfSDavid du Colombier regfree(&nod1);
2907dd7cddfSDavid du Colombier if(l->addable < INDEXED)
2917dd7cddfSDavid du Colombier regfree(&nod2);
2927dd7cddfSDavid du Colombier break;
2937dd7cddfSDavid du Colombier
2947dd7cddfSDavid du Colombier asbitop:
2957dd7cddfSDavid du Colombier regalloc(&nod4, n, nn);
2967dd7cddfSDavid du Colombier if(l->complex >= r->complex) {
2977dd7cddfSDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4);
2987dd7cddfSDavid du Colombier regalloc(&nod3, r, Z);
2994ac975e2SDavid du Colombier cgen(r, &nod3);
3007dd7cddfSDavid du Colombier } else {
3017dd7cddfSDavid du Colombier regalloc(&nod3, r, Z);
3024ac975e2SDavid du Colombier cgen(r, &nod3);
3037dd7cddfSDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4);
3047dd7cddfSDavid du Colombier }
3057dd7cddfSDavid du Colombier gmove(&nod, &nod4);
3067dd7cddfSDavid du Colombier gopcode(o, &nod3, Z, &nod4);
3077dd7cddfSDavid du Colombier regfree(&nod3);
3087dd7cddfSDavid du Colombier gmove(&nod4, &nod);
3097dd7cddfSDavid du Colombier regfree(&nod4);
3107dd7cddfSDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
3117dd7cddfSDavid du Colombier break;
3127dd7cddfSDavid du Colombier
3137dd7cddfSDavid du Colombier case OADDR:
3147dd7cddfSDavid du Colombier if(nn == Z) {
3157dd7cddfSDavid du Colombier nullwarn(l, Z);
3167dd7cddfSDavid du Colombier break;
3177dd7cddfSDavid du Colombier }
3187dd7cddfSDavid du Colombier lcgen(l, nn);
3197dd7cddfSDavid du Colombier break;
3207dd7cddfSDavid du Colombier
3217dd7cddfSDavid du Colombier case OFUNC:
3227dd7cddfSDavid du Colombier if(l->complex >= FNX) {
3237dd7cddfSDavid du Colombier if(l->op != OIND)
3247dd7cddfSDavid du Colombier diag(n, "bad function call");
3257dd7cddfSDavid du Colombier
3267dd7cddfSDavid du Colombier regret(&nod, l->left);
3274ac975e2SDavid du Colombier cgen(l->left, &nod);
3287dd7cddfSDavid du Colombier regsalloc(&nod1, l->left);
3297dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, &nod1);
3307dd7cddfSDavid du Colombier regfree(&nod);
3317dd7cddfSDavid du Colombier
3327dd7cddfSDavid du Colombier nod = *n;
3337dd7cddfSDavid du Colombier nod.left = &nod2;
3347dd7cddfSDavid du Colombier nod2 = *l;
3357dd7cddfSDavid du Colombier nod2.left = &nod1;
3367dd7cddfSDavid du Colombier nod2.complex = 1;
3374ac975e2SDavid du Colombier cgen(&nod, nn);
3387dd7cddfSDavid du Colombier
3397dd7cddfSDavid du Colombier return;
3407dd7cddfSDavid du Colombier }
3417dd7cddfSDavid du Colombier if(REGARG >= 0)
3427dd7cddfSDavid du Colombier o = reg[REGARG];
3437dd7cddfSDavid du Colombier gargs(r, &nod, &nod1);
3447dd7cddfSDavid du Colombier if(l->addable < INDEXED) {
3457dd7cddfSDavid du Colombier reglcgen(&nod, l, Z);
3467dd7cddfSDavid du Colombier gopcode(OFUNC, Z, Z, &nod);
3477dd7cddfSDavid du Colombier regfree(&nod);
3487dd7cddfSDavid du Colombier } else
3497dd7cddfSDavid du Colombier gopcode(OFUNC, Z, Z, l);
3507dd7cddfSDavid du Colombier if(REGARG >= 0)
3517dd7cddfSDavid du Colombier if(o != reg[REGARG])
3527dd7cddfSDavid du Colombier reg[REGARG]--;
3537dd7cddfSDavid du Colombier if(nn != Z) {
3547dd7cddfSDavid du Colombier regret(&nod, n);
3557dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, nn);
3567dd7cddfSDavid du Colombier regfree(&nod);
3577dd7cddfSDavid du Colombier }
3587dd7cddfSDavid du Colombier break;
3597dd7cddfSDavid du Colombier
3607dd7cddfSDavid du Colombier case OIND:
3617dd7cddfSDavid du Colombier if(nn == Z) {
3627dd7cddfSDavid du Colombier nullwarn(l, Z);
3637dd7cddfSDavid du Colombier break;
3647dd7cddfSDavid du Colombier }
3657dd7cddfSDavid du Colombier regialloc(&nod, n, nn);
3667dd7cddfSDavid du Colombier r = l;
3677dd7cddfSDavid du Colombier while(r->op == OADD)
3687dd7cddfSDavid du Colombier r = r->right;
36959cc4ca5SDavid du Colombier if(sconst(r) && (v = r->vconst+nod.xoffset) > -4096 && v < 4096) {
3707dd7cddfSDavid du Colombier v = r->vconst;
3717dd7cddfSDavid du Colombier r->vconst = 0;
3724ac975e2SDavid du Colombier cgen(l, &nod);
3737dd7cddfSDavid du Colombier nod.xoffset += v;
3747dd7cddfSDavid du Colombier r->vconst = v;
3757dd7cddfSDavid du Colombier } else
3764ac975e2SDavid du Colombier cgen(l, &nod);
3777dd7cddfSDavid du Colombier regind(&nod, n);
3787dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, nn);
3797dd7cddfSDavid du Colombier regfree(&nod);
3807dd7cddfSDavid du Colombier break;
3817dd7cddfSDavid du Colombier
3827dd7cddfSDavid du Colombier case OEQ:
3837dd7cddfSDavid du Colombier case ONE:
3847dd7cddfSDavid du Colombier case OLE:
3857dd7cddfSDavid du Colombier case OLT:
3867dd7cddfSDavid du Colombier case OGE:
3877dd7cddfSDavid du Colombier case OGT:
3887dd7cddfSDavid du Colombier case OLO:
3897dd7cddfSDavid du Colombier case OLS:
3907dd7cddfSDavid du Colombier case OHI:
3917dd7cddfSDavid du Colombier case OHS:
3927dd7cddfSDavid du Colombier if(nn == Z) {
3937dd7cddfSDavid du Colombier nullwarn(l, r);
3947dd7cddfSDavid du Colombier break;
3957dd7cddfSDavid du Colombier }
3967dd7cddfSDavid du Colombier boolgen(n, 1, nn);
3977dd7cddfSDavid du Colombier break;
3987dd7cddfSDavid du Colombier
3997dd7cddfSDavid du Colombier case OANDAND:
4007dd7cddfSDavid du Colombier case OOROR:
4017dd7cddfSDavid du Colombier boolgen(n, 1, nn);
4027dd7cddfSDavid du Colombier if(nn == Z)
4037dd7cddfSDavid du Colombier patch(p, pc);
4047dd7cddfSDavid du Colombier break;
4057dd7cddfSDavid du Colombier
4067dd7cddfSDavid du Colombier case ONOT:
4077dd7cddfSDavid du Colombier if(nn == Z) {
4087dd7cddfSDavid du Colombier nullwarn(l, Z);
4097dd7cddfSDavid du Colombier break;
4107dd7cddfSDavid du Colombier }
4117dd7cddfSDavid du Colombier boolgen(n, 1, nn);
4127dd7cddfSDavid du Colombier break;
4137dd7cddfSDavid du Colombier
4147dd7cddfSDavid du Colombier case OCOMMA:
4154ac975e2SDavid du Colombier cgen(l, Z);
4164ac975e2SDavid du Colombier cgen(r, nn);
4177dd7cddfSDavid du Colombier break;
4187dd7cddfSDavid du Colombier
4197dd7cddfSDavid du Colombier case OCAST:
4207dd7cddfSDavid du Colombier if(nn == Z) {
4217dd7cddfSDavid du Colombier nullwarn(l, Z);
4227dd7cddfSDavid du Colombier break;
4237dd7cddfSDavid du Colombier }
4247dd7cddfSDavid du Colombier /*
4257dd7cddfSDavid du Colombier * convert from types l->n->nn
4267dd7cddfSDavid du Colombier */
4277dd7cddfSDavid du Colombier if(nocast(l->type, n->type)) {
4287dd7cddfSDavid du Colombier if(nocast(n->type, nn->type)) {
4294ac975e2SDavid du Colombier cgen(l, nn);
4307dd7cddfSDavid du Colombier break;
4317dd7cddfSDavid du Colombier }
4327dd7cddfSDavid du Colombier }
4337dd7cddfSDavid du Colombier regalloc(&nod, l, nn);
4344ac975e2SDavid du Colombier cgen(l, &nod);
4357dd7cddfSDavid du Colombier regalloc(&nod1, n, &nod);
436375daca8SDavid du Colombier if(inrel)
437375daca8SDavid du Colombier gmover(&nod, &nod1);
438375daca8SDavid du Colombier else
4397dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, &nod1);
4407dd7cddfSDavid du Colombier gopcode(OAS, &nod1, Z, nn);
4417dd7cddfSDavid du Colombier regfree(&nod1);
4427dd7cddfSDavid du Colombier regfree(&nod);
4437dd7cddfSDavid du Colombier break;
4447dd7cddfSDavid du Colombier
4457dd7cddfSDavid du Colombier case ODOT:
4467dd7cddfSDavid du Colombier sugen(l, nodrat, l->type->width);
4477dd7cddfSDavid du Colombier if(nn != Z) {
4487dd7cddfSDavid du Colombier warn(n, "non-interruptable temporary");
4497dd7cddfSDavid du Colombier nod = *nodrat;
4507dd7cddfSDavid du Colombier if(!r || r->op != OCONST) {
4517dd7cddfSDavid du Colombier diag(n, "DOT and no offset");
4527dd7cddfSDavid du Colombier break;
4537dd7cddfSDavid du Colombier }
4547dd7cddfSDavid du Colombier nod.xoffset += (long)r->vconst;
4557dd7cddfSDavid du Colombier nod.type = n->type;
4564ac975e2SDavid du Colombier cgen(&nod, nn);
4577dd7cddfSDavid du Colombier }
4587dd7cddfSDavid du Colombier break;
4597dd7cddfSDavid du Colombier
4607dd7cddfSDavid du Colombier case OCOND:
4617dd7cddfSDavid du Colombier bcgen(l, 1);
4627dd7cddfSDavid du Colombier p1 = p;
4634ac975e2SDavid du Colombier cgen(r->left, nn);
4647dd7cddfSDavid du Colombier gbranch(OGOTO);
4657dd7cddfSDavid du Colombier patch(p1, pc);
4667dd7cddfSDavid du Colombier p1 = p;
4674ac975e2SDavid du Colombier cgen(r->right, nn);
4687dd7cddfSDavid du Colombier patch(p1, pc);
4697dd7cddfSDavid du Colombier break;
4707dd7cddfSDavid du Colombier
4717dd7cddfSDavid du Colombier case OPOSTINC:
4727dd7cddfSDavid du Colombier case OPOSTDEC:
4737dd7cddfSDavid du Colombier v = 1;
4747dd7cddfSDavid du Colombier if(l->type->etype == TIND)
4757dd7cddfSDavid du Colombier v = l->type->link->width;
4767dd7cddfSDavid du Colombier if(o == OPOSTDEC)
4777dd7cddfSDavid du Colombier v = -v;
4787dd7cddfSDavid du Colombier if(l->op == OBIT)
4797dd7cddfSDavid du Colombier goto bitinc;
4807dd7cddfSDavid du Colombier if(nn == Z)
4817dd7cddfSDavid du Colombier goto pre;
4827dd7cddfSDavid du Colombier
4837dd7cddfSDavid du Colombier if(l->addable < INDEXED)
4847dd7cddfSDavid du Colombier reglcgen(&nod2, l, Z);
4857dd7cddfSDavid du Colombier else
4867dd7cddfSDavid du Colombier nod2 = *l;
4877dd7cddfSDavid du Colombier
4887dd7cddfSDavid du Colombier regalloc(&nod, l, nn);
4897dd7cddfSDavid du Colombier gopcode(OAS, &nod2, Z, &nod);
4907dd7cddfSDavid du Colombier regalloc(&nod1, l, Z);
4917dd7cddfSDavid du Colombier if(typefd[l->type->etype]) {
4927dd7cddfSDavid du Colombier regalloc(&nod3, l, Z);
4937dd7cddfSDavid du Colombier if(v < 0) {
4947dd7cddfSDavid du Colombier gopcode(OAS, nodfconst(-v), Z, &nod3);
4957dd7cddfSDavid du Colombier gopcode(OSUB, &nod3, &nod, &nod1);
4967dd7cddfSDavid du Colombier } else {
4977dd7cddfSDavid du Colombier gopcode(OAS, nodfconst(v), Z, &nod3);
4987dd7cddfSDavid du Colombier gopcode(OADD, &nod3, &nod, &nod1);
4997dd7cddfSDavid du Colombier }
5007dd7cddfSDavid du Colombier regfree(&nod3);
5017dd7cddfSDavid du Colombier } else
5027dd7cddfSDavid du Colombier gopcode(OADD, nodconst(v), &nod, &nod1);
5037dd7cddfSDavid du Colombier gopcode(OAS, &nod1, Z, &nod2);
5047dd7cddfSDavid du Colombier
5057dd7cddfSDavid du Colombier regfree(&nod);
5067dd7cddfSDavid du Colombier regfree(&nod1);
5077dd7cddfSDavid du Colombier if(l->addable < INDEXED)
5087dd7cddfSDavid du Colombier regfree(&nod2);
5097dd7cddfSDavid du Colombier break;
5107dd7cddfSDavid du Colombier
5117dd7cddfSDavid du Colombier case OPREINC:
5127dd7cddfSDavid du Colombier case OPREDEC:
5137dd7cddfSDavid du Colombier v = 1;
5147dd7cddfSDavid du Colombier if(l->type->etype == TIND)
5157dd7cddfSDavid du Colombier v = l->type->link->width;
5167dd7cddfSDavid du Colombier if(o == OPREDEC)
5177dd7cddfSDavid du Colombier v = -v;
5187dd7cddfSDavid du Colombier if(l->op == OBIT)
5197dd7cddfSDavid du Colombier goto bitinc;
5207dd7cddfSDavid du Colombier
5217dd7cddfSDavid du Colombier pre:
5227dd7cddfSDavid du Colombier if(l->addable < INDEXED)
5237dd7cddfSDavid du Colombier reglcgen(&nod2, l, Z);
5247dd7cddfSDavid du Colombier else
5257dd7cddfSDavid du Colombier nod2 = *l;
5267dd7cddfSDavid du Colombier
5277dd7cddfSDavid du Colombier regalloc(&nod, l, nn);
5287dd7cddfSDavid du Colombier gopcode(OAS, &nod2, Z, &nod);
5297dd7cddfSDavid du Colombier if(typefd[l->type->etype]) {
5307dd7cddfSDavid du Colombier regalloc(&nod3, l, Z);
5317dd7cddfSDavid du Colombier if(v < 0) {
5327dd7cddfSDavid du Colombier gopcode(OAS, nodfconst(-v), Z, &nod3);
5337dd7cddfSDavid du Colombier gopcode(OSUB, &nod3, Z, &nod);
5347dd7cddfSDavid du Colombier } else {
5357dd7cddfSDavid du Colombier gopcode(OAS, nodfconst(v), Z, &nod3);
5367dd7cddfSDavid du Colombier gopcode(OADD, &nod3, Z, &nod);
5377dd7cddfSDavid du Colombier }
5387dd7cddfSDavid du Colombier regfree(&nod3);
5397dd7cddfSDavid du Colombier } else
5407dd7cddfSDavid du Colombier gopcode(OADD, nodconst(v), Z, &nod);
5417dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, &nod2);
5424ac975e2SDavid du Colombier if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
5434ac975e2SDavid du Colombier gins(ANOP, l, Z);
5447dd7cddfSDavid du Colombier
5457dd7cddfSDavid du Colombier regfree(&nod);
5467dd7cddfSDavid du Colombier if(l->addable < INDEXED)
5477dd7cddfSDavid du Colombier regfree(&nod2);
5487dd7cddfSDavid du Colombier break;
5497dd7cddfSDavid du Colombier
5507dd7cddfSDavid du Colombier bitinc:
5517dd7cddfSDavid du Colombier if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
5527dd7cddfSDavid du Colombier bitload(l, &nod, &nod1, &nod2, Z);
5537dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, nn);
5547dd7cddfSDavid du Colombier gopcode(OADD, nodconst(v), Z, &nod);
5557dd7cddfSDavid du Colombier bitstore(l, &nod, &nod1, &nod2, Z);
5567dd7cddfSDavid du Colombier break;
5577dd7cddfSDavid du Colombier }
5587dd7cddfSDavid du Colombier bitload(l, &nod, &nod1, &nod2, nn);
5597dd7cddfSDavid du Colombier gopcode(OADD, nodconst(v), Z, &nod);
5607dd7cddfSDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
5617dd7cddfSDavid du Colombier break;
5627dd7cddfSDavid du Colombier }
5637dd7cddfSDavid du Colombier cursafe = curs;
56459cc4ca5SDavid du Colombier return;
5657dd7cddfSDavid du Colombier }
5667dd7cddfSDavid du Colombier
5677dd7cddfSDavid du Colombier void
reglcgen(Node * t,Node * n,Node * nn)5687dd7cddfSDavid du Colombier reglcgen(Node *t, Node *n, Node *nn)
5697dd7cddfSDavid du Colombier {
5707dd7cddfSDavid du Colombier Node *r;
5717dd7cddfSDavid du Colombier long v;
5727dd7cddfSDavid du Colombier
5737dd7cddfSDavid du Colombier regialloc(t, n, nn);
5747dd7cddfSDavid du Colombier if(n->op == OIND) {
5757dd7cddfSDavid du Colombier r = n->left;
5767dd7cddfSDavid du Colombier while(r->op == OADD)
5777dd7cddfSDavid du Colombier r = r->right;
57859cc4ca5SDavid du Colombier if(sconst(r) && (v = r->vconst+t->xoffset) > -4096 && v < 4096) {
5797dd7cddfSDavid du Colombier v = r->vconst;
5807dd7cddfSDavid du Colombier r->vconst = 0;
5817dd7cddfSDavid du Colombier lcgen(n, t);
5827dd7cddfSDavid du Colombier t->xoffset += v;
5837dd7cddfSDavid du Colombier r->vconst = v;
5847dd7cddfSDavid du Colombier regind(t, n);
5857dd7cddfSDavid du Colombier return;
5867dd7cddfSDavid du Colombier }
58759cc4ca5SDavid du Colombier } else if(n->op == OINDREG) {
58859cc4ca5SDavid du Colombier if((v = n->xoffset) > -4096 && v < 4096) {
58959cc4ca5SDavid du Colombier n->op = OREGISTER;
5904ac975e2SDavid du Colombier cgen(n, t);
59159cc4ca5SDavid du Colombier t->xoffset += v;
59259cc4ca5SDavid du Colombier n->op = OINDREG;
59359cc4ca5SDavid du Colombier regind(t, n);
59459cc4ca5SDavid du Colombier return;
59559cc4ca5SDavid du Colombier }
5967dd7cddfSDavid du Colombier }
5977dd7cddfSDavid du Colombier lcgen(n, t);
5987dd7cddfSDavid du Colombier regind(t, n);
5997dd7cddfSDavid du Colombier }
6007dd7cddfSDavid du Colombier
6017dd7cddfSDavid du Colombier void
reglpcgen(Node * n,Node * nn,int f)60259cc4ca5SDavid du Colombier reglpcgen(Node *n, Node *nn, int f)
60359cc4ca5SDavid du Colombier {
60459cc4ca5SDavid du Colombier Type *t;
60559cc4ca5SDavid du Colombier
60659cc4ca5SDavid du Colombier t = nn->type;
60759cc4ca5SDavid du Colombier nn->type = types[TLONG];
60859cc4ca5SDavid du Colombier if(f)
60959cc4ca5SDavid du Colombier reglcgen(n, nn, Z);
61059cc4ca5SDavid du Colombier else {
61159cc4ca5SDavid du Colombier regialloc(n, nn, Z);
61259cc4ca5SDavid du Colombier lcgen(nn, n);
61359cc4ca5SDavid du Colombier regind(n, nn);
61459cc4ca5SDavid du Colombier }
61559cc4ca5SDavid du Colombier nn->type = t;
61659cc4ca5SDavid du Colombier }
61759cc4ca5SDavid du Colombier
61859cc4ca5SDavid du Colombier void
lcgen(Node * n,Node * nn)6197dd7cddfSDavid du Colombier lcgen(Node *n, Node *nn)
6207dd7cddfSDavid du Colombier {
6217dd7cddfSDavid du Colombier Prog *p1;
6227dd7cddfSDavid du Colombier Node nod;
6237dd7cddfSDavid du Colombier
6247dd7cddfSDavid du Colombier if(debug['g']) {
6257dd7cddfSDavid du Colombier prtree(nn, "lcgen lhs");
6267dd7cddfSDavid du Colombier prtree(n, "lcgen");
6277dd7cddfSDavid du Colombier }
6287dd7cddfSDavid du Colombier if(n == Z || n->type == T)
6297dd7cddfSDavid du Colombier return;
6307dd7cddfSDavid du Colombier if(nn == Z) {
6317dd7cddfSDavid du Colombier nn = &nod;
6327dd7cddfSDavid du Colombier regalloc(&nod, n, Z);
6337dd7cddfSDavid du Colombier }
6347dd7cddfSDavid du Colombier switch(n->op) {
6357dd7cddfSDavid du Colombier default:
6367dd7cddfSDavid du Colombier if(n->addable < INDEXED) {
6377dd7cddfSDavid du Colombier diag(n, "unknown op in lcgen: %O", n->op);
6387dd7cddfSDavid du Colombier break;
6397dd7cddfSDavid du Colombier }
6407dd7cddfSDavid du Colombier nod = *n;
6417dd7cddfSDavid du Colombier nod.op = OADDR;
6427dd7cddfSDavid du Colombier nod.left = n;
6437dd7cddfSDavid du Colombier nod.right = Z;
6447dd7cddfSDavid du Colombier nod.type = types[TIND];
6457dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, nn);
6467dd7cddfSDavid du Colombier break;
6477dd7cddfSDavid du Colombier
6487dd7cddfSDavid du Colombier case OCOMMA:
6494ac975e2SDavid du Colombier cgen(n->left, n->left);
6507dd7cddfSDavid du Colombier lcgen(n->right, nn);
6517dd7cddfSDavid du Colombier break;
6527dd7cddfSDavid du Colombier
6537dd7cddfSDavid du Colombier case OIND:
6544ac975e2SDavid du Colombier cgen(n->left, nn);
6557dd7cddfSDavid du Colombier break;
6567dd7cddfSDavid du Colombier
6577dd7cddfSDavid du Colombier case OCOND:
6587dd7cddfSDavid du Colombier bcgen(n->left, 1);
6597dd7cddfSDavid du Colombier p1 = p;
6607dd7cddfSDavid du Colombier lcgen(n->right->left, nn);
6617dd7cddfSDavid du Colombier gbranch(OGOTO);
6627dd7cddfSDavid du Colombier patch(p1, pc);
6637dd7cddfSDavid du Colombier p1 = p;
6647dd7cddfSDavid du Colombier lcgen(n->right->right, nn);
6657dd7cddfSDavid du Colombier patch(p1, pc);
6667dd7cddfSDavid du Colombier break;
6677dd7cddfSDavid du Colombier }
6687dd7cddfSDavid du Colombier }
6697dd7cddfSDavid du Colombier
6707dd7cddfSDavid du Colombier void
bcgen(Node * n,int true)6717dd7cddfSDavid du Colombier bcgen(Node *n, int true)
6727dd7cddfSDavid du Colombier {
6737dd7cddfSDavid du Colombier
6747dd7cddfSDavid du Colombier if(n->type == T)
6757dd7cddfSDavid du Colombier gbranch(OGOTO);
6767dd7cddfSDavid du Colombier else
6777dd7cddfSDavid du Colombier boolgen(n, true, Z);
6787dd7cddfSDavid du Colombier }
6797dd7cddfSDavid du Colombier
6807dd7cddfSDavid du Colombier void
boolgen(Node * n,int true,Node * nn)6817dd7cddfSDavid du Colombier boolgen(Node *n, int true, Node *nn)
6827dd7cddfSDavid du Colombier {
6837dd7cddfSDavid du Colombier int o;
6847dd7cddfSDavid du Colombier Prog *p1, *p2;
6857dd7cddfSDavid du Colombier Node *l, *r, nod, nod1;
6867dd7cddfSDavid du Colombier long curs;
6877dd7cddfSDavid du Colombier
6887dd7cddfSDavid du Colombier if(debug['g']) {
6897dd7cddfSDavid du Colombier prtree(nn, "boolgen lhs");
6907dd7cddfSDavid du Colombier prtree(n, "boolgen");
6917dd7cddfSDavid du Colombier }
6927dd7cddfSDavid du Colombier curs = cursafe;
6937dd7cddfSDavid du Colombier l = n->left;
6947dd7cddfSDavid du Colombier r = n->right;
6957dd7cddfSDavid du Colombier switch(n->op) {
6967dd7cddfSDavid du Colombier
6977dd7cddfSDavid du Colombier default:
6987dd7cddfSDavid du Colombier regalloc(&nod, n, nn);
6994ac975e2SDavid du Colombier cgen(n, &nod);
7007dd7cddfSDavid du Colombier o = ONE;
7017dd7cddfSDavid du Colombier if(true)
7027dd7cddfSDavid du Colombier o = comrel[relindex(o)];
7037dd7cddfSDavid du Colombier if(typefd[n->type->etype]) {
704*3ec63e64SDavid du Colombier gopcode(true ? o | BTRUE : o, nodfconst(0), &nod, Z);
7057dd7cddfSDavid du Colombier } else
7067dd7cddfSDavid du Colombier gopcode(o, nodconst(0), &nod, Z);
7077dd7cddfSDavid du Colombier regfree(&nod);
7087dd7cddfSDavid du Colombier goto com;
7097dd7cddfSDavid du Colombier
7107dd7cddfSDavid du Colombier case OCONST:
7117dd7cddfSDavid du Colombier o = vconst(n);
7127dd7cddfSDavid du Colombier if(!true)
7137dd7cddfSDavid du Colombier o = !o;
7147dd7cddfSDavid du Colombier gbranch(OGOTO);
7157dd7cddfSDavid du Colombier if(o) {
7167dd7cddfSDavid du Colombier p1 = p;
7177dd7cddfSDavid du Colombier gbranch(OGOTO);
7187dd7cddfSDavid du Colombier patch(p1, pc);
7197dd7cddfSDavid du Colombier }
7207dd7cddfSDavid du Colombier goto com;
7217dd7cddfSDavid du Colombier
7227dd7cddfSDavid du Colombier case OCOMMA:
7234ac975e2SDavid du Colombier cgen(l, Z);
7247dd7cddfSDavid du Colombier boolgen(r, true, nn);
7257dd7cddfSDavid du Colombier break;
7267dd7cddfSDavid du Colombier
7277dd7cddfSDavid du Colombier case ONOT:
7287dd7cddfSDavid du Colombier boolgen(l, !true, nn);
7297dd7cddfSDavid du Colombier break;
7307dd7cddfSDavid du Colombier
7317dd7cddfSDavid du Colombier case OCOND:
7327dd7cddfSDavid du Colombier bcgen(l, 1);
7337dd7cddfSDavid du Colombier p1 = p;
7347dd7cddfSDavid du Colombier bcgen(r->left, true);
7357dd7cddfSDavid du Colombier p2 = p;
7367dd7cddfSDavid du Colombier gbranch(OGOTO);
7377dd7cddfSDavid du Colombier patch(p1, pc);
7387dd7cddfSDavid du Colombier p1 = p;
7397dd7cddfSDavid du Colombier bcgen(r->right, !true);
7407dd7cddfSDavid du Colombier patch(p2, pc);
7417dd7cddfSDavid du Colombier p2 = p;
7427dd7cddfSDavid du Colombier gbranch(OGOTO);
7437dd7cddfSDavid du Colombier patch(p1, pc);
7447dd7cddfSDavid du Colombier patch(p2, pc);
7457dd7cddfSDavid du Colombier goto com;
7467dd7cddfSDavid du Colombier
7477dd7cddfSDavid du Colombier case OANDAND:
7487dd7cddfSDavid du Colombier if(!true)
7497dd7cddfSDavid du Colombier goto caseor;
7507dd7cddfSDavid du Colombier
7517dd7cddfSDavid du Colombier caseand:
7527dd7cddfSDavid du Colombier bcgen(l, true);
7537dd7cddfSDavid du Colombier p1 = p;
7547dd7cddfSDavid du Colombier bcgen(r, !true);
7557dd7cddfSDavid du Colombier p2 = p;
7567dd7cddfSDavid du Colombier patch(p1, pc);
7577dd7cddfSDavid du Colombier gbranch(OGOTO);
7587dd7cddfSDavid du Colombier patch(p2, pc);
7597dd7cddfSDavid du Colombier goto com;
7607dd7cddfSDavid du Colombier
7617dd7cddfSDavid du Colombier case OOROR:
7627dd7cddfSDavid du Colombier if(!true)
7637dd7cddfSDavid du Colombier goto caseand;
7647dd7cddfSDavid du Colombier
7657dd7cddfSDavid du Colombier caseor:
7667dd7cddfSDavid du Colombier bcgen(l, !true);
7677dd7cddfSDavid du Colombier p1 = p;
7687dd7cddfSDavid du Colombier bcgen(r, !true);
7697dd7cddfSDavid du Colombier p2 = p;
7707dd7cddfSDavid du Colombier gbranch(OGOTO);
7717dd7cddfSDavid du Colombier patch(p1, pc);
7727dd7cddfSDavid du Colombier patch(p2, pc);
7737dd7cddfSDavid du Colombier goto com;
7747dd7cddfSDavid du Colombier
7757dd7cddfSDavid du Colombier case OEQ:
7767dd7cddfSDavid du Colombier case ONE:
7777dd7cddfSDavid du Colombier case OLE:
7787dd7cddfSDavid du Colombier case OLT:
7797dd7cddfSDavid du Colombier case OGE:
7807dd7cddfSDavid du Colombier case OGT:
7817dd7cddfSDavid du Colombier case OHI:
7827dd7cddfSDavid du Colombier case OHS:
7837dd7cddfSDavid du Colombier case OLO:
7847dd7cddfSDavid du Colombier case OLS:
7857dd7cddfSDavid du Colombier o = n->op;
7867dd7cddfSDavid du Colombier if(true)
7877dd7cddfSDavid du Colombier o = comrel[relindex(o)];
7887dd7cddfSDavid du Colombier if(l->complex >= FNX && r->complex >= FNX) {
7897dd7cddfSDavid du Colombier regret(&nod, r);
7904ac975e2SDavid du Colombier cgenrel(r, &nod, 1);
7917dd7cddfSDavid du Colombier regsalloc(&nod1, r);
7927dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, &nod1);
7937dd7cddfSDavid du Colombier regfree(&nod);
7947dd7cddfSDavid du Colombier nod = *n;
7957dd7cddfSDavid du Colombier nod.right = &nod1;
7967dd7cddfSDavid du Colombier boolgen(&nod, true, nn);
7977dd7cddfSDavid du Colombier break;
7987dd7cddfSDavid du Colombier }
7997dd7cddfSDavid du Colombier if(sconst(l)) {
8007dd7cddfSDavid du Colombier regalloc(&nod, r, nn);
8014ac975e2SDavid du Colombier cgenrel(r, &nod, 1);
8027dd7cddfSDavid du Colombier o = invrel[relindex(o)];
803*3ec63e64SDavid du Colombier gopcode(true ? o | BTRUE : o, l, &nod, Z);
8047dd7cddfSDavid du Colombier regfree(&nod);
8057dd7cddfSDavid du Colombier goto com;
8067dd7cddfSDavid du Colombier }
8077dd7cddfSDavid du Colombier if(sconst(r)) {
8087dd7cddfSDavid du Colombier regalloc(&nod, l, nn);
8094ac975e2SDavid du Colombier cgenrel(l, &nod, 1);
810*3ec63e64SDavid du Colombier gopcode(true ? o | BTRUE : o, r, &nod, Z);
8117dd7cddfSDavid du Colombier regfree(&nod);
8127dd7cddfSDavid du Colombier goto com;
8137dd7cddfSDavid du Colombier }
8147dd7cddfSDavid du Colombier if(l->complex >= r->complex) {
8157dd7cddfSDavid du Colombier regalloc(&nod1, l, nn);
8164ac975e2SDavid du Colombier cgenrel(l, &nod1, 1);
8177dd7cddfSDavid du Colombier regalloc(&nod, r, Z);
8184ac975e2SDavid du Colombier cgenrel(r, &nod, 1);
8197dd7cddfSDavid du Colombier } else {
8207dd7cddfSDavid du Colombier regalloc(&nod, r, nn);
8214ac975e2SDavid du Colombier cgenrel(r, &nod, 1);
8227dd7cddfSDavid du Colombier regalloc(&nod1, l, Z);
8234ac975e2SDavid du Colombier cgenrel(l, &nod1, 1);
8247dd7cddfSDavid du Colombier }
825*3ec63e64SDavid du Colombier gopcode(true ? o | BTRUE : o, &nod, &nod1, Z);
8267dd7cddfSDavid du Colombier regfree(&nod);
8277dd7cddfSDavid du Colombier regfree(&nod1);
8287dd7cddfSDavid du Colombier
8297dd7cddfSDavid du Colombier com:
8307dd7cddfSDavid du Colombier if(nn != Z) {
8317dd7cddfSDavid du Colombier p1 = p;
8327dd7cddfSDavid du Colombier gopcode(OAS, nodconst(1), Z, nn);
8337dd7cddfSDavid du Colombier gbranch(OGOTO);
8347dd7cddfSDavid du Colombier p2 = p;
8357dd7cddfSDavid du Colombier patch(p1, pc);
8367dd7cddfSDavid du Colombier gopcode(OAS, nodconst(0), Z, nn);
8377dd7cddfSDavid du Colombier patch(p2, pc);
8387dd7cddfSDavid du Colombier }
8397dd7cddfSDavid du Colombier break;
8407dd7cddfSDavid du Colombier }
8417dd7cddfSDavid du Colombier cursafe = curs;
8427dd7cddfSDavid du Colombier }
8437dd7cddfSDavid du Colombier
8447dd7cddfSDavid du Colombier void
sugen(Node * n,Node * nn,long w)8457dd7cddfSDavid du Colombier sugen(Node *n, Node *nn, long w)
8467dd7cddfSDavid du Colombier {
8477dd7cddfSDavid du Colombier Prog *p1;
8487dd7cddfSDavid du Colombier Node nod0, nod1, nod2, nod3, nod4, *l, *r;
8497dd7cddfSDavid du Colombier Type *t;
8507dd7cddfSDavid du Colombier long pc1;
8517dd7cddfSDavid du Colombier int i, m, c;
8527dd7cddfSDavid du Colombier
8537dd7cddfSDavid du Colombier if(n == Z || n->type == T)
8547dd7cddfSDavid du Colombier return;
8557dd7cddfSDavid du Colombier if(debug['g']) {
8567dd7cddfSDavid du Colombier prtree(nn, "sugen lhs");
8577dd7cddfSDavid du Colombier prtree(n, "sugen");
8587dd7cddfSDavid du Colombier }
8597dd7cddfSDavid du Colombier if(nn == nodrat)
8607dd7cddfSDavid du Colombier if(w > nrathole)
8617dd7cddfSDavid du Colombier nrathole = w;
8627dd7cddfSDavid du Colombier switch(n->op) {
8637dd7cddfSDavid du Colombier case OIND:
8647dd7cddfSDavid du Colombier if(nn == Z) {
8657dd7cddfSDavid du Colombier nullwarn(n->left, Z);
8667dd7cddfSDavid du Colombier break;
8677dd7cddfSDavid du Colombier }
8687dd7cddfSDavid du Colombier
8697dd7cddfSDavid du Colombier default:
8707dd7cddfSDavid du Colombier goto copy;
8717dd7cddfSDavid du Colombier
8727dd7cddfSDavid du Colombier case OCONST:
8737dd7cddfSDavid du Colombier if(n->type && typev[n->type->etype]) {
8747dd7cddfSDavid du Colombier if(nn == Z) {
8757dd7cddfSDavid du Colombier nullwarn(n->left, Z);
8767dd7cddfSDavid du Colombier break;
8777dd7cddfSDavid du Colombier }
8787dd7cddfSDavid du Colombier
8797dd7cddfSDavid du Colombier t = nn->type;
8807dd7cddfSDavid du Colombier nn->type = types[TLONG];
8817dd7cddfSDavid du Colombier reglcgen(&nod1, nn, Z);
8827dd7cddfSDavid du Colombier nn->type = t;
8837dd7cddfSDavid du Colombier
88480ee5cbfSDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
8857dd7cddfSDavid du Colombier gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
88680ee5cbfSDavid du Colombier else
8877dd7cddfSDavid du Colombier gopcode(OAS, nod32const(n->vconst), Z, &nod1);
88880ee5cbfSDavid du Colombier nod1.xoffset += SZ_LONG;
88980ee5cbfSDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
89080ee5cbfSDavid du Colombier gopcode(OAS, nod32const(n->vconst), Z, &nod1);
89180ee5cbfSDavid du Colombier else
89280ee5cbfSDavid du Colombier gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
8937dd7cddfSDavid du Colombier
8947dd7cddfSDavid du Colombier regfree(&nod1);
8957dd7cddfSDavid du Colombier break;
8967dd7cddfSDavid du Colombier }
8977dd7cddfSDavid du Colombier goto copy;
8987dd7cddfSDavid du Colombier
8997dd7cddfSDavid du Colombier case ODOT:
9007dd7cddfSDavid du Colombier l = n->left;
9017dd7cddfSDavid du Colombier sugen(l, nodrat, l->type->width);
9027dd7cddfSDavid du Colombier if(nn != Z) {
9037dd7cddfSDavid du Colombier warn(n, "non-interruptable temporary");
9047dd7cddfSDavid du Colombier nod1 = *nodrat;
9057dd7cddfSDavid du Colombier r = n->right;
9067dd7cddfSDavid du Colombier if(!r || r->op != OCONST) {
9077dd7cddfSDavid du Colombier diag(n, "DOT and no offset");
9087dd7cddfSDavid du Colombier break;
9097dd7cddfSDavid du Colombier }
9107dd7cddfSDavid du Colombier nod1.xoffset += (long)r->vconst;
9117dd7cddfSDavid du Colombier nod1.type = n->type;
9127dd7cddfSDavid du Colombier sugen(&nod1, nn, w);
9137dd7cddfSDavid du Colombier }
9147dd7cddfSDavid du Colombier break;
9157dd7cddfSDavid du Colombier
9167dd7cddfSDavid du Colombier case OSTRUCT:
9177dd7cddfSDavid du Colombier /*
9187dd7cddfSDavid du Colombier * rewrite so lhs has no fn call
9197dd7cddfSDavid du Colombier */
9207dd7cddfSDavid du Colombier if(nn != Z && nn->complex >= FNX) {
9217dd7cddfSDavid du Colombier nod1 = *n;
9227dd7cddfSDavid du Colombier nod1.type = typ(TIND, n->type);
9237dd7cddfSDavid du Colombier regret(&nod2, &nod1);
9247dd7cddfSDavid du Colombier lcgen(nn, &nod2);
9257dd7cddfSDavid du Colombier regsalloc(&nod0, &nod1);
9267dd7cddfSDavid du Colombier gopcode(OAS, &nod2, Z, &nod0);
9277dd7cddfSDavid du Colombier regfree(&nod2);
9287dd7cddfSDavid du Colombier
9297dd7cddfSDavid du Colombier nod1 = *n;
9307dd7cddfSDavid du Colombier nod1.op = OIND;
9317dd7cddfSDavid du Colombier nod1.left = &nod0;
9327dd7cddfSDavid du Colombier nod1.right = Z;
9337dd7cddfSDavid du Colombier nod1.complex = 1;
9347dd7cddfSDavid du Colombier
9357dd7cddfSDavid du Colombier sugen(n, &nod1, w);
9367dd7cddfSDavid du Colombier return;
9377dd7cddfSDavid du Colombier }
9387dd7cddfSDavid du Colombier
9397dd7cddfSDavid du Colombier r = n->left;
9407dd7cddfSDavid du Colombier for(t = n->type->link; t != T; t = t->down) {
9417dd7cddfSDavid du Colombier l = r;
9427dd7cddfSDavid du Colombier if(r->op == OLIST) {
9437dd7cddfSDavid du Colombier l = r->left;
9447dd7cddfSDavid du Colombier r = r->right;
9457dd7cddfSDavid du Colombier }
9467dd7cddfSDavid du Colombier if(nn == Z) {
9474ac975e2SDavid du Colombier cgen(l, nn);
9487dd7cddfSDavid du Colombier continue;
9497dd7cddfSDavid du Colombier }
9507dd7cddfSDavid du Colombier /*
9517dd7cddfSDavid du Colombier * hand craft *(&nn + o) = l
9527dd7cddfSDavid du Colombier */
9537dd7cddfSDavid du Colombier nod0 = znode;
9547dd7cddfSDavid du Colombier nod0.op = OAS;
9557dd7cddfSDavid du Colombier nod0.type = t;
9567dd7cddfSDavid du Colombier nod0.left = &nod1;
9577dd7cddfSDavid du Colombier nod0.right = l;
9587dd7cddfSDavid du Colombier
9597dd7cddfSDavid du Colombier nod1 = znode;
9607dd7cddfSDavid du Colombier nod1.op = OIND;
9617dd7cddfSDavid du Colombier nod1.type = t;
9627dd7cddfSDavid du Colombier nod1.left = &nod2;
9637dd7cddfSDavid du Colombier
9647dd7cddfSDavid du Colombier nod2 = znode;
9657dd7cddfSDavid du Colombier nod2.op = OADD;
9667dd7cddfSDavid du Colombier nod2.type = typ(TIND, t);
9677dd7cddfSDavid du Colombier nod2.left = &nod3;
9687dd7cddfSDavid du Colombier nod2.right = &nod4;
9697dd7cddfSDavid du Colombier
9707dd7cddfSDavid du Colombier nod3 = znode;
9717dd7cddfSDavid du Colombier nod3.op = OADDR;
9727dd7cddfSDavid du Colombier nod3.type = nod2.type;
9737dd7cddfSDavid du Colombier nod3.left = nn;
9747dd7cddfSDavid du Colombier
9757dd7cddfSDavid du Colombier nod4 = znode;
9767dd7cddfSDavid du Colombier nod4.op = OCONST;
9777dd7cddfSDavid du Colombier nod4.type = nod2.type;
9787dd7cddfSDavid du Colombier nod4.vconst = t->offset;
9797dd7cddfSDavid du Colombier
9807dd7cddfSDavid du Colombier ccom(&nod0);
9817dd7cddfSDavid du Colombier acom(&nod0);
9827dd7cddfSDavid du Colombier xcom(&nod0);
9837dd7cddfSDavid du Colombier nod0.addable = 0;
9847dd7cddfSDavid du Colombier
9854ac975e2SDavid du Colombier cgen(&nod0, Z);
9867dd7cddfSDavid du Colombier }
9877dd7cddfSDavid du Colombier break;
9887dd7cddfSDavid du Colombier
9897dd7cddfSDavid du Colombier case OAS:
9907dd7cddfSDavid du Colombier if(nn == Z) {
9917dd7cddfSDavid du Colombier if(n->addable < INDEXED)
9927dd7cddfSDavid du Colombier sugen(n->right, n->left, w);
9937dd7cddfSDavid du Colombier break;
9947dd7cddfSDavid du Colombier }
9957dd7cddfSDavid du Colombier sugen(n->right, nodrat, w);
9967dd7cddfSDavid du Colombier warn(n, "non-interruptable temporary");
9977dd7cddfSDavid du Colombier sugen(nodrat, n->left, w);
9987dd7cddfSDavid du Colombier sugen(nodrat, nn, w);
9997dd7cddfSDavid du Colombier break;
10007dd7cddfSDavid du Colombier
10017dd7cddfSDavid du Colombier case OFUNC:
10027dd7cddfSDavid du Colombier if(nn == Z) {
10037dd7cddfSDavid du Colombier sugen(n, nodrat, w);
10047dd7cddfSDavid du Colombier break;
10057dd7cddfSDavid du Colombier }
10067dd7cddfSDavid du Colombier if(nn->op != OIND) {
10077dd7cddfSDavid du Colombier nn = new1(OADDR, nn, Z);
10087dd7cddfSDavid du Colombier nn->type = types[TIND];
10097dd7cddfSDavid du Colombier nn->addable = 0;
10107dd7cddfSDavid du Colombier } else
10117dd7cddfSDavid du Colombier nn = nn->left;
10127dd7cddfSDavid du Colombier n = new(OFUNC, n->left, new(OLIST, nn, n->right));
10137dd7cddfSDavid du Colombier n->type = types[TVOID];
10147dd7cddfSDavid du Colombier n->left->type = types[TVOID];
10154ac975e2SDavid du Colombier cgen(n, Z);
10167dd7cddfSDavid du Colombier break;
10177dd7cddfSDavid du Colombier
10187dd7cddfSDavid du Colombier case OCOND:
10197dd7cddfSDavid du Colombier bcgen(n->left, 1);
10207dd7cddfSDavid du Colombier p1 = p;
10217dd7cddfSDavid du Colombier sugen(n->right->left, nn, w);
10227dd7cddfSDavid du Colombier gbranch(OGOTO);
10237dd7cddfSDavid du Colombier patch(p1, pc);
10247dd7cddfSDavid du Colombier p1 = p;
10257dd7cddfSDavid du Colombier sugen(n->right->right, nn, w);
10267dd7cddfSDavid du Colombier patch(p1, pc);
10277dd7cddfSDavid du Colombier break;
10287dd7cddfSDavid du Colombier
10297dd7cddfSDavid du Colombier case OCOMMA:
10304ac975e2SDavid du Colombier cgen(n->left, Z);
10317dd7cddfSDavid du Colombier sugen(n->right, nn, w);
10327dd7cddfSDavid du Colombier break;
10337dd7cddfSDavid du Colombier }
10347dd7cddfSDavid du Colombier return;
10357dd7cddfSDavid du Colombier
10367dd7cddfSDavid du Colombier copy:
10377dd7cddfSDavid du Colombier if(nn == Z)
10387dd7cddfSDavid du Colombier return;
10397dd7cddfSDavid du Colombier if(n->complex >= FNX && nn->complex >= FNX) {
10407dd7cddfSDavid du Colombier t = nn->type;
10417dd7cddfSDavid du Colombier nn->type = types[TLONG];
10427dd7cddfSDavid du Colombier regialloc(&nod1, nn, Z);
10437dd7cddfSDavid du Colombier lcgen(nn, &nod1);
10447dd7cddfSDavid du Colombier regsalloc(&nod2, nn);
10457dd7cddfSDavid du Colombier nn->type = t;
10467dd7cddfSDavid du Colombier
10477dd7cddfSDavid du Colombier gopcode(OAS, &nod1, Z, &nod2);
10487dd7cddfSDavid du Colombier regfree(&nod1);
10497dd7cddfSDavid du Colombier
10507dd7cddfSDavid du Colombier nod2.type = typ(TIND, t);
10517dd7cddfSDavid du Colombier
10527dd7cddfSDavid du Colombier nod1 = nod2;
10537dd7cddfSDavid du Colombier nod1.op = OIND;
10547dd7cddfSDavid du Colombier nod1.left = &nod2;
10557dd7cddfSDavid du Colombier nod1.right = Z;
10567dd7cddfSDavid du Colombier nod1.complex = 1;
10577dd7cddfSDavid du Colombier nod1.type = t;
10587dd7cddfSDavid du Colombier
10597dd7cddfSDavid du Colombier sugen(n, &nod1, w);
10607dd7cddfSDavid du Colombier return;
10617dd7cddfSDavid du Colombier }
10627dd7cddfSDavid du Colombier
106359cc4ca5SDavid du Colombier w /= SZ_LONG;
106459cc4ca5SDavid du Colombier if(w <= 2) {
10657dd7cddfSDavid du Colombier if(n->complex > nn->complex) {
106659cc4ca5SDavid du Colombier reglpcgen(&nod1, n, 1);
106759cc4ca5SDavid du Colombier reglpcgen(&nod2, nn, 1);
10687dd7cddfSDavid du Colombier } else {
106959cc4ca5SDavid du Colombier reglpcgen(&nod2, nn, 1);
107059cc4ca5SDavid du Colombier reglpcgen(&nod1, n, 1);
107159cc4ca5SDavid du Colombier }
107259cc4ca5SDavid du Colombier regalloc(&nod3, ®node, Z);
107359cc4ca5SDavid du Colombier regalloc(&nod4, ®node, Z);
107451480713SDavid du Colombier if(nod3.reg > nod4.reg){
107551480713SDavid du Colombier /* code below assumes nod3 loaded first */
107651480713SDavid du Colombier Node t = nod3; nod3 = nod4; nod4 = t;
107751480713SDavid du Colombier }
107859cc4ca5SDavid du Colombier nod0 = *nodconst((1<<nod3.reg)|(1<<nod4.reg));
107959cc4ca5SDavid du Colombier if(w == 2 && nod1.xoffset == 0)
108059cc4ca5SDavid du Colombier gmovm(&nod1, &nod0, 0);
108159cc4ca5SDavid du Colombier else {
108259cc4ca5SDavid du Colombier gmove(&nod1, &nod3);
108359cc4ca5SDavid du Colombier if(w == 2) {
108459cc4ca5SDavid du Colombier nod1.xoffset += SZ_LONG;
108559cc4ca5SDavid du Colombier gmove(&nod1, &nod4);
108659cc4ca5SDavid du Colombier }
108759cc4ca5SDavid du Colombier }
108859cc4ca5SDavid du Colombier if(w == 2 && nod2.xoffset == 0)
108959cc4ca5SDavid du Colombier gmovm(&nod0, &nod2, 0);
109059cc4ca5SDavid du Colombier else {
109159cc4ca5SDavid du Colombier gmove(&nod3, &nod2);
109259cc4ca5SDavid du Colombier if(w == 2) {
109359cc4ca5SDavid du Colombier nod2.xoffset += SZ_LONG;
109459cc4ca5SDavid du Colombier gmove(&nod4, &nod2);
109559cc4ca5SDavid du Colombier }
109659cc4ca5SDavid du Colombier }
109759cc4ca5SDavid du Colombier regfree(&nod1);
109859cc4ca5SDavid du Colombier regfree(&nod2);
109959cc4ca5SDavid du Colombier regfree(&nod3);
110059cc4ca5SDavid du Colombier regfree(&nod4);
110159cc4ca5SDavid du Colombier return;
11027dd7cddfSDavid du Colombier }
11037dd7cddfSDavid du Colombier
110459cc4ca5SDavid du Colombier if(n->complex > nn->complex) {
110559cc4ca5SDavid du Colombier reglpcgen(&nod1, n, 0);
110659cc4ca5SDavid du Colombier reglpcgen(&nod2, nn, 0);
110759cc4ca5SDavid du Colombier } else {
110859cc4ca5SDavid du Colombier reglpcgen(&nod2, nn, 0);
110959cc4ca5SDavid du Colombier reglpcgen(&nod1, n, 0);
111059cc4ca5SDavid du Colombier }
111159cc4ca5SDavid du Colombier
111259cc4ca5SDavid du Colombier m = 0;
111359cc4ca5SDavid du Colombier for(c = 0; c < w && c < 4; c++) {
111459cc4ca5SDavid du Colombier i = tmpreg();
111559cc4ca5SDavid du Colombier if (i == 0)
111659cc4ca5SDavid du Colombier break;
111759cc4ca5SDavid du Colombier reg[i]++;
111859cc4ca5SDavid du Colombier m |= 1<<i;
111959cc4ca5SDavid du Colombier }
112059cc4ca5SDavid du Colombier nod4 = *(nodconst(m));
112159cc4ca5SDavid du Colombier if(w < 3*c) {
112259cc4ca5SDavid du Colombier for (; w>c; w-=c) {
112359cc4ca5SDavid du Colombier gmovm(&nod1, &nod4, 1);
112459cc4ca5SDavid du Colombier gmovm(&nod4, &nod2, 1);
112559cc4ca5SDavid du Colombier }
11267dd7cddfSDavid du Colombier goto out;
11277dd7cddfSDavid du Colombier }
11287dd7cddfSDavid du Colombier
11297dd7cddfSDavid du Colombier regalloc(&nod3, ®node, Z);
113059cc4ca5SDavid du Colombier gopcode(OAS, nodconst(w/c), Z, &nod3);
113159cc4ca5SDavid du Colombier w %= c;
11327dd7cddfSDavid du Colombier
11337dd7cddfSDavid du Colombier pc1 = pc;
113459cc4ca5SDavid du Colombier gmovm(&nod1, &nod4, 1);
113559cc4ca5SDavid du Colombier gmovm(&nod4, &nod2, 1);
11367dd7cddfSDavid du Colombier
11377dd7cddfSDavid du Colombier gopcode(OSUB, nodconst(1), Z, &nod3);
11387dd7cddfSDavid du Colombier gopcode(OEQ, nodconst(0), &nod3, Z);
11397dd7cddfSDavid du Colombier p->as = ABGT;
11407dd7cddfSDavid du Colombier patch(p, pc1);
11417dd7cddfSDavid du Colombier regfree(&nod3);
114259cc4ca5SDavid du Colombier
11437dd7cddfSDavid du Colombier out:
114459cc4ca5SDavid du Colombier if (w) {
114559cc4ca5SDavid du Colombier i = 0;
114659cc4ca5SDavid du Colombier while (c>w) {
114759cc4ca5SDavid du Colombier while ((m&(1<<i)) == 0)
114859cc4ca5SDavid du Colombier i++;
114959cc4ca5SDavid du Colombier m &= ~(1<<i);
115059cc4ca5SDavid du Colombier reg[i] = 0;
115159cc4ca5SDavid du Colombier c--;
115259cc4ca5SDavid du Colombier i++;
115359cc4ca5SDavid du Colombier }
115459cc4ca5SDavid du Colombier nod4.vconst = m;
115559cc4ca5SDavid du Colombier gmovm(&nod1, &nod4, 0);
115659cc4ca5SDavid du Colombier gmovm(&nod4, &nod2, 0);
115759cc4ca5SDavid du Colombier }
115859cc4ca5SDavid du Colombier i = 0;
115959cc4ca5SDavid du Colombier do {
116059cc4ca5SDavid du Colombier while ((m&(1<<i)) == 0)
116159cc4ca5SDavid du Colombier i++;
116259cc4ca5SDavid du Colombier reg[i] = 0;
116359cc4ca5SDavid du Colombier c--;
116459cc4ca5SDavid du Colombier i++;
116559cc4ca5SDavid du Colombier } while (c>0);
11667dd7cddfSDavid du Colombier regfree(&nod1);
11677dd7cddfSDavid du Colombier regfree(&nod2);
11687dd7cddfSDavid du Colombier }
1169