* support/Util/SDCCerr.h,
[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 static operand *geniCodeArray (operand *, operand *,int);
51 static 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 = operandFromValue (valCastLiteral (type,
1206                                  ((TYPE_UDWORD) operandLitValue (left) <<
1207                                   (TYPE_UDWORD) operandLitValue (right))));
1208       break;
1209     case RIGHT_OP:
1210       /* The number of right shifts is always unsigned. Signed doesn't make
1211          sense here. Shifting by a negative number is impossible. */
1212       if (IS_UNSIGNED(let))
1213         /* unsigned: logic shift right */
1214         retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1215                                  (TYPE_UDWORD) operandLitValue (right));
1216       else
1217         /* signed: arithmetic shift right */
1218         retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1219                                  (TYPE_UDWORD) operandLitValue (right));
1220       break;
1221     case EQ_OP:
1222       /* this op doesn't care about signedness */
1223       {
1224         TYPE_UDWORD l, r;
1225
1226         l = (TYPE_UDWORD) operandLitValue (left);
1227         if (IS_CHAR(OP_VALUE(left)->type))
1228           l &= 0xff;
1229         else if (!IS_LONG (OP_VALUE(left)->type))
1230           l &= 0xffff;
1231         r = (TYPE_UDWORD) operandLitValue (right);
1232         if (IS_CHAR(OP_VALUE(right)->type))
1233           r &= 0xff;
1234         else if (!IS_LONG (OP_VALUE(right)->type))
1235           r &= 0xffff;
1236         retval = operandFromLit (l == r);
1237       }
1238       break;
1239     case '<':
1240       retval = operandFromLit (operandLitValue (left) <
1241                                operandLitValue (right));
1242       break;
1243     case LE_OP:
1244       retval = operandFromLit (operandLitValue (left) <=
1245                                operandLitValue (right));
1246       break;
1247     case NE_OP:
1248       retval = operandFromLit (operandLitValue (left) !=
1249                                operandLitValue (right));
1250       break;
1251     case '>':
1252       retval = operandFromLit (operandLitValue (left) >
1253                                operandLitValue (right));
1254       break;
1255     case GE_OP:
1256       retval = operandFromLit (operandLitValue (left) >=
1257                                operandLitValue (right));
1258       break;
1259     case BITWISEAND:
1260       retval = operandFromValue (valCastLiteral (type,
1261                                                  (TYPE_UDWORD)operandLitValue(left) &
1262                                                  (TYPE_UDWORD)operandLitValue(right)));
1263       break;
1264     case '|':
1265       retval = operandFromValue (valCastLiteral (type,
1266                                                  (TYPE_UDWORD)operandLitValue(left) |
1267                                                  (TYPE_UDWORD)operandLitValue(right)));
1268       break;
1269     case '^':
1270       retval = operandFromValue (valCastLiteral (type,
1271                                                  (TYPE_UDWORD)operandLitValue(left) ^
1272                                                  (TYPE_UDWORD)operandLitValue(right)));
1273       break;
1274     case AND_OP:
1275       retval = operandFromLit (operandLitValue (left) &&
1276                                operandLitValue (right));
1277       break;
1278     case OR_OP:
1279       retval = operandFromLit (operandLitValue (left) ||
1280                                operandLitValue (right));
1281       break;
1282     case RRC:
1283       {
1284         TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1285
1286         retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1287                                  (i << 1));
1288       }
1289       break;
1290     case RLC:
1291       {
1292         TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1293
1294         retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1295                                  (i >> 1));
1296       }
1297       break;
1298
1299     case UNARYMINUS:
1300       retval = operandFromValue (valCastLiteral (type,
1301                                                  -1 * operandLitValue (left)));
1302       break;
1303
1304     case '~':
1305       retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1306       break;
1307
1308     case '!':
1309       retval = operandFromLit (!operandLitValue (left));
1310       break;
1311
1312     default:
1313       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1314               " operandOperation invalid operator ");
1315       assert (0);
1316     }
1317
1318   return retval;
1319 }
1320
1321
1322 /*-----------------------------------------------------------------*/
1323 /* isOperandEqual - compares two operand & return 1 if they r =    */
1324 /*-----------------------------------------------------------------*/
1325 int
1326 isOperandEqual (operand * left, operand * right)
1327 {
1328   /* if the pointers are equal then they are equal */
1329   if (left == right)
1330     return 1;
1331
1332   /* if either of them null then false */
1333   if (!left || !right)
1334     return 0;
1335
1336   if (left->type != right->type)
1337     return 0;
1338
1339   if (IS_SYMOP (left) && IS_SYMOP (right))
1340     return left->key == right->key;
1341
1342   /* if types are the same */
1343   switch (left->type)
1344     {
1345     case SYMBOL:
1346       return isSymbolEqual (left->operand.symOperand,
1347                             right->operand.symOperand);
1348     case VALUE:
1349       return (floatFromVal (left->operand.valOperand) ==
1350               floatFromVal (right->operand.valOperand));
1351     case TYPE:
1352       if (compareType (left->operand.typeOperand,
1353                      right->operand.typeOperand) == 1)
1354         return 1;
1355     }
1356
1357   return 0;
1358 }
1359
1360 /*-------------------------------------------------------------------*/
1361 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1362 /*-------------------------------------------------------------------*/
1363 int 
1364 isiCodeEqual (iCode * left, iCode * right)
1365 {
1366   /* if the same pointer */
1367   if (left == right)
1368     return 1;
1369
1370   /* if either of them null */
1371   if (!left || !right)
1372     return 0;
1373
1374   /* if operand are the same */
1375   if (left->op == right->op)
1376     {
1377
1378       /* compare all the elements depending on type */
1379       if (left->op != IFX)
1380         {
1381           if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1382             return 0;
1383           if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1384             return 0;
1385
1386         }
1387       else
1388         {
1389           if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1390             return 0;
1391           if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1392             return 0;
1393           if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1394             return 0;
1395         }
1396       
1397       return 1;
1398     }
1399   return 0;
1400 }
1401
1402 /*-----------------------------------------------------------------*/
1403 /* newiTempFromOp - create a temp Operand with same attributes     */
1404 /*-----------------------------------------------------------------*/
1405 operand *
1406 newiTempFromOp (operand * op)
1407 {
1408   operand *nop;
1409
1410   if (!op)
1411     return NULL;
1412
1413   if (!IS_ITEMP (op))
1414     return op;
1415
1416   nop = newiTempOperand (operandType (op), TRUE);
1417   nop->isaddr = op->isaddr;
1418   nop->isvolatile = op->isvolatile;
1419   nop->isGlobal = op->isGlobal;
1420   nop->isLiteral = op->isLiteral;
1421   nop->usesDefs = op->usesDefs;
1422   nop->isParm = op->isParm;
1423   return nop;
1424 }
1425
1426 /*-----------------------------------------------------------------*/
1427 /* operand from operand - creates an operand holder for the type   */
1428 /*-----------------------------------------------------------------*/
1429 operand *
1430 operandFromOperand (operand * op)
1431 {
1432   operand *nop;
1433
1434   if (!op)
1435     return NULL;
1436   nop = newOperand ();
1437   nop->type = op->type;
1438   nop->isaddr = op->isaddr;
1439   nop->key = op->key;
1440   nop->isvolatile = op->isvolatile;
1441   nop->isGlobal = op->isGlobal;
1442   nop->isLiteral = op->isLiteral;
1443   nop->usesDefs = op->usesDefs;
1444   nop->isParm = op->isParm;
1445   
1446   switch (nop->type)
1447     {
1448     case SYMBOL:
1449       nop->operand.symOperand = op->operand.symOperand;
1450       break;
1451     case VALUE:
1452       nop->operand.valOperand = op->operand.valOperand;
1453       break;
1454     case TYPE:
1455       nop->operand.typeOperand = op->operand.typeOperand;
1456       break;
1457     }
1458
1459   return nop;
1460 }
1461
1462 /*-----------------------------------------------------------------*/
1463 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
1464 /*-----------------------------------------------------------------*/
1465 operand *
1466 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1467 {
1468   operand *nop = operandFromOperand (op);
1469
1470   if (nop->type == SYMBOL)
1471     {
1472       OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1473       OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1474     }
1475
1476   return nop;
1477 }
1478
1479 /*-----------------------------------------------------------------*/
1480 /* operandFromSymbol - creates an operand from a symbol            */
1481 /*-----------------------------------------------------------------*/
1482 operand *
1483 operandFromSymbol (symbol * sym)
1484 {
1485   operand *op;
1486   iCode *ic;
1487   int ok = 1;
1488   /* if the symbol's type is a literal */
1489   /* then it is an enumerator type     */
1490   if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1491     return operandFromValue (valFromType (sym->etype));
1492
1493   if (!sym->key)
1494     sym->key = ++operandKey;
1495
1496   /* if this an implicit variable, means struct/union */
1497   /* member so just return it                         */
1498   if (sym->implicit || IS_FUNC (sym->type))
1499     {
1500       op = newOperand ();
1501       op->type = SYMBOL;
1502       op->operand.symOperand = sym;
1503       op->key = sym->key;
1504       op->isvolatile = isOperandVolatile (op, TRUE);
1505       op->isGlobal = isOperandGlobal (op);
1506       return op;
1507     }
1508
1509   /* under the following conditions create a
1510      register equivalent for a local symbol */
1511   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1512       (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1513       !TARGET_IS_HC08 &&
1514       (!(options.model == MODEL_FLAT24)) ) &&
1515       options.stackAuto == 0)
1516     ok = 0;
1517
1518   if (!IS_AGGREGATE (sym->type) &&      /* not an aggregate */
1519       !IS_FUNC (sym->type) &&   /* not a function   */
1520       !sym->_isparm &&          /* not a parameter  */
1521       sym->level &&             /* is a local variable */
1522       !sym->addrtaken &&        /* whose address has not been taken */
1523       !sym->reqv &&             /* does not already have a reg equivalence */
1524       !IS_VOLATILE (sym->etype) &&      /* not declared as volatile */
1525       !IS_STATIC (sym->etype) &&        /* and not declared static  */
1526       !sym->islbl &&            /* not a label */
1527       ok &&                     /* farspace check */
1528       !IS_BITVAR (sym->etype)   /* not a bit variable */
1529     )
1530     {                                   
1531
1532       /* we will use it after all optimizations
1533          and before liveRange calculation */
1534       sym->reqv = newiTempOperand (sym->type, 0);
1535       sym->reqv->key = sym->key;
1536       OP_SYMBOL (sym->reqv)->key = sym->key;
1537       OP_SYMBOL (sym->reqv)->isreqv = 1;
1538       OP_SYMBOL (sym->reqv)->islocal = 1;
1539       OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1540       SPIL_LOC (sym->reqv) = sym;
1541     }
1542
1543   if (!IS_AGGREGATE (sym->type))
1544     {
1545       op = newOperand ();
1546       op->type = SYMBOL;
1547       op->operand.symOperand = sym;
1548       op->isaddr = 1;
1549       op->key = sym->key;
1550       op->isvolatile = isOperandVolatile (op, TRUE);
1551       op->isGlobal = isOperandGlobal (op);
1552       op->isPtr = IS_PTR (operandType (op));
1553       op->isParm = sym->_isparm;
1554       return op;
1555     }
1556
1557   /* create :-                     */
1558   /*    itemp = &[_symbol]         */
1559
1560   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1561   IC_LEFT (ic)->type = SYMBOL;
1562   IC_LEFT (ic)->operand.symOperand = sym;
1563   IC_LEFT (ic)->key = sym->key;
1564   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1565   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1566   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1567
1568   /* create result */
1569   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1570   if (IS_ARRAY (sym->type))
1571     {
1572       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1573       IC_RESULT (ic)->isaddr = 0;
1574     }
1575   else
1576     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1577
1578   ADDTOCHAIN (ic);
1579
1580   return IC_RESULT (ic);
1581 }
1582
1583 /*-----------------------------------------------------------------*/
1584 /* operandFromValue - creates an operand from value                */
1585 /*-----------------------------------------------------------------*/
1586 operand *
1587 operandFromValue (value * val)
1588 {
1589   operand *op;
1590
1591   /* if this is a symbol then do the symbol thing */
1592   if (val->sym)
1593     return operandFromSymbol (val->sym);
1594
1595   /* this is not a symbol */
1596   op = newOperand ();
1597   op->type = VALUE;
1598   op->operand.valOperand = val;
1599   op->isLiteral = isOperandLiteral (op);
1600   return op;
1601 }
1602
1603 /*-----------------------------------------------------------------*/
1604 /* operandFromLink - operand from typeChain                        */
1605 /*-----------------------------------------------------------------*/
1606 operand *
1607 operandFromLink (sym_link * type)
1608 {
1609   operand *op;
1610
1611   /* operand from sym_link */
1612   if (!type)
1613     return NULL;
1614
1615   op = newOperand ();
1616   op->type = TYPE;
1617   op->operand.typeOperand = copyLinkChain (type);
1618   return op;
1619 }
1620
1621 /*-----------------------------------------------------------------*/
1622 /* operandFromLit - makes an operand from a literal value          */
1623 /*-----------------------------------------------------------------*/
1624 operand *
1625 operandFromLit (double i)
1626 {
1627   return operandFromValue (valueFromLit (i));
1628 }
1629
1630 /*-----------------------------------------------------------------*/
1631 /* operandFromAst - creates an operand from an ast                 */
1632 /*-----------------------------------------------------------------*/
1633 operand *
1634 operandFromAst (ast * tree,int lvl)
1635 {
1636
1637   if (!tree)
1638     return NULL;
1639
1640   /* depending on type do */
1641   switch (tree->type)
1642     {
1643     case EX_OP:
1644       return ast2iCode (tree,lvl+1);
1645       break;
1646
1647     case EX_VALUE:
1648       return operandFromValue (tree->opval.val);
1649       break;
1650
1651     case EX_LINK:
1652       return operandFromLink (tree->opval.lnk);
1653       break;
1654
1655     default:
1656       assert (0);
1657     }
1658   
1659   /*  Just to keep the compiler happy */
1660   return (operand *) 0;
1661 }
1662
1663 /*-----------------------------------------------------------------*/
1664 /* setOperandType - sets the operand's type to the given type      */
1665 /*-----------------------------------------------------------------*/
1666 void 
1667 setOperandType (operand * op, sym_link * type)
1668 {
1669   /* depending on the type of operand */
1670   switch (op->type)
1671     {
1672
1673     case VALUE:
1674       op->operand.valOperand->etype =
1675         getSpec (op->operand.valOperand->type =
1676                  copyLinkChain (type));
1677       return;
1678
1679     case SYMBOL:
1680       if (op->operand.symOperand->isitmp)
1681         op->operand.symOperand->etype =
1682           getSpec (op->operand.symOperand->type =
1683                    copyLinkChain (type));
1684       else
1685         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1686                 "attempt to modify type of source");
1687       return;
1688
1689     case TYPE:
1690       op->operand.typeOperand = copyLinkChain (type);
1691       return;
1692     }
1693
1694 }
1695 /*-----------------------------------------------------------------*/
1696 /* Get size in byte of ptr need to access an array                 */
1697 /*-----------------------------------------------------------------*/
1698 int
1699 getArraySizePtr (operand * op)
1700 {
1701   sym_link *ltype = operandType(op);
1702
1703   if(IS_PTR(ltype))
1704     {
1705       int size = getSize(ltype);
1706       return(IS_GENPTR(ltype)?(size-1):size);
1707     }
1708
1709   if(IS_ARRAY(ltype))
1710     {
1711       sym_link *letype = getSpec(ltype);
1712       switch (PTR_TYPE (SPEC_OCLS (letype)))
1713         {
1714         case IPOINTER:
1715         case PPOINTER:
1716         case POINTER:
1717           return (PTRSIZE);
1718         case EEPPOINTER:
1719         case FPOINTER:
1720         case CPOINTER:
1721         case FUNCTION:
1722           return (FPTRSIZE);
1723         case GPOINTER:
1724           return (GPTRSIZE-1);
1725
1726         default:
1727           return (FPTRSIZE);
1728         }
1729     }
1730   return (FPTRSIZE);
1731 }
1732
1733 /*-----------------------------------------------------------------*/
1734 /* perform "usual unary conversions"                               */
1735 /*-----------------------------------------------------------------*/
1736 #if 0
1737 static operand *
1738 usualUnaryConversions (operand * op)
1739 {
1740   if (IS_INTEGRAL (operandType (op)))
1741     {
1742       if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1743         {
1744           /* Widen to int. */
1745           return geniCodeCast (INTTYPE, op, TRUE);
1746         }
1747     }
1748   return op;
1749 }
1750 #endif
1751
1752 /*-----------------------------------------------------------------*/
1753 /* perform "usual binary conversions"                              */
1754 /*-----------------------------------------------------------------*/
1755 static sym_link *
1756 usualBinaryConversions (operand ** op1, operand ** op2,
1757                         bool promoteCharToInt, bool isMul)
1758 {
1759   sym_link *ctype;
1760   sym_link *rtype = operandType (*op2);
1761   sym_link *ltype = operandType (*op1);
1762
1763   ctype = computeType (ltype, rtype, promoteCharToInt);
1764
1765   /* special for multiplication:
1766      This if for 'mul a,b', which takes two chars and returns an int */
1767   if (   isMul
1768       /* && promoteCharToInt    superfluous, already handled by computeType() */
1769       && IS_INT  (getSpec (ctype)))
1770     {
1771       sym_link *retype = getSpec (rtype);
1772       sym_link *letype = getSpec (ltype);
1773
1774       if (   IS_CHAR (letype)
1775           && IS_CHAR (retype)
1776           && IS_UNSIGNED (letype)
1777           && IS_UNSIGNED (retype))
1778         {
1779           return ctype;
1780         }
1781     }
1782   *op1 = geniCodeCast (ctype, *op1, TRUE);
1783   *op2 = geniCodeCast (ctype, *op2, TRUE);
1784
1785   return ctype;
1786 }
1787
1788 /*-----------------------------------------------------------------*/
1789 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1790 /*                          at address                             */
1791 /*-----------------------------------------------------------------*/
1792 operand *
1793 geniCodeRValue (operand * op, bool force)
1794 {
1795   iCode *ic;
1796   sym_link *type = operandType (op);
1797   sym_link *etype = getSpec (type);
1798
1799   /* if this is an array & already */
1800   /* an address then return this   */
1801   if (IS_AGGREGATE (type) ||
1802       (IS_PTR (type) && !force && !op->isaddr))
1803     return operandFromOperand (op);
1804
1805   /* if this is not an address then must be */
1806   /* rvalue already so return this one      */
1807   if (!op->isaddr)
1808     return op;
1809
1810   /* if this is not a temp symbol then */
1811   if (!IS_ITEMP (op) &&
1812       !force &&
1813       !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1814     {
1815       op = operandFromOperand (op);
1816       op->isaddr = 0;
1817       return op;
1818     }
1819
1820   if (IS_SPEC (type) &&
1821       IS_TRUE_SYMOP (op) &&
1822       (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1823       (options.model == MODEL_FLAT24) ))
1824     {
1825       op = operandFromOperand (op);
1826       op->isaddr = 0;
1827       return op;
1828     }
1829
1830   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1831   if (IS_PTR (type) && op->isaddr && force)
1832     type = type->next;
1833
1834   type = copyLinkChain (type);
1835
1836   IC_RESULT (ic) = newiTempOperand (type, 1);
1837   IC_RESULT (ic)->isaddr = 0;
1838
1839 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1840
1841   ADDTOCHAIN (ic);
1842
1843   return IC_RESULT (ic);
1844 }
1845
1846 /*-----------------------------------------------------------------*/
1847 /* geniCodeCast - changes the value from one type to another       */
1848 /*-----------------------------------------------------------------*/
1849 static operand *
1850 geniCodeCast (sym_link * type, operand * op, bool implicit)
1851 {
1852   iCode *ic;
1853   sym_link *optype;
1854   sym_link *opetype = getSpec (optype = operandType (op));
1855   sym_link *restype;
1856   int errors=0;
1857
1858   /* one of them has size zero then error */
1859   if (IS_VOID (optype))
1860     {
1861       werror (E_CAST_ZERO);
1862       return op;
1863     }
1864
1865   if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1866     {
1867       geniCodeArray2Ptr (op);
1868       op->isaddr = 0;
1869     }
1870     
1871   /* if the operand is already the desired type then do nothing */
1872   if (compareType (type, optype) == 1)
1873     return op;
1874
1875   /* if this is a literal then just change the type & return */
1876   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1877     {
1878       return operandFromValue (valCastLiteral (type,
1879                                                operandLitValue (op)));
1880     }
1881
1882   /* if casting to/from pointers, do some checking */
1883   if (IS_PTR(type)) { // to a pointer
1884     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1885       if (IS_INTEGRAL(optype)) {
1886         // maybe this is NULL, than it's ok.
1887         if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1888           if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1889             // no way to set the storage
1890             if (IS_LITERAL(optype)) {
1891               werror(E_LITERAL_GENERIC);
1892               errors++;
1893             } else {
1894               werror(E_NONPTR2_GENPTR);
1895               errors++;
1896             }
1897           } else if (implicit) {
1898             werror(W_INTEGRAL2PTR_NOCAST);
1899             errors++;
1900           }
1901         }
1902       } else {
1903         // shouldn't do that with float, array or structure unless to void
1904         if (!IS_VOID(getSpec(type)) &&
1905             !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1906           werror(E_INCOMPAT_TYPES);
1907           errors++;
1908         }
1909       }
1910     } else { // from a pointer to a pointer
1911       if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1912         // if not a pointer to a function
1913         if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1914           if (implicit) { // if not to generic, they have to match
1915             if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1916               werror(E_INCOMPAT_PTYPES);
1917               errors++;
1918             }
1919           }
1920         }
1921       }
1922     }
1923   } else { // to a non pointer
1924     if (IS_PTR(optype)) { // from a pointer
1925       if (implicit) { // sneaky
1926         if (IS_INTEGRAL(type)) {
1927           werror(W_PTR2INTEGRAL_NOCAST);
1928           errors++;
1929         } else { // shouldn't do that with float, array or structure
1930           werror(E_INCOMPAT_TYPES);
1931           errors++;
1932         }
1933       }
1934     }
1935   }
1936   if (errors) {
1937     printFromToType (optype, type);
1938   }
1939
1940   /* if they are the same size create an assignment */
1941   
1942   /* This seems very dangerous to me, since there are several */
1943   /* optimizations (for example, gcse) that don't notice the  */
1944   /* cast hidden in this assignement and may simplify an      */
1945   /* iCode to use the original (uncasted) operand.            */
1946   /* Unfortunately, other things break when this cast is      */
1947   /* made explicit. Need to fix this someday.                 */
1948   /* -- EEP, 2004/01/21                                       */
1949   if (getSize (type) == getSize (optype) &&
1950       !IS_BITFIELD (type) &&
1951       !IS_FLOAT (type) &&
1952       !IS_FLOAT (optype) &&
1953       ((IS_SPEC (type) && IS_SPEC (optype)) ||
1954        (!IS_SPEC (type) && !IS_SPEC (optype))))
1955     {
1956       ic = newiCode ('=', NULL, op);
1957       IC_RESULT (ic) = newiTempOperand (type, 0);
1958       SPIL_LOC (IC_RESULT (ic)) =
1959         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1960       IC_RESULT (ic)->isaddr = 0;
1961     }
1962   else
1963     {
1964       ic = newiCode (CAST, operandFromLink (type),
1965                      geniCodeRValue (op, FALSE));
1966
1967       IC_RESULT (ic) = newiTempOperand (type, 0);
1968     }
1969
1970   /* preserve the storage class & output class */
1971   /* of the original variable                  */
1972   restype = getSpec (operandType (IC_RESULT (ic)));
1973   if (!IS_LITERAL(opetype))
1974       SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1975   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1976
1977   ADDTOCHAIN (ic);
1978   return IC_RESULT (ic);
1979 }
1980
1981 /*-----------------------------------------------------------------*/
1982 /* geniCodeLabel - will create a Label                             */
1983 /*-----------------------------------------------------------------*/
1984 void
1985 geniCodeLabel (symbol * label)
1986 {
1987   iCode *ic;
1988
1989   ic = newiCodeLabelGoto (LABEL, label);
1990   ADDTOCHAIN (ic);
1991 }
1992
1993 /*-----------------------------------------------------------------*/
1994 /* geniCodeGoto  - will create a Goto                              */
1995 /*-----------------------------------------------------------------*/
1996 void
1997 geniCodeGoto (symbol * label)
1998 {
1999   iCode *ic;
2000
2001   ic = newiCodeLabelGoto (GOTO, label);
2002   ADDTOCHAIN (ic);
2003 }
2004
2005 /*-----------------------------------------------------------------*/
2006 /* geniCodeMultiply - gen intermediate code for multiplication     */
2007 /*-----------------------------------------------------------------*/
2008 operand *
2009 geniCodeMultiply (operand * left, operand * right, int resultIsInt)
2010 {
2011   iCode *ic;
2012   int p2 = 0;
2013   sym_link *resType;
2014   LRTYPE;
2015
2016   /* if they are both literal then we know the result */
2017   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2018     return operandFromValue (valMult (left->operand.valOperand,
2019                                       right->operand.valOperand));
2020
2021   if (IS_LITERAL(retype)) {
2022     p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2023   }
2024
2025   resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
2026 #if 1
2027   rtype = operandType (right);
2028   retype = getSpec (rtype);
2029   ltype = operandType (left);
2030   letype = getSpec (ltype);
2031 #endif
2032
2033   /* if the right is a literal & power of 2 */
2034   /* then make it a left shift              */
2035   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2036      efficient in most cases than 2 bytes result = 2 bytes << literal
2037      if port has 1 byte muldiv */
2038   if (p2 && !IS_FLOAT (letype) &&
2039       !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2040         (port->support.muldiv == 1)))
2041     {
2042       if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2043         {
2044           /* LEFT_OP need same size for left and result, */
2045           left = geniCodeCast (resType, left, TRUE);
2046           ltype = operandType (left);
2047         }
2048       ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2049     }
2050   else
2051     {
2052       ic = newiCode ('*', left, right);         /* normal multiplication */
2053       /* if the size left or right > 1 then support routine */
2054       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2055         ic->supportRtn = 1;
2056
2057     }
2058   IC_RESULT (ic) = newiTempOperand (resType, 1);
2059
2060   ADDTOCHAIN (ic);
2061   return IC_RESULT (ic);
2062 }
2063
2064 /*-----------------------------------------------------------------*/
2065 /* geniCodeDivision - gen intermediate code for division           */
2066 /*-----------------------------------------------------------------*/
2067 operand *
2068 geniCodeDivision (operand * left, operand * right)
2069 {
2070   iCode *ic;
2071   int p2 = 0;
2072   sym_link *resType;
2073   sym_link *rtype = operandType (right);
2074   sym_link *retype = getSpec (rtype);
2075   sym_link *ltype = operandType (left);
2076   sym_link *letype = getSpec (ltype);
2077
2078   resType = usualBinaryConversions (&left, &right,
2079               (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2080               FALSE);
2081
2082   /* if the right is a literal & power of 2
2083      and left is unsigned then make it a
2084      right shift */
2085   if (IS_LITERAL (retype) &&
2086       !IS_FLOAT (letype) &&
2087       IS_UNSIGNED(letype) &&
2088       (p2 = powof2 ((TYPE_UDWORD)
2089                     floatFromVal (right->operand.valOperand)))) {
2090     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2091   }
2092   else
2093     {
2094       ic = newiCode ('/', left, right);         /* normal division */
2095       /* if the size left or right > 1 then support routine */
2096       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2097         ic->supportRtn = 1;
2098     }
2099   IC_RESULT (ic) = newiTempOperand (resType, 0);
2100
2101   ADDTOCHAIN (ic);
2102   return IC_RESULT (ic);
2103 }
2104 /*-----------------------------------------------------------------*/
2105 /* geniCodeModulus  - gen intermediate code for modulus            */
2106 /*-----------------------------------------------------------------*/
2107 operand *
2108 geniCodeModulus (operand * left, operand * right)
2109 {
2110   iCode *ic;
2111   sym_link *resType;
2112   LRTYPE;
2113
2114   /* if they are both literal then we know the result */
2115   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2116     return operandFromValue (valMod (left->operand.valOperand,
2117                                      right->operand.valOperand));
2118
2119   resType = usualBinaryConversions (&left, &right,
2120               (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2121               FALSE);
2122
2123   /* now they are the same size */
2124   ic = newiCode ('%', left, right);
2125
2126   /* if the size left or right > 1 then support routine */
2127   if (getSize (ltype) > 1 || getSize (rtype) > 1)
2128     ic->supportRtn = 1;
2129   IC_RESULT (ic) = newiTempOperand (resType, 0);
2130
2131   ADDTOCHAIN (ic);
2132   return IC_RESULT (ic);
2133 }
2134
2135 /*-----------------------------------------------------------------*/
2136 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
2137 /*-----------------------------------------------------------------*/
2138 operand *
2139 geniCodePtrPtrSubtract (operand * left, operand * right)
2140 {
2141   iCode *ic;
2142   operand *result;
2143   LRTYPE;
2144
2145   /* if they are both literals then */
2146   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2147     {
2148       result = operandFromValue (valMinus (left->operand.valOperand,
2149                                            right->operand.valOperand));
2150       goto subtractExit;
2151     }
2152
2153   ic = newiCode ('-', left, right);
2154
2155   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2156   ADDTOCHAIN (ic);
2157
2158 subtractExit:
2159   if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2160     return result;
2161   }
2162   
2163   // should we really do this? is this ANSI?
2164   return geniCodeDivision (result,
2165                            operandFromLit (getSize (ltype->next)));
2166 }
2167
2168 /*-----------------------------------------------------------------*/
2169 /* geniCodeSubtract - generates code for subtraction               */
2170 /*-----------------------------------------------------------------*/
2171 operand *
2172 geniCodeSubtract (operand * left, operand * right)
2173 {
2174   iCode *ic;
2175   int isarray = 0;
2176   sym_link *resType;
2177   LRTYPE;
2178
2179   /* if they both pointers then */
2180   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2181       (IS_PTR (rtype) || IS_ARRAY (rtype)))
2182     return geniCodePtrPtrSubtract (left, right);
2183
2184   /* if they are both literal then we know the result */
2185   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2186       && left->isLiteral && right->isLiteral)
2187     return operandFromValue (valMinus (left->operand.valOperand,
2188                                        right->operand.valOperand));
2189
2190   /* if left is an array or pointer */
2191   if (IS_PTR (ltype) || IS_ARRAY (ltype))
2192     {
2193       isarray = left->isaddr;
2194       right = geniCodeMultiply (right,
2195                                 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2196       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2197     }
2198   else
2199     {                           /* make them the same size */
2200       resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2201     }
2202
2203   ic = newiCode ('-', left, right);
2204
2205   IC_RESULT (ic) = newiTempOperand (resType, 1);
2206   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2207
2208   /* if left or right is a float */
2209   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2210     ic->supportRtn = 1;
2211
2212   ADDTOCHAIN (ic);
2213   return IC_RESULT (ic);
2214 }
2215
2216 /*-----------------------------------------------------------------*/
2217 /* geniCodeAdd - generates iCode for addition                      */
2218 /*-----------------------------------------------------------------*/
2219 operand *
2220 geniCodeAdd (operand * left, operand * right, int lvl)
2221 {
2222   iCode *ic;
2223   sym_link *resType;
2224   operand *size;
2225   int isarray = 0;
2226   bool indexUnsigned;
2227   LRTYPE;
2228
2229   /* if the right side is LITERAL zero */
2230   /* return the left side              */
2231   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2232     return left;
2233
2234   /* if left is literal zero return right */
2235   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2236     return right;
2237
2238   /* if left is a pointer then size */
2239   if (IS_PTR (ltype) || IS_ARRAY(ltype))
2240     {
2241       isarray = left->isaddr;
2242       // there is no need to multiply with 1
2243       if (getSize (ltype->next) != 1)
2244         {
2245           size  = operandFromLit (getSize (ltype->next));
2246           SPEC_USIGN (getSpec (operandType (size))) = 1;
2247           indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2248           right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2249           /* Even if right is a 'unsigned char',
2250              the result will be a 'signed int' due to the promotion rules.
2251              It doesn't make sense when accessing arrays, so let's fix it here: */
2252           if (indexUnsigned)
2253             SPEC_USIGN (getSpec (operandType (right))) = 1;
2254         }
2255       resType = copyLinkChain (ltype);
2256     }
2257   else
2258     { // make them the same size
2259       resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2260     }
2261
2262   /* if they are both literals then we know */
2263   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2264       && left->isLiteral && right->isLiteral)
2265     return operandFromValue (valPlus (valFromType (ltype),
2266                                       valFromType (rtype)));
2267
2268   ic = newiCode ('+', left, right);
2269
2270   IC_RESULT (ic) = newiTempOperand (resType, 1);
2271   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2272
2273   /* if left or right is a float then support
2274      routine */
2275   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2276     ic->supportRtn = 1;
2277
2278   ADDTOCHAIN (ic);
2279
2280   return IC_RESULT (ic);
2281
2282 }
2283
2284 /*-----------------------------------------------------------------*/
2285 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
2286 /*-----------------------------------------------------------------*/
2287 sym_link *
2288 aggrToPtr (sym_link * type, bool force)
2289 {
2290   sym_link *etype;
2291   sym_link *ptype;
2292
2293   if (IS_PTR (type) && !force)
2294     return type;
2295
2296   etype = getSpec (type);
2297   ptype = newLink (DECLARATOR);
2298
2299   ptype->next = type;
2300
2301   /* set the pointer depending on the storage class */
2302   DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2303   return ptype;
2304 }
2305
2306 /*-----------------------------------------------------------------*/
2307 /* geniCodeArray2Ptr - array to pointer                            */
2308 /*-----------------------------------------------------------------*/
2309 static operand *
2310 geniCodeArray2Ptr (operand * op)
2311 {
2312   sym_link *optype = operandType (op);
2313   sym_link *opetype = getSpec (optype);
2314
2315   /* set the pointer depending on the storage class */
2316   DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2317
2318   op->isaddr = 0;
2319   return op;
2320 }
2321
2322
2323 /*-----------------------------------------------------------------*/
2324 /* geniCodeArray - array access                                    */
2325 /*-----------------------------------------------------------------*/
2326 static operand *
2327 geniCodeArray (operand * left, operand * right, int lvl)
2328 {
2329   iCode *ic;
2330   operand *size;
2331   sym_link *ltype = operandType (left);
2332   bool indexUnsigned;
2333
2334   if (IS_PTR (ltype))
2335     {
2336       if (IS_PTR (ltype->next) && left->isaddr)
2337         {
2338           left = geniCodeRValue (left, FALSE);
2339         }
2340
2341       return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2342     }
2343   size = operandFromLit (getSize (ltype->next));
2344   SPEC_USIGN (getSpec (operandType (size))) = 1;
2345   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2346   right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2347   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2348      It doesn't make sense when accessing arrays, so let's fix it here: */
2349   if (indexUnsigned)
2350     SPEC_USIGN (getSpec (operandType (right))) = 1;
2351   /* we can check for limits here */
2352   /* already done in SDCCast.c
2353   if (isOperandLiteral (right) &&
2354       IS_ARRAY (ltype) &&
2355       DCL_ELEM (ltype) &&
2356       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2357     {
2358       werror (W_IDX_OUT_OF_BOUNDS,
2359               (int) operandLitValue (right) / getSize (ltype->next),
2360               DCL_ELEM (ltype));
2361     }
2362   */
2363
2364   ic = newiCode ('+', left, right);
2365
2366   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2367                                       !IS_AGGREGATE (ltype->next) &&
2368                                       !IS_PTR (ltype->next))
2369                                      ? ltype : ltype->next), 0);
2370
2371   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2372   ADDTOCHAIN (ic);
2373
2374   return IC_RESULT (ic);
2375 }
2376
2377 /*-----------------------------------------------------------------*/
2378 /* geniCodeStruct - generates intermediate code for structures     */
2379 /*-----------------------------------------------------------------*/
2380 operand *
2381 geniCodeStruct (operand * left, operand * right, bool islval)
2382 {
2383   iCode *ic;
2384   sym_link *type = operandType (left);
2385   sym_link *etype = getSpec (type);
2386   sym_link *retype;
2387   symbol *element = getStructElement (SPEC_STRUCT (etype),
2388                                       right->operand.symOperand);
2389
2390   wassert(IS_SYMOP(right));
2391     
2392   /* add the offset */
2393   ic = newiCode ('+', left, operandFromLit (element->offset));
2394
2395   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2396
2397   /* preserve the storage & output class of the struct */
2398   /* as well as the volatile attribute */
2399   retype = getSpec (operandType (IC_RESULT (ic)));
2400   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2401   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2402   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2403   SPEC_CONST (retype) |= SPEC_CONST (etype);
2404   
2405   if (IS_PTR (element->type))
2406     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2407   
2408   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2409
2410   ADDTOCHAIN (ic);
2411   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2412 }
2413
2414 /*-----------------------------------------------------------------*/
2415 /* geniCodePostInc - generate int code for Post increment          */
2416 /*-----------------------------------------------------------------*/
2417 operand *
2418 geniCodePostInc (operand * op)
2419 {
2420   iCode *ic;
2421   operand *rOp;
2422   sym_link *optype = operandType (op);
2423   operand *result;
2424   operand *rv = (IS_ITEMP (op) ?
2425                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2426                  op);
2427   sym_link *rvtype = operandType (rv);
2428   int size = 0;
2429
2430   /* if this is not an address we have trouble */
2431   if (!op->isaddr)
2432     {
2433       werror (E_LVALUE_REQUIRED, "++");
2434       return op;
2435     }
2436
2437   rOp = newiTempOperand (rvtype, 0);
2438   OP_SYMBOL(rOp)->noSpilLoc = 1;
2439
2440   if (IS_ITEMP (rv))
2441     OP_SYMBOL(rv)->noSpilLoc = 1;
2442
2443   geniCodeAssign (rOp, rv, 0);
2444
2445   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2446   if (IS_FLOAT (rvtype))
2447     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2448   else
2449     ic = newiCode ('+', rv, operandFromLit (size));
2450
2451   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2452   ADDTOCHAIN (ic);
2453
2454   geniCodeAssign (op, result, 0);
2455
2456   return rOp;
2457
2458 }
2459
2460 /*-----------------------------------------------------------------*/
2461 /* geniCodePreInc - generate code for preIncrement                 */
2462 /*-----------------------------------------------------------------*/
2463 operand *
2464 geniCodePreInc (operand * op, bool lvalue)
2465 {
2466   iCode *ic;
2467   sym_link *optype = operandType (op);
2468   operand *rop = (IS_ITEMP (op) ?
2469                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2470                   op);
2471   sym_link *roptype = operandType (rop);
2472   operand *result;
2473   int size = 0;
2474
2475   if (!op->isaddr)
2476     {
2477       werror (E_LVALUE_REQUIRED, "++");
2478       return op;
2479     }
2480
2481
2482   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2483   if (IS_FLOAT (roptype))
2484     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2485   else
2486     ic = newiCode ('+', rop, operandFromLit (size));
2487   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2488   ADDTOCHAIN (ic);
2489
2490   (void) geniCodeAssign (op, result, 0);
2491   if (lvalue || IS_TRUE_SYMOP (op))
2492     return op;
2493   else
2494     return result;
2495 }
2496
2497 /*-----------------------------------------------------------------*/
2498 /* geniCodePostDec - generates code for Post decrement             */
2499 /*-----------------------------------------------------------------*/
2500 operand *
2501 geniCodePostDec (operand * op)
2502 {
2503   iCode *ic;
2504   operand *rOp;
2505   sym_link *optype = operandType (op);
2506   operand *result;
2507   operand *rv = (IS_ITEMP (op) ?
2508                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2509                  op);
2510   sym_link *rvtype = operandType (rv);
2511   int size = 0;
2512
2513   /* if this is not an address we have trouble */
2514   if (!op->isaddr)
2515     {
2516       werror (E_LVALUE_REQUIRED, "--");
2517       return op;
2518     }
2519
2520   rOp = newiTempOperand (rvtype, 0);
2521   OP_SYMBOL(rOp)->noSpilLoc = 1;
2522
2523   if (IS_ITEMP (rv))
2524     OP_SYMBOL(rv)->noSpilLoc = 1;
2525
2526   geniCodeAssign (rOp, rv, 0);
2527
2528   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2529   if (IS_FLOAT (rvtype))
2530     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2531   else
2532     ic = newiCode ('-', rv, operandFromLit (size));
2533
2534   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2535   ADDTOCHAIN (ic);
2536
2537   geniCodeAssign (op, result, 0);
2538
2539   return rOp;
2540
2541 }
2542
2543 /*-----------------------------------------------------------------*/
2544 /* geniCodePreDec - generate code for pre  decrement               */
2545 /*-----------------------------------------------------------------*/
2546 operand *
2547 geniCodePreDec (operand * op, bool lvalue)
2548 {
2549   iCode *ic;
2550   sym_link *optype = operandType (op);
2551   operand *rop = (IS_ITEMP (op) ?
2552                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2553                   op);
2554   sym_link *roptype = operandType (rop);
2555   operand *result;
2556   int size = 0;
2557
2558   if (!op->isaddr)
2559     {
2560       werror (E_LVALUE_REQUIRED, "--");
2561       return op;
2562     }
2563
2564
2565   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2566   if (IS_FLOAT (roptype))
2567     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2568   else
2569     ic = newiCode ('-', rop, operandFromLit (size));
2570   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2571   ADDTOCHAIN (ic);
2572
2573   (void) geniCodeAssign (op, result, 0);
2574   if (lvalue || IS_TRUE_SYMOP (op))
2575     return op;
2576   else
2577     return result;
2578 }
2579
2580
2581 /*-----------------------------------------------------------------*/
2582 /* geniCodeBitwise - gen int code for bitWise  operators           */
2583 /*-----------------------------------------------------------------*/
2584 operand *
2585 geniCodeBitwise (operand * left, operand * right,
2586                  int oper, sym_link * resType)
2587 {
2588   iCode *ic;
2589
2590   left = geniCodeCast (resType, left, TRUE);
2591   right = geniCodeCast (resType, right, TRUE);
2592
2593   ic = newiCode (oper, left, right);
2594   IC_RESULT (ic) = newiTempOperand (resType, 0);
2595
2596   ADDTOCHAIN (ic);
2597   return IC_RESULT (ic);
2598 }
2599
2600 /*-----------------------------------------------------------------*/
2601 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2602 /*-----------------------------------------------------------------*/
2603 operand *
2604 geniCodeAddressOf (operand * op)
2605 {
2606   iCode *ic;
2607   sym_link *p;
2608   sym_link *optype = operandType (op);
2609   sym_link *opetype = getSpec (optype);
2610
2611   if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2612     {
2613       op = operandFromOperand (op);
2614       op->isaddr = 0;
2615       return op;
2616     }
2617   
2618   /* lvalue check already done in decorateType */
2619   /* this must be a lvalue */
2620 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2621 /*  werror (E_LVALUE_REQUIRED,"&"); */
2622 /*  return op; */
2623 /*     } */
2624
2625   p = newLink (DECLARATOR);
2626
2627   /* set the pointer depending on the storage class */
2628   DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2629
2630   p->next = copyLinkChain (optype);
2631
2632   /* if already a temp */
2633   if (IS_ITEMP (op))
2634     {
2635       setOperandType (op, p);
2636       op->isaddr = 0;
2637       return op;
2638     }
2639
2640   /* other wise make this of the type coming in */
2641   ic = newiCode (ADDRESS_OF, op, NULL);
2642   IC_RESULT (ic) = newiTempOperand (p, 1);
2643   IC_RESULT (ic)->isaddr = 0;
2644   ADDTOCHAIN (ic);
2645   return IC_RESULT (ic);
2646 }
2647 /*-----------------------------------------------------------------*/
2648 /* setOClass - sets the output class depending on the pointer type */
2649 /*-----------------------------------------------------------------*/
2650 void 
2651 setOClass (sym_link * ptr, sym_link * spec)
2652 {
2653   switch (DCL_TYPE (ptr))
2654     {
2655     case POINTER:
2656       SPEC_OCLS (spec) = data;
2657       break;
2658
2659     case GPOINTER:
2660       SPEC_OCLS (spec) = generic;
2661       break;
2662
2663     case FPOINTER:
2664       SPEC_OCLS (spec) = xdata;
2665       break;
2666
2667     case CPOINTER:
2668       SPEC_OCLS (spec) = code;
2669       break;
2670
2671     case IPOINTER:
2672       SPEC_OCLS (spec) = idata;
2673       break;
2674
2675     case PPOINTER:
2676       SPEC_OCLS (spec) = xstack;
2677       break;
2678
2679     case EEPPOINTER:
2680       SPEC_OCLS (spec) = eeprom;
2681       break;
2682
2683     default:
2684       break;
2685
2686     }
2687 }
2688
2689 /*-----------------------------------------------------------------*/
2690 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2691 /*-----------------------------------------------------------------*/
2692 operand *
2693 geniCodeDerefPtr (operand * op,int lvl)
2694 {
2695   sym_link *rtype, *retype;
2696   sym_link *optype = operandType (op);
2697
2698   // if this is an array then array access
2699   if (IS_ARRAY (optype)) {
2700     // don't worry, this will be optimized out later
2701     return geniCodeArray (op, operandFromLit (0), lvl);
2702   }
2703
2704   // just in case someone screws up
2705   wassert (IS_PTR (optype));
2706
2707   if (IS_TRUE_SYMOP (op))
2708     {
2709       op->isaddr = 1;
2710       op = geniCodeRValue (op, TRUE);
2711     }
2712
2713   /* now get rid of the pointer part */
2714   if (isLvaluereq(lvl) && IS_ITEMP (op))
2715     {
2716       retype = getSpec (rtype = copyLinkChain (optype));
2717     }
2718   else
2719     {
2720       retype = getSpec (rtype = copyLinkChain (optype->next));
2721       /* outputclass needs 2b updated */
2722       setOClass (optype, retype);
2723     }
2724   
2725   op->isGptr = IS_GENPTR (optype);
2726
2727   op->isaddr = (IS_PTR (rtype) ||
2728                 IS_STRUCT (rtype) ||
2729                 IS_INT (rtype) ||
2730                 IS_CHAR (rtype) ||
2731                 IS_FLOAT (rtype));
2732
2733   if (!isLvaluereq(lvl))
2734     op = geniCodeRValue (op, TRUE);
2735
2736   setOperandType (op, rtype);
2737
2738   return op;
2739 }
2740
2741 /*-----------------------------------------------------------------*/
2742 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2743 /*-----------------------------------------------------------------*/
2744 operand *
2745 geniCodeUnaryMinus (operand * op)
2746 {
2747   iCode *ic;
2748   sym_link *optype = operandType (op);
2749
2750   if (IS_LITERAL (optype))
2751     return operandFromLit (-floatFromVal (op->operand.valOperand));
2752
2753   ic = newiCode (UNARYMINUS, op, NULL);
2754   IC_RESULT (ic) = newiTempOperand (optype, 0);
2755   ADDTOCHAIN (ic);
2756   return IC_RESULT (ic);
2757 }
2758
2759 /*-----------------------------------------------------------------*/
2760 /* geniCodeLeftShift - gen i code for left shift                   */
2761 /*-----------------------------------------------------------------*/
2762 operand *
2763 geniCodeLeftShift (operand * left, operand * right)
2764 {
2765   iCode *ic;
2766
2767   ic = newiCode (LEFT_OP, left, right);
2768   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2769   ADDTOCHAIN (ic);
2770   return IC_RESULT (ic);
2771 }
2772
2773 /*-----------------------------------------------------------------*/
2774 /* geniCodeRightShift - gen i code for right shift                 */
2775 /*-----------------------------------------------------------------*/
2776 operand *
2777 geniCodeRightShift (operand * left, operand * right)
2778 {
2779   iCode *ic;
2780
2781   ic = newiCode (RIGHT_OP, left, right);
2782   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2783   ADDTOCHAIN (ic);
2784   return IC_RESULT (ic);
2785 }
2786
2787 /*-----------------------------------------------------------------*/
2788 /* geniCodeLogic- logic code                                       */
2789 /*-----------------------------------------------------------------*/
2790 operand *
2791 geniCodeLogic (operand * left, operand * right, int op)
2792 {
2793   iCode *ic;
2794   sym_link *ctype;
2795   sym_link *rtype = operandType (right);
2796   sym_link *ltype = operandType (left);
2797
2798   /* left is integral type and right is literal then
2799      check if the literal value is within bounds */
2800   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2801     {
2802       checkConstantRange(ltype,
2803                          OP_VALUE(right), "compare operation", 1);
2804     }
2805
2806   /* if one operand is a pointer and the other is a literal generic void pointer,
2807      change the type of the literal generic void pointer to match the other pointer */
2808   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2809       && IS_PTR (rtype) && !IS_GENPTR(rtype))
2810     {
2811       /* find left's definition */
2812       ic = (iCode *) setFirstItem (iCodeChain);
2813       while (ic)
2814         {
2815           if (((ic->op == CAST) || (ic->op == '='))
2816               && isOperandEqual(left, IC_RESULT (ic)))
2817             break;
2818           else
2819             ic = setNextItem (iCodeChain);
2820         }
2821       /* if casting literal to generic pointer, then cast to rtype instead */
2822       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2823         {
2824           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2825           ltype = operandType(left);
2826         }
2827     }
2828   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2829       && IS_PTR (ltype) && !IS_GENPTR(ltype))
2830     {
2831       /* find right's definition */
2832       ic = (iCode *) setFirstItem (iCodeChain);
2833       while (ic)
2834         {
2835           if (((ic->op == CAST) || (ic->op == '='))
2836               && isOperandEqual(right, IC_RESULT (ic)))
2837             break;
2838           else
2839             ic = setNextItem (iCodeChain);
2840         }
2841       /* if casting literal to generic pointer, then cast to rtype instead */
2842       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2843         {
2844           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2845           rtype = operandType(right);
2846         }
2847     }
2848
2849   ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2850
2851   ic = newiCode (op, left, right);
2852   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2853
2854   /* if comparing float
2855      and not a '==' || '!=' || '&&' || '||' (these
2856      will be inlined */
2857   if (IS_FLOAT(ctype) &&
2858       op != EQ_OP &&
2859       op != NE_OP &&
2860       op != AND_OP &&
2861       op != OR_OP)
2862     ic->supportRtn = 1;
2863
2864   ADDTOCHAIN (ic);
2865   return IC_RESULT (ic);
2866 }
2867
2868 /*-----------------------------------------------------------------*/
2869 /* geniCodeUnary - for a a generic unary operation                 */
2870 /*-----------------------------------------------------------------*/
2871 operand *
2872 geniCodeUnary (operand * op, int oper)
2873 {
2874   iCode *ic = newiCode (oper, op, NULL);
2875
2876   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2877   ADDTOCHAIN (ic);
2878   return IC_RESULT (ic);
2879 }
2880
2881 /*-----------------------------------------------------------------*/
2882 /* geniCodeConditional - geniCode for '?' ':' operation            */
2883 /*-----------------------------------------------------------------*/
2884 operand *
2885 geniCodeConditional (ast * tree,int lvl)
2886 {
2887   iCode *ic;
2888   symbol *falseLabel = newiTempLabel (NULL);
2889   symbol *exitLabel = newiTempLabel (NULL);
2890   operand *cond = ast2iCode (tree->left,lvl+1);
2891   operand *true, *false, *result;
2892
2893   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2894                           NULL, falseLabel);
2895   ADDTOCHAIN (ic);
2896
2897   true = ast2iCode (tree->right->left,lvl+1);
2898
2899   /* move the value to a new Operand */
2900   result = newiTempOperand (tree->right->ftype, 0);
2901   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2902
2903   /* generate an unconditional goto */
2904   geniCodeGoto (exitLabel);
2905
2906   /* now for the right side */
2907   geniCodeLabel (falseLabel);
2908
2909   false = ast2iCode (tree->right->right,lvl+1);
2910   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2911
2912   /* create the exit label */
2913   geniCodeLabel (exitLabel);
2914
2915   return result;
2916 }
2917
2918 /*-----------------------------------------------------------------*/
2919 /* geniCodeAssign - generate code for assignment                   */
2920 /*-----------------------------------------------------------------*/
2921 operand *
2922 geniCodeAssign (operand * left, operand * right, int nosupdate)
2923 {
2924   iCode *ic;
2925   sym_link *ltype = operandType (left);
2926   sym_link *rtype = operandType (right);
2927
2928   if (!left->isaddr && !IS_ITEMP (left))
2929     {
2930       werror (E_LVALUE_REQUIRED, "assignment");
2931       return left;
2932     }
2933
2934   /* left is integral type and right is literal then
2935      check if the literal value is within bounds */
2936   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2937     {
2938       checkConstantRange(ltype, 
2939                          OP_VALUE(right), "= operation", 0);
2940     }
2941
2942   /* if the left & right type don't exactly match */
2943   /* if pointer set then make sure the check is
2944      done with the type & not the pointer */
2945   /* then cast rights type to left */
2946
2947   /* first check the type for pointer assignement */
2948   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2949       compareType (ltype, rtype) <= 0)
2950     {
2951       if (compareType (ltype->next, rtype) < 0)
2952         right = geniCodeCast (ltype->next, right, TRUE);
2953     }
2954   else if (compareType (ltype, rtype) < 0)
2955     right = geniCodeCast (ltype, right, TRUE);
2956
2957   /* If left is a true symbol & ! volatile
2958      create an assignment to temporary for
2959      the right & then assign this temporary
2960      to the symbol. This is SSA (static single
2961      assignment). Isn't it simple and folks have
2962      published mountains of paper on it */
2963   if (IS_TRUE_SYMOP (left) &&
2964       !isOperandVolatile (left, FALSE) &&
2965       isOperandGlobal (left))
2966     {
2967       symbol *sym = NULL;
2968
2969       if (IS_TRUE_SYMOP (right))
2970         sym = OP_SYMBOL (right);
2971       ic = newiCode ('=', NULL, right);
2972       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2973       SPIL_LOC (right) = sym;
2974       ADDTOCHAIN (ic);
2975     }
2976
2977   ic = newiCode ('=', NULL, right);
2978   IC_RESULT (ic) = left;
2979   ADDTOCHAIN (ic);
2980
2981   /* if left isgptr flag is set then support
2982      routine will be required */
2983   if (left->isGptr)
2984     ic->supportRtn = 1;
2985
2986   ic->nosupdate = nosupdate;
2987   return left;
2988 }
2989
2990 /*-----------------------------------------------------------------*/
2991 /* geniCodeDummyRead - generate code for dummy read                */
2992 /*-----------------------------------------------------------------*/
2993 static void
2994 geniCodeDummyRead (operand * op)
2995 {
2996   iCode *ic;
2997   sym_link *type = operandType (op);
2998
2999   if (!IS_VOLATILE(type))
3000     return;
3001     
3002   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3003   ADDTOCHAIN (ic);
3004
3005   ic->nosupdate = 1;
3006 }
3007
3008 /*-----------------------------------------------------------------*/
3009 /* geniCodeSEParms - generate code for side effecting fcalls       */
3010 /*-----------------------------------------------------------------*/
3011 static void 
3012 geniCodeSEParms (ast * parms,int lvl)
3013 {
3014   if (!parms)
3015     return;
3016
3017   if (parms->type == EX_OP && parms->opval.op == PARAM)
3018     {
3019       geniCodeSEParms (parms->left,lvl);
3020       geniCodeSEParms (parms->right,lvl);
3021       return;
3022     }
3023
3024   /* hack don't like this but too lazy to think of
3025      something better */
3026   if (IS_ADDRESS_OF_OP (parms))
3027     parms->left->lvalue = 1;
3028
3029   if (IS_CAST_OP (parms) &&
3030       IS_PTR (parms->ftype) &&
3031       IS_ADDRESS_OF_OP (parms->right))
3032     parms->right->left->lvalue = 1;
3033
3034   parms->opval.oprnd = 
3035     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3036                 
3037   parms->type = EX_OPERAND;
3038   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3039                 SPEC_ARGREG(parms->ftype);
3040 }
3041
3042 /*-----------------------------------------------------------------*/
3043 /* geniCodeParms - generates parameters                            */
3044 /*-----------------------------------------------------------------*/
3045 value *
3046 geniCodeParms (ast * parms, value *argVals, int *stack, 
3047                sym_link * ftype, int lvl)
3048 {
3049   iCode *ic;
3050   operand *pval;
3051
3052   if (!parms)
3053     return argVals;
3054
3055   if (argVals==NULL) {
3056     // first argument
3057     argVals = FUNC_ARGS (ftype);
3058   }
3059
3060   /* if this is a param node then do the left & right */
3061   if (parms->type == EX_OP && parms->opval.op == PARAM)
3062     {
3063       argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3064       argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3065       return argVals;
3066     }
3067
3068   /* get the parameter value */
3069   if (parms->type == EX_OPERAND)
3070     pval = parms->opval.oprnd;
3071   else
3072     {
3073       /* maybe this else should go away ?? */
3074       /* hack don't like this but too lazy to think of
3075          something better */
3076       if (IS_ADDRESS_OF_OP (parms))
3077         parms->left->lvalue = 1;
3078
3079       if (IS_CAST_OP (parms) &&
3080           IS_PTR (parms->ftype) &&
3081           IS_ADDRESS_OF_OP (parms->right))
3082         parms->right->left->lvalue = 1;
3083
3084       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3085     }
3086
3087   /* if register parm then make it a send */
3088   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3089       IFFUNC_ISBUILTIN(ftype))
3090     {
3091       ic = newiCode (SEND, pval, NULL);
3092       ic->argreg = SPEC_ARGREG(parms->etype);
3093       ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3094       ADDTOCHAIN (ic);
3095     }
3096   else
3097     {
3098       /* now decide whether to push or assign */
3099       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3100         {
3101
3102           /* assign */
3103           operand *top = operandFromSymbol (argVals->sym);
3104           /* clear useDef and other bitVectors */
3105           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3106           geniCodeAssign (top, pval, 1);
3107         }
3108       else
3109         {
3110           sym_link *p = operandType (pval);
3111           /* push */
3112           ic = newiCode (IPUSH, pval, NULL);
3113           ic->parmPush = 1;
3114           /* update the stack adjustment */
3115           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3116           ADDTOCHAIN (ic);
3117         }
3118     }
3119
3120   argVals=argVals->next;
3121   return argVals;
3122 }
3123
3124 /*-----------------------------------------------------------------*/
3125 /* geniCodeCall - generates temp code for calling                  */
3126 /*-----------------------------------------------------------------*/
3127 operand *
3128 geniCodeCall (operand * left, ast * parms,int lvl)
3129 {
3130   iCode *ic;
3131   operand *result;
3132   sym_link *type, *etype;
3133   sym_link *ftype;
3134   int stack = 0;
3135
3136   if (!IS_FUNC(OP_SYMBOL(left)->type) && 
3137       !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3138     werror (E_FUNCTION_EXPECTED);
3139     return operandFromValue(valueFromLit(0));
3140   }
3141
3142   /* take care of parameters with side-effecting
3143      function calls in them, this is required to take care
3144      of overlaying function parameters */
3145   geniCodeSEParms (parms,lvl);
3146
3147   ftype = operandType (left);
3148   if (IS_CODEPTR (ftype))
3149     ftype = ftype->next;
3150     
3151   /* first the parameters */
3152   geniCodeParms (parms, NULL, &stack, ftype, lvl);
3153
3154   /* now call : if symbol then pcall */
3155   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3156     ic = newiCode (PCALL, left, NULL);
3157   } else {
3158     ic = newiCode (CALL, left, NULL);
3159   }
3160
3161   type = copyLinkChain (ftype->next);
3162   etype = getSpec (type);
3163   SPEC_EXTR (etype) = 0;
3164   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3165
3166   ADDTOCHAIN (ic);
3167
3168   /* stack adjustment after call */
3169   ic->parmBytes = stack;
3170
3171   return result;
3172 }
3173
3174 /*-----------------------------------------------------------------*/
3175 /* geniCodeReceive - generate intermediate code for "receive"      */
3176 /*-----------------------------------------------------------------*/
3177 static void 
3178 geniCodeReceive (value * args)
3179 {
3180   /* for all arguments that are passed in registers */
3181   while (args)
3182     {
3183       int first = 1;
3184       if (IS_REGPARM (args->etype))
3185         {
3186           operand *opr = operandFromValue (args);
3187           operand *opl;
3188           symbol *sym = OP_SYMBOL (opr);
3189           iCode *ic;
3190
3191           /* we will use it after all optimizations
3192              and before liveRange calculation */
3193           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3194             {
3195
3196               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3197                   options.stackAuto == 0 &&
3198                   (!(options.model == MODEL_FLAT24)) )
3199                 {
3200                 }
3201               else
3202                 {
3203                   opl = newiTempOperand (args->type, 0);
3204                   sym->reqv = opl;
3205                   sym->reqv->key = sym->key;
3206                   OP_SYMBOL (sym->reqv)->key = sym->key;
3207                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3208                   OP_SYMBOL (sym->reqv)->islocal = 0;
3209                   SPIL_LOC (sym->reqv) = sym;
3210                 }
3211             }
3212
3213           ic = newiCode (RECEIVE, NULL, NULL);    
3214           ic->argreg = SPEC_ARGREG(args->etype);
3215           if (first) {
3216               currFunc->recvSize = getSize (sym->type);
3217               first = 0;
3218           }
3219           IC_RESULT (ic) = opr;
3220           ADDTOCHAIN (ic);
3221         }
3222
3223       args = args->next;
3224     }
3225 }
3226
3227 /*-----------------------------------------------------------------*/
3228 /* geniCodeFunctionBody - create the function body                 */
3229 /*-----------------------------------------------------------------*/
3230 void 
3231 geniCodeFunctionBody (ast * tree,int lvl)
3232 {
3233   iCode *ic;
3234   operand *func;
3235   sym_link *fetype;
3236   int savelineno;
3237
3238   /* reset the auto generation */
3239   /* numbers */
3240   iTempNum = 0;
3241   iTempLblNum = 0;
3242   operandKey = 0;
3243   iCodeKey = 0;
3244   func = ast2iCode (tree->left,lvl+1);
3245   fetype = getSpec (operandType (func));
3246
3247   savelineno = lineno;
3248   lineno = OP_SYMBOL (func)->lineDef;
3249   /* create an entry label */
3250   geniCodeLabel (entryLabel);
3251   lineno = savelineno;
3252
3253   /* create a proc icode */
3254   ic = newiCode (FUNCTION, func, NULL);
3255   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3256
3257   ADDTOCHAIN (ic);
3258
3259   /* for all parameters that are passed
3260      on registers add a "receive" */
3261   geniCodeReceive (tree->values.args);
3262
3263   /* generate code for the body */
3264   ast2iCode (tree->right,lvl+1);
3265
3266   /* create a label for return */
3267   geniCodeLabel (returnLabel);
3268
3269   /* now generate the end proc */
3270   ic = newiCode (ENDFUNCTION, func, NULL);
3271   ADDTOCHAIN (ic);
3272   return;
3273 }
3274
3275 /*-----------------------------------------------------------------*/
3276 /* geniCodeReturn - gen icode for 'return' statement               */
3277 /*-----------------------------------------------------------------*/
3278 void 
3279 geniCodeReturn (operand * op)
3280 {
3281   iCode *ic;
3282
3283   /* if the operand is present force an rvalue */
3284   if (op)
3285     op = geniCodeRValue (op, FALSE);
3286
3287   ic = newiCode (RETURN, op, NULL);
3288   ADDTOCHAIN (ic);
3289 }
3290
3291 /*-----------------------------------------------------------------*/
3292 /* geniCodeIfx - generates code for extended if statement          */
3293 /*-----------------------------------------------------------------*/
3294 void 
3295 geniCodeIfx (ast * tree,int lvl)
3296 {
3297   iCode *ic;
3298   operand *condition = ast2iCode (tree->left,lvl+1);
3299   sym_link *cetype;
3300
3301   /* if condition is null then exit */
3302   if (!condition)
3303     goto exit;
3304   else
3305     condition = geniCodeRValue (condition, FALSE);
3306
3307   cetype = getSpec (operandType (condition));
3308   /* if the condition is a literal */
3309   if (IS_LITERAL (cetype))
3310     {
3311       if (floatFromVal (condition->operand.valOperand))
3312         {
3313           if (tree->trueLabel)
3314             geniCodeGoto (tree->trueLabel);
3315           else
3316             assert (0);
3317         }
3318       else
3319         {
3320           if (tree->falseLabel)
3321             geniCodeGoto (tree->falseLabel);
3322           else
3323             assert (0);
3324         }
3325       goto exit;
3326     }
3327
3328   if (tree->trueLabel)
3329     {
3330       ic = newiCodeCondition (condition,
3331                               tree->trueLabel,
3332                               NULL);
3333       ADDTOCHAIN (ic);
3334
3335       if (tree->falseLabel)
3336         geniCodeGoto (tree->falseLabel);
3337     }
3338   else
3339     {
3340       ic = newiCodeCondition (condition,
3341                               NULL,
3342                               tree->falseLabel);
3343       ADDTOCHAIN (ic);
3344     }
3345
3346 exit:
3347   ast2iCode (tree->right,lvl+1);
3348 }
3349
3350 /*-----------------------------------------------------------------*/
3351 /* geniCodeJumpTable - tries to create a jump table for switch     */
3352 /*-----------------------------------------------------------------*/
3353 int 
3354 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3355 {
3356   int min = 0, max = 0, t, cnt = 0;
3357   value *vch;
3358   iCode *ic;
3359   operand *boundary;
3360   symbol *falseLabel;
3361   set *labels = NULL;
3362   int needRangeCheck = !optimize.noJTabBoundary
3363                        || tree->values.switchVals.swDefault;
3364
3365   if (!tree || !caseVals)
3366     return 0;
3367
3368   /* the criteria for creating a jump table is */
3369   /* all integer numbers between the maximum & minimum must */
3370   /* be present , the maximum value should not exceed 255 */
3371   min = max = (int) floatFromVal (vch = caseVals);
3372   SNPRINTF (buffer, sizeof(buffer), 
3373             "_case_%d_%d",
3374            tree->values.switchVals.swNum,
3375            min);
3376   addSet (&labels, newiTempLabel (buffer));
3377
3378   /* if there is only one case value then no need */
3379   if (!(vch = vch->next))
3380     return 0;
3381
3382   while (vch)
3383     {
3384       if (((t = (int) floatFromVal (vch)) - max) != 1)
3385         return 0;
3386       SNPRINTF (buffer, sizeof(buffer), 
3387                 "_case_%d_%d",
3388                tree->values.switchVals.swNum,
3389                t);
3390       addSet (&labels, newiTempLabel (buffer));
3391       max = t;
3392       cnt++;
3393       vch = vch->next;
3394     }
3395
3396   /* if the number of case statements <= 2 then */
3397   /* it is not economical to create the jump table */
3398   /* since two compares are needed for boundary conditions */
3399   if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3400     return 0;
3401
3402   if (tree->values.switchVals.swDefault)
3403     {
3404         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3405     }
3406   else
3407     {
3408         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3409     }
3410     
3411
3412   falseLabel = newiTempLabel (buffer);
3413
3414   /* so we can create a jumptable */
3415   /* first we rule out the boundary conditions */
3416   /* if only optimization says so */
3417   if (needRangeCheck)
3418     {
3419       sym_link *cetype = getSpec (operandType (cond));
3420       /* no need to check the lower bound if
3421          the condition is unsigned & minimum value is zero */
3422       if (!(min == 0 && IS_UNSIGNED (cetype)))
3423         {
3424           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3425           ic = newiCodeCondition (boundary, falseLabel, NULL);
3426           ADDTOCHAIN (ic);
3427         }
3428
3429       /* now for upper bounds */
3430       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3431       ic = newiCodeCondition (boundary, falseLabel, NULL);
3432       ADDTOCHAIN (ic);
3433     }
3434
3435   /* if the min is not zero then we no make it zero */
3436   if (min)
3437     {
3438       cond = geniCodeSubtract (cond, operandFromLit (min));
3439       if (!IS_LITERAL(getSpec(operandType(cond))))
3440         setOperandType (cond, UCHARTYPE);
3441     }
3442
3443   /* now create the jumptable */
3444   ic = newiCode (JUMPTABLE, NULL, NULL);
3445   IC_JTCOND (ic) = cond;
3446   IC_JTLABELS (ic) = labels;
3447   ADDTOCHAIN (ic);
3448   return 1;
3449 }
3450
3451 /*-----------------------------------------------------------------*/
3452 /* geniCodeSwitch - changes a switch to a if statement             */
3453 /*-----------------------------------------------------------------*/
3454 void
3455 geniCodeSwitch (ast * tree,int lvl)
3456 {
3457   iCode *ic;
3458   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3459   value *caseVals = tree->values.switchVals.swVals;
3460   symbol *trueLabel, *falseLabel;
3461       
3462   /* If the condition is a literal, then just jump to the */
3463   /* appropriate case label. */
3464   if (IS_LITERAL(getSpec(operandType(cond))))
3465     {
3466       int switchVal, caseVal;
3467       
3468       switchVal = (int) floatFromVal (cond->operand.valOperand);
3469       while (caseVals)
3470         {
3471           caseVal = (int) floatFromVal (caseVals);
3472           if (caseVal == switchVal)
3473             {
3474               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3475                         tree->values.switchVals.swNum, caseVal);
3476               trueLabel = newiTempLabel (buffer);
3477               geniCodeGoto (trueLabel);
3478               goto jumpTable;
3479             }
3480           caseVals = caseVals->next;
3481         }
3482       goto defaultOrBreak;
3483     }
3484
3485   /* if we can make this a jump table */
3486   if (geniCodeJumpTable (cond, caseVals, tree))
3487     goto jumpTable;             /* no need for the comparison */
3488
3489   /* for the cases defined do */
3490   while (caseVals)
3491     {
3492
3493       operand *compare = geniCodeLogic (cond,
3494                                         operandFromValue (caseVals),
3495                                         EQ_OP);
3496
3497       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3498                tree->values.switchVals.swNum,
3499                (int) floatFromVal (caseVals));
3500       trueLabel = newiTempLabel (buffer);
3501
3502       ic = newiCodeCondition (compare, trueLabel, NULL);
3503       ADDTOCHAIN (ic);
3504       caseVals = caseVals->next;
3505     }
3506
3507
3508 defaultOrBreak:
3509   /* if default is present then goto break else break */
3510   if (tree->values.switchVals.swDefault)
3511     {
3512         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3513     }
3514   else
3515     {
3516         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3517     }
3518
3519   falseLabel = newiTempLabel (buffer);
3520   geniCodeGoto (falseLabel);
3521
3522 jumpTable:
3523   ast2iCode (tree->right,lvl+1);
3524 }
3525
3526 /*-----------------------------------------------------------------*/
3527 /* geniCodeInline - intermediate code for inline assembler         */
3528 /*-----------------------------------------------------------------*/
3529 static void 
3530 geniCodeInline (ast * tree)
3531 {
3532   iCode *ic;
3533
3534   ic = newiCode (INLINEASM, NULL, NULL);
3535   IC_INLINE (ic) = tree->values.inlineasm;
3536   ADDTOCHAIN (ic);
3537 }
3538
3539 /*-----------------------------------------------------------------*/
3540 /* geniCodeArrayInit - intermediate code for array initializer     */
3541 /*-----------------------------------------------------------------*/
3542 static void
3543 geniCodeArrayInit (ast * tree, operand *array)
3544 {
3545   iCode *ic;
3546
3547   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3548     ic = newiCode (ARRAYINIT, array, NULL);
3549     IC_ARRAYILIST (ic) = tree->values.constlist;
3550   } else {
3551     operand *left=newOperand(), *right=newOperand();
3552     left->type=right->type=SYMBOL;
3553     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3554     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3555     ic = newiCode (ARRAYINIT, left, right);
3556   }
3557   ADDTOCHAIN (ic);
3558 }
3559         
3560 /*-----------------------------------------------------------------*/
3561 /* geniCodeCritical - intermediate code for a critical statement   */
3562 /*-----------------------------------------------------------------*/
3563 static void 
3564 geniCodeCritical (ast *tree, int lvl)
3565 {
3566   iCode *ic;
3567   operand *op = NULL;
3568
3569   /* If op is NULL, the original interrupt state will saved on */
3570   /* the stack. Otherwise, it will be saved in op. */
3571   
3572   /* Generate a save of the current interrupt state & disabled */
3573   ic = newiCode (CRITICAL, NULL, NULL);
3574   IC_RESULT (ic) = op;
3575   ADDTOCHAIN (ic);
3576   
3577   /* Generate the critical code sequence */
3578   if (tree->left && tree->left->type == EX_VALUE)
3579     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3580   else
3581     ast2iCode (tree->left,lvl+1);
3582   
3583   /* Generate a restore of the original interrupt state */
3584   ic = newiCode (ENDCRITICAL, NULL, op);
3585   ADDTOCHAIN (ic);
3586 }
3587
3588 /*-----------------------------------------------------------------*/
3589 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3590 /* particular case. Ie : assigning or dereferencing array or ptr   */
3591 /*-----------------------------------------------------------------*/
3592 set * lvaluereqSet = NULL;
3593 typedef struct lvalItem
3594   {
3595     int req;
3596     int lvl;
3597   }
3598 lvalItem;
3599
3600 /*-----------------------------------------------------------------*/
3601 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3602 /*-----------------------------------------------------------------*/
3603 void addLvaluereq(int lvl)
3604 {
3605   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3606   lpItem->req=1;
3607   lpItem->lvl=lvl;
3608   addSetHead(&lvaluereqSet,lpItem);
3609
3610 }
3611 /*-----------------------------------------------------------------*/
3612 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3613 /*-----------------------------------------------------------------*/
3614 void delLvaluereq()
3615 {
3616   lvalItem * lpItem;
3617   lpItem = getSet(&lvaluereqSet);
3618   if(lpItem) Safe_free(lpItem);
3619 }
3620 /*-----------------------------------------------------------------*/
3621 /* clearLvaluereq - clear lvalreq flag                             */
3622 /*-----------------------------------------------------------------*/
3623 void clearLvaluereq()
3624 {
3625   lvalItem * lpItem;
3626   lpItem = peekSet(lvaluereqSet);
3627   if(lpItem) lpItem->req = 0;
3628 }
3629 /*-----------------------------------------------------------------*/
3630 /* getLvaluereq - get the last lvalreq level                       */
3631 /*-----------------------------------------------------------------*/
3632 int getLvaluereqLvl()
3633 {
3634   lvalItem * lpItem;
3635   lpItem = peekSet(lvaluereqSet);
3636   if(lpItem) return lpItem->lvl;
3637   return 0;
3638 }
3639 /*-----------------------------------------------------------------*/
3640 /* isLvaluereq - is lvalreq valid for this level ?                 */
3641 /*-----------------------------------------------------------------*/
3642 int isLvaluereq(int lvl)
3643 {
3644   lvalItem * lpItem;
3645   lpItem = peekSet(lvaluereqSet);
3646   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3647   return 0;
3648 }
3649
3650 /*-----------------------------------------------------------------*/
3651 /* ast2iCode - creates an icodeList from an ast                    */
3652 /*-----------------------------------------------------------------*/
3653 operand *
3654 ast2iCode (ast * tree,int lvl)
3655 {
3656   operand *left = NULL;
3657   operand *right = NULL;
3658   if (!tree)
3659     return NULL;
3660
3661   /* set the global variables for filename & line number */
3662   if (tree->filename)
3663     filename = tree->filename;
3664   if (tree->lineno)
3665     lineno = tree->lineno;
3666   if (tree->block)
3667     block = tree->block;
3668   if (tree->level)
3669     scopeLevel = tree->level;
3670   if (tree->seqPoint)
3671     seqPoint = tree->seqPoint;
3672
3673   if (tree->type == EX_VALUE)
3674     return operandFromValue (tree->opval.val);
3675
3676   if (tree->type == EX_LINK)
3677     return operandFromLink (tree->opval.lnk);
3678
3679   /* if we find a nullop */
3680   if (tree->type == EX_OP &&
3681      (tree->opval.op == NULLOP ||
3682      tree->opval.op == BLOCK))
3683     {
3684       if (tree->left && tree->left->type == EX_VALUE)
3685         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3686       else
3687         ast2iCode (tree->left,lvl+1);
3688       if (tree->right && tree->right->type == EX_VALUE)
3689         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3690       else
3691         ast2iCode (tree->right,lvl+1);
3692       return NULL;
3693     }
3694
3695   /* special cases for not evaluating */
3696   if (tree->opval.op != ':' &&
3697       tree->opval.op != '?' &&
3698       tree->opval.op != CALL &&
3699       tree->opval.op != IFX &&
3700       tree->opval.op != LABEL &&
3701       tree->opval.op != GOTO &&
3702       tree->opval.op != SWITCH &&
3703       tree->opval.op != FUNCTION &&
3704       tree->opval.op != INLINEASM &&
3705       tree->opval.op != CRITICAL)
3706     {
3707
3708         if (IS_ASSIGN_OP (tree->opval.op) ||
3709            IS_DEREF_OP (tree) ||
3710            (tree->opval.op == '&' && !tree->right) ||
3711            tree->opval.op == PTR_OP)
3712           {
3713             addLvaluereq(lvl);
3714             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3715                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3716               clearLvaluereq();
3717
3718             left = operandFromAst (tree->left,lvl);
3719             delLvaluereq();
3720             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3721               left = geniCodeRValue (left, TRUE);
3722           }
3723         else
3724           {
3725             left = operandFromAst (tree->left,lvl);
3726           }
3727         if (tree->opval.op == INC_OP ||
3728             tree->opval.op == DEC_OP)
3729           {
3730             addLvaluereq(lvl);
3731             right = operandFromAst (tree->right,lvl);
3732             delLvaluereq();
3733           }
3734         else
3735           {
3736             right = operandFromAst (tree->right,lvl);
3737           }
3738       }
3739
3740   /* now depending on the type of operand */
3741   /* this will be a biggy                 */
3742   switch (tree->opval.op)
3743     {
3744
3745     case '[':                   /* array operation */
3746       {
3747         //sym_link *ltype = operandType (left);
3748         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3749         left = geniCodeRValue (left, FALSE);
3750         right = geniCodeRValue (right, TRUE);
3751       }
3752
3753       return geniCodeArray (left, right,lvl);
3754
3755     case '.':                   /* structure dereference */
3756       if (IS_PTR (operandType (left)))
3757         left = geniCodeRValue (left, TRUE);
3758       else
3759         left = geniCodeRValue (left, FALSE);
3760
3761       return geniCodeStruct (left, right, tree->lvalue);
3762
3763     case PTR_OP:                /* structure pointer dereference */
3764       {
3765         sym_link *pType;
3766         pType = operandType (left);
3767         left = geniCodeRValue (left, TRUE);
3768
3769         setOClass (pType, getSpec (operandType (left)));
3770       }
3771
3772       return geniCodeStruct (left, right, tree->lvalue);
3773
3774     case INC_OP:                /* increment operator */
3775       if (left)
3776         return geniCodePostInc (left);
3777       else
3778         return geniCodePreInc (right, tree->lvalue);
3779
3780     case DEC_OP:                /* decrement operator */
3781       if (left)
3782         return geniCodePostDec (left);
3783       else
3784         return geniCodePreDec (right, tree->lvalue);
3785
3786     case '&':                   /* bitwise and or address of operator */
3787       if (right)
3788         {                       /* this is a bitwise operator   */
3789           left = geniCodeRValue (left, FALSE);
3790           right = geniCodeRValue (right, FALSE);
3791           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3792         }
3793       else
3794         return geniCodeAddressOf (left);
3795
3796     case '|':                   /* bitwise or & xor */
3797     case '^':
3798       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3799                               geniCodeRValue (right, FALSE),
3800                               tree->opval.op,
3801                               tree->ftype);
3802
3803     case '/':
3804       return geniCodeDivision (geniCodeRValue (left, FALSE),
3805                                geniCodeRValue (right, FALSE));
3806
3807     case '%':
3808       return geniCodeModulus (geniCodeRValue (left, FALSE),
3809                               geniCodeRValue (right, FALSE));
3810     case '*':
3811       if (right)
3812         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3813                                  geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3814       else
3815         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3816
3817     case '-':
3818       if (right)
3819         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3820                                  geniCodeRValue (right, FALSE));
3821       else
3822         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3823
3824     case '+':
3825       if (right)
3826         return geniCodeAdd (geniCodeRValue (left, FALSE),
3827                             geniCodeRValue (right, FALSE),lvl);
3828       else
3829         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3830
3831     case LEFT_OP:
3832       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3833                                 geniCodeRValue (right, FALSE));
3834
3835     case RIGHT_OP:
3836       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3837                                  geniCodeRValue (right, FALSE));
3838     case CAST:
3839 #if 0 // this indeed needs a second thought
3840       {
3841         operand *op;
3842
3843         // let's keep this simple: get the rvalue we need
3844         op=geniCodeRValue (right, FALSE);
3845         // now cast it to whatever we want
3846         op=geniCodeCast (operandType(left), op, FALSE);
3847         // if this is going to be used as an lvalue, make it so
3848         if (tree->lvalue) {
3849           op->isaddr=1;
3850         }
3851         return op;
3852       }
3853 #else // bug #604575, is it a bug ????
3854       return geniCodeCast (operandType (left),
3855                            geniCodeRValue (right, FALSE), FALSE);
3856 #endif
3857
3858     case '~':
3859     case RRC:
3860     case RLC:
3861     case SWAP:
3862       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3863
3864     case '!':
3865     case GETHBIT:
3866       {
3867         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3868         setOperandType (op, UCHARTYPE);
3869         return op;
3870       }
3871     case '>':
3872     case '<':
3873     case LE_OP:
3874     case GE_OP:
3875     case EQ_OP:
3876     case NE_OP:
3877     case AND_OP:
3878     case OR_OP:
3879       /* different compilers (even different gccs) evaluate
3880          the two calls in a different order. to get the same
3881          result on all machines we've to specify a clear sequence.
3882       return geniCodeLogic (geniCodeRValue (left, FALSE),
3883                             geniCodeRValue (right, FALSE),
3884                             tree->opval.op);
3885       */
3886       {
3887         operand *leftOp, *rightOp;
3888
3889         rightOp = geniCodeRValue (right, FALSE);
3890         leftOp  = geniCodeRValue (left , FALSE);
3891
3892         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3893       }
3894     case '?':
3895       return geniCodeConditional (tree,lvl);
3896
3897     case SIZEOF:
3898       return operandFromLit (getSize (tree->right->ftype));
3899
3900     case '=':
3901       {
3902         sym_link *rtype = operandType (right);
3903         sym_link *ltype = operandType (left);
3904         if (IS_PTR (rtype) && IS_ITEMP (right)
3905             && right->isaddr && compareType (rtype->next, ltype) == 1)
3906           right = geniCodeRValue (right, TRUE);
3907         else
3908           right = geniCodeRValue (right, FALSE);
3909
3910         geniCodeAssign (left, right, 0);
3911         return right;
3912       }
3913     case MUL_ASSIGN:
3914       return
3915         geniCodeAssign (left,
3916                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3917                                                   FALSE),
3918                                   geniCodeRValue (right, FALSE),FALSE), 0);
3919
3920     case DIV_ASSIGN:
3921       return
3922         geniCodeAssign (left,
3923                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3924                                                   FALSE),
3925                                   geniCodeRValue (right, FALSE)), 0);
3926     case MOD_ASSIGN:
3927       return
3928         geniCodeAssign (left,
3929                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3930                                                   FALSE),
3931                                   geniCodeRValue (right, FALSE)), 0);
3932     case ADD_ASSIGN:
3933       {
3934         sym_link *rtype = operandType (right);
3935         sym_link *ltype = operandType (left);
3936         if (IS_PTR (rtype) && IS_ITEMP (right)
3937             && right->isaddr && compareType (rtype->next, ltype) == 1)
3938           right = geniCodeRValue (right, TRUE);
3939         else
3940           right = geniCodeRValue (right, FALSE);
3941
3942
3943         return geniCodeAssign (left,
3944                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3945                                                   FALSE),
3946                                   right,lvl), 0);
3947       }
3948     case SUB_ASSIGN:
3949       {
3950         sym_link *rtype = operandType (right);
3951         sym_link *ltype = operandType (left);
3952         if (IS_PTR (rtype) && IS_ITEMP (right)
3953             && right->isaddr && compareType (rtype->next, ltype) == 1)
3954           {
3955             right = geniCodeRValue (right, TRUE);
3956           }
3957         else
3958           {
3959             right = geniCodeRValue (right, FALSE);
3960           }
3961         return
3962           geniCodeAssign (left,
3963                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3964                                                   FALSE),
3965                                   right), 0);
3966       }
3967     case LEFT_ASSIGN:
3968       return
3969         geniCodeAssign (left,
3970                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3971                                                    ,FALSE),
3972                                    geniCodeRValue (right, FALSE)), 0);
3973     case RIGHT_ASSIGN:
3974       return
3975         geniCodeAssign (left,
3976                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3977                                                    ,FALSE),
3978                                    geniCodeRValue (right, FALSE)), 0);
3979     case AND_ASSIGN:
3980       return
3981         geniCodeAssign (left,
3982                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3983                                                   FALSE),
3984                                   geniCodeRValue (right, FALSE),
3985                                   BITWISEAND,
3986                                   operandType (left)), 0);
3987     case XOR_ASSIGN:
3988       return
3989         geniCodeAssign (left,
3990                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3991                                                   FALSE),
3992                                   geniCodeRValue (right, FALSE),
3993                                   '^',
3994                                   operandType (left)), 0);
3995     case OR_ASSIGN:
3996       return
3997         geniCodeAssign (left,
3998                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3999                                                    ,FALSE),
4000                                    geniCodeRValue (right, FALSE),
4001                                    '|',
4002                                    operandType (left)), 0);
4003     case ',':
4004       return geniCodeRValue (right, FALSE);
4005
4006     case CALL:
4007       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4008                            tree->right,lvl);
4009     case LABEL:
4010       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4011       return ast2iCode (tree->right,lvl+1);
4012
4013     case GOTO:
4014       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4015       return ast2iCode (tree->right,lvl+1);
4016
4017     case FUNCTION:
4018       geniCodeFunctionBody (tree,lvl);
4019       return NULL;
4020
4021     case RETURN:
4022       geniCodeReturn (right);
4023       return NULL;
4024
4025     case IFX:
4026       geniCodeIfx (tree,lvl);
4027       return NULL;
4028
4029     case SWITCH:
4030       geniCodeSwitch (tree,lvl);
4031       return NULL;
4032
4033     case INLINEASM:
4034       geniCodeInline (tree);
4035       return NULL;
4036         
4037     case ARRAYINIT:
4038         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4039         return NULL;
4040     
4041     case CRITICAL:
4042         geniCodeCritical (tree, lvl);
4043     }
4044
4045   return NULL;
4046 }
4047
4048 /*-----------------------------------------------------------------*/
4049 /* reverseICChain - gets from the list and creates a linkedlist    */
4050 /*-----------------------------------------------------------------*/
4051 iCode *
4052 reverseiCChain ()
4053 {
4054   iCode *loop = NULL;
4055   iCode *prev = NULL;
4056
4057   while ((loop = getSet (&iCodeChain)))
4058     {
4059       loop->next = prev;
4060       if (prev)
4061         prev->prev = loop;
4062       prev = loop;
4063     }
4064
4065   return prev;
4066 }
4067
4068
4069 /*-----------------------------------------------------------------*/
4070 /* iCodeFromAst - given an ast will convert it to iCode            */
4071 /*-----------------------------------------------------------------*/
4072 iCode *
4073 iCodeFromAst (ast * tree)
4074 {
4075   returnLabel = newiTempLabel ("_return");
4076   entryLabel = newiTempLabel ("_entry");
4077   ast2iCode (tree,0);
4078   return reverseiCChain ();
4079 }
4080
4081 static const char *opTypeToStr(OPTYPE op)
4082 {
4083     switch(op)
4084     {
4085       case SYMBOL: return "symbol";
4086       case VALUE: return "value";
4087       case TYPE: return "type";
4088     }
4089     return "undefined type";    
4090 }
4091
4092
4093 operand *validateOpType(operand         *op, 
4094                         const char      *macro,
4095                         const char      *args,
4096                         OPTYPE          type,
4097                         const char      *file, 
4098                         unsigned        line)
4099 {    
4100     if (op && op->type == type)
4101     {
4102         return op;
4103     }
4104     fprintf(stderr, 
4105             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4106             " expected %s, got %s\n",
4107             macro, args, file, line, 
4108             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4109     exit(-1);
4110     return op; // never reached, makes compiler happy.
4111 }