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