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