* as/hc08/lkaomf51.c (OutputName): made name unsigned char,
[fw/sdcc] / src / SDCCopt.c
1 /*-------------------------------------------------------------------------
2   SDCCopt.c - calls all the optimizations routines and does some of the
3               hackier transformations, these include translating iCodes
4               to function calls and replacing local variables with their
5               register equivalents etc. Also contains the driver routine
6               for dead code elimination
7
8              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
9
10    This program is free software; you can redistribute it and/or modify it
11    under the terms of the GNU General Public License as published by the
12    Free Software Foundation; either version 2, or (at your option) any
13    later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24    In other words, you are welcome to use, share and improve this program.
25    You are forbidden to forbid anyone else to use, share and improve
26    what you give them.   Help stamp out software-hoarding!
27 -------------------------------------------------------------------------*/
28
29 #include <math.h>
30 #include "common.h"
31
32 /*-----------------------------------------------------------------*/
33 /* global variables */
34 int cseDefNum = 0;
35
36 char flowChanged = 0;
37
38
39 /*-----------------------------------------------------------------*/
40 /* printSymName - prints the symbol names                          */
41 /*-----------------------------------------------------------------*/
42 int
43 printSymName (void *vsym)
44 {
45   symbol *sym = vsym;
46   fprintf (stdout, " %s ", sym->name);
47   return 0;
48 }
49
50 /*-----------------------------------------------------------------*/
51 /* cnvToFcall - does the actual conversion to function call        */
52 /*-----------------------------------------------------------------*/
53 static void
54 cnvToFcall (iCode * ic, eBBlock * ebp)
55 {
56   iCode *ip;
57   iCode *newic;
58   operand *left;
59   operand *right;
60   symbol *func = NULL;
61   int lineno = ic->lineno;
62   int bytesPushed=0;
63
64   ip = ic->next;                /* insertion point */
65   /* remove it from the iCode */
66   remiCodeFromeBBlock (ebp, ic);
67
68   left = IC_LEFT (ic);
69   right = IC_RIGHT (ic);
70
71   if(IS_FLOAT(operandType( IC_RIGHT( ic ) ))) {
72     switch (ic->op)
73       {
74       case '+':
75         func = __fsadd;
76         break;
77       case '-':
78         func = __fssub;
79         break;
80       case '/':
81         func = __fsdiv;
82         break;
83       case '*':
84         func = __fsmul;
85         break;
86       case EQ_OP:
87         func = __fseq;
88         break;
89       case NE_OP:
90         func = __fsneq;
91         break;
92       case '<':
93         func = __fslt;
94         break;
95       case '>':
96         func = __fsgt;
97         break;
98       case LE_OP:
99         func = __fslteq;
100         break;
101       case GE_OP:
102         func = __fsgteq;
103         break;
104       }
105   } else
106   if(IS_FIXED16X16 (operandType (IC_RIGHT(ic)))) {
107     switch (ic->op)
108       {
109       case '+':
110         func = __fps16x16_add;
111         break;
112       case '-':
113         func = __fps16x16_sub;
114         break;
115       case '/':
116         func = __fps16x16_div;
117         break;
118       case '*':
119         func = __fps16x16_mul;
120         break;
121       case EQ_OP:
122         func = __fps16x16_eq;
123         break;
124       case NE_OP:
125         func = __fps16x16_neq;
126         break;
127       case '<':
128         func = __fps16x16_lt;
129         break;
130       case '>':
131         func = __fps16x16_gt;
132         break;
133       case LE_OP:
134         func = __fps16x16_lteq;
135         break;
136       case GE_OP:
137         func = __fps16x16_gteq;
138         break;
139       }
140   }
141   
142
143   /* if float support routines NOT compiled as reentrant */
144   if (!options.float_rent)
145     {
146
147       /* first one */
148       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
149         {
150           newic = newiCode (SEND, IC_LEFT (ic), NULL);
151           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
152         }
153       else
154         {
155           newic = newiCode ('=', NULL, IC_LEFT (ic));
156           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
157         }
158
159       addiCodeToeBBlock (ebp, newic, ip);
160       newic->lineno = lineno;
161
162       /* second one */
163       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
164         {
165           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
166           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
167         }
168       else
169         {
170           newic = newiCode ('=', NULL, IC_RIGHT (ic));
171           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
172         }
173       addiCodeToeBBlock (ebp, newic, ip);
174       newic->lineno = lineno;
175
176     }
177   else
178     {
179
180       /* push right */
181       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
182         {
183           newic = newiCode (SEND, right, NULL);
184           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
185         }
186       else
187         {
188           newic = newiCode (IPUSH, right, NULL);
189           newic->parmPush = 1;
190           //bytesPushed+=4;
191           bytesPushed += getSize(operandType(right));
192         }
193
194       addiCodeToeBBlock (ebp, newic, ip);
195       newic->lineno = lineno;
196
197       /* insert push left */
198       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
199         {
200           newic = newiCode (SEND, left, NULL);
201           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
202         }
203       else
204         {
205           newic = newiCode (IPUSH, left, NULL);
206           newic->parmPush = 1;
207           //bytesPushed+=4;
208           bytesPushed += getSize(operandType(left));
209         }
210       addiCodeToeBBlock (ebp, newic, ip);
211       newic->lineno = lineno;
212     }
213   /* insert the call */
214   newic = newiCode (CALL, operandFromSymbol (func), NULL);
215   IC_RESULT (newic) = IC_RESULT (ic);
216   newic->lineno = lineno;
217   newic->parmBytes+=bytesPushed;
218   ebp->hasFcall = 1;
219   if (currFunc)
220     FUNC_HASFCALL (currFunc->type) = 1;
221
222   if(TARGET_IS_PIC16) {
223         /* normally these functions aren't marked external, so we can use their
224          * _extern field to marked as already added to symbol table */
225
226         if(!SPEC_EXTR(func->etype)) {
227             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
228
229                 SPEC_EXTR(func->etype) = 1;
230                 seg = SPEC_OCLS( func->etype );
231                 addSet(&seg->syms, func);
232         }
233   }
234
235   addiCodeToeBBlock (ebp, newic, ip);
236 }
237
238 /*-----------------------------------------------------------------*/
239 /* cnvToFloatCast - converts casts to floats to function calls     */
240 /*-----------------------------------------------------------------*/
241 static void
242 cnvToFloatCast (iCode * ic, eBBlock * ebp)
243 {
244   iCode *ip, *newic;
245   symbol *func = NULL;
246   sym_link *type = operandType (IC_RIGHT (ic));
247   int linenno = ic->lineno;
248   int bwd, su;
249   int bytesPushed=0;
250
251   ip = ic->next;
252   /* remove it from the iCode */
253   remiCodeFromeBBlock (ebp, ic);
254   /* depending on the type */
255   for (bwd = 0; bwd < 3; bwd++)
256     {
257       for (su = 0; su < 2; su++)
258         {
259           if (compareType (type, __multypes[bwd][su]) == 1)
260             {
261               func = __conv[0][bwd][su];
262               goto found;
263             }
264         }
265     }
266
267   if(compareType (type, fixed16x16Type) == 1) {
268     func = __fp16x16conv[0][3][0];
269     goto found;
270   }
271
272   assert (0);
273 found:
274
275   /* if float support routines NOT compiled as reentrant */
276   if (!options.float_rent)
277     {
278       /* first one */
279       if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) 
280         {
281           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
282           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
283         }
284       else
285         {
286           newic = newiCode ('=', NULL, IC_RIGHT (ic));
287           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
288         }
289       addiCodeToeBBlock (ebp, newic, ip);
290       newic->lineno = linenno;
291
292     }
293   else
294     {
295       /* push the left */
296       if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
297         newic = newiCode (SEND, IC_RIGHT (ic), NULL);
298         newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
299       }
300       else
301       {
302         newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
303         newic->parmPush = 1;
304         bytesPushed += getSize(operandType(IC_RIGHT(ic)));
305       }
306       addiCodeToeBBlock (ebp, newic, ip);
307       newic->lineno = linenno;
308
309     }
310
311   /* make the call */
312   newic = newiCode (CALL, operandFromSymbol (func), NULL);
313   IC_RESULT (newic) = IC_RESULT (ic);
314   newic->parmBytes+=bytesPushed;
315   ebp->hasFcall = 1;
316   if (currFunc)
317     FUNC_HASFCALL (currFunc->type) = 1;
318
319   if(TARGET_IS_PIC16) {
320         /* normally these functions aren't marked external, so we can use their
321          * _extern field to marked as already added to symbol table */
322
323         if(!SPEC_EXTR(func->etype)) {
324             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
325                 
326                 SPEC_EXTR(func->etype) = 1;
327                 seg = SPEC_OCLS( func->etype );
328                 addSet(&seg->syms, func);
329         }
330   }
331
332   addiCodeToeBBlock (ebp, newic, ip);
333   newic->lineno = linenno;
334 }
335
336 /*----------------------------------------------------------------------*/
337 /* cnvToFixed16x16Cast - converts casts to fixed16x16 to function calls */
338 /*----------------------------------------------------------------------*/
339 static void 
340 cnvToFixed16x16Cast (iCode * ic, eBBlock * ebp)
341 {
342   iCode *ip, *newic;
343   symbol *func = NULL;
344   sym_link *type = operandType (IC_RIGHT (ic));
345   int linenno = ic->lineno;
346   int bwd, su;
347   int bytesPushed=0;
348
349   ip = ic->next;
350   /* remove it from the iCode */
351   remiCodeFromeBBlock (ebp, ic);
352   /* depending on the type */
353   for (bwd = 0; bwd < 3; bwd++)
354     {
355       for (su = 0; su < 2; su++)
356         {
357           if (compareType (type, __multypes[bwd][su]) == 1)
358             {
359               func = __fp16x16conv[0][bwd][su];
360               goto found;
361             }
362         }
363     }
364   assert (0);
365 found:
366
367   /* if float support routines NOT compiled as reentrant */
368   if (!options.float_rent)
369     {
370       /* first one */
371         if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
372             {
373                 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
374                 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
375             }
376       else
377         {
378           newic = newiCode ('=', NULL, IC_RIGHT (ic));
379           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
380         }
381       addiCodeToeBBlock (ebp, newic, ip);
382       newic->lineno = linenno;
383
384     }
385   else
386     {
387       /* push the left */
388         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
389             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
390             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
391         }
392       else
393         {
394           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
395           newic->parmPush = 1;
396           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
397         }
398       addiCodeToeBBlock (ebp, newic, ip);
399       newic->lineno = linenno;
400
401     }
402
403   /* make the call */
404   newic = newiCode (CALL, operandFromSymbol (func), NULL);
405   IC_RESULT (newic) = IC_RESULT (ic);
406   newic->parmBytes+=bytesPushed;
407   ebp->hasFcall = 1;
408   if (currFunc)
409     FUNC_HASFCALL (currFunc->type) = 1;
410
411   if(TARGET_IS_PIC16) {
412         /* normally these functions aren't marked external, so we can use their
413          * _extern field to marked as already added to symbol table */
414
415         if(!SPEC_EXTR(func->etype)) {
416             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
417
418                 SPEC_EXTR(func->etype) = 1;
419                 seg = SPEC_OCLS( func->etype );
420                 addSet(&seg->syms, func);
421         }
422   }
423
424   addiCodeToeBBlock (ebp, newic, ip);
425   newic->lineno = linenno;
426 }
427
428 /*-----------------------------------------------------------------*/
429 /* cnvFromFloatCast - converts casts From floats to function calls */
430 /*-----------------------------------------------------------------*/
431 static void
432 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
433 {
434   iCode *ip, *newic;
435   symbol *func = NULL;
436   sym_link *type = operandType (IC_LEFT (ic));
437   int lineno = ic->lineno;
438   int bwd, su;
439   int bytesPushed=0;
440
441   ip = ic->next;
442   /* remove it from the iCode */
443   remiCodeFromeBBlock (ebp, ic);
444
445   /* depending on the type */
446   for (bwd = 0; bwd < 3; bwd++)
447     {
448       for (su = 0; su < 2; su++)
449         {
450           if (compareType (type, __multypes[bwd][su]) == 1)
451             {
452               func = __conv[1][bwd][su];
453               goto found;
454             }
455         }
456     }
457   assert (0);
458 found:
459
460   /* if float support routines NOT compiled as reentrant */
461   if (!options.float_rent)
462     {
463       /* first one */
464         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
465             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
466             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
467         }
468       else
469         {
470           newic = newiCode ('=', NULL, IC_RIGHT (ic));
471           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
472         }
473       addiCodeToeBBlock (ebp, newic, ip);
474       newic->lineno = lineno;
475
476     }
477   else
478     {
479
480       /* push the left */
481         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
482             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
483             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
484         }
485       else
486         {
487           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
488           newic->parmPush = 1;
489           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
490         }
491       addiCodeToeBBlock (ebp, newic, ip);
492       newic->lineno = lineno;
493
494     }
495
496   /* make the call */
497   newic = newiCode (CALL, operandFromSymbol (func), NULL);
498   IC_RESULT (newic) = IC_RESULT (ic);
499   newic->parmBytes+=bytesPushed;
500   ebp->hasFcall = 1;
501   if (currFunc)
502     FUNC_HASFCALL (currFunc->type) = 1;
503
504   if(TARGET_IS_PIC16) {
505         /* normally these functions aren't marked external, so we can use their
506          * _extern field to marked as already added to symbol table */
507
508         if(!SPEC_EXTR(func->etype)) {
509             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
510
511                 SPEC_EXTR(func->etype) = 1;
512                 seg = SPEC_OCLS( func->etype );
513                 addSet(&seg->syms, func);
514         }
515   }
516
517   addiCodeToeBBlock (ebp, newic, ip);
518   newic->lineno = lineno;
519 }
520
521 /*--------------------------------------------------------------------------*/
522 /* cnvFromFixed16x16Cast - converts casts from fixed16x16 to function calls */
523 /*--------------------------------------------------------------------------*/
524 static void 
525 cnvFromFixed16x16Cast (iCode * ic, eBBlock * ebp)
526 {
527   iCode *ip, *newic;
528   symbol *func = NULL;
529   sym_link *type = operandType (IC_LEFT (ic));
530   int lineno = ic->lineno;
531   int bwd, su;
532   int bytesPushed=0;
533
534   ip = ic->next;
535   /* remove it from the iCode */
536   remiCodeFromeBBlock (ebp, ic);
537
538   /* depending on the type */
539   for (bwd = 0; bwd < 3; bwd++)
540     {
541       for (su = 0; su < 2; su++)
542         {
543           if (compareType (type, __multypes[bwd][su]) == 1)
544             {
545               func = __fp16x16conv[1][bwd][su];
546               goto found;
547             }
548         }
549     }
550     
551   if (compareType (type, floatType) == 1)
552     {
553       func = __fp16x16conv[1][3][0];
554       goto found;
555     }
556     
557   assert (0);
558 found:
559
560   /* if float support routines NOT compiled as reentrant */
561   if (!options.float_rent)
562     {
563       /* first one */
564         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
565             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
566             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
567         }
568       else
569         {
570           newic = newiCode ('=', NULL, IC_RIGHT (ic));
571           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
572         }
573       addiCodeToeBBlock (ebp, newic, ip);
574       newic->lineno = lineno;
575
576     }
577   else
578     {
579
580       /* push the left */
581         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
582             newic = newiCode (SEND, IC_RIGHT (ic), NULL);
583             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
584         }
585       else
586         {
587           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
588           newic->parmPush = 1;
589           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
590         }
591       addiCodeToeBBlock (ebp, newic, ip);
592       newic->lineno = lineno;
593
594     }
595
596   /* make the call */
597   newic = newiCode (CALL, operandFromSymbol (func), NULL);
598   IC_RESULT (newic) = IC_RESULT (ic);
599   newic->parmBytes+=bytesPushed;
600   ebp->hasFcall = 1;
601   if (currFunc)
602     FUNC_HASFCALL (currFunc->type) = 1;
603
604   if(TARGET_IS_PIC16) {
605         /* normally these functions aren't marked external, so we can use their
606          * _extern field to marked as already added to symbol table */
607
608         if(!SPEC_EXTR(func->etype)) {
609             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
610                 
611                 SPEC_EXTR(func->etype) = 1;
612                 seg = SPEC_OCLS( func->etype );
613                 addSet(&seg->syms, func);
614         }
615   }
616
617   addiCodeToeBBlock (ebp, newic, ip);
618   newic->lineno = lineno;
619 }
620
621 extern operand *geniCodeRValue (operand *, bool);
622
623 /*-----------------------------------------------------------------*/
624 /* convilong - converts int or long mults or divs to fcalls        */
625 /*-----------------------------------------------------------------*/
626 static void
627 convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
628 {
629   symbol *func = NULL;
630   iCode *ip = ic->next;
631   iCode *newic;
632   int lineno = ic->lineno;
633   int bwd;
634   int su;
635   int bytesPushed=0;
636
637   remiCodeFromeBBlock (ebp, ic);
638
639   /* depending on the type */
640   for (bwd = 0; bwd < 3; bwd++)
641     {
642       for (su = 0; su < 2; su++)
643         {
644           if (compareType (type, __multypes[bwd][su]) == 1)
645             {
646               if (op == '*')
647                 func = __muldiv[0][bwd][su];
648               else if (op == '/')
649                 func = __muldiv[1][bwd][su];
650               else if (op == '%')
651                 func = __muldiv[2][bwd][su];
652               else if (op == RRC)
653                 func = __rlrr[1][bwd][su];
654               else if (op == RLC)
655                 func = __rlrr[0][bwd][su];
656               else if (op == RIGHT_OP)
657                 func = __rlrr[1][bwd][su];
658               else if (op == LEFT_OP)
659                 func = __rlrr[0][bwd][su];
660               else
661                 assert (0);
662               goto found;
663             }
664         }
665     }
666   assert (0);
667 found:
668   /* if int & long support routines NOT compiled as reentrant */
669   if (!options.intlong_rent)
670     {
671       /* first one */
672         if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
673             newic = newiCode (SEND, IC_LEFT (ic), NULL);
674             newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
675         }
676       else
677         {
678           newic = newiCode ('=', NULL, IC_LEFT (ic));
679           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
680         }
681       addiCodeToeBBlock (ebp, newic, ip);
682       newic->lineno = lineno;
683
684       /* second one */
685       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
686           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
687           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
688       }
689       else
690         {
691           newic = newiCode ('=', NULL, IC_RIGHT (ic));
692           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
693         }
694       addiCodeToeBBlock (ebp, newic, ip);
695       newic->lineno = lineno;
696
697     }
698   else
699     {
700       /* compiled as reentrant then push */
701       /* push right */
702       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
703         {
704           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
705           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
706         }
707       else
708         {
709           newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
710           newic->parmPush = 1;
711
712           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
713         }
714       addiCodeToeBBlock (ebp, newic, ip);
715       newic->lineno = lineno;
716
717       /* insert push left */
718       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
719         {
720           newic = newiCode (SEND, IC_LEFT (ic), NULL);
721           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
722         }
723       else
724         {
725           newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
726           newic->parmPush = 1;
727
728           bytesPushed += getSize(operandType(IC_LEFT(ic)));
729         }
730       addiCodeToeBBlock (ebp, newic, ip);
731       newic->lineno = lineno;
732
733     }
734
735   /* for the result */
736   newic = newiCode (CALL, operandFromSymbol (func), NULL);
737   IC_RESULT (newic) = IC_RESULT (ic);
738   newic->lineno = lineno;
739   newic->parmBytes+=bytesPushed; // to clear the stack after the call
740   ebp->hasFcall = 1;
741   if (currFunc)
742     FUNC_HASFCALL (currFunc->type) = 1;
743
744   if(TARGET_IS_PIC16) {
745         /* normally these functions aren't marked external, so we can use their
746          * _extern field to marked as already added to symbol table */
747
748         if(!SPEC_EXTR(func->etype)) {
749             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
750
751                 SPEC_EXTR(func->etype) = 1;
752                 seg = SPEC_OCLS( func->etype );
753                 addSet(&seg->syms, func);
754         }
755   }
756
757   addiCodeToeBBlock (ebp, newic, ip);
758 }
759
760 /*-----------------------------------------------------------------*/
761 /* convertToFcall - converts some operations to fcalls             */
762 /*-----------------------------------------------------------------*/
763 static void
764 convertToFcall (eBBlock ** ebbs, int count)
765 {
766   int i;
767
768   /* for all blocks do */
769   for (i = 0; i < count; i++)
770     {
771       iCode *ic;
772
773       /* for all instructions in the block do */
774       for (ic = ebbs[i]->sch; ic; ic = ic->next)
775         {
776
777           /* floating point operations are
778              converted to function calls */
779           if ((IS_CONDITIONAL (ic) ||
780                IS_ARITHMETIC_OP (ic)) &&
781               (IS_FLOAT (operandType (IC_RIGHT (ic)))
782                 || IS_FIXED( operandType (IC_RIGHT (ic)))))
783             {
784
785               cnvToFcall (ic, ebbs[i]);
786             }
787
788           /* casting is a little different */
789           if (ic->op == CAST)
790             {
791               if (IS_FLOAT (operandType (IC_RIGHT (ic))))
792                 cnvFromFloatCast (ic, ebbs[i]);
793               else if (IS_FLOAT (operandType (IC_LEFT (ic))))
794                 cnvToFloatCast (ic, ebbs[i]);
795               if (IS_FIXED16X16 (operandType (IC_RIGHT (ic))))
796                 cnvFromFixed16x16Cast (ic, ebbs[i]);
797               else if (IS_FIXED16X16 (operandType (IC_LEFT (ic))))
798                 cnvToFixed16x16Cast (ic, ebbs[i]);
799             }
800
801           // Easy special case which avoids function call: modulo by a literal power
802           // of two can be replaced by a bitwise AND.
803           if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
804               IS_UNSIGNED(operandType(IC_LEFT(ic))))
805             {
806               unsigned litVal = fabs(operandLitValue(IC_RIGHT(ic)));
807
808               /* modulo by 1: no remainder */
809               if (litVal == 1)
810                 {
811                   ic->op = '=';
812                   IC_RIGHT (ic) = operandFromLit(0);
813                   IC_LEFT (ic) = NULL;
814                   continue;
815                 }
816               // See if literal value is a power of 2.
817               while (litVal && !(litVal & 1))
818                 {
819                   litVal >>= 1;
820                 }
821               if (litVal)
822                 {
823                   // discard lowest set bit.
824                   litVal >>= 1;
825                 }
826
827               if (!litVal)
828                 {
829                   ic->op = BITWISEAND;
830                   IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
831                   continue;
832                 }
833             }
834
835           /* if long / int mult or divide or mod */
836           if (ic->op == '*' || ic->op == '/' || ic->op == '%')
837             {
838               sym_link *leftType = operandType (IC_LEFT (ic));
839
840               if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
841                 {
842                   sym_link *rightType = operandType (IC_RIGHT (ic));
843
844                   if (port->hasNativeMulFor != NULL &&
845                       port->hasNativeMulFor (ic, leftType, rightType))
846                     {
847                       /* Leave as native */
848                     }
849                   else
850                     {
851                       convilong (ic, ebbs[i], leftType, ic->op);
852                     }
853                 }
854             }
855
856           if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
857             {
858               sym_link *type = operandType (IC_LEFT (ic));
859
860               if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
861                 {
862                   convilong (ic, ebbs[i], type, ic->op);
863                 }
864             }
865         }
866     }
867 }
868
869 /*-----------------------------------------------------------------*/
870 /* isLocalWithoutDef - return 1 if sym might be used without a     */
871 /*                     defining iCode                              */
872 /*-----------------------------------------------------------------*/
873 static int
874 isLocalWithoutDef (symbol * sym)
875 {
876   if (!IS_AUTO (sym))
877     return 0;
878
879   if (IS_VOLATILE (sym->type))
880     return 0;
881
882   if (sym->_isparm)
883     return 0;
884
885   if (IS_AGGREGATE (sym->type))
886     return 0;
887
888   if (sym->addrtaken)
889     return 0;
890
891   return !sym->defs;
892 }
893
894 /*-----------------------------------------------------------------*/
895 /* replaceRegEqv - replace all local variables with their reqv     */
896 /*-----------------------------------------------------------------*/
897 static void
898 replaceRegEqv (ebbIndex * ebbi)
899 {
900   eBBlock ** ebbs = ebbi->bbOrder;
901   int count = ebbi->count;
902   int i;
903
904   /* Update the symbols' def bitvector so we know if there is   */
905   /* a defining iCode or not. Only replace a local variable     */
906   /* with its register equivalent if there is a defining iCode; */
907   /* otherwise, the port's register allocater may choke.        */
908   cseAllBlocks (ebbi, TRUE);
909
910   for (i = 0; i < count; i++)
911     {
912
913       iCode *ic;
914
915       for (ic = ebbs[i]->sch; ic; ic = ic->next)
916         {
917
918           if (SKIP_IC2 (ic))
919             continue;
920
921           if (ic->op == IFX)
922             {
923               if (IC_COND (ic) &&
924                   IS_TRUE_SYMOP (IC_COND (ic)) &&
925                   isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
926                 {
927                   werrorfl (ic->filename, ic->lineno,
928                           W_LOCAL_NOINIT,
929                           OP_SYMBOL (IC_COND (ic))->name);
930                   OP_REQV (IC_COND (ic)) = NULL;
931                   OP_SYMBOL (IC_COND (ic))->allocreq = 1;
932                 }
933
934               if (IS_TRUE_SYMOP (IC_COND (ic)) &&
935                   OP_REQV (IC_COND (ic)))
936                 IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
937                                              OP_SYMBOL (IC_COND (ic))->defs,
938                                             OP_SYMBOL (IC_COND (ic))->uses);
939
940               continue;
941             }
942
943
944           if (ic->op == JUMPTABLE)
945             {
946               if (IC_JTCOND (ic) &&
947                   IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
948                   isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
949                 {
950                   werrorfl (ic->filename, ic->lineno,
951                           W_LOCAL_NOINIT,
952                           OP_SYMBOL (IC_JTCOND (ic))->name);
953                   OP_REQV (IC_JTCOND (ic)) = NULL;
954                   OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
955                 }
956
957               if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
958                   OP_REQV (IC_JTCOND (ic)))
959                 IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
960                                            OP_SYMBOL (IC_JTCOND (ic))->defs,
961                                           OP_SYMBOL (IC_JTCOND (ic))->uses);
962               continue;
963             }
964
965           if (ic->op == RECEIVE)
966             {
967               if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
968                 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
969             }
970
971           /* general case */
972           if (IC_RESULT (ic) &&
973               IS_TRUE_SYMOP (IC_RESULT (ic)) &&
974               OP_REQV (IC_RESULT (ic)))
975             {
976               if (POINTER_SET (ic))
977                 {
978                   IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
979                                            OP_SYMBOL (IC_RESULT (ic))->defs,
980                                           OP_SYMBOL (IC_RESULT (ic))->uses);
981                   IC_RESULT (ic)->isaddr = 1;
982                 }
983               else
984                 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
985                                            OP_SYMBOL (IC_RESULT (ic))->defs,
986                                           OP_SYMBOL (IC_RESULT (ic))->uses);
987             }
988
989           if (IC_RIGHT (ic) &&
990               IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
991               isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
992             {
993               werrorfl (ic->filename, ic->lineno,
994                         W_LOCAL_NOINIT,
995                         OP_SYMBOL (IC_RIGHT (ic))->name);
996               OP_REQV (IC_RIGHT (ic)) = NULL;
997               OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
998             }
999
1000           if (IC_RIGHT (ic) &&
1001               IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
1002               OP_REQV (IC_RIGHT (ic)))
1003             {
1004               IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
1005                                             OP_SYMBOL (IC_RIGHT (ic))->defs,
1006                                            OP_SYMBOL (IC_RIGHT (ic))->uses);
1007               IC_RIGHT (ic)->isaddr = 0;
1008             }
1009
1010           if (IC_LEFT (ic) &&
1011               IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1012               isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
1013             {
1014               werrorfl (ic->filename, ic->lineno,
1015                         W_LOCAL_NOINIT,
1016                         OP_SYMBOL (IC_LEFT (ic))->name);
1017               OP_REQV (IC_LEFT (ic)) = NULL;
1018               OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
1019             }
1020
1021           if (IC_LEFT (ic) &&
1022               IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1023               OP_REQV (IC_LEFT (ic)))
1024             {
1025               IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
1026                                              OP_SYMBOL (IC_LEFT (ic))->defs,
1027                                              OP_SYMBOL (IC_LEFT (ic))->uses);
1028               IC_LEFT (ic)->isaddr = 0;
1029             }
1030         }
1031     }
1032 }
1033
1034 /*-----------------------------------------------------------------*/
1035 /* findReqv - search for a register equivalent                     */
1036 /*-----------------------------------------------------------------*/
1037 operand *
1038 findReqv (symbol * prereqv, eBBlock ** ebbs, int count)
1039 {
1040   int i;
1041   iCode * ic;
1042
1043   /* for all blocks do */
1044   for (i=0; i<count; i++)
1045     {
1046       /* for all instructions in the block do */
1047       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1048         {
1049           if (ic->op == IFX)
1050             {
1051               if (IS_ITEMP (IC_COND (ic))
1052                   && OP_SYMBOL (IC_COND (ic))->prereqv == prereqv)
1053                 return IC_COND (ic);
1054             }
1055           else if (ic->op == JUMPTABLE)
1056             {
1057               if (IS_ITEMP (IC_JTCOND (ic))
1058                   && OP_SYMBOL (IC_JTCOND (ic))->prereqv == prereqv)
1059                 return IC_JTCOND (ic);
1060             }
1061           else
1062             {
1063               if (IS_ITEMP (IC_LEFT (ic))
1064                   && OP_SYMBOL (IC_LEFT (ic))->prereqv == prereqv)
1065                 return IC_LEFT (ic);
1066               if (IS_ITEMP (IC_RIGHT (ic))
1067                   && OP_SYMBOL (IC_RIGHT (ic))->prereqv == prereqv)
1068                 return IC_RIGHT (ic);
1069               if (IS_ITEMP (IC_RESULT (ic))
1070                   && OP_SYMBOL (IC_RESULT (ic))->prereqv == prereqv)
1071                 return IC_RESULT (ic);
1072             }
1073         }
1074     }
1075
1076   return NULL;
1077 }
1078
1079 /*-----------------------------------------------------------------*/
1080 /* killDeadCode - eliminates dead assignments                      */
1081 /*-----------------------------------------------------------------*/
1082 int
1083 killDeadCode (ebbIndex * ebbi)
1084 {
1085   eBBlock ** ebbs = ebbi->dfOrder;
1086   int count = ebbi->count;
1087   int change = 1;
1088   int gchange = 0;
1089   int i = 0;
1090
1091
1092   /* basic algorithm :-                                          */
1093   /* first the exclusion rules :-                                */
1094   /*  1. if result is a global or volatile then skip             */
1095   /*  2. if assignment and result is a temp & isaddr  then skip  */
1096   /*     since this means array & pointer access, will be taken  */
1097   /*     care of by alias analysis.                              */
1098   /*  3. if the result is used in the remainder of the block skip */
1099   /*  4. if this definition does not reach the end of the block  */
1100   /*     i.e. the result is not present in the outExprs then KILL */
1101   /*  5. if it reaches the end of block & is used by some success */
1102   /*     or then skip                                            */
1103   /*     else            KILL                                    */
1104   /* this whole process is carried on iteratively till no change */
1105   while (1)
1106     {
1107
1108       change = 0;
1109       /* for all blocks do */
1110       for (i = 0; i < count; i++)
1111         {
1112           iCode *ic;
1113
1114           /* for all instructions in the block do */
1115           for (ic = ebbs[i]->sch; ic; ic = ic->next)
1116             {
1117               int kill, j;
1118               kill = 0;
1119
1120               if (SKIP_IC (ic) ||
1121                   ic->op == IFX ||
1122                   ic->op == RETURN ||
1123                   ic->op == DUMMY_READ_VOLATILE ||
1124                   ic->op == CRITICAL ||
1125                   ic->op == ENDCRITICAL)
1126                 continue;
1127
1128               /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
1129               /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are  */
1130               /* valid. */
1131
1132               /* if the result is volatile then continue */
1133               if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
1134                 continue;
1135
1136               /* if the result is a temp & isaddr then skip */
1137               if (IC_RESULT (ic) && POINTER_SET (ic))
1138                 continue;
1139
1140               if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
1141                   && !SPIL_LOC (IC_RESULT (ic)))
1142                 continue;
1143
1144               /* if the result is used in the remainder of the */
1145               /* block then skip */
1146               if (usedInRemaining (IC_RESULT (ic), ic->next))
1147                 continue;
1148
1149               /* does this definition reach the end of the block
1150                  or the usage is zero then we can kill */
1151               if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
1152                 kill = 1;       /* if not we can kill it */
1153               else
1154                 {
1155                   /* if this is a global variable or function parameter */
1156                   /* we cannot kill anyway             */
1157                   if (isOperandGlobal (IC_RESULT (ic)) ||
1158                       (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1159                        !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
1160                     continue;
1161
1162                   /* if we are sure there are no usages */
1163                   if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
1164                     {
1165                       kill = 1;
1166                       goto kill;
1167                     }
1168
1169                   /* reset visited flag */
1170                   for (j = 0; j < count; ebbs[j++]->visited = 0);
1171
1172                   /* find out if this definition is alive */
1173                   if (applyToSet (ebbs[i]->succList,
1174                                   isDefAlive,
1175                                   ic))
1176                     continue;
1177
1178                   kill = 1;
1179                 }
1180
1181             kill:
1182               /* kill this one if required */
1183               if (kill)
1184                 {
1185                   bool volLeft = IS_SYMOP (IC_LEFT (ic))
1186                                  && isOperandVolatile (IC_LEFT (ic), FALSE);
1187                   bool volRight = IS_SYMOP (IC_RIGHT (ic))
1188                                   && isOperandVolatile (IC_RIGHT (ic), FALSE);
1189
1190                   /* a dead address-of operation should die, even if volatile */
1191                   if (ic->op == ADDRESS_OF)
1192                     volLeft = FALSE;
1193
1194                   if (ic->next && ic->seqPoint == ic->next->seqPoint
1195                       && (ic->next->op == '+' || ic->next->op == '-'))
1196                     {
1197                       if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
1198                           || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
1199                         volLeft = FALSE;
1200                       if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
1201                           || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
1202                         volRight = FALSE;
1203                     }
1204
1205                   if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
1206                     {
1207                       if (SPIL_LOC (IC_RESULT (ic)))
1208                         {
1209                           IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
1210                           SPIL_LOC (IC_RESULT (ic)) = NULL;
1211                         }
1212                       continue;
1213                     }
1214
1215                   change = 1;
1216                   gchange++;
1217
1218                   /* now delete from defUseSet */
1219                   deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
1220                   bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
1221
1222                   /* and defset of the block */
1223                   bitVectUnSetBit (ebbs[i]->defSet, ic->key);
1224
1225                   /* If this is the last of a register equivalent, */
1226                   /* look for a successor register equivalent. */
1227                   bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1228                   if (IS_ITEMP (IC_RESULT (ic))
1229                       && OP_SYMBOL (IC_RESULT (ic))->isreqv
1230                       && bitVectIsZero (OP_DEFS (IC_RESULT (ic))))
1231                     {
1232                       symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
1233                       symbol * prereqv = resultsym->prereqv;
1234
1235                       if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
1236                         {
1237                           operand * newreqv;
1238
1239                           IC_RESULT (ic) = NULL;
1240                           newreqv = findReqv (prereqv, ebbs, count);
1241                           if (newreqv)
1242                             {
1243                               prereqv->reqv = newreqv;
1244                             }
1245                         }
1246                     }
1247
1248                   /* delete the result */
1249                   IC_RESULT (ic) = NULL;
1250
1251                   if (volLeft || volRight)
1252                     {
1253                       /* something is volatile, so keep the iCode */
1254                       /* and change the operator instead */
1255                       ic->op = DUMMY_READ_VOLATILE;
1256
1257                       /* keep only the volatile operands */
1258                       if (!volLeft)
1259                         IC_LEFT (ic) = NULL;
1260                       if (!volRight)
1261                         IC_RIGHT (ic) = NULL;
1262                     }
1263                   else
1264                     {
1265                       /* nothing is volatile, eliminate the iCode */
1266                       remiCodeFromeBBlock (ebbs[i], ic);
1267
1268                       /* for the left & right remove the usage */
1269                       if (IS_SYMOP (IC_LEFT (ic)))
1270                         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1271
1272                       if (IS_SYMOP (IC_RIGHT (ic)))
1273                         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1274                     }
1275                 }
1276
1277             }                   /* end of all instructions */
1278
1279           if (!ebbs[i]->sch && !ebbs[i]->noPath)
1280             disconBBlock (ebbs[i], ebbi);
1281
1282         }                       /* end of for all blocks */
1283
1284       if (!change)
1285         break;
1286     }                           /* end of while(1) */
1287
1288   return gchange;
1289 }
1290
1291 /*-----------------------------------------------------------------*/
1292 /* printCyclomatic - prints the cyclomatic information             */
1293 /*-----------------------------------------------------------------*/
1294 static void
1295 printCyclomatic (eBBlock ** ebbs, int count)
1296 {
1297   int nEdges = elementsInSet (graphEdges);
1298   int i, nNodes = 0;
1299
1300   for (i = 0; i < count; i++)
1301     nNodes += (!ebbs[i]->noPath);
1302
1303   /* print the information */
1304   werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
1305 }
1306
1307 /*-----------------------------------------------------------------*/
1308 /* discardDeadParamReceives - remove any RECEIVE opcodes which     */
1309 /* refer to dead variables.                                        */
1310 /*-----------------------------------------------------------------*/
1311 static void
1312 discardDeadParamReceives (eBBlock ** ebbs, int count)
1313 {
1314   int i;
1315   iCode *ic;
1316   iCode dummyIcode;
1317
1318   for (i = 0; i < count; i++)
1319     {
1320       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1321         {
1322           if (ic->op == RECEIVE)
1323             {
1324               if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
1325                   && !OP_SYMBOL (IC_RESULT (ic))->used)
1326                 {
1327 #if 0
1328                   fprintf (stderr, "discarding dead receive for %s\n",
1329                            OP_SYMBOL (IC_RESULT (ic))->name);
1330 #endif
1331                   dummyIcode.next = ic->next;
1332                   remiCodeFromeBBlock (ebbs[i], ic);
1333                   ic = &dummyIcode;
1334                 }
1335             }
1336         }
1337     }
1338 }
1339
1340 /*-----------------------------------------------------------------*/
1341 /* optimizeCastCast - remove unneeded intermediate casts.          */
1342 /* Integer promotion may cast (un)signed char to int and then      */
1343 /* recast the int to (un)signed long. If the signedness of the     */
1344 /* char and long are the same, the cast can be safely performed in */
1345 /* a single step.                                                  */
1346 /*-----------------------------------------------------------------*/
1347 static void
1348 optimizeCastCast (eBBlock ** ebbs, int count)
1349 {
1350   int i;
1351   iCode *ic;
1352   iCode *uic;
1353   sym_link * type1;
1354   sym_link * type2;
1355   sym_link * type3;
1356   symbol * sym;
1357
1358   for (i = 0; i < count; i++)
1359     {
1360       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1361         {
1362
1363           if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
1364             {
1365               type1 = operandType (IC_RIGHT (ic));
1366               type2 = operandType (IC_RESULT (ic));
1367
1368               /* Look only for a cast from an integer type to an */
1369               /* integer type that has no loss of bits */
1370               if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2))
1371                 continue;
1372               if (getSize (type2) < getSize (type1))
1373                 continue;
1374
1375               /* There must be only one use of this first result */
1376               if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
1377                 continue;
1378
1379               /* This use must be a second cast */
1380               uic = hTabItemWithKey (iCodehTab,
1381                         bitVectFirstBit (OP_USES (IC_RESULT (ic))));
1382               if (!uic || uic->op != CAST)
1383                 continue;
1384
1385               /* It must be a cast to another integer type that */
1386               /* has no loss of bits */
1387               type3 = operandType (IC_RESULT (uic));
1388               if (!IS_INTEGRAL (type3))
1389                  continue;
1390               if (getSize (type3) < getSize (type2))
1391                  continue;
1392
1393               /* The signedness between the first and last types */
1394               /* must match */
1395               if (SPEC_USIGN (type3) != SPEC_USIGN (type1))
1396                  continue;
1397
1398               /* Change the first cast to a simple assignment and */
1399               /* let the second cast do all the work */
1400               ic->op = '=';
1401               IC_LEFT (ic) = NULL;
1402               sym = OP_SYMBOL (IC_RESULT (ic));
1403               sym->type = copyLinkChain (type1);
1404               sym->etype = getSpec (sym->type);
1405             }
1406         }
1407     }
1408 }
1409
1410 /*-----------------------------------------------------------------*/
1411 /* eBBlockFromiCode - creates extended basic blocks from iCode     */
1412 /*                    will return an array of eBBlock pointers     */
1413 /*-----------------------------------------------------------------*/
1414 eBBlock **
1415 eBBlockFromiCode (iCode * ic)
1416 {
1417   ebbIndex *ebbi = NULL;
1418   int change = 1;
1419   int lchange = 0;
1420   int kchange = 0;
1421   hTab *loops;
1422
1423   /* if nothing passed then return nothing */
1424   if (!ic)
1425     return NULL;
1426
1427   eBBNum = 0;
1428
1429   /* optimize the chain for labels & gotos
1430      this will eliminate redundant labels and
1431      will change jump to jumps by jumps */
1432   ic = iCodeLabelOptimize (ic);
1433
1434   /* break it down into basic blocks */
1435   ebbi = iCodeBreakDown (ic);
1436
1437   /* hash the iCode keys so that we can quickly index */
1438   /* them in the rest of the optimization steps */
1439   setToNull ((void *) &iCodehTab);
1440   iCodehTab = newHashTable (iCodeKey);
1441   hashiCodeKeys (ebbi->bbOrder, ebbi->count);
1442
1443   /* compute the control flow */
1444   computeControlFlow (ebbi);
1445
1446   /* dumpraw if asked for */
1447   if (options.dump_raw)
1448     dumpEbbsToFileExt (DUMP_RAW0, ebbi);
1449
1450   /* replace the local variables with their
1451      register equivalents : the liveRange computation
1452      along with the register allocation will determine 
1453      if it finally stays in the registers */
1454   replaceRegEqv (ebbi);
1455
1456   /* create loop regions */
1457   loops = createLoopRegions (ebbi);
1458
1459   /* dumpraw if asked for */
1460   if (options.dump_raw)
1461     dumpEbbsToFileExt (DUMP_RAW1, ebbi);
1462
1463   optimizeCastCast (ebbi->bbOrder, ebbi->count);
1464
1465   /* do common subexpression elimination for each block */
1466   change = cseAllBlocks (ebbi, FALSE);
1467
1468   /* dumpraw if asked for */
1469   if (options.dump_raw)
1470     dumpEbbsToFileExt (DUMP_CSE, ebbi);
1471
1472   /* compute the data flow */
1473   computeDataFlow (ebbi);
1474
1475   /* dumpraw if asked for */
1476   if (options.dump_raw)
1477     dumpEbbsToFileExt (DUMP_DFLOW, ebbi);
1478
1479   /* global common subexpression elimination  */
1480   if (optimize.global_cse)
1481     {
1482       change += cseAllBlocks (ebbi, FALSE);
1483       if (options.dump_gcse)
1484         dumpEbbsToFileExt (DUMP_GCSE, ebbi);
1485     }
1486   else
1487     {
1488       // compute the dataflow only
1489       assert(cseAllBlocks (ebbi, TRUE)==0);
1490     }
1491   /* kill dead code */
1492   kchange = killDeadCode (ebbi);
1493
1494   if (options.dump_kill)
1495     dumpEbbsToFileExt (DUMP_DEADCODE, ebbi);
1496
1497   /* do loop optimizations */
1498   change += (lchange = loopOptimizations (loops, ebbi));
1499   if (options.dump_loop)
1500     dumpEbbsToFileExt (DUMP_LOOP, ebbi);
1501
1502   /* recompute the data flow and apply global cse again
1503      if loops optimizations or dead code caused a change:
1504      loops will brings out of the loop which then may be
1505      available for use in the later blocks: dead code
1506      elimination could potentially disconnect some blocks
1507      conditional flow may be efected so we need to apply
1508      subexpression once more */
1509   if (lchange || kchange)
1510     {
1511       computeDataFlow (ebbi);
1512       change += cseAllBlocks (ebbi, FALSE);
1513       if (options.dump_loop)
1514         dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
1515
1516       /* if loop optimizations caused a change then do
1517          dead code elimination once more : this will
1518          get rid of the extra assignments to the induction
1519          variables created during loop optimizations */
1520       killDeadCode (ebbi);
1521
1522       if (options.dump_loop)
1523         dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
1524
1525     }
1526
1527   /* sort it back by block number */
1528   //qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
1529
1530   if (!options.lessPedantic) {
1531     // this is a good place to check missing return values
1532     if (currFunc) {
1533       // the user is on his own with naked functions...
1534       if (!IS_VOID(currFunc->etype)
1535        && !FUNC_ISNAKED(currFunc->type)) {
1536         eBBlock *bp;
1537         // make sure all predecessors of the last block end in a return
1538         for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList); 
1539              bp;
1540              bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
1541           if (bp->ech->op != RETURN) {
1542             werrorfl (bp->ech->filename, bp->ech->lineno,
1543                       W_VOID_FUNC, currFunc->name);
1544           }
1545         }
1546       }
1547     }
1548   }
1549
1550   /* if cyclomatic info requested then print it */
1551   if (options.cyclomatic)
1552     printCyclomatic (ebbi->bbOrder, ebbi->count);
1553
1554   /* convert operations with support routines
1555      written in C to function calls : I am doing
1556      this at this point since I want all the
1557      operations to be as they are for optimzations */
1558   convertToFcall (ebbi->bbOrder, ebbi->count);
1559
1560   /* compute the live ranges */
1561   computeLiveRanges (ebbi->bbOrder, ebbi->count);
1562
1563   if (options.dump_range)
1564     dumpEbbsToFileExt (DUMP_RANGE, ebbi);
1565
1566   /* Now that we have the live ranges, discard parameter
1567    * receives for unused parameters.
1568    */
1569   discardDeadParamReceives (ebbi->bbOrder, ebbi->count);
1570
1571   /* allocate registers & generate code */
1572   port->assignRegisters (ebbi);
1573
1574   /* throw away blocks */
1575   setToNull ((void *) &graphEdges);
1576
1577   return NULL;
1578 }
1579
1580
1581 /* (add-hook 'c-mode-hook (lambda () (setq c-basic-offset 4))) */