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