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