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