* src/SDCCicode.c (geniCodeParms),
[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 the operand is already the desired type then do nothing */
1866   if (compareType (type, optype) == 1)
1867     return op;
1868
1869   /* if this is a literal then just change the type & return */
1870   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1871     {
1872       return operandFromValue (valCastLiteral (type,
1873                                                operandLitValue (op)));
1874     }
1875
1876   /* if casting to/from pointers, do some checking */
1877   if (IS_PTR(type)) { // to a pointer
1878     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1879       if (IS_INTEGRAL(optype)) {
1880         // maybe this is NULL, than it's ok.
1881         if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1882           if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1883             // no way to set the storage
1884             if (IS_LITERAL(optype)) {
1885               werror(E_LITERAL_GENERIC);
1886               errors++;
1887             } else {
1888               werror(E_NONPTR2_GENPTR);
1889               errors++;
1890             }
1891           } else if (implicit) {
1892             werror(W_INTEGRAL2PTR_NOCAST);
1893             errors++;
1894           }
1895         }
1896       } else {
1897         // shouldn't do that with float, array or structure unless to void
1898         if (!IS_VOID(getSpec(type)) &&
1899             !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1900           werror(E_INCOMPAT_TYPES);
1901           errors++;
1902         }
1903       }
1904     } else { // from a pointer to a pointer
1905       if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1906         // if not a pointer to a function
1907         if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1908           if (implicit) { // if not to generic, they have to match
1909             if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1910               werror(E_INCOMPAT_PTYPES);
1911               errors++;
1912             }
1913           }
1914         }
1915       }
1916     }
1917   } else { // to a non pointer
1918     if (IS_PTR(optype)) { // from a pointer
1919       if (implicit) { // sneaky
1920         if (IS_INTEGRAL(type)) {
1921           werror(W_PTR2INTEGRAL_NOCAST);
1922           errors++;
1923         } else { // shouldn't do that with float, array or structure
1924           werror(E_INCOMPAT_TYPES);
1925           errors++;
1926         }
1927       }
1928     }
1929   }
1930   if (errors) {
1931     printFromToType (optype, type);
1932   }
1933
1934   /* if they are the same size create an assignment */
1935   
1936   /* This seems very dangerous to me, since there are several */
1937   /* optimizations (for example, gcse) that don't notice the  */
1938   /* cast hidden in this assignement and may simplify an      */
1939   /* iCode to use the original (uncasted) operand.            */
1940   /* Unfortunately, other things break when this cast is      */
1941   /* made explicit. Need to fix this someday.                 */
1942   /* -- EEP, 2004/01/21                                       */
1943   if (getSize (type) == getSize (optype) &&
1944       !IS_BITFIELD (type) &&
1945       !IS_FLOAT (type) &&
1946       !IS_FLOAT (optype) &&
1947       ((IS_SPEC (type) && IS_SPEC (optype)) ||
1948        (!IS_SPEC (type) && !IS_SPEC (optype))))
1949     {
1950       ic = newiCode ('=', NULL, op);
1951       IC_RESULT (ic) = newiTempOperand (type, 0);
1952       SPIL_LOC (IC_RESULT (ic)) =
1953         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1954       IC_RESULT (ic)->isaddr = 0;
1955     }
1956   else
1957     {
1958       ic = newiCode (CAST, operandFromLink (type),
1959                      geniCodeRValue (op, FALSE));
1960
1961       IC_RESULT (ic) = newiTempOperand (type, 0);
1962     }
1963
1964   /* preserve the storage class & output class */
1965   /* of the original variable                  */
1966   restype = getSpec (operandType (IC_RESULT (ic)));
1967   if (!IS_LITERAL(opetype))
1968       SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1969   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1970
1971   ADDTOCHAIN (ic);
1972   return IC_RESULT (ic);
1973 }
1974
1975 /*-----------------------------------------------------------------*/
1976 /* geniCodeLabel - will create a Label                             */
1977 /*-----------------------------------------------------------------*/
1978 void
1979 geniCodeLabel (symbol * label)
1980 {
1981   iCode *ic;
1982
1983   ic = newiCodeLabelGoto (LABEL, label);
1984   ADDTOCHAIN (ic);
1985 }
1986
1987 /*-----------------------------------------------------------------*/
1988 /* geniCodeGoto  - will create a Goto                              */
1989 /*-----------------------------------------------------------------*/
1990 void
1991 geniCodeGoto (symbol * label)
1992 {
1993   iCode *ic;
1994
1995   ic = newiCodeLabelGoto (GOTO, label);
1996   ADDTOCHAIN (ic);
1997 }
1998
1999 /*-----------------------------------------------------------------*/
2000 /* geniCodeMultiply - gen intermediate code for multiplication     */
2001 /*-----------------------------------------------------------------*/
2002 operand *
2003 geniCodeMultiply (operand * left, operand * right, int resultIsInt)
2004 {
2005   iCode *ic;
2006   int p2 = 0;
2007   sym_link *resType;
2008   LRTYPE;
2009
2010   /* if they are both literal then we know the result */
2011   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2012     return operandFromValue (valMult (left->operand.valOperand,
2013                                       right->operand.valOperand));
2014
2015   if (IS_LITERAL(retype)) {
2016     p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2017   }
2018
2019   resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
2020 #if 1
2021   rtype = operandType (right);
2022   retype = getSpec (rtype);
2023   ltype = operandType (left);
2024   letype = getSpec (ltype);
2025 #endif
2026
2027   /* if the right is a literal & power of 2 */
2028   /* then make it a left shift              */
2029   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2030      efficient in most cases than 2 bytes result = 2 bytes << literal
2031      if port has 1 byte muldiv */
2032   if (p2 && !IS_FLOAT (letype) &&
2033       !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2034         (port->support.muldiv == 1)))
2035     {
2036       if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2037         {
2038           /* LEFT_OP need same size for left and result, */
2039           left = geniCodeCast (resType, left, TRUE);
2040           ltype = operandType (left);
2041         }
2042       ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2043     }
2044   else
2045     {
2046       ic = newiCode ('*', left, right);         /* normal multiplication */
2047       /* if the size left or right > 1 then support routine */
2048       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2049         ic->supportRtn = 1;
2050
2051     }
2052   IC_RESULT (ic) = newiTempOperand (resType, 1);
2053
2054   ADDTOCHAIN (ic);
2055   return IC_RESULT (ic);
2056 }
2057
2058 /*-----------------------------------------------------------------*/
2059 /* geniCodeDivision - gen intermediate code for division           */
2060 /*-----------------------------------------------------------------*/
2061 operand *
2062 geniCodeDivision (operand * left, operand * right)
2063 {
2064   iCode *ic;
2065   int p2 = 0;
2066   sym_link *resType;
2067   sym_link *rtype = operandType (right);
2068   sym_link *retype = getSpec (rtype);
2069   sym_link *ltype = operandType (left);
2070   sym_link *letype = getSpec (ltype);
2071
2072   resType = usualBinaryConversions (&left, &right,
2073               (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2074               FALSE);
2075
2076   /* if the right is a literal & power of 2
2077      and left is unsigned then make it a
2078      right shift */
2079   if (IS_LITERAL (retype) &&
2080       !IS_FLOAT (letype) &&
2081       IS_UNSIGNED(letype) &&
2082       (p2 = powof2 ((TYPE_UDWORD)
2083                     floatFromVal (right->operand.valOperand)))) {
2084     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2085   }
2086   else
2087     {
2088       ic = newiCode ('/', left, right);         /* normal division */
2089       /* if the size left or right > 1 then support routine */
2090       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2091         ic->supportRtn = 1;
2092     }
2093   IC_RESULT (ic) = newiTempOperand (resType, 0);
2094
2095   ADDTOCHAIN (ic);
2096   return IC_RESULT (ic);
2097 }
2098 /*-----------------------------------------------------------------*/
2099 /* geniCodeModulus  - gen intermediate code for modulus            */
2100 /*-----------------------------------------------------------------*/
2101 operand *
2102 geniCodeModulus (operand * left, operand * right)
2103 {
2104   iCode *ic;
2105   sym_link *resType;
2106   LRTYPE;
2107
2108   /* if they are both literal then we know the result */
2109   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2110     return operandFromValue (valMod (left->operand.valOperand,
2111                                      right->operand.valOperand));
2112
2113   resType = usualBinaryConversions (&left, &right,
2114               (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2115               FALSE);
2116
2117   /* now they are the same size */
2118   ic = newiCode ('%', left, right);
2119
2120   /* if the size left or right > 1 then support routine */
2121   if (getSize (ltype) > 1 || getSize (rtype) > 1)
2122     ic->supportRtn = 1;
2123   IC_RESULT (ic) = newiTempOperand (resType, 0);
2124
2125   ADDTOCHAIN (ic);
2126   return IC_RESULT (ic);
2127 }
2128
2129 /*-----------------------------------------------------------------*/
2130 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
2131 /*-----------------------------------------------------------------*/
2132 operand *
2133 geniCodePtrPtrSubtract (operand * left, operand * right)
2134 {
2135   iCode *ic;
2136   operand *result;
2137   LRTYPE;
2138
2139   /* if they are both literals then */
2140   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2141     {
2142       result = operandFromValue (valMinus (left->operand.valOperand,
2143                                            right->operand.valOperand));
2144       goto subtractExit;
2145     }
2146
2147   ic = newiCode ('-', left, right);
2148
2149   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2150   ADDTOCHAIN (ic);
2151
2152 subtractExit:
2153   if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2154     return result;
2155   }
2156   
2157   // should we really do this? is this ANSI?
2158   return geniCodeDivision (result,
2159                            operandFromLit (getSize (ltype->next)));
2160 }
2161
2162 /*-----------------------------------------------------------------*/
2163 /* geniCodeSubtract - generates code for subtraction               */
2164 /*-----------------------------------------------------------------*/
2165 operand *
2166 geniCodeSubtract (operand * left, operand * right)
2167 {
2168   iCode *ic;
2169   int isarray = 0;
2170   sym_link *resType;
2171   LRTYPE;
2172
2173   /* if they both pointers then */
2174   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2175       (IS_PTR (rtype) || IS_ARRAY (rtype)))
2176     return geniCodePtrPtrSubtract (left, right);
2177
2178   /* if they are both literal then we know the result */
2179   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2180       && left->isLiteral && right->isLiteral)
2181     return operandFromValue (valMinus (left->operand.valOperand,
2182                                        right->operand.valOperand));
2183
2184   /* if left is an array or pointer */
2185   if (IS_PTR (ltype) || IS_ARRAY (ltype))
2186     {
2187       isarray = left->isaddr;
2188       right = geniCodeMultiply (right,
2189                                 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2190       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2191     }
2192   else
2193     {                           /* make them the same size */
2194       resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2195     }
2196
2197   ic = newiCode ('-', left, right);
2198
2199   IC_RESULT (ic) = newiTempOperand (resType, 1);
2200   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2201
2202   /* if left or right is a float */
2203   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2204     ic->supportRtn = 1;
2205
2206   ADDTOCHAIN (ic);
2207   return IC_RESULT (ic);
2208 }
2209
2210 /*-----------------------------------------------------------------*/
2211 /* geniCodeAdd - generates iCode for addition                      */
2212 /*-----------------------------------------------------------------*/
2213 operand *
2214 geniCodeAdd (operand * left, operand * right, int lvl)
2215 {
2216   iCode *ic;
2217   sym_link *resType;
2218   operand *size;
2219   int isarray = 0;
2220   bool indexUnsigned;
2221   LRTYPE;
2222
2223   /* if the right side is LITERAL zero */
2224   /* return the left side              */
2225   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2226     return left;
2227
2228   /* if left is literal zero return right */
2229   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2230     return right;
2231
2232   /* if left is a pointer then size */
2233   if (IS_PTR (ltype) || IS_ARRAY(ltype))
2234     {
2235       isarray = left->isaddr;
2236       // there is no need to multiply with 1
2237       if (getSize (ltype->next) != 1)
2238         {
2239           size  = operandFromLit (getSize (ltype->next));
2240           SPEC_USIGN (getSpec (operandType (size))) = 1;
2241           indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2242           right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2243           /* Even if right is a 'unsigned char',
2244              the result will be a 'signed int' due to the promotion rules.
2245              It doesn't make sense when accessing arrays, so let's fix it here: */
2246           if (indexUnsigned)
2247             SPEC_USIGN (getSpec (operandType (right))) = 1;
2248         }
2249       resType = copyLinkChain (ltype);
2250     }
2251   else
2252     { // make them the same size
2253       resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2254     }
2255
2256   /* if they are both literals then we know */
2257   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2258       && left->isLiteral && right->isLiteral)
2259     return operandFromValue (valPlus (valFromType (ltype),
2260                                       valFromType (rtype)));
2261
2262   ic = newiCode ('+', left, right);
2263
2264   IC_RESULT (ic) = newiTempOperand (resType, 1);
2265   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2266
2267   /* if left or right is a float then support
2268      routine */
2269   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2270     ic->supportRtn = 1;
2271
2272   ADDTOCHAIN (ic);
2273
2274   return IC_RESULT (ic);
2275
2276 }
2277
2278 /*-----------------------------------------------------------------*/
2279 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
2280 /*-----------------------------------------------------------------*/
2281 sym_link *
2282 aggrToPtr (sym_link * type, bool force)
2283 {
2284   sym_link *etype;
2285   sym_link *ptype;
2286
2287   if (IS_PTR (type) && !force)
2288     return type;
2289
2290   etype = getSpec (type);
2291   ptype = newLink (DECLARATOR);
2292
2293   ptype->next = type;
2294
2295   /* set the pointer depending on the storage class */
2296   DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2297   return ptype;
2298 }
2299
2300 /*-----------------------------------------------------------------*/
2301 /* geniCodeArray2Ptr - array to pointer                            */
2302 /*-----------------------------------------------------------------*/
2303 static operand *
2304 geniCodeArray2Ptr (operand * op)
2305 {
2306   sym_link *optype = operandType (op);
2307   sym_link *opetype = getSpec (optype);
2308
2309   /* set the pointer depending on the storage class */
2310   DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2311
2312   op->isaddr = 0;
2313   return op;
2314 }
2315
2316
2317 /*-----------------------------------------------------------------*/
2318 /* geniCodeArray - array access                                    */
2319 /*-----------------------------------------------------------------*/
2320 static operand *
2321 geniCodeArray (operand * left, operand * right, int lvl)
2322 {
2323   iCode *ic;
2324   operand *size;
2325   sym_link *ltype = operandType (left);
2326   bool indexUnsigned;
2327
2328   if (IS_PTR (ltype))
2329     {
2330       if (IS_PTR (ltype->next) && left->isaddr)
2331         {
2332           left = geniCodeRValue (left, FALSE);
2333         }
2334
2335       return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2336     }
2337   size = operandFromLit (getSize (ltype->next));
2338   SPEC_USIGN (getSpec (operandType (size))) = 1;
2339   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2340   right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2341   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2342      It doesn't make sense when accessing arrays, so let's fix it here: */
2343   if (indexUnsigned)
2344     SPEC_USIGN (getSpec (operandType (right))) = 1;
2345   /* we can check for limits here */
2346   /* already done in SDCCast.c
2347   if (isOperandLiteral (right) &&
2348       IS_ARRAY (ltype) &&
2349       DCL_ELEM (ltype) &&
2350       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2351     {
2352       werror (W_IDX_OUT_OF_BOUNDS,
2353               (int) operandLitValue (right) / getSize (ltype->next),
2354               DCL_ELEM (ltype));
2355     }
2356   */
2357
2358   ic = newiCode ('+', left, right);
2359
2360   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2361                                       !IS_AGGREGATE (ltype->next) &&
2362                                       !IS_PTR (ltype->next))
2363                                      ? ltype : ltype->next), 0);
2364
2365   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2366   ADDTOCHAIN (ic);
2367
2368   return IC_RESULT (ic);
2369 }
2370
2371 /*-----------------------------------------------------------------*/
2372 /* geniCodeStruct - generates intermediate code for structures     */
2373 /*-----------------------------------------------------------------*/
2374 operand *
2375 geniCodeStruct (operand * left, operand * right, bool islval)
2376 {
2377   iCode *ic;
2378   sym_link *type = operandType (left);
2379   sym_link *etype = getSpec (type);
2380   sym_link *retype;
2381   symbol *element = getStructElement (SPEC_STRUCT (etype),
2382                                       right->operand.symOperand);
2383
2384   wassert(IS_SYMOP(right));
2385     
2386   /* add the offset */
2387   ic = newiCode ('+', left, operandFromLit (element->offset));
2388
2389   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2390
2391   /* preserve the storage & output class of the struct */
2392   /* as well as the volatile attribute */
2393   retype = getSpec (operandType (IC_RESULT (ic)));
2394   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2395   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2396   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2397   SPEC_CONST (retype) |= SPEC_CONST (etype);
2398   
2399   if (IS_PTR (element->type))
2400     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2401   
2402   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2403
2404   ADDTOCHAIN (ic);
2405   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2406 }
2407
2408 /*-----------------------------------------------------------------*/
2409 /* geniCodePostInc - generate int code for Post increment          */
2410 /*-----------------------------------------------------------------*/
2411 operand *
2412 geniCodePostInc (operand * op)
2413 {
2414   iCode *ic;
2415   operand *rOp;
2416   sym_link *optype = operandType (op);
2417   operand *result;
2418   operand *rv = (IS_ITEMP (op) ?
2419                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2420                  op);
2421   sym_link *rvtype = operandType (rv);
2422   int size = 0;
2423
2424   /* if this is not an address we have trouble */
2425   if (!op->isaddr)
2426     {
2427       werror (E_LVALUE_REQUIRED, "++");
2428       return op;
2429     }
2430
2431   rOp = newiTempOperand (rvtype, 0);
2432   OP_SYMBOL(rOp)->noSpilLoc = 1;
2433
2434   if (IS_ITEMP (rv))
2435     OP_SYMBOL(rv)->noSpilLoc = 1;
2436
2437   geniCodeAssign (rOp, rv, 0);
2438
2439   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2440   if (IS_FLOAT (rvtype))
2441     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2442   else
2443     ic = newiCode ('+', rv, operandFromLit (size));
2444
2445   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2446   ADDTOCHAIN (ic);
2447
2448   geniCodeAssign (op, result, 0);
2449
2450   return rOp;
2451
2452 }
2453
2454 /*-----------------------------------------------------------------*/
2455 /* geniCodePreInc - generate code for preIncrement                 */
2456 /*-----------------------------------------------------------------*/
2457 operand *
2458 geniCodePreInc (operand * op, bool lvalue)
2459 {
2460   iCode *ic;
2461   sym_link *optype = operandType (op);
2462   operand *rop = (IS_ITEMP (op) ?
2463                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2464                   op);
2465   sym_link *roptype = operandType (rop);
2466   operand *result;
2467   int size = 0;
2468
2469   if (!op->isaddr)
2470     {
2471       werror (E_LVALUE_REQUIRED, "++");
2472       return op;
2473     }
2474
2475
2476   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2477   if (IS_FLOAT (roptype))
2478     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2479   else
2480     ic = newiCode ('+', rop, operandFromLit (size));
2481   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2482   ADDTOCHAIN (ic);
2483
2484   (void) geniCodeAssign (op, result, 0);
2485   if (lvalue || IS_TRUE_SYMOP (op))
2486     return op;
2487   else
2488     return result;
2489 }
2490
2491 /*-----------------------------------------------------------------*/
2492 /* geniCodePostDec - generates code for Post decrement             */
2493 /*-----------------------------------------------------------------*/
2494 operand *
2495 geniCodePostDec (operand * op)
2496 {
2497   iCode *ic;
2498   operand *rOp;
2499   sym_link *optype = operandType (op);
2500   operand *result;
2501   operand *rv = (IS_ITEMP (op) ?
2502                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2503                  op);
2504   sym_link *rvtype = operandType (rv);
2505   int size = 0;
2506
2507   /* if this is not an address we have trouble */
2508   if (!op->isaddr)
2509     {
2510       werror (E_LVALUE_REQUIRED, "--");
2511       return op;
2512     }
2513
2514   rOp = newiTempOperand (rvtype, 0);
2515   OP_SYMBOL(rOp)->noSpilLoc = 1;
2516
2517   if (IS_ITEMP (rv))
2518     OP_SYMBOL(rv)->noSpilLoc = 1;
2519
2520   geniCodeAssign (rOp, rv, 0);
2521
2522   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2523   if (IS_FLOAT (rvtype))
2524     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2525   else
2526     ic = newiCode ('-', rv, operandFromLit (size));
2527
2528   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2529   ADDTOCHAIN (ic);
2530
2531   geniCodeAssign (op, result, 0);
2532
2533   return rOp;
2534
2535 }
2536
2537 /*-----------------------------------------------------------------*/
2538 /* geniCodePreDec - generate code for pre  decrement               */
2539 /*-----------------------------------------------------------------*/
2540 operand *
2541 geniCodePreDec (operand * op, bool lvalue)
2542 {
2543   iCode *ic;
2544   sym_link *optype = operandType (op);
2545   operand *rop = (IS_ITEMP (op) ?
2546                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2547                   op);
2548   sym_link *roptype = operandType (rop);
2549   operand *result;
2550   int size = 0;
2551
2552   if (!op->isaddr)
2553     {
2554       werror (E_LVALUE_REQUIRED, "--");
2555       return op;
2556     }
2557
2558
2559   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2560   if (IS_FLOAT (roptype))
2561     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2562   else
2563     ic = newiCode ('-', rop, operandFromLit (size));
2564   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2565   ADDTOCHAIN (ic);
2566
2567   (void) geniCodeAssign (op, result, 0);
2568   if (lvalue || IS_TRUE_SYMOP (op))
2569     return op;
2570   else
2571     return result;
2572 }
2573
2574
2575 /*-----------------------------------------------------------------*/
2576 /* geniCodeBitwise - gen int code for bitWise  operators           */
2577 /*-----------------------------------------------------------------*/
2578 operand *
2579 geniCodeBitwise (operand * left, operand * right,
2580                  int oper, sym_link * resType)
2581 {
2582   iCode *ic;
2583
2584   left = geniCodeCast (resType, left, TRUE);
2585   right = geniCodeCast (resType, right, TRUE);
2586
2587   ic = newiCode (oper, left, right);
2588   IC_RESULT (ic) = newiTempOperand (resType, 0);
2589
2590   ADDTOCHAIN (ic);
2591   return IC_RESULT (ic);
2592 }
2593
2594 /*-----------------------------------------------------------------*/
2595 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2596 /*-----------------------------------------------------------------*/
2597 operand *
2598 geniCodeAddressOf (operand * op)
2599 {
2600   iCode *ic;
2601   sym_link *p;
2602   sym_link *optype = operandType (op);
2603   sym_link *opetype = getSpec (optype);
2604
2605   if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2606     {
2607       op = operandFromOperand (op);
2608       op->isaddr = 0;
2609       return op;
2610     }
2611   
2612   /* lvalue check already done in decorateType */
2613   /* this must be a lvalue */
2614 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2615 /*  werror (E_LVALUE_REQUIRED,"&"); */
2616 /*  return op; */
2617 /*     } */
2618
2619   p = newLink (DECLARATOR);
2620
2621   /* set the pointer depending on the storage class */
2622   DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2623
2624   p->next = copyLinkChain (optype);
2625
2626   /* if already a temp */
2627   if (IS_ITEMP (op))
2628     {
2629       setOperandType (op, p);
2630       op->isaddr = 0;
2631       return op;
2632     }
2633
2634   /* other wise make this of the type coming in */
2635   ic = newiCode (ADDRESS_OF, op, NULL);
2636   IC_RESULT (ic) = newiTempOperand (p, 1);
2637   IC_RESULT (ic)->isaddr = 0;
2638   ADDTOCHAIN (ic);
2639   return IC_RESULT (ic);
2640 }
2641 /*-----------------------------------------------------------------*/
2642 /* setOClass - sets the output class depending on the pointer type */
2643 /*-----------------------------------------------------------------*/
2644 void 
2645 setOClass (sym_link * ptr, sym_link * spec)
2646 {
2647   switch (DCL_TYPE (ptr))
2648     {
2649     case POINTER:
2650       SPEC_OCLS (spec) = data;
2651       break;
2652
2653     case GPOINTER:
2654       SPEC_OCLS (spec) = generic;
2655       break;
2656
2657     case FPOINTER:
2658       SPEC_OCLS (spec) = xdata;
2659       break;
2660
2661     case CPOINTER:
2662       SPEC_OCLS (spec) = code;
2663       break;
2664
2665     case IPOINTER:
2666       SPEC_OCLS (spec) = idata;
2667       break;
2668
2669     case PPOINTER:
2670       SPEC_OCLS (spec) = xstack;
2671       break;
2672
2673     case EEPPOINTER:
2674       SPEC_OCLS (spec) = eeprom;
2675       break;
2676
2677     default:
2678       break;
2679
2680     }
2681 }
2682
2683 /*-----------------------------------------------------------------*/
2684 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2685 /*-----------------------------------------------------------------*/
2686 operand *
2687 geniCodeDerefPtr (operand * op,int lvl)
2688 {
2689   sym_link *rtype, *retype;
2690   sym_link *optype = operandType (op);
2691
2692   // if this is an array then array access
2693   if (IS_ARRAY (optype)) {
2694     // don't worry, this will be optimized out later
2695     return geniCodeArray (op, operandFromLit (0), lvl);
2696   }
2697
2698   // just in case someone screws up
2699   wassert (IS_PTR (optype));
2700
2701   if (IS_TRUE_SYMOP (op))
2702     {
2703       op->isaddr = 1;
2704       op = geniCodeRValue (op, TRUE);
2705     }
2706
2707   /* now get rid of the pointer part */
2708   if (isLvaluereq(lvl) && IS_ITEMP (op))
2709     {
2710       retype = getSpec (rtype = copyLinkChain (optype));
2711     }
2712   else
2713     {
2714       retype = getSpec (rtype = copyLinkChain (optype->next));
2715       /* outputclass needs 2b updated */
2716       setOClass (optype, retype);
2717     }
2718   
2719   op->isGptr = IS_GENPTR (optype);
2720
2721   op->isaddr = (IS_PTR (rtype) ||
2722                 IS_STRUCT (rtype) ||
2723                 IS_INT (rtype) ||
2724                 IS_CHAR (rtype) ||
2725                 IS_FLOAT (rtype));
2726
2727   if (!isLvaluereq(lvl))
2728     op = geniCodeRValue (op, TRUE);
2729
2730   setOperandType (op, rtype);
2731
2732   return op;
2733 }
2734
2735 /*-----------------------------------------------------------------*/
2736 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2737 /*-----------------------------------------------------------------*/
2738 operand *
2739 geniCodeUnaryMinus (operand * op)
2740 {
2741   iCode *ic;
2742   sym_link *optype = operandType (op);
2743
2744   if (IS_LITERAL (optype))
2745     return operandFromLit (-floatFromVal (op->operand.valOperand));
2746
2747   ic = newiCode (UNARYMINUS, op, NULL);
2748   IC_RESULT (ic) = newiTempOperand (optype, 0);
2749   ADDTOCHAIN (ic);
2750   return IC_RESULT (ic);
2751 }
2752
2753 /*-----------------------------------------------------------------*/
2754 /* geniCodeLeftShift - gen i code for left shift                   */
2755 /*-----------------------------------------------------------------*/
2756 operand *
2757 geniCodeLeftShift (operand * left, operand * right)
2758 {
2759   iCode *ic;
2760
2761   ic = newiCode (LEFT_OP, left, right);
2762   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2763   ADDTOCHAIN (ic);
2764   return IC_RESULT (ic);
2765 }
2766
2767 /*-----------------------------------------------------------------*/
2768 /* geniCodeRightShift - gen i code for right shift                 */
2769 /*-----------------------------------------------------------------*/
2770 operand *
2771 geniCodeRightShift (operand * left, operand * right)
2772 {
2773   iCode *ic;
2774
2775   ic = newiCode (RIGHT_OP, left, right);
2776   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2777   ADDTOCHAIN (ic);
2778   return IC_RESULT (ic);
2779 }
2780
2781 /*-----------------------------------------------------------------*/
2782 /* geniCodeLogic- logic code                                       */
2783 /*-----------------------------------------------------------------*/
2784 operand *
2785 geniCodeLogic (operand * left, operand * right, int op)
2786 {
2787   iCode *ic;
2788   sym_link *ctype;
2789   sym_link *rtype = operandType (right);
2790   sym_link *ltype = operandType (left);
2791
2792   /* left is integral type and right is literal then
2793      check if the literal value is within bounds */
2794   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2795     {
2796       checkConstantRange(ltype,
2797                          OP_VALUE(right), "compare operation", 1);
2798     }
2799
2800   /* if one operand is a pointer and the other is a literal generic void pointer,
2801      change the type of the literal generic void pointer to match the other pointer */
2802   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2803       && IS_PTR (rtype) && !IS_GENPTR(rtype))
2804     {
2805       /* find left's definition */
2806       ic = (iCode *) setFirstItem (iCodeChain);
2807       while (ic)
2808         {
2809           if (((ic->op == CAST) || (ic->op == '='))
2810               && isOperandEqual(left, IC_RESULT (ic)))
2811             break;
2812           else
2813             ic = setNextItem (iCodeChain);
2814         }
2815       /* if casting literal to generic pointer, then cast to rtype instead */
2816       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2817         {
2818           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2819           ltype = operandType(left);
2820         }
2821     }
2822   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2823       && IS_PTR (ltype) && !IS_GENPTR(ltype))
2824     {
2825       /* find right's definition */
2826       ic = (iCode *) setFirstItem (iCodeChain);
2827       while (ic)
2828         {
2829           if (((ic->op == CAST) || (ic->op == '='))
2830               && isOperandEqual(right, IC_RESULT (ic)))
2831             break;
2832           else
2833             ic = setNextItem (iCodeChain);
2834         }
2835       /* if casting literal to generic pointer, then cast to rtype instead */
2836       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2837         {
2838           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2839           rtype = operandType(right);
2840         }
2841     }
2842
2843   ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2844
2845   ic = newiCode (op, left, right);
2846   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2847
2848   /* if comparing float
2849      and not a '==' || '!=' || '&&' || '||' (these
2850      will be inlined */
2851   if (IS_FLOAT(ctype) &&
2852       op != EQ_OP &&
2853       op != NE_OP &&
2854       op != AND_OP &&
2855       op != OR_OP)
2856     ic->supportRtn = 1;
2857
2858   ADDTOCHAIN (ic);
2859   return IC_RESULT (ic);
2860 }
2861
2862 /*-----------------------------------------------------------------*/
2863 /* geniCodeUnary - for a a generic unary operation                 */
2864 /*-----------------------------------------------------------------*/
2865 operand *
2866 geniCodeUnary (operand * op, int oper)
2867 {
2868   iCode *ic = newiCode (oper, op, NULL);
2869
2870   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2871   ADDTOCHAIN (ic);
2872   return IC_RESULT (ic);
2873 }
2874
2875 /*-----------------------------------------------------------------*/
2876 /* geniCodeConditional - geniCode for '?' ':' operation            */
2877 /*-----------------------------------------------------------------*/
2878 operand *
2879 geniCodeConditional (ast * tree,int lvl)
2880 {
2881   iCode *ic;
2882   symbol *falseLabel = newiTempLabel (NULL);
2883   symbol *exitLabel = newiTempLabel (NULL);
2884   operand *cond = ast2iCode (tree->left,lvl+1);
2885   operand *true, *false, *result;
2886
2887   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2888                           NULL, falseLabel);
2889   ADDTOCHAIN (ic);
2890
2891   true = ast2iCode (tree->right->left,lvl+1);
2892
2893   /* move the value to a new Operand */
2894   result = newiTempOperand (tree->right->ftype, 0);
2895   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2896
2897   /* generate an unconditional goto */
2898   geniCodeGoto (exitLabel);
2899
2900   /* now for the right side */
2901   geniCodeLabel (falseLabel);
2902
2903   false = ast2iCode (tree->right->right,lvl+1);
2904   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2905
2906   /* create the exit label */
2907   geniCodeLabel (exitLabel);
2908
2909   return result;
2910 }
2911
2912 /*-----------------------------------------------------------------*/
2913 /* geniCodeAssign - generate code for assignment                   */
2914 /*-----------------------------------------------------------------*/
2915 operand *
2916 geniCodeAssign (operand * left, operand * right, int nosupdate)
2917 {
2918   iCode *ic;
2919   sym_link *ltype = operandType (left);
2920   sym_link *rtype = operandType (right);
2921
2922   if (!left->isaddr && !IS_ITEMP (left))
2923     {
2924       werror (E_LVALUE_REQUIRED, "assignment");
2925       return left;
2926     }
2927
2928   /* left is integral type and right is literal then
2929      check if the literal value is within bounds */
2930   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2931     {
2932       checkConstantRange(ltype, 
2933                          OP_VALUE(right), "= operation", 0);
2934     }
2935
2936   /* if the left & right type don't exactly match */
2937   /* if pointer set then make sure the check is
2938      done with the type & not the pointer */
2939   /* then cast rights type to left */
2940
2941   /* first check the type for pointer assignement */
2942   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2943       compareType (ltype, rtype) <= 0)
2944     {
2945       if (compareType (ltype->next, rtype) < 0)
2946         right = geniCodeCast (ltype->next, right, TRUE);
2947     }
2948   else if (compareType (ltype, rtype) < 0)
2949     right = geniCodeCast (ltype, right, TRUE);
2950
2951   /* If left is a true symbol & ! volatile
2952      create an assignment to temporary for
2953      the right & then assign this temporary
2954      to the symbol. This is SSA (static single
2955      assignment). Isn't it simple and folks have
2956      published mountains of paper on it */
2957   if (IS_TRUE_SYMOP (left) &&
2958       !isOperandVolatile (left, FALSE) &&
2959       isOperandGlobal (left))
2960     {
2961       symbol *sym = NULL;
2962
2963       if (IS_TRUE_SYMOP (right))
2964         sym = OP_SYMBOL (right);
2965       ic = newiCode ('=', NULL, right);
2966       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2967       SPIL_LOC (right) = sym;
2968       ADDTOCHAIN (ic);
2969     }
2970
2971   ic = newiCode ('=', NULL, right);
2972   IC_RESULT (ic) = left;
2973   ADDTOCHAIN (ic);
2974
2975   /* if left isgptr flag is set then support
2976      routine will be required */
2977   if (left->isGptr)
2978     ic->supportRtn = 1;
2979
2980   ic->nosupdate = nosupdate;
2981   return left;
2982 }
2983
2984 /*-----------------------------------------------------------------*/
2985 /* geniCodeDummyRead - generate code for dummy read                */
2986 /*-----------------------------------------------------------------*/
2987 static void
2988 geniCodeDummyRead (operand * op)
2989 {
2990   iCode *ic;
2991   sym_link *type = operandType (op);
2992
2993   if (!IS_VOLATILE(type))
2994     return;
2995     
2996   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2997   ADDTOCHAIN (ic);
2998
2999   ic->nosupdate = 1;
3000 }
3001
3002 /*-----------------------------------------------------------------*/
3003 /* geniCodeSEParms - generate code for side effecting fcalls       */
3004 /*-----------------------------------------------------------------*/
3005 static void 
3006 geniCodeSEParms (ast * parms,int lvl)
3007 {
3008   if (!parms)
3009     return;
3010
3011   if (parms->type == EX_OP && parms->opval.op == PARAM)
3012     {
3013       geniCodeSEParms (parms->left,lvl);
3014       geniCodeSEParms (parms->right,lvl);
3015       return;
3016     }
3017
3018   /* hack don't like this but too lazy to think of
3019      something better */
3020   if (IS_ADDRESS_OF_OP (parms))
3021     parms->left->lvalue = 1;
3022
3023   if (IS_CAST_OP (parms) &&
3024       IS_PTR (parms->ftype) &&
3025       IS_ADDRESS_OF_OP (parms->right))
3026     parms->right->left->lvalue = 1;
3027
3028   parms->opval.oprnd = 
3029     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3030                 
3031   parms->type = EX_OPERAND;
3032   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3033                 SPEC_ARGREG(parms->ftype);
3034 }
3035
3036 /*-----------------------------------------------------------------*/
3037 /* geniCodeParms - generates parameters                            */
3038 /*-----------------------------------------------------------------*/
3039 value *
3040 geniCodeParms (ast * parms, value *argVals, int *stack, 
3041                sym_link * fetype, symbol * func,int lvl)
3042 {
3043   iCode *ic;
3044   operand *pval;
3045
3046   if (!parms)
3047     return argVals;
3048
3049   if (argVals==NULL) {
3050     // first argument
3051     if (IS_CODEPTR(func->type))
3052       argVals = FUNC_ARGS (func->type->next);
3053     else
3054       argVals = FUNC_ARGS (func->type);
3055   }
3056
3057   /* if this is a param node then do the left & right */
3058   if (parms->type == EX_OP && parms->opval.op == PARAM)
3059     {
3060       argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
3061       argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
3062       return argVals;
3063     }
3064
3065   /* get the parameter value */
3066   if (parms->type == EX_OPERAND)
3067     pval = parms->opval.oprnd;
3068   else
3069     {
3070       /* maybe this else should go away ?? */
3071       /* hack don't like this but too lazy to think of
3072          something better */
3073       if (IS_ADDRESS_OF_OP (parms))
3074         parms->left->lvalue = 1;
3075
3076       if (IS_CAST_OP (parms) &&
3077           IS_PTR (parms->ftype) &&
3078           IS_ADDRESS_OF_OP (parms->right))
3079         parms->right->left->lvalue = 1;
3080
3081       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3082     }
3083
3084   /* if register parm then make it a send */
3085   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3086       IFFUNC_ISBUILTIN(func->type))
3087     {
3088       ic = newiCode (SEND, pval, NULL);
3089       ic->argreg = SPEC_ARGREG(parms->etype);
3090       ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3091       ADDTOCHAIN (ic);
3092     }
3093   else
3094     {
3095       /* now decide whether to push or assign */
3096       if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3097         {
3098
3099           /* assign */
3100           operand *top = operandFromSymbol (argVals->sym);
3101           /* clear useDef and other bitVectors */
3102           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3103           geniCodeAssign (top, pval, 1);
3104         }
3105       else
3106         {
3107           sym_link *p = operandType (pval);
3108           /* push */
3109           ic = newiCode (IPUSH, pval, NULL);
3110           ic->parmPush = 1;
3111           /* update the stack adjustment */
3112           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3113           ADDTOCHAIN (ic);
3114         }
3115     }
3116
3117   argVals=argVals->next;
3118   return argVals;
3119 }
3120
3121 /*-----------------------------------------------------------------*/
3122 /* geniCodeCall - generates temp code for calling                  */
3123 /*-----------------------------------------------------------------*/
3124 operand *
3125 geniCodeCall (operand * left, ast * parms,int lvl)
3126 {
3127   iCode *ic;
3128   operand *result;
3129   sym_link *type, *etype;
3130   int stack = 0;
3131
3132   if (!IS_FUNC(OP_SYMBOL(left)->type) && 
3133       !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3134     werror (E_FUNCTION_EXPECTED);
3135     return operandFromValue(valueFromLit(0));
3136   }
3137
3138   /* take care of parameters with side-effecting
3139      function calls in them, this is required to take care
3140      of overlaying function parameters */
3141   geniCodeSEParms (parms,lvl);
3142
3143   /* first the parameters */
3144   geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3145
3146   /* now call : if symbol then pcall */
3147   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3148     ic = newiCode (PCALL, left, NULL);
3149   } else {
3150     ic = newiCode (CALL, left, NULL);
3151   }
3152
3153   type = copyLinkChain (operandType (left)->next);
3154   etype = getSpec (type);
3155   SPEC_EXTR (etype) = 0;
3156   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3157
3158   ADDTOCHAIN (ic);
3159
3160   /* stack adjustment after call */
3161   ic->parmBytes = stack;
3162
3163   return result;
3164 }
3165
3166 /*-----------------------------------------------------------------*/
3167 /* geniCodeReceive - generate intermediate code for "receive"      */
3168 /*-----------------------------------------------------------------*/
3169 static void 
3170 geniCodeReceive (value * args)
3171 {
3172   /* for all arguments that are passed in registers */
3173   while (args)
3174     {
3175       int first = 1;
3176       if (IS_REGPARM (args->etype))
3177         {
3178           operand *opr = operandFromValue (args);
3179           operand *opl;
3180           symbol *sym = OP_SYMBOL (opr);
3181           iCode *ic;
3182
3183           /* we will use it after all optimizations
3184              and before liveRange calculation */
3185           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3186             {
3187
3188               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3189                   options.stackAuto == 0 &&
3190                   (!(options.model == MODEL_FLAT24)) )
3191                 {
3192                 }
3193               else
3194                 {
3195                   opl = newiTempOperand (args->type, 0);
3196                   sym->reqv = opl;
3197                   sym->reqv->key = sym->key;
3198                   OP_SYMBOL (sym->reqv)->key = sym->key;
3199                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3200                   OP_SYMBOL (sym->reqv)->islocal = 0;
3201                   SPIL_LOC (sym->reqv) = sym;
3202                 }
3203             }
3204
3205           ic = newiCode (RECEIVE, NULL, NULL);    
3206           ic->argreg = SPEC_ARGREG(args->etype);
3207           if (first) {
3208               currFunc->recvSize = getSize (sym->type);
3209               first = 0;
3210           }
3211           IC_RESULT (ic) = opr;
3212           ADDTOCHAIN (ic);
3213         }
3214
3215       args = args->next;
3216     }
3217 }
3218
3219 /*-----------------------------------------------------------------*/
3220 /* geniCodeFunctionBody - create the function body                 */
3221 /*-----------------------------------------------------------------*/
3222 void 
3223 geniCodeFunctionBody (ast * tree,int lvl)
3224 {
3225   iCode *ic;
3226   operand *func;
3227   sym_link *fetype;
3228   int savelineno;
3229
3230   /* reset the auto generation */
3231   /* numbers */
3232   iTempNum = 0;
3233   iTempLblNum = 0;
3234   operandKey = 0;
3235   iCodeKey = 0;
3236   func = ast2iCode (tree->left,lvl+1);
3237   fetype = getSpec (operandType (func));
3238
3239   savelineno = lineno;
3240   lineno = OP_SYMBOL (func)->lineDef;
3241   /* create an entry label */
3242   geniCodeLabel (entryLabel);
3243   lineno = savelineno;
3244
3245   /* create a proc icode */
3246   ic = newiCode (FUNCTION, func, NULL);
3247   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3248
3249   ADDTOCHAIN (ic);
3250
3251   /* for all parameters that are passed
3252      on registers add a "receive" */
3253   geniCodeReceive (tree->values.args);
3254
3255   /* generate code for the body */
3256   ast2iCode (tree->right,lvl+1);
3257
3258   /* create a label for return */
3259   geniCodeLabel (returnLabel);
3260
3261   /* now generate the end proc */
3262   ic = newiCode (ENDFUNCTION, func, NULL);
3263   ADDTOCHAIN (ic);
3264   return;
3265 }
3266
3267 /*-----------------------------------------------------------------*/
3268 /* geniCodeReturn - gen icode for 'return' statement               */
3269 /*-----------------------------------------------------------------*/
3270 void 
3271 geniCodeReturn (operand * op)
3272 {
3273   iCode *ic;
3274
3275   /* if the operand is present force an rvalue */
3276   if (op)
3277     op = geniCodeRValue (op, FALSE);
3278
3279   ic = newiCode (RETURN, op, NULL);
3280   ADDTOCHAIN (ic);
3281 }
3282
3283 /*-----------------------------------------------------------------*/
3284 /* geniCodeIfx - generates code for extended if statement          */
3285 /*-----------------------------------------------------------------*/
3286 void 
3287 geniCodeIfx (ast * tree,int lvl)
3288 {
3289   iCode *ic;
3290   operand *condition = ast2iCode (tree->left,lvl+1);
3291   sym_link *cetype;
3292
3293   /* if condition is null then exit */
3294   if (!condition)
3295     goto exit;
3296   else
3297     condition = geniCodeRValue (condition, FALSE);
3298
3299   cetype = getSpec (operandType (condition));
3300   /* if the condition is a literal */
3301   if (IS_LITERAL (cetype))
3302     {
3303       if (floatFromVal (condition->operand.valOperand))
3304         {
3305           if (tree->trueLabel)
3306             geniCodeGoto (tree->trueLabel);
3307           else
3308             assert (0);
3309         }
3310       else
3311         {
3312           if (tree->falseLabel)
3313             geniCodeGoto (tree->falseLabel);
3314           else
3315             assert (0);
3316         }
3317       goto exit;
3318     }
3319
3320   if (tree->trueLabel)
3321     {
3322       ic = newiCodeCondition (condition,
3323                               tree->trueLabel,
3324                               NULL);
3325       ADDTOCHAIN (ic);
3326
3327       if (tree->falseLabel)
3328         geniCodeGoto (tree->falseLabel);
3329     }
3330   else
3331     {
3332       ic = newiCodeCondition (condition,
3333                               NULL,
3334                               tree->falseLabel);
3335       ADDTOCHAIN (ic);
3336     }
3337
3338 exit:
3339   ast2iCode (tree->right,lvl+1);
3340 }
3341
3342 /*-----------------------------------------------------------------*/
3343 /* geniCodeJumpTable - tries to create a jump table for switch     */
3344 /*-----------------------------------------------------------------*/
3345 int 
3346 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3347 {
3348   int min = 0, max = 0, t, cnt = 0;
3349   value *vch;
3350   iCode *ic;
3351   operand *boundary;
3352   symbol *falseLabel;
3353   set *labels = NULL;
3354   int needRangeCheck = !optimize.noJTabBoundary
3355                        || tree->values.switchVals.swDefault;
3356
3357   if (!tree || !caseVals)
3358     return 0;
3359
3360   /* the criteria for creating a jump table is */
3361   /* all integer numbers between the maximum & minimum must */
3362   /* be present , the maximum value should not exceed 255 */
3363   min = max = (int) floatFromVal (vch = caseVals);
3364   SNPRINTF (buffer, sizeof(buffer), 
3365             "_case_%d_%d",
3366            tree->values.switchVals.swNum,
3367            min);
3368   addSet (&labels, newiTempLabel (buffer));
3369
3370   /* if there is only one case value then no need */
3371   if (!(vch = vch->next))
3372     return 0;
3373
3374   while (vch)
3375     {
3376       if (((t = (int) floatFromVal (vch)) - max) != 1)
3377         return 0;
3378       SNPRINTF (buffer, sizeof(buffer), 
3379                 "_case_%d_%d",
3380                tree->values.switchVals.swNum,
3381                t);
3382       addSet (&labels, newiTempLabel (buffer));
3383       max = t;
3384       cnt++;
3385       vch = vch->next;
3386     }
3387
3388   /* if the number of case statements <= 2 then */
3389   /* it is not economical to create the jump table */
3390   /* since two compares are needed for boundary conditions */
3391   if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3392     return 0;
3393
3394   if (tree->values.switchVals.swDefault)
3395     {
3396         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3397     }
3398   else
3399     {
3400         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3401     }
3402     
3403
3404   falseLabel = newiTempLabel (buffer);
3405
3406   /* so we can create a jumptable */
3407   /* first we rule out the boundary conditions */
3408   /* if only optimization says so */
3409   if (needRangeCheck)
3410     {
3411       sym_link *cetype = getSpec (operandType (cond));
3412       /* no need to check the lower bound if
3413          the condition is unsigned & minimum value is zero */
3414       if (!(min == 0 && IS_UNSIGNED (cetype)))
3415         {
3416           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3417           ic = newiCodeCondition (boundary, falseLabel, NULL);
3418           ADDTOCHAIN (ic);
3419         }
3420
3421       /* now for upper bounds */
3422       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3423       ic = newiCodeCondition (boundary, falseLabel, NULL);
3424       ADDTOCHAIN (ic);
3425     }
3426
3427   /* if the min is not zero then we no make it zero */
3428   if (min)
3429     {
3430       cond = geniCodeSubtract (cond, operandFromLit (min));
3431       if (!IS_LITERAL(getSpec(operandType(cond))))
3432         setOperandType (cond, UCHARTYPE);
3433     }
3434
3435   /* now create the jumptable */
3436   ic = newiCode (JUMPTABLE, NULL, NULL);
3437   IC_JTCOND (ic) = cond;
3438   IC_JTLABELS (ic) = labels;
3439   ADDTOCHAIN (ic);
3440   return 1;
3441 }
3442
3443 /*-----------------------------------------------------------------*/
3444 /* geniCodeSwitch - changes a switch to a if statement             */
3445 /*-----------------------------------------------------------------*/
3446 void
3447 geniCodeSwitch (ast * tree,int lvl)
3448 {
3449   iCode *ic;
3450   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3451   value *caseVals = tree->values.switchVals.swVals;
3452   symbol *trueLabel, *falseLabel;
3453       
3454   /* If the condition is a literal, then just jump to the */
3455   /* appropriate case label. */
3456   if (IS_LITERAL(getSpec(operandType(cond))))
3457     {
3458       int switchVal, caseVal;
3459       
3460       switchVal = (int) floatFromVal (cond->operand.valOperand);
3461       while (caseVals)
3462         {
3463           caseVal = (int) floatFromVal (caseVals);
3464           if (caseVal == switchVal)
3465             {
3466               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3467                         tree->values.switchVals.swNum, caseVal);
3468               trueLabel = newiTempLabel (buffer);
3469               geniCodeGoto (trueLabel);
3470               goto jumpTable;
3471             }
3472           caseVals = caseVals->next;
3473         }
3474       goto defaultOrBreak;
3475     }
3476
3477   /* if we can make this a jump table */
3478   if (geniCodeJumpTable (cond, caseVals, tree))
3479     goto jumpTable;             /* no need for the comparison */
3480
3481   /* for the cases defined do */
3482   while (caseVals)
3483     {
3484
3485       operand *compare = geniCodeLogic (cond,
3486                                         operandFromValue (caseVals),
3487                                         EQ_OP);
3488
3489       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3490                tree->values.switchVals.swNum,
3491                (int) floatFromVal (caseVals));
3492       trueLabel = newiTempLabel (buffer);
3493
3494       ic = newiCodeCondition (compare, trueLabel, NULL);
3495       ADDTOCHAIN (ic);
3496       caseVals = caseVals->next;
3497     }
3498
3499
3500 defaultOrBreak:
3501   /* if default is present then goto break else break */
3502   if (tree->values.switchVals.swDefault)
3503     {
3504         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3505     }
3506   else
3507     {
3508         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3509     }
3510
3511   falseLabel = newiTempLabel (buffer);
3512   geniCodeGoto (falseLabel);
3513
3514 jumpTable:
3515   ast2iCode (tree->right,lvl+1);
3516 }
3517
3518 /*-----------------------------------------------------------------*/
3519 /* geniCodeInline - intermediate code for inline assembler         */
3520 /*-----------------------------------------------------------------*/
3521 static void 
3522 geniCodeInline (ast * tree)
3523 {
3524   iCode *ic;
3525
3526   ic = newiCode (INLINEASM, NULL, NULL);
3527   IC_INLINE (ic) = tree->values.inlineasm;
3528   ADDTOCHAIN (ic);
3529 }
3530
3531 /*-----------------------------------------------------------------*/
3532 /* geniCodeArrayInit - intermediate code for array initializer     */
3533 /*-----------------------------------------------------------------*/
3534 static void
3535 geniCodeArrayInit (ast * tree, operand *array)
3536 {
3537   iCode *ic;
3538
3539   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3540     ic = newiCode (ARRAYINIT, array, NULL);
3541     IC_ARRAYILIST (ic) = tree->values.constlist;
3542   } else {
3543     operand *left=newOperand(), *right=newOperand();
3544     left->type=right->type=SYMBOL;
3545     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3546     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3547     ic = newiCode (ARRAYINIT, left, right);
3548   }
3549   ADDTOCHAIN (ic);
3550 }
3551         
3552 /*-----------------------------------------------------------------*/
3553 /* geniCodeCritical - intermediate code for a critical statement   */
3554 /*-----------------------------------------------------------------*/
3555 static void 
3556 geniCodeCritical (ast *tree, int lvl)
3557 {
3558   iCode *ic;
3559   operand *op = NULL;
3560
3561   /* If op is NULL, the original interrupt state will saved on */
3562   /* the stack. Otherwise, it will be saved in op. */
3563   
3564   /* Generate a save of the current interrupt state & disabled */
3565   ic = newiCode (CRITICAL, NULL, NULL);
3566   IC_RESULT (ic) = op;
3567   ADDTOCHAIN (ic);
3568   
3569   /* Generate the critical code sequence */
3570   if (tree->left && tree->left->type == EX_VALUE)
3571     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3572   else
3573     ast2iCode (tree->left,lvl+1);
3574   
3575   /* Generate a restore of the original interrupt state */
3576   ic = newiCode (ENDCRITICAL, NULL, op);
3577   ADDTOCHAIN (ic);
3578 }
3579
3580 /*-----------------------------------------------------------------*/
3581 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3582 /* particular case. Ie : assigning or dereferencing array or ptr   */
3583 /*-----------------------------------------------------------------*/
3584 set * lvaluereqSet = NULL;
3585 typedef struct lvalItem
3586   {
3587     int req;
3588     int lvl;
3589   }
3590 lvalItem;
3591
3592 /*-----------------------------------------------------------------*/
3593 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3594 /*-----------------------------------------------------------------*/
3595 void addLvaluereq(int lvl)
3596 {
3597   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3598   lpItem->req=1;
3599   lpItem->lvl=lvl;
3600   addSetHead(&lvaluereqSet,lpItem);
3601
3602 }
3603 /*-----------------------------------------------------------------*/
3604 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3605 /*-----------------------------------------------------------------*/
3606 void delLvaluereq()
3607 {
3608   lvalItem * lpItem;
3609   lpItem = getSet(&lvaluereqSet);
3610   if(lpItem) Safe_free(lpItem);
3611 }
3612 /*-----------------------------------------------------------------*/
3613 /* clearLvaluereq - clear lvalreq flag                             */
3614 /*-----------------------------------------------------------------*/
3615 void clearLvaluereq()
3616 {
3617   lvalItem * lpItem;
3618   lpItem = peekSet(lvaluereqSet);
3619   if(lpItem) lpItem->req = 0;
3620 }
3621 /*-----------------------------------------------------------------*/
3622 /* getLvaluereq - get the last lvalreq level                       */
3623 /*-----------------------------------------------------------------*/
3624 int getLvaluereqLvl()
3625 {
3626   lvalItem * lpItem;
3627   lpItem = peekSet(lvaluereqSet);
3628   if(lpItem) return lpItem->lvl;
3629   return 0;
3630 }
3631 /*-----------------------------------------------------------------*/
3632 /* isLvaluereq - is lvalreq valid for this level ?                 */
3633 /*-----------------------------------------------------------------*/
3634 int isLvaluereq(int lvl)
3635 {
3636   lvalItem * lpItem;
3637   lpItem = peekSet(lvaluereqSet);
3638   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3639   return 0;
3640 }
3641
3642 /*-----------------------------------------------------------------*/
3643 /* ast2iCode - creates an icodeList from an ast                    */
3644 /*-----------------------------------------------------------------*/
3645 operand *
3646 ast2iCode (ast * tree,int lvl)
3647 {
3648   operand *left = NULL;
3649   operand *right = NULL;
3650   if (!tree)
3651     return NULL;
3652
3653   /* set the global variables for filename & line number */
3654   if (tree->filename)
3655     filename = tree->filename;
3656   if (tree->lineno)
3657     lineno = tree->lineno;
3658   if (tree->block)
3659     block = tree->block;
3660   if (tree->level)
3661     scopeLevel = tree->level;
3662   if (tree->seqPoint)
3663     seqPoint = tree->seqPoint;
3664
3665   if (tree->type == EX_VALUE)
3666     return operandFromValue (tree->opval.val);
3667
3668   if (tree->type == EX_LINK)
3669     return operandFromLink (tree->opval.lnk);
3670
3671   /* if we find a nullop */
3672   if (tree->type == EX_OP &&
3673      (tree->opval.op == NULLOP ||
3674      tree->opval.op == BLOCK))
3675     {
3676       if (tree->left && tree->left->type == EX_VALUE)
3677         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3678       else
3679         ast2iCode (tree->left,lvl+1);
3680       if (tree->right && tree->right->type == EX_VALUE)
3681         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3682       else
3683         ast2iCode (tree->right,lvl+1);
3684       return NULL;
3685     }
3686
3687   /* special cases for not evaluating */
3688   if (tree->opval.op != ':' &&
3689       tree->opval.op != '?' &&
3690       tree->opval.op != CALL &&
3691       tree->opval.op != IFX &&
3692       tree->opval.op != LABEL &&
3693       tree->opval.op != GOTO &&
3694       tree->opval.op != SWITCH &&
3695       tree->opval.op != FUNCTION &&
3696       tree->opval.op != INLINEASM &&
3697       tree->opval.op != CRITICAL)
3698     {
3699
3700         if (IS_ASSIGN_OP (tree->opval.op) ||
3701            IS_DEREF_OP (tree) ||
3702            (tree->opval.op == '&' && !tree->right) ||
3703            tree->opval.op == PTR_OP)
3704           {
3705             addLvaluereq(lvl);
3706             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3707                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3708               clearLvaluereq();
3709
3710             left = operandFromAst (tree->left,lvl);
3711             delLvaluereq();
3712             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3713               left = geniCodeRValue (left, TRUE);
3714           }
3715         else
3716           {
3717             left = operandFromAst (tree->left,lvl);
3718           }
3719         if (tree->opval.op == INC_OP ||
3720             tree->opval.op == DEC_OP)
3721           {
3722             addLvaluereq(lvl);
3723             right = operandFromAst (tree->right,lvl);
3724             delLvaluereq();
3725           }
3726         else
3727           {
3728             right = operandFromAst (tree->right,lvl);
3729           }
3730       }
3731
3732   /* now depending on the type of operand */
3733   /* this will be a biggy                 */
3734   switch (tree->opval.op)
3735     {
3736
3737     case '[':                   /* array operation */
3738       {
3739         //sym_link *ltype = operandType (left);
3740         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3741         left = geniCodeRValue (left, FALSE);
3742         right = geniCodeRValue (right, TRUE);
3743       }
3744
3745       return geniCodeArray (left, right,lvl);
3746
3747     case '.':                   /* structure dereference */
3748       if (IS_PTR (operandType (left)))
3749         left = geniCodeRValue (left, TRUE);
3750       else
3751         left = geniCodeRValue (left, FALSE);
3752
3753       return geniCodeStruct (left, right, tree->lvalue);
3754
3755     case PTR_OP:                /* structure pointer dereference */
3756       {
3757         sym_link *pType;
3758         pType = operandType (left);
3759         left = geniCodeRValue (left, TRUE);
3760
3761         setOClass (pType, getSpec (operandType (left)));
3762       }
3763
3764       return geniCodeStruct (left, right, tree->lvalue);
3765
3766     case INC_OP:                /* increment operator */
3767       if (left)
3768         return geniCodePostInc (left);
3769       else
3770         return geniCodePreInc (right, tree->lvalue);
3771
3772     case DEC_OP:                /* decrement operator */
3773       if (left)
3774         return geniCodePostDec (left);
3775       else
3776         return geniCodePreDec (right, tree->lvalue);
3777
3778     case '&':                   /* bitwise and or address of operator */
3779       if (right)
3780         {                       /* this is a bitwise operator   */
3781           left = geniCodeRValue (left, FALSE);
3782           right = geniCodeRValue (right, FALSE);
3783           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3784         }
3785       else
3786         return geniCodeAddressOf (left);
3787
3788     case '|':                   /* bitwise or & xor */
3789     case '^':
3790       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3791                               geniCodeRValue (right, FALSE),
3792                               tree->opval.op,
3793                               tree->ftype);
3794
3795     case '/':
3796       return geniCodeDivision (geniCodeRValue (left, FALSE),
3797                                geniCodeRValue (right, FALSE));
3798
3799     case '%':
3800       return geniCodeModulus (geniCodeRValue (left, FALSE),
3801                               geniCodeRValue (right, FALSE));
3802     case '*':
3803       if (right)
3804         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3805                                  geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3806       else
3807         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3808
3809     case '-':
3810       if (right)
3811         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3812                                  geniCodeRValue (right, FALSE));
3813       else
3814         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3815
3816     case '+':
3817       if (right)
3818         return geniCodeAdd (geniCodeRValue (left, FALSE),
3819                             geniCodeRValue (right, FALSE),lvl);
3820       else
3821         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3822
3823     case LEFT_OP:
3824       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3825                                 geniCodeRValue (right, FALSE));
3826
3827     case RIGHT_OP:
3828       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3829                                  geniCodeRValue (right, FALSE));
3830     case CAST:
3831 #if 0 // this indeed needs a second thought
3832       {
3833         operand *op;
3834
3835         // let's keep this simple: get the rvalue we need
3836         op=geniCodeRValue (right, FALSE);
3837         // now cast it to whatever we want
3838         op=geniCodeCast (operandType(left), op, FALSE);
3839         // if this is going to be used as an lvalue, make it so
3840         if (tree->lvalue) {
3841           op->isaddr=1;
3842         }
3843         return op;
3844       }
3845 #else // bug #604575, is it a bug ????
3846       return geniCodeCast (operandType (left),
3847                            geniCodeRValue (right, FALSE), FALSE);
3848 #endif
3849
3850     case '~':
3851     case RRC:
3852     case RLC:
3853     case SWAP:
3854       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3855
3856     case '!':
3857     case GETHBIT:
3858       {
3859         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3860         setOperandType (op, UCHARTYPE);
3861         return op;
3862       }
3863     case '>':
3864     case '<':
3865     case LE_OP:
3866     case GE_OP:
3867     case EQ_OP:
3868     case NE_OP:
3869     case AND_OP:
3870     case OR_OP:
3871       /* different compilers (even different gccs) evaluate
3872          the two calls in a different order. to get the same
3873          result on all machines we've to specify a clear sequence.
3874       return geniCodeLogic (geniCodeRValue (left, FALSE),
3875                             geniCodeRValue (right, FALSE),
3876                             tree->opval.op);
3877       */
3878       {
3879         operand *leftOp, *rightOp;
3880
3881         rightOp = geniCodeRValue (right, FALSE);
3882         leftOp  = geniCodeRValue (left , FALSE);
3883
3884         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3885       }
3886     case '?':
3887       return geniCodeConditional (tree,lvl);
3888
3889     case SIZEOF:
3890       return operandFromLit (getSize (tree->right->ftype));
3891
3892     case '=':
3893       {
3894         sym_link *rtype = operandType (right);
3895         sym_link *ltype = operandType (left);
3896         if (IS_PTR (rtype) && IS_ITEMP (right)
3897             && right->isaddr && compareType (rtype->next, ltype) == 1)
3898           right = geniCodeRValue (right, TRUE);
3899         else
3900           right = geniCodeRValue (right, FALSE);
3901
3902         geniCodeAssign (left, right, 0);
3903         return right;
3904       }
3905     case MUL_ASSIGN:
3906       return
3907         geniCodeAssign (left,
3908                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3909                                                   FALSE),
3910                                   geniCodeRValue (right, FALSE),FALSE), 0);
3911
3912     case DIV_ASSIGN:
3913       return
3914         geniCodeAssign (left,
3915                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3916                                                   FALSE),
3917                                   geniCodeRValue (right, FALSE)), 0);
3918     case MOD_ASSIGN:
3919       return
3920         geniCodeAssign (left,
3921                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3922                                                   FALSE),
3923                                   geniCodeRValue (right, FALSE)), 0);
3924     case ADD_ASSIGN:
3925       {
3926         sym_link *rtype = operandType (right);
3927         sym_link *ltype = operandType (left);
3928         if (IS_PTR (rtype) && IS_ITEMP (right)
3929             && right->isaddr && compareType (rtype->next, ltype) == 1)
3930           right = geniCodeRValue (right, TRUE);
3931         else
3932           right = geniCodeRValue (right, FALSE);
3933
3934
3935         return geniCodeAssign (left,
3936                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3937                                                   FALSE),
3938                                   right,lvl), 0);
3939       }
3940     case SUB_ASSIGN:
3941       {
3942         sym_link *rtype = operandType (right);
3943         sym_link *ltype = operandType (left);
3944         if (IS_PTR (rtype) && IS_ITEMP (right)
3945             && right->isaddr && compareType (rtype->next, ltype) == 1)
3946           {
3947             right = geniCodeRValue (right, TRUE);
3948           }
3949         else
3950           {
3951             right = geniCodeRValue (right, FALSE);
3952           }
3953         return
3954           geniCodeAssign (left,
3955                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3956                                                   FALSE),
3957                                   right), 0);
3958       }
3959     case LEFT_ASSIGN:
3960       return
3961         geniCodeAssign (left,
3962                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3963                                                    ,FALSE),
3964                                    geniCodeRValue (right, FALSE)), 0);
3965     case RIGHT_ASSIGN:
3966       return
3967         geniCodeAssign (left,
3968                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3969                                                    ,FALSE),
3970                                    geniCodeRValue (right, FALSE)), 0);
3971     case AND_ASSIGN:
3972       return
3973         geniCodeAssign (left,
3974                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3975                                                   FALSE),
3976                                   geniCodeRValue (right, FALSE),
3977                                   BITWISEAND,
3978                                   operandType (left)), 0);
3979     case XOR_ASSIGN:
3980       return
3981         geniCodeAssign (left,
3982                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3983                                                   FALSE),
3984                                   geniCodeRValue (right, FALSE),
3985                                   '^',
3986                                   operandType (left)), 0);
3987     case OR_ASSIGN:
3988       return
3989         geniCodeAssign (left,
3990                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3991                                                    ,FALSE),
3992                                    geniCodeRValue (right, FALSE),
3993                                    '|',
3994                                    operandType (left)), 0);
3995     case ',':
3996       return geniCodeRValue (right, FALSE);
3997
3998     case CALL:
3999       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4000                            tree->right,lvl);
4001     case LABEL:
4002       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4003       return ast2iCode (tree->right,lvl+1);
4004
4005     case GOTO:
4006       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4007       return ast2iCode (tree->right,lvl+1);
4008
4009     case FUNCTION:
4010       geniCodeFunctionBody (tree,lvl);
4011       return NULL;
4012
4013     case RETURN:
4014       geniCodeReturn (right);
4015       return NULL;
4016
4017     case IFX:
4018       geniCodeIfx (tree,lvl);
4019       return NULL;
4020
4021     case SWITCH:
4022       geniCodeSwitch (tree,lvl);
4023       return NULL;
4024
4025     case INLINEASM:
4026       geniCodeInline (tree);
4027       return NULL;
4028         
4029     case ARRAYINIT:
4030         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4031         return NULL;
4032     
4033     case CRITICAL:
4034         geniCodeCritical (tree, lvl);
4035     }
4036
4037   return NULL;
4038 }
4039
4040 /*-----------------------------------------------------------------*/
4041 /* reverseICChain - gets from the list and creates a linkedlist    */
4042 /*-----------------------------------------------------------------*/
4043 iCode *
4044 reverseiCChain ()
4045 {
4046   iCode *loop = NULL;
4047   iCode *prev = NULL;
4048
4049   while ((loop = getSet (&iCodeChain)))
4050     {
4051       loop->next = prev;
4052       if (prev)
4053         prev->prev = loop;
4054       prev = loop;
4055     }
4056
4057   return prev;
4058 }
4059
4060
4061 /*-----------------------------------------------------------------*/
4062 /* iCodeFromAst - given an ast will convert it to iCode            */
4063 /*-----------------------------------------------------------------*/
4064 iCode *
4065 iCodeFromAst (ast * tree)
4066 {
4067   returnLabel = newiTempLabel ("_return");
4068   entryLabel = newiTempLabel ("_entry");
4069   ast2iCode (tree,0);
4070   return reverseiCChain ();
4071 }
4072
4073 static const char *opTypeToStr(OPTYPE op)
4074 {
4075     switch(op)
4076     {
4077       case SYMBOL: return "symbol";
4078       case VALUE: return "value";
4079       case TYPE: return "type";
4080     }
4081     return "undefined type";    
4082 }
4083
4084
4085 operand *validateOpType(operand         *op, 
4086                         const char      *macro,
4087                         const char      *args,
4088                         OPTYPE          type,
4089                         const char      *file, 
4090                         unsigned        line)
4091 {    
4092     if (op && op->type == type)
4093     {
4094         return op;
4095     }
4096     fprintf(stderr, 
4097             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4098             " expected %s, got %s\n",
4099             macro, args, file, line, 
4100             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4101     exit(-1);
4102     return op; // never reached, makes compiler happy.
4103 }