* src/mcs51/gen.c (getTempRegs): return 0 if not enough registers found,
[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       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) ||
1331           IS_FLOAT (ret))
1332         {
1333           retval = operandFromLit (operandLitValue (left) ==
1334                                    operandLitValue (right));
1335         }
1336       else
1337       if (IS_FIXED16X16 (let) ||
1338           IS_FIXED16X16 (ret))
1339         {
1340           retval = operandFromLit (operandLitValue (left) ==
1341                                    operandLitValue (right));
1342         }
1343       else
1344         {
1345           /* this op doesn't care about signedness */
1346           TYPE_UDWORD l, r;
1347
1348           l = (TYPE_UDWORD) operandLitValue (left);
1349           r = (TYPE_UDWORD) operandLitValue (right);
1350           /* In order to correctly compare 'signed int' and 'unsigned int' it's
1351              neccessary to strip them to 16 bit.
1352              Literals are reduced to their cheapest type, therefore left and
1353              right might have different types. It's neccessary to find a
1354              common type: int (used for char too) or long */
1355           if (!IS_LONG (let) &&
1356               !IS_LONG (ret))
1357             {
1358               r = (TYPE_UWORD) r;
1359               l = (TYPE_UWORD) l;
1360             }
1361           retval = operandFromLit (l == r);
1362         }
1363       break;
1364     case '<':
1365       retval = operandFromLit (operandLitValue (left) <
1366                                operandLitValue (right));
1367       break;
1368     case LE_OP:
1369       retval = operandFromLit (operandLitValue (left) <=
1370                                operandLitValue (right));
1371       break;
1372     case NE_OP:
1373       retval = operandFromLit (operandLitValue (left) !=
1374                                operandLitValue (right));
1375       break;
1376     case '>':
1377       retval = operandFromLit (operandLitValue (left) >
1378                                operandLitValue (right));
1379       break;
1380     case GE_OP:
1381       retval = operandFromLit (operandLitValue (left) >=
1382                                operandLitValue (right));
1383       break;
1384     case BITWISEAND:
1385       retval = operandFromValue (valCastLiteral (type,
1386                                                  (TYPE_UDWORD)operandLitValue(left) &
1387                                                  (TYPE_UDWORD)operandLitValue(right)));
1388       break;
1389     case '|':
1390       retval = operandFromValue (valCastLiteral (type,
1391                                                  (TYPE_UDWORD)operandLitValue(left) |
1392                                                  (TYPE_UDWORD)operandLitValue(right)));
1393       break;
1394     case '^':
1395       retval = operandFromValue (valCastLiteral (type,
1396                                                  (TYPE_UDWORD)operandLitValue(left) ^
1397                                                  (TYPE_UDWORD)operandLitValue(right)));
1398       break;
1399     case AND_OP:
1400       retval = operandFromLit (operandLitValue (left) &&
1401                                operandLitValue (right));
1402       break;
1403     case OR_OP:
1404       retval = operandFromLit (operandLitValue (left) ||
1405                                operandLitValue (right));
1406       break;
1407     case RRC:
1408       {
1409         TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1410
1411         retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1412                                  (i << 1));
1413       }
1414       break;
1415     case RLC:
1416       {
1417         TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1418
1419         retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1420                                  (i >> 1));
1421       }
1422       break;
1423     case GETABIT:
1424       retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1425                                 (TYPE_UDWORD)operandLitValue(right)) & 1);
1426       break;
1427     case GETBYTE:
1428       retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1429                                 (TYPE_UDWORD)operandLitValue(right)) & 0xFF);
1430       break;
1431     case GETWORD:
1432       retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1433                                 (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF);
1434       break;
1435
1436     case GETHBIT:
1437       retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1438                                 ((getSize (let) * 8) - 1)) & 1);
1439       break;
1440
1441     case UNARYMINUS:
1442       retval = operandFromValue (valCastLiteral (type,
1443                                                  -1 * operandLitValue (left)));
1444       break;
1445
1446     case '~':
1447       retval = operandFromValue (valCastLiteral (type,
1448                                                  ~((TYPE_UDWORD)
1449                                                    operandLitValue (left))));
1450       break;
1451
1452     case '!':
1453       retval = operandFromLit (!operandLitValue (left));
1454       break;
1455
1456     default:
1457       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1458               " operandOperation invalid operator ");
1459       assert (0);
1460     }
1461
1462   return retval;
1463 }
1464
1465
1466 /*-----------------------------------------------------------------*/
1467 /* isOperandEqual - compares two operand & return 1 if they r =    */
1468 /*-----------------------------------------------------------------*/
1469 int
1470 isOperandEqual (operand * left, operand * right)
1471 {
1472   /* if the pointers are equal then they are equal */
1473   if (left == right)
1474     return 1;
1475
1476   /* if either of them null then false */
1477   if (!left || !right)
1478     return 0;
1479
1480   if (left->type != right->type)
1481     return 0;
1482
1483   if (IS_SYMOP (left) && IS_SYMOP (right))
1484     return left->key == right->key;
1485
1486   /* if types are the same */
1487   switch (left->type)
1488     {
1489     case SYMBOL:
1490       return isSymbolEqual (left->operand.symOperand,
1491                             right->operand.symOperand);
1492     case VALUE:
1493       return (compareType (left->operand.valOperand->type,
1494                            right->operand.valOperand->type) &&
1495               (floatFromVal (left->operand.valOperand) ==
1496                floatFromVal (right->operand.valOperand)));
1497     case TYPE:
1498       if (compareType (left->operand.typeOperand,
1499                      right->operand.typeOperand) == 1)
1500         return 1;
1501     }
1502
1503   return 0;
1504 }
1505
1506 /*-------------------------------------------------------------------*/
1507 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1508 /*-------------------------------------------------------------------*/
1509 int
1510 isiCodeEqual (iCode * left, iCode * right)
1511 {
1512   /* if the same pointer */
1513   if (left == right)
1514     return 1;
1515
1516   /* if either of them null */
1517   if (!left || !right)
1518     return 0;
1519
1520   /* if operand are the same */
1521   if (left->op == right->op)
1522     {
1523
1524       /* compare all the elements depending on type */
1525       if (left->op != IFX)
1526         {
1527           if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1528             return 0;
1529           if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1530             return 0;
1531
1532         }
1533       else
1534         {
1535           if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1536             return 0;
1537           if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1538             return 0;
1539           if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1540             return 0;
1541         }
1542
1543       return 1;
1544     }
1545   return 0;
1546 }
1547
1548 /*-----------------------------------------------------------------*/
1549 /* newiTempFromOp - create a temp Operand with same attributes     */
1550 /*-----------------------------------------------------------------*/
1551 operand *
1552 newiTempFromOp (operand * op)
1553 {
1554   operand *nop;
1555
1556   if (!op)
1557     return NULL;
1558
1559   if (!IS_ITEMP (op))
1560     return op;
1561
1562   nop = newiTempOperand (operandType (op), TRUE);
1563   nop->isaddr = op->isaddr;
1564   nop->isvolatile = op->isvolatile;
1565   nop->isGlobal = op->isGlobal;
1566   nop->isLiteral = op->isLiteral;
1567   nop->usesDefs = op->usesDefs;
1568   nop->isParm = op->isParm;
1569   return nop;
1570 }
1571
1572 /*-----------------------------------------------------------------*/
1573 /* operand from operand - creates an operand holder for the type   */
1574 /*-----------------------------------------------------------------*/
1575 operand *
1576 operandFromOperand (operand * op)
1577 {
1578   operand *nop;
1579
1580   if (!op)
1581     return NULL;
1582   nop = newOperand ();
1583   nop->type = op->type;
1584   nop->isaddr = op->isaddr;
1585   nop->key = op->key;
1586   nop->isvolatile = op->isvolatile;
1587   nop->isGlobal = op->isGlobal;
1588   nop->isLiteral = op->isLiteral;
1589   nop->usesDefs = op->usesDefs;
1590   nop->isParm = op->isParm;
1591
1592   switch (nop->type)
1593     {
1594     case SYMBOL:
1595       nop->operand.symOperand = op->operand.symOperand;
1596       break;
1597     case VALUE:
1598       nop->operand.valOperand = op->operand.valOperand;
1599       break;
1600     case TYPE:
1601       nop->operand.typeOperand = op->operand.typeOperand;
1602       break;
1603     }
1604
1605   return nop;
1606 }
1607
1608 /*-----------------------------------------------------------------*/
1609 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
1610 /*-----------------------------------------------------------------*/
1611 operand *
1612 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1613 {
1614   operand *nop = operandFromOperand (op);
1615
1616   if (nop->type == SYMBOL)
1617     {
1618       OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1619       OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1620     }
1621
1622   return nop;
1623 }
1624
1625 /*-----------------------------------------------------------------*/
1626 /* operandFromSymbol - creates an operand from a symbol            */
1627 /*-----------------------------------------------------------------*/
1628 operand *
1629 operandFromSymbol (symbol * sym)
1630 {
1631   operand *op;
1632   iCode *ic;
1633   int ok = 1;
1634   /* if the symbol's type is a literal */
1635   /* then it is an enumerator type     */
1636   if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1637     return operandFromValue (valFromType (sym->etype));
1638
1639   if (!sym->key)
1640     sym->key = ++operandKey;
1641
1642   /* if this an implicit variable, means struct/union */
1643   /* member so just return it                         */
1644   if (sym->implicit || IS_FUNC (sym->type))
1645     {
1646       op = newOperand ();
1647       op->type = SYMBOL;
1648       op->operand.symOperand = sym;
1649       op->key = sym->key;
1650       op->isvolatile = isOperandVolatile (op, TRUE);
1651       op->isGlobal = isOperandGlobal (op);
1652       return op;
1653     }
1654
1655   /* under the following conditions create a
1656      register equivalent for a local symbol */
1657   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1658       (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1659       !TARGET_IS_HC08 &&
1660       (!(options.model == MODEL_FLAT24)) ) &&
1661       options.stackAuto == 0)
1662     ok = 0;
1663
1664   if (!IS_AGGREGATE (sym->type) &&      /* not an aggregate */
1665       !IS_FUNC (sym->type) &&           /* not a function   */
1666       !sym->_isparm &&                  /* not a parameter  */
1667       IS_AUTO (sym) &&                  /* is a local auto variable */
1668       !sym->addrtaken &&                /* whose address has not been taken */
1669       !sym->reqv &&                     /* does not already have a reg equivalence */
1670       !IS_VOLATILE (sym->etype) &&      /* not declared as volatile */
1671       !sym->islbl &&                    /* not a label */
1672       ok                            /* farspace check */
1673     )
1674     {
1675
1676       /* we will use it after all optimizations
1677          and before liveRange calculation */
1678       sym->reqv = newiTempOperand (sym->type, 0);
1679       sym->reqv->key = sym->key;
1680       OP_SYMBOL (sym->reqv)->prereqv = sym;
1681       OP_SYMBOL (sym->reqv)->key = sym->key;
1682       OP_SYMBOL (sym->reqv)->isreqv = 1;
1683       OP_SYMBOL (sym->reqv)->islocal = 1;
1684       OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1685       SPIL_LOC (sym->reqv) = sym;
1686     }
1687
1688   if (!IS_AGGREGATE (sym->type))
1689     {
1690       op = newOperand ();
1691       op->type = SYMBOL;
1692       op->operand.symOperand = sym;
1693       op->isaddr = 1;
1694       op->key = sym->key;
1695       op->isvolatile = isOperandVolatile (op, TRUE);
1696       op->isGlobal = isOperandGlobal (op);
1697       op->isPtr = IS_PTR (operandType (op));
1698       op->isParm = sym->_isparm;
1699       return op;
1700     }
1701
1702   /* create :-                     */
1703   /*    itemp = &[_symbol]         */
1704
1705   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1706   IC_LEFT (ic)->type = SYMBOL;
1707   IC_LEFT (ic)->operand.symOperand = sym;
1708   IC_LEFT (ic)->key = sym->key;
1709   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1710   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1711   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1712
1713   /* create result */
1714   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1715   if (IS_ARRAY (sym->type))
1716     {
1717       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1718       IC_RESULT (ic)->isaddr = 0;
1719     }
1720   else
1721     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1722
1723   ADDTOCHAIN (ic);
1724
1725   return IC_RESULT (ic);
1726 }
1727
1728 /*-----------------------------------------------------------------*/
1729 /* operandFromValue - creates an operand from value                */
1730 /*-----------------------------------------------------------------*/
1731 operand *
1732 operandFromValue (value * val)
1733 {
1734   operand *op;
1735
1736   /* if this is a symbol then do the symbol thing */
1737   if (val->sym)
1738     return operandFromSymbol (val->sym);
1739
1740   /* this is not a symbol */
1741   op = newOperand ();
1742   op->type = VALUE;
1743   op->operand.valOperand = val;
1744   op->isLiteral = isOperandLiteral (op);
1745   return op;
1746 }
1747
1748 /*-----------------------------------------------------------------*/
1749 /* operandFromLink - operand from typeChain                        */
1750 /*-----------------------------------------------------------------*/
1751 operand *
1752 operandFromLink (sym_link * type)
1753 {
1754   operand *op;
1755
1756   /* operand from sym_link */
1757   if (!type)
1758     return NULL;
1759
1760   op = newOperand ();
1761   op->type = TYPE;
1762   op->operand.typeOperand = copyLinkChain (type);
1763   return op;
1764 }
1765
1766 /*-----------------------------------------------------------------*/
1767 /* operandFromLit - makes an operand from a literal value          */
1768 /*-----------------------------------------------------------------*/
1769 operand *
1770 operandFromLit (double i)
1771 {
1772   return operandFromValue (valueFromLit (i));
1773 }
1774
1775 /*-----------------------------------------------------------------*/
1776 /* operandFromAst - creates an operand from an ast                 */
1777 /*-----------------------------------------------------------------*/
1778 operand *
1779 operandFromAst (ast * tree,int lvl)
1780 {
1781
1782   if (!tree)
1783     return NULL;
1784
1785   /* depending on type do */
1786   switch (tree->type)
1787     {
1788     case EX_OP:
1789       return ast2iCode (tree,lvl+1);
1790       break;
1791
1792     case EX_VALUE:
1793       return operandFromValue (tree->opval.val);
1794       break;
1795
1796     case EX_LINK:
1797       return operandFromLink (tree->opval.lnk);
1798       break;
1799
1800     default:
1801       assert (0);
1802     }
1803
1804   /*  Just to keep the compiler happy */
1805   return (operand *) 0;
1806 }
1807
1808 /*-----------------------------------------------------------------*/
1809 /* setOperandType - sets the operand's type to the given type      */
1810 /*-----------------------------------------------------------------*/
1811 void
1812 setOperandType (operand * op, sym_link * type)
1813 {
1814   /* depending on the type of operand */
1815   switch (op->type)
1816     {
1817
1818     case VALUE:
1819       op->operand.valOperand->etype =
1820         getSpec (op->operand.valOperand->type =
1821                  copyLinkChain (type));
1822       return;
1823
1824     case SYMBOL:
1825       if (op->operand.symOperand->isitmp)
1826         op->operand.symOperand->etype =
1827           getSpec (op->operand.symOperand->type =
1828                    copyLinkChain (type));
1829       else
1830         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1831                 "attempt to modify type of source");
1832       return;
1833
1834     case TYPE:
1835       op->operand.typeOperand = copyLinkChain (type);
1836       return;
1837     }
1838
1839 }
1840
1841 /*-----------------------------------------------------------------*/
1842 /* Get size in byte of ptr need to access an array                 */
1843 /*-----------------------------------------------------------------*/
1844 static int
1845 getArraySizePtr (operand * op)
1846 {
1847   sym_link *ltype = operandType(op);
1848
1849   if(IS_PTR(ltype))
1850     {
1851       int size = getSize(ltype);
1852       return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1853     }
1854
1855   if(IS_ARRAY(ltype))
1856     {
1857       sym_link *letype = getSpec(ltype);
1858       switch (PTR_TYPE (SPEC_OCLS (letype)))
1859         {
1860         case IPOINTER:
1861         case PPOINTER:
1862         case POINTER:
1863           return (PTRSIZE);
1864         case EEPPOINTER:
1865         case FPOINTER:
1866         case CPOINTER:
1867         case FUNCTION:
1868           return (FPTRSIZE);
1869         case GPOINTER:
1870           if (GPTRSIZE > FPTRSIZE)
1871             return (GPTRSIZE-1);
1872           else
1873             return (FPTRSIZE);
1874
1875         default:
1876           return (FPTRSIZE);
1877         }
1878     }
1879   return (FPTRSIZE);
1880 }
1881
1882 /*-----------------------------------------------------------------*/
1883 /* perform "usual unary conversions"                               */
1884 /*-----------------------------------------------------------------*/
1885 #if 0
1886 static operand *
1887 usualUnaryConversions (operand * op)
1888 {
1889   if (IS_INTEGRAL (operandType (op)))
1890     {
1891       if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1892         {
1893           /* Widen to int. */
1894           return geniCodeCast (INTTYPE, op, TRUE);
1895         }
1896     }
1897   return op;
1898 }
1899 #endif
1900
1901 /*-----------------------------------------------------------------*/
1902 /* perform "usual binary conversions"                              */
1903 /*-----------------------------------------------------------------*/
1904
1905 static sym_link *
1906 usualBinaryConversions (operand ** op1, operand ** op2,
1907                         RESULT_TYPE resultType, int op)
1908 {
1909   sym_link *ctype;
1910   sym_link *rtype = operandType (*op2);
1911   sym_link *ltype = operandType (*op1);
1912
1913   ctype = computeType (ltype, rtype, resultType, op);
1914
1915   switch (op)
1916     {
1917       case '*':
1918       case '/':
1919       case '%':
1920         if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1921           {
1922             /* one byte operations: keep signedness for code generator */
1923             return ctype;
1924           }
1925         break;
1926       default:
1927         break;
1928     }
1929
1930   *op1 = geniCodeCast (ctype, *op1, TRUE);
1931   *op2 = geniCodeCast (ctype, *op2, TRUE);
1932
1933   return ctype;
1934 }
1935
1936 /*-----------------------------------------------------------------*/
1937 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1938 /*                          at address                             */
1939 /*-----------------------------------------------------------------*/
1940 operand *
1941 geniCodeRValue (operand * op, bool force)
1942 {
1943   iCode *ic;
1944   sym_link *type = operandType (op);
1945   sym_link *etype = getSpec (type);
1946
1947   /* if this is an array & already */
1948   /* an address then return this   */
1949   if (IS_AGGREGATE (type) ||
1950       (IS_PTR (type) && !force && !op->isaddr))
1951     return operandFromOperand (op);
1952
1953   /* if this is not an address then must be */
1954   /* rvalue already so return this one      */
1955   if (!op->isaddr)
1956     return op;
1957
1958   /* if this is not a temp symbol then */
1959   if (!IS_ITEMP (op) &&
1960       !force &&
1961       !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1962     {
1963       op = operandFromOperand (op);
1964       op->isaddr = 0;
1965       return op;
1966     }
1967
1968   if (IS_SPEC (type) &&
1969       IS_TRUE_SYMOP (op) &&
1970       (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1971       (options.model == MODEL_FLAT24) ))
1972     {
1973       op = operandFromOperand (op);
1974       op->isaddr = 0;
1975       return op;
1976     }
1977
1978   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1979   if (IS_PTR (type) && op->isaddr && force)
1980     type = type->next;
1981
1982   type = copyLinkChain (type);
1983
1984   IC_RESULT (ic) = newiTempOperand (type, 1);
1985   IC_RESULT (ic)->isaddr = 0;
1986
1987 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1988
1989   ADDTOCHAIN (ic);
1990
1991   return IC_RESULT (ic);
1992 }
1993
1994 /*-----------------------------------------------------------------*/
1995 /* geniCodeCast - changes the value from one type to another       */
1996 /*-----------------------------------------------------------------*/
1997 static operand *
1998 geniCodeCast (sym_link * type, operand * op, bool implicit)
1999 {
2000   iCode *ic;
2001   sym_link *optype;
2002   sym_link *opetype = getSpec (optype = operandType (op));
2003   sym_link *restype;
2004   int errors=0;
2005
2006   /* one of them has size zero then error */
2007   if (IS_VOID (optype))
2008     {
2009       werror (E_CAST_ZERO);
2010       return op;
2011     }
2012
2013   if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
2014     {
2015       geniCodeArray2Ptr (op);
2016       op->isaddr = 0;
2017     }
2018
2019   /* if the operand is already the desired type then do nothing */
2020   if (compareType (type, optype) == 1)
2021     return op;
2022
2023   /* if this is a literal then just change the type & return */
2024   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
2025     {
2026       return operandFromValue (valCastLiteral (type,
2027                                                operandLitValue (op)));
2028     }
2029
2030   /* if casting to/from pointers, do some checking */
2031   if (IS_PTR(type)) { // to a pointer
2032     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
2033       if (IS_INTEGRAL(optype)) {
2034         // maybe this is NULL, than it's ok.
2035         if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
2036           if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
2037             // no way to set the storage
2038             if (IS_LITERAL(optype)) {
2039               werror(E_LITERAL_GENERIC);
2040               errors++;
2041             } else {
2042               werror(E_NONPTR2_GENPTR);
2043               errors++;
2044             }
2045           } else if (implicit) {
2046             werror(W_INTEGRAL2PTR_NOCAST);
2047             errors++;
2048           }
2049         }
2050       } else {
2051         // shouldn't do that with float, array or structure unless to void
2052         if (!IS_VOID(getSpec(type)) &&
2053             !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2054           werror(E_INCOMPAT_TYPES);
2055           errors++;
2056         }
2057       }
2058     } else { // from a pointer to a pointer
2059       if (IS_GENPTR(type) && IS_VOID(type->next))
2060         { // cast to void* is always allowed
2061         }
2062       else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2063         { // cast from void* is always allowed
2064         }
2065       else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2066         // if not a pointer to a function
2067         if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2068           if (implicit) { // if not to generic, they have to match
2069             if (!IS_GENPTR(type) &&
2070                 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2071                   ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2072                  )
2073                )
2074             {
2075               werror(E_INCOMPAT_PTYPES);
2076               errors++;
2077             }
2078           }
2079         }
2080       }
2081     }
2082   } else { // to a non pointer
2083     if (IS_PTR(optype)) { // from a pointer
2084       if (implicit) { // sneaky
2085         if (IS_INTEGRAL(type)) {
2086           werror(W_PTR2INTEGRAL_NOCAST);
2087           errors++;
2088         } else { // shouldn't do that with float, array or structure
2089           werror(E_INCOMPAT_TYPES);
2090           errors++;
2091         }
2092       }
2093     }
2094   }
2095   if (errors) {
2096     printFromToType (optype, type);
2097   }
2098
2099   /* if they are the same size create an assignment */
2100
2101   /* This seems very dangerous to me, since there are several */
2102   /* optimizations (for example, gcse) that don't notice the  */
2103   /* cast hidden in this assignement and may simplify an      */
2104   /* iCode to use the original (uncasted) operand.            */
2105   /* Unfortunately, other things break when this cast is      */
2106   /* made explicit. Need to fix this someday.                 */
2107   /* -- EEP, 2004/01/21                                       */
2108   if (getSize (type) == getSize (optype) &&
2109       !IS_BITFIELD (type) &&
2110       !IS_FLOAT (type) &&
2111       !IS_FLOAT (optype) &&
2112       !IS_FIXED (type) &&
2113       !IS_FIXED (optype) &&
2114       ((IS_SPEC (type) && IS_SPEC (optype)) ||
2115        (!IS_SPEC (type) && !IS_SPEC (optype))))
2116     {
2117       ic = newiCode ('=', NULL, op);
2118       IC_RESULT (ic) = newiTempOperand (type, 0);
2119       if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2120           SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2121       IC_RESULT (ic)->isaddr = 0;
2122     }
2123   else
2124     {
2125       ic = newiCode (CAST, operandFromLink (type),
2126                      geniCodeRValue (op, FALSE));
2127
2128       IC_RESULT (ic) = newiTempOperand (type, 0);
2129     }
2130
2131   /* preserve the storage class & output class */
2132   /* of the original variable                  */
2133   restype = getSpec (operandType (IC_RESULT (ic)));
2134   if (!IS_LITERAL(opetype) &&
2135       !IS_BIT(opetype))
2136     {
2137       SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2138       SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2139     }
2140   ADDTOCHAIN (ic);
2141   return IC_RESULT (ic);
2142 }
2143
2144 /*-----------------------------------------------------------------*/
2145 /* geniCodeLabel - will create a Label                             */
2146 /*-----------------------------------------------------------------*/
2147 void
2148 geniCodeLabel (symbol * label)
2149 {
2150   iCode *ic;
2151
2152   ic = newiCodeLabelGoto (LABEL, label);
2153   ADDTOCHAIN (ic);
2154 }
2155
2156 /*-----------------------------------------------------------------*/
2157 /* geniCodeGoto  - will create a Goto                              */
2158 /*-----------------------------------------------------------------*/
2159 void
2160 geniCodeGoto (symbol * label)
2161 {
2162   iCode *ic;
2163
2164   ic = newiCodeLabelGoto (GOTO, label);
2165   ADDTOCHAIN (ic);
2166 }
2167
2168 /*-----------------------------------------------------------------*/
2169 /* geniCodeMultiply - gen intermediate code for multiplication     */
2170 /*-----------------------------------------------------------------*/
2171 static operand *
2172 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2173 {
2174   iCode *ic;
2175   int p2 = 0;
2176   sym_link *resType;
2177   LRTYPE;
2178
2179   /* if they are both literal then we know the result */
2180   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2181     return operandFromValue (valMult (left->operand.valOperand,
2182                                       right->operand.valOperand));
2183
2184   if (IS_LITERAL(retype)) {
2185     p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2186   }
2187
2188   resType = usualBinaryConversions (&left, &right, resultType, '*');
2189 #if 1
2190   rtype = operandType (right);
2191   retype = getSpec (rtype);
2192   ltype = operandType (left);
2193   letype = getSpec (ltype);
2194 #endif
2195
2196   /* if the right is a literal & power of 2 */
2197   /* then make it a left shift              */
2198   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2199      efficient in most cases than 2 bytes result = 2 bytes << literal
2200      if port has 1 byte muldiv */
2201   if (p2 && !IS_FLOAT (letype) && !IS_FIXED (letype)
2202       && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2203            && (port->support.muldiv == 1))
2204       && strcmp (port->target, "pic16") != 0  /* don't shift for pic */
2205       && strcmp (port->target, "pic14") != 0)
2206     {
2207       if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2208         {
2209           /* LEFT_OP need same size for left and result, */
2210           left = geniCodeCast (resType, left, TRUE);
2211           ltype = operandType (left);
2212         }
2213       ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2214     }
2215   else
2216     {
2217       ic = newiCode ('*', left, right);         /* normal multiplication */
2218       /* if the size left or right > 1 then support routine */
2219       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2220         ic->supportRtn = 1;
2221
2222     }
2223   IC_RESULT (ic) = newiTempOperand (resType, 1);
2224
2225   ADDTOCHAIN (ic);
2226   return IC_RESULT (ic);
2227 }
2228
2229 /*-----------------------------------------------------------------*/
2230 /* geniCodeDivision - gen intermediate code for division           */
2231 /*-----------------------------------------------------------------*/
2232 static operand *
2233 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2234 {
2235   iCode *ic;
2236   int p2 = 0;
2237   sym_link *resType;
2238   sym_link *rtype = operandType (right);
2239   sym_link *retype = getSpec (rtype);
2240   sym_link *ltype = operandType (left);
2241   sym_link *letype = getSpec (ltype);
2242
2243   resType = usualBinaryConversions (&left, &right, resultType, '/');
2244
2245   /* if the right is a literal & power of 2
2246      and left is unsigned then make it a
2247      right shift */
2248   if (IS_LITERAL (retype) &&
2249       !IS_FLOAT (letype) &&
2250       !IS_FIXED (letype) &&
2251       IS_UNSIGNED(letype) &&
2252       (p2 = powof2 ((TYPE_UDWORD)
2253                     floatFromVal (right->operand.valOperand)))) {
2254     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2255   }
2256   else
2257     {
2258       ic = newiCode ('/', left, right);         /* normal division */
2259       /* if the size left or right > 1 then support routine */
2260       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2261         ic->supportRtn = 1;
2262     }
2263   IC_RESULT (ic) = newiTempOperand (resType, 0);
2264
2265   ADDTOCHAIN (ic);
2266   return IC_RESULT (ic);
2267 }
2268 /*-----------------------------------------------------------------*/
2269 /* geniCodeModulus  - gen intermediate code for modulus            */
2270 /*-----------------------------------------------------------------*/
2271 static operand *
2272 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2273 {
2274   iCode *ic;
2275   sym_link *resType;
2276   LRTYPE;
2277
2278   /* if they are both literal then we know the result */
2279   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2280     return operandFromValue (valMod (left->operand.valOperand,
2281                                      right->operand.valOperand));
2282
2283   resType = usualBinaryConversions (&left, &right, resultType, '%');
2284
2285   /* now they are the same size */
2286   ic = newiCode ('%', left, right);
2287
2288   /* if the size left or right > 1 then support routine */
2289   if (getSize (ltype) > 1 || getSize (rtype) > 1)
2290     ic->supportRtn = 1;
2291   IC_RESULT (ic) = newiTempOperand (resType, 0);
2292
2293   ADDTOCHAIN (ic);
2294   return IC_RESULT (ic);
2295 }
2296
2297 /*-----------------------------------------------------------------*/
2298 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
2299 /*-----------------------------------------------------------------*/
2300 operand *
2301 geniCodePtrPtrSubtract (operand * left, operand * right)
2302 {
2303   iCode *ic;
2304   operand *result;
2305   LRTYPE;
2306
2307   /* if they are both literals then */
2308   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2309     {
2310       result = operandFromValue (valMinus (left->operand.valOperand,
2311                                            right->operand.valOperand));
2312       goto subtractExit;
2313     }
2314
2315   ic = newiCode ('-', left, right);
2316
2317   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2318   ADDTOCHAIN (ic);
2319
2320 subtractExit:
2321   if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2322     return result;
2323   }
2324
2325   // should we really do this? is this ANSI?
2326   return geniCodeDivision (result,
2327                            operandFromLit (getSize (ltype->next)),
2328                            FALSE);
2329 }
2330
2331 /*-----------------------------------------------------------------*/
2332 /* geniCodeSubtract - generates code for subtraction               */
2333 /*-----------------------------------------------------------------*/
2334 static operand *
2335 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2336 {
2337   iCode *ic;
2338   int isarray = 0;
2339   sym_link *resType;
2340   LRTYPE;
2341
2342   /* if they both pointers then */
2343   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2344       (IS_PTR (rtype) || IS_ARRAY (rtype)))
2345     return geniCodePtrPtrSubtract (left, right);
2346
2347   /* if they are both literal then we know the result */
2348   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2349       && left->isLiteral && right->isLiteral)
2350     return operandFromValue (valMinus (left->operand.valOperand,
2351                                        right->operand.valOperand));
2352
2353   /* if left is an array or pointer */
2354   if (IS_PTR (ltype) || IS_ARRAY (ltype))
2355     {
2356       isarray = left->isaddr;
2357       right = geniCodeMultiply (right,
2358                                 operandFromLit (getSize (ltype->next)),
2359                                 (getArraySizePtr(left) >= INTSIZE) ?
2360                                   RESULT_TYPE_INT :
2361                                   RESULT_TYPE_CHAR);
2362       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2363     }
2364   else
2365     {                           /* make them the same size */
2366       resType = usualBinaryConversions (&left, &right, resultType, '-');
2367     }
2368
2369   ic = newiCode ('-', left, right);
2370
2371   IC_RESULT (ic) = newiTempOperand (resType, 1);
2372   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2373
2374   /* if left or right is a float */
2375   if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2376       || IS_FIXED (ltype) || IS_FIXED (rtype))
2377     ic->supportRtn = 1;
2378
2379   ADDTOCHAIN (ic);
2380   return IC_RESULT (ic);
2381 }
2382
2383 /*-----------------------------------------------------------------*/
2384 /* geniCodeAdd - generates iCode for addition                      */
2385 /*-----------------------------------------------------------------*/
2386 static operand *
2387 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2388 {
2389   iCode *ic;
2390   sym_link *resType;
2391   operand *size;
2392   int isarray = 0;
2393   bool indexUnsigned;
2394   LRTYPE;
2395
2396   /* if the right side is LITERAL zero */
2397   /* return the left side              */
2398   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2399     return left;
2400
2401   /* if left is literal zero return right */
2402   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2403     return right;
2404
2405   /* if left is a pointer then size */
2406   if (IS_PTR (ltype) || IS_ARRAY(ltype))
2407     {
2408       isarray = left->isaddr;
2409       // there is no need to multiply with 1
2410       if (getSize (ltype->next) != 1)
2411         {
2412           size  = operandFromLit (getSize (ltype->next));
2413           SPEC_USIGN (getSpec (operandType (size))) = 1;
2414           indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2415           right = geniCodeMultiply (right,
2416                                     size,
2417                                     (getArraySizePtr(left) >= INTSIZE) ?
2418                                       RESULT_TYPE_INT :
2419                                       RESULT_TYPE_CHAR);
2420           /* Even if right is a 'unsigned char',
2421              the result will be a 'signed int' due to the promotion rules.
2422              It doesn't make sense when accessing arrays, so let's fix it here: */
2423           if (indexUnsigned)
2424             SPEC_USIGN (getSpec (operandType (right))) = 1;
2425         }
2426       resType = copyLinkChain (ltype);
2427     }
2428   else
2429     { // make them the same size
2430       resType = usualBinaryConversions (&left, &right, resultType, '+');
2431     }
2432
2433   /* if they are both literals then we know */
2434   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2435       && left->isLiteral && right->isLiteral)
2436     return operandFromValue (valPlus (valFromType (ltype),
2437                                       valFromType (rtype)));
2438
2439   ic = newiCode ('+', left, right);
2440
2441   IC_RESULT (ic) = newiTempOperand (resType, 1);
2442   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2443
2444   /* if left or right is a float then support
2445      routine */
2446   if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2447       || IS_FIXED (ltype) || IS_FIXED (rtype))
2448     ic->supportRtn = 1;
2449
2450   ADDTOCHAIN (ic);
2451
2452   return IC_RESULT (ic);
2453
2454 }
2455
2456 /*-----------------------------------------------------------------*/
2457 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate"  */
2458 /*-----------------------------------------------------------------*/
2459 sym_link *
2460 aggrToPtr (sym_link * type, bool force)
2461 {
2462   sym_link *etype;
2463   sym_link *ptype;
2464
2465   if (IS_PTR (type) && !force)
2466     return type;
2467
2468   etype = getSpec (type);
2469   ptype = newLink (DECLARATOR);
2470
2471   ptype->next = type;
2472
2473   /* set the pointer depending on the storage class */
2474   DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2475   return ptype;
2476 }
2477
2478 /*------------------------------------------------------------------*/
2479 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2480 /*------------------------------------------------------------------*/
2481 int
2482 aggrToPtrDclType (sym_link * type, bool force)
2483 {
2484   if (IS_PTR (type) && !force)
2485     return DCL_TYPE (type);
2486
2487   /* return the pointer depending on the storage class */
2488   return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2489 }
2490
2491 /*-----------------------------------------------------------------*/
2492 /* geniCodeArray2Ptr - array to pointer                            */
2493 /*-----------------------------------------------------------------*/
2494 static operand *
2495 geniCodeArray2Ptr (operand * op)
2496 {
2497   sym_link *optype = operandType (op);
2498   sym_link *opetype = getSpec (optype);
2499
2500   /* set the pointer depending on the storage class */
2501   DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2502
2503   op->isaddr = 0;
2504   return op;
2505 }
2506
2507
2508 /*-----------------------------------------------------------------*/
2509 /* geniCodeArray - array access                                    */
2510 /*-----------------------------------------------------------------*/
2511 static operand *
2512 geniCodeArray (operand * left, operand * right, int lvl)
2513 {
2514   iCode *ic;
2515   operand *size;
2516   sym_link *ltype = operandType (left);
2517   bool indexUnsigned;
2518
2519   if (IS_PTR (ltype))
2520     {
2521       if (IS_PTR (ltype->next) && left->isaddr)
2522         {
2523           left = geniCodeRValue (left, FALSE);
2524         }
2525
2526       return geniCodeDerefPtr (geniCodeAdd (left,
2527                                             right,
2528                                             (getArraySizePtr(left) >= INTSIZE) ?
2529                                               RESULT_TYPE_INT :
2530                                               RESULT_TYPE_CHAR,
2531                                             lvl),
2532                                lvl);
2533     }
2534   size = operandFromLit (getSize (ltype->next));
2535   SPEC_USIGN (getSpec (operandType (size))) = 1;
2536   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2537   right = geniCodeMultiply (right,
2538                             size,
2539                             (getArraySizePtr(left) >= INTSIZE) ?
2540                               RESULT_TYPE_INT :
2541                               RESULT_TYPE_CHAR);
2542   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2543      It doesn't make sense when accessing arrays, so let's fix it here: */
2544   if (indexUnsigned)
2545     SPEC_USIGN (getSpec (operandType (right))) = 1;
2546   /* we can check for limits here */
2547   /* already done in SDCCast.c
2548   if (isOperandLiteral (right) &&
2549       IS_ARRAY (ltype) &&
2550       DCL_ELEM (ltype) &&
2551       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2552     {
2553       werror (W_IDX_OUT_OF_BOUNDS,
2554               (int) operandLitValue (right) / getSize (ltype->next),
2555               DCL_ELEM (ltype));
2556     }
2557   */
2558
2559   ic = newiCode ('+', left, right);
2560
2561   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2562                                       !IS_AGGREGATE (ltype->next) &&
2563                                       !IS_PTR (ltype->next))
2564                                      ? ltype : ltype->next), 0);
2565
2566   if (!IS_AGGREGATE (ltype->next))
2567     {
2568       IC_RESULT (ic)->isaddr = 1;
2569       IC_RESULT (ic)->aggr2ptr = 1;
2570     }
2571   ADDTOCHAIN (ic);
2572
2573   return IC_RESULT (ic);
2574 }
2575
2576 /*-----------------------------------------------------------------*/
2577 /* geniCodeStruct - generates intermediate code for structures     */
2578 /*-----------------------------------------------------------------*/
2579 operand *
2580 geniCodeStruct (operand * left, operand * right, bool islval)
2581 {
2582   iCode *ic;
2583   sym_link *type = operandType (left);
2584   sym_link *etype = getSpec (type);
2585   sym_link *retype;
2586   symbol *element = getStructElement (SPEC_STRUCT (etype),
2587                                       right->operand.symOperand);
2588
2589   wassert(IS_SYMOP(right));
2590
2591   /* add the offset */
2592   ic = newiCode ('+', left, operandFromLit (element->offset));
2593
2594   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2595
2596   /* preserve the storage & output class of the struct */
2597   /* as well as the volatile attribute */
2598   retype = getSpec (operandType (IC_RESULT (ic)));
2599   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2600   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2601   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2602   SPEC_CONST (retype) |= SPEC_CONST (etype);
2603
2604   if (IS_PTR (element->type))
2605     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2606
2607   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2608
2609   ADDTOCHAIN (ic);
2610   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2611 }
2612
2613 /*-----------------------------------------------------------------*/
2614 /* geniCodePostInc - generate int code for Post increment          */
2615 /*-----------------------------------------------------------------*/
2616 operand *
2617 geniCodePostInc (operand * op)
2618 {
2619   iCode *ic;
2620   operand *rOp;
2621   sym_link *optype = operandType (op);
2622   operand *result;
2623   operand *rv = (IS_ITEMP (op) ?
2624                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2625                  op);
2626   sym_link *rvtype = operandType (rv);
2627   int size = 0;
2628
2629   /* if this is not an address we have trouble */
2630   if (!op->isaddr)
2631     {
2632       werror (E_LVALUE_REQUIRED, "++");
2633       return op;
2634     }
2635
2636   rOp = newiTempOperand (rvtype, 0);
2637   OP_SYMBOL(rOp)->noSpilLoc = 1;
2638
2639   if (IS_ITEMP (rv))
2640     OP_SYMBOL(rv)->noSpilLoc = 1;
2641
2642   geniCodeAssign (rOp, rv, 0, 0);
2643
2644   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2645   if (size == 0)
2646     werror(W_SIZEOF_VOID);
2647   if (IS_FLOAT (rvtype))
2648     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2649   else
2650   if (IS_FIXED16X16 (rvtype))
2651     ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2652   else
2653     ic = newiCode ('+', rv, operandFromLit (size));
2654
2655   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2656   ADDTOCHAIN (ic);
2657
2658   geniCodeAssign (op, result, 0, 0);
2659
2660   return rOp;
2661
2662 }
2663
2664 /*-----------------------------------------------------------------*/
2665 /* geniCodePreInc - generate code for preIncrement                 */
2666 /*-----------------------------------------------------------------*/
2667 operand *
2668 geniCodePreInc (operand * op, bool lvalue)
2669 {
2670   iCode *ic;
2671   sym_link *optype = operandType (op);
2672   operand *rop = (IS_ITEMP (op) ?
2673                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2674                   op);
2675   sym_link *roptype = operandType (rop);
2676   operand *result;
2677   int size = 0;
2678
2679   if (!op->isaddr)
2680     {
2681       werror (E_LVALUE_REQUIRED, "++");
2682       return op;
2683     }
2684
2685   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2686   if (size == 0)
2687     werror(W_SIZEOF_VOID);
2688   if (IS_FLOAT (roptype))
2689     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2690   else
2691   if (IS_FIXED16X16 (roptype))
2692     ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2693   else
2694     ic = newiCode ('+', rop, operandFromLit (size));
2695   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2696   ADDTOCHAIN (ic);
2697
2698   (void) geniCodeAssign (op, result, 0, 0);
2699   if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2700     return op;
2701   else
2702     return result;
2703 }
2704
2705 /*-----------------------------------------------------------------*/
2706 /* geniCodePostDec - generates code for Post decrement             */
2707 /*-----------------------------------------------------------------*/
2708 operand *
2709 geniCodePostDec (operand * op)
2710 {
2711   iCode *ic;
2712   operand *rOp;
2713   sym_link *optype = operandType (op);
2714   operand *result;
2715   operand *rv = (IS_ITEMP (op) ?
2716                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2717                  op);
2718   sym_link *rvtype = operandType (rv);
2719   int size = 0;
2720
2721   /* if this is not an address we have trouble */
2722   if (!op->isaddr)
2723     {
2724       werror (E_LVALUE_REQUIRED, "--");
2725       return op;
2726     }
2727
2728   rOp = newiTempOperand (rvtype, 0);
2729   OP_SYMBOL(rOp)->noSpilLoc = 1;
2730
2731   if (IS_ITEMP (rv))
2732     OP_SYMBOL(rv)->noSpilLoc = 1;
2733
2734   geniCodeAssign (rOp, rv, 0, 0);
2735
2736   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2737   if (size == 0)
2738     werror(W_SIZEOF_VOID);
2739   if (IS_FLOAT (rvtype))
2740     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2741   else
2742   if (IS_FIXED16X16 (rvtype))
2743     ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2744   else
2745     ic = newiCode ('-', rv, operandFromLit (size));
2746
2747   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2748   ADDTOCHAIN (ic);
2749
2750   geniCodeAssign (op, result, 0, 0);
2751
2752   return rOp;
2753
2754 }
2755
2756 /*-----------------------------------------------------------------*/
2757 /* geniCodePreDec - generate code for pre  decrement               */
2758 /*-----------------------------------------------------------------*/
2759 operand *
2760 geniCodePreDec (operand * op, bool lvalue)
2761 {
2762   iCode *ic;
2763   sym_link *optype = operandType (op);
2764   operand *rop = (IS_ITEMP (op) ?
2765                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2766                   op);
2767   sym_link *roptype = operandType (rop);
2768   operand *result;
2769   int size = 0;
2770
2771   if (!op->isaddr)
2772     {
2773       werror (E_LVALUE_REQUIRED, "--");
2774       return op;
2775     }
2776
2777   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2778   if (size == 0)
2779     werror(W_SIZEOF_VOID);
2780   if (IS_FLOAT (roptype))
2781     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2782   else
2783   if (IS_FIXED16X16 (roptype))
2784     ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2785   else
2786     ic = newiCode ('-', rop, operandFromLit (size));
2787   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2788   ADDTOCHAIN (ic);
2789
2790   (void) geniCodeAssign (op, result, 0, 0);
2791   if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2792     return op;
2793   else
2794     return result;
2795 }
2796
2797
2798 /*-----------------------------------------------------------------*/
2799 /* geniCodeBitwise - gen int code for bitWise  operators           */
2800 /*-----------------------------------------------------------------*/
2801 operand *
2802 geniCodeBitwise (operand * left, operand * right,
2803                  int oper, sym_link * resType)
2804 {
2805   iCode *ic;
2806
2807   left = geniCodeCast (resType, left, TRUE);
2808   right = geniCodeCast (resType, right, TRUE);
2809
2810   ic = newiCode (oper, left, right);
2811   IC_RESULT (ic) = newiTempOperand (resType, 0);
2812
2813   ADDTOCHAIN (ic);
2814   return IC_RESULT (ic);
2815 }
2816
2817 /*-----------------------------------------------------------------*/
2818 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2819 /*-----------------------------------------------------------------*/
2820 operand *
2821 geniCodeAddressOf (operand * op)
2822 {
2823   iCode *ic;
2824   sym_link *p;
2825   sym_link *optype = operandType (op);
2826   sym_link *opetype = getSpec (optype);
2827
2828   if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2829     {
2830       op = operandFromOperand (op);
2831       op->isaddr = 0;
2832       return op;
2833     }
2834
2835   /* lvalue check already done in decorateType */
2836   /* this must be a lvalue */
2837 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2838 /*  werror (E_LVALUE_REQUIRED,"&"); */
2839 /*  return op; */
2840 /*     } */
2841
2842   p = newLink (DECLARATOR);
2843
2844   /* set the pointer depending on the storage class */
2845   DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2846
2847   p->next = copyLinkChain (optype);
2848
2849   /* if already a temp */
2850   if (IS_ITEMP (op))
2851     {
2852       setOperandType (op, p);
2853       op->isaddr = 0;
2854       return op;
2855     }
2856
2857   /* other wise make this of the type coming in */
2858   ic = newiCode (ADDRESS_OF, op, NULL);
2859   IC_RESULT (ic) = newiTempOperand (p, 1);
2860   IC_RESULT (ic)->isaddr = 0;
2861   ADDTOCHAIN (ic);
2862   return IC_RESULT (ic);
2863 }
2864 /*-----------------------------------------------------------------*/
2865 /* setOClass - sets the output class depending on the pointer type */
2866 /*-----------------------------------------------------------------*/
2867 void
2868 setOClass (sym_link * ptr, sym_link * spec)
2869 {
2870   switch (DCL_TYPE (ptr))
2871     {
2872     case POINTER:
2873       SPEC_OCLS (spec) = data;
2874       break;
2875
2876     case GPOINTER:
2877       SPEC_OCLS (spec) = generic;
2878       break;
2879
2880     case FPOINTER:
2881       SPEC_OCLS (spec) = xdata;
2882       break;
2883
2884     case CPOINTER:
2885       SPEC_OCLS (spec) = code;
2886       break;
2887
2888     case IPOINTER:
2889       SPEC_OCLS (spec) = idata;
2890       break;
2891
2892     case PPOINTER:
2893       SPEC_OCLS (spec) = xstack;
2894       break;
2895
2896     case EEPPOINTER:
2897       SPEC_OCLS (spec) = eeprom;
2898       break;
2899
2900     default:
2901       break;
2902
2903     }
2904 }
2905
2906 /*-----------------------------------------------------------------*/
2907 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2908 /*-----------------------------------------------------------------*/
2909 operand *
2910 geniCodeDerefPtr (operand * op,int lvl)
2911 {
2912   sym_link *rtype, *retype;
2913   sym_link *optype = operandType (op);
2914
2915   // if this is an array then array access
2916   if (IS_ARRAY (optype)) {
2917     // don't worry, this will be optimized out later
2918     return geniCodeArray (op, operandFromLit (0), lvl);
2919   }
2920
2921   // just in case someone screws up
2922   wassert (IS_PTR (optype));
2923
2924   if (IS_TRUE_SYMOP (op))
2925     {
2926       op->isaddr = 1;
2927       op = geniCodeRValue (op, TRUE);
2928     }
2929
2930   /* now get rid of the pointer part */
2931   if (isLvaluereq(lvl) && IS_ITEMP (op))
2932     {
2933       retype = getSpec (rtype = copyLinkChain (optype));
2934     }
2935   else
2936     {
2937       retype = getSpec (rtype = copyLinkChain (optype->next));
2938       /* outputclass needs 2b updated */
2939       setOClass (optype, retype);
2940     }
2941
2942   op->isGptr = IS_GENPTR (optype);
2943
2944   op->isaddr = (IS_PTR (rtype) ||
2945                 IS_STRUCT (rtype) ||
2946                 IS_INT (rtype) ||
2947                 IS_CHAR (rtype) ||
2948                 IS_FLOAT (rtype) ||
2949                 IS_FIXED (rtype));
2950
2951   if (!isLvaluereq(lvl))
2952     op = geniCodeRValue (op, TRUE);
2953
2954   setOperandType (op, rtype);
2955
2956   return op;
2957 }
2958
2959 /*-----------------------------------------------------------------*/
2960 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2961 /*-----------------------------------------------------------------*/
2962 operand *
2963 geniCodeUnaryMinus (operand * op)
2964 {
2965   iCode *ic;
2966   sym_link *optype = operandType (op);
2967
2968   if (IS_LITERAL (optype))
2969     return operandFromLit (-floatFromVal (op->operand.valOperand));
2970
2971   ic = newiCode (UNARYMINUS, op, NULL);
2972   IC_RESULT (ic) = newiTempOperand (optype, 0);
2973   ADDTOCHAIN (ic);
2974   return IC_RESULT (ic);
2975 }
2976
2977 /*-----------------------------------------------------------------*/
2978 /* geniCodeLeftShift - gen i code for left shift                   */
2979 /*-----------------------------------------------------------------*/
2980 operand *
2981 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2982 {
2983   iCode *ic;
2984   sym_link *resType;
2985
2986   ic = newiCode (LEFT_OP, left, right);
2987
2988   resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2989   IC_RESULT (ic) = newiTempOperand (resType, 0);
2990   ADDTOCHAIN (ic);
2991   return IC_RESULT (ic);
2992 }
2993
2994 /*-----------------------------------------------------------------*/
2995 /* geniCodeRightShift - gen i code for right shift                 */
2996 /*-----------------------------------------------------------------*/
2997 operand *
2998 geniCodeRightShift (operand * left, operand * right)
2999 {
3000   iCode *ic;
3001
3002   ic = newiCode (RIGHT_OP, left, right);
3003   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3004   ADDTOCHAIN (ic);
3005   return IC_RESULT (ic);
3006 }
3007
3008 /*-----------------------------------------------------------------*/
3009 /* geniCodeLogic- logic code                                       */
3010 /*-----------------------------------------------------------------*/
3011 static operand *
3012 geniCodeLogic (operand * left, operand * right, int op)
3013 {
3014   iCode *ic;
3015   sym_link *ctype;
3016   sym_link *rtype = operandType (right);
3017   sym_link *ltype = operandType (left);
3018
3019   /* left is integral type and right is literal then
3020      check if the literal value is within bounds */
3021   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3022     {
3023       checkConstantRange(ltype,
3024                          OP_VALUE(right), "compare operation", 1);
3025     }
3026
3027   /* if one operand is a pointer and the other is a literal generic void pointer,
3028      change the type of the literal generic void pointer to match the other pointer */
3029   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3030       && IS_PTR (rtype) && !IS_GENPTR(rtype))
3031     {
3032       /* find left's definition */
3033       ic = (iCode *) setFirstItem (iCodeChain);
3034       while (ic)
3035         {
3036           if (((ic->op == CAST) || (ic->op == '='))
3037               && isOperandEqual(left, IC_RESULT (ic)))
3038             break;
3039           else
3040             ic = setNextItem (iCodeChain);
3041         }
3042       /* if casting literal to generic pointer, then cast to rtype instead */
3043       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3044         {
3045           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3046           ltype = operandType(left);
3047         }
3048     }
3049   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3050       && IS_PTR (ltype) && !IS_GENPTR(ltype))
3051     {
3052       /* find right's definition */
3053       ic = (iCode *) setFirstItem (iCodeChain);
3054       while (ic)
3055         {
3056           if (((ic->op == CAST) || (ic->op == '='))
3057               && isOperandEqual(right, IC_RESULT (ic)))
3058             break;
3059           else
3060             ic = setNextItem (iCodeChain);
3061         }
3062       /* if casting literal to generic pointer, then cast to rtype instead */
3063       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3064         {
3065           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3066           rtype = operandType(right);
3067         }
3068     }
3069
3070   ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3071
3072   ic = newiCode (op, left, right);
3073   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3074
3075   /* if comparing float
3076      and not a '==' || '!=' || '&&' || '||' (these
3077      will be inlined */
3078   if (IS_FLOAT(ctype) &&
3079       op != EQ_OP &&
3080       op != NE_OP &&
3081       op != AND_OP &&
3082       op != OR_OP)
3083    ic->supportRtn = 1;
3084
3085   /* if comparing a fixed type use support functions */
3086   if (IS_FIXED(ctype))
3087     ic->supportRtn = 1;
3088
3089   ADDTOCHAIN (ic);
3090   return IC_RESULT (ic);
3091 }
3092
3093 /*-----------------------------------------------------------------*/
3094 /* geniCodeLogicAndOr - && || operations                           */
3095 /*-----------------------------------------------------------------*/
3096 static operand *
3097 geniCodeLogicAndOr (ast *tree, int lvl)
3098 {
3099   iCode *ic;
3100   sym_link *type;
3101   symbol *falseLabel = newiTempLabel (NULL);
3102   symbol *trueLabel  = newiTempLabel (NULL);
3103   symbol *exitLabel  = newiTempLabel (NULL);
3104   operand *op, *result, *condition;
3105
3106   /* AND_OP and OR_OP are no longer generated because of bug-905492.
3107      They can be reenabled by executing the following block. If you find
3108      a decent optimization you could start right here:
3109   */
3110 #if 0
3111   if (0)
3112     {
3113        operand *leftOp, *rightOp;
3114
3115        leftOp  = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3116        rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3117
3118        return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3119     }
3120 #endif
3121
3122   /* generate two IFX for the '&&' or '||' op */
3123
3124   /* evaluate left operand */
3125   condition = ast2iCode (tree->left, lvl + 1);
3126   op = geniCodeRValue (condition, FALSE);
3127
3128   /* test left operand */
3129   if (tree->opval.op == AND_OP)
3130     ic = newiCodeCondition (op, NULL, falseLabel);
3131   else /* OR_OP */
3132     ic = newiCodeCondition (op, trueLabel, NULL);
3133   ADDTOCHAIN (ic);
3134
3135   /* evaluate right operand */
3136   condition = ast2iCode (tree->right, lvl + 1);
3137   op = geniCodeRValue (condition, FALSE);
3138
3139   /* test right operand */
3140   ic = newiCodeCondition (op, trueLabel, NULL);
3141   ADDTOCHAIN (ic);
3142
3143   /* store 0 or 1 in result */
3144   type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3145   result = newiTempOperand (type, 1);
3146
3147   geniCodeLabel (falseLabel);
3148   geniCodeAssign (result, operandFromLit (0), 0, 0);
3149   /* generate an unconditional goto */
3150   geniCodeGoto (exitLabel);
3151
3152   geniCodeLabel (trueLabel);
3153   geniCodeAssign (result, operandFromLit (1), 0, 0);
3154
3155   geniCodeLabel (exitLabel);
3156
3157   return result;
3158 }
3159
3160 /*-----------------------------------------------------------------*/
3161 /* geniCodeUnary - for a generic unary operation                   */
3162 /*-----------------------------------------------------------------*/
3163 operand *
3164 geniCodeUnary (operand * op, int oper)
3165 {
3166   iCode *ic = newiCode (oper, op, NULL);
3167
3168   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3169   ADDTOCHAIN (ic);
3170   return IC_RESULT (ic);
3171 }
3172
3173 /*-----------------------------------------------------------------*/
3174 /* geniCodeBinary - for a generic binary operation                 */
3175 /*-----------------------------------------------------------------*/
3176 operand *
3177 geniCodeBinary (operand * left, operand * right, int oper)
3178 {
3179   iCode *ic = newiCode (oper, left, right);
3180
3181   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3182   ADDTOCHAIN (ic);
3183   return IC_RESULT (ic);
3184 }
3185
3186 /*-----------------------------------------------------------------*/
3187 /* geniCodeConditional - geniCode for '?' ':' operation            */
3188 /*-----------------------------------------------------------------*/
3189 operand *
3190 geniCodeConditional (ast * tree,int lvl)
3191 {
3192   iCode *ic;
3193   symbol *falseLabel = newiTempLabel (NULL);
3194   symbol *exitLabel = newiTempLabel (NULL);
3195   operand *cond = ast2iCode (tree->left,lvl+1);
3196   operand *true, *false, *result;
3197
3198   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3199                           NULL, falseLabel);
3200   ADDTOCHAIN (ic);
3201
3202   true = ast2iCode (tree->right->left,lvl+1);
3203
3204   /* move the value to a new Operand */
3205   result = newiTempOperand (tree->right->ftype, 0);
3206   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3207
3208   /* generate an unconditional goto */
3209   geniCodeGoto (exitLabel);
3210
3211   /* now for the right side */
3212   geniCodeLabel (falseLabel);
3213
3214   false = ast2iCode (tree->right->right,lvl+1);
3215   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3216
3217   /* create the exit label */
3218   geniCodeLabel (exitLabel);
3219
3220   return result;
3221 }
3222
3223 /*-----------------------------------------------------------------*/
3224 /* geniCodeAssign - generate code for assignment                   */
3225 /*-----------------------------------------------------------------*/
3226 operand *
3227 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3228 {
3229   iCode *ic;
3230   sym_link *ltype = operandType (left);
3231   sym_link *rtype = operandType (right);
3232
3233   if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3234     {
3235       werror (E_LVALUE_REQUIRED, "assignment");
3236       return left;
3237     }
3238
3239   /* left is integral type and right is literal then
3240      check if the literal value is within bounds */
3241   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3242     {
3243       checkConstantRange(ltype,
3244                          OP_VALUE(right), "= operation", 0);
3245     }
3246
3247   /* if the left & right type don't exactly match */
3248   /* if pointer set then make sure the check is
3249      done with the type & not the pointer */
3250   /* then cast rights type to left */
3251
3252   /* first check the type for pointer assignement */
3253   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3254       compareType (ltype, rtype) <= 0)
3255     {
3256       if (compareType (ltype->next, rtype) < 0)
3257         right = geniCodeCast (ltype->next, right, TRUE);
3258     }
3259   else if (compareType (ltype, rtype) < 0)
3260     right = geniCodeCast (ltype, right, TRUE);
3261
3262   /* If left is a true symbol & ! volatile
3263      create an assignment to temporary for
3264      the right & then assign this temporary
3265      to the symbol. This is SSA (static single
3266      assignment). Isn't it simple and folks have
3267      published mountains of paper on it */
3268   if (IS_TRUE_SYMOP (left) &&
3269       !isOperandVolatile (left, FALSE) &&
3270       isOperandGlobal (left))
3271     {
3272       symbol *sym = NULL;
3273
3274       if (IS_TRUE_SYMOP (right))
3275         sym = OP_SYMBOL (right);
3276       ic = newiCode ('=', NULL, right);
3277       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3278       SPIL_LOC (right) = sym;
3279       ADDTOCHAIN (ic);
3280     }
3281
3282   ic = newiCode ('=', NULL, right);
3283   IC_RESULT (ic) = left;
3284   ADDTOCHAIN (ic);
3285
3286   /* if left isgptr flag is set then support
3287      routine will be required */
3288   if (left->isGptr)
3289     ic->supportRtn = 1;
3290
3291   ic->nosupdate = nosupdate;
3292   return left;
3293 }
3294
3295 /*-----------------------------------------------------------------*/
3296 /* geniCodeDummyRead - generate code for dummy read                */
3297 /*-----------------------------------------------------------------*/
3298 static void
3299 geniCodeDummyRead (operand * op)
3300 {
3301   iCode *ic;
3302   sym_link *type = operandType (op);
3303
3304   if (!IS_VOLATILE(type))
3305     return;
3306
3307   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3308   ADDTOCHAIN (ic);
3309
3310   ic->nosupdate = 1;
3311 }
3312
3313 /*-----------------------------------------------------------------*/
3314 /* geniCodeSEParms - generate code for side effecting fcalls       */
3315 /*-----------------------------------------------------------------*/
3316 static void
3317 geniCodeSEParms (ast * parms,int lvl)
3318 {
3319   if (!parms)
3320     return;
3321
3322   if (parms->type == EX_OP && parms->opval.op == PARAM)
3323     {
3324       geniCodeSEParms (parms->left,lvl);
3325       geniCodeSEParms (parms->right,lvl);
3326       return;
3327     }
3328
3329   /* hack don't like this but too lazy to think of
3330      something better */
3331   if (IS_ADDRESS_OF_OP (parms))
3332     parms->left->lvalue = 1;
3333
3334   if (IS_CAST_OP (parms) &&
3335       IS_PTR (parms->ftype) &&
3336       IS_ADDRESS_OF_OP (parms->right))
3337     parms->right->left->lvalue = 1;
3338
3339   parms->opval.oprnd =
3340     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3341
3342   parms->type = EX_OPERAND;
3343   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3344                 SPEC_ARGREG(parms->ftype);
3345 }
3346
3347 /*-----------------------------------------------------------------*/
3348 /* geniCodeParms - generates parameters                            */
3349 /*-----------------------------------------------------------------*/
3350 value *
3351 geniCodeParms (ast * parms, value *argVals, int *stack,
3352                sym_link * ftype, int lvl)
3353 {
3354   iCode *ic;
3355   operand *pval;
3356
3357   if (!parms)
3358     return argVals;
3359
3360   if (argVals==NULL) {
3361     // first argument
3362     argVals = FUNC_ARGS (ftype);
3363   }
3364
3365   /* if this is a param node then do the left & right */
3366   if (parms->type == EX_OP && parms->opval.op == PARAM)
3367     {
3368       argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3369       argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3370       return argVals;
3371     }
3372
3373   /* get the parameter value */
3374   if (parms->type == EX_OPERAND)
3375     pval = parms->opval.oprnd;
3376   else
3377     {
3378       /* maybe this else should go away ?? */
3379       /* hack don't like this but too lazy to think of
3380          something better */
3381       if (IS_ADDRESS_OF_OP (parms))
3382         parms->left->lvalue = 1;
3383
3384       if (IS_CAST_OP (parms) &&
3385           IS_PTR (parms->ftype) &&
3386           IS_ADDRESS_OF_OP (parms->right))
3387         parms->right->left->lvalue = 1;
3388
3389       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3390     }
3391
3392   /* if register parm then make it a send */
3393   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3394       IFFUNC_ISBUILTIN(ftype))
3395     {
3396       ic = newiCode (SEND, pval, NULL);
3397       ic->argreg = SPEC_ARGREG(parms->etype);
3398       ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3399       ADDTOCHAIN (ic);
3400     }
3401   else
3402     {
3403       /* now decide whether to push or assign */
3404       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3405         {
3406
3407           /* assign */
3408           operand *top = operandFromSymbol (argVals->sym);
3409           /* clear useDef and other bitVectors */
3410           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3411           geniCodeAssign (top, pval, 1, 0);
3412         }
3413       else
3414         {
3415           sym_link *p = operandType (pval);
3416           /* push */
3417           ic = newiCode (IPUSH, pval, NULL);
3418           ic->parmPush = 1;
3419           /* update the stack adjustment */
3420           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3421           ADDTOCHAIN (ic);
3422         }
3423     }
3424
3425   argVals=argVals->next;
3426   return argVals;
3427 }
3428
3429 /*-----------------------------------------------------------------*/
3430 /* geniCodeCall - generates temp code for calling                  */
3431 /*-----------------------------------------------------------------*/
3432 operand *
3433 geniCodeCall (operand * left, ast * parms,int lvl)
3434 {
3435   iCode *ic;
3436   operand *result;
3437   sym_link *type, *etype;
3438   sym_link *ftype;
3439   int stack = 0;
3440
3441   if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3442       !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3443     werror (E_FUNCTION_EXPECTED);
3444     return operandFromValue(valueFromLit(0));
3445   }
3446
3447   /* take care of parameters with side-effecting
3448      function calls in them, this is required to take care
3449      of overlaying function parameters */
3450   geniCodeSEParms (parms,lvl);
3451
3452   ftype = operandType (left);
3453   if (IS_FUNCPTR (ftype))
3454     ftype = ftype->next;
3455
3456   /* first the parameters */
3457   geniCodeParms (parms, NULL, &stack, ftype, lvl);
3458
3459   /* now call : if symbol then pcall */
3460   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3461     ic = newiCode (PCALL, left, NULL);
3462   } else {
3463     ic = newiCode (CALL, left, NULL);
3464   }
3465
3466   type = copyLinkChain (ftype->next);
3467   etype = getSpec (type);
3468   SPEC_EXTR (etype) = 0;
3469   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3470
3471   ADDTOCHAIN (ic);
3472
3473   /* stack adjustment after call */
3474   ic->parmBytes = stack;
3475
3476   return result;
3477 }
3478
3479 /*-----------------------------------------------------------------*/
3480 /* geniCodeReceive - generate intermediate code for "receive"      */
3481 /*-----------------------------------------------------------------*/
3482 static void
3483 geniCodeReceive (value * args, operand * func)
3484 {
3485   unsigned char paramByteCounter = 0;
3486
3487   /* for all arguments that are passed in registers */
3488   while (args)
3489     {
3490       if (IS_REGPARM (args->etype))
3491         {
3492           operand *opr = operandFromValue (args);
3493           operand *opl;
3494           symbol *sym = OP_SYMBOL (opr);
3495           iCode *ic;
3496
3497           /* we will use it after all optimizations
3498              and before liveRange calculation */
3499           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3500             {
3501
3502               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3503                   options.stackAuto == 0 &&
3504                   (!(options.model == MODEL_FLAT24)) )
3505                 {
3506                 }
3507               else
3508                 {
3509                   opl = newiTempOperand (args->type, 0);
3510                   sym->reqv = opl;
3511                   sym->reqv->key = sym->key;
3512                   OP_SYMBOL (sym->reqv)->key = sym->key;
3513                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3514                   OP_SYMBOL (sym->reqv)->islocal = 0;
3515                   SPIL_LOC (sym->reqv) = sym;
3516                 }
3517             }
3518
3519           ic = newiCode (RECEIVE, func, NULL);
3520           ic->argreg = SPEC_ARGREG(args->etype);
3521           if (ic->argreg == 1) {
3522               currFunc->recvSize = getSize (sym->type);
3523           }
3524           IC_RESULT (ic) = opr;
3525
3526           /* misuse of parmBytes (normally used for functions)
3527            * to save estimated stack position of this argument.
3528            * Normally this should be zero for RECEIVE iCodes.
3529            * No idea if this causes side effects on other ports. - dw
3530            */
3531           ic->parmBytes = paramByteCounter;
3532
3533           /* what stack position do we have? */
3534           paramByteCounter += getSize (sym->type);
3535
3536           ADDTOCHAIN (ic);
3537         }
3538
3539       args = args->next;
3540     }
3541 }
3542
3543 /*-----------------------------------------------------------------*/
3544 /* geniCodeFunctionBody - create the function body                 */
3545 /*-----------------------------------------------------------------*/
3546 void
3547 geniCodeFunctionBody (ast * tree,int lvl)
3548 {
3549   iCode *ic;
3550   operand *func;
3551   sym_link *fetype;
3552   int savelineno;
3553
3554   /* reset the auto generation */
3555   /* numbers */
3556   iTempNum = 0;
3557   iTempLblNum = 0;
3558   operandKey = 0;
3559   iCodeKey = 0;
3560   func = ast2iCode (tree->left,lvl+1);
3561   fetype = getSpec (operandType (func));
3562
3563   savelineno = lineno;
3564   lineno = OP_SYMBOL (func)->lineDef;
3565   /* create an entry label */
3566   geniCodeLabel (entryLabel);
3567   lineno = savelineno;
3568
3569   /* create a proc icode */
3570   ic = newiCode (FUNCTION, func, NULL);
3571   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3572   ic->tree = tree;
3573
3574   ADDTOCHAIN (ic);
3575
3576   /* for all parameters that are passed
3577      on registers add a "receive" */
3578   geniCodeReceive (tree->values.args, func);
3579
3580   /* generate code for the body */
3581   ast2iCode (tree->right,lvl+1);
3582
3583   /* create a label for return */
3584   geniCodeLabel (returnLabel);
3585
3586   /* now generate the end proc */
3587   ic = newiCode (ENDFUNCTION, func, NULL);
3588   ic->tree = tree;
3589   ADDTOCHAIN (ic);
3590   return;
3591 }
3592
3593 /*-----------------------------------------------------------------*/
3594 /* geniCodeReturn - gen icode for 'return' statement               */
3595 /*-----------------------------------------------------------------*/
3596 void
3597 geniCodeReturn (operand * op)
3598 {
3599   iCode *ic;
3600
3601   /* if the operand is present force an rvalue */
3602   if (op)
3603     op = geniCodeRValue (op, FALSE);
3604
3605   ic = newiCode (RETURN, op, NULL);
3606   ADDTOCHAIN (ic);
3607 }
3608
3609 /*-----------------------------------------------------------------*/
3610 /* geniCodeIfx - generates code for extended if statement          */
3611 /*-----------------------------------------------------------------*/
3612 void
3613 geniCodeIfx (ast * tree,int lvl)
3614 {
3615   iCode *ic;
3616   operand *condition = ast2iCode (tree->left,lvl+1);
3617   sym_link *cetype;
3618
3619   /* if condition is null then exit */
3620   if (!condition)
3621     goto exit;
3622   else
3623     condition = geniCodeRValue (condition, FALSE);
3624
3625   cetype = getSpec (operandType (condition));
3626   /* if the condition is a literal */
3627   if (IS_LITERAL (cetype))
3628     {
3629       if (floatFromVal (condition->operand.valOperand))
3630         {
3631           if (tree->trueLabel)
3632             geniCodeGoto (tree->trueLabel);
3633           else
3634             assert (0);
3635         }
3636       else
3637         {
3638           if (tree->falseLabel)
3639             geniCodeGoto (tree->falseLabel);
3640           else
3641             assert (0);
3642         }
3643       goto exit;
3644     }
3645
3646   if (tree->trueLabel)
3647     {
3648       ic = newiCodeCondition (condition,
3649                               tree->trueLabel,
3650                               NULL);
3651       ADDTOCHAIN (ic);
3652
3653       if (tree->falseLabel)
3654         geniCodeGoto (tree->falseLabel);
3655     }
3656   else
3657     {
3658       ic = newiCodeCondition (condition,
3659                               NULL,
3660                               tree->falseLabel);
3661       ADDTOCHAIN (ic);
3662     }
3663
3664 exit:
3665   ast2iCode (tree->right,lvl+1);
3666 }
3667
3668 /*-----------------------------------------------------------------*/
3669 /* geniCodeJumpTable - tries to create a jump table for switch     */
3670 /*-----------------------------------------------------------------*/
3671 int
3672 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3673 {
3674   int min, max, cnt = 1;
3675   int i, t;
3676   value *vch;
3677   iCode *ic;
3678   operand *boundary;
3679   symbol *falseLabel;
3680   set *labels = NULL;
3681   int needRangeCheck = !optimize.noJTabBoundary
3682                        || tree->values.switchVals.swDefault;
3683   sym_link *cetype = getSpec (operandType (cond));
3684   int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3685   int sizeofMatchJump, sizeofJumpTable;
3686   int sizeIndex;
3687
3688   if (!tree || !caseVals)
3689     return 0;
3690
3691   /* the criteria for creating a jump table is */
3692   /* all integer numbers between the maximum & minimum must */
3693   /* be present , the maximum value should not exceed 255 */
3694   /* If not all integer numbers are present the algorithm */
3695   /* inserts jumps to the default label for the missing numbers */
3696   /* and decides later whether it is worth it */
3697   min = (int) floatFromVal (vch = caseVals);
3698
3699   while (vch->next)
3700     {
3701       cnt++;
3702       vch = vch->next;
3703     }
3704   max = (int) floatFromVal (vch);
3705
3706   /* Exit if the range is too large to handle with a jump table. */
3707   if (1 + max - min > port->jumptableCost.maxCount)
3708     return 0;
3709
3710   switch (getSize (operandType (cond)))
3711     {
3712     case 1: sizeIndex = 0; break;
3713     case 2: sizeIndex = 1; break;
3714     case 4: sizeIndex = 2; break;
3715     default: return 0;
3716     }
3717
3718   /* Compute the size cost of the range check and subtraction. */
3719   sizeofMinCost = 0;
3720   sizeofZeroMinCost = 0;
3721   sizeofMaxCost = 0;
3722   if (needRangeCheck)
3723     {
3724       if (!(min==0 && IS_UNSIGNED (cetype)))
3725         sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3726       if (!IS_UNSIGNED (cetype))
3727         sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3728       sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3729     }
3730   if (min)
3731     sizeofMinCost += port->jumptableCost.sizeofSubtract;
3732
3733   /* If the size cost of handling a non-zero minimum exceeds the */
3734   /* cost of extending the range down to zero, then it might be */
3735   /* better to extend the range to zero. */
3736   if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3737                  >= (min * port->jumptableCost.sizeofElement))
3738     {
3739       /* Only extend the jump table if it would still be manageable. */
3740       if (1 + max <= port->jumptableCost.maxCount)
3741         {
3742           min = 0;
3743           if (IS_UNSIGNED (cetype))
3744             sizeofMinCost = 0;
3745           else
3746             sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3747         }
3748     }
3749
3750   /* Compute the total size cost of a jump table. */
3751   sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3752                      + port->jumptableCost.sizeofDispatch
3753                      + sizeofMinCost + sizeofMaxCost;
3754
3755   /* Compute the total size cost of a match & jump sequence */
3756   sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3757
3758   /* If the size cost of the jump table is uneconomical then exit */
3759   if (sizeofMatchJump <  sizeofJumpTable)
3760     return 0;
3761
3762   /* The jump table is preferable. */
3763
3764   /* First, a label for the default or missing cases. */
3765   if (tree->values.switchVals.swDefault)
3766     {
3767       SNPRINTF (buffer, sizeof(buffer),
3768                 "_default_%d",
3769                 tree->values.switchVals.swNum);
3770     }
3771   else
3772     {
3773       SNPRINTF (buffer, sizeof(buffer),
3774                 "_swBrk_%d",
3775                 tree->values.switchVals.swNum);
3776     }
3777   falseLabel = newiTempLabel (buffer);
3778
3779   /* Build the list of labels for the jump table. */
3780   vch = caseVals;
3781   t = (int) floatFromVal (vch);
3782   for (i=min; i<=max; i++)
3783     {
3784       if (vch && t==i)
3785         {
3786           /* Explicit case: make a new label for it. */
3787           SNPRINTF (buffer, sizeof(buffer),
3788                     "_case_%d_%d",
3789                     tree->values.switchVals.swNum,
3790                     i);
3791           addSet (&labels, newiTempLabel (buffer));
3792           vch = vch->next;
3793           if (vch)
3794             t = (int) floatFromVal (vch);
3795         }
3796       else
3797         {
3798           /* Implicit case: use the default label. */
3799           addSet (&labels, falseLabel);
3800         }
3801     }
3802
3803   /* first we rule out the boundary conditions */
3804   /* if only optimization says so */
3805   if (needRangeCheck)
3806     {
3807       sym_link *cetype = getSpec (operandType (cond));
3808       /* no need to check the lower bound if
3809          the condition is unsigned & minimum value is zero */
3810       if (!(min == 0 && IS_UNSIGNED (cetype)))
3811         {
3812           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3813           ic = newiCodeCondition (boundary, falseLabel, NULL);
3814           ADDTOCHAIN (ic);
3815         }
3816
3817       /* now for upper bounds */
3818       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3819       ic = newiCodeCondition (boundary, falseLabel, NULL);
3820       ADDTOCHAIN (ic);
3821     }
3822
3823   /* if the min is not zero then we no make it zero */
3824   if (min)
3825     {
3826       cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3827       if (!IS_LITERAL(getSpec(operandType(cond))))
3828         setOperandType (cond, UCHARTYPE);
3829     }
3830
3831   /* now create the jumptable */
3832   ic = newiCode (JUMPTABLE, NULL, NULL);
3833   IC_JTCOND (ic) = cond;
3834   IC_JTLABELS (ic) = labels;
3835   ADDTOCHAIN (ic);
3836   return 1;
3837 }
3838
3839 /*-----------------------------------------------------------------*/
3840 /* geniCodeSwitch - changes a switch to a if statement             */
3841 /*-----------------------------------------------------------------*/
3842 void
3843 geniCodeSwitch (ast * tree,int lvl)
3844 {
3845   iCode *ic;
3846   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3847   value *caseVals = tree->values.switchVals.swVals;
3848   symbol *trueLabel, *falseLabel;
3849
3850   /* If the condition is a literal, then just jump to the */
3851   /* appropriate case label. */
3852   if (IS_LITERAL(getSpec(operandType(cond))))
3853     {
3854       int switchVal, caseVal;
3855
3856       switchVal = (int) floatFromVal (cond->operand.valOperand);
3857       while (caseVals)
3858         {
3859           caseVal = (int) floatFromVal (caseVals);
3860           if (caseVal == switchVal)
3861             {
3862               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3863                         tree->values.switchVals.swNum, caseVal);
3864               trueLabel = newiTempLabel (buffer);
3865               geniCodeGoto (trueLabel);
3866               goto jumpTable;
3867             }
3868           caseVals = caseVals->next;
3869         }
3870       goto defaultOrBreak;
3871     }
3872
3873   /* If cond is volatile, it might change while we are trying to */
3874   /* find the matching case. To avoid this possibility, make a   */
3875   /* non-volatile copy to use instead. */
3876   if (IS_OP_VOLATILE (cond))
3877     {
3878       operand * newcond;
3879       iCode * ic;
3880
3881       newcond = newiTempOperand (operandType (cond), TRUE);
3882       newcond->isvolatile = 0;
3883       ic = newiCode ('=', NULL, cond);
3884       IC_RESULT (ic) = newcond;
3885       ADDTOCHAIN (ic);
3886       cond = newcond;
3887     }
3888
3889   /* if we can make this a jump table */
3890   if (geniCodeJumpTable (cond, caseVals, tree))
3891     goto jumpTable;             /* no need for the comparison */
3892
3893   /* for the cases defined do */
3894   while (caseVals)
3895     {
3896
3897       operand *compare = geniCodeLogic (cond,
3898                                         operandFromValue (caseVals),
3899                                         EQ_OP);
3900
3901       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3902                tree->values.switchVals.swNum,
3903                (int) floatFromVal (caseVals));
3904       trueLabel = newiTempLabel (buffer);
3905
3906       ic = newiCodeCondition (compare, trueLabel, NULL);
3907       ADDTOCHAIN (ic);
3908       caseVals = caseVals->next;
3909     }
3910
3911
3912 defaultOrBreak:
3913   /* if default is present then goto break else break */
3914   if (tree->values.switchVals.swDefault)
3915     {
3916         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3917     }
3918   else
3919     {
3920         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3921     }
3922
3923   falseLabel = newiTempLabel (buffer);
3924   geniCodeGoto (falseLabel);
3925
3926 jumpTable:
3927   ast2iCode (tree->right,lvl+1);
3928 }
3929
3930 /*-----------------------------------------------------------------*/
3931 /* geniCodeInline - intermediate code for inline assembler         */
3932 /*-----------------------------------------------------------------*/
3933 static void
3934 geniCodeInline (ast * tree)
3935 {
3936   iCode *ic;
3937
3938   ic = newiCode (INLINEASM, NULL, NULL);
3939   IC_INLINE (ic) = tree->values.inlineasm;
3940   ADDTOCHAIN (ic);
3941 }
3942
3943 /*-----------------------------------------------------------------*/
3944 /* geniCodeArrayInit - intermediate code for array initializer     */
3945 /*-----------------------------------------------------------------*/
3946 static void
3947 geniCodeArrayInit (ast * tree, operand *array)
3948 {
3949   iCode *ic;
3950
3951   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3952     ic = newiCode (ARRAYINIT, array, NULL);
3953     IC_ARRAYILIST (ic) = tree->values.constlist;
3954   } else {
3955     operand *left=newOperand(), *right=newOperand();
3956     left->type=right->type=SYMBOL;
3957     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3958     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3959     ic = newiCode (ARRAYINIT, left, right);
3960   }
3961   ADDTOCHAIN (ic);
3962 }
3963
3964 /*-----------------------------------------------------------------*/
3965 /* geniCodeCritical - intermediate code for a critical statement   */
3966 /*-----------------------------------------------------------------*/
3967 static void
3968 geniCodeCritical (ast *tree, int lvl)
3969 {
3970   iCode *ic;
3971   operand *op = NULL;
3972   sym_link *type;
3973
3974   if (!options.stackAuto)
3975     {
3976       type = newLink(SPECIFIER);
3977       SPEC_VOLATILE(type) = 1;
3978       SPEC_NOUN(type) = V_BIT;
3979       SPEC_SCLS(type) = S_BIT;
3980       SPEC_BLEN(type) = 1;
3981       SPEC_BSTR(type) = 0;
3982       op = newiTempOperand(type, 1);
3983     }
3984
3985   /* If op is NULL, the original interrupt state will saved on */
3986   /* the stack. Otherwise, it will be saved in op. */
3987
3988   /* Generate a save of the current interrupt state & disable */
3989   ic = newiCode (CRITICAL, NULL, NULL);
3990   IC_RESULT (ic) = op;
3991   ADDTOCHAIN (ic);
3992
3993   /* Generate the critical code sequence */
3994   if (tree->left && tree->left->type == EX_VALUE)
3995     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3996   else
3997     ast2iCode (tree->left,lvl+1);
3998
3999   /* Generate a restore of the original interrupt state */
4000   ic = newiCode (ENDCRITICAL, NULL, op);
4001   ADDTOCHAIN (ic);
4002 }
4003
4004 /*-----------------------------------------------------------------*/
4005 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
4006 /* particular case. Ie : assigning or dereferencing array or ptr   */
4007 /*-----------------------------------------------------------------*/
4008 set * lvaluereqSet = NULL;
4009 typedef struct lvalItem
4010   {
4011     int req;
4012     int lvl;
4013   }
4014 lvalItem;
4015
4016 /*-----------------------------------------------------------------*/
4017 /* addLvaluereq - add a flag for lvalreq for current ast level     */
4018 /*-----------------------------------------------------------------*/
4019 void addLvaluereq(int lvl)
4020 {
4021   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4022   lpItem->req=1;
4023   lpItem->lvl=lvl;
4024   addSetHead(&lvaluereqSet,lpItem);
4025
4026 }
4027 /*-----------------------------------------------------------------*/
4028 /* delLvaluereq - del a flag for lvalreq for current ast level     */
4029 /*-----------------------------------------------------------------*/
4030 void delLvaluereq()
4031 {
4032   lvalItem * lpItem;
4033   lpItem = getSet(&lvaluereqSet);
4034   if(lpItem) Safe_free(lpItem);
4035 }
4036 /*-----------------------------------------------------------------*/
4037 /* clearLvaluereq - clear lvalreq flag                             */
4038 /*-----------------------------------------------------------------*/
4039 void clearLvaluereq()
4040 {
4041   lvalItem * lpItem;
4042   lpItem = peekSet(lvaluereqSet);
4043   if(lpItem) lpItem->req = 0;
4044 }
4045 /*-----------------------------------------------------------------*/
4046 /* getLvaluereq - get the last lvalreq level                       */
4047 /*-----------------------------------------------------------------*/
4048 int getLvaluereqLvl()
4049 {
4050   lvalItem * lpItem;
4051   lpItem = peekSet(lvaluereqSet);
4052   if(lpItem) return lpItem->lvl;
4053   return 0;
4054 }
4055 /*-----------------------------------------------------------------*/
4056 /* isLvaluereq - is lvalreq valid for this level ?                 */
4057 /*-----------------------------------------------------------------*/
4058 int isLvaluereq(int lvl)
4059 {
4060   lvalItem * lpItem;
4061   lpItem = peekSet(lvaluereqSet);
4062   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4063   return 0;
4064 }
4065
4066 /*-----------------------------------------------------------------*/
4067 /* ast2iCode - creates an icodeList from an ast                    */
4068 /*-----------------------------------------------------------------*/
4069 operand *
4070 ast2iCode (ast * tree,int lvl)
4071 {
4072   operand *left = NULL;
4073   operand *right = NULL;
4074   if (!tree)
4075     return NULL;
4076
4077   /* set the global variables for filename & line number */
4078   if (tree->filename)
4079     filename = tree->filename;
4080   if (tree->lineno)
4081     lineno = tree->lineno;
4082   if (tree->block)
4083     block = tree->block;
4084   if (tree->level)
4085     scopeLevel = tree->level;
4086   if (tree->seqPoint)
4087     seqPoint = tree->seqPoint;
4088
4089   if (tree->type == EX_VALUE)
4090     return operandFromValue (tree->opval.val);
4091
4092   if (tree->type == EX_LINK)
4093     return operandFromLink (tree->opval.lnk);
4094
4095   /* if we find a nullop */
4096   if (tree->type == EX_OP &&
4097      (tree->opval.op == NULLOP ||
4098      tree->opval.op == BLOCK))
4099     {
4100       if (tree->left && tree->left->type == EX_VALUE)
4101         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4102       else
4103         ast2iCode (tree->left,lvl+1);
4104       if (tree->right && tree->right->type == EX_VALUE)
4105         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4106       else
4107         ast2iCode (tree->right,lvl+1);
4108       return NULL;
4109     }
4110
4111   /* special cases for not evaluating */
4112   if (tree->opval.op != ':' &&
4113       tree->opval.op != '?' &&
4114       tree->opval.op != CALL &&
4115       tree->opval.op != IFX &&
4116       tree->opval.op != AND_OP &&
4117       tree->opval.op != OR_OP &&
4118       tree->opval.op != LABEL &&
4119       tree->opval.op != GOTO &&
4120       tree->opval.op != SWITCH &&
4121       tree->opval.op != FUNCTION &&
4122       tree->opval.op != INLINEASM &&
4123       tree->opval.op != CRITICAL)
4124     {
4125
4126         if (IS_ASSIGN_OP (tree->opval.op) ||
4127            IS_DEREF_OP (tree) ||
4128            (tree->opval.op == '&' && !tree->right) ||
4129            tree->opval.op == PTR_OP)
4130           {
4131             addLvaluereq(lvl);
4132             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4133                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4134               clearLvaluereq();
4135
4136             left = operandFromAst (tree->left,lvl);
4137             delLvaluereq();
4138             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4139               left = geniCodeRValue (left, TRUE);
4140           }
4141         else
4142           {
4143             left = operandFromAst (tree->left,lvl);
4144           }
4145         if (tree->opval.op == INC_OP ||
4146             tree->opval.op == DEC_OP)
4147           {
4148             addLvaluereq(lvl);
4149             right = operandFromAst (tree->right,lvl);
4150             delLvaluereq();
4151           }
4152         else
4153           {
4154             right = operandFromAst (tree->right,lvl);
4155           }
4156       }
4157
4158   /* now depending on the type of operand */
4159   /* this will be a biggy                 */
4160   switch (tree->opval.op)
4161     {
4162
4163     case '[':                   /* array operation */
4164       {
4165         //sym_link *ltype = operandType (left);
4166         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4167         left = geniCodeRValue (left, FALSE);
4168         right = geniCodeRValue (right, TRUE);
4169       }
4170
4171       return geniCodeArray (left, right,lvl);
4172
4173     case '.':                   /* structure dereference */
4174       if (IS_PTR (operandType (left)))
4175         left = geniCodeRValue (left, TRUE);
4176       else
4177         left = geniCodeRValue (left, FALSE);
4178
4179       return geniCodeStruct (left, right, tree->lvalue);
4180
4181     case PTR_OP:                /* structure pointer dereference */
4182       {
4183         sym_link *pType;
4184         pType = operandType (left);
4185         left = geniCodeRValue (left, TRUE);
4186
4187         setOClass (pType, getSpec (operandType (left)));
4188       }
4189
4190       return geniCodeStruct (left, right, tree->lvalue);
4191
4192     case INC_OP:                /* increment operator */
4193       if (left)
4194         return geniCodePostInc (left);
4195       else
4196         return geniCodePreInc (right, tree->lvalue);
4197
4198     case DEC_OP:                /* decrement operator */
4199       if (left)
4200         return geniCodePostDec (left);
4201       else
4202         return geniCodePreDec (right, tree->lvalue);
4203
4204     case '&':                   /* bitwise and or address of operator */
4205       if (right)
4206         {                       /* this is a bitwise operator   */
4207           left = geniCodeRValue (left, FALSE);
4208           right = geniCodeRValue (right, FALSE);
4209           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4210         }
4211       else
4212         return geniCodeAddressOf (left);
4213
4214     case '|':                   /* bitwise or & xor */
4215     case '^':
4216       return geniCodeBitwise (geniCodeRValue (left, FALSE),
4217                               geniCodeRValue (right, FALSE),
4218                               tree->opval.op,
4219                               tree->ftype);
4220
4221     case '/':
4222       return geniCodeDivision (geniCodeRValue (left, FALSE),
4223                                geniCodeRValue (right, FALSE),
4224                                getResultTypeFromType (tree->ftype));
4225
4226     case '%':
4227       return geniCodeModulus (geniCodeRValue (left, FALSE),
4228                               geniCodeRValue (right, FALSE),
4229                               getResultTypeFromType (tree->ftype));
4230     case '*':
4231       if (right)
4232         return geniCodeMultiply (geniCodeRValue (left, FALSE),
4233                                  geniCodeRValue (right, FALSE),
4234                                  getResultTypeFromType (tree->ftype));
4235       else
4236         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4237
4238     case '-':
4239       if (right)
4240         return geniCodeSubtract (geniCodeRValue (left, FALSE),
4241                                  geniCodeRValue (right, FALSE),
4242                                  getResultTypeFromType (tree->ftype));
4243       else
4244         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4245
4246     case '+':
4247       if (right)
4248         return geniCodeAdd (geniCodeRValue (left, FALSE),
4249                             geniCodeRValue (right, FALSE),
4250                             getResultTypeFromType (tree->ftype),
4251                             lvl);
4252       else
4253         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
4254
4255     case LEFT_OP:
4256       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4257                                 geniCodeRValue (right, FALSE),
4258                                 getResultTypeFromType (tree->ftype));
4259
4260     case RIGHT_OP:
4261       return geniCodeRightShift (geniCodeRValue (left, FALSE),
4262                                  geniCodeRValue (right, FALSE));
4263     case CAST:
4264 #if 0 // this indeed needs a second thought
4265       {
4266         operand *op;
4267
4268         // let's keep this simple: get the rvalue we need
4269         op=geniCodeRValue (right, FALSE);
4270         // now cast it to whatever we want
4271         op=geniCodeCast (operandType(left), op, FALSE);
4272         // if this is going to be used as an lvalue, make it so
4273         if (tree->lvalue) {
4274           op->isaddr=1;
4275         }
4276         return op;
4277       }
4278 #else // bug #604575, is it a bug ????
4279       return geniCodeCast (operandType (left),
4280                            geniCodeRValue (right, FALSE), FALSE);
4281 #endif
4282
4283     case '~':
4284     case RRC:
4285     case RLC:
4286     case SWAP:
4287       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4288
4289     case '!':
4290     case GETHBIT:
4291       {
4292         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4293         setOperandType (op, UCHARTYPE);
4294         return op;
4295       }
4296     case GETABIT:
4297     case GETBYTE:
4298     case GETWORD:
4299       {
4300         operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4301                                       geniCodeRValue (right, FALSE),
4302                                       tree->opval.op);
4303         setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4304         return op;
4305       }
4306     case AND_OP:
4307     case OR_OP:
4308       return geniCodeLogicAndOr (tree, lvl);
4309     case '>':
4310     case '<':
4311     case LE_OP:
4312     case GE_OP:
4313     case EQ_OP:
4314     case NE_OP:
4315       /* different compilers (even different gccs) evaluate
4316          the two calls in a different order. to get the same
4317          result on all machines we've to specify a clear sequence.
4318       return geniCodeLogic (geniCodeRValue (left, FALSE),
4319                             geniCodeRValue (right, FALSE),
4320                             tree->opval.op);
4321       */
4322       {
4323         operand *leftOp, *rightOp;
4324
4325         leftOp  = geniCodeRValue (left , FALSE);
4326         rightOp = geniCodeRValue (right, FALSE);
4327
4328         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4329       }
4330     case '?':
4331       return geniCodeConditional (tree,lvl);
4332
4333     case SIZEOF:
4334       return operandFromLit (getSize (tree->right->ftype));
4335
4336     case '=':
4337       {
4338         sym_link *rtype = operandType (right);
4339         sym_link *ltype = operandType (left);
4340         if (IS_PTR (rtype) && IS_ITEMP (right)
4341             && right->isaddr && compareType (rtype->next, ltype) == 1)
4342           right = geniCodeRValue (right, TRUE);
4343         else
4344           right = geniCodeRValue (right, FALSE);
4345
4346         geniCodeAssign (left, right, 0, 1);
4347         return right;
4348       }
4349     case MUL_ASSIGN:
4350       return
4351         geniCodeAssign (left,
4352                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4353                                                   FALSE),
4354                                   geniCodeRValue (right, FALSE),
4355                                   getResultTypeFromType (tree->ftype)),
4356                         0, 1);
4357
4358     case DIV_ASSIGN:
4359       return
4360         geniCodeAssign (left,
4361                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4362                                                   FALSE),
4363                                   geniCodeRValue (right, FALSE),
4364                                   getResultTypeFromType (tree->ftype)),
4365                         0, 1);
4366     case MOD_ASSIGN:
4367       return
4368         geniCodeAssign (left,
4369                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4370                                                   FALSE),
4371                                   geniCodeRValue (right, FALSE),
4372                                   getResultTypeFromType (tree->ftype)),
4373                         0, 1);
4374     case ADD_ASSIGN:
4375       {
4376         sym_link *rtype = operandType (right);
4377         sym_link *ltype = operandType (left);
4378         if (IS_PTR (rtype) && IS_ITEMP (right)
4379             && right->isaddr && compareType (rtype->next, ltype) == 1)
4380           right = geniCodeRValue (right, TRUE);
4381         else
4382           right = geniCodeRValue (right, FALSE);
4383
4384
4385         return geniCodeAssign (left,
4386                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4387                                                   FALSE),
4388                                   right,
4389                                   getResultTypeFromType (tree->ftype),
4390                                   lvl),
4391                                0, 1);
4392       }
4393     case SUB_ASSIGN:
4394       {
4395         sym_link *rtype = operandType (right);
4396         sym_link *ltype = operandType (left);
4397         if (IS_PTR (rtype) && IS_ITEMP (right)
4398             && right->isaddr && compareType (rtype->next, ltype) == 1)
4399           {
4400             right = geniCodeRValue (right, TRUE);
4401           }
4402         else
4403           {
4404             right = geniCodeRValue (right, FALSE);
4405           }
4406         return
4407           geniCodeAssign (left,
4408                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4409                                                   FALSE),
4410                                   right,
4411                                   getResultTypeFromType (tree->ftype)),
4412                           0, 1);
4413       }
4414     case LEFT_ASSIGN:
4415       return
4416         geniCodeAssign (left,
4417                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4418                                                    ,FALSE),
4419                                    geniCodeRValue (right, FALSE),
4420                                    getResultTypeFromType (tree->ftype)),
4421                         0, 1);
4422     case RIGHT_ASSIGN:
4423       return
4424         geniCodeAssign (left,
4425                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4426                                                    ,FALSE),
4427                                    geniCodeRValue (right, FALSE)), 0, 1);
4428     case AND_ASSIGN:
4429       return
4430         geniCodeAssign (left,
4431                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4432                                                   FALSE),
4433                                   geniCodeRValue (right, FALSE),
4434                                   BITWISEAND,
4435                                   operandType (left)), 0, 1);
4436     case XOR_ASSIGN:
4437       return
4438         geniCodeAssign (left,
4439                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4440                                                   FALSE),
4441                                   geniCodeRValue (right, FALSE),
4442                                   '^',
4443                                   operandType (left)), 0, 1);
4444     case OR_ASSIGN:
4445       return
4446         geniCodeAssign (left,
4447                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4448                                                    ,FALSE),
4449                                    geniCodeRValue (right, FALSE),
4450                                    '|',
4451                                    operandType (left)), 0, 1);
4452     case ',':
4453       return geniCodeRValue (right, FALSE);
4454
4455     case CALL:
4456       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4457                            tree->right,lvl);
4458     case LABEL:
4459       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4460       return ast2iCode (tree->right,lvl+1);
4461
4462     case GOTO:
4463       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4464       return ast2iCode (tree->right,lvl+1);
4465
4466     case FUNCTION:
4467       geniCodeFunctionBody (tree,lvl);
4468       return NULL;
4469
4470     case RETURN:
4471       geniCodeReturn (right);
4472       return NULL;
4473
4474     case IFX:
4475       geniCodeIfx (tree,lvl);
4476       return NULL;
4477
4478     case SWITCH:
4479       geniCodeSwitch (tree,lvl);
4480       return NULL;
4481
4482     case INLINEASM:
4483       geniCodeInline (tree);
4484       return NULL;
4485
4486     case ARRAYINIT:
4487         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4488         return NULL;
4489
4490     case CRITICAL:
4491         geniCodeCritical (tree, lvl);
4492     }
4493
4494   return NULL;
4495 }
4496
4497 /*-----------------------------------------------------------------*/
4498 /* reverseICChain - gets from the list and creates a linkedlist    */
4499 /*-----------------------------------------------------------------*/
4500 iCode *
4501 reverseiCChain ()
4502 {
4503   iCode *loop = NULL;
4504   iCode *prev = NULL;
4505
4506   while ((loop = getSet (&iCodeChain)))
4507     {
4508       loop->next = prev;
4509       if (prev)
4510         prev->prev = loop;
4511       prev = loop;
4512     }
4513
4514   return prev;
4515 }
4516
4517
4518 /*-----------------------------------------------------------------*/
4519 /* iCodeFromAst - given an ast will convert it to iCode            */
4520 /*-----------------------------------------------------------------*/
4521 iCode *
4522 iCodeFromAst (ast * tree)
4523 {
4524   returnLabel = newiTempLabel ("_return");
4525   entryLabel = newiTempLabel ("_entry");
4526   ast2iCode (tree,0);
4527   return reverseiCChain ();
4528 }
4529
4530 static const char *opTypeToStr(OPTYPE op)
4531 {
4532     switch(op)
4533     {
4534       case SYMBOL: return "symbol";
4535       case VALUE: return "value";
4536       case TYPE: return "type";
4537     }
4538     return "undefined type";
4539 }
4540
4541
4542 operand *validateOpType(operand         *op,
4543                         const char      *macro,
4544                         const char      *args,
4545                         OPTYPE          type,
4546                         const char      *file,
4547                         unsigned        line)
4548 {
4549     if (op && op->type == type)
4550     {
4551         return op;
4552     }
4553     fprintf(stderr,
4554             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4555             " expected %s, got %s\n",
4556             macro, args, file, line,
4557             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4558     exit(-1);
4559     return op; // never reached, makes compiler happy.
4560 }