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