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