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