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