14ac975e2SDavid du Colombier #include "gc.h"
24ac975e2SDavid du Colombier
34ac975e2SDavid du Colombier void
codgen(Node * n,Node * nn)44ac975e2SDavid du Colombier codgen(Node *n, Node *nn)
54ac975e2SDavid du Colombier {
64ac975e2SDavid du Colombier Prog *sp;
74ac975e2SDavid du Colombier Node *n1, nod, nod1;
84ac975e2SDavid du Colombier
94ac975e2SDavid du Colombier cursafe = 0;
104ac975e2SDavid du Colombier curarg = 0;
114ac975e2SDavid du Colombier maxargsafe = 0;
126891d857SDavid du Colombier hasdoubled = 0;
134ac975e2SDavid du Colombier
144ac975e2SDavid du Colombier /*
154ac975e2SDavid du Colombier * isolate name
164ac975e2SDavid du Colombier */
174ac975e2SDavid du Colombier for(n1 = nn;; n1 = n1->left) {
184ac975e2SDavid du Colombier if(n1 == Z) {
194ac975e2SDavid du Colombier diag(nn, "cant find function name");
204ac975e2SDavid du Colombier return;
214ac975e2SDavid du Colombier }
224ac975e2SDavid du Colombier if(n1->op == ONAME)
234ac975e2SDavid du Colombier break;
244ac975e2SDavid du Colombier }
254ac975e2SDavid du Colombier nearln = nn->lineno;
264ac975e2SDavid du Colombier gpseudo(ATEXT, n1->sym, nodconst(stkoff));
274ac975e2SDavid du Colombier sp = p;
284ac975e2SDavid du Colombier
296891d857SDavid du Colombier if(typecmplx[thisfn->link->etype]) {
306891d857SDavid du Colombier if(nodret == nil) {
316891d857SDavid du Colombier nodret = new(ONAME, Z, Z);
326891d857SDavid du Colombier nodret->sym = slookup(".ret");
336891d857SDavid du Colombier nodret->class = CPARAM;
346891d857SDavid du Colombier nodret->type = types[TIND];
356891d857SDavid du Colombier nodret->etype = TIND;
366891d857SDavid du Colombier nodret = new(OIND, nodret, Z);
376891d857SDavid du Colombier }
386891d857SDavid du Colombier n1 = nodret->left;
396891d857SDavid du Colombier if(n1->type == T || n1->type->link != thisfn->link) {
406891d857SDavid du Colombier n1->type = typ(TIND, thisfn->link);
416891d857SDavid du Colombier n1->etype = n1->type->etype;
426891d857SDavid du Colombier nodret = new(OIND, n1, Z);
436891d857SDavid du Colombier complex(nodret);
446891d857SDavid du Colombier }
456891d857SDavid du Colombier }
466891d857SDavid du Colombier
474ac975e2SDavid du Colombier /*
484ac975e2SDavid du Colombier * isolate first argument
494ac975e2SDavid du Colombier */
504ac975e2SDavid du Colombier if(REGARG >= 0) {
514ac975e2SDavid du Colombier if(typecmplx[thisfn->link->etype]) {
524ac975e2SDavid du Colombier nod1 = *nodret->left;
534ac975e2SDavid du Colombier nodreg(&nod, &nod1, REGARG);
544ac975e2SDavid du Colombier gmove(&nod, &nod1);
554ac975e2SDavid du Colombier } else
564ac975e2SDavid du Colombier if(firstarg && typeword[firstargtype->etype]) {
576891d857SDavid du Colombier nod1 = znode;
586891d857SDavid du Colombier nod1.op = ONAME;
594ac975e2SDavid du Colombier nod1.sym = firstarg;
604ac975e2SDavid du Colombier nod1.type = firstargtype;
616891d857SDavid du Colombier nod1.class = CPARAM;
624ac975e2SDavid du Colombier nod1.xoffset = align(0, firstargtype, Aarg1);
634ac975e2SDavid du Colombier nod1.etype = firstargtype->etype;
646891d857SDavid du Colombier xcom(&nod1);
654ac975e2SDavid du Colombier nodreg(&nod, &nod1, REGARG);
664ac975e2SDavid du Colombier gmove(&nod, &nod1);
674ac975e2SDavid du Colombier }
684ac975e2SDavid du Colombier }
694ac975e2SDavid du Colombier
70b85a8364SDavid du Colombier canreach = 1;
71b85a8364SDavid du Colombier warnreach = 1;
724ac975e2SDavid du Colombier gen(n);
733a276d32SDavid du Colombier if(canreach && thisfn->link->etype != TVOID){
743a276d32SDavid du Colombier if(debug['B'])
754ac975e2SDavid du Colombier warn(Z, "no return at end of function: %s", n1->sym->name);
763a276d32SDavid du Colombier else
773a276d32SDavid du Colombier diag(Z, "no return at end of function: %s", n1->sym->name);
783a276d32SDavid du Colombier }
794ac975e2SDavid du Colombier noretval(3);
804ac975e2SDavid du Colombier gbranch(ORETURN);
814ac975e2SDavid du Colombier
824ac975e2SDavid du Colombier if(!debug['N'] || debug['R'] || debug['P'])
834ac975e2SDavid du Colombier regopt(sp);
844ac975e2SDavid du Colombier
856891d857SDavid du Colombier if(thechar=='6' || thechar=='7' || thechar=='9' || hasdoubled) /* [sic] */
864ac975e2SDavid du Colombier maxargsafe = round(maxargsafe, 8);
874ac975e2SDavid du Colombier sp->to.offset += maxargsafe;
884ac975e2SDavid du Colombier }
894ac975e2SDavid du Colombier
904ac975e2SDavid du Colombier void
supgen(Node * n)914ac975e2SDavid du Colombier supgen(Node *n)
924ac975e2SDavid du Colombier {
93b85a8364SDavid du Colombier int owarn;
944ac975e2SDavid du Colombier long spc;
954ac975e2SDavid du Colombier Prog *sp;
964ac975e2SDavid du Colombier
974ac975e2SDavid du Colombier if(n == Z)
984ac975e2SDavid du Colombier return;
994ac975e2SDavid du Colombier suppress++;
100b85a8364SDavid du Colombier owarn = warnreach;
101b85a8364SDavid du Colombier warnreach = 0;
1024ac975e2SDavid du Colombier spc = pc;
1034ac975e2SDavid du Colombier sp = lastp;
1044ac975e2SDavid du Colombier gen(n);
1054ac975e2SDavid du Colombier lastp = sp;
1064ac975e2SDavid du Colombier pc = spc;
1074ac975e2SDavid du Colombier sp->link = nil;
1084ac975e2SDavid du Colombier suppress--;
109b85a8364SDavid du Colombier warnreach = owarn;
1104ac975e2SDavid du Colombier }
1114ac975e2SDavid du Colombier
112d40255d8SDavid du Colombier Node*
uncomma(Node * n)113d40255d8SDavid du Colombier uncomma(Node *n)
114d40255d8SDavid du Colombier {
115d40255d8SDavid du Colombier while(n != Z && n->op == OCOMMA) {
116d40255d8SDavid du Colombier cgen(n->left, Z);
117d40255d8SDavid du Colombier n = n->right;
118d40255d8SDavid du Colombier }
119d40255d8SDavid du Colombier return n;
120d40255d8SDavid du Colombier }
121d40255d8SDavid du Colombier
1224ac975e2SDavid du Colombier void
gen(Node * n)1234ac975e2SDavid du Colombier gen(Node *n)
1244ac975e2SDavid du Colombier {
125d40255d8SDavid du Colombier Node *l, nod, rn;
1264ac975e2SDavid du Colombier Prog *sp, *spc, *spb;
1274ac975e2SDavid du Colombier Case *cn;
1284ac975e2SDavid du Colombier long sbc, scc;
129b85a8364SDavid du Colombier int snbreak, sncontin;
130b85a8364SDavid du Colombier int f, o, oldreach;
1314ac975e2SDavid du Colombier
1324ac975e2SDavid du Colombier loop:
1334ac975e2SDavid du Colombier if(n == Z)
1344ac975e2SDavid du Colombier return;
1354ac975e2SDavid du Colombier nearln = n->lineno;
1364ac975e2SDavid du Colombier o = n->op;
1374ac975e2SDavid du Colombier if(debug['G'])
1384ac975e2SDavid du Colombier if(o != OLIST)
1394ac975e2SDavid du Colombier print("%L %O\n", nearln, o);
1404ac975e2SDavid du Colombier
141b85a8364SDavid du Colombier if(!canreach) {
142b85a8364SDavid du Colombier switch(o) {
143b85a8364SDavid du Colombier case OLABEL:
144b85a8364SDavid du Colombier case OCASE:
145b85a8364SDavid du Colombier case OLIST:
146d40255d8SDavid du Colombier case OCOMMA:
147b85a8364SDavid du Colombier case OBREAK:
148b85a8364SDavid du Colombier case OFOR:
149b85a8364SDavid du Colombier case OWHILE:
150b85a8364SDavid du Colombier case ODWHILE:
151b85a8364SDavid du Colombier /* all handled specially - see switch body below */
152b85a8364SDavid du Colombier break;
153b85a8364SDavid du Colombier default:
154b85a8364SDavid du Colombier if(warnreach) {
155b85a8364SDavid du Colombier warn(n, "unreachable code %O", o);
156b85a8364SDavid du Colombier warnreach = 0;
157b85a8364SDavid du Colombier }
158b85a8364SDavid du Colombier }
159b85a8364SDavid du Colombier }
160b85a8364SDavid du Colombier
1614ac975e2SDavid du Colombier switch(o) {
1624ac975e2SDavid du Colombier
1634ac975e2SDavid du Colombier default:
1644ac975e2SDavid du Colombier complex(n);
1654ac975e2SDavid du Colombier cgen(n, Z);
1664ac975e2SDavid du Colombier break;
1674ac975e2SDavid du Colombier
1684ac975e2SDavid du Colombier case OLIST:
169d40255d8SDavid du Colombier case OCOMMA:
1704ac975e2SDavid du Colombier gen(n->left);
1714ac975e2SDavid du Colombier
1724ac975e2SDavid du Colombier rloop:
1734ac975e2SDavid du Colombier n = n->right;
1744ac975e2SDavid du Colombier goto loop;
1754ac975e2SDavid du Colombier
1764ac975e2SDavid du Colombier case ORETURN:
177b85a8364SDavid du Colombier canreach = 0;
178b85a8364SDavid du Colombier warnreach = !suppress;
1794ac975e2SDavid du Colombier complex(n);
1804ac975e2SDavid du Colombier if(n->type == T)
1814ac975e2SDavid du Colombier break;
182d40255d8SDavid du Colombier l = uncomma(n->left);
1834ac975e2SDavid du Colombier if(l == Z) {
1844ac975e2SDavid du Colombier noretval(3);
1854ac975e2SDavid du Colombier gbranch(ORETURN);
1864ac975e2SDavid du Colombier break;
1874ac975e2SDavid du Colombier }
1884ac975e2SDavid du Colombier if(typecmplx[n->type->etype]) {
1896891d857SDavid du Colombier nod = znode;
1906891d857SDavid du Colombier nod.op = OAS;
1916891d857SDavid du Colombier nod.left = nodret;
1926891d857SDavid du Colombier nod.right = l;
1936891d857SDavid du Colombier nod.type = n->type;
1946891d857SDavid du Colombier nod.complex = l->complex;
1956891d857SDavid du Colombier cgen(&nod, Z);
1964ac975e2SDavid du Colombier noretval(3);
1974ac975e2SDavid du Colombier gbranch(ORETURN);
1984ac975e2SDavid du Colombier break;
1994ac975e2SDavid du Colombier }
200d40255d8SDavid du Colombier if(newvlongcode && !typefd[n->type->etype]){
201d40255d8SDavid du Colombier regret(&rn, n);
202d40255d8SDavid du Colombier regfree(&rn);
203d40255d8SDavid du Colombier nod = znode;
204d40255d8SDavid du Colombier nod.op = OAS;
205d40255d8SDavid du Colombier nod.left = &rn;
206d40255d8SDavid du Colombier nod.right = l;
207d40255d8SDavid du Colombier nod.type = n->type;
208d40255d8SDavid du Colombier nod.complex = l->complex;
209d40255d8SDavid du Colombier cgen(&nod, Z);
210d40255d8SDavid du Colombier noretval(2);
211d40255d8SDavid du Colombier gbranch(ORETURN);
212d40255d8SDavid du Colombier break;
213d40255d8SDavid du Colombier }
2144ac975e2SDavid du Colombier regret(&nod, n);
2154ac975e2SDavid du Colombier cgen(l, &nod);
2164ac975e2SDavid du Colombier regfree(&nod);
2174ac975e2SDavid du Colombier if(typefd[n->type->etype])
2184ac975e2SDavid du Colombier noretval(1);
2194ac975e2SDavid du Colombier else
2204ac975e2SDavid du Colombier noretval(2);
2214ac975e2SDavid du Colombier gbranch(ORETURN);
2224ac975e2SDavid du Colombier break;
2234ac975e2SDavid du Colombier
2244ac975e2SDavid du Colombier case OLABEL:
225b85a8364SDavid du Colombier canreach = 1;
2264ac975e2SDavid du Colombier l = n->left;
2274ac975e2SDavid du Colombier if(l) {
2284ac975e2SDavid du Colombier l->pc = pc;
2294ac975e2SDavid du Colombier if(l->label)
2304ac975e2SDavid du Colombier patch(l->label, pc);
2314ac975e2SDavid du Colombier }
2324ac975e2SDavid du Colombier gbranch(OGOTO); /* prevent self reference in reg */
2334ac975e2SDavid du Colombier patch(p, pc);
2344ac975e2SDavid du Colombier goto rloop;
2354ac975e2SDavid du Colombier
2364ac975e2SDavid du Colombier case OGOTO:
237b85a8364SDavid du Colombier canreach = 0;
238b85a8364SDavid du Colombier warnreach = !suppress;
2394ac975e2SDavid du Colombier n = n->left;
2404ac975e2SDavid du Colombier if(n == Z)
2414ac975e2SDavid du Colombier return;
2424ac975e2SDavid du Colombier if(n->complex == 0) {
2434ac975e2SDavid du Colombier diag(Z, "label undefined: %s", n->sym->name);
2444ac975e2SDavid du Colombier return;
2454ac975e2SDavid du Colombier }
2464ac975e2SDavid du Colombier if(suppress)
2474ac975e2SDavid du Colombier return;
2484ac975e2SDavid du Colombier gbranch(OGOTO);
2494ac975e2SDavid du Colombier if(n->pc) {
2504ac975e2SDavid du Colombier patch(p, n->pc);
2514ac975e2SDavid du Colombier return;
2524ac975e2SDavid du Colombier }
2534ac975e2SDavid du Colombier if(n->label)
2544ac975e2SDavid du Colombier patch(n->label, pc-1);
2554ac975e2SDavid du Colombier n->label = p;
2564ac975e2SDavid du Colombier return;
2574ac975e2SDavid du Colombier
2584ac975e2SDavid du Colombier case OCASE:
259b85a8364SDavid du Colombier canreach = 1;
2604ac975e2SDavid du Colombier l = n->left;
2614ac975e2SDavid du Colombier if(cases == C)
2624ac975e2SDavid du Colombier diag(n, "case/default outside a switch");
2634ac975e2SDavid du Colombier if(l == Z) {
264ff4cd143SDavid du Colombier casf();
2654ac975e2SDavid du Colombier cases->val = 0;
2664ac975e2SDavid du Colombier cases->def = 1;
2674ac975e2SDavid du Colombier cases->label = pc;
2685ede6b93SDavid du Colombier cases->isv = 0;
2694ac975e2SDavid du Colombier goto rloop;
2704ac975e2SDavid du Colombier }
2714ac975e2SDavid du Colombier complex(l);
2724ac975e2SDavid du Colombier if(l->type == T)
2734ac975e2SDavid du Colombier goto rloop;
2743a276d32SDavid du Colombier if(l->op != OCONST || !typeswitch[l->type->etype]) {
2753a276d32SDavid du Colombier diag(n, "case expression must be integer constant");
2763a276d32SDavid du Colombier goto rloop;
2773a276d32SDavid du Colombier }
278ff4cd143SDavid du Colombier casf();
2794ac975e2SDavid du Colombier cases->val = l->vconst;
2804ac975e2SDavid du Colombier cases->def = 0;
2814ac975e2SDavid du Colombier cases->label = pc;
2824ac975e2SDavid du Colombier cases->isv = typev[l->type->etype];
2834ac975e2SDavid du Colombier goto rloop;
2844ac975e2SDavid du Colombier
2854ac975e2SDavid du Colombier case OSWITCH:
2864ac975e2SDavid du Colombier l = n->left;
2874ac975e2SDavid du Colombier complex(l);
2884ac975e2SDavid du Colombier if(l->type == T)
2894ac975e2SDavid du Colombier break;
2903a276d32SDavid du Colombier if(!typeswitch[l->type->etype]) {
2914ac975e2SDavid du Colombier diag(n, "switch expression must be integer");
2924ac975e2SDavid du Colombier break;
2934ac975e2SDavid du Colombier }
2944ac975e2SDavid du Colombier
2954ac975e2SDavid du Colombier gbranch(OGOTO); /* entry */
2964ac975e2SDavid du Colombier sp = p;
2974ac975e2SDavid du Colombier
2984ac975e2SDavid du Colombier cn = cases;
2994ac975e2SDavid du Colombier cases = C;
300ff4cd143SDavid du Colombier casf();
3014ac975e2SDavid du Colombier
3024ac975e2SDavid du Colombier sbc = breakpc;
3034ac975e2SDavid du Colombier breakpc = pc;
3044ac975e2SDavid du Colombier snbreak = nbreak;
3054ac975e2SDavid du Colombier nbreak = 0;
3064ac975e2SDavid du Colombier gbranch(OGOTO);
3074ac975e2SDavid du Colombier spb = p;
3084ac975e2SDavid du Colombier
3094ac975e2SDavid du Colombier gen(n->right); /* body */
310b85a8364SDavid du Colombier if(canreach){
3114ac975e2SDavid du Colombier gbranch(OGOTO);
3124ac975e2SDavid du Colombier patch(p, breakpc);
3134ac975e2SDavid du Colombier nbreak++;
3144ac975e2SDavid du Colombier }
3154ac975e2SDavid du Colombier
3164ac975e2SDavid du Colombier patch(sp, pc);
3174ac975e2SDavid du Colombier regalloc(&nod, l, Z);
3184ac975e2SDavid du Colombier /* always signed */
3194ac975e2SDavid du Colombier if(typev[l->type->etype])
3204ac975e2SDavid du Colombier nod.type = types[TVLONG];
3214ac975e2SDavid du Colombier else
3224ac975e2SDavid du Colombier nod.type = types[TLONG];
3234ac975e2SDavid du Colombier cgen(l, &nod);
3244ac975e2SDavid du Colombier doswit(&nod);
3254ac975e2SDavid du Colombier regfree(&nod);
3264ac975e2SDavid du Colombier patch(spb, pc);
3274ac975e2SDavid du Colombier
3284ac975e2SDavid du Colombier cases = cn;
3294ac975e2SDavid du Colombier breakpc = sbc;
330b85a8364SDavid du Colombier canreach = nbreak!=0;
331b85a8364SDavid du Colombier if(canreach == 0)
332b85a8364SDavid du Colombier warnreach = !suppress;
3334ac975e2SDavid du Colombier nbreak = snbreak;
3344ac975e2SDavid du Colombier break;
3354ac975e2SDavid du Colombier
3364ac975e2SDavid du Colombier case OWHILE:
3374ac975e2SDavid du Colombier case ODWHILE:
3384ac975e2SDavid du Colombier l = n->left;
3394ac975e2SDavid du Colombier gbranch(OGOTO); /* entry */
3404ac975e2SDavid du Colombier sp = p;
3414ac975e2SDavid du Colombier
3424ac975e2SDavid du Colombier scc = continpc;
3434ac975e2SDavid du Colombier continpc = pc;
3444ac975e2SDavid du Colombier gbranch(OGOTO);
3454ac975e2SDavid du Colombier spc = p;
3464ac975e2SDavid du Colombier
3474ac975e2SDavid du Colombier sbc = breakpc;
3484ac975e2SDavid du Colombier breakpc = pc;
3494ac975e2SDavid du Colombier snbreak = nbreak;
3504ac975e2SDavid du Colombier nbreak = 0;
3514ac975e2SDavid du Colombier gbranch(OGOTO);
3524ac975e2SDavid du Colombier spb = p;
3534ac975e2SDavid du Colombier
3544ac975e2SDavid du Colombier patch(spc, pc);
3554ac975e2SDavid du Colombier if(n->op == OWHILE)
3564ac975e2SDavid du Colombier patch(sp, pc);
3574ac975e2SDavid du Colombier bcomplex(l, Z); /* test */
3584ac975e2SDavid du Colombier patch(p, breakpc);
3594ac975e2SDavid du Colombier if(l->op != OCONST || vconst(l) == 0)
3604ac975e2SDavid du Colombier nbreak++;
3614ac975e2SDavid du Colombier
3624ac975e2SDavid du Colombier if(n->op == ODWHILE)
3634ac975e2SDavid du Colombier patch(sp, pc);
3644ac975e2SDavid du Colombier gen(n->right); /* body */
3654ac975e2SDavid du Colombier gbranch(OGOTO);
3664ac975e2SDavid du Colombier patch(p, continpc);
3674ac975e2SDavid du Colombier
3684ac975e2SDavid du Colombier patch(spb, pc);
3694ac975e2SDavid du Colombier continpc = scc;
3704ac975e2SDavid du Colombier breakpc = sbc;
371b85a8364SDavid du Colombier canreach = nbreak!=0;
372b85a8364SDavid du Colombier if(canreach == 0)
373b85a8364SDavid du Colombier warnreach = !suppress;
3744ac975e2SDavid du Colombier nbreak = snbreak;
3754ac975e2SDavid du Colombier break;
3764ac975e2SDavid du Colombier
3774ac975e2SDavid du Colombier case OFOR:
3784ac975e2SDavid du Colombier l = n->left;
379b85a8364SDavid du Colombier if(!canreach && l->right->left && warnreach) {
380b85a8364SDavid du Colombier warn(n, "unreachable code FOR");
381b85a8364SDavid du Colombier warnreach = 0;
382b85a8364SDavid du Colombier }
3834ac975e2SDavid du Colombier gen(l->right->left); /* init */
3844ac975e2SDavid du Colombier gbranch(OGOTO); /* entry */
3854ac975e2SDavid du Colombier sp = p;
3864ac975e2SDavid du Colombier
387b85a8364SDavid du Colombier /*
388b85a8364SDavid du Colombier * if there are no incoming labels in the
389b85a8364SDavid du Colombier * body and the top's not reachable, warn
390b85a8364SDavid du Colombier */
391b85a8364SDavid du Colombier if(!canreach && warnreach && deadheads(n)) {
392b85a8364SDavid du Colombier warn(n, "unreachable code %O", o);
393b85a8364SDavid du Colombier warnreach = 0;
394b85a8364SDavid du Colombier }
395b85a8364SDavid du Colombier
3964ac975e2SDavid du Colombier scc = continpc;
3974ac975e2SDavid du Colombier continpc = pc;
3984ac975e2SDavid du Colombier gbranch(OGOTO);
3994ac975e2SDavid du Colombier spc = p;
4004ac975e2SDavid du Colombier
4014ac975e2SDavid du Colombier sbc = breakpc;
4024ac975e2SDavid du Colombier breakpc = pc;
4034ac975e2SDavid du Colombier snbreak = nbreak;
4044ac975e2SDavid du Colombier nbreak = 0;
405b85a8364SDavid du Colombier sncontin = ncontin;
406b85a8364SDavid du Colombier ncontin = 0;
4074ac975e2SDavid du Colombier gbranch(OGOTO);
4084ac975e2SDavid du Colombier spb = p;
4094ac975e2SDavid du Colombier
4104ac975e2SDavid du Colombier patch(spc, pc);
4114ac975e2SDavid du Colombier gen(l->right->right); /* inc */
4124ac975e2SDavid du Colombier patch(sp, pc);
4134ac975e2SDavid du Colombier if(l->left != Z) { /* test */
4144ac975e2SDavid du Colombier bcomplex(l->left, Z);
4154ac975e2SDavid du Colombier patch(p, breakpc);
4164ac975e2SDavid du Colombier if(l->left->op != OCONST || vconst(l->left) == 0)
4174ac975e2SDavid du Colombier nbreak++;
4184ac975e2SDavid du Colombier }
419b85a8364SDavid du Colombier canreach = 1;
4204ac975e2SDavid du Colombier gen(n->right); /* body */
421b85a8364SDavid du Colombier if(canreach){
4224ac975e2SDavid du Colombier gbranch(OGOTO);
4234ac975e2SDavid du Colombier patch(p, continpc);
424b85a8364SDavid du Colombier ncontin++;
425b85a8364SDavid du Colombier }
426b85a8364SDavid du Colombier if(!ncontin && l->right->right && warnreach) {
427b85a8364SDavid du Colombier warn(l->right->right, "unreachable FOR inc");
428b85a8364SDavid du Colombier warnreach = 0;
429b85a8364SDavid du Colombier }
4304ac975e2SDavid du Colombier
4314ac975e2SDavid du Colombier patch(spb, pc);
4324ac975e2SDavid du Colombier continpc = scc;
4334ac975e2SDavid du Colombier breakpc = sbc;
434b85a8364SDavid du Colombier canreach = nbreak!=0;
435b85a8364SDavid du Colombier if(canreach == 0)
436b85a8364SDavid du Colombier warnreach = !suppress;
4374ac975e2SDavid du Colombier nbreak = snbreak;
438b85a8364SDavid du Colombier ncontin = sncontin;
4394ac975e2SDavid du Colombier break;
4404ac975e2SDavid du Colombier
4414ac975e2SDavid du Colombier case OCONTINUE:
4424ac975e2SDavid du Colombier if(continpc < 0) {
4434ac975e2SDavid du Colombier diag(n, "continue not in a loop");
4444ac975e2SDavid du Colombier break;
4454ac975e2SDavid du Colombier }
4464ac975e2SDavid du Colombier gbranch(OGOTO);
4474ac975e2SDavid du Colombier patch(p, continpc);
448b85a8364SDavid du Colombier ncontin++;
449b85a8364SDavid du Colombier canreach = 0;
450b85a8364SDavid du Colombier warnreach = !suppress;
4514ac975e2SDavid du Colombier break;
4524ac975e2SDavid du Colombier
4534ac975e2SDavid du Colombier case OBREAK:
4544ac975e2SDavid du Colombier if(breakpc < 0) {
4554ac975e2SDavid du Colombier diag(n, "break not in a loop");
4564ac975e2SDavid du Colombier break;
4574ac975e2SDavid du Colombier }
458b85a8364SDavid du Colombier /*
459b85a8364SDavid du Colombier * Don't complain about unreachable break statements.
460b85a8364SDavid du Colombier * There are breaks hidden in yacc's output and some people
461b85a8364SDavid du Colombier * write return; break; in their switch statements out of habit.
462b85a8364SDavid du Colombier * However, don't confuse the analysis by inserting an
463b85a8364SDavid du Colombier * unreachable reference to breakpc either.
464b85a8364SDavid du Colombier */
465b85a8364SDavid du Colombier if(!canreach)
466b85a8364SDavid du Colombier break;
4674ac975e2SDavid du Colombier gbranch(OGOTO);
4684ac975e2SDavid du Colombier patch(p, breakpc);
4694ac975e2SDavid du Colombier nbreak++;
470b85a8364SDavid du Colombier canreach = 0;
471b85a8364SDavid du Colombier warnreach = !suppress;
4724ac975e2SDavid du Colombier break;
4734ac975e2SDavid du Colombier
4744ac975e2SDavid du Colombier case OIF:
4754ac975e2SDavid du Colombier l = n->left;
4764ac975e2SDavid du Colombier if(bcomplex(l, n->right)) {
4774ac975e2SDavid du Colombier if(typefd[l->type->etype])
4784ac975e2SDavid du Colombier f = !l->fconst;
4794ac975e2SDavid du Colombier else
4804ac975e2SDavid du Colombier f = !l->vconst;
4814ac975e2SDavid du Colombier if(debug['c'])
4824ac975e2SDavid du Colombier print("%L const if %s\n", nearln, f ? "false" : "true");
4834ac975e2SDavid du Colombier if(f) {
484b85a8364SDavid du Colombier canreach = 1;
4854ac975e2SDavid du Colombier supgen(n->right->left);
486b85a8364SDavid du Colombier oldreach = canreach;
487b85a8364SDavid du Colombier canreach = 1;
4884ac975e2SDavid du Colombier gen(n->right->right);
489b85a8364SDavid du Colombier /*
490b85a8364SDavid du Colombier * treat constant ifs as regular ifs for
491b85a8364SDavid du Colombier * reachability warnings.
492b85a8364SDavid du Colombier */
493b85a8364SDavid du Colombier if(!canreach && oldreach && debug['w'] < 2)
494b85a8364SDavid du Colombier warnreach = 0;
4954ac975e2SDavid du Colombier }
4964ac975e2SDavid du Colombier else {
497b85a8364SDavid du Colombier canreach = 1;
4984ac975e2SDavid du Colombier gen(n->right->left);
499b85a8364SDavid du Colombier oldreach = canreach;
500b85a8364SDavid du Colombier canreach = 1;
5014ac975e2SDavid du Colombier supgen(n->right->right);
502b85a8364SDavid du Colombier /*
503b85a8364SDavid du Colombier * treat constant ifs as regular ifs for
504b85a8364SDavid du Colombier * reachability warnings.
505b85a8364SDavid du Colombier */
506b85a8364SDavid du Colombier if(!oldreach && canreach && debug['w'] < 2)
507b85a8364SDavid du Colombier warnreach = 0;
508b85a8364SDavid du Colombier canreach = oldreach;
5094ac975e2SDavid du Colombier }
5104ac975e2SDavid du Colombier }
5114ac975e2SDavid du Colombier else {
5124ac975e2SDavid du Colombier sp = p;
513b85a8364SDavid du Colombier canreach = 1;
5144ac975e2SDavid du Colombier if(n->right->left != Z)
5154ac975e2SDavid du Colombier gen(n->right->left);
516b85a8364SDavid du Colombier oldreach = canreach;
517b85a8364SDavid du Colombier canreach = 1;
5184ac975e2SDavid du Colombier if(n->right->right != Z) {
5194ac975e2SDavid du Colombier gbranch(OGOTO);
5204ac975e2SDavid du Colombier patch(sp, pc);
5214ac975e2SDavid du Colombier sp = p;
5224ac975e2SDavid du Colombier gen(n->right->right);
5234ac975e2SDavid du Colombier }
5244ac975e2SDavid du Colombier patch(sp, pc);
525b85a8364SDavid du Colombier canreach = canreach || oldreach;
526b85a8364SDavid du Colombier if(canreach == 0)
527b85a8364SDavid du Colombier warnreach = !suppress;
5284ac975e2SDavid du Colombier }
5294ac975e2SDavid du Colombier break;
5304ac975e2SDavid du Colombier
5314ac975e2SDavid du Colombier case OSET:
5324ac975e2SDavid du Colombier case OUSED:
5334ac975e2SDavid du Colombier usedset(n->left, o);
5344ac975e2SDavid du Colombier break;
5354ac975e2SDavid du Colombier }
5364ac975e2SDavid du Colombier }
5374ac975e2SDavid du Colombier
5384ac975e2SDavid du Colombier void
usedset(Node * n,int o)5394ac975e2SDavid du Colombier usedset(Node *n, int o)
5404ac975e2SDavid du Colombier {
5414ac975e2SDavid du Colombier if(n->op == OLIST) {
5424ac975e2SDavid du Colombier usedset(n->left, o);
5434ac975e2SDavid du Colombier usedset(n->right, o);
5444ac975e2SDavid du Colombier return;
5454ac975e2SDavid du Colombier }
5464ac975e2SDavid du Colombier complex(n);
5474ac975e2SDavid du Colombier switch(n->op) {
5484ac975e2SDavid du Colombier case OADDR: /* volatile */
5494ac975e2SDavid du Colombier gins(ANOP, n, Z);
5504ac975e2SDavid du Colombier break;
5514ac975e2SDavid du Colombier case ONAME:
5524ac975e2SDavid du Colombier if(o == OSET)
5534ac975e2SDavid du Colombier gins(ANOP, Z, n);
5544ac975e2SDavid du Colombier else
5554ac975e2SDavid du Colombier gins(ANOP, n, Z);
5564ac975e2SDavid du Colombier break;
5574ac975e2SDavid du Colombier }
5584ac975e2SDavid du Colombier }
5594ac975e2SDavid du Colombier
5604ac975e2SDavid du Colombier int
bcomplex(Node * n,Node * c)5614ac975e2SDavid du Colombier bcomplex(Node *n, Node *c)
5624ac975e2SDavid du Colombier {
563d40255d8SDavid du Colombier Node *b, nod;
564d40255d8SDavid du Colombier
5654ac975e2SDavid du Colombier
5664ac975e2SDavid du Colombier complex(n);
5674ac975e2SDavid du Colombier if(n->type != T)
5684ac975e2SDavid du Colombier if(tcompat(n, T, n->type, tnot))
5694ac975e2SDavid du Colombier n->type = T;
5704ac975e2SDavid du Colombier if(n->type == T) {
5714ac975e2SDavid du Colombier gbranch(OGOTO);
5724ac975e2SDavid du Colombier return 0;
5734ac975e2SDavid du Colombier }
5744ac975e2SDavid du Colombier if(c != Z && n->op == OCONST && deadheads(c))
5754ac975e2SDavid du Colombier return 1;
576*f38ffa1bSDavid du Colombier /* this is not quite right yet, so ignore it for now */
577*f38ffa1bSDavid du Colombier if(0 && newvlongcode && typev[n->type->etype] && machcap(Z)) {
578d40255d8SDavid du Colombier b = &nod;
579d40255d8SDavid du Colombier b->op = ONE;
580d40255d8SDavid du Colombier b->left = n;
581d40255d8SDavid du Colombier b->right = new(0, Z, Z);
582d40255d8SDavid du Colombier *b->right = *nodconst(0);
583d40255d8SDavid du Colombier b->right->type = n->type;
584d40255d8SDavid du Colombier b->type = types[TLONG];
585d40255d8SDavid du Colombier cgen(b, Z);
586d40255d8SDavid du Colombier return 0;
587d40255d8SDavid du Colombier }
5884ac975e2SDavid du Colombier bool64(n);
5894ac975e2SDavid du Colombier boolgen(n, 1, Z);
5904ac975e2SDavid du Colombier return 0;
5914ac975e2SDavid du Colombier }
592