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