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