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