* src/*.c, src/pic16/{gen.c,glue.c,main.c}: applied Vangelis
[fw/sdcc] / src / SDCCicode.c
1 /*-------------------------------------------------------------------------
2
3   SDCCicode.c - intermediate code generation etc.
4                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #include "common.h"
26 #include "newalloc.h"
27 #include "math.h"
28
29 /*-----------------------------------------------------------------*/
30 /* global variables       */
31
32 set *iCodeChain = NULL;
33 int iTempNum = 0;
34 int iTempLblNum = 0;
35 int operandKey = 0;
36 int iCodeKey = 0;
37 char *filename;
38 int lineno;
39 int block;
40 int scopeLevel;
41 int seqPoint;
42
43 symbol *returnLabel;            /* function return label */
44 symbol *entryLabel;             /* function entry  label */
45
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeAssign (operand *, operand *, int, int);
49 static operand *geniCodeArray (operand *, operand *,int);
50 static operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
54 void  setOClass (sym_link * ptr, sym_link * spec);
55 static operand *geniCodeCast (sym_link *, operand *, bool);
56
57 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
58 /* forward definition of ic print functions */
59 PRINTFUNC (picGetValueAtAddr);
60 PRINTFUNC (picSetValueAtAddr);
61 PRINTFUNC (picAddrOf);
62 PRINTFUNC (picGeneric);
63 PRINTFUNC (picGenericOne);
64 PRINTFUNC (picCast);
65 PRINTFUNC (picAssign);
66 PRINTFUNC (picLabel);
67 PRINTFUNC (picGoto);
68 PRINTFUNC (picIfx);
69 PRINTFUNC (picJumpTable);
70 PRINTFUNC (picInline);
71 PRINTFUNC (picReceive);
72 PRINTFUNC (picDummyRead);
73 PRINTFUNC (picCritical);
74 PRINTFUNC (picEndCritical);
75
76 iCodeTable codeTable[] =
77 {
78   {'!', "not", picGenericOne, NULL},
79   {'~', "~", picGenericOne, NULL},
80   {RRC, "rrc", picGenericOne, NULL},
81   {RLC, "rlc", picGenericOne, NULL},
82   {GETHBIT, "ghbit", picGenericOne, NULL},
83   {UNARYMINUS, "-", picGenericOne, NULL},
84   {IPUSH, "push", picGenericOne, NULL},
85   {IPOP, "pop", picGenericOne, NULL},
86   {CALL, "call", picGenericOne, NULL},
87   {PCALL, "pcall", picGenericOne, NULL},
88   {FUNCTION, "proc", picGenericOne, NULL},
89   {ENDFUNCTION, "eproc", picGenericOne, NULL},
90   {RETURN, "ret", picGenericOne, NULL},
91   {'+', "+", picGeneric, NULL},
92   {'-', "-", picGeneric, NULL},
93   {'*', "*", picGeneric, NULL},
94   {'/', "/", picGeneric, NULL},
95   {'%', "%", picGeneric, NULL},
96   {'>', ">", picGeneric, NULL},
97   {'<', "<", picGeneric, NULL},
98   {LE_OP, "<=", picGeneric, NULL},
99   {GE_OP, ">=", picGeneric, NULL},
100   {EQ_OP, "==", picGeneric, NULL},
101   {NE_OP, "!=", picGeneric, NULL},
102   {AND_OP, "&&", picGeneric, NULL},
103   {OR_OP, "||", picGeneric, NULL},
104   {'^', "^", picGeneric, NULL},
105   {'|', "|", picGeneric, NULL},
106   {BITWISEAND, "&", picGeneric, NULL},
107   {LEFT_OP, "<<", picGeneric, NULL},
108   {RIGHT_OP, ">>", picGeneric, NULL},
109   {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110   {ADDRESS_OF, "&", picAddrOf, NULL},
111   {CAST, "<>", picCast, NULL},
112   {'=', ":=", picAssign, NULL},
113   {LABEL, "", picLabel, NULL},
114   {GOTO, "", picGoto, NULL},
115   {JUMPTABLE, "jtab", picJumpTable, NULL},
116   {IFX, "if", picIfx, NULL},
117   {INLINEASM, "", picInline, NULL},
118   {RECEIVE, "recv", picReceive, NULL},
119   {SEND, "send", picGenericOne, NULL},
120   {ARRAYINIT, "arrayInit", picGenericOne, NULL},
121   {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
122   {CRITICAL, "critical_start", picCritical, NULL},
123   {ENDCRITICAL, "critical_end", picEndCritical, NULL},
124   {SWAP, "swap", picGenericOne, NULL}
125 };
126
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type           */
129 /*-----------------------------------------------------------------*/
130
131
132 /*   pedantic=0: allmost anything is allowed as long as the absolute
133        value is within the bit range of the type, and -1 is treated as
134        0xf..f for unsigned types (e.g. in assign)
135      pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136      pedantic>1: "char c=200" is not allowed (evaluates to -56)
137 */
138
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
140                         int pedantic) {
141   double max;
142   int warnings=0;
143   int negative=0;
144   long v;
145
146   max = pow ((double)2.0, (double)bitsForType(ltype));
147
148   if (IS_LONG(val->type)) {
149     if (IS_UNSIGNED(val->type)) {
150       v=SPEC_CVAL(val->type).v_ulong;
151     } else {
152       v=SPEC_CVAL(val->type).v_long;
153     }
154   } else {
155     if (IS_UNSIGNED(val->type)) {
156       v=SPEC_CVAL(val->type).v_uint;
157     } else {
158       v=SPEC_CVAL(val->type).v_int;
159     }
160   }
161
162
163 #if 0
164   // this could be a good idea
165   if (options.pedantic)
166     pedantic=2;
167 #endif
168
169   if (IS_FLOAT(ltype)) {
170     // anything will do
171     return;
172   }
173
174   if (IS_FIXED(ltype)) {
175     // anything will do
176     return;
177   }
178
179   if (!IS_UNSIGNED(val->type) && v<0) {
180     negative=1;
181     if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182       warnings++;
183     }
184     v=-v;
185   }
186
187   // if very pedantic: "char c=200" is not allowed
188   if (pedantic>1 && !IS_UNSIGNED(ltype)) {
189     max = max/2 + negative;
190   }
191
192   if (v >= max) {
193     warnings++;
194   }
195
196 #if 0 // temporary disabled, leaving the warning as a reminder
197   if (warnings) {
198     SNPRINTF (message, sizeof(message), "for %s %s in %s",
199              IS_UNSIGNED(ltype) ? "unsigned" : "signed",
200              nounName(ltype), msg);
201     werror (W_CONST_RANGE, message);
202
203     if (pedantic>1)
204       fatalError++;
205   }
206 #endif
207 }
208
209 /*-----------------------------------------------------------------*/
210 /* operandName - returns the name of the operand                   */
211 /*-----------------------------------------------------------------*/
212 int
213 printOperand (operand * op, FILE * file)
214 {
215   sym_link *opetype;
216   int pnl = 0;
217
218   if (!op)
219     return 1;
220
221   if (!file)
222     {
223       file = stdout;
224       pnl = 1;
225     }
226   switch (op->type)
227     {
228
229     case VALUE:
230       opetype = getSpec (operandType (op));
231       if (IS_FLOAT (opetype))
232         fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
233       if (IS_FIXED16X16 (opetype))
234         fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
235       else
236         fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
237       printTypeChain (operandType (op), file);
238       fprintf (file, "}");
239       break;
240
241     case SYMBOL:
242 #define REGA 1
243 //#if REGA      /* { */
244     if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
245       fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}",           /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
246                (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
247                op->key,
248                OP_LIVEFROM (op), OP_LIVETO (op),
249                OP_SYMBOL (op)->stack,
250                op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
251                OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
252                OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
253         );
254       {
255         fprintf (file, "{");
256         printTypeChain (operandType (op), file);
257         if (SPIL_LOC (op) && IS_ITEMP (op))
258           fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
259         fprintf (file, "}");
260
261       }
262
263       /* if assigned to registers */
264       if (OP_SYMBOL (op)->nRegs)
265         {
266           if (OP_SYMBOL (op)->isspilt)
267             {
268               if (!OP_SYMBOL (op)->remat)
269                 if (OP_SYMBOL (op)->usl.spillLoc)
270                   fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
271                                        OP_SYMBOL (op)->usl.spillLoc->rname :
272                                        OP_SYMBOL (op)->usl.spillLoc->name));
273                 else
274                   fprintf (file, "[err]");
275               else
276                 fprintf (file, "[remat]");
277             }
278           else
279             {
280               int i;
281               fprintf (file, "[");
282               for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
283                 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
284               fprintf (file, "]");
285             }
286         }
287 //#else         /* } else { */
288     } else {
289       /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
290       fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
291
292       if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
293         {
294           fprintf (file, "[lr%d:%d so:%d]",
295                OP_LIVEFROM (op), OP_LIVETO (op),
296                OP_SYMBOL (op)->stack);
297         }
298
299       if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
300         {
301           fprintf (file, "{");
302           printTypeChain (operandType (op), file);
303           if (SPIL_LOC (op) && IS_ITEMP (op))
304               fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
305           fprintf (file, "}");
306         }
307
308       /* if assigned to registers */
309       if (OP_SYMBOL (op)->nRegs)
310         {
311           if (OP_SYMBOL (op)->isspilt)
312             {
313               if (!OP_SYMBOL (op)->remat)
314                 if (OP_SYMBOL (op)->usl.spillLoc)
315                   fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
316                                        OP_SYMBOL (op)->usl.spillLoc->rname :
317                                        OP_SYMBOL (op)->usl.spillLoc->name));
318                 else
319                   fprintf (file, "[err]");
320               else
321                 fprintf (file, "[remat]");
322             }
323           else
324             {
325               int i;
326               fprintf (file, "[");
327               for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
328                 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
329               fprintf (file, "]");
330             }
331         }
332 //#endif                /* } */
333     }
334       break;
335
336     case TYPE:
337       fprintf (file, "(");
338       printTypeChain (op->operand.typeOperand, file);
339       fprintf (file, ")");
340       break;
341     }
342
343   if (pnl)
344     fprintf (file, "\n");
345   return 0;
346 }
347
348
349 /*-----------------------------------------------------------------*/
350 /*                    print functions                              */
351 /*-----------------------------------------------------------------*/
352 PRINTFUNC (picGetValueAtAddr)
353 {
354   fprintf (of, "\t");
355   printOperand (IC_RESULT (ic), of);
356   fprintf (of, " = ");
357   fprintf (of, "@[");
358   printOperand (IC_LEFT (ic), of);
359   fprintf (of, "]");
360
361   fprintf (of, "\n");
362 }
363
364 PRINTFUNC (picSetValueAtAddr)
365 {
366   fprintf (of, "\t");
367   fprintf (of, "*[");
368   printOperand (IC_LEFT (ic), of);
369   fprintf (of, "] = ");
370   printOperand (IC_RIGHT (ic), of);
371   fprintf (of, "\n");
372 }
373
374 PRINTFUNC (picAddrOf)
375 {
376   fprintf (of, "\t");
377   printOperand (IC_RESULT (ic), of);
378   if (IS_ITEMP (IC_LEFT (ic)))
379     fprintf (of, " = ");
380   else
381     fprintf (of, " = &[");
382   printOperand (IC_LEFT (ic), of);
383   if (IC_RIGHT (ic))
384     {
385       if (IS_ITEMP (IC_LEFT (ic)))
386         fprintf (of, " offsetAdd ");
387       else
388         fprintf (of, " , ");
389       printOperand (IC_RIGHT (ic), of);
390     }
391   if (IS_ITEMP (IC_LEFT (ic)))
392     fprintf (of, "\n");
393   else
394     fprintf (of, "]\n");
395 }
396
397 PRINTFUNC (picJumpTable)
398 {
399   symbol *sym;
400
401   fprintf (of, "\t");
402   fprintf (of, "%s\t", s);
403   printOperand (IC_JTCOND (ic), of);
404   fprintf (of, "\n");
405   for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
406        sym = setNextItem (IC_JTLABELS (ic)))
407     fprintf (of, "\t\t\t%s\n", sym->name);
408 }
409
410 PRINTFUNC (picGeneric)
411 {
412   fprintf (of, "\t");
413   printOperand (IC_RESULT (ic), of);
414   fprintf (of, " = ");
415   printOperand (IC_LEFT (ic), of);
416   fprintf (of, " %s ", s);
417   printOperand (IC_RIGHT (ic), of);
418   fprintf (of, "\n");
419 }
420
421 PRINTFUNC (picGenericOne)
422 {
423   fprintf (of, "\t");
424   if (IC_RESULT (ic))
425     {
426       printOperand (IC_RESULT (ic), of);
427       fprintf (of, " = ");
428     }
429
430   if (IC_LEFT (ic))
431     {
432       fprintf (of, "%s ", s);
433       printOperand (IC_LEFT (ic), of);
434     }
435
436   if (!IC_RESULT (ic) && !IC_LEFT (ic))
437     fprintf (of, s);
438
439   if (ic->op == SEND || ic->op == RECEIVE) {
440       fprintf(of,"{argreg = %d}",ic->argreg);
441   }
442   if (ic->op == IPUSH) {
443       fprintf(of,"{parmPush = %d}",ic->parmPush);
444   }
445   fprintf (of, "\n");
446 }
447
448 PRINTFUNC (picCast)
449 {
450   fprintf (of, "\t");
451   printOperand (IC_RESULT (ic), of);
452   fprintf (of, " = ");
453   printOperand (IC_LEFT (ic), of);
454   printOperand (IC_RIGHT (ic), of);
455   fprintf (of, "\n");
456 }
457
458
459 PRINTFUNC (picAssign)
460 {
461   fprintf (of, "\t");
462
463   if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
464     fprintf (of, "*(");
465
466   printOperand (IC_RESULT (ic), of);
467
468   if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
469     fprintf (of, ")");
470
471   fprintf (of, " %s ", s);
472   printOperand (IC_RIGHT (ic), of);
473
474   fprintf (of, "\n");
475 }
476
477 PRINTFUNC (picLabel)
478 {
479   fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
480 }
481
482 PRINTFUNC (picGoto)
483 {
484   fprintf (of, "\t");
485   fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
486 }
487
488 PRINTFUNC (picIfx)
489 {
490   fprintf (of, "\t");
491   fprintf (of, "if ");
492   printOperand (IC_COND (ic), of);
493
494   if (!IC_TRUE (ic))
495     fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
496   else
497     {
498       fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
499       if (IC_FALSE (ic))
500         fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
501     }
502 }
503
504 PRINTFUNC (picInline)
505 {
506   fprintf (of, "%s", IC_INLINE (ic));
507 }
508
509 PRINTFUNC (picReceive)
510 {
511   printOperand (IC_RESULT (ic), of);
512   fprintf (of, " = %s ", s);
513   printOperand (IC_LEFT (ic), of);
514   fprintf (of, "\n");
515 }
516
517 PRINTFUNC (picDummyRead)
518 {
519   fprintf (of, "\t");
520   fprintf (of, "%s ", s);
521   printOperand (IC_RIGHT (ic), of);
522   fprintf (of, "\n");
523 }
524
525 PRINTFUNC (picCritical)
526 {
527   fprintf (of, "\t");
528   if (IC_RESULT (ic))
529     printOperand (IC_RESULT (ic), of);
530   else
531     fprintf (of, "(stack)");
532   fprintf (of, " = %s ", s);
533   fprintf (of, "\n");
534 }
535
536 PRINTFUNC (picEndCritical)
537 {
538   fprintf (of, "\t");
539   fprintf (of, "%s = ", s);
540   if (IC_RIGHT (ic))
541     printOperand (IC_RIGHT (ic), of);
542   else
543     fprintf (of, "(stack)");
544   fprintf (of, "\n");
545 }
546
547 /*-----------------------------------------------------------------*/
548 /* piCode - prints one iCode                                       */
549 /*-----------------------------------------------------------------*/
550 int
551 piCode (void *item, FILE * of)
552 {
553   iCode *ic = item;
554   iCodeTable *icTab;
555
556   if (!of)
557     of = stdout;
558
559   icTab = getTableEntry (ic->op);
560   fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
561            ic->filename, ic->lineno,
562            ic->seq, ic->key, ic->depth, ic->supportRtn);
563   icTab->iCodePrint (of, ic, icTab->printName);
564   return 1;
565 }
566
567 void PICC(iCode *ic)
568 {
569         printiCChain(ic,stdout);
570 }
571 /*-----------------------------------------------------------------*/
572 /* printiCChain - prints intermediate code for humans              */
573 /*-----------------------------------------------------------------*/
574 void
575 printiCChain (iCode * icChain, FILE * of)
576 {
577   iCode *loop;
578   iCodeTable *icTab;
579
580   if (!of)
581     of = stdout;
582   for (loop = icChain; loop; loop = loop->next)
583     {
584       if ((icTab = getTableEntry (loop->op)))
585         {
586           fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
587                    loop->filename, loop->lineno,
588                    loop->seq, loop->key, loop->depth, loop->supportRtn);
589
590           icTab->iCodePrint (of, loop, icTab->printName);
591         }
592     }
593 }
594
595
596 /*-----------------------------------------------------------------*/
597 /* newOperand - allocate, init & return a new iCode                */
598 /*-----------------------------------------------------------------*/
599 operand *
600 newOperand ()
601 {
602   operand *op;
603
604   op = Safe_alloc ( sizeof (operand));
605
606   op->key = 0;
607   return op;
608 }
609
610 /*-----------------------------------------------------------------*/
611 /* newiCode - create and return a new iCode entry initialised      */
612 /*-----------------------------------------------------------------*/
613 iCode *
614 newiCode (int op, operand * left, operand * right)
615 {
616   iCode *ic;
617
618   ic = Safe_alloc ( sizeof (iCode));
619
620   ic->seqPoint = seqPoint;
621   ic->lineno = lineno;
622   ic->filename = filename;
623   ic->block = block;
624   ic->level = scopeLevel;
625   ic->op = op;
626   ic->key = iCodeKey++;
627   IC_LEFT (ic) = left;
628   IC_RIGHT (ic) = right;
629
630   return ic;
631 }
632
633 /*-----------------------------------------------------------------*/
634 /* newiCode for conditional statements                             */
635 /*-----------------------------------------------------------------*/
636 iCode *
637 newiCodeCondition (operand * condition,
638                    symbol * trueLabel,
639                    symbol * falseLabel)
640 {
641   iCode *ic;
642
643   if (IS_VOID(operandType(condition))) {
644     werror(E_VOID_VALUE_USED);
645   }
646
647   ic = newiCode (IFX, NULL, NULL);
648   IC_COND (ic) = condition;
649   IC_TRUE (ic) = trueLabel;
650   IC_FALSE (ic) = falseLabel;
651   return ic;
652 }
653
654 /*-----------------------------------------------------------------*/
655 /* newiCodeLabelGoto - unconditional goto statement| label stmnt   */
656 /*-----------------------------------------------------------------*/
657 iCode *
658 newiCodeLabelGoto (int op, symbol * label)
659 {
660   iCode *ic;
661
662   ic = newiCode (op, NULL, NULL);
663   ic->op = op;
664   ic->label = label;
665   IC_LEFT (ic) = NULL;
666   IC_RIGHT (ic) = NULL;
667   IC_RESULT (ic) = NULL;
668   return ic;
669 }
670
671 /*-----------------------------------------------------------------*/
672 /* newiTemp - allocate & return a newItemp Variable                */
673 /*-----------------------------------------------------------------*/
674 symbol *
675 newiTemp (char *s)
676 {
677   symbol *itmp;
678
679   if (s)
680   {
681       SNPRINTF (buffer, sizeof(buffer), "%s", s);
682   }
683   else
684   {
685       SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
686   }
687
688   itmp = newSymbol (buffer, 1);
689   strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
690   itmp->isitmp = 1;
691
692   return itmp;
693 }
694
695 /*-----------------------------------------------------------------*/
696 /* newiTempLabel - creates a temp variable label                   */
697 /*-----------------------------------------------------------------*/
698 symbol *
699 newiTempLabel (char *s)
700 {
701   symbol *itmplbl;
702
703   /* check if this already exists */
704   if (s && (itmplbl = findSym (LabelTab, NULL, s)))
705     return itmplbl;
706
707   if (s)
708     {
709       itmplbl = newSymbol (s, 1);
710     }
711   else
712     {
713       SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
714       itmplbl = newSymbol (buffer, 1);
715     }
716
717   itmplbl->isitmp = 1;
718   itmplbl->islbl = 1;
719   itmplbl->key = labelKey++;
720   addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
721   return itmplbl;
722 }
723
724 /*-----------------------------------------------------------------*/
725 /* newiTempPreheaderLabel - creates a new preheader label          */
726 /*-----------------------------------------------------------------*/
727 symbol *
728 newiTempPreheaderLabel ()
729 {
730   symbol *itmplbl;
731
732   SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
733   itmplbl = newSymbol (buffer, 1);
734
735   itmplbl->isitmp = 1;
736   itmplbl->islbl = 1;
737   itmplbl->key = labelKey++;
738   addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
739   return itmplbl;
740 }
741
742
743 /*-----------------------------------------------------------------*/
744 /* initiCode - initialises some iCode related stuff                */
745 /*-----------------------------------------------------------------*/
746 void
747 initiCode ()
748 {
749
750 }
751
752 /*-----------------------------------------------------------------*/
753 /* copyiCode - make a copy of the iCode given                      */
754 /*-----------------------------------------------------------------*/
755 iCode *
756 copyiCode (iCode * ic)
757 {
758   iCode *nic = newiCode (ic->op, NULL, NULL);
759
760   nic->lineno = ic->lineno;
761   nic->filename = ic->filename;
762   nic->block = ic->block;
763   nic->level = ic->level;
764   nic->parmBytes = ic->parmBytes;
765
766   /* deal with the special cases first */
767   switch (ic->op)
768     {
769     case IFX:
770       IC_COND (nic) = operandFromOperand (IC_COND (ic));
771       IC_TRUE (nic) = IC_TRUE (ic);
772       IC_FALSE (nic) = IC_FALSE (ic);
773       break;
774
775     case JUMPTABLE:
776       IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
777       IC_JTLABELS (nic) = IC_JTLABELS (ic);
778       break;
779
780     case CALL:
781     case PCALL:
782       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
783       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
784       break;
785
786     case INLINEASM:
787       IC_INLINE (nic) = IC_INLINE (ic);
788       break;
789
790     case ARRAYINIT:
791       IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
792       break;
793
794     default:
795       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
796       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
797       IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
798     }
799
800   return nic;
801 }
802
803 /*-----------------------------------------------------------------*/
804 /* getTableEntry - gets the table entry for the given operator     */
805 /*-----------------------------------------------------------------*/
806 iCodeTable *
807 getTableEntry (int oper)
808 {
809   unsigned i;
810
811   for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
812     if (oper == codeTable[i].icode)
813       return &codeTable[i];
814
815   return NULL;
816 }
817
818 /*-----------------------------------------------------------------*/
819 /* newiTempOperand - new intermediate temp operand                 */
820 /*-----------------------------------------------------------------*/
821 operand *
822 newiTempOperand (sym_link * type, char throwType)
823 {
824   symbol *itmp;
825   operand *op = newOperand ();
826   sym_link *etype;
827
828   op->type = SYMBOL;
829   itmp = newiTemp (NULL);
830
831   etype = getSpec (type);
832
833   if (IS_LITERAL (etype))
834     throwType = 0;
835
836   /* copy the type information */
837   if (type)
838     itmp->etype = getSpec (itmp->type = (throwType ? type :
839                                          copyLinkChain (type)));
840   if (IS_LITERAL (itmp->etype))
841     {
842       SPEC_SCLS (itmp->etype) = S_REGISTER;
843       SPEC_OCLS (itmp->etype) = reg;
844     }
845
846   op->operand.symOperand = itmp;
847   op->key = itmp->key = ++operandKey;
848   return op;
849 }
850
851 /*-----------------------------------------------------------------*/
852 /* operandType - returns the type chain for an operand             */
853 /*-----------------------------------------------------------------*/
854 sym_link *
855 operandType (operand * op)
856 {
857   /* depending on type of operand */
858   switch (op->type)
859     {
860
861     case VALUE:
862       return op->operand.valOperand->type;
863
864     case SYMBOL:
865       return op->operand.symOperand->type;
866
867     case TYPE:
868       return op->operand.typeOperand;
869     default:
870       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
871               " operand type not known ");
872       assert (0);               /* should never come here */
873       /*  Just to keep the compiler happy */
874       return (sym_link *) 0;
875     }
876 }
877
878 /*-----------------------------------------------------------------*/
879 /* isParamterToCall - will return 1 if op is a parameter to args   */
880 /*-----------------------------------------------------------------*/
881 int
882 isParameterToCall (value * args, operand * op)
883 {
884   value *tval = args;
885
886   wassert (IS_SYMOP(op));
887
888   while (tval)
889     {
890       if (tval->sym &&
891           isSymbolEqual (op->operand.symOperand, tval->sym))
892         return 1;
893       tval = tval->next;
894     }
895   return 0;
896 }
897
898 /*-----------------------------------------------------------------*/
899 /* isOperandGlobal   - return 1 if operand is a global variable    */
900 /*-----------------------------------------------------------------*/
901 int
902 isOperandGlobal (operand * op)
903 {
904   if (!op)
905     return 0;
906
907   if (IS_ITEMP (op))
908     return 0;
909
910   if (IS_SYMOP(op) &&
911       (op->operand.symOperand->level == 0 ||
912        IS_STATIC (op->operand.symOperand->etype) ||
913        IS_EXTERN (op->operand.symOperand->etype))
914     )
915     return 1;
916
917   return 0;
918 }
919
920 /*-----------------------------------------------------------------*/
921 /* isOperandVolatile - return 1 if the operand is volatile         */
922 /*-----------------------------------------------------------------*/
923 int
924 isOperandVolatile (operand * op, bool chkTemp)
925 {
926   sym_link *optype;
927   sym_link *opetype;
928
929   if (IS_ITEMP (op) && !chkTemp)
930     return 0;
931
932   opetype = getSpec (optype = operandType (op));
933
934   if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
935     return 1;
936
937   if (IS_VOLATILE (opetype))
938     return 1;
939   return 0;
940 }
941
942 /*-----------------------------------------------------------------*/
943 /* isOperandLiteral - returns 1 if an operand contains a literal   */
944 /*-----------------------------------------------------------------*/
945 int
946 isOperandLiteral (operand * op)
947 {
948   sym_link *opetype;
949
950   if (!op)
951     return 0;
952
953   opetype = getSpec (operandType (op));
954
955   if (IS_LITERAL (opetype))
956     return 1;
957
958   return 0;
959 }
960
961 /*-----------------------------------------------------------------*/
962 /* isOperandInFarSpace - will return true if operand is in farSpace */
963 /*-----------------------------------------------------------------*/
964 bool
965 isOperandInFarSpace (operand * op)
966 {
967   sym_link *etype;
968
969   if (!op)
970     return FALSE;
971
972   if (!IS_SYMOP (op))
973     return FALSE;
974
975   if (!IS_TRUE_SYMOP (op))
976     {
977       if (SPIL_LOC (op))
978         etype = SPIL_LOC (op)->etype;
979       else
980         return FALSE;
981     }
982   else
983     {
984       etype = getSpec (operandType (op));
985     }
986   return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
987 }
988
989 /*------------------------------------------------------------------*/
990 /* isOperandInDirSpace - will return true if operand is in dirSpace */
991 /*------------------------------------------------------------------*/
992 bool
993 isOperandInDirSpace (operand * op)
994 {
995   sym_link *etype;
996
997   if (!op)
998     return FALSE;
999
1000   if (!IS_SYMOP (op))
1001     return FALSE;
1002
1003   if (!IS_TRUE_SYMOP (op))
1004     {
1005       if (SPIL_LOC (op))
1006         etype = SPIL_LOC (op)->etype;
1007       else
1008         return FALSE;
1009     }
1010   else
1011     {
1012       etype = getSpec (operandType (op));
1013     }
1014   return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1015 }
1016
1017 /*--------------------------------------------------------------------*/
1018 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
1019 /*--------------------------------------------------------------------*/
1020 bool
1021 isOperandInCodeSpace (operand * op)
1022 {
1023   sym_link *etype;
1024
1025   if (!op)
1026     return FALSE;
1027
1028   if (!IS_SYMOP (op))
1029     return FALSE;
1030
1031   etype = getSpec (operandType (op));
1032
1033   if (!IS_TRUE_SYMOP (op))
1034     {
1035       if (SPIL_LOC (op))
1036         etype = SPIL_LOC (op)->etype;
1037       else
1038         return FALSE;
1039     }
1040   else
1041     {
1042       etype = getSpec (operandType (op));
1043     }
1044   return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1045 }
1046
1047 /*-----------------------------------------------------------------*/
1048 /* isOperandOnStack - will return true if operand is on stack      */
1049 /*-----------------------------------------------------------------*/
1050 bool
1051 isOperandOnStack (operand * op)
1052 {
1053   sym_link *etype;
1054
1055   if (!op)
1056     return FALSE;
1057
1058   if (!IS_SYMOP (op))
1059     return FALSE;
1060
1061   etype = getSpec (operandType (op));
1062   if (IN_STACK (etype) ||
1063       OP_SYMBOL(op)->onStack ||
1064       (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1065     return TRUE;
1066
1067   return FALSE;
1068 }
1069
1070 /*-----------------------------------------------------------------*/
1071 /* isOclsExpensive - will return true if accesses to an output     */
1072 /*                   storage class are expensive                   */
1073 /*-----------------------------------------------------------------*/
1074 bool
1075 isOclsExpensive (struct memmap *oclass)
1076 {
1077   if (port->oclsExpense)
1078     return port->oclsExpense (oclass) > 0;
1079
1080   /* In the absence of port specific guidance, assume only */
1081   /* farspace is expensive. */
1082   return IN_FARSPACE (oclass);
1083 }
1084
1085 /*-----------------------------------------------------------------*/
1086 /* isiCodeInFunctionCall - return TRUE if an iCode is between a    */
1087 /*   CALL/PCALL and the first IPUSH/SEND associated with the call  */
1088 /*-----------------------------------------------------------------*/
1089 int
1090 isiCodeInFunctionCall (iCode * ic)
1091 {
1092   iCode * lic = ic;
1093
1094   /* Find the next CALL/PCALL */
1095   while (lic)
1096     {
1097       if (lic->op == CALL || lic->op == PCALL)
1098         break;
1099       lic = lic->next;
1100     }
1101
1102   if (!lic)
1103     return FALSE;
1104
1105   /* A function call was found. Scan backwards and see if an */
1106   /* IPUSH or SEND is encountered */
1107   while (ic)
1108     {
1109       if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1110         return FALSE;
1111       if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1112         return TRUE;
1113       ic = ic->prev;
1114     }
1115
1116   return FALSE;
1117 }
1118
1119 /*-----------------------------------------------------------------*/
1120 /* operandLitValue - literal value of an operand                   */
1121 /*-----------------------------------------------------------------*/
1122 double
1123 operandLitValue (operand * op)
1124 {
1125   assert (isOperandLiteral (op));
1126
1127   return floatFromVal (op->operand.valOperand);
1128 }
1129
1130 /*-----------------------------------------------------------------*/
1131 /* getBuiltInParms - returns parameters to a builtin functions     */
1132 /*-----------------------------------------------------------------*/
1133 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1134 {
1135     sym_link *ftype;
1136
1137     *pcount = 0;
1138     /* builtin functions uses only SEND for parameters */
1139     while (ic->op != CALL) {
1140         assert(ic->op == SEND && ic->builtinSEND);
1141         ic->generated = 1;    /* mark the icode as generated */
1142         parms[*pcount] = IC_LEFT(ic);
1143         ic = ic->next;
1144         (*pcount)++;
1145     }
1146
1147     ic->generated = 1;
1148     /* make sure this is a builtin function call */
1149     assert(IS_SYMOP(IC_LEFT(ic)));
1150     ftype = operandType(IC_LEFT(ic));
1151     assert(IFFUNC_ISBUILTIN(ftype));
1152     return ic;
1153 }
1154
1155 /*-----------------------------------------------------------------*/
1156 /* operandOperation - performs operations on operands             */
1157 /*-----------------------------------------------------------------*/
1158 operand *
1159 operandOperation (operand * left, operand * right,
1160                   int op, sym_link * type)
1161 {
1162   sym_link *let , *ret=NULL;
1163   operand *retval = (operand *) 0;
1164
1165   assert (isOperandLiteral (left));
1166   let = getSpec(operandType(left));
1167   if (right) {
1168     assert (isOperandLiteral (right));
1169     ret = getSpec(operandType(right));
1170   }
1171
1172   switch (op)
1173     {
1174     case '+':
1175       retval = operandFromValue (valCastLiteral (type,
1176                                                  operandLitValue (left) +
1177                                                  operandLitValue (right)));
1178       break;
1179     case '-':
1180       retval = operandFromValue (valCastLiteral (type,
1181                                                  operandLitValue (left) -
1182                                                  operandLitValue (right)));
1183       break;
1184     case '*':
1185       /*
1186       retval = operandFromValue (valCastLiteral (type,
1187                                                  operandLitValue (left) *
1188                                                  operandLitValue (right)));
1189       This could be all we've to do, but with gcc we've to take care about
1190       overflows. Two examples:
1191       ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1192       significant bits are lost (52 in fraction, 63 bits would be
1193       necessary to keep full precision).
1194       If the resulting double value is greater than ULONG_MAX (resp.
1195       USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1196       */
1197
1198       /* if it is not a specifier then we can assume that */
1199       /* it will be an unsigned long                      */
1200       if (IS_INT (type) ||
1201           !IS_SPEC (type))
1202         {
1203           /* long is handled here, because it can overflow with double */
1204           if (IS_LONG (type) ||
1205               !IS_SPEC (type))
1206           /* signed and unsigned mul are the same, as long as the precision
1207              of the result isn't bigger than the precision of the operands. */
1208             retval = operandFromValue (valCastLiteral (type,
1209                      (TYPE_UDWORD) operandLitValue (left) *
1210                      (TYPE_UDWORD) operandLitValue (right)));
1211           else if (IS_UNSIGNED (type)) /* unsigned int */
1212             {
1213               /* unsigned int is handled here in order to detect overflow */
1214               TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1215                                (TYPE_UWORD) operandLitValue (right);
1216
1217               retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1218               if (ul != (TYPE_UWORD) ul)
1219                 werror (W_INT_OVL);
1220             }
1221           else /* signed int */
1222             {
1223               /* signed int is handled here in order to detect overflow */
1224               TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1225                              (TYPE_WORD) operandLitValue (right);
1226
1227               retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1228               if (l != (TYPE_WORD) l)
1229                 werror (W_INT_OVL);
1230             }
1231         }
1232       else
1233         /* all others go here: */
1234         retval = operandFromValue (valCastLiteral (type,
1235                                                    operandLitValue (left) *
1236                                                    operandLitValue (right)));
1237       break;
1238     case '/':
1239       if ((TYPE_UDWORD) operandLitValue (right) == 0)
1240         {
1241           werror (E_DIVIDE_BY_ZERO);
1242           retval = right;
1243
1244         }
1245       else
1246         {
1247           if (IS_UNSIGNED (type))
1248             {
1249               SPEC_USIGN (let) = 1;
1250               SPEC_USIGN (ret) = 1;
1251               retval = operandFromValue (valCastLiteral (type,
1252                                         (TYPE_UDWORD) operandLitValue (left) /
1253                                         (TYPE_UDWORD) operandLitValue (right)));
1254             }
1255           else
1256             {
1257               retval = operandFromValue (valCastLiteral (type,
1258                                                      operandLitValue (left) /
1259                                                      operandLitValue (right)));
1260             }
1261         }
1262       break;
1263     case '%':
1264       if ((TYPE_UDWORD) operandLitValue (right) == 0)
1265         {
1266           werror (E_DIVIDE_BY_ZERO);
1267           retval = right;
1268         }
1269       else
1270         {
1271           if (IS_UNSIGNED (type))
1272             retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1273                                      (TYPE_UDWORD) operandLitValue (right));
1274           else
1275             retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1276                                      (TYPE_DWORD) operandLitValue (right));
1277         }
1278       break;
1279     case LEFT_OP:
1280       /* The number of left shifts is always unsigned. Signed doesn't make
1281          sense here. Shifting by a negative number is impossible. */
1282       retval = operandFromValue (valCastLiteral (type,
1283                                  ((TYPE_UDWORD) operandLitValue (left) <<
1284                                   (TYPE_UDWORD) operandLitValue (right))));
1285       break;
1286     case RIGHT_OP:
1287       /* The number of right shifts is always unsigned. Signed doesn't make
1288          sense here. Shifting by a negative number is impossible. */
1289       if (IS_UNSIGNED(let))
1290         /* unsigned: logic shift right */
1291         retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1292                                  (TYPE_UDWORD) operandLitValue (right));
1293       else
1294         /* signed: arithmetic shift right */
1295         retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1296                                  (TYPE_UDWORD) operandLitValue (right));
1297       break;
1298     case EQ_OP:
1299       if (IS_FLOAT (let) ||
1300           IS_FLOAT (ret))
1301         {
1302           retval = operandFromLit (operandLitValue (left) ==
1303                                    operandLitValue (right));
1304         }
1305       else
1306       if (IS_FIXED16X16 (let) ||
1307           IS_FIXED16X16 (ret))
1308         {
1309           retval = operandFromLit (operandLitValue (left) ==
1310                                    operandLitValue (right));
1311         }
1312       else
1313         {
1314           /* this op doesn't care about signedness */
1315           TYPE_UDWORD l, r;
1316
1317           l = (TYPE_UDWORD) operandLitValue (left);
1318           r = (TYPE_UDWORD) operandLitValue (right);
1319           /* In order to correctly compare 'signed int' and 'unsigned int' it's
1320              neccessary to strip them to 16 bit.
1321              Literals are reduced to their cheapest type, therefore left and
1322              right might have different types. It's neccessary to find a
1323              common type: int (used for char too) or long */
1324           if (!IS_LONG (let) &&
1325               !IS_LONG (ret))
1326             {
1327               r = (TYPE_UWORD) r;
1328               l = (TYPE_UWORD) l;
1329             }
1330           retval = operandFromLit (l == r);
1331         }
1332       break;
1333     case '<':
1334       retval = operandFromLit (operandLitValue (left) <
1335                                operandLitValue (right));
1336       break;
1337     case LE_OP:
1338       retval = operandFromLit (operandLitValue (left) <=
1339                                operandLitValue (right));
1340       break;
1341     case NE_OP:
1342       retval = operandFromLit (operandLitValue (left) !=
1343                                operandLitValue (right));
1344       break;
1345     case '>':
1346       retval = operandFromLit (operandLitValue (left) >
1347                                operandLitValue (right));
1348       break;
1349     case GE_OP:
1350       retval = operandFromLit (operandLitValue (left) >=
1351                                operandLitValue (right));
1352       break;
1353     case BITWISEAND:
1354       retval = operandFromValue (valCastLiteral (type,
1355                                                  (TYPE_UDWORD)operandLitValue(left) &
1356                                                  (TYPE_UDWORD)operandLitValue(right)));
1357       break;
1358     case '|':
1359       retval = operandFromValue (valCastLiteral (type,
1360                                                  (TYPE_UDWORD)operandLitValue(left) |
1361                                                  (TYPE_UDWORD)operandLitValue(right)));
1362       break;
1363     case '^':
1364       retval = operandFromValue (valCastLiteral (type,
1365                                                  (TYPE_UDWORD)operandLitValue(left) ^
1366                                                  (TYPE_UDWORD)operandLitValue(right)));
1367       break;
1368     case AND_OP:
1369       retval = operandFromLit (operandLitValue (left) &&
1370                                operandLitValue (right));
1371       break;
1372     case OR_OP:
1373       retval = operandFromLit (operandLitValue (left) ||
1374                                operandLitValue (right));
1375       break;
1376     case RRC:
1377       {
1378         TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1379
1380         retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1381                                  (i << 1));
1382       }
1383       break;
1384     case RLC:
1385       {
1386         TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1387
1388         retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1389                                  (i >> 1));
1390       }
1391       break;
1392
1393     case UNARYMINUS:
1394       retval = operandFromValue (valCastLiteral (type,
1395                                                  -1 * operandLitValue (left)));
1396       break;
1397
1398     case '~':
1399       retval = operandFromValue (valCastLiteral (type,
1400                                                  ~((TYPE_UDWORD)
1401                                                    operandLitValue (left))));
1402       break;
1403
1404     case '!':
1405       retval = operandFromLit (!operandLitValue (left));
1406       break;
1407
1408     default:
1409       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1410               " operandOperation invalid operator ");
1411       assert (0);
1412     }
1413
1414   return retval;
1415 }
1416
1417
1418 /*-----------------------------------------------------------------*/
1419 /* isOperandEqual - compares two operand & return 1 if they r =    */
1420 /*-----------------------------------------------------------------*/
1421 int
1422 isOperandEqual (operand * left, operand * right)
1423 {
1424   /* if the pointers are equal then they are equal */
1425   if (left == right)
1426     return 1;
1427
1428   /* if either of them null then false */
1429   if (!left || !right)
1430     return 0;
1431
1432   if (left->type != right->type)
1433     return 0;
1434
1435   if (IS_SYMOP (left) && IS_SYMOP (right))
1436     return left->key == right->key;
1437
1438   /* if types are the same */
1439   switch (left->type)
1440     {
1441     case SYMBOL:
1442       return isSymbolEqual (left->operand.symOperand,
1443                             right->operand.symOperand);
1444     case VALUE:
1445       return (compareType (left->operand.valOperand->type,
1446                            right->operand.valOperand->type) &&
1447               (floatFromVal (left->operand.valOperand) ==
1448                floatFromVal (right->operand.valOperand)));
1449     case TYPE:
1450       if (compareType (left->operand.typeOperand,
1451                      right->operand.typeOperand) == 1)
1452         return 1;
1453     }
1454
1455   return 0;
1456 }
1457
1458 /*-------------------------------------------------------------------*/
1459 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1460 /*-------------------------------------------------------------------*/
1461 int
1462 isiCodeEqual (iCode * left, iCode * right)
1463 {
1464   /* if the same pointer */
1465   if (left == right)
1466     return 1;
1467
1468   /* if either of them null */
1469   if (!left || !right)
1470     return 0;
1471
1472   /* if operand are the same */
1473   if (left->op == right->op)
1474     {
1475
1476       /* compare all the elements depending on type */
1477       if (left->op != IFX)
1478         {
1479           if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1480             return 0;
1481           if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1482             return 0;
1483
1484         }
1485       else
1486         {
1487           if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1488             return 0;
1489           if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1490             return 0;
1491           if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1492             return 0;
1493         }
1494
1495       return 1;
1496     }
1497   return 0;
1498 }
1499
1500 /*-----------------------------------------------------------------*/
1501 /* newiTempFromOp - create a temp Operand with same attributes     */
1502 /*-----------------------------------------------------------------*/
1503 operand *
1504 newiTempFromOp (operand * op)
1505 {
1506   operand *nop;
1507
1508   if (!op)
1509     return NULL;
1510
1511   if (!IS_ITEMP (op))
1512     return op;
1513
1514   nop = newiTempOperand (operandType (op), TRUE);
1515   nop->isaddr = op->isaddr;
1516   nop->isvolatile = op->isvolatile;
1517   nop->isGlobal = op->isGlobal;
1518   nop->isLiteral = op->isLiteral;
1519   nop->usesDefs = op->usesDefs;
1520   nop->isParm = op->isParm;
1521   return nop;
1522 }
1523
1524 /*-----------------------------------------------------------------*/
1525 /* operand from operand - creates an operand holder for the type   */
1526 /*-----------------------------------------------------------------*/
1527 operand *
1528 operandFromOperand (operand * op)
1529 {
1530   operand *nop;
1531
1532   if (!op)
1533     return NULL;
1534   nop = newOperand ();
1535   nop->type = op->type;
1536   nop->isaddr = op->isaddr;
1537   nop->key = op->key;
1538   nop->isvolatile = op->isvolatile;
1539   nop->isGlobal = op->isGlobal;
1540   nop->isLiteral = op->isLiteral;
1541   nop->usesDefs = op->usesDefs;
1542   nop->isParm = op->isParm;
1543
1544   switch (nop->type)
1545     {
1546     case SYMBOL:
1547       nop->operand.symOperand = op->operand.symOperand;
1548       break;
1549     case VALUE:
1550       nop->operand.valOperand = op->operand.valOperand;
1551       break;
1552     case TYPE:
1553       nop->operand.typeOperand = op->operand.typeOperand;
1554       break;
1555     }
1556
1557   return nop;
1558 }
1559
1560 /*-----------------------------------------------------------------*/
1561 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
1562 /*-----------------------------------------------------------------*/
1563 operand *
1564 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1565 {
1566   operand *nop = operandFromOperand (op);
1567
1568   if (nop->type == SYMBOL)
1569     {
1570       OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1571       OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1572     }
1573
1574   return nop;
1575 }
1576
1577 /*-----------------------------------------------------------------*/
1578 /* operandFromSymbol - creates an operand from a symbol            */
1579 /*-----------------------------------------------------------------*/
1580 operand *
1581 operandFromSymbol (symbol * sym)
1582 {
1583   operand *op;
1584   iCode *ic;
1585   int ok = 1;
1586   /* if the symbol's type is a literal */
1587   /* then it is an enumerator type     */
1588   if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1589     return operandFromValue (valFromType (sym->etype));
1590
1591   if (!sym->key)
1592     sym->key = ++operandKey;
1593
1594   /* if this an implicit variable, means struct/union */
1595   /* member so just return it                         */
1596   if (sym->implicit || IS_FUNC (sym->type))
1597     {
1598       op = newOperand ();
1599       op->type = SYMBOL;
1600       op->operand.symOperand = sym;
1601       op->key = sym->key;
1602       op->isvolatile = isOperandVolatile (op, TRUE);
1603       op->isGlobal = isOperandGlobal (op);
1604       return op;
1605     }
1606
1607   /* under the following conditions create a
1608      register equivalent for a local symbol */
1609   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1610       (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1611       !TARGET_IS_HC08 &&
1612       (!(options.model == MODEL_FLAT24)) ) &&
1613       options.stackAuto == 0)
1614     ok = 0;
1615
1616   if (!IS_AGGREGATE (sym->type) &&      /* not an aggregate */
1617       !IS_FUNC (sym->type) &&           /* not a function   */
1618       !sym->_isparm &&                  /* not a parameter  */
1619       IS_AUTO (sym) &&                  /* is a local auto variable */
1620       !sym->addrtaken &&                /* whose address has not been taken */
1621       !sym->reqv &&                     /* does not already have a reg equivalence */
1622       !IS_VOLATILE (sym->etype) &&      /* not declared as volatile */
1623       !sym->islbl &&                    /* not a label */
1624       ok &&                             /* farspace check */
1625       !IS_BITVAR (sym->etype)           /* not a bit variable */
1626     )
1627     {
1628
1629       /* we will use it after all optimizations
1630          and before liveRange calculation */
1631       sym->reqv = newiTempOperand (sym->type, 0);
1632       sym->reqv->key = sym->key;
1633       OP_SYMBOL (sym->reqv)->prereqv = sym;
1634       OP_SYMBOL (sym->reqv)->key = sym->key;
1635       OP_SYMBOL (sym->reqv)->isreqv = 1;
1636       OP_SYMBOL (sym->reqv)->islocal = 1;
1637       OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1638       SPIL_LOC (sym->reqv) = sym;
1639     }
1640
1641   if (!IS_AGGREGATE (sym->type))
1642     {
1643       op = newOperand ();
1644       op->type = SYMBOL;
1645       op->operand.symOperand = sym;
1646       op->isaddr = 1;
1647       op->key = sym->key;
1648       op->isvolatile = isOperandVolatile (op, TRUE);
1649       op->isGlobal = isOperandGlobal (op);
1650       op->isPtr = IS_PTR (operandType (op));
1651       op->isParm = sym->_isparm;
1652       return op;
1653     }
1654
1655   /* create :-                     */
1656   /*    itemp = &[_symbol]         */
1657
1658   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1659   IC_LEFT (ic)->type = SYMBOL;
1660   IC_LEFT (ic)->operand.symOperand = sym;
1661   IC_LEFT (ic)->key = sym->key;
1662   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1663   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1664   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1665
1666   /* create result */
1667   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1668   if (IS_ARRAY (sym->type))
1669     {
1670       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1671       IC_RESULT (ic)->isaddr = 0;
1672     }
1673   else
1674     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1675
1676   ADDTOCHAIN (ic);
1677
1678   return IC_RESULT (ic);
1679 }
1680
1681 /*-----------------------------------------------------------------*/
1682 /* operandFromValue - creates an operand from value                */
1683 /*-----------------------------------------------------------------*/
1684 operand *
1685 operandFromValue (value * val)
1686 {
1687   operand *op;
1688
1689   /* if this is a symbol then do the symbol thing */
1690   if (val->sym)
1691     return operandFromSymbol (val->sym);
1692
1693   /* this is not a symbol */
1694   op = newOperand ();
1695   op->type = VALUE;
1696   op->operand.valOperand = val;
1697   op->isLiteral = isOperandLiteral (op);
1698   return op;
1699 }
1700
1701 /*-----------------------------------------------------------------*/
1702 /* operandFromLink - operand from typeChain                        */
1703 /*-----------------------------------------------------------------*/
1704 operand *
1705 operandFromLink (sym_link * type)
1706 {
1707   operand *op;
1708
1709   /* operand from sym_link */
1710   if (!type)
1711     return NULL;
1712
1713   op = newOperand ();
1714   op->type = TYPE;
1715   op->operand.typeOperand = copyLinkChain (type);
1716   return op;
1717 }
1718
1719 /*-----------------------------------------------------------------*/
1720 /* operandFromLit - makes an operand from a literal value          */
1721 /*-----------------------------------------------------------------*/
1722 operand *
1723 operandFromLit (double i)
1724 {
1725   return operandFromValue (valueFromLit (i));
1726 }
1727
1728 /*-----------------------------------------------------------------*/
1729 /* operandFromAst - creates an operand from an ast                 */
1730 /*-----------------------------------------------------------------*/
1731 operand *
1732 operandFromAst (ast * tree,int lvl)
1733 {
1734
1735   if (!tree)
1736     return NULL;
1737
1738   /* depending on type do */
1739   switch (tree->type)
1740     {
1741     case EX_OP:
1742       return ast2iCode (tree,lvl+1);
1743       break;
1744
1745     case EX_VALUE:
1746       return operandFromValue (tree->opval.val);
1747       break;
1748
1749     case EX_LINK:
1750       return operandFromLink (tree->opval.lnk);
1751       break;
1752
1753     default:
1754       assert (0);
1755     }
1756
1757   /*  Just to keep the compiler happy */
1758   return (operand *) 0;
1759 }
1760
1761 /*-----------------------------------------------------------------*/
1762 /* setOperandType - sets the operand's type to the given type      */
1763 /*-----------------------------------------------------------------*/
1764 void
1765 setOperandType (operand * op, sym_link * type)
1766 {
1767   /* depending on the type of operand */
1768   switch (op->type)
1769     {
1770
1771     case VALUE:
1772       op->operand.valOperand->etype =
1773         getSpec (op->operand.valOperand->type =
1774                  copyLinkChain (type));
1775       return;
1776
1777     case SYMBOL:
1778       if (op->operand.symOperand->isitmp)
1779         op->operand.symOperand->etype =
1780           getSpec (op->operand.symOperand->type =
1781                    copyLinkChain (type));
1782       else
1783         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1784                 "attempt to modify type of source");
1785       return;
1786
1787     case TYPE:
1788       op->operand.typeOperand = copyLinkChain (type);
1789       return;
1790     }
1791
1792 }
1793
1794 /*-----------------------------------------------------------------*/
1795 /* Get size in byte of ptr need to access an array                 */
1796 /*-----------------------------------------------------------------*/
1797 static int
1798 getArraySizePtr (operand * op)
1799 {
1800   sym_link *ltype = operandType(op);
1801
1802   if(IS_PTR(ltype))
1803     {
1804       int size = getSize(ltype);
1805       return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1806     }
1807
1808   if(IS_ARRAY(ltype))
1809     {
1810       sym_link *letype = getSpec(ltype);
1811       switch (PTR_TYPE (SPEC_OCLS (letype)))
1812         {
1813         case IPOINTER:
1814         case PPOINTER:
1815         case POINTER:
1816           return (PTRSIZE);
1817         case EEPPOINTER:
1818         case FPOINTER:
1819         case CPOINTER:
1820         case FUNCTION:
1821           return (FPTRSIZE);
1822         case GPOINTER:
1823           if (GPTRSIZE > FPTRSIZE)
1824             return (GPTRSIZE-1);
1825           else
1826             return (FPTRSIZE);
1827
1828         default:
1829           return (FPTRSIZE);
1830         }
1831     }
1832   return (FPTRSIZE);
1833 }
1834
1835 /*-----------------------------------------------------------------*/
1836 /* perform "usual unary conversions"                               */
1837 /*-----------------------------------------------------------------*/
1838 #if 0
1839 static operand *
1840 usualUnaryConversions (operand * op)
1841 {
1842   if (IS_INTEGRAL (operandType (op)))
1843     {
1844       if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1845         {
1846           /* Widen to int. */
1847           return geniCodeCast (INTTYPE, op, TRUE);
1848         }
1849     }
1850   return op;
1851 }
1852 #endif
1853
1854 /*-----------------------------------------------------------------*/
1855 /* perform "usual binary conversions"                              */
1856 /*-----------------------------------------------------------------*/
1857
1858 static sym_link *
1859 usualBinaryConversions (operand ** op1, operand ** op2,
1860                         RESULT_TYPE resultType, int op)
1861 {
1862   sym_link *ctype;
1863   sym_link *rtype = operandType (*op2);
1864   sym_link *ltype = operandType (*op1);
1865
1866   ctype = computeType (ltype, rtype, resultType, op);
1867
1868   switch (op)
1869     {
1870       case '*':
1871       case '/':
1872       case '%':
1873         if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1874           {
1875             /* one byte operations: keep signedness for code generator */
1876             return ctype;
1877           }
1878         break;
1879       default:
1880         break;
1881     }
1882
1883   *op1 = geniCodeCast (ctype, *op1, TRUE);
1884   *op2 = geniCodeCast (ctype, *op2, TRUE);
1885
1886   return ctype;
1887 }
1888
1889 /*-----------------------------------------------------------------*/
1890 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1891 /*                          at address                             */
1892 /*-----------------------------------------------------------------*/
1893 operand *
1894 geniCodeRValue (operand * op, bool force)
1895 {
1896   iCode *ic;
1897   sym_link *type = operandType (op);
1898   sym_link *etype = getSpec (type);
1899
1900   /* if this is an array & already */
1901   /* an address then return this   */
1902   if (IS_AGGREGATE (type) ||
1903       (IS_PTR (type) && !force && !op->isaddr))
1904     return operandFromOperand (op);
1905
1906   /* if this is not an address then must be */
1907   /* rvalue already so return this one      */
1908   if (!op->isaddr)
1909     return op;
1910
1911   /* if this is not a temp symbol then */
1912   if (!IS_ITEMP (op) &&
1913       !force &&
1914       !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1915     {
1916       op = operandFromOperand (op);
1917       op->isaddr = 0;
1918       return op;
1919     }
1920
1921   if (IS_SPEC (type) &&
1922       IS_TRUE_SYMOP (op) &&
1923       (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1924       (options.model == MODEL_FLAT24) ))
1925     {
1926       op = operandFromOperand (op);
1927       op->isaddr = 0;
1928       return op;
1929     }
1930
1931   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1932   if (IS_PTR (type) && op->isaddr && force)
1933     type = type->next;
1934
1935   type = copyLinkChain (type);
1936
1937   IC_RESULT (ic) = newiTempOperand (type, 1);
1938   IC_RESULT (ic)->isaddr = 0;
1939
1940 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1941
1942   ADDTOCHAIN (ic);
1943
1944   return IC_RESULT (ic);
1945 }
1946
1947 /*-----------------------------------------------------------------*/
1948 /* geniCodeCast - changes the value from one type to another       */
1949 /*-----------------------------------------------------------------*/
1950 static operand *
1951 geniCodeCast (sym_link * type, operand * op, bool implicit)
1952 {
1953   iCode *ic;
1954   sym_link *optype;
1955   sym_link *opetype = getSpec (optype = operandType (op));
1956   sym_link *restype;
1957   int errors=0;
1958
1959   /* one of them has size zero then error */
1960   if (IS_VOID (optype))
1961     {
1962       werror (E_CAST_ZERO);
1963       return op;
1964     }
1965
1966   if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1967     {
1968       geniCodeArray2Ptr (op);
1969       op->isaddr = 0;
1970     }
1971
1972   /* if the operand is already the desired type then do nothing */
1973   if (compareType (type, optype) == 1)
1974     return op;
1975
1976   /* if this is a literal then just change the type & return */
1977   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1978     {
1979       return operandFromValue (valCastLiteral (type,
1980                                                operandLitValue (op)));
1981     }
1982
1983   /* if casting to/from pointers, do some checking */
1984   if (IS_PTR(type)) { // to a pointer
1985     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1986       if (IS_INTEGRAL(optype)) {
1987         // maybe this is NULL, than it's ok.
1988         if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1989           if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1990             // no way to set the storage
1991             if (IS_LITERAL(optype)) {
1992               werror(E_LITERAL_GENERIC);
1993               errors++;
1994             } else {
1995               werror(E_NONPTR2_GENPTR);
1996               errors++;
1997             }
1998           } else if (implicit) {
1999             werror(W_INTEGRAL2PTR_NOCAST);
2000             errors++;
2001           }
2002         }
2003       } else {
2004         // shouldn't do that with float, array or structure unless to void
2005         if (!IS_VOID(getSpec(type)) &&
2006             !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2007           werror(E_INCOMPAT_TYPES);
2008           errors++;
2009         }
2010       }
2011     } else { // from a pointer to a pointer
2012       if (IS_GENPTR(type) && IS_VOID(type->next))
2013         { // cast to void* is always allowed
2014         }
2015       else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2016         { // cast from void* is always allowed
2017         }
2018       else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2019         // if not a pointer to a function
2020         if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2021           if (implicit) { // if not to generic, they have to match
2022             if (!IS_GENPTR(type) &&
2023                 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2024                   ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2025                  )
2026                )
2027             {
2028               werror(E_INCOMPAT_PTYPES);
2029               errors++;
2030             }
2031           }
2032         }
2033       }
2034     }
2035   } else { // to a non pointer
2036     if (IS_PTR(optype)) { // from a pointer
2037       if (implicit) { // sneaky
2038         if (IS_INTEGRAL(type)) {
2039           werror(W_PTR2INTEGRAL_NOCAST);
2040           errors++;
2041         } else { // shouldn't do that with float, array or structure
2042           werror(E_INCOMPAT_TYPES);
2043           errors++;
2044         }
2045       }
2046     }
2047   }
2048   if (errors) {
2049     printFromToType (optype, type);
2050   }
2051
2052   /* if they are the same size create an assignment */
2053
2054   /* This seems very dangerous to me, since there are several */
2055   /* optimizations (for example, gcse) that don't notice the  */
2056   /* cast hidden in this assignement and may simplify an      */
2057   /* iCode to use the original (uncasted) operand.            */
2058   /* Unfortunately, other things break when this cast is      */
2059   /* made explicit. Need to fix this someday.                 */
2060   /* -- EEP, 2004/01/21                                       */
2061   if (getSize (type) == getSize (optype) &&
2062       !IS_BITFIELD (type) &&
2063       !IS_FLOAT (type) &&
2064       !IS_FLOAT (optype) &&
2065       !IS_FIXED (type) &&
2066       !IS_FIXED (optype) &&
2067       ((IS_SPEC (type) && IS_SPEC (optype)) ||
2068        (!IS_SPEC (type) && !IS_SPEC (optype))))
2069     {
2070       ic = newiCode ('=', NULL, op);
2071       IC_RESULT (ic) = newiTempOperand (type, 0);
2072       SPIL_LOC (IC_RESULT (ic)) =
2073         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2074       IC_RESULT (ic)->isaddr = 0;
2075     }
2076   else
2077     {
2078       ic = newiCode (CAST, operandFromLink (type),
2079                      geniCodeRValue (op, FALSE));
2080
2081       IC_RESULT (ic) = newiTempOperand (type, 0);
2082     }
2083
2084   /* preserve the storage class & output class */
2085   /* of the original variable                  */
2086   restype = getSpec (operandType (IC_RESULT (ic)));
2087   if (!IS_LITERAL(opetype) &&
2088       !IS_BIT(opetype))
2089     {
2090       SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2091       SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2092     }
2093   ADDTOCHAIN (ic);
2094   return IC_RESULT (ic);
2095 }
2096
2097 /*-----------------------------------------------------------------*/
2098 /* geniCodeLabel - will create a Label                             */
2099 /*-----------------------------------------------------------------*/
2100 void
2101 geniCodeLabel (symbol * label)
2102 {
2103   iCode *ic;
2104
2105   ic = newiCodeLabelGoto (LABEL, label);
2106   ADDTOCHAIN (ic);
2107 }
2108
2109 /*-----------------------------------------------------------------*/
2110 /* geniCodeGoto  - will create a Goto                              */
2111 /*-----------------------------------------------------------------*/
2112 void
2113 geniCodeGoto (symbol * label)
2114 {
2115   iCode *ic;
2116
2117   ic = newiCodeLabelGoto (GOTO, label);
2118   ADDTOCHAIN (ic);
2119 }
2120
2121 /*-----------------------------------------------------------------*/
2122 /* geniCodeMultiply - gen intermediate code for multiplication     */
2123 /*-----------------------------------------------------------------*/
2124 static operand *
2125 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2126 {
2127   iCode *ic;
2128   int p2 = 0;
2129   sym_link *resType;
2130   LRTYPE;
2131
2132   /* if they are both literal then we know the result */
2133   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2134     return operandFromValue (valMult (left->operand.valOperand,
2135                                       right->operand.valOperand));
2136
2137   if (IS_LITERAL(retype)) {
2138     p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2139   }
2140
2141   resType = usualBinaryConversions (&left, &right, resultType, '*');
2142 #if 1
2143   rtype = operandType (right);
2144   retype = getSpec (rtype);
2145   ltype = operandType (left);
2146   letype = getSpec (ltype);
2147 #endif
2148
2149   /* if the right is a literal & power of 2 */
2150   /* then make it a left shift              */
2151   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2152      efficient in most cases than 2 bytes result = 2 bytes << literal
2153      if port has 1 byte muldiv */
2154   if (p2 && !IS_FLOAT (letype) && !IS_FIXED (letype)
2155       && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2156            && (port->support.muldiv == 1))
2157       && strcmp (port->target, "pic16") != 0  /* don't shift for pic */
2158       && strcmp (port->target, "pic14") != 0)
2159     {
2160       if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2161         {
2162           /* LEFT_OP need same size for left and result, */
2163           left = geniCodeCast (resType, left, TRUE);
2164           ltype = operandType (left);
2165         }
2166       ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2167     }
2168   else
2169     {
2170       ic = newiCode ('*', left, right);         /* normal multiplication */
2171       /* if the size left or right > 1 then support routine */
2172       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2173         ic->supportRtn = 1;
2174
2175     }
2176   IC_RESULT (ic) = newiTempOperand (resType, 1);
2177
2178   ADDTOCHAIN (ic);
2179   return IC_RESULT (ic);
2180 }
2181
2182 /*-----------------------------------------------------------------*/
2183 /* geniCodeDivision - gen intermediate code for division           */
2184 /*-----------------------------------------------------------------*/
2185 static operand *
2186 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2187 {
2188   iCode *ic;
2189   int p2 = 0;
2190   sym_link *resType;
2191   sym_link *rtype = operandType (right);
2192   sym_link *retype = getSpec (rtype);
2193   sym_link *ltype = operandType (left);
2194   sym_link *letype = getSpec (ltype);
2195
2196   resType = usualBinaryConversions (&left, &right, resultType, '/');
2197
2198   /* if the right is a literal & power of 2
2199      and left is unsigned then make it a
2200      right shift */
2201   if (IS_LITERAL (retype) &&
2202       !IS_FLOAT (letype) &&
2203       !IS_FIXED (letype) &&
2204       IS_UNSIGNED(letype) &&
2205       (p2 = powof2 ((TYPE_UDWORD)
2206                     floatFromVal (right->operand.valOperand)))) {
2207     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2208   }
2209   else
2210     {
2211       ic = newiCode ('/', left, right);         /* normal division */
2212       /* if the size left or right > 1 then support routine */
2213       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2214         ic->supportRtn = 1;
2215     }
2216   IC_RESULT (ic) = newiTempOperand (resType, 0);
2217
2218   ADDTOCHAIN (ic);
2219   return IC_RESULT (ic);
2220 }
2221 /*-----------------------------------------------------------------*/
2222 /* geniCodeModulus  - gen intermediate code for modulus            */
2223 /*-----------------------------------------------------------------*/
2224 static operand *
2225 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2226 {
2227   iCode *ic;
2228   sym_link *resType;
2229   LRTYPE;
2230
2231   /* if they are both literal then we know the result */
2232   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2233     return operandFromValue (valMod (left->operand.valOperand,
2234                                      right->operand.valOperand));
2235
2236   resType = usualBinaryConversions (&left, &right, resultType, '%');
2237
2238   /* now they are the same size */
2239   ic = newiCode ('%', left, right);
2240
2241   /* if the size left or right > 1 then support routine */
2242   if (getSize (ltype) > 1 || getSize (rtype) > 1)
2243     ic->supportRtn = 1;
2244   IC_RESULT (ic) = newiTempOperand (resType, 0);
2245
2246   ADDTOCHAIN (ic);
2247   return IC_RESULT (ic);
2248 }
2249
2250 /*-----------------------------------------------------------------*/
2251 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
2252 /*-----------------------------------------------------------------*/
2253 operand *
2254 geniCodePtrPtrSubtract (operand * left, operand * right)
2255 {
2256   iCode *ic;
2257   operand *result;
2258   LRTYPE;
2259
2260   /* if they are both literals then */
2261   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2262     {
2263       result = operandFromValue (valMinus (left->operand.valOperand,
2264                                            right->operand.valOperand));
2265       goto subtractExit;
2266     }
2267
2268   ic = newiCode ('-', left, right);
2269
2270   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2271   ADDTOCHAIN (ic);
2272
2273 subtractExit:
2274   if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2275     return result;
2276   }
2277
2278   // should we really do this? is this ANSI?
2279   return geniCodeDivision (result,
2280                            operandFromLit (getSize (ltype->next)),
2281                            FALSE);
2282 }
2283
2284 /*-----------------------------------------------------------------*/
2285 /* geniCodeSubtract - generates code for subtraction               */
2286 /*-----------------------------------------------------------------*/
2287 static operand *
2288 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2289 {
2290   iCode *ic;
2291   int isarray = 0;
2292   sym_link *resType;
2293   LRTYPE;
2294
2295   /* if they both pointers then */
2296   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2297       (IS_PTR (rtype) || IS_ARRAY (rtype)))
2298     return geniCodePtrPtrSubtract (left, right);
2299
2300   /* if they are both literal then we know the result */
2301   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2302       && left->isLiteral && right->isLiteral)
2303     return operandFromValue (valMinus (left->operand.valOperand,
2304                                        right->operand.valOperand));
2305
2306   /* if left is an array or pointer */
2307   if (IS_PTR (ltype) || IS_ARRAY (ltype))
2308     {
2309       isarray = left->isaddr;
2310       right = geniCodeMultiply (right,
2311                                 operandFromLit (getSize (ltype->next)),
2312                                 (getArraySizePtr(left) >= INTSIZE) ?
2313                                   RESULT_TYPE_INT :
2314                                   RESULT_TYPE_CHAR);
2315       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2316     }
2317   else
2318     {                           /* make them the same size */
2319       resType = usualBinaryConversions (&left, &right, resultType, '-');
2320     }
2321
2322   ic = newiCode ('-', left, right);
2323
2324   IC_RESULT (ic) = newiTempOperand (resType, 1);
2325   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2326
2327   /* if left or right is a float */
2328   if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2329       || IS_FIXED (ltype) || IS_FIXED (rtype))
2330     ic->supportRtn = 1;
2331
2332   ADDTOCHAIN (ic);
2333   return IC_RESULT (ic);
2334 }
2335
2336 /*-----------------------------------------------------------------*/
2337 /* geniCodeAdd - generates iCode for addition                      */
2338 /*-----------------------------------------------------------------*/
2339 static operand *
2340 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2341 {
2342   iCode *ic;
2343   sym_link *resType;
2344   operand *size;
2345   int isarray = 0;
2346   bool indexUnsigned;
2347   LRTYPE;
2348
2349   /* if the right side is LITERAL zero */
2350   /* return the left side              */
2351   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2352     return left;
2353
2354   /* if left is literal zero return right */
2355   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2356     return right;
2357
2358   /* if left is a pointer then size */
2359   if (IS_PTR (ltype) || IS_ARRAY(ltype))
2360     {
2361       isarray = left->isaddr;
2362       // there is no need to multiply with 1
2363       if (getSize (ltype->next) != 1)
2364         {
2365           size  = operandFromLit (getSize (ltype->next));
2366           SPEC_USIGN (getSpec (operandType (size))) = 1;
2367           indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2368           right = geniCodeMultiply (right,
2369                                     size,
2370                                     (getArraySizePtr(left) >= INTSIZE) ?
2371                                       RESULT_TYPE_INT :
2372                                       RESULT_TYPE_CHAR);
2373           /* Even if right is a 'unsigned char',
2374              the result will be a 'signed int' due to the promotion rules.
2375              It doesn't make sense when accessing arrays, so let's fix it here: */
2376           if (indexUnsigned)
2377             SPEC_USIGN (getSpec (operandType (right))) = 1;
2378         }
2379       resType = copyLinkChain (ltype);
2380     }
2381   else
2382     { // make them the same size
2383       resType = usualBinaryConversions (&left, &right, resultType, '+');
2384     }
2385
2386   /* if they are both literals then we know */
2387   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2388       && left->isLiteral && right->isLiteral)
2389     return operandFromValue (valPlus (valFromType (ltype),
2390                                       valFromType (rtype)));
2391
2392   ic = newiCode ('+', left, right);
2393
2394   IC_RESULT (ic) = newiTempOperand (resType, 1);
2395   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2396
2397   /* if left or right is a float then support
2398      routine */
2399   if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2400       || IS_FIXED (ltype) || IS_FIXED (rtype))
2401     ic->supportRtn = 1;
2402
2403   ADDTOCHAIN (ic);
2404
2405   return IC_RESULT (ic);
2406
2407 }
2408
2409 /*-----------------------------------------------------------------*/
2410 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate"  */
2411 /*-----------------------------------------------------------------*/
2412 sym_link *
2413 aggrToPtr (sym_link * type, bool force)
2414 {
2415   sym_link *etype;
2416   sym_link *ptype;
2417
2418   if (IS_PTR (type) && !force)
2419     return type;
2420
2421   etype = getSpec (type);
2422   ptype = newLink (DECLARATOR);
2423
2424   ptype->next = type;
2425
2426   /* set the pointer depending on the storage class */
2427   DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2428   return ptype;
2429 }
2430
2431 /*------------------------------------------------------------------*/
2432 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2433 /*------------------------------------------------------------------*/
2434 int
2435 aggrToPtrDclType (sym_link * type, bool force)
2436 {
2437   if (IS_PTR (type) && !force)
2438     return DCL_TYPE (type);
2439
2440   /* return the pointer depending on the storage class */
2441   return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2442 }
2443
2444 /*-----------------------------------------------------------------*/
2445 /* geniCodeArray2Ptr - array to pointer                            */
2446 /*-----------------------------------------------------------------*/
2447 static operand *
2448 geniCodeArray2Ptr (operand * op)
2449 {
2450   sym_link *optype = operandType (op);
2451   sym_link *opetype = getSpec (optype);
2452
2453   /* set the pointer depending on the storage class */
2454   DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2455
2456   op->isaddr = 0;
2457   return op;
2458 }
2459
2460
2461 /*-----------------------------------------------------------------*/
2462 /* geniCodeArray - array access                                    */
2463 /*-----------------------------------------------------------------*/
2464 static operand *
2465 geniCodeArray (operand * left, operand * right, int lvl)
2466 {
2467   iCode *ic;
2468   operand *size;
2469   sym_link *ltype = operandType (left);
2470   bool indexUnsigned;
2471
2472   if (IS_PTR (ltype))
2473     {
2474       if (IS_PTR (ltype->next) && left->isaddr)
2475         {
2476           left = geniCodeRValue (left, FALSE);
2477         }
2478
2479       return geniCodeDerefPtr (geniCodeAdd (left,
2480                                             right,
2481                                             (getArraySizePtr(left) >= INTSIZE) ?
2482                                               RESULT_TYPE_INT :
2483                                               RESULT_TYPE_CHAR,
2484                                             lvl),
2485                                lvl);
2486     }
2487   size = operandFromLit (getSize (ltype->next));
2488   SPEC_USIGN (getSpec (operandType (size))) = 1;
2489   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2490   right = geniCodeMultiply (right,
2491                             size,
2492                             (getArraySizePtr(left) >= INTSIZE) ?
2493                               RESULT_TYPE_INT :
2494                               RESULT_TYPE_CHAR);
2495   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2496      It doesn't make sense when accessing arrays, so let's fix it here: */
2497   if (indexUnsigned)
2498     SPEC_USIGN (getSpec (operandType (right))) = 1;
2499   /* we can check for limits here */
2500   /* already done in SDCCast.c
2501   if (isOperandLiteral (right) &&
2502       IS_ARRAY (ltype) &&
2503       DCL_ELEM (ltype) &&
2504       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2505     {
2506       werror (W_IDX_OUT_OF_BOUNDS,
2507               (int) operandLitValue (right) / getSize (ltype->next),
2508               DCL_ELEM (ltype));
2509     }
2510   */
2511
2512   ic = newiCode ('+', left, right);
2513
2514   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2515                                       !IS_AGGREGATE (ltype->next) &&
2516                                       !IS_PTR (ltype->next))
2517                                      ? ltype : ltype->next), 0);
2518
2519   if (!IS_AGGREGATE (ltype->next))
2520     {
2521       IC_RESULT (ic)->isaddr = 1;
2522       IC_RESULT (ic)->aggr2ptr = 1;
2523     }
2524   ADDTOCHAIN (ic);
2525
2526   return IC_RESULT (ic);
2527 }
2528
2529 /*-----------------------------------------------------------------*/
2530 /* geniCodeStruct - generates intermediate code for structures     */
2531 /*-----------------------------------------------------------------*/
2532 operand *
2533 geniCodeStruct (operand * left, operand * right, bool islval)
2534 {
2535   iCode *ic;
2536   sym_link *type = operandType (left);
2537   sym_link *etype = getSpec (type);
2538   sym_link *retype;
2539   symbol *element = getStructElement (SPEC_STRUCT (etype),
2540                                       right->operand.symOperand);
2541
2542   wassert(IS_SYMOP(right));
2543
2544   /* add the offset */
2545   ic = newiCode ('+', left, operandFromLit (element->offset));
2546
2547   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2548
2549   /* preserve the storage & output class of the struct */
2550   /* as well as the volatile attribute */
2551   retype = getSpec (operandType (IC_RESULT (ic)));
2552   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2553   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2554   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2555   SPEC_CONST (retype) |= SPEC_CONST (etype);
2556
2557   if (IS_PTR (element->type))
2558     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2559
2560   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2561
2562   ADDTOCHAIN (ic);
2563   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2564 }
2565
2566 /*-----------------------------------------------------------------*/
2567 /* geniCodePostInc - generate int code for Post increment          */
2568 /*-----------------------------------------------------------------*/
2569 operand *
2570 geniCodePostInc (operand * op)
2571 {
2572   iCode *ic;
2573   operand *rOp;
2574   sym_link *optype = operandType (op);
2575   operand *result;
2576   operand *rv = (IS_ITEMP (op) ?
2577                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2578                  op);
2579   sym_link *rvtype = operandType (rv);
2580   int size = 0;
2581
2582   /* if this is not an address we have trouble */
2583   if (!op->isaddr)
2584     {
2585       werror (E_LVALUE_REQUIRED, "++");
2586       return op;
2587     }
2588
2589   rOp = newiTempOperand (rvtype, 0);
2590   OP_SYMBOL(rOp)->noSpilLoc = 1;
2591
2592   if (IS_ITEMP (rv))
2593     OP_SYMBOL(rv)->noSpilLoc = 1;
2594
2595   geniCodeAssign (rOp, rv, 0, 0);
2596
2597   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2598   if (size == 0)
2599     werror(W_SIZEOF_VOID);
2600   if (IS_FLOAT (rvtype))
2601     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2602   else
2603   if (IS_FIXED16X16 (rvtype))
2604     ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2605   else
2606     ic = newiCode ('+', rv, operandFromLit (size));
2607
2608   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2609   ADDTOCHAIN (ic);
2610
2611   geniCodeAssign (op, result, 0, 0);
2612
2613   return rOp;
2614
2615 }
2616
2617 /*-----------------------------------------------------------------*/
2618 /* geniCodePreInc - generate code for preIncrement                 */
2619 /*-----------------------------------------------------------------*/
2620 operand *
2621 geniCodePreInc (operand * op, bool lvalue)
2622 {
2623   iCode *ic;
2624   sym_link *optype = operandType (op);
2625   operand *rop = (IS_ITEMP (op) ?
2626                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2627                   op);
2628   sym_link *roptype = operandType (rop);
2629   operand *result;
2630   int size = 0;
2631
2632   if (!op->isaddr)
2633     {
2634       werror (E_LVALUE_REQUIRED, "++");
2635       return op;
2636     }
2637
2638   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2639   if (size == 0)
2640     werror(W_SIZEOF_VOID);
2641   if (IS_FLOAT (roptype))
2642     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2643   else
2644   if (IS_FIXED16X16 (roptype))
2645     ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2646   else
2647     ic = newiCode ('+', rop, operandFromLit (size));
2648   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2649   ADDTOCHAIN (ic);
2650
2651   (void) geniCodeAssign (op, result, 0, 0);
2652   if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2653     return op;
2654   else
2655     return result;
2656 }
2657
2658 /*-----------------------------------------------------------------*/
2659 /* geniCodePostDec - generates code for Post decrement             */
2660 /*-----------------------------------------------------------------*/
2661 operand *
2662 geniCodePostDec (operand * op)
2663 {
2664   iCode *ic;
2665   operand *rOp;
2666   sym_link *optype = operandType (op);
2667   operand *result;
2668   operand *rv = (IS_ITEMP (op) ?
2669                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2670                  op);
2671   sym_link *rvtype = operandType (rv);
2672   int size = 0;
2673
2674   /* if this is not an address we have trouble */
2675   if (!op->isaddr)
2676     {
2677       werror (E_LVALUE_REQUIRED, "--");
2678       return op;
2679     }
2680
2681   rOp = newiTempOperand (rvtype, 0);
2682   OP_SYMBOL(rOp)->noSpilLoc = 1;
2683
2684   if (IS_ITEMP (rv))
2685     OP_SYMBOL(rv)->noSpilLoc = 1;
2686
2687   geniCodeAssign (rOp, rv, 0, 0);
2688
2689   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2690   if (size == 0)
2691     werror(W_SIZEOF_VOID);
2692   if (IS_FLOAT (rvtype))
2693     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2694   else
2695   if (IS_FIXED16X16 (rvtype))
2696     ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2697   else
2698     ic = newiCode ('-', rv, operandFromLit (size));
2699
2700   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2701   ADDTOCHAIN (ic);
2702
2703   geniCodeAssign (op, result, 0, 0);
2704
2705   return rOp;
2706
2707 }
2708
2709 /*-----------------------------------------------------------------*/
2710 /* geniCodePreDec - generate code for pre  decrement               */
2711 /*-----------------------------------------------------------------*/
2712 operand *
2713 geniCodePreDec (operand * op, bool lvalue)
2714 {
2715   iCode *ic;
2716   sym_link *optype = operandType (op);
2717   operand *rop = (IS_ITEMP (op) ?
2718                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2719                   op);
2720   sym_link *roptype = operandType (rop);
2721   operand *result;
2722   int size = 0;
2723
2724   if (!op->isaddr)
2725     {
2726       werror (E_LVALUE_REQUIRED, "--");
2727       return op;
2728     }
2729
2730   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2731   if (size == 0)
2732     werror(W_SIZEOF_VOID);
2733   if (IS_FLOAT (roptype))
2734     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2735   else
2736   if (IS_FIXED16X16 (roptype))
2737     ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2738   else
2739     ic = newiCode ('-', rop, operandFromLit (size));
2740   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2741   ADDTOCHAIN (ic);
2742
2743   (void) geniCodeAssign (op, result, 0, 0);
2744   if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2745     return op;
2746   else
2747     return result;
2748 }
2749
2750
2751 /*-----------------------------------------------------------------*/
2752 /* geniCodeBitwise - gen int code for bitWise  operators           */
2753 /*-----------------------------------------------------------------*/
2754 operand *
2755 geniCodeBitwise (operand * left, operand * right,
2756                  int oper, sym_link * resType)
2757 {
2758   iCode *ic;
2759
2760   left = geniCodeCast (resType, left, TRUE);
2761   right = geniCodeCast (resType, right, TRUE);
2762
2763   ic = newiCode (oper, left, right);
2764   IC_RESULT (ic) = newiTempOperand (resType, 0);
2765
2766   ADDTOCHAIN (ic);
2767   return IC_RESULT (ic);
2768 }
2769
2770 /*-----------------------------------------------------------------*/
2771 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2772 /*-----------------------------------------------------------------*/
2773 operand *
2774 geniCodeAddressOf (operand * op)
2775 {
2776   iCode *ic;
2777   sym_link *p;
2778   sym_link *optype = operandType (op);
2779   sym_link *opetype = getSpec (optype);
2780
2781   if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2782     {
2783       op = operandFromOperand (op);
2784       op->isaddr = 0;
2785       return op;
2786     }
2787
2788   /* lvalue check already done in decorateType */
2789   /* this must be a lvalue */
2790 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2791 /*  werror (E_LVALUE_REQUIRED,"&"); */
2792 /*  return op; */
2793 /*     } */
2794
2795   p = newLink (DECLARATOR);
2796
2797   /* set the pointer depending on the storage class */
2798   DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2799
2800   p->next = copyLinkChain (optype);
2801
2802   /* if already a temp */
2803   if (IS_ITEMP (op))
2804     {
2805       setOperandType (op, p);
2806       op->isaddr = 0;
2807       return op;
2808     }
2809
2810   /* other wise make this of the type coming in */
2811   ic = newiCode (ADDRESS_OF, op, NULL);
2812   IC_RESULT (ic) = newiTempOperand (p, 1);
2813   IC_RESULT (ic)->isaddr = 0;
2814   ADDTOCHAIN (ic);
2815   return IC_RESULT (ic);
2816 }
2817 /*-----------------------------------------------------------------*/
2818 /* setOClass - sets the output class depending on the pointer type */
2819 /*-----------------------------------------------------------------*/
2820 void
2821 setOClass (sym_link * ptr, sym_link * spec)
2822 {
2823   switch (DCL_TYPE (ptr))
2824     {
2825     case POINTER:
2826       SPEC_OCLS (spec) = data;
2827       break;
2828
2829     case GPOINTER:
2830       SPEC_OCLS (spec) = generic;
2831       break;
2832
2833     case FPOINTER:
2834       SPEC_OCLS (spec) = xdata;
2835       break;
2836
2837     case CPOINTER:
2838       SPEC_OCLS (spec) = code;
2839       break;
2840
2841     case IPOINTER:
2842       SPEC_OCLS (spec) = idata;
2843       break;
2844
2845     case PPOINTER:
2846       SPEC_OCLS (spec) = xstack;
2847       break;
2848
2849     case EEPPOINTER:
2850       SPEC_OCLS (spec) = eeprom;
2851       break;
2852
2853     default:
2854       break;
2855
2856     }
2857 }
2858
2859 /*-----------------------------------------------------------------*/
2860 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2861 /*-----------------------------------------------------------------*/
2862 operand *
2863 geniCodeDerefPtr (operand * op,int lvl)
2864 {
2865   sym_link *rtype, *retype;
2866   sym_link *optype = operandType (op);
2867
2868   // if this is an array then array access
2869   if (IS_ARRAY (optype)) {
2870     // don't worry, this will be optimized out later
2871     return geniCodeArray (op, operandFromLit (0), lvl);
2872   }
2873
2874   // just in case someone screws up
2875   wassert (IS_PTR (optype));
2876
2877   if (IS_TRUE_SYMOP (op))
2878     {
2879       op->isaddr = 1;
2880       op = geniCodeRValue (op, TRUE);
2881     }
2882
2883   /* now get rid of the pointer part */
2884   if (isLvaluereq(lvl) && IS_ITEMP (op))
2885     {
2886       retype = getSpec (rtype = copyLinkChain (optype));
2887     }
2888   else
2889     {
2890       retype = getSpec (rtype = copyLinkChain (optype->next));
2891       /* outputclass needs 2b updated */
2892       setOClass (optype, retype);
2893     }
2894
2895   op->isGptr = IS_GENPTR (optype);
2896
2897   op->isaddr = (IS_PTR (rtype) ||
2898                 IS_STRUCT (rtype) ||
2899                 IS_INT (rtype) ||
2900                 IS_CHAR (rtype) ||
2901                 IS_FLOAT (rtype) ||
2902                 IS_FIXED (rtype));
2903
2904   if (!isLvaluereq(lvl))
2905     op = geniCodeRValue (op, TRUE);
2906
2907   setOperandType (op, rtype);
2908
2909   return op;
2910 }
2911
2912 /*-----------------------------------------------------------------*/
2913 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2914 /*-----------------------------------------------------------------*/
2915 operand *
2916 geniCodeUnaryMinus (operand * op)
2917 {
2918   iCode *ic;
2919   sym_link *optype = operandType (op);
2920
2921   if (IS_LITERAL (optype))
2922     return operandFromLit (-floatFromVal (op->operand.valOperand));
2923
2924   ic = newiCode (UNARYMINUS, op, NULL);
2925   IC_RESULT (ic) = newiTempOperand (optype, 0);
2926   ADDTOCHAIN (ic);
2927   return IC_RESULT (ic);
2928 }
2929
2930 /*-----------------------------------------------------------------*/
2931 /* geniCodeLeftShift - gen i code for left shift                   */
2932 /*-----------------------------------------------------------------*/
2933 operand *
2934 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2935 {
2936   iCode *ic;
2937   sym_link *resType;
2938
2939   ic = newiCode (LEFT_OP, left, right);
2940
2941   resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2942   IC_RESULT (ic) = newiTempOperand (resType, 0);
2943   ADDTOCHAIN (ic);
2944   return IC_RESULT (ic);
2945 }
2946
2947 /*-----------------------------------------------------------------*/
2948 /* geniCodeRightShift - gen i code for right shift                 */
2949 /*-----------------------------------------------------------------*/
2950 operand *
2951 geniCodeRightShift (operand * left, operand * right)
2952 {
2953   iCode *ic;
2954
2955   ic = newiCode (RIGHT_OP, left, right);
2956   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2957   ADDTOCHAIN (ic);
2958   return IC_RESULT (ic);
2959 }
2960
2961 /*-----------------------------------------------------------------*/
2962 /* geniCodeLogic- logic code                                       */
2963 /*-----------------------------------------------------------------*/
2964 static operand *
2965 geniCodeLogic (operand * left, operand * right, int op)
2966 {
2967   iCode *ic;
2968   sym_link *ctype;
2969   sym_link *rtype = operandType (right);
2970   sym_link *ltype = operandType (left);
2971
2972   /* left is integral type and right is literal then
2973      check if the literal value is within bounds */
2974   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2975     {
2976       checkConstantRange(ltype,
2977                          OP_VALUE(right), "compare operation", 1);
2978     }
2979
2980   /* if one operand is a pointer and the other is a literal generic void pointer,
2981      change the type of the literal generic void pointer to match the other pointer */
2982   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2983       && IS_PTR (rtype) && !IS_GENPTR(rtype))
2984     {
2985       /* find left's definition */
2986       ic = (iCode *) setFirstItem (iCodeChain);
2987       while (ic)
2988         {
2989           if (((ic->op == CAST) || (ic->op == '='))
2990               && isOperandEqual(left, IC_RESULT (ic)))
2991             break;
2992           else
2993             ic = setNextItem (iCodeChain);
2994         }
2995       /* if casting literal to generic pointer, then cast to rtype instead */
2996       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2997         {
2998           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2999           ltype = operandType(left);
3000         }
3001     }
3002   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3003       && IS_PTR (ltype) && !IS_GENPTR(ltype))
3004     {
3005       /* find right's definition */
3006       ic = (iCode *) setFirstItem (iCodeChain);
3007       while (ic)
3008         {
3009           if (((ic->op == CAST) || (ic->op == '='))
3010               && isOperandEqual(right, IC_RESULT (ic)))
3011             break;
3012           else
3013             ic = setNextItem (iCodeChain);
3014         }
3015       /* if casting literal to generic pointer, then cast to rtype instead */
3016       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3017         {
3018           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3019           rtype = operandType(right);
3020         }
3021     }
3022
3023   ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3024
3025   ic = newiCode (op, left, right);
3026   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3027
3028   /* if comparing float
3029      and not a '==' || '!=' || '&&' || '||' (these
3030      will be inlined */
3031   if (IS_FLOAT(ctype) &&
3032       op != EQ_OP &&
3033       op != NE_OP &&
3034       op != AND_OP &&
3035       op != OR_OP)
3036    ic->supportRtn = 1;
3037
3038   /* if comparing a fixed type use support functions */
3039   if (IS_FIXED(ctype))
3040     ic->supportRtn = 1;
3041
3042   ADDTOCHAIN (ic);
3043   return IC_RESULT (ic);
3044 }
3045
3046 /*-----------------------------------------------------------------*/
3047 /* geniCodeLogicAndOr - && || operations                           */
3048 /*-----------------------------------------------------------------*/
3049 static operand *
3050 geniCodeLogicAndOr (ast *tree, int lvl)
3051 {
3052   iCode *ic;
3053   symbol *falseLabel = newiTempLabel (NULL);
3054   symbol *trueLabel  = newiTempLabel (NULL);
3055   symbol *exitLabel  = newiTempLabel (NULL);
3056   operand *op, *result, *condition;
3057
3058   /* AND_OP and OR_OP are no longer generated because of bug-905492.
3059      They can be reenabled by executing the following block. If you find
3060      a decent optimization you could start right here:
3061   */
3062 #if 0
3063   if (0)
3064     {
3065        operand *leftOp, *rightOp;
3066
3067        leftOp  = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3068        rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3069
3070        return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3071     }
3072 #endif
3073
3074   /* generate two IFX for the '&&' or '||' op */
3075
3076   /* evaluate left operand */
3077   condition = ast2iCode (tree->left, lvl + 1);
3078   op = geniCodeRValue (condition, FALSE);
3079
3080   /* test left operand */
3081   if (tree->opval.op == AND_OP)
3082     ic = newiCodeCondition (op, NULL, falseLabel);
3083   else /* OR_OP */
3084     ic = newiCodeCondition (op, trueLabel, NULL);
3085   ADDTOCHAIN (ic);
3086
3087   /* evaluate right operand */
3088   condition = ast2iCode (tree->right, lvl + 1);
3089   op = geniCodeRValue (condition, FALSE);
3090
3091   /* test right operand */
3092   ic = newiCodeCondition (op, trueLabel, NULL);
3093   ADDTOCHAIN (ic);
3094
3095   /* store 0 or 1 in result */
3096   result = newiTempOperand (newCharLink(), 1);
3097
3098   geniCodeLabel (falseLabel);
3099   geniCodeAssign (result, operandFromLit (0), 0, 0);
3100   /* generate an unconditional goto */
3101   geniCodeGoto (exitLabel);
3102
3103   geniCodeLabel (trueLabel);
3104   geniCodeAssign (result, operandFromLit (1), 0, 0);
3105
3106   geniCodeLabel (exitLabel);
3107
3108   return result;
3109 }
3110
3111 /*-----------------------------------------------------------------*/
3112 /* geniCodeUnary - for a a generic unary operation                 */
3113 /*-----------------------------------------------------------------*/
3114 operand *
3115 geniCodeUnary (operand * op, int oper)
3116 {
3117   iCode *ic = newiCode (oper, op, NULL);
3118
3119   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3120   ADDTOCHAIN (ic);
3121   return IC_RESULT (ic);
3122 }
3123
3124 /*-----------------------------------------------------------------*/
3125 /* geniCodeConditional - geniCode for '?' ':' operation            */
3126 /*-----------------------------------------------------------------*/
3127 operand *
3128 geniCodeConditional (ast * tree,int lvl)
3129 {
3130   iCode *ic;
3131   symbol *falseLabel = newiTempLabel (NULL);
3132   symbol *exitLabel = newiTempLabel (NULL);
3133   operand *cond = ast2iCode (tree->left,lvl+1);
3134   operand *true, *false, *result;
3135
3136   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3137                           NULL, falseLabel);
3138   ADDTOCHAIN (ic);
3139
3140   true = ast2iCode (tree->right->left,lvl+1);
3141
3142   /* move the value to a new Operand */
3143   result = newiTempOperand (tree->right->ftype, 0);
3144   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3145
3146   /* generate an unconditional goto */
3147   geniCodeGoto (exitLabel);
3148
3149   /* now for the right side */
3150   geniCodeLabel (falseLabel);
3151
3152   false = ast2iCode (tree->right->right,lvl+1);
3153   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3154
3155   /* create the exit label */
3156   geniCodeLabel (exitLabel);
3157
3158   return result;
3159 }
3160
3161 /*-----------------------------------------------------------------*/
3162 /* geniCodeAssign - generate code for assignment                   */
3163 /*-----------------------------------------------------------------*/
3164 operand *
3165 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3166 {
3167   iCode *ic;
3168   sym_link *ltype = operandType (left);
3169   sym_link *rtype = operandType (right);
3170
3171   if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3172     {
3173       werror (E_LVALUE_REQUIRED, "assignment");
3174       return left;
3175     }
3176
3177   /* left is integral type and right is literal then
3178      check if the literal value is within bounds */
3179   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3180     {
3181       checkConstantRange(ltype,
3182                          OP_VALUE(right), "= operation", 0);
3183     }
3184
3185   /* if the left & right type don't exactly match */
3186   /* if pointer set then make sure the check is
3187      done with the type & not the pointer */
3188   /* then cast rights type to left */
3189
3190   /* first check the type for pointer assignement */
3191   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3192       compareType (ltype, rtype) <= 0)
3193     {
3194       if (compareType (ltype->next, rtype) < 0)
3195         right = geniCodeCast (ltype->next, right, TRUE);
3196     }
3197   else if (compareType (ltype, rtype) < 0)
3198     right = geniCodeCast (ltype, right, TRUE);
3199
3200   /* If left is a true symbol & ! volatile
3201      create an assignment to temporary for
3202      the right & then assign this temporary
3203      to the symbol. This is SSA (static single
3204      assignment). Isn't it simple and folks have
3205      published mountains of paper on it */
3206   if (IS_TRUE_SYMOP (left) &&
3207       !isOperandVolatile (left, FALSE) &&
3208       isOperandGlobal (left))
3209     {
3210       symbol *sym = NULL;
3211
3212       if (IS_TRUE_SYMOP (right))
3213         sym = OP_SYMBOL (right);
3214       ic = newiCode ('=', NULL, right);
3215       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3216       SPIL_LOC (right) = sym;
3217       ADDTOCHAIN (ic);
3218     }
3219
3220   ic = newiCode ('=', NULL, right);
3221   IC_RESULT (ic) = left;
3222   ADDTOCHAIN (ic);
3223
3224   /* if left isgptr flag is set then support
3225      routine will be required */
3226   if (left->isGptr)
3227     ic->supportRtn = 1;
3228
3229   ic->nosupdate = nosupdate;
3230   return left;
3231 }
3232
3233 /*-----------------------------------------------------------------*/
3234 /* geniCodeDummyRead - generate code for dummy read                */
3235 /*-----------------------------------------------------------------*/
3236 static void
3237 geniCodeDummyRead (operand * op)
3238 {
3239   iCode *ic;
3240   sym_link *type = operandType (op);
3241
3242   if (!IS_VOLATILE(type))
3243     return;
3244
3245   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3246   ADDTOCHAIN (ic);
3247
3248   ic->nosupdate = 1;
3249 }
3250
3251 /*-----------------------------------------------------------------*/
3252 /* geniCodeSEParms - generate code for side effecting fcalls       */
3253 /*-----------------------------------------------------------------*/
3254 static void
3255 geniCodeSEParms (ast * parms,int lvl)
3256 {
3257   if (!parms)
3258     return;
3259
3260   if (parms->type == EX_OP && parms->opval.op == PARAM)
3261     {
3262       geniCodeSEParms (parms->left,lvl);
3263       geniCodeSEParms (parms->right,lvl);
3264       return;
3265     }
3266
3267   /* hack don't like this but too lazy to think of
3268      something better */
3269   if (IS_ADDRESS_OF_OP (parms))
3270     parms->left->lvalue = 1;
3271
3272   if (IS_CAST_OP (parms) &&
3273       IS_PTR (parms->ftype) &&
3274       IS_ADDRESS_OF_OP (parms->right))
3275     parms->right->left->lvalue = 1;
3276
3277   parms->opval.oprnd =
3278     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3279
3280   parms->type = EX_OPERAND;
3281   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3282                 SPEC_ARGREG(parms->ftype);
3283 }
3284
3285 /*-----------------------------------------------------------------*/
3286 /* geniCodeParms - generates parameters                            */
3287 /*-----------------------------------------------------------------*/
3288 value *
3289 geniCodeParms (ast * parms, value *argVals, int *stack,
3290                sym_link * ftype, int lvl)
3291 {
3292   iCode *ic;
3293   operand *pval;
3294
3295   if (!parms)
3296     return argVals;
3297
3298   if (argVals==NULL) {
3299     // first argument
3300     argVals = FUNC_ARGS (ftype);
3301   }
3302
3303   /* if this is a param node then do the left & right */
3304   if (parms->type == EX_OP && parms->opval.op == PARAM)
3305     {
3306       argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3307       argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3308       return argVals;
3309     }
3310
3311   /* get the parameter value */
3312   if (parms->type == EX_OPERAND)
3313     pval = parms->opval.oprnd;
3314   else
3315     {
3316       /* maybe this else should go away ?? */
3317       /* hack don't like this but too lazy to think of
3318          something better */
3319       if (IS_ADDRESS_OF_OP (parms))
3320         parms->left->lvalue = 1;
3321
3322       if (IS_CAST_OP (parms) &&
3323           IS_PTR (parms->ftype) &&
3324           IS_ADDRESS_OF_OP (parms->right))
3325         parms->right->left->lvalue = 1;
3326
3327       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3328     }
3329
3330   /* if register parm then make it a send */
3331   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3332       IFFUNC_ISBUILTIN(ftype))
3333     {
3334       ic = newiCode (SEND, pval, NULL);
3335       ic->argreg = SPEC_ARGREG(parms->etype);
3336       ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3337       ADDTOCHAIN (ic);
3338     }
3339   else
3340     {
3341       /* now decide whether to push or assign */
3342       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3343         {
3344
3345           /* assign */
3346           operand *top = operandFromSymbol (argVals->sym);
3347           /* clear useDef and other bitVectors */
3348           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3349           geniCodeAssign (top, pval, 1, 0);
3350         }
3351       else
3352         {
3353           sym_link *p = operandType (pval);
3354           /* push */
3355           ic = newiCode (IPUSH, pval, NULL);
3356           ic->parmPush = 1;
3357           /* update the stack adjustment */
3358           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3359           ADDTOCHAIN (ic);
3360         }
3361     }
3362
3363   argVals=argVals->next;
3364   return argVals;
3365 }
3366
3367 /*-----------------------------------------------------------------*/
3368 /* geniCodeCall - generates temp code for calling                  */
3369 /*-----------------------------------------------------------------*/
3370 operand *
3371 geniCodeCall (operand * left, ast * parms,int lvl)
3372 {
3373   iCode *ic;
3374   operand *result;
3375   sym_link *type, *etype;
3376   sym_link *ftype;
3377   int stack = 0;
3378
3379   if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3380       !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3381     werror (E_FUNCTION_EXPECTED);
3382     return operandFromValue(valueFromLit(0));
3383   }
3384
3385   /* take care of parameters with side-effecting
3386      function calls in them, this is required to take care
3387      of overlaying function parameters */
3388   geniCodeSEParms (parms,lvl);
3389
3390   ftype = operandType (left);
3391   if (IS_FUNCPTR (ftype))
3392     ftype = ftype->next;
3393
3394   /* first the parameters */
3395   geniCodeParms (parms, NULL, &stack, ftype, lvl);
3396
3397   /* now call : if symbol then pcall */
3398   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3399     ic = newiCode (PCALL, left, NULL);
3400   } else {
3401     ic = newiCode (CALL, left, NULL);
3402   }
3403
3404   type = copyLinkChain (ftype->next);
3405   etype = getSpec (type);
3406   SPEC_EXTR (etype) = 0;
3407   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3408
3409   ADDTOCHAIN (ic);
3410
3411   /* stack adjustment after call */
3412   ic->parmBytes = stack;
3413
3414   return result;
3415 }
3416
3417 /*-----------------------------------------------------------------*/
3418 /* geniCodeReceive - generate intermediate code for "receive"      */
3419 /*-----------------------------------------------------------------*/
3420 static void
3421 geniCodeReceive (value * args)
3422 {
3423   unsigned char paramByteCounter = 0;
3424
3425   /* for all arguments that are passed in registers */
3426   while (args)
3427     {
3428       int first = 1;
3429       if (IS_REGPARM (args->etype))
3430         {
3431           operand *opr = operandFromValue (args);
3432           operand *opl;
3433           symbol *sym = OP_SYMBOL (opr);
3434           iCode *ic;
3435
3436           /* we will use it after all optimizations
3437              and before liveRange calculation */
3438           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3439             {
3440
3441               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3442                   options.stackAuto == 0 &&
3443                   (!(options.model == MODEL_FLAT24)) )
3444                 {
3445                 }
3446               else
3447                 {
3448                   opl = newiTempOperand (args->type, 0);
3449                   sym->reqv = opl;
3450                   sym->reqv->key = sym->key;
3451                   OP_SYMBOL (sym->reqv)->key = sym->key;
3452                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3453                   OP_SYMBOL (sym->reqv)->islocal = 0;
3454                   SPIL_LOC (sym->reqv) = sym;
3455                 }
3456             }
3457
3458           ic = newiCode (RECEIVE, NULL, NULL);
3459           ic->argreg = SPEC_ARGREG(args->etype);
3460           if (first) {
3461               currFunc->recvSize = getSize (sym->type);
3462               first = 0;
3463           }
3464           IC_RESULT (ic) = opr;
3465
3466           /* misuse of parmBytes (normally used for functions)
3467            * to save estimated stack position of this argument.
3468            * Normally this should be zero for RECEIVE iCodes.
3469            * No idea if this causes side effects on other ports. - dw
3470            */
3471           ic->parmBytes = paramByteCounter;
3472
3473           /* what stack position do we have? */
3474           paramByteCounter += getSize (sym->type);
3475
3476           ADDTOCHAIN (ic);
3477         }
3478
3479       args = args->next;
3480     }
3481 }
3482
3483 /*-----------------------------------------------------------------*/
3484 /* geniCodeFunctionBody - create the function body                 */
3485 /*-----------------------------------------------------------------*/
3486 void
3487 geniCodeFunctionBody (ast * tree,int lvl)
3488 {
3489   iCode *ic;
3490   operand *func;
3491   sym_link *fetype;
3492   int savelineno;
3493
3494   /* reset the auto generation */
3495   /* numbers */
3496   iTempNum = 0;
3497   iTempLblNum = 0;
3498   operandKey = 0;
3499   iCodeKey = 0;
3500   func = ast2iCode (tree->left,lvl+1);
3501   fetype = getSpec (operandType (func));
3502
3503   savelineno = lineno;
3504   lineno = OP_SYMBOL (func)->lineDef;
3505   /* create an entry label */
3506   geniCodeLabel (entryLabel);
3507   lineno = savelineno;
3508
3509   /* create a proc icode */
3510   ic = newiCode (FUNCTION, func, NULL);
3511   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3512   ic->tree = tree;
3513
3514   ADDTOCHAIN (ic);
3515
3516   /* for all parameters that are passed
3517      on registers add a "receive" */
3518   geniCodeReceive (tree->values.args);
3519
3520   /* generate code for the body */
3521   ast2iCode (tree->right,lvl+1);
3522
3523   /* create a label for return */
3524   geniCodeLabel (returnLabel);
3525
3526   /* now generate the end proc */
3527   ic = newiCode (ENDFUNCTION, func, NULL);
3528   ic->tree = tree;
3529   ADDTOCHAIN (ic);
3530   return;
3531 }
3532
3533 /*-----------------------------------------------------------------*/
3534 /* geniCodeReturn - gen icode for 'return' statement               */
3535 /*-----------------------------------------------------------------*/
3536 void
3537 geniCodeReturn (operand * op)
3538 {
3539   iCode *ic;
3540
3541   /* if the operand is present force an rvalue */
3542   if (op)
3543     op = geniCodeRValue (op, FALSE);
3544
3545   ic = newiCode (RETURN, op, NULL);
3546   ADDTOCHAIN (ic);
3547 }
3548
3549 /*-----------------------------------------------------------------*/
3550 /* geniCodeIfx - generates code for extended if statement          */
3551 /*-----------------------------------------------------------------*/
3552 void
3553 geniCodeIfx (ast * tree,int lvl)
3554 {
3555   iCode *ic;
3556   operand *condition = ast2iCode (tree->left,lvl+1);
3557   sym_link *cetype;
3558
3559   /* if condition is null then exit */
3560   if (!condition)
3561     goto exit;
3562   else
3563     condition = geniCodeRValue (condition, FALSE);
3564
3565   cetype = getSpec (operandType (condition));
3566   /* if the condition is a literal */
3567   if (IS_LITERAL (cetype))
3568     {
3569       if (floatFromVal (condition->operand.valOperand))
3570         {
3571           if (tree->trueLabel)
3572             geniCodeGoto (tree->trueLabel);
3573           else
3574             assert (0);
3575         }
3576       else
3577         {
3578           if (tree->falseLabel)
3579             geniCodeGoto (tree->falseLabel);
3580           else
3581             assert (0);
3582         }
3583       goto exit;
3584     }
3585
3586   if (tree->trueLabel)
3587     {
3588       ic = newiCodeCondition (condition,
3589                               tree->trueLabel,
3590                               NULL);
3591       ADDTOCHAIN (ic);
3592
3593       if (tree->falseLabel)
3594         geniCodeGoto (tree->falseLabel);
3595     }
3596   else
3597     {
3598       ic = newiCodeCondition (condition,
3599                               NULL,
3600                               tree->falseLabel);
3601       ADDTOCHAIN (ic);
3602     }
3603
3604 exit:
3605   ast2iCode (tree->right,lvl+1);
3606 }
3607
3608 /*-----------------------------------------------------------------*/
3609 /* geniCodeJumpTable - tries to create a jump table for switch     */
3610 /*-----------------------------------------------------------------*/
3611 int
3612 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3613 {
3614   int min, max, cnt = 1;
3615   int i, t;
3616   value *vch;
3617   iCode *ic;
3618   operand *boundary;
3619   symbol *falseLabel;
3620   set *labels = NULL;
3621   int needRangeCheck = !optimize.noJTabBoundary
3622                        || tree->values.switchVals.swDefault;
3623   sym_link *cetype = getSpec (operandType (cond));
3624   int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3625   int sizeofMatchJump, sizeofJumpTable;
3626   int sizeIndex;
3627
3628   if (!tree || !caseVals)
3629     return 0;
3630
3631   /* the criteria for creating a jump table is */
3632   /* all integer numbers between the maximum & minimum must */
3633   /* be present , the maximum value should not exceed 255 */
3634   /* If not all integer numbers are present the algorithm */
3635   /* inserts jumps to the default label for the missing numbers */
3636   /* and decides later whether it is worth it */
3637   min = (int) floatFromVal (vch = caseVals);
3638
3639   while (vch->next)
3640     {
3641       cnt++;
3642       vch = vch->next;
3643     }
3644   max = (int) floatFromVal (vch);
3645
3646   /* Exit if the range is too large to handle with a jump table. */
3647   if (1 + max - min > port->jumptableCost.maxCount)
3648     return 0;
3649
3650   switch (getSize (operandType (cond)))
3651     {
3652     case 1: sizeIndex = 0; break;
3653     case 2: sizeIndex = 1; break;
3654     case 4: sizeIndex = 2; break;
3655     default: return 0;
3656     }
3657
3658   /* Compute the size cost of the range check and subtraction. */
3659   sizeofMinCost = 0;
3660   sizeofZeroMinCost = 0;
3661   sizeofMaxCost = 0;
3662   if (needRangeCheck)
3663     {
3664       if (!(min==0 && IS_UNSIGNED (cetype)))
3665         sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3666       if (!IS_UNSIGNED (cetype))
3667         sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3668       sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3669     }
3670   if (min)
3671     sizeofMinCost += port->jumptableCost.sizeofSubtract;
3672
3673   /* If the size cost of handling a non-zero minimum exceeds the */
3674   /* cost of extending the range down to zero, then it might be */
3675   /* better to extend the range to zero. */
3676   if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3677                  >= (min * port->jumptableCost.sizeofElement))
3678     {
3679       /* Only extend the jump table if it would still be manageable. */
3680       if (1 + max <= port->jumptableCost.maxCount)
3681         {
3682           min = 0;
3683           if (IS_UNSIGNED (cetype))
3684             sizeofMinCost = 0;
3685           else
3686             sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3687         }
3688     }
3689
3690   /* Compute the total size cost of a jump table. */
3691   sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3692                      + port->jumptableCost.sizeofDispatch
3693                      + sizeofMinCost + sizeofMaxCost;
3694
3695   /* Compute the total size cost of a match & jump sequence */
3696   sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3697
3698   /* If the size cost of the jump table is uneconomical then exit */
3699   if (sizeofMatchJump <  sizeofJumpTable)
3700     return 0;
3701
3702   /* The jump table is preferable. */
3703
3704   /* First, a label for the default or missing cases. */
3705   if (tree->values.switchVals.swDefault)
3706     {
3707       SNPRINTF (buffer, sizeof(buffer),
3708                 "_default_%d",
3709                 tree->values.switchVals.swNum);
3710     }
3711   else
3712     {
3713       SNPRINTF (buffer, sizeof(buffer),
3714                 "_swBrk_%d",
3715                 tree->values.switchVals.swNum);
3716     }
3717   falseLabel = newiTempLabel (buffer);
3718
3719   /* Build the list of labels for the jump table. */
3720   vch = caseVals;
3721   t = (int) floatFromVal (vch);
3722   for (i=min; i<=max; i++)
3723     {
3724       if (vch && t==i)
3725         {
3726           /* Explicit case: make a new label for it. */
3727           SNPRINTF (buffer, sizeof(buffer),
3728                     "_case_%d_%d",
3729                     tree->values.switchVals.swNum,
3730                     i);
3731           addSet (&labels, newiTempLabel (buffer));
3732           vch = vch->next;
3733           if (vch)
3734             t = (int) floatFromVal (vch);
3735         }
3736       else
3737         {
3738           /* Implicit case: use the default label. */
3739           addSet (&labels, falseLabel);
3740         }
3741     }
3742
3743   /* first we rule out the boundary conditions */
3744   /* if only optimization says so */
3745   if (needRangeCheck)
3746     {
3747       sym_link *cetype = getSpec (operandType (cond));
3748       /* no need to check the lower bound if
3749          the condition is unsigned & minimum value is zero */
3750       if (!(min == 0 && IS_UNSIGNED (cetype)))
3751         {
3752           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3753           ic = newiCodeCondition (boundary, falseLabel, NULL);
3754           ADDTOCHAIN (ic);
3755         }
3756
3757       /* now for upper bounds */
3758       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3759       ic = newiCodeCondition (boundary, falseLabel, NULL);
3760       ADDTOCHAIN (ic);
3761     }
3762
3763   /* if the min is not zero then we no make it zero */
3764   if (min)
3765     {
3766       cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3767       if (!IS_LITERAL(getSpec(operandType(cond))))
3768         setOperandType (cond, UCHARTYPE);
3769     }
3770
3771   /* now create the jumptable */
3772   ic = newiCode (JUMPTABLE, NULL, NULL);
3773   IC_JTCOND (ic) = cond;
3774   IC_JTLABELS (ic) = labels;
3775   ADDTOCHAIN (ic);
3776   return 1;
3777 }
3778
3779 /*-----------------------------------------------------------------*/
3780 /* geniCodeSwitch - changes a switch to a if statement             */
3781 /*-----------------------------------------------------------------*/
3782 void
3783 geniCodeSwitch (ast * tree,int lvl)
3784 {
3785   iCode *ic;
3786   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3787   value *caseVals = tree->values.switchVals.swVals;
3788   symbol *trueLabel, *falseLabel;
3789
3790   /* If the condition is a literal, then just jump to the */
3791   /* appropriate case label. */
3792   if (IS_LITERAL(getSpec(operandType(cond))))
3793     {
3794       int switchVal, caseVal;
3795
3796       switchVal = (int) floatFromVal (cond->operand.valOperand);
3797       while (caseVals)
3798         {
3799           caseVal = (int) floatFromVal (caseVals);
3800           if (caseVal == switchVal)
3801             {
3802               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3803                         tree->values.switchVals.swNum, caseVal);
3804               trueLabel = newiTempLabel (buffer);
3805               geniCodeGoto (trueLabel);
3806               goto jumpTable;
3807             }
3808           caseVals = caseVals->next;
3809         }
3810       goto defaultOrBreak;
3811     }
3812
3813   /* If cond is volatile, it might change while we are trying to */
3814   /* find the matching case. To avoid this possibility, make a   */
3815   /* non-volatile copy to use instead. */
3816   if (IS_OP_VOLATILE (cond))
3817     {
3818       operand * newcond;
3819       iCode * ic;
3820
3821       newcond = newiTempOperand (operandType (cond), TRUE);
3822       newcond->isvolatile = 0;
3823       ic = newiCode ('=', NULL, cond);
3824       IC_RESULT (ic) = newcond;
3825       ADDTOCHAIN (ic);
3826       cond = newcond;
3827     }
3828
3829   /* if we can make this a jump table */
3830   if (geniCodeJumpTable (cond, caseVals, tree))
3831     goto jumpTable;             /* no need for the comparison */
3832
3833   /* for the cases defined do */
3834   while (caseVals)
3835     {
3836
3837       operand *compare = geniCodeLogic (cond,
3838                                         operandFromValue (caseVals),
3839                                         EQ_OP);
3840
3841       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3842                tree->values.switchVals.swNum,
3843                (int) floatFromVal (caseVals));
3844       trueLabel = newiTempLabel (buffer);
3845
3846       ic = newiCodeCondition (compare, trueLabel, NULL);
3847       ADDTOCHAIN (ic);
3848       caseVals = caseVals->next;
3849     }
3850
3851
3852 defaultOrBreak:
3853   /* if default is present then goto break else break */
3854   if (tree->values.switchVals.swDefault)
3855     {
3856         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3857     }
3858   else
3859     {
3860         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3861     }
3862
3863   falseLabel = newiTempLabel (buffer);
3864   geniCodeGoto (falseLabel);
3865
3866 jumpTable:
3867   ast2iCode (tree->right,lvl+1);
3868 }
3869
3870 /*-----------------------------------------------------------------*/
3871 /* geniCodeInline - intermediate code for inline assembler         */
3872 /*-----------------------------------------------------------------*/
3873 static void
3874 geniCodeInline (ast * tree)
3875 {
3876   iCode *ic;
3877
3878   ic = newiCode (INLINEASM, NULL, NULL);
3879   IC_INLINE (ic) = tree->values.inlineasm;
3880   ADDTOCHAIN (ic);
3881 }
3882
3883 /*-----------------------------------------------------------------*/
3884 /* geniCodeArrayInit - intermediate code for array initializer     */
3885 /*-----------------------------------------------------------------*/
3886 static void
3887 geniCodeArrayInit (ast * tree, operand *array)
3888 {
3889   iCode *ic;
3890
3891   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3892     ic = newiCode (ARRAYINIT, array, NULL);
3893     IC_ARRAYILIST (ic) = tree->values.constlist;
3894   } else {
3895     operand *left=newOperand(), *right=newOperand();
3896     left->type=right->type=SYMBOL;
3897     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3898     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3899     ic = newiCode (ARRAYINIT, left, right);
3900   }
3901   ADDTOCHAIN (ic);
3902 }
3903
3904 /*-----------------------------------------------------------------*/
3905 /* geniCodeCritical - intermediate code for a critical statement   */
3906 /*-----------------------------------------------------------------*/
3907 static void
3908 geniCodeCritical (ast *tree, int lvl)
3909 {
3910   iCode *ic;
3911   operand *op = NULL;
3912   sym_link *type;
3913
3914   if (!options.stackAuto)
3915     {
3916       type = newLink(SPECIFIER);
3917       SPEC_VOLATILE(type) = 1;
3918       SPEC_NOUN(type) = V_BIT;
3919       SPEC_SCLS(type) = S_BIT;
3920       SPEC_BLEN(type) = 1;
3921       SPEC_BSTR(type) = 0;
3922       op = newiTempOperand(type, 1);
3923     }
3924
3925   /* If op is NULL, the original interrupt state will saved on */
3926   /* the stack. Otherwise, it will be saved in op. */
3927
3928   /* Generate a save of the current interrupt state & disable */
3929   ic = newiCode (CRITICAL, NULL, NULL);
3930   IC_RESULT (ic) = op;
3931   ADDTOCHAIN (ic);
3932
3933   /* Generate the critical code sequence */
3934   if (tree->left && tree->left->type == EX_VALUE)
3935     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3936   else
3937     ast2iCode (tree->left,lvl+1);
3938
3939   /* Generate a restore of the original interrupt state */
3940   ic = newiCode (ENDCRITICAL, NULL, op);
3941   ADDTOCHAIN (ic);
3942 }
3943
3944 /*-----------------------------------------------------------------*/
3945 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3946 /* particular case. Ie : assigning or dereferencing array or ptr   */
3947 /*-----------------------------------------------------------------*/
3948 set * lvaluereqSet = NULL;
3949 typedef struct lvalItem
3950   {
3951     int req;
3952     int lvl;
3953   }
3954 lvalItem;
3955
3956 /*-----------------------------------------------------------------*/
3957 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3958 /*-----------------------------------------------------------------*/
3959 void addLvaluereq(int lvl)
3960 {
3961   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3962   lpItem->req=1;
3963   lpItem->lvl=lvl;
3964   addSetHead(&lvaluereqSet,lpItem);
3965
3966 }
3967 /*-----------------------------------------------------------------*/
3968 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3969 /*-----------------------------------------------------------------*/
3970 void delLvaluereq()
3971 {
3972   lvalItem * lpItem;
3973   lpItem = getSet(&lvaluereqSet);
3974   if(lpItem) Safe_free(lpItem);
3975 }
3976 /*-----------------------------------------------------------------*/
3977 /* clearLvaluereq - clear lvalreq flag                             */
3978 /*-----------------------------------------------------------------*/
3979 void clearLvaluereq()
3980 {
3981   lvalItem * lpItem;
3982   lpItem = peekSet(lvaluereqSet);
3983   if(lpItem) lpItem->req = 0;
3984 }
3985 /*-----------------------------------------------------------------*/
3986 /* getLvaluereq - get the last lvalreq level                       */
3987 /*-----------------------------------------------------------------*/
3988 int getLvaluereqLvl()
3989 {
3990   lvalItem * lpItem;
3991   lpItem = peekSet(lvaluereqSet);
3992   if(lpItem) return lpItem->lvl;
3993   return 0;
3994 }
3995 /*-----------------------------------------------------------------*/
3996 /* isLvaluereq - is lvalreq valid for this level ?                 */
3997 /*-----------------------------------------------------------------*/
3998 int isLvaluereq(int lvl)
3999 {
4000   lvalItem * lpItem;
4001   lpItem = peekSet(lvaluereqSet);
4002   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4003   return 0;
4004 }
4005
4006 /*-----------------------------------------------------------------*/
4007 /* ast2iCode - creates an icodeList from an ast                    */
4008 /*-----------------------------------------------------------------*/
4009 operand *
4010 ast2iCode (ast * tree,int lvl)
4011 {
4012   operand *left = NULL;
4013   operand *right = NULL;
4014   if (!tree)
4015     return NULL;
4016
4017   /* set the global variables for filename & line number */
4018   if (tree->filename)
4019     filename = tree->filename;
4020   if (tree->lineno)
4021     lineno = tree->lineno;
4022   if (tree->block)
4023     block = tree->block;
4024   if (tree->level)
4025     scopeLevel = tree->level;
4026   if (tree->seqPoint)
4027     seqPoint = tree->seqPoint;
4028
4029   if (tree->type == EX_VALUE)
4030     return operandFromValue (tree->opval.val);
4031
4032   if (tree->type == EX_LINK)
4033     return operandFromLink (tree->opval.lnk);
4034
4035   /* if we find a nullop */
4036   if (tree->type == EX_OP &&
4037      (tree->opval.op == NULLOP ||
4038      tree->opval.op == BLOCK))
4039     {
4040       if (tree->left && tree->left->type == EX_VALUE)
4041         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4042       else
4043         ast2iCode (tree->left,lvl+1);
4044       if (tree->right && tree->right->type == EX_VALUE)
4045         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4046       else
4047         ast2iCode (tree->right,lvl+1);
4048       return NULL;
4049     }
4050
4051   /* special cases for not evaluating */
4052   if (tree->opval.op != ':' &&
4053       tree->opval.op != '?' &&
4054       tree->opval.op != CALL &&
4055       tree->opval.op != IFX &&
4056       tree->opval.op != AND_OP &&
4057       tree->opval.op != OR_OP &&
4058       tree->opval.op != LABEL &&
4059       tree->opval.op != GOTO &&
4060       tree->opval.op != SWITCH &&
4061       tree->opval.op != FUNCTION &&
4062       tree->opval.op != INLINEASM &&
4063       tree->opval.op != CRITICAL)
4064     {
4065
4066         if (IS_ASSIGN_OP (tree->opval.op) ||
4067            IS_DEREF_OP (tree) ||
4068            (tree->opval.op == '&' && !tree->right) ||
4069            tree->opval.op == PTR_OP)
4070           {
4071             addLvaluereq(lvl);
4072             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4073                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4074               clearLvaluereq();
4075
4076             left = operandFromAst (tree->left,lvl);
4077             delLvaluereq();
4078             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4079               left = geniCodeRValue (left, TRUE);
4080           }
4081         else
4082           {
4083             left = operandFromAst (tree->left,lvl);
4084           }
4085         if (tree->opval.op == INC_OP ||
4086             tree->opval.op == DEC_OP)
4087           {
4088             addLvaluereq(lvl);
4089             right = operandFromAst (tree->right,lvl);
4090             delLvaluereq();
4091           }
4092         else
4093           {
4094             right = operandFromAst (tree->right,lvl);
4095           }
4096       }
4097
4098   /* now depending on the type of operand */
4099   /* this will be a biggy                 */
4100   switch (tree->opval.op)
4101     {
4102
4103     case '[':                   /* array operation */
4104       {
4105         //sym_link *ltype = operandType (left);
4106         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4107         left = geniCodeRValue (left, FALSE);
4108         right = geniCodeRValue (right, TRUE);
4109       }
4110
4111       return geniCodeArray (left, right,lvl);
4112
4113     case '.':                   /* structure dereference */
4114       if (IS_PTR (operandType (left)))
4115         left = geniCodeRValue (left, TRUE);
4116       else
4117         left = geniCodeRValue (left, FALSE);
4118
4119       return geniCodeStruct (left, right, tree->lvalue);
4120
4121     case PTR_OP:                /* structure pointer dereference */
4122       {
4123         sym_link *pType;
4124         pType = operandType (left);
4125         left = geniCodeRValue (left, TRUE);
4126
4127         setOClass (pType, getSpec (operandType (left)));
4128       }
4129
4130       return geniCodeStruct (left, right, tree->lvalue);
4131
4132     case INC_OP:                /* increment operator */
4133       if (left)
4134         return geniCodePostInc (left);
4135       else
4136         return geniCodePreInc (right, tree->lvalue);
4137
4138     case DEC_OP:                /* decrement operator */
4139       if (left)
4140         return geniCodePostDec (left);
4141       else
4142         return geniCodePreDec (right, tree->lvalue);
4143
4144     case '&':                   /* bitwise and or address of operator */
4145       if (right)
4146         {                       /* this is a bitwise operator   */
4147           left = geniCodeRValue (left, FALSE);
4148           right = geniCodeRValue (right, FALSE);
4149           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4150         }
4151       else
4152         return geniCodeAddressOf (left);
4153
4154     case '|':                   /* bitwise or & xor */
4155     case '^':
4156       return geniCodeBitwise (geniCodeRValue (left, FALSE),
4157                               geniCodeRValue (right, FALSE),
4158                               tree->opval.op,
4159                               tree->ftype);
4160
4161     case '/':
4162       return geniCodeDivision (geniCodeRValue (left, FALSE),
4163                                geniCodeRValue (right, FALSE),
4164                                getResultTypeFromType (tree->ftype));
4165
4166     case '%':
4167       return geniCodeModulus (geniCodeRValue (left, FALSE),
4168                               geniCodeRValue (right, FALSE),
4169                               getResultTypeFromType (tree->ftype));
4170     case '*':
4171       if (right)
4172         return geniCodeMultiply (geniCodeRValue (left, FALSE),
4173                                  geniCodeRValue (right, FALSE),
4174                                  getResultTypeFromType (tree->ftype));
4175       else
4176         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4177
4178     case '-':
4179       if (right)
4180         return geniCodeSubtract (geniCodeRValue (left, FALSE),
4181                                  geniCodeRValue (right, FALSE),
4182                                  getResultTypeFromType (tree->ftype));
4183       else
4184         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4185
4186     case '+':
4187       if (right)
4188         return geniCodeAdd (geniCodeRValue (left, FALSE),
4189                             geniCodeRValue (right, FALSE),
4190                             getResultTypeFromType (tree->ftype),
4191                             lvl);
4192       else
4193         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
4194
4195     case LEFT_OP:
4196       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4197                                 geniCodeRValue (right, FALSE),
4198                                 getResultTypeFromType (tree->ftype));
4199
4200     case RIGHT_OP:
4201       return geniCodeRightShift (geniCodeRValue (left, FALSE),
4202                                  geniCodeRValue (right, FALSE));
4203     case CAST:
4204 #if 0 // this indeed needs a second thought
4205       {
4206         operand *op;
4207
4208         // let's keep this simple: get the rvalue we need
4209         op=geniCodeRValue (right, FALSE);
4210         // now cast it to whatever we want
4211         op=geniCodeCast (operandType(left), op, FALSE);
4212         // if this is going to be used as an lvalue, make it so
4213         if (tree->lvalue) {
4214           op->isaddr=1;
4215         }
4216         return op;
4217       }
4218 #else // bug #604575, is it a bug ????
4219       return geniCodeCast (operandType (left),
4220                            geniCodeRValue (right, FALSE), FALSE);
4221 #endif
4222
4223     case '~':
4224     case RRC:
4225     case RLC:
4226     case SWAP:
4227       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4228
4229     case '!':
4230     case GETHBIT:
4231       {
4232         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4233         setOperandType (op, UCHARTYPE);
4234         return op;
4235       }
4236     case AND_OP:
4237     case OR_OP:
4238       return geniCodeLogicAndOr (tree, lvl);
4239     case '>':
4240     case '<':
4241     case LE_OP:
4242     case GE_OP:
4243     case EQ_OP:
4244     case NE_OP:
4245       /* different compilers (even different gccs) evaluate
4246          the two calls in a different order. to get the same
4247          result on all machines we've to specify a clear sequence.
4248       return geniCodeLogic (geniCodeRValue (left, FALSE),
4249                             geniCodeRValue (right, FALSE),
4250                             tree->opval.op);
4251       */
4252       {
4253         operand *leftOp, *rightOp;
4254
4255         leftOp  = geniCodeRValue (left , FALSE);
4256         rightOp = geniCodeRValue (right, FALSE);
4257
4258         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4259       }
4260     case '?':
4261       return geniCodeConditional (tree,lvl);
4262
4263     case SIZEOF:
4264       return operandFromLit (getSize (tree->right->ftype));
4265
4266     case '=':
4267       {
4268         sym_link *rtype = operandType (right);
4269         sym_link *ltype = operandType (left);
4270         if (IS_PTR (rtype) && IS_ITEMP (right)
4271             && right->isaddr && compareType (rtype->next, ltype) == 1)
4272           right = geniCodeRValue (right, TRUE);
4273         else
4274           right = geniCodeRValue (right, FALSE);
4275
4276         geniCodeAssign (left, right, 0, 1);
4277         return right;
4278       }
4279     case MUL_ASSIGN:
4280       return
4281         geniCodeAssign (left,
4282                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4283                                                   FALSE),
4284                                   geniCodeRValue (right, FALSE),
4285                                   getResultTypeFromType (tree->ftype)),
4286                         0, 1);
4287
4288     case DIV_ASSIGN:
4289       return
4290         geniCodeAssign (left,
4291                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4292                                                   FALSE),
4293                                   geniCodeRValue (right, FALSE),
4294                                   getResultTypeFromType (tree->ftype)),
4295                         0, 1);
4296     case MOD_ASSIGN:
4297       return
4298         geniCodeAssign (left,
4299                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4300                                                   FALSE),
4301                                   geniCodeRValue (right, FALSE),
4302                                   getResultTypeFromType (tree->ftype)),
4303                         0, 1);
4304     case ADD_ASSIGN:
4305       {
4306         sym_link *rtype = operandType (right);
4307         sym_link *ltype = operandType (left);
4308         if (IS_PTR (rtype) && IS_ITEMP (right)
4309             && right->isaddr && compareType (rtype->next, ltype) == 1)
4310           right = geniCodeRValue (right, TRUE);
4311         else
4312           right = geniCodeRValue (right, FALSE);
4313
4314
4315         return geniCodeAssign (left,
4316                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4317                                                   FALSE),
4318                                   right,
4319                                   getResultTypeFromType (tree->ftype),
4320                                   lvl),
4321                                0, 1);
4322       }
4323     case SUB_ASSIGN:
4324       {
4325         sym_link *rtype = operandType (right);
4326         sym_link *ltype = operandType (left);
4327         if (IS_PTR (rtype) && IS_ITEMP (right)
4328             && right->isaddr && compareType (rtype->next, ltype) == 1)
4329           {
4330             right = geniCodeRValue (right, TRUE);
4331           }
4332         else
4333           {
4334             right = geniCodeRValue (right, FALSE);
4335           }
4336         return
4337           geniCodeAssign (left,
4338                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4339                                                   FALSE),
4340                                   right,
4341                                   getResultTypeFromType (tree->ftype)),
4342                           0, 1);
4343       }
4344     case LEFT_ASSIGN:
4345       return
4346         geniCodeAssign (left,
4347                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4348                                                    ,FALSE),
4349                                    geniCodeRValue (right, FALSE),
4350                                    getResultTypeFromType (tree->ftype)),
4351                         0, 1);
4352     case RIGHT_ASSIGN:
4353       return
4354         geniCodeAssign (left,
4355                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4356                                                    ,FALSE),
4357                                    geniCodeRValue (right, FALSE)), 0, 1);
4358     case AND_ASSIGN:
4359       return
4360         geniCodeAssign (left,
4361                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4362                                                   FALSE),
4363                                   geniCodeRValue (right, FALSE),
4364                                   BITWISEAND,
4365                                   operandType (left)), 0, 1);
4366     case XOR_ASSIGN:
4367       return
4368         geniCodeAssign (left,
4369                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4370                                                   FALSE),
4371                                   geniCodeRValue (right, FALSE),
4372                                   '^',
4373                                   operandType (left)), 0, 1);
4374     case OR_ASSIGN:
4375       return
4376         geniCodeAssign (left,
4377                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4378                                                    ,FALSE),
4379                                    geniCodeRValue (right, FALSE),
4380                                    '|',
4381                                    operandType (left)), 0, 1);
4382     case ',':
4383       return geniCodeRValue (right, FALSE);
4384
4385     case CALL:
4386       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4387                            tree->right,lvl);
4388     case LABEL:
4389       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4390       return ast2iCode (tree->right,lvl+1);
4391
4392     case GOTO:
4393       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4394       return ast2iCode (tree->right,lvl+1);
4395
4396     case FUNCTION:
4397       geniCodeFunctionBody (tree,lvl);
4398       return NULL;
4399
4400     case RETURN:
4401       geniCodeReturn (right);
4402       return NULL;
4403
4404     case IFX:
4405       geniCodeIfx (tree,lvl);
4406       return NULL;
4407
4408     case SWITCH:
4409       geniCodeSwitch (tree,lvl);
4410       return NULL;
4411
4412     case INLINEASM:
4413       geniCodeInline (tree);
4414       return NULL;
4415
4416     case ARRAYINIT:
4417         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4418         return NULL;
4419
4420     case CRITICAL:
4421         geniCodeCritical (tree, lvl);
4422     }
4423
4424   return NULL;
4425 }
4426
4427 /*-----------------------------------------------------------------*/
4428 /* reverseICChain - gets from the list and creates a linkedlist    */
4429 /*-----------------------------------------------------------------*/
4430 iCode *
4431 reverseiCChain ()
4432 {
4433   iCode *loop = NULL;
4434   iCode *prev = NULL;
4435
4436   while ((loop = getSet (&iCodeChain)))
4437     {
4438       loop->next = prev;
4439       if (prev)
4440         prev->prev = loop;
4441       prev = loop;
4442     }
4443
4444   return prev;
4445 }
4446
4447
4448 /*-----------------------------------------------------------------*/
4449 /* iCodeFromAst - given an ast will convert it to iCode            */
4450 /*-----------------------------------------------------------------*/
4451 iCode *
4452 iCodeFromAst (ast * tree)
4453 {
4454   returnLabel = newiTempLabel ("_return");
4455   entryLabel = newiTempLabel ("_entry");
4456   ast2iCode (tree,0);
4457   return reverseiCChain ();
4458 }
4459
4460 static const char *opTypeToStr(OPTYPE op)
4461 {
4462     switch(op)
4463     {
4464       case SYMBOL: return "symbol";
4465       case VALUE: return "value";
4466       case TYPE: return "type";
4467     }
4468     return "undefined type";
4469 }
4470
4471
4472 operand *validateOpType(operand         *op,
4473                         const char      *macro,
4474                         const char      *args,
4475                         OPTYPE          type,
4476                         const char      *file,
4477                         unsigned        line)
4478 {
4479     if (op && op->type == type)
4480     {
4481         return op;
4482     }
4483     fprintf(stderr,
4484             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4485             " expected %s, got %s\n",
4486             macro, args, file, line,
4487             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4488     exit(-1);
4489     return op; // never reached, makes compiler happy.
4490 }