* device/lib/medium/Makefile: added for new memory model medium
[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 > 0) && !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))) > 0)) {
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 /*-----------------------------------------------------------------*/
2866 /* setOClass - sets the output class depending on the pointer type */
2867 /*-----------------------------------------------------------------*/
2868 void
2869 setOClass (sym_link * ptr, sym_link * spec)
2870 {
2871   switch (DCL_TYPE (ptr))
2872     {
2873     case POINTER:
2874       SPEC_OCLS (spec) = data;
2875       break;
2876
2877     case GPOINTER:
2878       SPEC_OCLS (spec) = generic;
2879       break;
2880
2881     case FPOINTER:
2882       SPEC_OCLS (spec) = xdata;
2883       break;
2884
2885     case CPOINTER:
2886       SPEC_OCLS (spec) = code;
2887       break;
2888
2889     case IPOINTER:
2890       SPEC_OCLS (spec) = idata;
2891       break;
2892
2893     case PPOINTER:
2894       SPEC_OCLS (spec) = xstack;
2895       break;
2896
2897     case EEPPOINTER:
2898       SPEC_OCLS (spec) = eeprom;
2899       break;
2900
2901     default:
2902       break;
2903
2904     }
2905 }
2906
2907 /*-----------------------------------------------------------------*/
2908 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2909 /*-----------------------------------------------------------------*/
2910 operand *
2911 geniCodeDerefPtr (operand * op,int lvl)
2912 {
2913   sym_link *rtype, *retype;
2914   sym_link *optype = operandType (op);
2915
2916   // if this is an array then array access
2917   if (IS_ARRAY (optype)) {
2918     // don't worry, this will be optimized out later
2919     return geniCodeArray (op, operandFromLit (0), lvl);
2920   }
2921
2922   // just in case someone screws up
2923   wassert (IS_PTR (optype));
2924
2925   if (IS_TRUE_SYMOP (op))
2926     {
2927       op->isaddr = 1;
2928       op = geniCodeRValue (op, TRUE);
2929     }
2930
2931   /* now get rid of the pointer part */
2932   if (isLvaluereq(lvl) && IS_ITEMP (op))
2933     {
2934       retype = getSpec (rtype = copyLinkChain (optype));
2935     }
2936   else
2937     {
2938       retype = getSpec (rtype = copyLinkChain (optype->next));
2939       /* outputclass needs 2b updated */
2940       setOClass (optype, retype);
2941     }
2942
2943   op->isGptr = IS_GENPTR (optype);
2944
2945   op->isaddr = (IS_PTR (rtype) ||
2946                 IS_STRUCT (rtype) ||
2947                 IS_INT (rtype) ||
2948                 IS_CHAR (rtype) ||
2949                 IS_FLOAT (rtype) ||
2950                 IS_FIXED (rtype));
2951
2952   if (!isLvaluereq(lvl))
2953     op = geniCodeRValue (op, TRUE);
2954
2955   setOperandType (op, rtype);
2956
2957   return op;
2958 }
2959
2960 /*-----------------------------------------------------------------*/
2961 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2962 /*-----------------------------------------------------------------*/
2963 operand *
2964 geniCodeUnaryMinus (operand * op)
2965 {
2966   iCode *ic;
2967   sym_link *optype = operandType (op);
2968
2969   if (IS_LITERAL (optype))
2970     return operandFromLit (-floatFromVal (op->operand.valOperand));
2971
2972   ic = newiCode (UNARYMINUS, op, NULL);
2973   IC_RESULT (ic) = newiTempOperand (optype, 0);
2974   ADDTOCHAIN (ic);
2975   return IC_RESULT (ic);
2976 }
2977
2978 /*-----------------------------------------------------------------*/
2979 /* geniCodeLeftShift - gen i code for left shift                   */
2980 /*-----------------------------------------------------------------*/
2981 operand *
2982 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2983 {
2984   iCode *ic;
2985   sym_link *resType;
2986
2987   ic = newiCode (LEFT_OP, left, right);
2988
2989   resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2990   IC_RESULT (ic) = newiTempOperand (resType, 0);
2991   ADDTOCHAIN (ic);
2992   return IC_RESULT (ic);
2993 }
2994
2995 /*-----------------------------------------------------------------*/
2996 /* geniCodeRightShift - gen i code for right shift                 */
2997 /*-----------------------------------------------------------------*/
2998 operand *
2999 geniCodeRightShift (operand * left, operand * right)
3000 {
3001   iCode *ic;
3002
3003   ic = newiCode (RIGHT_OP, left, right);
3004   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3005   ADDTOCHAIN (ic);
3006   return IC_RESULT (ic);
3007 }
3008
3009 /*-----------------------------------------------------------------*/
3010 /* geniCodeLogic- logic code                                       */
3011 /*-----------------------------------------------------------------*/
3012 static operand *
3013 geniCodeLogic (operand * left, operand * right, int op)
3014 {
3015   iCode *ic;
3016   sym_link *ctype;
3017   sym_link *rtype = operandType (right);
3018   sym_link *ltype = operandType (left);
3019
3020   /* left is integral type and right is literal then
3021      check if the literal value is within bounds */
3022   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3023     {
3024       checkConstantRange(ltype,
3025                          OP_VALUE(right), "compare operation", 1);
3026     }
3027
3028   /* if one operand is a pointer and the other is a literal generic void pointer,
3029      change the type of the literal generic void pointer to match the other pointer */
3030   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3031       && IS_PTR (rtype) && !IS_GENPTR(rtype))
3032     {
3033       /* find left's definition */
3034       ic = (iCode *) setFirstItem (iCodeChain);
3035       while (ic)
3036         {
3037           if (((ic->op == CAST) || (ic->op == '='))
3038               && isOperandEqual(left, IC_RESULT (ic)))
3039             break;
3040           else
3041             ic = setNextItem (iCodeChain);
3042         }
3043       /* if casting literal to generic pointer, then cast to rtype instead */
3044       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3045         {
3046           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3047           ltype = operandType(left);
3048         }
3049     }
3050   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3051       && IS_PTR (ltype) && !IS_GENPTR(ltype))
3052     {
3053       /* find right's definition */
3054       ic = (iCode *) setFirstItem (iCodeChain);
3055       while (ic)
3056         {
3057           if (((ic->op == CAST) || (ic->op == '='))
3058               && isOperandEqual(right, IC_RESULT (ic)))
3059             break;
3060           else
3061             ic = setNextItem (iCodeChain);
3062         }
3063       /* if casting literal to generic pointer, then cast to rtype instead */
3064       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3065         {
3066           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3067           rtype = operandType(right);
3068         }
3069     }
3070
3071   ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3072
3073   ic = newiCode (op, left, right);
3074   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3075
3076   /* if comparing float
3077      and not a '==' || '!=' || '&&' || '||' (these
3078      will be inlined */
3079   if (IS_FLOAT(ctype) &&
3080       op != EQ_OP &&
3081       op != NE_OP &&
3082       op != AND_OP &&
3083       op != OR_OP)
3084    ic->supportRtn = 1;
3085
3086   /* if comparing a fixed type use support functions */
3087   if (IS_FIXED(ctype))
3088     ic->supportRtn = 1;
3089
3090   ADDTOCHAIN (ic);
3091   return IC_RESULT (ic);
3092 }
3093
3094 /*-----------------------------------------------------------------*/
3095 /* geniCodeLogicAndOr - && || operations                           */
3096 /*-----------------------------------------------------------------*/
3097 static operand *
3098 geniCodeLogicAndOr (ast *tree, int lvl)
3099 {
3100   iCode *ic;
3101   sym_link *type;
3102   symbol *falseLabel = newiTempLabel (NULL);
3103   symbol *trueLabel  = newiTempLabel (NULL);
3104   symbol *exitLabel  = newiTempLabel (NULL);
3105   operand *op, *result, *condition;
3106
3107   /* AND_OP and OR_OP are no longer generated because of bug-905492.
3108      They can be reenabled by executing the following block. If you find
3109      a decent optimization you could start right here:
3110   */
3111 #if 0
3112   if (0)
3113     {
3114        operand *leftOp, *rightOp;
3115
3116        leftOp  = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3117        rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3118
3119        return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3120     }
3121 #endif
3122
3123   /* generate two IFX for the '&&' or '||' op */
3124
3125   /* evaluate left operand */
3126   condition = ast2iCode (tree->left, lvl + 1);
3127   op = geniCodeRValue (condition, FALSE);
3128
3129   /* test left operand */
3130   if (tree->opval.op == AND_OP)
3131     ic = newiCodeCondition (op, NULL, falseLabel);
3132   else /* OR_OP */
3133     ic = newiCodeCondition (op, trueLabel, NULL);
3134   ADDTOCHAIN (ic);
3135
3136   /* evaluate right operand */
3137   condition = ast2iCode (tree->right, lvl + 1);
3138   op = geniCodeRValue (condition, FALSE);
3139
3140   /* test right operand */
3141   ic = newiCodeCondition (op, trueLabel, NULL);
3142   ADDTOCHAIN (ic);
3143
3144   /* store 0 or 1 in result */
3145   type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3146   result = newiTempOperand (type, 1);
3147
3148   geniCodeLabel (falseLabel);
3149   geniCodeAssign (result, operandFromLit (0), 0, 0);
3150   /* generate an unconditional goto */
3151   geniCodeGoto (exitLabel);
3152
3153   geniCodeLabel (trueLabel);
3154   geniCodeAssign (result, operandFromLit (1), 0, 0);
3155
3156   geniCodeLabel (exitLabel);
3157
3158   return result;
3159 }
3160
3161 /*-----------------------------------------------------------------*/
3162 /* geniCodeUnary - for a generic unary operation                   */
3163 /*-----------------------------------------------------------------*/
3164 operand *
3165 geniCodeUnary (operand * op, int oper)
3166 {
3167   iCode *ic = newiCode (oper, op, NULL);
3168
3169   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3170   ADDTOCHAIN (ic);
3171   return IC_RESULT (ic);
3172 }
3173
3174 /*-----------------------------------------------------------------*/
3175 /* geniCodeBinary - for a generic binary operation                 */
3176 /*-----------------------------------------------------------------*/
3177 operand *
3178 geniCodeBinary (operand * left, operand * right, int oper)
3179 {
3180   iCode *ic = newiCode (oper, left, right);
3181
3182   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3183   ADDTOCHAIN (ic);
3184   return IC_RESULT (ic);
3185 }
3186
3187 /*-----------------------------------------------------------------*/
3188 /* geniCodeConditional - geniCode for '?' ':' operation            */
3189 /*-----------------------------------------------------------------*/
3190 operand *
3191 geniCodeConditional (ast * tree,int lvl)
3192 {
3193   iCode *ic;
3194   symbol *falseLabel = newiTempLabel (NULL);
3195   symbol *exitLabel = newiTempLabel (NULL);
3196   operand *cond = ast2iCode (tree->left,lvl+1);
3197   operand *true, *false, *result;
3198
3199   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3200                           NULL, falseLabel);
3201   ADDTOCHAIN (ic);
3202
3203   true = ast2iCode (tree->right->left,lvl+1);
3204
3205   /* move the value to a new Operand */
3206   result = newiTempOperand (tree->right->ftype, 0);
3207   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3208
3209   /* generate an unconditional goto */
3210   geniCodeGoto (exitLabel);
3211
3212   /* now for the right side */
3213   geniCodeLabel (falseLabel);
3214
3215   false = ast2iCode (tree->right->right,lvl+1);
3216   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3217
3218   /* create the exit label */
3219   geniCodeLabel (exitLabel);
3220
3221   return result;
3222 }
3223
3224 /*-----------------------------------------------------------------*/
3225 /* geniCodeAssign - generate code for assignment                   */
3226 /*-----------------------------------------------------------------*/
3227 operand *
3228 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3229 {
3230   iCode *ic;
3231   sym_link *ltype = operandType (left);
3232   sym_link *rtype = operandType (right);
3233
3234   if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3235     {
3236       werror (E_LVALUE_REQUIRED, "assignment");
3237       return left;
3238     }
3239
3240   /* left is integral type and right is literal then
3241      check if the literal value is within bounds */
3242   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3243     {
3244       checkConstantRange(ltype,
3245                          OP_VALUE(right), "= operation", 0);
3246     }
3247
3248   /* if the left & right type don't exactly match */
3249   /* if pointer set then make sure the check is
3250      done with the type & not the pointer */
3251   /* then cast rights type to left */
3252
3253   /* first check the type for pointer assignement */
3254   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3255       compareType (ltype, rtype) <= 0)
3256     {
3257       if (compareType (ltype->next, rtype) < 0)
3258         right = geniCodeCast (ltype->next, right, TRUE);
3259     }
3260   else if (compareType (ltype, rtype) < 0)
3261     right = geniCodeCast (ltype, right, TRUE);
3262
3263   /* If left is a true symbol & ! volatile
3264      create an assignment to temporary for
3265      the right & then assign this temporary
3266      to the symbol. This is SSA (static single
3267      assignment). Isn't it simple and folks have
3268      published mountains of paper on it */
3269   if (IS_TRUE_SYMOP (left) &&
3270       !isOperandVolatile (left, FALSE) &&
3271       isOperandGlobal (left))
3272     {
3273       symbol *sym = NULL;
3274
3275       if (IS_TRUE_SYMOP (right))
3276         sym = OP_SYMBOL (right);
3277       ic = newiCode ('=', NULL, right);
3278       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3279       SPIL_LOC (right) = sym;
3280       ADDTOCHAIN (ic);
3281     }
3282
3283   ic = newiCode ('=', NULL, right);
3284   IC_RESULT (ic) = left;
3285   ADDTOCHAIN (ic);
3286
3287   /* if left isgptr flag is set then support
3288      routine will be required */
3289   if (left->isGptr)
3290     ic->supportRtn = 1;
3291
3292   ic->nosupdate = nosupdate;
3293   return left;
3294 }
3295
3296 /*-----------------------------------------------------------------*/
3297 /* geniCodeDummyRead - generate code for dummy read                */
3298 /*-----------------------------------------------------------------*/
3299 static void
3300 geniCodeDummyRead (operand * op)
3301 {
3302   iCode *ic;
3303   sym_link *type = operandType (op);
3304
3305   if (!IS_VOLATILE(type))
3306     return;
3307
3308   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3309   ADDTOCHAIN (ic);
3310
3311   ic->nosupdate = 1;
3312 }
3313
3314 /*-----------------------------------------------------------------*/
3315 /* geniCodeSEParms - generate code for side effecting fcalls       */
3316 /*-----------------------------------------------------------------*/
3317 static void
3318 geniCodeSEParms (ast * parms,int lvl)
3319 {
3320   if (!parms)
3321     return;
3322
3323   if (parms->type == EX_OP && parms->opval.op == PARAM)
3324     {
3325       geniCodeSEParms (parms->left,lvl);
3326       geniCodeSEParms (parms->right,lvl);
3327       return;
3328     }
3329
3330   /* hack don't like this but too lazy to think of
3331      something better */
3332   if (IS_ADDRESS_OF_OP (parms))
3333     parms->left->lvalue = 1;
3334
3335   if (IS_CAST_OP (parms) &&
3336       IS_PTR (parms->ftype) &&
3337       IS_ADDRESS_OF_OP (parms->right))
3338     parms->right->left->lvalue = 1;
3339
3340   parms->opval.oprnd =
3341     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3342
3343   parms->type = EX_OPERAND;
3344   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3345                 SPEC_ARGREG(parms->ftype);
3346 }
3347
3348 /*-----------------------------------------------------------------*/
3349 /* geniCodeParms - generates parameters                            */
3350 /*-----------------------------------------------------------------*/
3351 value *
3352 geniCodeParms (ast * parms, value *argVals, int *stack,
3353                sym_link * ftype, int lvl)
3354 {
3355   iCode *ic;
3356   operand *pval;
3357
3358   if (!parms)
3359     return argVals;
3360
3361   if (argVals==NULL) {
3362     // first argument
3363     argVals = FUNC_ARGS (ftype);
3364   }
3365
3366   /* if this is a param node then do the left & right */
3367   if (parms->type == EX_OP && parms->opval.op == PARAM)
3368     {
3369       argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3370       argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3371       return argVals;
3372     }
3373
3374   /* get the parameter value */
3375   if (parms->type == EX_OPERAND)
3376     pval = parms->opval.oprnd;
3377   else
3378     {
3379       /* maybe this else should go away ?? */
3380       /* hack don't like this but too lazy to think of
3381          something better */
3382       if (IS_ADDRESS_OF_OP (parms))
3383         parms->left->lvalue = 1;
3384
3385       if (IS_CAST_OP (parms) &&
3386           IS_PTR (parms->ftype) &&
3387           IS_ADDRESS_OF_OP (parms->right))
3388         parms->right->left->lvalue = 1;
3389
3390       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3391     }
3392
3393   /* if register parm then make it a send */
3394   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3395       IFFUNC_ISBUILTIN(ftype))
3396     {
3397       ic = newiCode (SEND, pval, NULL);
3398       ic->argreg = SPEC_ARGREG(parms->etype);
3399       ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3400       ADDTOCHAIN (ic);
3401     }
3402   else
3403     {
3404       /* now decide whether to push or assign */
3405       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3406         {
3407
3408           /* assign */
3409           operand *top = operandFromSymbol (argVals->sym);
3410           /* clear useDef and other bitVectors */
3411           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3412           geniCodeAssign (top, pval, 1, 0);
3413         }
3414       else
3415         {
3416           sym_link *p = operandType (pval);
3417           /* push */
3418           ic = newiCode (IPUSH, pval, NULL);
3419           ic->parmPush = 1;
3420           /* update the stack adjustment */
3421           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3422           ADDTOCHAIN (ic);
3423         }
3424     }
3425
3426   argVals=argVals->next;
3427   return argVals;
3428 }
3429
3430 /*-----------------------------------------------------------------*/
3431 /* geniCodeCall - generates temp code for calling                  */
3432 /*-----------------------------------------------------------------*/
3433 operand *
3434 geniCodeCall (operand * left, ast * parms,int lvl)
3435 {
3436   iCode *ic;
3437   operand *result;
3438   sym_link *type, *etype;
3439   sym_link *ftype;
3440   int stack = 0;
3441
3442   if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3443       !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3444     werror (E_FUNCTION_EXPECTED);
3445     return operandFromValue(valueFromLit(0));
3446   }
3447
3448   /* take care of parameters with side-effecting
3449      function calls in them, this is required to take care
3450      of overlaying function parameters */
3451   geniCodeSEParms (parms,lvl);
3452
3453   ftype = operandType (left);
3454   if (IS_FUNCPTR (ftype))
3455     ftype = ftype->next;
3456
3457   /* first the parameters */
3458   geniCodeParms (parms, NULL, &stack, ftype, lvl);
3459
3460   /* now call : if symbol then pcall */
3461   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3462     ic = newiCode (PCALL, left, NULL);
3463   } else {
3464     ic = newiCode (CALL, left, NULL);
3465   }
3466
3467   type = copyLinkChain (ftype->next);
3468   etype = getSpec (type);
3469   SPEC_EXTR (etype) = 0;
3470   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3471
3472   ADDTOCHAIN (ic);
3473
3474   /* stack adjustment after call */
3475   ic->parmBytes = stack;
3476
3477   return result;
3478 }
3479
3480 /*-----------------------------------------------------------------*/
3481 /* geniCodeReceive - generate intermediate code for "receive"      */
3482 /*-----------------------------------------------------------------*/
3483 static void
3484 geniCodeReceive (value * args, operand * func)
3485 {
3486   unsigned char paramByteCounter = 0;
3487
3488   /* for all arguments that are passed in registers */
3489   while (args)
3490     {
3491       if (IS_REGPARM (args->etype))
3492         {
3493           operand *opr = operandFromValue (args);
3494           operand *opl;
3495           symbol *sym = OP_SYMBOL (opr);
3496           iCode *ic;
3497
3498           /* we will use it after all optimizations
3499              and before liveRange calculation */
3500           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3501             {
3502
3503               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3504                   options.stackAuto == 0 &&
3505                   (!(options.model == MODEL_FLAT24)) )
3506                 {
3507                 }
3508               else
3509                 {
3510                   opl = newiTempOperand (args->type, 0);
3511                   sym->reqv = opl;
3512                   sym->reqv->key = sym->key;
3513                   OP_SYMBOL (sym->reqv)->key = sym->key;
3514                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3515                   OP_SYMBOL (sym->reqv)->islocal = 0;
3516                   SPIL_LOC (sym->reqv) = sym;
3517                 }
3518             }
3519
3520           ic = newiCode (RECEIVE, func, NULL);
3521           ic->argreg = SPEC_ARGREG(args->etype);
3522           if (ic->argreg == 1) {
3523               currFunc->recvSize = getSize (sym->type);
3524           }
3525           IC_RESULT (ic) = opr;
3526
3527           /* misuse of parmBytes (normally used for functions)
3528            * to save estimated stack position of this argument.
3529            * Normally this should be zero for RECEIVE iCodes.
3530            * No idea if this causes side effects on other ports. - dw
3531            */
3532           ic->parmBytes = paramByteCounter;
3533
3534           /* what stack position do we have? */
3535           paramByteCounter += getSize (sym->type);
3536
3537           ADDTOCHAIN (ic);
3538         }
3539
3540       args = args->next;
3541     }
3542 }
3543
3544 /*-----------------------------------------------------------------*/
3545 /* geniCodeFunctionBody - create the function body                 */
3546 /*-----------------------------------------------------------------*/
3547 void
3548 geniCodeFunctionBody (ast * tree,int lvl)
3549 {
3550   iCode *ic;
3551   operand *func;
3552   sym_link *fetype;
3553   int savelineno;
3554
3555   /* reset the auto generation */
3556   /* numbers */
3557   iTempNum = 0;
3558   iTempLblNum = 0;
3559   operandKey = 0;
3560   iCodeKey = 0;
3561   func = ast2iCode (tree->left,lvl+1);
3562   fetype = getSpec (operandType (func));
3563
3564   savelineno = lineno;
3565   lineno = OP_SYMBOL (func)->lineDef;
3566   /* create an entry label */
3567   geniCodeLabel (entryLabel);
3568   lineno = savelineno;
3569
3570   /* create a proc icode */
3571   ic = newiCode (FUNCTION, func, NULL);
3572   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3573   ic->tree = tree;
3574
3575   ADDTOCHAIN (ic);
3576
3577   /* for all parameters that are passed
3578      on registers add a "receive" */
3579   geniCodeReceive (tree->values.args, func);
3580
3581   /* generate code for the body */
3582   ast2iCode (tree->right,lvl+1);
3583
3584   /* create a label for return */
3585   geniCodeLabel (returnLabel);
3586
3587   /* now generate the end proc */
3588   ic = newiCode (ENDFUNCTION, func, NULL);
3589   ic->tree = tree;
3590   ADDTOCHAIN (ic);
3591   return;
3592 }
3593
3594 /*-----------------------------------------------------------------*/
3595 /* geniCodeReturn - gen icode for 'return' statement               */
3596 /*-----------------------------------------------------------------*/
3597 void
3598 geniCodeReturn (operand * op)
3599 {
3600   iCode *ic;
3601
3602   /* if the operand is present force an rvalue */
3603   if (op)
3604     op = geniCodeRValue (op, FALSE);
3605
3606   ic = newiCode (RETURN, op, NULL);
3607   ADDTOCHAIN (ic);
3608 }
3609
3610 /*-----------------------------------------------------------------*/
3611 /* geniCodeIfx - generates code for extended if statement          */
3612 /*-----------------------------------------------------------------*/
3613 void
3614 geniCodeIfx (ast * tree,int lvl)
3615 {
3616   iCode *ic;
3617   operand *condition = ast2iCode (tree->left,lvl+1);
3618   sym_link *cetype;
3619
3620   /* if condition is null then exit */
3621   if (!condition)
3622     goto exit;
3623   else
3624     condition = geniCodeRValue (condition, FALSE);
3625
3626   cetype = getSpec (operandType (condition));
3627   /* if the condition is a literal */
3628   if (IS_LITERAL (cetype))
3629     {
3630       if (floatFromVal (condition->operand.valOperand))
3631         {
3632           if (tree->trueLabel)
3633             geniCodeGoto (tree->trueLabel);
3634           else
3635             assert (0);
3636         }
3637       else
3638         {
3639           if (tree->falseLabel)
3640             geniCodeGoto (tree->falseLabel);
3641           else
3642             assert (0);
3643         }
3644       goto exit;
3645     }
3646
3647   if (tree->trueLabel)
3648     {
3649       ic = newiCodeCondition (condition,
3650                               tree->trueLabel,
3651                               NULL);
3652       ADDTOCHAIN (ic);
3653
3654       if (tree->falseLabel)
3655         geniCodeGoto (tree->falseLabel);
3656     }
3657   else
3658     {
3659       ic = newiCodeCondition (condition,
3660                               NULL,
3661                               tree->falseLabel);
3662       ADDTOCHAIN (ic);
3663     }
3664
3665 exit:
3666   ast2iCode (tree->right,lvl+1);
3667 }
3668
3669 /*-----------------------------------------------------------------*/
3670 /* geniCodeJumpTable - tries to create a jump table for switch     */
3671 /*-----------------------------------------------------------------*/
3672 int
3673 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3674 {
3675   int min, max, cnt = 1;
3676   int i, t;
3677   value *vch;
3678   iCode *ic;
3679   operand *boundary;
3680   symbol *falseLabel;
3681   set *labels = NULL;
3682   int needRangeCheck = !optimize.noJTabBoundary
3683                        || tree->values.switchVals.swDefault;
3684   sym_link *cetype = getSpec (operandType (cond));
3685   int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3686   int sizeofMatchJump, sizeofJumpTable;
3687   int sizeIndex;
3688
3689   if (!tree || !caseVals)
3690     return 0;
3691
3692   /* the criteria for creating a jump table is */
3693   /* all integer numbers between the maximum & minimum must */
3694   /* be present , the maximum value should not exceed 255 */
3695   /* If not all integer numbers are present the algorithm */
3696   /* inserts jumps to the default label for the missing numbers */
3697   /* and decides later whether it is worth it */
3698   min = (int) floatFromVal (vch = caseVals);
3699
3700   while (vch->next)
3701     {
3702       cnt++;
3703       vch = vch->next;
3704     }
3705   max = (int) floatFromVal (vch);
3706
3707   /* Exit if the range is too large to handle with a jump table. */
3708   if (1 + max - min > port->jumptableCost.maxCount)
3709     return 0;
3710
3711   switch (getSize (operandType (cond)))
3712     {
3713     case 1: sizeIndex = 0; break;
3714     case 2: sizeIndex = 1; break;
3715     case 4: sizeIndex = 2; break;
3716     default: return 0;
3717     }
3718
3719   /* Compute the size cost of the range check and subtraction. */
3720   sizeofMinCost = 0;
3721   sizeofZeroMinCost = 0;
3722   sizeofMaxCost = 0;
3723   if (needRangeCheck)
3724     {
3725       if (!(min==0 && IS_UNSIGNED (cetype)))
3726         sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3727       if (!IS_UNSIGNED (cetype))
3728         sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3729       sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3730     }
3731   if (min)
3732     sizeofMinCost += port->jumptableCost.sizeofSubtract;
3733
3734   /* If the size cost of handling a non-zero minimum exceeds the */
3735   /* cost of extending the range down to zero, then it might be */
3736   /* better to extend the range to zero. */
3737   if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3738                  >= (min * port->jumptableCost.sizeofElement))
3739     {
3740       /* Only extend the jump table if it would still be manageable. */
3741       if (1 + max <= port->jumptableCost.maxCount)
3742         {
3743           min = 0;
3744           if (IS_UNSIGNED (cetype))
3745             sizeofMinCost = 0;
3746           else
3747             sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3748         }
3749     }
3750
3751   /* Compute the total size cost of a jump table. */
3752   sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3753                      + port->jumptableCost.sizeofDispatch
3754                      + sizeofMinCost + sizeofMaxCost;
3755
3756   /* Compute the total size cost of a match & jump sequence */
3757   sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3758
3759   /* If the size cost of the jump table is uneconomical then exit */
3760   if (sizeofMatchJump <  sizeofJumpTable)
3761     return 0;
3762
3763   /* The jump table is preferable. */
3764
3765   /* First, a label for the default or missing cases. */
3766   if (tree->values.switchVals.swDefault)
3767     {
3768       SNPRINTF (buffer, sizeof(buffer),
3769                 "_default_%d",
3770                 tree->values.switchVals.swNum);
3771     }
3772   else
3773     {
3774       SNPRINTF (buffer, sizeof(buffer),
3775                 "_swBrk_%d",
3776                 tree->values.switchVals.swNum);
3777     }
3778   falseLabel = newiTempLabel (buffer);
3779
3780   /* Build the list of labels for the jump table. */
3781   vch = caseVals;
3782   t = (int) floatFromVal (vch);
3783   for (i=min; i<=max; i++)
3784     {
3785       if (vch && t==i)
3786         {
3787           /* Explicit case: make a new label for it. */
3788           SNPRINTF (buffer, sizeof(buffer),
3789                     "_case_%d_%d",
3790                     tree->values.switchVals.swNum,
3791                     i);
3792           addSet (&labels, newiTempLabel (buffer));
3793           vch = vch->next;
3794           if (vch)
3795             t = (int) floatFromVal (vch);
3796         }
3797       else
3798         {
3799           /* Implicit case: use the default label. */
3800           addSet (&labels, falseLabel);
3801         }
3802     }
3803
3804   /* first we rule out the boundary conditions */
3805   /* if only optimization says so */
3806   if (needRangeCheck)
3807     {
3808       sym_link *cetype = getSpec (operandType (cond));
3809       /* no need to check the lower bound if
3810          the condition is unsigned & minimum value is zero */
3811       if (!(min == 0 && IS_UNSIGNED (cetype)))
3812         {
3813           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3814           ic = newiCodeCondition (boundary, falseLabel, NULL);
3815           ADDTOCHAIN (ic);
3816         }
3817
3818       /* now for upper bounds */
3819       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3820       ic = newiCodeCondition (boundary, falseLabel, NULL);
3821       ADDTOCHAIN (ic);
3822     }
3823
3824   /* if the min is not zero then we no make it zero */
3825   if (min)
3826     {
3827       cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3828       if (!IS_LITERAL(getSpec(operandType(cond))))
3829         setOperandType (cond, UCHARTYPE);
3830     }
3831
3832   /* now create the jumptable */
3833   ic = newiCode (JUMPTABLE, NULL, NULL);
3834   IC_JTCOND (ic) = cond;
3835   IC_JTLABELS (ic) = labels;
3836   ADDTOCHAIN (ic);
3837   return 1;
3838 }
3839
3840 /*-----------------------------------------------------------------*/
3841 /* geniCodeSwitch - changes a switch to a if statement             */
3842 /*-----------------------------------------------------------------*/
3843 void
3844 geniCodeSwitch (ast * tree,int lvl)
3845 {
3846   iCode *ic;
3847   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3848   value *caseVals = tree->values.switchVals.swVals;
3849   symbol *trueLabel, *falseLabel;
3850
3851   /* If the condition is a literal, then just jump to the */
3852   /* appropriate case label. */
3853   if (IS_LITERAL(getSpec(operandType(cond))))
3854     {
3855       int switchVal, caseVal;
3856
3857       switchVal = (int) floatFromVal (cond->operand.valOperand);
3858       while (caseVals)
3859         {
3860           caseVal = (int) floatFromVal (caseVals);
3861           if (caseVal == switchVal)
3862             {
3863               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3864                         tree->values.switchVals.swNum, caseVal);
3865               trueLabel = newiTempLabel (buffer);
3866               geniCodeGoto (trueLabel);
3867               goto jumpTable;
3868             }
3869           caseVals = caseVals->next;
3870         }
3871       goto defaultOrBreak;
3872     }
3873
3874   /* If cond is volatile, it might change while we are trying to */
3875   /* find the matching case. To avoid this possibility, make a   */
3876   /* non-volatile copy to use instead. */
3877   if (IS_OP_VOLATILE (cond))
3878     {
3879       operand * newcond;
3880       iCode * ic;
3881
3882       newcond = newiTempOperand (operandType (cond), TRUE);
3883       newcond->isvolatile = 0;
3884       ic = newiCode ('=', NULL, cond);
3885       IC_RESULT (ic) = newcond;
3886       ADDTOCHAIN (ic);
3887       cond = newcond;
3888     }
3889
3890   /* if we can make this a jump table */
3891   if (geniCodeJumpTable (cond, caseVals, tree))
3892     goto jumpTable;             /* no need for the comparison */
3893
3894   /* for the cases defined do */
3895   while (caseVals)
3896     {
3897
3898       operand *compare = geniCodeLogic (cond,
3899                                         operandFromValue (caseVals),
3900                                         EQ_OP);
3901
3902       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3903                tree->values.switchVals.swNum,
3904                (int) floatFromVal (caseVals));
3905       trueLabel = newiTempLabel (buffer);
3906
3907       ic = newiCodeCondition (compare, trueLabel, NULL);
3908       ADDTOCHAIN (ic);
3909       caseVals = caseVals->next;
3910     }
3911
3912
3913 defaultOrBreak:
3914   /* if default is present then goto break else break */
3915   if (tree->values.switchVals.swDefault)
3916     {
3917         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3918     }
3919   else
3920     {
3921         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3922     }
3923
3924   falseLabel = newiTempLabel (buffer);
3925   geniCodeGoto (falseLabel);
3926
3927 jumpTable:
3928   ast2iCode (tree->right,lvl+1);
3929 }
3930
3931 /*-----------------------------------------------------------------*/
3932 /* geniCodeInline - intermediate code for inline assembler         */
3933 /*-----------------------------------------------------------------*/
3934 static void
3935 geniCodeInline (ast * tree)
3936 {
3937   iCode *ic;
3938
3939   ic = newiCode (INLINEASM, NULL, NULL);
3940   IC_INLINE (ic) = tree->values.inlineasm;
3941   ADDTOCHAIN (ic);
3942 }
3943
3944 /*-----------------------------------------------------------------*/
3945 /* geniCodeArrayInit - intermediate code for array initializer     */
3946 /*-----------------------------------------------------------------*/
3947 static void
3948 geniCodeArrayInit (ast * tree, operand *array)
3949 {
3950   iCode *ic;
3951
3952   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3953     ic = newiCode (ARRAYINIT, array, NULL);
3954     IC_ARRAYILIST (ic) = tree->values.constlist;
3955   } else {
3956     operand *left=newOperand(), *right=newOperand();
3957     left->type=right->type=SYMBOL;
3958     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3959     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3960     ic = newiCode (ARRAYINIT, left, right);
3961   }
3962   ADDTOCHAIN (ic);
3963 }
3964
3965 /*-----------------------------------------------------------------*/
3966 /* geniCodeCritical - intermediate code for a critical statement   */
3967 /*-----------------------------------------------------------------*/
3968 static void
3969 geniCodeCritical (ast *tree, int lvl)
3970 {
3971   iCode *ic;
3972   operand *op = NULL;
3973   sym_link *type;
3974
3975   if (!options.stackAuto)
3976     {
3977       type = newLink(SPECIFIER);
3978       SPEC_VOLATILE(type) = 1;
3979       SPEC_NOUN(type) = V_BIT;
3980       SPEC_SCLS(type) = S_BIT;
3981       SPEC_BLEN(type) = 1;
3982       SPEC_BSTR(type) = 0;
3983       op = newiTempOperand(type, 1);
3984     }
3985
3986   /* If op is NULL, the original interrupt state will saved on */
3987   /* the stack. Otherwise, it will be saved in op. */
3988
3989   /* Generate a save of the current interrupt state & disable */
3990   ic = newiCode (CRITICAL, NULL, NULL);
3991   IC_RESULT (ic) = op;
3992   ADDTOCHAIN (ic);
3993
3994   /* Generate the critical code sequence */
3995   if (tree->left && tree->left->type == EX_VALUE)
3996     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3997   else
3998     ast2iCode (tree->left,lvl+1);
3999
4000   /* Generate a restore of the original interrupt state */
4001   ic = newiCode (ENDCRITICAL, NULL, op);
4002   ADDTOCHAIN (ic);
4003 }
4004
4005 /*-----------------------------------------------------------------*/
4006 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
4007 /* particular case. Ie : assigning or dereferencing array or ptr   */
4008 /*-----------------------------------------------------------------*/
4009 set * lvaluereqSet = NULL;
4010 typedef struct lvalItem
4011   {
4012     int req;
4013     int lvl;
4014   }
4015 lvalItem;
4016
4017 /*-----------------------------------------------------------------*/
4018 /* addLvaluereq - add a flag for lvalreq for current ast level     */
4019 /*-----------------------------------------------------------------*/
4020 void addLvaluereq(int lvl)
4021 {
4022   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4023   lpItem->req=1;
4024   lpItem->lvl=lvl;
4025   addSetHead(&lvaluereqSet,lpItem);
4026
4027 }
4028 /*-----------------------------------------------------------------*/
4029 /* delLvaluereq - del a flag for lvalreq for current ast level     */
4030 /*-----------------------------------------------------------------*/
4031 void delLvaluereq()
4032 {
4033   lvalItem * lpItem;
4034   lpItem = getSet(&lvaluereqSet);
4035   if(lpItem) Safe_free(lpItem);
4036 }
4037 /*-----------------------------------------------------------------*/
4038 /* clearLvaluereq - clear lvalreq flag                             */
4039 /*-----------------------------------------------------------------*/
4040 void clearLvaluereq()
4041 {
4042   lvalItem * lpItem;
4043   lpItem = peekSet(lvaluereqSet);
4044   if(lpItem) lpItem->req = 0;
4045 }
4046 /*-----------------------------------------------------------------*/
4047 /* getLvaluereq - get the last lvalreq level                       */
4048 /*-----------------------------------------------------------------*/
4049 int getLvaluereqLvl()
4050 {
4051   lvalItem * lpItem;
4052   lpItem = peekSet(lvaluereqSet);
4053   if(lpItem) return lpItem->lvl;
4054   return 0;
4055 }
4056 /*-----------------------------------------------------------------*/
4057 /* isLvaluereq - is lvalreq valid for this level ?                 */
4058 /*-----------------------------------------------------------------*/
4059 int isLvaluereq(int lvl)
4060 {
4061   lvalItem * lpItem;
4062   lpItem = peekSet(lvaluereqSet);
4063   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4064   return 0;
4065 }
4066
4067 /*-----------------------------------------------------------------*/
4068 /* ast2iCode - creates an icodeList from an ast                    */
4069 /*-----------------------------------------------------------------*/
4070 operand *
4071 ast2iCode (ast * tree,int lvl)
4072 {
4073   operand *left = NULL;
4074   operand *right = NULL;
4075   if (!tree)
4076     return NULL;
4077
4078   /* set the global variables for filename & line number */
4079   if (tree->filename)
4080     filename = tree->filename;
4081   if (tree->lineno)
4082     lineno = tree->lineno;
4083   if (tree->block)
4084     block = tree->block;
4085   if (tree->level)
4086     scopeLevel = tree->level;
4087   if (tree->seqPoint)
4088     seqPoint = tree->seqPoint;
4089
4090   if (tree->type == EX_VALUE)
4091     return operandFromValue (tree->opval.val);
4092
4093   if (tree->type == EX_LINK)
4094     return operandFromLink (tree->opval.lnk);
4095
4096   /* if we find a nullop */
4097   if (tree->type == EX_OP &&
4098      (tree->opval.op == NULLOP ||
4099      tree->opval.op == BLOCK))
4100     {
4101       if (tree->left && tree->left->type == EX_VALUE)
4102         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4103       else
4104         ast2iCode (tree->left,lvl+1);
4105       if (tree->right && tree->right->type == EX_VALUE)
4106         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4107       else
4108         ast2iCode (tree->right,lvl+1);
4109       return NULL;
4110     }
4111
4112   /* special cases for not evaluating */
4113   if (tree->opval.op != ':' &&
4114       tree->opval.op != '?' &&
4115       tree->opval.op != CALL &&
4116       tree->opval.op != IFX &&
4117       tree->opval.op != AND_OP &&
4118       tree->opval.op != OR_OP &&
4119       tree->opval.op != LABEL &&
4120       tree->opval.op != GOTO &&
4121       tree->opval.op != SWITCH &&
4122       tree->opval.op != FUNCTION &&
4123       tree->opval.op != INLINEASM &&
4124       tree->opval.op != CRITICAL)
4125     {
4126
4127         if (IS_ASSIGN_OP (tree->opval.op) ||
4128            IS_DEREF_OP (tree) ||
4129            (tree->opval.op == '&' && !tree->right) ||
4130            tree->opval.op == PTR_OP)
4131           {
4132             addLvaluereq(lvl);
4133             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4134                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4135               clearLvaluereq();
4136
4137             left = operandFromAst (tree->left,lvl);
4138             delLvaluereq();
4139             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4140               left = geniCodeRValue (left, TRUE);
4141           }
4142         else
4143           {
4144             left = operandFromAst (tree->left,lvl);
4145           }
4146         if (tree->opval.op == INC_OP ||
4147             tree->opval.op == DEC_OP)
4148           {
4149             addLvaluereq(lvl);
4150             right = operandFromAst (tree->right,lvl);
4151             delLvaluereq();
4152           }
4153         else
4154           {
4155             right = operandFromAst (tree->right,lvl);
4156           }
4157       }
4158
4159   /* now depending on the type of operand */
4160   /* this will be a biggy                 */
4161   switch (tree->opval.op)
4162     {
4163
4164     case '[':                   /* array operation */
4165       {
4166         //sym_link *ltype = operandType (left);
4167         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4168         left = geniCodeRValue (left, FALSE);
4169         right = geniCodeRValue (right, TRUE);
4170       }
4171
4172       return geniCodeArray (left, right,lvl);
4173
4174     case '.':                   /* structure dereference */
4175       if (IS_PTR (operandType (left)))
4176         left = geniCodeRValue (left, TRUE);
4177       else
4178         left = geniCodeRValue (left, FALSE);
4179
4180       return geniCodeStruct (left, right, tree->lvalue);
4181
4182     case PTR_OP:                /* structure pointer dereference */
4183       {
4184         sym_link *pType;
4185         pType = operandType (left);
4186         left = geniCodeRValue (left, TRUE);
4187
4188         setOClass (pType, getSpec (operandType (left)));
4189       }
4190
4191       return geniCodeStruct (left, right, tree->lvalue);
4192
4193     case INC_OP:                /* increment operator */
4194       if (left)
4195         return geniCodePostInc (left);
4196       else
4197         return geniCodePreInc (right, tree->lvalue);
4198
4199     case DEC_OP:                /* decrement operator */
4200       if (left)
4201         return geniCodePostDec (left);
4202       else
4203         return geniCodePreDec (right, tree->lvalue);
4204
4205     case '&':                   /* bitwise and or address of operator */
4206       if (right)
4207         {                       /* this is a bitwise operator   */
4208           left = geniCodeRValue (left, FALSE);
4209           right = geniCodeRValue (right, FALSE);
4210           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4211         }
4212       else
4213         return geniCodeAddressOf (left);
4214
4215     case '|':                   /* bitwise or & xor */
4216     case '^':
4217       return geniCodeBitwise (geniCodeRValue (left, FALSE),
4218                               geniCodeRValue (right, FALSE),
4219                               tree->opval.op,
4220                               tree->ftype);
4221
4222     case '/':
4223       return geniCodeDivision (geniCodeRValue (left, FALSE),
4224                                geniCodeRValue (right, FALSE),
4225                                getResultTypeFromType (tree->ftype));
4226
4227     case '%':
4228       return geniCodeModulus (geniCodeRValue (left, FALSE),
4229                               geniCodeRValue (right, FALSE),
4230                               getResultTypeFromType (tree->ftype));
4231     case '*':
4232       if (right)
4233         return geniCodeMultiply (geniCodeRValue (left, FALSE),
4234                                  geniCodeRValue (right, FALSE),
4235                                  getResultTypeFromType (tree->ftype));
4236       else
4237         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4238
4239     case '-':
4240       if (right)
4241         return geniCodeSubtract (geniCodeRValue (left, FALSE),
4242                                  geniCodeRValue (right, FALSE),
4243                                  getResultTypeFromType (tree->ftype));
4244       else
4245         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4246
4247     case '+':
4248       if (right)
4249         return geniCodeAdd (geniCodeRValue (left, FALSE),
4250                             geniCodeRValue (right, FALSE),
4251                             getResultTypeFromType (tree->ftype),
4252                             lvl);
4253       else
4254         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
4255
4256     case LEFT_OP:
4257       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4258                                 geniCodeRValue (right, FALSE),
4259                                 getResultTypeFromType (tree->ftype));
4260
4261     case RIGHT_OP:
4262       return geniCodeRightShift (geniCodeRValue (left, FALSE),
4263                                  geniCodeRValue (right, FALSE));
4264     case CAST:
4265 #if 0 // this indeed needs a second thought
4266       {
4267         operand *op;
4268
4269         // let's keep this simple: get the rvalue we need
4270         op=geniCodeRValue (right, FALSE);
4271         // now cast it to whatever we want
4272         op=geniCodeCast (operandType(left), op, FALSE);
4273         // if this is going to be used as an lvalue, make it so
4274         if (tree->lvalue) {
4275           op->isaddr=1;
4276         }
4277         return op;
4278       }
4279 #else // bug #604575, is it a bug ????
4280       return geniCodeCast (operandType (left),
4281                            geniCodeRValue (right, FALSE), FALSE);
4282 #endif
4283
4284     case '~':
4285     case RRC:
4286     case RLC:
4287     case SWAP:
4288       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4289
4290     case '!':
4291     case GETHBIT:
4292       {
4293         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4294         setOperandType (op, UCHARTYPE);
4295         return op;
4296       }
4297     case GETABIT:
4298     case GETBYTE:
4299     case GETWORD:
4300       {
4301         operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4302                                       geniCodeRValue (right, FALSE),
4303                                       tree->opval.op);
4304         setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4305         return op;
4306       }
4307     case AND_OP:
4308     case OR_OP:
4309       return geniCodeLogicAndOr (tree, lvl);
4310     case '>':
4311     case '<':
4312     case LE_OP:
4313     case GE_OP:
4314     case EQ_OP:
4315     case NE_OP:
4316       /* different compilers (even different gccs) evaluate
4317          the two calls in a different order. to get the same
4318          result on all machines we've to specify a clear sequence.
4319       return geniCodeLogic (geniCodeRValue (left, FALSE),
4320                             geniCodeRValue (right, FALSE),
4321                             tree->opval.op);
4322       */
4323       {
4324         operand *leftOp, *rightOp;
4325
4326         leftOp  = geniCodeRValue (left , FALSE);
4327         rightOp = geniCodeRValue (right, FALSE);
4328
4329         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4330       }
4331     case '?':
4332       return geniCodeConditional (tree,lvl);
4333
4334     case SIZEOF:
4335       return operandFromLit (getSize (tree->right->ftype));
4336
4337     case '=':
4338       {
4339         sym_link *rtype = operandType (right);
4340         sym_link *ltype = operandType (left);
4341         if (IS_PTR (rtype) && IS_ITEMP (right)
4342             && right->isaddr && compareType (rtype->next, ltype) == 1)
4343           right = geniCodeRValue (right, TRUE);
4344         else
4345           right = geniCodeRValue (right, FALSE);
4346
4347         geniCodeAssign (left, right, 0, 1);
4348         return right;
4349       }
4350     case MUL_ASSIGN:
4351       return
4352         geniCodeAssign (left,
4353                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4354                                                   FALSE),
4355                                   geniCodeRValue (right, FALSE),
4356                                   getResultTypeFromType (tree->ftype)),
4357                         0, 1);
4358
4359     case DIV_ASSIGN:
4360       return
4361         geniCodeAssign (left,
4362                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4363                                                   FALSE),
4364                                   geniCodeRValue (right, FALSE),
4365                                   getResultTypeFromType (tree->ftype)),
4366                         0, 1);
4367     case MOD_ASSIGN:
4368       return
4369         geniCodeAssign (left,
4370                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4371                                                   FALSE),
4372                                   geniCodeRValue (right, FALSE),
4373                                   getResultTypeFromType (tree->ftype)),
4374                         0, 1);
4375     case ADD_ASSIGN:
4376       {
4377         sym_link *rtype = operandType (right);
4378         sym_link *ltype = operandType (left);
4379         if (IS_PTR (rtype) && IS_ITEMP (right)
4380             && right->isaddr && compareType (rtype->next, ltype) == 1)
4381           right = geniCodeRValue (right, TRUE);
4382         else
4383           right = geniCodeRValue (right, FALSE);
4384
4385
4386         return geniCodeAssign (left,
4387                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4388                                                   FALSE),
4389                                   right,
4390                                   getResultTypeFromType (tree->ftype),
4391                                   lvl),
4392                                0, 1);
4393       }
4394     case SUB_ASSIGN:
4395       {
4396         sym_link *rtype = operandType (right);
4397         sym_link *ltype = operandType (left);
4398         if (IS_PTR (rtype) && IS_ITEMP (right)
4399             && right->isaddr && compareType (rtype->next, ltype) == 1)
4400           {
4401             right = geniCodeRValue (right, TRUE);
4402           }
4403         else
4404           {
4405             right = geniCodeRValue (right, FALSE);
4406           }
4407         return
4408           geniCodeAssign (left,
4409                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4410                                                   FALSE),
4411                                   right,
4412                                   getResultTypeFromType (tree->ftype)),
4413                           0, 1);
4414       }
4415     case LEFT_ASSIGN:
4416       return
4417         geniCodeAssign (left,
4418                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4419                                                    ,FALSE),
4420                                    geniCodeRValue (right, FALSE),
4421                                    getResultTypeFromType (tree->ftype)),
4422                         0, 1);
4423     case RIGHT_ASSIGN:
4424       return
4425         geniCodeAssign (left,
4426                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4427                                                    ,FALSE),
4428                                    geniCodeRValue (right, FALSE)), 0, 1);
4429     case AND_ASSIGN:
4430       return
4431         geniCodeAssign (left,
4432                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4433                                                   FALSE),
4434                                   geniCodeRValue (right, FALSE),
4435                                   BITWISEAND,
4436                                   operandType (left)), 0, 1);
4437     case XOR_ASSIGN:
4438       return
4439         geniCodeAssign (left,
4440                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4441                                                   FALSE),
4442                                   geniCodeRValue (right, FALSE),
4443                                   '^',
4444                                   operandType (left)), 0, 1);
4445     case OR_ASSIGN:
4446       return
4447         geniCodeAssign (left,
4448                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4449                                                    ,FALSE),
4450                                    geniCodeRValue (right, FALSE),
4451                                    '|',
4452                                    operandType (left)), 0, 1);
4453     case ',':
4454       return geniCodeRValue (right, FALSE);
4455
4456     case CALL:
4457       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4458                            tree->right,lvl);
4459     case LABEL:
4460       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4461       return ast2iCode (tree->right,lvl+1);
4462
4463     case GOTO:
4464       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4465       return ast2iCode (tree->right,lvl+1);
4466
4467     case FUNCTION:
4468       geniCodeFunctionBody (tree,lvl);
4469       return NULL;
4470
4471     case RETURN:
4472       geniCodeReturn (right);
4473       return NULL;
4474
4475     case IFX:
4476       geniCodeIfx (tree,lvl);
4477       return NULL;
4478
4479     case SWITCH:
4480       geniCodeSwitch (tree,lvl);
4481       return NULL;
4482
4483     case INLINEASM:
4484       geniCodeInline (tree);
4485       return NULL;
4486
4487     case ARRAYINIT:
4488         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4489         return NULL;
4490
4491     case CRITICAL:
4492         geniCodeCritical (tree, lvl);
4493     }
4494
4495   return NULL;
4496 }
4497
4498 /*-----------------------------------------------------------------*/
4499 /* reverseICChain - gets from the list and creates a linkedlist    */
4500 /*-----------------------------------------------------------------*/
4501 iCode *
4502 reverseiCChain ()
4503 {
4504   iCode *loop = NULL;
4505   iCode *prev = NULL;
4506
4507   while ((loop = getSet (&iCodeChain)))
4508     {
4509       loop->next = prev;
4510       if (prev)
4511         prev->prev = loop;
4512       prev = loop;
4513     }
4514
4515   return prev;
4516 }
4517
4518
4519 /*-----------------------------------------------------------------*/
4520 /* iCodeFromAst - given an ast will convert it to iCode            */
4521 /*-----------------------------------------------------------------*/
4522 iCode *
4523 iCodeFromAst (ast * tree)
4524 {
4525   returnLabel = newiTempLabel ("_return");
4526   entryLabel = newiTempLabel ("_entry");
4527   ast2iCode (tree,0);
4528   return reverseiCChain ();
4529 }
4530
4531 static const char *opTypeToStr(OPTYPE op)
4532 {
4533     switch(op)
4534     {
4535       case SYMBOL: return "symbol";
4536       case VALUE: return "value";
4537       case TYPE: return "type";
4538     }
4539     return "undefined type";
4540 }
4541
4542
4543 operand *validateOpType(operand         *op,
4544                         const char      *macro,
4545                         const char      *args,
4546                         OPTYPE          type,
4547                         const char      *file,
4548                         unsigned        line)
4549 {
4550     if (op && op->type == type)
4551     {
4552         return op;
4553     }
4554     fprintf(stderr,
4555             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4556             " expected %s, got %s\n",
4557             macro, args, file, line,
4558             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4559     exit(-1);
4560     return op; // never reached, makes compiler happy.
4561 }