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