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