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