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