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