* src/SDCCast.c (decorateType),
[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   ast *astTrue  = tree->right->left;
3145   ast *astFalse = tree->right->right;
3146   operand *cond = ast2iCode (tree->left, lvl+1);
3147   operand *result = newiTempOperand (tree->right->ftype, 0);
3148   operand *opTrue, *opFalse;
3149
3150   ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel);
3151   ADDTOCHAIN (ic);
3152
3153   opTrue = ast2iCode (astTrue, lvl+1);
3154
3155   /* move the value to the new operand */
3156   geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0);
3157
3158   /* generate an unconditional goto */
3159   geniCodeGoto (exitLabel);
3160
3161   /* now for the right side */
3162   geniCodeLabel (falseLabel);
3163
3164   opFalse = ast2iCode (astFalse, lvl+1);
3165   geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0);
3166
3167   /* create the exit label */
3168   geniCodeLabel (exitLabel);
3169
3170   return result;
3171 }
3172
3173 /*-----------------------------------------------------------------*/
3174 /* geniCodeAssign - generate code for assignment                   */
3175 /*-----------------------------------------------------------------*/
3176 operand *
3177 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3178 {
3179   iCode *ic;
3180   sym_link *ltype = operandType (left);
3181   sym_link *rtype = operandType (right);
3182
3183   if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3184     {
3185       werror (E_LVALUE_REQUIRED, "assignment");
3186       return left;
3187     }
3188
3189   /* left is integral type and right is literal then
3190      check if the literal value is within bounds */
3191   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3192       checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3193       !options.lessPedantic)
3194     {
3195       werror (W_LIT_OVERFLOW);
3196     }
3197
3198   /* if the left & right type don't exactly match */
3199   /* if pointer set then make sure the check is
3200      done with the type & not the pointer */
3201   /* then cast rights type to left */
3202
3203   /* first check the type for pointer assignement */
3204   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3205       compareType (ltype, rtype) <= 0)
3206     {
3207       if (compareType (ltype->next, rtype) < 0)
3208         right = geniCodeCast (ltype->next, right, TRUE);
3209     }
3210   else if (compareType (ltype, rtype) < 0)
3211     right = geniCodeCast (ltype, right, TRUE);
3212
3213   /* If left is a true symbol & ! volatile
3214      create an assignment to temporary for
3215      the right & then assign this temporary
3216      to the symbol. This is SSA (static single
3217      assignment). Isn't it simple and folks have
3218      published mountains of paper on it */
3219   if (IS_TRUE_SYMOP (left) &&
3220       !isOperandVolatile (left, FALSE) &&
3221       isOperandGlobal (left))
3222     {
3223       symbol *sym = NULL;
3224       operand *newRight;
3225
3226       if (IS_TRUE_SYMOP (right))
3227         sym = OP_SYMBOL (right);
3228       ic = newiCode ('=', NULL, right);
3229       IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3230       /* avoid double fetch from volatile right, see bug 1369874 */
3231       if (!isOperandVolatile (right, FALSE))
3232         SPIL_LOC (newRight) = sym;
3233       right = newRight;
3234       ADDTOCHAIN (ic);
3235     }
3236
3237   ic = newiCode ('=', NULL, right);
3238   IC_RESULT (ic) = left;
3239   ADDTOCHAIN (ic);
3240
3241   /* if left isgptr flag is set then support
3242      routine will be required */
3243   if (left->isGptr)
3244     ic->supportRtn = 1;
3245
3246   ic->nosupdate = nosupdate;
3247   /* left could be a pointer assignment,
3248      return the properly casted right instead */
3249   return right;
3250 }
3251
3252 /*-----------------------------------------------------------------*/
3253 /* geniCodeDummyRead - generate code for dummy read                */
3254 /*-----------------------------------------------------------------*/
3255 static void
3256 geniCodeDummyRead (operand * op)
3257 {
3258   iCode *ic;
3259   sym_link *type = operandType (op);
3260
3261   if (!IS_VOLATILE(type))
3262     return;
3263
3264   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3265   ADDTOCHAIN (ic);
3266
3267   ic->nosupdate = 1;
3268 }
3269
3270 /*-----------------------------------------------------------------*/
3271 /* geniCodeSEParms - generate code for side effecting fcalls       */
3272 /*-----------------------------------------------------------------*/
3273 static void
3274 geniCodeSEParms (ast * parms,int lvl)
3275 {
3276   if (!parms)
3277     return;
3278
3279   if (parms->type == EX_OP && parms->opval.op == PARAM)
3280     {
3281       geniCodeSEParms (parms->left,lvl);
3282       geniCodeSEParms (parms->right,lvl);
3283       return;
3284     }
3285
3286   /* hack don't like this but too lazy to think of
3287      something better */
3288   if (IS_ADDRESS_OF_OP (parms))
3289     parms->left->lvalue = 1;
3290
3291   if (IS_CAST_OP (parms) &&
3292       IS_PTR (parms->ftype) &&
3293       IS_ADDRESS_OF_OP (parms->right))
3294     parms->right->left->lvalue = 1;
3295
3296   parms->opval.oprnd =
3297     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3298
3299   parms->type = EX_OPERAND;
3300   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3301                 SPEC_ARGREG(parms->ftype);
3302 }
3303
3304 /*-----------------------------------------------------------------*/
3305 /* geniCodeParms - generates parameters                            */
3306 /*-----------------------------------------------------------------*/
3307 value *
3308 geniCodeParms (ast * parms, value *argVals, int *stack,
3309                sym_link * ftype, int lvl)
3310 {
3311   iCode *ic;
3312   operand *pval;
3313
3314   if (!parms)
3315     return argVals;
3316
3317   if (argVals==NULL) {
3318     // first argument
3319     argVals = FUNC_ARGS (ftype);
3320   }
3321
3322   /* if this is a param node then do the left & right */
3323   if (parms->type == EX_OP && parms->opval.op == PARAM)
3324     {
3325       argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3326       argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3327       return argVals;
3328     }
3329
3330   /* get the parameter value */
3331   if (parms->type == EX_OPERAND)
3332     pval = parms->opval.oprnd;
3333   else
3334     {
3335       /* maybe this else should go away ?? */
3336       /* hack don't like this but too lazy to think of
3337          something better */
3338       if (IS_ADDRESS_OF_OP (parms))
3339         parms->left->lvalue = 1;
3340
3341       if (IS_CAST_OP (parms) &&
3342           IS_PTR (parms->ftype) &&
3343           IS_ADDRESS_OF_OP (parms->right))
3344         parms->right->left->lvalue = 1;
3345
3346       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3347     }
3348
3349   /* if register parm then make it a send */
3350   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3351       IFFUNC_ISBUILTIN(ftype))
3352     {
3353       ic = newiCode (SEND, pval, NULL);
3354       ic->argreg = SPEC_ARGREG(parms->etype);
3355       ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3356       ADDTOCHAIN (ic);
3357     }
3358   else
3359     {
3360       /* now decide whether to push or assign */
3361       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3362         {
3363
3364           /* assign */
3365           operand *top = operandFromSymbol (argVals->sym);
3366           /* clear useDef and other bitVectors */
3367           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3368           geniCodeAssign (top, pval, 1, 0);
3369         }
3370       else
3371         {
3372           sym_link *p = operandType (pval);
3373           /* push */
3374           ic = newiCode (IPUSH, pval, NULL);
3375           ic->parmPush = 1;
3376           /* update the stack adjustment */
3377           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3378           ADDTOCHAIN (ic);
3379         }
3380     }
3381
3382   argVals=argVals->next;
3383   return argVals;
3384 }
3385
3386 /*-----------------------------------------------------------------*/
3387 /* geniCodeCall - generates temp code for calling                  */
3388 /*-----------------------------------------------------------------*/
3389 operand *
3390 geniCodeCall (operand * left, ast * parms,int lvl)
3391 {
3392   iCode *ic;
3393   operand *result;
3394   sym_link *type, *etype;
3395   sym_link *ftype;
3396   int stack = 0;
3397
3398   if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3399       !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3400     werror (E_FUNCTION_EXPECTED);
3401     return operandFromValue(valueFromLit(0));
3402   }
3403
3404   /* take care of parameters with side-effecting
3405      function calls in them, this is required to take care
3406      of overlaying function parameters */
3407   geniCodeSEParms (parms,lvl);
3408
3409   ftype = operandType (left);
3410   if (IS_FUNCPTR (ftype))
3411     ftype = ftype->next;
3412
3413   /* first the parameters */
3414   geniCodeParms (parms, NULL, &stack, ftype, lvl);
3415
3416   /* now call : if symbol then pcall */
3417   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3418     ic = newiCode (PCALL, left, NULL);
3419   } else {
3420     ic = newiCode (CALL, left, NULL);
3421   }
3422
3423   type = copyLinkChain (ftype->next);
3424   etype = getSpec (type);
3425   SPEC_EXTR (etype) = 0;
3426   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3427
3428   ADDTOCHAIN (ic);
3429
3430   /* stack adjustment after call */
3431   ic->parmBytes = stack;
3432
3433   return result;
3434 }
3435
3436 /*-----------------------------------------------------------------*/
3437 /* geniCodeReceive - generate intermediate code for "receive"      */
3438 /*-----------------------------------------------------------------*/
3439 static void
3440 geniCodeReceive (value * args, operand * func)
3441 {
3442   unsigned char paramByteCounter = 0;
3443
3444   /* for all arguments that are passed in registers */
3445   while (args)
3446     {
3447       if (IS_REGPARM (args->etype))
3448         {
3449           operand *opr = operandFromValue (args);
3450           operand *opl;
3451           symbol *sym = OP_SYMBOL (opr);
3452           iCode *ic;
3453
3454           /* we will use it after all optimizations
3455              and before liveRange calculation */
3456           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3457             {
3458
3459               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3460                   options.stackAuto == 0 &&
3461                   (!(options.model == MODEL_FLAT24)) )
3462                 {
3463                 }
3464               else
3465                 {
3466                   opl = newiTempOperand (args->type, 0);
3467                   sym->reqv = opl;
3468                   sym->reqv->key = sym->key;
3469                   OP_SYMBOL (sym->reqv)->key = sym->key;
3470                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3471                   OP_SYMBOL (sym->reqv)->islocal = 0;
3472                   SPIL_LOC (sym->reqv) = sym;
3473                 }
3474             }
3475
3476           ic = newiCode (RECEIVE, func, NULL);
3477           ic->argreg = SPEC_ARGREG(args->etype);
3478           if (ic->argreg == 1) {
3479               currFunc->recvSize = getSize (sym->type);
3480           }
3481           IC_RESULT (ic) = opr;
3482
3483           /* misuse of parmBytes (normally used for functions)
3484            * to save estimated stack position of this argument.
3485            * Normally this should be zero for RECEIVE iCodes.
3486            * No idea if this causes side effects on other ports. - dw
3487            */
3488           ic->parmBytes = paramByteCounter;
3489
3490           /* what stack position do we have? */
3491           paramByteCounter += getSize (sym->type);
3492
3493           ADDTOCHAIN (ic);
3494         }
3495
3496       args = args->next;
3497     }
3498 }
3499
3500 /*-----------------------------------------------------------------*/
3501 /* geniCodeFunctionBody - create the function body                 */
3502 /*-----------------------------------------------------------------*/
3503 void
3504 geniCodeFunctionBody (ast * tree,int lvl)
3505 {
3506   iCode *ic;
3507   operand *func;
3508   sym_link *fetype;
3509   int savelineno;
3510
3511   /* reset the auto generation */
3512   /* numbers */
3513   iTempNum = 0;
3514   iTempLblNum = 0;
3515   operandKey = 0;
3516   iCodeKey = 0;
3517   func = ast2iCode (tree->left,lvl+1);
3518   fetype = getSpec (operandType (func));
3519
3520   savelineno = lineno;
3521   lineno = OP_SYMBOL (func)->lineDef;
3522   /* create an entry label */
3523   geniCodeLabel (entryLabel);
3524   lineno = savelineno;
3525
3526   /* create a proc icode */
3527   ic = newiCode (FUNCTION, func, NULL);
3528   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3529   ic->tree = tree;
3530
3531   ADDTOCHAIN (ic);
3532
3533   /* for all parameters that are passed
3534      on registers add a "receive" */
3535   geniCodeReceive (tree->values.args, func);
3536
3537   /* generate code for the body */
3538   ast2iCode (tree->right,lvl+1);
3539
3540   /* create a label for return */
3541   geniCodeLabel (returnLabel);
3542
3543   /* now generate the end proc */
3544   ic = newiCode (ENDFUNCTION, func, NULL);
3545   ic->tree = tree;
3546   ADDTOCHAIN (ic);
3547   return;
3548 }
3549
3550 /*-----------------------------------------------------------------*/
3551 /* geniCodeReturn - gen icode for 'return' statement               */
3552 /*-----------------------------------------------------------------*/
3553 void
3554 geniCodeReturn (operand * op)
3555 {
3556   iCode *ic;
3557
3558   /* if the operand is present force an rvalue */
3559   if (op)
3560     op = geniCodeRValue (op, FALSE);
3561
3562   ic = newiCode (RETURN, op, NULL);
3563   ADDTOCHAIN (ic);
3564 }
3565
3566 /*-----------------------------------------------------------------*/
3567 /* geniCodeIfx - generates code for extended if statement          */
3568 /*-----------------------------------------------------------------*/
3569 void
3570 geniCodeIfx (ast * tree,int lvl)
3571 {
3572   iCode *ic;
3573   operand *condition = ast2iCode (tree->left,lvl+1);
3574   sym_link *cetype;
3575
3576   /* if condition is null then exit */
3577   if (!condition)
3578     goto exit;
3579   else
3580     condition = geniCodeRValue (condition, FALSE);
3581
3582   cetype = getSpec (operandType (condition));
3583   /* if the condition is a literal */
3584   if (IS_LITERAL (cetype))
3585     {
3586       if (floatFromVal (condition->operand.valOperand))
3587         {
3588           if (tree->trueLabel)
3589             geniCodeGoto (tree->trueLabel);
3590           else
3591             assert (0);
3592         }
3593       else
3594         {
3595           if (tree->falseLabel)
3596             geniCodeGoto (tree->falseLabel);
3597         }
3598       goto exit;
3599     }
3600
3601   if (tree->trueLabel)
3602     {
3603       ic = newiCodeCondition (condition,
3604                               tree->trueLabel,
3605                               NULL);
3606       ADDTOCHAIN (ic);
3607
3608       if (tree->falseLabel)
3609         geniCodeGoto (tree->falseLabel);
3610     }
3611   else
3612     {
3613       ic = newiCodeCondition (condition,
3614                               NULL,
3615                               tree->falseLabel);
3616       ADDTOCHAIN (ic);
3617     }
3618
3619 exit:
3620   ast2iCode (tree->right,lvl+1);
3621 }
3622
3623 /*-----------------------------------------------------------------*/
3624 /* geniCodeJumpTable - tries to create a jump table for switch     */
3625 /*-----------------------------------------------------------------*/
3626 int
3627 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3628 {
3629   int min, max, cnt = 1;
3630   int i, t;
3631   value *vch;
3632   iCode *ic;
3633   operand *boundary;
3634   symbol *falseLabel;
3635   set *labels = NULL;
3636   int needRangeCheck = !optimize.noJTabBoundary
3637                        || tree->values.switchVals.swDefault;
3638   sym_link *cetype = getSpec (operandType (cond));
3639   int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3640   int sizeofMatchJump, sizeofJumpTable;
3641   int sizeIndex;
3642
3643   if (!tree || !caseVals)
3644     return 0;
3645
3646   /* the criteria for creating a jump table is */
3647   /* all integer numbers between the maximum & minimum must */
3648   /* be present , the maximum value should not exceed 255 */
3649   /* If not all integer numbers are present the algorithm */
3650   /* inserts jumps to the default label for the missing numbers */
3651   /* and decides later whether it is worth it */
3652   min = (int) floatFromVal (vch = caseVals);
3653
3654   while (vch->next)
3655     {
3656       cnt++;
3657       vch = vch->next;
3658     }
3659   max = (int) floatFromVal (vch);
3660
3661   /* Exit if the range is too large to handle with a jump table. */
3662   if (1 + max - min > port->jumptableCost.maxCount)
3663     return 0;
3664
3665   switch (getSize (operandType (cond)))
3666     {
3667     case 1: sizeIndex = 0; break;
3668     case 2: sizeIndex = 1; break;
3669     case 4: sizeIndex = 2; break;
3670     default: return 0;
3671     }
3672
3673   /* Compute the size cost of the range check and subtraction. */
3674   sizeofMinCost = 0;
3675   sizeofZeroMinCost = 0;
3676   sizeofMaxCost = 0;
3677   if (needRangeCheck)
3678     {
3679       if (!(min==0 && IS_UNSIGNED (cetype)))
3680         sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3681       if (!IS_UNSIGNED (cetype))
3682         sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3683       sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3684     }
3685   if (min)
3686     sizeofMinCost += port->jumptableCost.sizeofSubtract;
3687
3688   /* If the size cost of handling a non-zero minimum exceeds the */
3689   /* cost of extending the range down to zero, then it might be */
3690   /* better to extend the range to zero. */
3691   if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3692                  >= (min * port->jumptableCost.sizeofElement))
3693     {
3694       /* Only extend the jump table if it would still be manageable. */
3695       if (1 + max <= port->jumptableCost.maxCount)
3696         {
3697           min = 0;
3698           if (IS_UNSIGNED (cetype))
3699             sizeofMinCost = 0;
3700           else
3701             sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3702         }
3703     }
3704
3705   /* Compute the total size cost of a jump table. */
3706   sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3707                      + port->jumptableCost.sizeofDispatch
3708                      + sizeofMinCost + sizeofMaxCost;
3709
3710   /* Compute the total size cost of a match & jump sequence */
3711   sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3712
3713   /* If the size cost of the jump table is uneconomical then exit */
3714   if (sizeofMatchJump <  sizeofJumpTable)
3715     return 0;
3716
3717   /* The jump table is preferable. */
3718
3719   /* First, a label for the default or missing cases. */
3720   if (tree->values.switchVals.swDefault)
3721     {
3722       SNPRINTF (buffer, sizeof(buffer),
3723                 "_default_%d",
3724                 tree->values.switchVals.swNum);
3725     }
3726   else
3727     {
3728       SNPRINTF (buffer, sizeof(buffer),
3729                 "_swBrk_%d",
3730                 tree->values.switchVals.swNum);
3731     }
3732   falseLabel = newiTempLabel (buffer);
3733
3734   /* Build the list of labels for the jump table. */
3735   vch = caseVals;
3736   t = (int) floatFromVal (vch);
3737   for (i=min; i<=max; i++)
3738     {
3739       if (vch && t==i)
3740         {
3741           /* Explicit case: make a new label for it. */
3742           SNPRINTF (buffer, sizeof(buffer),
3743                     "_case_%d_%d",
3744                     tree->values.switchVals.swNum,
3745                     i);
3746           addSet (&labels, newiTempLabel (buffer));
3747           vch = vch->next;
3748           if (vch)
3749             t = (int) floatFromVal (vch);
3750         }
3751       else
3752         {
3753           /* Implicit case: use the default label. */
3754           addSet (&labels, falseLabel);
3755         }
3756     }
3757
3758   /* first we rule out the boundary conditions */
3759   /* if only optimization says so */
3760   if (needRangeCheck)
3761     {
3762       sym_link *cetype = getSpec (operandType (cond));
3763       /* no need to check the lower bound if
3764          the condition is unsigned & minimum value is zero */
3765       if (!(min == 0 && IS_UNSIGNED (cetype)))
3766         {
3767           boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
3768           ic = newiCodeCondition (boundary, falseLabel, NULL);
3769           ADDTOCHAIN (ic);
3770         }
3771
3772       /* now for upper bounds */
3773       boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
3774       ic = newiCodeCondition (boundary, falseLabel, NULL);
3775       ADDTOCHAIN (ic);
3776     }
3777
3778   /* if the min is not zero then we no make it zero */
3779   if (min)
3780     {
3781       cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3782       if (!IS_LITERAL(getSpec(operandType(cond))))
3783         setOperandType (cond, UCHARTYPE);
3784     }
3785
3786   /* now create the jumptable */
3787   ic = newiCode (JUMPTABLE, NULL, NULL);
3788   IC_JTCOND (ic) = cond;
3789   IC_JTLABELS (ic) = labels;
3790   ADDTOCHAIN (ic);
3791   return 1;
3792 }
3793
3794 /*-----------------------------------------------------------------*/
3795 /* geniCodeSwitch - changes a switch to a if statement             */
3796 /*-----------------------------------------------------------------*/
3797 void
3798 geniCodeSwitch (ast * tree,int lvl)
3799 {
3800   iCode *ic;
3801   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3802   value *caseVals = tree->values.switchVals.swVals;
3803   symbol *trueLabel, *falseLabel;
3804
3805   /* If the condition is a literal, then just jump to the */
3806   /* appropriate case label. */
3807   if (IS_LITERAL(getSpec(operandType(cond))))
3808     {
3809       int switchVal, caseVal;
3810
3811       switchVal = (int) floatFromVal (cond->operand.valOperand);
3812       while (caseVals)
3813         {
3814           caseVal = (int) floatFromVal (caseVals);
3815           if (caseVal == switchVal)
3816             {
3817               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3818                         tree->values.switchVals.swNum, caseVal);
3819               trueLabel = newiTempLabel (buffer);
3820               geniCodeGoto (trueLabel);
3821               goto jumpTable;
3822             }
3823           caseVals = caseVals->next;
3824         }
3825       goto defaultOrBreak;
3826     }
3827
3828   /* If cond is volatile, it might change while we are trying to */
3829   /* find the matching case. To avoid this possibility, make a   */
3830   /* non-volatile copy to use instead. */
3831   if (IS_OP_VOLATILE (cond))
3832     {
3833       operand * newcond;
3834       iCode * ic;
3835
3836       newcond = newiTempOperand (operandType (cond), TRUE);
3837       newcond->isvolatile = 0;
3838       ic = newiCode ('=', NULL, cond);
3839       IC_RESULT (ic) = newcond;
3840       ADDTOCHAIN (ic);
3841       cond = newcond;
3842     }
3843
3844   /* if we can make this a jump table */
3845   if (geniCodeJumpTable (cond, caseVals, tree))
3846     goto jumpTable;             /* no need for the comparison */
3847
3848   /* for the cases defined do */
3849   while (caseVals)
3850     {
3851
3852       operand *compare = geniCodeLogic (cond,
3853                                         operandFromValue (caseVals),
3854                                         EQ_OP, NULL);
3855
3856       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3857                tree->values.switchVals.swNum,
3858                (int) floatFromVal (caseVals));
3859       trueLabel = newiTempLabel (buffer);
3860
3861       ic = newiCodeCondition (compare, trueLabel, NULL);
3862       ADDTOCHAIN (ic);
3863       caseVals = caseVals->next;
3864     }
3865
3866
3867 defaultOrBreak:
3868   /* if default is present then goto break else break */
3869   if (tree->values.switchVals.swDefault)
3870     {
3871         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3872     }
3873   else
3874     {
3875         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3876     }
3877
3878   falseLabel = newiTempLabel (buffer);
3879   geniCodeGoto (falseLabel);
3880
3881 jumpTable:
3882   ast2iCode (tree->right,lvl+1);
3883 }
3884
3885 /*-----------------------------------------------------------------*/
3886 /* geniCodeInline - intermediate code for inline assembler         */
3887 /*-----------------------------------------------------------------*/
3888 static void
3889 geniCodeInline (ast * tree)
3890 {
3891   iCode *ic;
3892
3893   ic = newiCode (INLINEASM, NULL, NULL);
3894   IC_INLINE (ic) = tree->values.inlineasm;
3895   ADDTOCHAIN (ic);
3896 }
3897
3898 /*-----------------------------------------------------------------*/
3899 /* geniCodeArrayInit - intermediate code for array initializer     */
3900 /*-----------------------------------------------------------------*/
3901 static void
3902 geniCodeArrayInit (ast * tree, operand *array)
3903 {
3904   iCode *ic;
3905
3906   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3907     ic = newiCode (ARRAYINIT, array, NULL);
3908     IC_ARRAYILIST (ic) = tree->values.constlist;
3909   } else {
3910     operand *left=newOperand(), *right=newOperand();
3911     left->type=right->type=SYMBOL;
3912     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3913     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3914     ic = newiCode (ARRAYINIT, left, right);
3915   }
3916   ADDTOCHAIN (ic);
3917 }
3918
3919 /*-----------------------------------------------------------------*/
3920 /* geniCodeCritical - intermediate code for a critical statement   */
3921 /*-----------------------------------------------------------------*/
3922 static void
3923 geniCodeCritical (ast *tree, int lvl)
3924 {
3925   iCode *ic;
3926   operand *op = NULL;
3927   sym_link *type;
3928
3929   if (!options.stackAuto)
3930     {
3931       type = newLink(SPECIFIER);
3932       SPEC_VOLATILE(type) = 1;
3933       SPEC_NOUN(type) = V_BIT;
3934       SPEC_SCLS(type) = S_BIT;
3935       SPEC_BLEN(type) = 1;
3936       SPEC_BSTR(type) = 0;
3937       op = newiTempOperand(type, 1);
3938     }
3939
3940   /* If op is NULL, the original interrupt state will saved on */
3941   /* the stack. Otherwise, it will be saved in op. */
3942
3943   /* Generate a save of the current interrupt state & disable */
3944   ic = newiCode (CRITICAL, NULL, NULL);
3945   IC_RESULT (ic) = op;
3946   ADDTOCHAIN (ic);
3947
3948   /* Generate the critical code sequence */
3949   if (tree->left && tree->left->type == EX_VALUE)
3950     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3951   else
3952     ast2iCode (tree->left,lvl+1);
3953
3954   /* Generate a restore of the original interrupt state */
3955   ic = newiCode (ENDCRITICAL, NULL, op);
3956   ADDTOCHAIN (ic);
3957 }
3958
3959 /*-----------------------------------------------------------------*/
3960 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3961 /* particular case. Ie : assigning or dereferencing array or ptr   */
3962 /*-----------------------------------------------------------------*/
3963 set * lvaluereqSet = NULL;
3964 typedef struct lvalItem
3965   {
3966     int req;
3967     int lvl;
3968   }
3969 lvalItem;
3970
3971 /*-----------------------------------------------------------------*/
3972 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3973 /*-----------------------------------------------------------------*/
3974 void addLvaluereq(int lvl)
3975 {
3976   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3977   lpItem->req=1;
3978   lpItem->lvl=lvl;
3979   addSetHead(&lvaluereqSet,lpItem);
3980
3981 }
3982 /*-----------------------------------------------------------------*/
3983 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3984 /*-----------------------------------------------------------------*/
3985 void delLvaluereq()
3986 {
3987   lvalItem * lpItem;
3988   lpItem = getSet(&lvaluereqSet);
3989   if(lpItem) Safe_free(lpItem);
3990 }
3991 /*-----------------------------------------------------------------*/
3992 /* clearLvaluereq - clear lvalreq flag                             */
3993 /*-----------------------------------------------------------------*/
3994 void clearLvaluereq()
3995 {
3996   lvalItem * lpItem;
3997   lpItem = peekSet(lvaluereqSet);
3998   if(lpItem) lpItem->req = 0;
3999 }
4000 /*-----------------------------------------------------------------*/
4001 /* getLvaluereq - get the last lvalreq level                       */
4002 /*-----------------------------------------------------------------*/
4003 int getLvaluereqLvl()
4004 {
4005   lvalItem * lpItem;
4006   lpItem = peekSet(lvaluereqSet);
4007   if(lpItem) return lpItem->lvl;
4008   return 0;
4009 }
4010 /*-----------------------------------------------------------------*/
4011 /* isLvaluereq - is lvalreq valid for this level ?                 */
4012 /*-----------------------------------------------------------------*/
4013 int isLvaluereq(int lvl)
4014 {
4015   lvalItem * lpItem;
4016   lpItem = peekSet(lvaluereqSet);
4017   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4018   return 0;
4019 }
4020
4021 /*-----------------------------------------------------------------*/
4022 /* ast2iCode - creates an icodeList from an ast                    */
4023 /*-----------------------------------------------------------------*/
4024 operand *
4025 ast2iCode (ast * tree,int lvl)
4026 {
4027   operand *left = NULL;
4028   operand *right = NULL;
4029   if (!tree)
4030     return NULL;
4031
4032   /* set the global variables for filename & line number */
4033   if (tree->filename)
4034     filename = tree->filename;
4035   if (tree->lineno)
4036     lineno = tree->lineno;
4037   if (tree->block)
4038     block = tree->block;
4039   if (tree->level)
4040     scopeLevel = tree->level;
4041   if (tree->seqPoint)
4042     seqPoint = tree->seqPoint;
4043
4044   if (tree->type == EX_VALUE)
4045     return operandFromValue (tree->opval.val);
4046
4047   if (tree->type == EX_LINK)
4048     return operandFromLink (tree->opval.lnk);
4049
4050   /* if we find a nullop */
4051   if (tree->type == EX_OP &&
4052      (tree->opval.op == NULLOP ||
4053      tree->opval.op == BLOCK))
4054     {
4055       if (tree->left && tree->left->type == EX_VALUE)
4056         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4057       else
4058         ast2iCode (tree->left,lvl+1);
4059       if (tree->right && tree->right->type == EX_VALUE)
4060         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4061       else
4062         ast2iCode (tree->right,lvl+1);
4063       return NULL;
4064     }
4065
4066   /* special cases for not evaluating */
4067   if (tree->opval.op != ':' &&
4068       tree->opval.op != '?' &&
4069       tree->opval.op != CALL &&
4070       tree->opval.op != IFX &&
4071       tree->opval.op != AND_OP &&
4072       tree->opval.op != OR_OP &&
4073       tree->opval.op != LABEL &&
4074       tree->opval.op != GOTO &&
4075       tree->opval.op != SWITCH &&
4076       tree->opval.op != FUNCTION &&
4077       tree->opval.op != INLINEASM &&
4078       tree->opval.op != CRITICAL)
4079     {
4080
4081         if (IS_ASSIGN_OP (tree->opval.op) ||
4082            IS_DEREF_OP (tree) ||
4083            (tree->opval.op == '&' && !tree->right) ||
4084            tree->opval.op == PTR_OP)
4085           {
4086             addLvaluereq(lvl);
4087             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4088                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4089               clearLvaluereq();
4090
4091             left = operandFromAst (tree->left,lvl);
4092             delLvaluereq();
4093             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4094               left = geniCodeRValue (left, TRUE);
4095           }
4096         else
4097           {
4098             left = operandFromAst (tree->left,lvl);
4099           }
4100         if (tree->opval.op == INC_OP ||
4101             tree->opval.op == DEC_OP)
4102           {
4103             addLvaluereq(lvl);
4104             right = operandFromAst (tree->right,lvl);
4105             delLvaluereq();
4106           }
4107         else
4108           {
4109             right = operandFromAst (tree->right,lvl);
4110           }
4111       }
4112
4113   /* now depending on the type of operand */
4114   /* this will be a biggy                 */
4115   switch (tree->opval.op)
4116     {
4117
4118     case '[':                   /* array operation */
4119       {
4120         //sym_link *ltype = operandType (left);
4121         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4122         left = geniCodeRValue (left, FALSE);
4123         right = geniCodeRValue (right, TRUE);
4124       }
4125
4126       return geniCodeArray (left, right,lvl);
4127
4128     case '.':                   /* structure dereference */
4129       if (IS_PTR (operandType (left)))
4130         left = geniCodeRValue (left, TRUE);
4131       else
4132         left = geniCodeRValue (left, FALSE);
4133
4134       return geniCodeStruct (left, right, tree->lvalue);
4135
4136     case PTR_OP:                /* structure pointer dereference */
4137       {
4138         sym_link *pType;
4139         pType = operandType (left);
4140         left = geniCodeRValue (left, TRUE);
4141
4142         setOClass (pType, getSpec (operandType (left)));
4143       }
4144
4145       return geniCodeStruct (left, right, tree->lvalue);
4146
4147     case INC_OP:                /* increment operator */
4148       if (left)
4149         return geniCodePostInc (left);
4150       else
4151         return geniCodePreInc (right, tree->lvalue);
4152
4153     case DEC_OP:                /* decrement operator */
4154       if (left)
4155         return geniCodePostDec (left);
4156       else
4157         return geniCodePreDec (right, tree->lvalue);
4158
4159     case '&':                   /* bitwise and or address of operator */
4160       if (right)
4161         {                       /* this is a bitwise operator   */
4162           left = geniCodeRValue (left, FALSE);
4163           right = geniCodeRValue (right, FALSE);
4164           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4165         }
4166       else
4167         return geniCodeAddressOf (left);
4168
4169     case '|':                   /* bitwise or & xor */
4170     case '^':
4171       return geniCodeBitwise (geniCodeRValue (left, FALSE),
4172                               geniCodeRValue (right, FALSE),
4173                               tree->opval.op,
4174                               tree->ftype);
4175
4176     case '/':
4177       return geniCodeDivision (geniCodeRValue (left, FALSE),
4178                                geniCodeRValue (right, FALSE),
4179                                getResultTypeFromType (tree->ftype));
4180
4181     case '%':
4182       return geniCodeModulus (geniCodeRValue (left, FALSE),
4183                               geniCodeRValue (right, FALSE),
4184                               getResultTypeFromType (tree->ftype));
4185     case '*':
4186       if (right)
4187         return geniCodeMultiply (geniCodeRValue (left, FALSE),
4188                                  geniCodeRValue (right, FALSE),
4189                                  getResultTypeFromType (tree->ftype));
4190       else
4191         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4192
4193     case '-':
4194       if (right)
4195         return geniCodeSubtract (geniCodeRValue (left, FALSE),
4196                                  geniCodeRValue (right, FALSE),
4197                                  getResultTypeFromType (tree->ftype));
4198       else
4199         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4200
4201     case '+':
4202       if (right)
4203         return geniCodeAdd (geniCodeRValue (left, FALSE),
4204                             geniCodeRValue (right, FALSE),
4205                             getResultTypeFromType (tree->ftype),
4206                             lvl);
4207       else
4208         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
4209
4210     case LEFT_OP:
4211       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4212                                 geniCodeRValue (right, FALSE),
4213                                 getResultTypeFromType (tree->ftype));
4214
4215     case RIGHT_OP:
4216       return geniCodeRightShift (geniCodeRValue (left, FALSE),
4217                                  geniCodeRValue (right, FALSE));
4218     case CAST:
4219 #if 0 // this indeed needs a second thought
4220       {
4221         operand *op;
4222
4223         // let's keep this simple: get the rvalue we need
4224         op=geniCodeRValue (right, FALSE);
4225         // now cast it to whatever we want
4226         op=geniCodeCast (operandType(left), op, FALSE);
4227         // if this is going to be used as an lvalue, make it so
4228         if (tree->lvalue) {
4229           op->isaddr=1;
4230         }
4231         return op;
4232       }
4233 #else // bug #604575, is it a bug ????
4234       return geniCodeCast (operandType (left),
4235                            geniCodeRValue (right, FALSE), FALSE);
4236 #endif
4237
4238     case '~':
4239     case RRC:
4240     case RLC:
4241     case SWAP:
4242       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4243
4244     case '!':
4245     case GETHBIT:
4246       {
4247         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4248         if (!IS_BIT (operandType (op)))
4249           setOperandType (op, UCHARTYPE);
4250         return op;
4251       }
4252     case GETABIT:
4253       {
4254         operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4255                                       geniCodeRValue (right, FALSE),
4256                                       tree->opval.op);
4257         if (!IS_BIT (operandType (op)))
4258           setOperandType (op, UCHARTYPE);
4259         return op;
4260       }
4261     case GETBYTE:
4262       {
4263         operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4264                                       geniCodeRValue (right, FALSE),
4265                                       tree->opval.op);
4266         setOperandType (op, UCHARTYPE);
4267         return op;
4268       }
4269     case GETWORD:
4270       {
4271         operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4272                                       geniCodeRValue (right, FALSE),
4273                                       tree->opval.op);
4274         setOperandType (op, UINTTYPE);
4275         return op;
4276       }
4277     case AND_OP:
4278     case OR_OP:
4279       return geniCodeLogicAndOr (tree, lvl);
4280     case '>':
4281     case '<':
4282     case LE_OP:
4283     case GE_OP:
4284     case EQ_OP:
4285     case NE_OP:
4286       /* different compilers (even different gccs) evaluate
4287          the two calls in a different order. to get the same
4288          result on all machines we have to specify a clear sequence.
4289       return geniCodeLogic (geniCodeRValue (left, FALSE),
4290                             geniCodeRValue (right, FALSE),
4291                             tree->opval.op);
4292       */
4293       {
4294         operand *leftOp, *rightOp;
4295
4296         leftOp  = geniCodeRValue (left , FALSE);
4297         rightOp = geniCodeRValue (right, FALSE);
4298
4299         return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
4300       }
4301     case '?':
4302       return geniCodeConditional (tree,lvl);
4303
4304     case SIZEOF:
4305       return operandFromLit (getSize (tree->right->ftype));
4306
4307     case '=':
4308       {
4309         sym_link *rtype = operandType (right);
4310         sym_link *ltype = operandType (left);
4311         if (IS_PTR (rtype) && IS_ITEMP (right)
4312             && right->isaddr && compareType (rtype->next, ltype) == 1)
4313           right = geniCodeRValue (right, TRUE);
4314         else
4315           right = geniCodeRValue (right, FALSE);
4316
4317         return geniCodeAssign (left, right, 0, 1);
4318       }
4319     case MUL_ASSIGN:
4320       return
4321         geniCodeAssign (left,
4322                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4323                                                   FALSE),
4324                                   geniCodeRValue (right, FALSE),
4325                                   getResultTypeFromType (tree->ftype)),
4326                         0, 1);
4327
4328     case DIV_ASSIGN:
4329       return
4330         geniCodeAssign (left,
4331                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4332                                                   FALSE),
4333                                   geniCodeRValue (right, FALSE),
4334                                   getResultTypeFromType (tree->ftype)),
4335                         0, 1);
4336     case MOD_ASSIGN:
4337       return
4338         geniCodeAssign (left,
4339                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4340                                                   FALSE),
4341                                   geniCodeRValue (right, FALSE),
4342                                   getResultTypeFromType (tree->ftype)),
4343                         0, 1);
4344     case ADD_ASSIGN:
4345       {
4346         sym_link *rtype = operandType (right);
4347         sym_link *ltype = operandType (left);
4348         if (IS_PTR (rtype) && IS_ITEMP (right)
4349             && right->isaddr && compareType (rtype->next, ltype) == 1)
4350           right = geniCodeRValue (right, TRUE);
4351         else
4352           right = geniCodeRValue (right, FALSE);
4353
4354
4355         return geniCodeAssign (left,
4356                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4357                                                   FALSE),
4358                                   right,
4359                                   getResultTypeFromType (tree->ftype),
4360                                   lvl),
4361                                0, 1);
4362       }
4363     case SUB_ASSIGN:
4364       {
4365         sym_link *rtype = operandType (right);
4366         sym_link *ltype = operandType (left);
4367         if (IS_PTR (rtype) && IS_ITEMP (right)
4368             && right->isaddr && compareType (rtype->next, ltype) == 1)
4369           {
4370             right = geniCodeRValue (right, TRUE);
4371           }
4372         else
4373           {
4374             right = geniCodeRValue (right, FALSE);
4375           }
4376         return
4377           geniCodeAssign (left,
4378                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4379                                                   FALSE),
4380                                   right,
4381                                   getResultTypeFromType (tree->ftype)),
4382                           0, 1);
4383       }
4384     case LEFT_ASSIGN:
4385       return
4386         geniCodeAssign (left,
4387                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4388                                                    ,FALSE),
4389                                    geniCodeRValue (right, FALSE),
4390                                    getResultTypeFromType (tree->ftype)),
4391                         0, 1);
4392     case RIGHT_ASSIGN:
4393       return
4394         geniCodeAssign (left,
4395                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4396                                                    ,FALSE),
4397                                    geniCodeRValue (right, FALSE)), 0, 1);
4398     case AND_ASSIGN:
4399       return
4400         geniCodeAssign (left,
4401                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4402                                                   FALSE),
4403                                   geniCodeRValue (right, FALSE),
4404                                   BITWISEAND,
4405                                   operandType (left)), 0, 1);
4406     case XOR_ASSIGN:
4407       return
4408         geniCodeAssign (left,
4409                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4410                                                   FALSE),
4411                                   geniCodeRValue (right, FALSE),
4412                                   '^',
4413                                   operandType (left)), 0, 1);
4414     case OR_ASSIGN:
4415       return
4416         geniCodeAssign (left,
4417                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4418                                                    ,FALSE),
4419                                    geniCodeRValue (right, FALSE),
4420                                    '|',
4421                                    operandType (left)), 0, 1);
4422     case ',':
4423       return geniCodeRValue (right, FALSE);
4424
4425     case CALL:
4426       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4427                            tree->right,lvl);
4428     case LABEL:
4429       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4430       return ast2iCode (tree->right,lvl+1);
4431
4432     case GOTO:
4433       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4434       return ast2iCode (tree->right,lvl+1);
4435
4436     case FUNCTION:
4437       geniCodeFunctionBody (tree,lvl);
4438       return NULL;
4439
4440     case RETURN:
4441       geniCodeReturn (right);
4442       return NULL;
4443
4444     case IFX:
4445       geniCodeIfx (tree,lvl);
4446       return NULL;
4447
4448     case SWITCH:
4449       geniCodeSwitch (tree,lvl);
4450       return NULL;
4451
4452     case INLINEASM:
4453       geniCodeInline (tree);
4454       return NULL;
4455
4456     case ARRAYINIT:
4457         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4458         return NULL;
4459
4460     case CRITICAL:
4461         geniCodeCritical (tree, lvl);
4462     }
4463
4464   return NULL;
4465 }
4466
4467 /*-----------------------------------------------------------------*/
4468 /* reverseICChain - gets from the list and creates a linkedlist    */
4469 /*-----------------------------------------------------------------*/
4470 iCode *
4471 reverseiCChain ()
4472 {
4473   iCode *loop = NULL;
4474   iCode *prev = NULL;
4475
4476   while ((loop = getSet (&iCodeChain)))
4477     {
4478       loop->next = prev;
4479       if (prev)
4480         prev->prev = loop;
4481       prev = loop;
4482     }
4483
4484   return prev;
4485 }
4486
4487
4488 /*-----------------------------------------------------------------*/
4489 /* iCodeFromAst - given an ast will convert it to iCode            */
4490 /*-----------------------------------------------------------------*/
4491 iCode *
4492 iCodeFromAst (ast * tree)
4493 {
4494   returnLabel = newiTempLabel ("_return");
4495   entryLabel = newiTempLabel ("_entry");
4496   ast2iCode (tree,0);
4497   return reverseiCChain ();
4498 }
4499
4500 static const char *opTypeToStr(OPTYPE op)
4501 {
4502     switch(op)
4503     {
4504       case SYMBOL: return "symbol";
4505       case VALUE: return "value";
4506       case TYPE: return "type";
4507     }
4508     return "undefined type";
4509 }
4510
4511
4512 operand *validateOpType(operand         *op,
4513                         const char      *macro,
4514                         const char      *args,
4515                         OPTYPE          type,
4516                         const char      *file,
4517                         unsigned        line)
4518 {
4519     if (op && op->type == type)
4520     {
4521         return op;
4522     }
4523     fprintf(stderr,
4524             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4525             " expected %s, got %s\n",
4526             macro, args, file, line,
4527             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4528     exit(EXIT_FAILURE);
4529     return op; // never reached, makes compiler happy.
4530 }