17dd7cddfSDavid du Colombier #include "gc.h" 27dd7cddfSDavid du Colombier 37dd7cddfSDavid du Colombier void 4*4ac975e2SDavid du Colombier cgen(Node *n, Node *nn) 5*4ac975e2SDavid du Colombier { 6*4ac975e2SDavid du Colombier cgenrel(n, nn, 0); 7*4ac975e2SDavid du Colombier } 8*4ac975e2SDavid du Colombier 9*4ac975e2SDavid du Colombier void 10*4ac975e2SDavid 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); 54*4ac975e2SDavid 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; 62*4ac975e2SDavid 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); 88*4ac975e2SDavid 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); 107*4ac975e2SDavid du Colombier cgen(r, &nod); 1087dd7cddfSDavid du Colombier } else { 1097dd7cddfSDavid du Colombier regalloc(&nod, r, nn); 110*4ac975e2SDavid 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); 123*4ac975e2SDavid du Colombier cgen(r, &nod); 1247dd7cddfSDavid du Colombier } else { 125*4ac975e2SDavid 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 */ 148*4ac975e2SDavid 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]) { 173*4ac975e2SDavid 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]) { 190*4ac975e2SDavid 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); 214*4ac975e2SDavid du Colombier cgen(l, &nod); 2157dd7cddfSDavid du Colombier regalloc(&nod1, r, Z); 216*4ac975e2SDavid du Colombier cgen(r, &nod1); 2177dd7cddfSDavid du Colombier gopcode(o, &nod1, Z, &nod); 2187dd7cddfSDavid du Colombier } else { 2197dd7cddfSDavid du Colombier regalloc(&nod, r, nn); 220*4ac975e2SDavid du Colombier cgen(r, &nod); 2217dd7cddfSDavid du Colombier regalloc(&nod1, l, Z); 222*4ac975e2SDavid 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); 272*4ac975e2SDavid du Colombier cgen(r, &nod1); 2737dd7cddfSDavid du Colombier } else { 2747dd7cddfSDavid du Colombier regalloc(&nod1, r, Z); 275*4ac975e2SDavid 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); 299*4ac975e2SDavid du Colombier cgen(r, &nod3); 3007dd7cddfSDavid du Colombier } else { 3017dd7cddfSDavid du Colombier regalloc(&nod3, r, Z); 302*4ac975e2SDavid 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); 327*4ac975e2SDavid 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; 337*4ac975e2SDavid 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; 372*4ac975e2SDavid du Colombier cgen(l, &nod); 3737dd7cddfSDavid du Colombier nod.xoffset += v; 3747dd7cddfSDavid du Colombier r->vconst = v; 3757dd7cddfSDavid du Colombier } else 376*4ac975e2SDavid 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: 415*4ac975e2SDavid du Colombier cgen(l, Z); 416*4ac975e2SDavid 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)) { 429*4ac975e2SDavid du Colombier cgen(l, nn); 4307dd7cddfSDavid du Colombier break; 4317dd7cddfSDavid du Colombier } 4327dd7cddfSDavid du Colombier } 4337dd7cddfSDavid du Colombier regalloc(&nod, l, nn); 434*4ac975e2SDavid 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; 456*4ac975e2SDavid 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; 463*4ac975e2SDavid du Colombier cgen(r->left, nn); 4647dd7cddfSDavid du Colombier gbranch(OGOTO); 4657dd7cddfSDavid du Colombier patch(p1, pc); 4667dd7cddfSDavid du Colombier p1 = p; 467*4ac975e2SDavid 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); 542*4ac975e2SDavid du Colombier if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */ 543*4ac975e2SDavid 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 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; 590*4ac975e2SDavid 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 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 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: 649*4ac975e2SDavid 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: 654*4ac975e2SDavid 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 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 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); 699*4ac975e2SDavid 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]) { 7047dd7cddfSDavid du Colombier gopcode(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: 723*4ac975e2SDavid 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); 790*4ac975e2SDavid 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); 801*4ac975e2SDavid du Colombier cgenrel(r, &nod, 1); 8027dd7cddfSDavid du Colombier o = invrel[relindex(o)]; 8037dd7cddfSDavid du Colombier gopcode(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); 809*4ac975e2SDavid du Colombier cgenrel(l, &nod, 1); 8107dd7cddfSDavid du Colombier gopcode(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); 816*4ac975e2SDavid du Colombier cgenrel(l, &nod1, 1); 8177dd7cddfSDavid du Colombier regalloc(&nod, r, Z); 818*4ac975e2SDavid du Colombier cgenrel(r, &nod, 1); 8197dd7cddfSDavid du Colombier } else { 8207dd7cddfSDavid du Colombier regalloc(&nod, r, nn); 821*4ac975e2SDavid du Colombier cgenrel(r, &nod, 1); 8227dd7cddfSDavid du Colombier regalloc(&nod1, l, Z); 823*4ac975e2SDavid du Colombier cgenrel(l, &nod1, 1); 8247dd7cddfSDavid du Colombier } 8257dd7cddfSDavid du Colombier gopcode(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 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) { 947*4ac975e2SDavid 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 985*4ac975e2SDavid 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]; 1015*4ac975e2SDavid 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: 1030*4ac975e2SDavid 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); 107459cc4ca5SDavid du Colombier nod0 = *nodconst((1<<nod3.reg)|(1<<nod4.reg)); 107559cc4ca5SDavid du Colombier if(w == 2 && nod1.xoffset == 0) 107659cc4ca5SDavid du Colombier gmovm(&nod1, &nod0, 0); 107759cc4ca5SDavid du Colombier else { 107859cc4ca5SDavid du Colombier gmove(&nod1, &nod3); 107959cc4ca5SDavid du Colombier if(w == 2) { 108059cc4ca5SDavid du Colombier nod1.xoffset += SZ_LONG; 108159cc4ca5SDavid du Colombier gmove(&nod1, &nod4); 108259cc4ca5SDavid du Colombier } 108359cc4ca5SDavid du Colombier } 108459cc4ca5SDavid du Colombier if(w == 2 && nod2.xoffset == 0) 108559cc4ca5SDavid du Colombier gmovm(&nod0, &nod2, 0); 108659cc4ca5SDavid du Colombier else { 108759cc4ca5SDavid du Colombier gmove(&nod3, &nod2); 108859cc4ca5SDavid du Colombier if(w == 2) { 108959cc4ca5SDavid du Colombier nod2.xoffset += SZ_LONG; 109059cc4ca5SDavid du Colombier gmove(&nod4, &nod2); 109159cc4ca5SDavid du Colombier } 109259cc4ca5SDavid du Colombier } 109359cc4ca5SDavid du Colombier regfree(&nod1); 109459cc4ca5SDavid du Colombier regfree(&nod2); 109559cc4ca5SDavid du Colombier regfree(&nod3); 109659cc4ca5SDavid du Colombier regfree(&nod4); 109759cc4ca5SDavid du Colombier return; 10987dd7cddfSDavid du Colombier } 10997dd7cddfSDavid du Colombier 110059cc4ca5SDavid du Colombier if(n->complex > nn->complex) { 110159cc4ca5SDavid du Colombier reglpcgen(&nod1, n, 0); 110259cc4ca5SDavid du Colombier reglpcgen(&nod2, nn, 0); 110359cc4ca5SDavid du Colombier } else { 110459cc4ca5SDavid du Colombier reglpcgen(&nod2, nn, 0); 110559cc4ca5SDavid du Colombier reglpcgen(&nod1, n, 0); 110659cc4ca5SDavid du Colombier } 110759cc4ca5SDavid du Colombier 110859cc4ca5SDavid du Colombier m = 0; 110959cc4ca5SDavid du Colombier for(c = 0; c < w && c < 4; c++) { 111059cc4ca5SDavid du Colombier i = tmpreg(); 111159cc4ca5SDavid du Colombier if (i == 0) 111259cc4ca5SDavid du Colombier break; 111359cc4ca5SDavid du Colombier reg[i]++; 111459cc4ca5SDavid du Colombier m |= 1<<i; 111559cc4ca5SDavid du Colombier } 111659cc4ca5SDavid du Colombier nod4 = *(nodconst(m)); 111759cc4ca5SDavid du Colombier if(w < 3*c) { 111859cc4ca5SDavid du Colombier for (; w>c; w-=c) { 111959cc4ca5SDavid du Colombier gmovm(&nod1, &nod4, 1); 112059cc4ca5SDavid du Colombier gmovm(&nod4, &nod2, 1); 112159cc4ca5SDavid du Colombier } 11227dd7cddfSDavid du Colombier goto out; 11237dd7cddfSDavid du Colombier } 11247dd7cddfSDavid du Colombier 11257dd7cddfSDavid du Colombier regalloc(&nod3, ®node, Z); 112659cc4ca5SDavid du Colombier gopcode(OAS, nodconst(w/c), Z, &nod3); 112759cc4ca5SDavid du Colombier w %= c; 11287dd7cddfSDavid du Colombier 11297dd7cddfSDavid du Colombier pc1 = pc; 113059cc4ca5SDavid du Colombier gmovm(&nod1, &nod4, 1); 113159cc4ca5SDavid du Colombier gmovm(&nod4, &nod2, 1); 11327dd7cddfSDavid du Colombier 11337dd7cddfSDavid du Colombier gopcode(OSUB, nodconst(1), Z, &nod3); 11347dd7cddfSDavid du Colombier gopcode(OEQ, nodconst(0), &nod3, Z); 11357dd7cddfSDavid du Colombier p->as = ABGT; 11367dd7cddfSDavid du Colombier patch(p, pc1); 11377dd7cddfSDavid du Colombier regfree(&nod3); 113859cc4ca5SDavid du Colombier 11397dd7cddfSDavid du Colombier out: 114059cc4ca5SDavid du Colombier if (w) { 114159cc4ca5SDavid du Colombier i = 0; 114259cc4ca5SDavid du Colombier while (c>w) { 114359cc4ca5SDavid du Colombier while ((m&(1<<i)) == 0) 114459cc4ca5SDavid du Colombier i++; 114559cc4ca5SDavid du Colombier m &= ~(1<<i); 114659cc4ca5SDavid du Colombier reg[i] = 0; 114759cc4ca5SDavid du Colombier c--; 114859cc4ca5SDavid du Colombier i++; 114959cc4ca5SDavid du Colombier } 115059cc4ca5SDavid du Colombier nod4.vconst = m; 115159cc4ca5SDavid du Colombier gmovm(&nod1, &nod4, 0); 115259cc4ca5SDavid du Colombier gmovm(&nod4, &nod2, 0); 115359cc4ca5SDavid du Colombier } 115459cc4ca5SDavid du Colombier i = 0; 115559cc4ca5SDavid du Colombier do { 115659cc4ca5SDavid du Colombier while ((m&(1<<i)) == 0) 115759cc4ca5SDavid du Colombier i++; 115859cc4ca5SDavid du Colombier reg[i] = 0; 115959cc4ca5SDavid du Colombier c--; 116059cc4ca5SDavid du Colombier i++; 116159cc4ca5SDavid du Colombier } while (c>0); 11627dd7cddfSDavid du Colombier regfree(&nod1); 11637dd7cddfSDavid du Colombier regfree(&nod2); 11647dd7cddfSDavid du Colombier } 1165