1d4da0dfc53b3656b64b26e96c457c0412414310
[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_TARGET_ULONG) operandLitValue (left) *
1160                      (TYPE_TARGET_ULONG) operandLitValue (right)));
1161           else if (IS_UNSIGNED (type)) /* unsigned int */
1162             {
1163               /* unsigned int is handled here in order to detect overflow */
1164               TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) operandLitValue (left) *
1165                                      (TYPE_TARGET_UINT) operandLitValue (right);
1166
1167               retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul));
1168               if (ul != (TYPE_TARGET_UINT) 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_TARGET_LONG l = (TYPE_TARGET_INT) operandLitValue (left) *
1175                                    (TYPE_TARGET_INT) operandLitValue (right);
1176
1177               retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_INT) l));
1178               if (l != (TYPE_TARGET_INT) 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_TARGET_ULONG) 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_TARGET_ULONG) operandLitValue (left) /
1203                                         (TYPE_TARGET_ULONG) 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_TARGET_ULONG) 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_TARGET_ULONG) operandLitValue (left) %
1223                                      (TYPE_TARGET_ULONG) operandLitValue (right));
1224           else
1225             retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
1226                                      (TYPE_TARGET_LONG) 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_TARGET_ULONG) operandLitValue (left) <<
1234                                   (TYPE_TARGET_ULONG) 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_TARGET_ULONG) operandLitValue (left) >>
1242                                  (TYPE_TARGET_ULONG) operandLitValue (right));
1243       else
1244         /* signed: arithmetic shift right */
1245         retval = operandFromLit ((TYPE_TARGET_LONG ) operandLitValue (left) >>
1246                                  (TYPE_TARGET_ULONG) 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_TARGET_ULONG l, r;
1263
1264           l = (TYPE_TARGET_ULONG) operandLitValue (left);
1265           r = (TYPE_TARGET_ULONG) 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_TARGET_UINT) r;
1275               l = (TYPE_TARGET_UINT) 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_TARGET_ULONG)operandLitValue(left) &
1303                                                  (TYPE_TARGET_ULONG)operandLitValue(right)));
1304       break;
1305     case '|':
1306       retval = operandFromValue (valCastLiteral (type,
1307                                                  (TYPE_TARGET_ULONG)operandLitValue(left) |
1308                                                  (TYPE_TARGET_ULONG)operandLitValue(right)));
1309       break;
1310     case '^':
1311       retval = operandFromValue (valCastLiteral (type,
1312                                                  (TYPE_TARGET_ULONG)operandLitValue(left) ^
1313                                                  (TYPE_TARGET_ULONG)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_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
1326
1327         retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1328                                  (i << 1));
1329       }
1330       break;
1331     case RLC:
1332       {
1333         TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) 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_TARGET_ULONG)operandLitValue(left) >>
1341                                 (TYPE_TARGET_ULONG)operandLitValue(right)) & 1);
1342       break;
1343     case GETBYTE:
1344       retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1345                                 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFF);
1346       break;
1347     case GETWORD:
1348       retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1349                                 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFFFF);
1350       break;
1351
1352     case GETHBIT:
1353       retval = operandFromLit (((TYPE_TARGET_ULONG)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_TARGET_ULONG)
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_TARGET_ULONG) 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       /* if the size left or right > 1 then support routine */
2134       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2135         {
2136           if (IS_LITERAL (retype))
2137             ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
2138           else
2139             ic = newiCode ('*', left, right); /* multiplication by support routine */
2140           ic->supportRtn = 1;
2141         }
2142       else
2143         {
2144           ic = newiCode ('*', left, right);   /* normal multiplication */
2145         }
2146     }
2147   IC_RESULT (ic) = newiTempOperand (resType, 1);
2148
2149   ADDTOCHAIN (ic);
2150   return IC_RESULT (ic);
2151 }
2152
2153 /*-----------------------------------------------------------------*/
2154 /* geniCodeDivision - gen intermediate code for division           */
2155 /*-----------------------------------------------------------------*/
2156 static operand *
2157 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2158 {
2159   iCode *ic;
2160   int p2 = 0;
2161   sym_link *resType;
2162   sym_link *rtype = operandType (right);
2163   sym_link *retype = getSpec (rtype);
2164   sym_link *ltype = operandType (left);
2165   sym_link *letype = getSpec (ltype);
2166
2167   resType = usualBinaryConversions (&left, &right, resultType, '/');
2168
2169   /* if the right is a literal & power of 2
2170      and left is unsigned then make it a
2171      right shift */
2172   if (IS_LITERAL (retype) &&
2173       !IS_FLOAT (letype) &&
2174       !IS_FIXED (letype) &&
2175       IS_UNSIGNED(letype) &&
2176       ((p2 = powof2 ((TYPE_TARGET_ULONG)
2177                     floatFromVal (right->operand.valOperand))) > 0)) {
2178     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2179   }
2180   else
2181     {
2182       ic = newiCode ('/', left, right);         /* normal division */
2183       /* if the size left or right > 1 then support routine */
2184       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2185         ic->supportRtn = 1;
2186     }
2187   IC_RESULT (ic) = newiTempOperand (resType, 0);
2188
2189   ADDTOCHAIN (ic);
2190   return IC_RESULT (ic);
2191 }
2192 /*-----------------------------------------------------------------*/
2193 /* geniCodeModulus  - gen intermediate code for modulus            */
2194 /*-----------------------------------------------------------------*/
2195 static operand *
2196 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2197 {
2198   iCode *ic;
2199   sym_link *resType;
2200   LRTYPE;
2201
2202   /* if they are both literal then we know the result */
2203   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2204     return operandFromValue (valMod (left->operand.valOperand,
2205                                      right->operand.valOperand));
2206
2207   resType = usualBinaryConversions (&left, &right, resultType, '%');
2208
2209   /* now they are the same size */
2210   ic = newiCode ('%', left, right);
2211
2212   /* if the size left or right > 1 then support routine */
2213   if (getSize (ltype) > 1 || getSize (rtype) > 1)
2214     ic->supportRtn = 1;
2215   IC_RESULT (ic) = newiTempOperand (resType, 0);
2216
2217   ADDTOCHAIN (ic);
2218   return IC_RESULT (ic);
2219 }
2220
2221 /*-----------------------------------------------------------------*/
2222 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
2223 /*-----------------------------------------------------------------*/
2224 operand *
2225 geniCodePtrPtrSubtract (operand * left, operand * right)
2226 {
2227   iCode *ic;
2228   operand *result;
2229   LRTYPE;
2230
2231   /* if they are both literals then */
2232   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2233     {
2234       result = operandFromValue (valMinus (left->operand.valOperand,
2235                                            right->operand.valOperand));
2236       goto subtractExit;
2237     }
2238
2239   ic = newiCode ('-', left, right);
2240
2241   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2242   ADDTOCHAIN (ic);
2243
2244 subtractExit:
2245   if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2246     return result;
2247   }
2248
2249   // should we really do this? is this ANSI?
2250   return geniCodeDivision (result,
2251                            operandFromLit (getSize (ltype->next)),
2252                            FALSE);
2253 }
2254
2255 /*-----------------------------------------------------------------*/
2256 /* geniCodeSubtract - generates code for subtraction               */
2257 /*-----------------------------------------------------------------*/
2258 static operand *
2259 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2260 {
2261   iCode *ic;
2262   int isarray = 0;
2263   sym_link *resType;
2264   LRTYPE;
2265
2266   /* if they both pointers then */
2267   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2268       (IS_PTR (rtype) || IS_ARRAY (rtype)))
2269     return geniCodePtrPtrSubtract (left, right);
2270
2271   /* if they are both literal then we know the result */
2272   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2273       && left->isLiteral && right->isLiteral)
2274     return operandFromValue (valMinus (left->operand.valOperand,
2275                                        right->operand.valOperand));
2276
2277   /* if left is an array or pointer */
2278   if (IS_PTR (ltype) || IS_ARRAY (ltype))
2279     {
2280       isarray = left->isaddr;
2281       right = geniCodeMultiply (right,
2282                                 operandFromLit (getSize (ltype->next)),
2283                                 (getArraySizePtr(left) >= INTSIZE) ?
2284                                   RESULT_TYPE_INT :
2285                                   RESULT_TYPE_CHAR);
2286       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2287     }
2288   else
2289     {                           /* make them the same size */
2290       resType = usualBinaryConversions (&left, &right, resultType, '-');
2291     }
2292
2293   ic = newiCode ('-', left, right);
2294
2295   IC_RESULT (ic) = newiTempOperand (resType, 1);
2296   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2297
2298   /* if left or right is a float */
2299   if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2300       || IS_FIXED (ltype) || IS_FIXED (rtype))
2301     ic->supportRtn = 1;
2302
2303   ADDTOCHAIN (ic);
2304   return IC_RESULT (ic);
2305 }
2306
2307 /*-----------------------------------------------------------------*/
2308 /* geniCodeAdd - generates iCode for addition                      */
2309 /*-----------------------------------------------------------------*/
2310 static operand *
2311 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2312 {
2313   iCode *ic;
2314   sym_link *resType;
2315   operand *size;
2316   int isarray = 0;
2317   bool indexUnsigned;
2318   LRTYPE;
2319
2320   /* if the right side is LITERAL zero */
2321   /* return the left side              */
2322   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2323     return left;
2324
2325   /* if left is literal zero return right */
2326   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2327     return right;
2328
2329   /* if left is a pointer then size */
2330   if (IS_PTR (ltype) || IS_ARRAY(ltype))
2331     {
2332       isarray = left->isaddr;
2333       // there is no need to multiply with 1
2334       if (getSize (ltype->next) != 1)
2335         {
2336           size  = operandFromLit (getSize (ltype->next));
2337           SPEC_USIGN (getSpec (operandType (size))) = 1;
2338           indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2339           right = geniCodeMultiply (right, size, resultType);
2340           /* Even if right is a 'unsigned char',
2341              the result will be a 'signed int' due to the promotion rules.
2342              It doesn't make sense when accessing arrays, so let's fix it here: */
2343           if (indexUnsigned)
2344             SPEC_USIGN (getSpec (operandType (right))) = 1;
2345         }
2346       resType = copyLinkChain (ltype);
2347     }
2348   else
2349     { // make them the same size
2350       resType = usualBinaryConversions (&left, &right, resultType, '+');
2351     }
2352
2353   /* if they are both literals then we know */
2354   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2355       && left->isLiteral && right->isLiteral)
2356     return operandFromValue (valPlus (valFromType (ltype),
2357                                       valFromType (rtype)));
2358
2359   ic = newiCode ('+', left, right);
2360
2361   IC_RESULT (ic) = newiTempOperand (resType, 1);
2362   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2363
2364   /* if left or right is a float then support
2365      routine */
2366   if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2367       || IS_FIXED (ltype) || IS_FIXED (rtype))
2368     ic->supportRtn = 1;
2369
2370   ADDTOCHAIN (ic);
2371
2372   return IC_RESULT (ic);
2373
2374 }
2375
2376 /*-----------------------------------------------------------------*/
2377 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate"  */
2378 /*-----------------------------------------------------------------*/
2379 sym_link *
2380 aggrToPtr (sym_link * type, bool force)
2381 {
2382   sym_link *etype;
2383   sym_link *ptype;
2384
2385   if (IS_PTR (type) && !force)
2386     return type;
2387
2388   etype = getSpec (type);
2389   ptype = newLink (DECLARATOR);
2390
2391   ptype->next = type;
2392
2393   /* set the pointer depending on the storage class */
2394   DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2395   return ptype;
2396 }
2397
2398 /*------------------------------------------------------------------*/
2399 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2400 /*------------------------------------------------------------------*/
2401 int
2402 aggrToPtrDclType (sym_link * type, bool force)
2403 {
2404   if (IS_PTR (type) && !force)
2405     return DCL_TYPE (type);
2406
2407   /* return the pointer depending on the storage class */
2408   return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2409 }
2410
2411 /*-----------------------------------------------------------------*/
2412 /* geniCodeArray2Ptr - array to pointer                            */
2413 /*-----------------------------------------------------------------*/
2414 static operand *
2415 geniCodeArray2Ptr (operand * op)
2416 {
2417   sym_link *optype = operandType (op);
2418   sym_link *opetype = getSpec (optype);
2419
2420   /* set the pointer depending on the storage class */
2421   DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2422
2423   op->isaddr = 0;
2424   return op;
2425 }
2426
2427
2428 /*-----------------------------------------------------------------*/
2429 /* geniCodeArray - array access                                    */
2430 /*-----------------------------------------------------------------*/
2431 static operand *
2432 geniCodeArray (operand * left, operand * right, int lvl)
2433 {
2434   iCode *ic;
2435   operand *size;
2436   sym_link *ltype = operandType (left);
2437   bool indexUnsigned;
2438   RESULT_TYPE resultType;
2439
2440   resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2441   if (DCL_ELEM (ltype))
2442     {
2443       if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2444         resultType = RESULT_TYPE_CHAR;
2445     }
2446
2447   if (IS_PTR (ltype))
2448     {
2449       if (IS_PTR (ltype->next) && left->isaddr)
2450         {
2451           left = geniCodeRValue (left, FALSE);
2452         }
2453
2454       return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2455                                lvl);
2456     }
2457   size = operandFromLit (getSize (ltype->next));
2458   SPEC_USIGN (getSpec (operandType (size))) = 1;
2459   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2460   right = geniCodeMultiply (right, size, resultType);
2461   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2462      It doesn't make sense when accessing arrays, so let's fix it here: */
2463   if (indexUnsigned)
2464     SPEC_USIGN (getSpec (operandType (right))) = 1;
2465   /* we can check for limits here */
2466   /* already done in SDCCast.c
2467   if (isOperandLiteral (right) &&
2468       IS_ARRAY (ltype) &&
2469       DCL_ELEM (ltype) &&
2470       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2471     {
2472       werror (W_IDX_OUT_OF_BOUNDS,
2473               (int) operandLitValue (right) / getSize (ltype->next),
2474               DCL_ELEM (ltype));
2475     }
2476   */
2477
2478   ic = newiCode ('+', left, right);
2479
2480   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2481                                       !IS_AGGREGATE (ltype->next) &&
2482                                       !IS_PTR (ltype->next))
2483                                      ? ltype : ltype->next), 0);
2484
2485   if (!IS_AGGREGATE (ltype->next))
2486     {
2487       IC_RESULT (ic)->isaddr = 1;
2488       IC_RESULT (ic)->aggr2ptr = 1;
2489     }
2490   ADDTOCHAIN (ic);
2491
2492   return IC_RESULT (ic);
2493 }
2494
2495 /*-----------------------------------------------------------------*/
2496 /* geniCodeStruct - generates intermediate code for structures     */
2497 /*-----------------------------------------------------------------*/
2498 operand *
2499 geniCodeStruct (operand * left, operand * right, bool islval)
2500 {
2501   iCode *ic;
2502   sym_link *type = operandType (left);
2503   sym_link *etype = getSpec (type);
2504   sym_link *retype;
2505   symbol *element = getStructElement (SPEC_STRUCT (etype),
2506                                       right->operand.symOperand);
2507
2508   wassert(IS_SYMOP(right));
2509
2510   /* add the offset */
2511   ic = newiCode ('+', left, operandFromLit (element->offset));
2512
2513   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2514
2515   /* preserve the storage & output class of the struct */
2516   /* as well as the volatile attribute */
2517   retype = getSpec (operandType (IC_RESULT (ic)));
2518   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2519   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2520   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2521   SPEC_CONST (retype) |= SPEC_CONST (etype);
2522
2523   if (IS_PTR (element->type))
2524     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2525
2526   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2527
2528   ADDTOCHAIN (ic);
2529   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2530 }
2531
2532 /*-----------------------------------------------------------------*/
2533 /* geniCodePostInc - generate int code for Post increment          */
2534 /*-----------------------------------------------------------------*/
2535 operand *
2536 geniCodePostInc (operand * op)
2537 {
2538   iCode *ic;
2539   operand *rOp;
2540   sym_link *optype = operandType (op);
2541   operand *result;
2542   operand *rv = (IS_ITEMP (op) ?
2543                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2544                  op);
2545   sym_link *rvtype = operandType (rv);
2546   int size = 0;
2547
2548   /* if this is not an address we have trouble */
2549   if (!op->isaddr)
2550     {
2551       werror (E_LVALUE_REQUIRED, "++");
2552       return op;
2553     }
2554
2555   rOp = newiTempOperand (rvtype, 0);
2556   OP_SYMBOL(rOp)->noSpilLoc = 1;
2557
2558   if (IS_ITEMP (rv))
2559     OP_SYMBOL(rv)->noSpilLoc = 1;
2560
2561   geniCodeAssign (rOp, rv, 0, 0);
2562
2563   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2564   if (size == 0)
2565     werror(W_SIZEOF_VOID);
2566   if (IS_FLOAT (rvtype))
2567     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2568   else if (IS_FIXED16X16 (rvtype))
2569     ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2570   else
2571     ic = newiCode ('+', rv, operandFromLit (size));
2572
2573   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2574   ADDTOCHAIN (ic);
2575
2576   geniCodeAssign (op, result, 0, 0);
2577
2578   return rOp;
2579
2580 }
2581
2582 /*-----------------------------------------------------------------*/
2583 /* geniCodePreInc - generate code for preIncrement                 */
2584 /*-----------------------------------------------------------------*/
2585 operand *
2586 geniCodePreInc (operand * op, bool lvalue)
2587 {
2588   iCode *ic;
2589   sym_link *optype = operandType (op);
2590   operand *rop = (IS_ITEMP (op) ?
2591                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2592                   op);
2593   sym_link *roptype = operandType (rop);
2594   operand *result;
2595   int size = 0;
2596
2597   if (!op->isaddr)
2598     {
2599       werror (E_LVALUE_REQUIRED, "++");
2600       return op;
2601     }
2602
2603   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2604   if (size == 0)
2605     werror(W_SIZEOF_VOID);
2606   if (IS_FLOAT (roptype))
2607     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2608   else if (IS_FIXED16X16 (roptype))
2609     ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2610   else
2611     ic = newiCode ('+', rop, operandFromLit (size));
2612   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2613   ADDTOCHAIN (ic);
2614
2615   (void) geniCodeAssign (op, result, 0, 0);
2616   if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2617     return op;
2618   else
2619     return result;
2620 }
2621
2622 /*-----------------------------------------------------------------*/
2623 /* geniCodePostDec - generates code for Post decrement             */
2624 /*-----------------------------------------------------------------*/
2625 operand *
2626 geniCodePostDec (operand * op)
2627 {
2628   iCode *ic;
2629   operand *rOp;
2630   sym_link *optype = operandType (op);
2631   operand *result;
2632   operand *rv = (IS_ITEMP (op) ?
2633                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2634                  op);
2635   sym_link *rvtype = operandType (rv);
2636   int size = 0;
2637
2638   /* if this is not an address we have trouble */
2639   if (!op->isaddr)
2640     {
2641       werror (E_LVALUE_REQUIRED, "--");
2642       return op;
2643     }
2644
2645   rOp = newiTempOperand (rvtype, 0);
2646   OP_SYMBOL(rOp)->noSpilLoc = 1;
2647
2648   if (IS_ITEMP (rv))
2649     OP_SYMBOL(rv)->noSpilLoc = 1;
2650
2651   geniCodeAssign (rOp, rv, 0, 0);
2652
2653   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2654   if (size == 0)
2655     werror(W_SIZEOF_VOID);
2656   if (IS_FLOAT (rvtype))
2657     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2658   else if (IS_FIXED16X16 (rvtype))
2659     ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2660   else
2661     ic = newiCode ('-', rv, operandFromLit (size));
2662
2663   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2664   ADDTOCHAIN (ic);
2665
2666   geniCodeAssign (op, result, 0, 0);
2667
2668   return rOp;
2669
2670 }
2671
2672 /*-----------------------------------------------------------------*/
2673 /* geniCodePreDec - generate code for pre  decrement               */
2674 /*-----------------------------------------------------------------*/
2675 operand *
2676 geniCodePreDec (operand * op, bool lvalue)
2677 {
2678   iCode *ic;
2679   sym_link *optype = operandType (op);
2680   operand *rop = (IS_ITEMP (op) ?
2681                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2682                   op);
2683   sym_link *roptype = operandType (rop);
2684   operand *result;
2685   int size = 0;
2686
2687   if (!op->isaddr)
2688     {
2689       werror (E_LVALUE_REQUIRED, "--");
2690       return op;
2691     }
2692
2693   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2694   if (size == 0)
2695     werror(W_SIZEOF_VOID);
2696   if (IS_FLOAT (roptype))
2697     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2698   else if (IS_FIXED16X16 (roptype))
2699     ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2700   else
2701     ic = newiCode ('-', rop, operandFromLit (size));
2702   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2703   ADDTOCHAIN (ic);
2704
2705   (void) geniCodeAssign (op, result, 0, 0);
2706   if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2707     return op;
2708   else
2709     return result;
2710 }
2711
2712
2713 /*-----------------------------------------------------------------*/
2714 /* geniCodeBitwise - gen int code for bitWise  operators           */
2715 /*-----------------------------------------------------------------*/
2716 operand *
2717 geniCodeBitwise (operand * left, operand * right,
2718                  int oper, sym_link * resType)
2719 {
2720   iCode *ic;
2721
2722   left = geniCodeCast (resType, left, TRUE);
2723   right = geniCodeCast (resType, right, TRUE);
2724
2725   ic = newiCode (oper, left, right);
2726   IC_RESULT (ic) = newiTempOperand (resType, 0);
2727
2728   ADDTOCHAIN (ic);
2729   return IC_RESULT (ic);
2730 }
2731
2732 /*-----------------------------------------------------------------*/
2733 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2734 /*-----------------------------------------------------------------*/
2735 operand *
2736 geniCodeAddressOf (operand * op)
2737 {
2738   iCode *ic;
2739   sym_link *p;
2740   sym_link *optype = operandType (op);
2741   sym_link *opetype = getSpec (optype);
2742
2743   if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2744     {
2745       op = operandFromOperand (op);
2746       op->isaddr = 0;
2747       return op;
2748     }
2749
2750   /* lvalue check already done in decorateType */
2751   /* this must be a lvalue */
2752 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2753 /*  werror (E_LVALUE_REQUIRED,"&"); */
2754 /*  return op; */
2755 /*     } */
2756
2757   p = newLink (DECLARATOR);
2758
2759   /* set the pointer depending on the storage class */
2760   DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2761
2762   p->next = copyLinkChain (optype);
2763
2764   /* if already a temp */
2765   if (IS_ITEMP (op))
2766     {
2767       setOperandType (op, p);
2768       op->isaddr = 0;
2769       return op;
2770     }
2771
2772   /* otherwise make this of the type coming in */
2773   ic = newiCode (ADDRESS_OF, op, NULL);
2774   IC_RESULT (ic) = newiTempOperand (p, 1);
2775   IC_RESULT (ic)->isaddr = 0;
2776   ADDTOCHAIN (ic);
2777   return IC_RESULT (ic);
2778 }
2779
2780 /*-----------------------------------------------------------------*/
2781 /* setOClass - sets the output class depending on the pointer type */
2782 /*-----------------------------------------------------------------*/
2783 void
2784 setOClass (sym_link * ptr, sym_link * spec)
2785 {
2786   switch (DCL_TYPE (ptr))
2787     {
2788     case POINTER:
2789       SPEC_OCLS (spec) = data;
2790       break;
2791
2792     case GPOINTER:
2793       SPEC_OCLS (spec) = generic;
2794       break;
2795
2796     case FPOINTER:
2797       SPEC_OCLS (spec) = xdata;
2798       break;
2799
2800     case CPOINTER:
2801       SPEC_OCLS (spec) = code;
2802       break;
2803
2804     case IPOINTER:
2805       SPEC_OCLS (spec) = idata;
2806       break;
2807
2808     case PPOINTER:
2809       SPEC_OCLS (spec) = xstack;
2810       break;
2811
2812     case EEPPOINTER:
2813       SPEC_OCLS (spec) = eeprom;
2814       break;
2815
2816     default:
2817       break;
2818
2819     }
2820 }
2821
2822 /*-----------------------------------------------------------------*/
2823 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2824 /*-----------------------------------------------------------------*/
2825 operand *
2826 geniCodeDerefPtr (operand * op,int lvl)
2827 {
2828   sym_link *rtype, *retype;
2829   sym_link *optype = operandType (op);
2830
2831   // if this is an array then array access
2832   if (IS_ARRAY (optype)) {
2833     // don't worry, this will be optimized out later
2834     return geniCodeArray (op, operandFromLit (0), lvl);
2835   }
2836
2837   // just in case someone screws up
2838   wassert (IS_PTR (optype));
2839
2840   if (IS_TRUE_SYMOP (op))
2841     {
2842       op->isaddr = 1;
2843       op = geniCodeRValue (op, TRUE);
2844     }
2845
2846   /* now get rid of the pointer part */
2847   if (isLvaluereq(lvl) && IS_ITEMP (op))
2848     {
2849       retype = getSpec (rtype = copyLinkChain (optype));
2850     }
2851   else
2852     {
2853       retype = getSpec (rtype = copyLinkChain (optype->next));
2854       /* outputclass needs 2b updated */
2855       setOClass (optype, retype);
2856     }
2857
2858   op->isGptr = IS_GENPTR (optype);
2859
2860   op->isaddr = (IS_PTR (rtype) ||
2861                 IS_STRUCT (rtype) ||
2862                 IS_INT (rtype) ||
2863                 IS_CHAR (rtype) ||
2864                 IS_FLOAT (rtype) ||
2865                 IS_FIXED (rtype));
2866
2867   if (!isLvaluereq(lvl))
2868     op = geniCodeRValue (op, TRUE);
2869
2870   setOperandType (op, rtype);
2871
2872   return op;
2873 }
2874
2875 /*-----------------------------------------------------------------*/
2876 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2877 /*-----------------------------------------------------------------*/
2878 operand *
2879 geniCodeUnaryMinus (operand * op)
2880 {
2881   iCode *ic;
2882   sym_link *optype = operandType (op);
2883
2884   if (IS_LITERAL (optype))
2885     return operandFromLit (-floatFromVal (op->operand.valOperand));
2886
2887   ic = newiCode (UNARYMINUS, op, NULL);
2888   IC_RESULT (ic) = newiTempOperand (optype, 0);
2889   ADDTOCHAIN (ic);
2890   return IC_RESULT (ic);
2891 }
2892
2893 /*-----------------------------------------------------------------*/
2894 /* geniCodeLeftShift - gen i code for left shift                   */
2895 /*-----------------------------------------------------------------*/
2896 operand *
2897 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2898 {
2899   iCode *ic;
2900   sym_link *resType;
2901
2902   ic = newiCode (LEFT_OP, left, right);
2903
2904   resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2905   IC_RESULT (ic) = newiTempOperand (resType, 0);
2906   ADDTOCHAIN (ic);
2907   return IC_RESULT (ic);
2908 }
2909
2910 /*-----------------------------------------------------------------*/
2911 /* geniCodeRightShift - gen i code for right shift                 */
2912 /*-----------------------------------------------------------------*/
2913 operand *
2914 geniCodeRightShift (operand * left, operand * right)
2915 {
2916   iCode *ic;
2917
2918   ic = newiCode (RIGHT_OP, left, right);
2919   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2920   ADDTOCHAIN (ic);
2921   return IC_RESULT (ic);
2922 }
2923
2924 /*-----------------------------------------------------------------*/
2925 /* geniCodeLogic- logic code                                       */
2926 /*-----------------------------------------------------------------*/
2927 static operand *
2928 geniCodeLogic (operand * left, operand * right, int op)
2929 {
2930   iCode *ic;
2931   sym_link *ctype;
2932   sym_link *rtype = operandType (right);
2933   sym_link *ltype = operandType (left);
2934
2935   /* left is integral type and right is literal then
2936      check if the literal value is within bounds */
2937   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2938     {
2939       CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
2940       switch (ccr_result)
2941         {
2942           case CCR_ALWAYS_TRUE:
2943           case CCR_ALWAYS_FALSE:
2944             if (!options.lessPedantic)
2945               werror (W_COMP_RANGE, "true resp. false");
2946             return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
2947           default:
2948             break;
2949         }
2950     }
2951
2952   /* if one operand is a pointer and the other is a literal generic void pointer,
2953      change the type of the literal generic void pointer to match the other pointer */
2954   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2955       && IS_PTR (rtype) && !IS_GENPTR(rtype))
2956     {
2957       /* find left's definition */
2958       ic = (iCode *) setFirstItem (iCodeChain);
2959       while (ic)
2960         {
2961           if (((ic->op == CAST) || (ic->op == '='))
2962               && isOperandEqual(left, IC_RESULT (ic)))
2963             break;
2964           else
2965             ic = setNextItem (iCodeChain);
2966         }
2967       /* if casting literal to generic pointer, then cast to rtype instead */
2968       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2969         {
2970           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2971           ltype = operandType(left);
2972         }
2973     }
2974   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2975       && IS_PTR (ltype) && !IS_GENPTR(ltype))
2976     {
2977       /* find right's definition */
2978       ic = (iCode *) setFirstItem (iCodeChain);
2979       while (ic)
2980         {
2981           if (((ic->op == CAST) || (ic->op == '='))
2982               && isOperandEqual(right, IC_RESULT (ic)))
2983             break;
2984           else
2985             ic = setNextItem (iCodeChain);
2986         }
2987       /* if casting literal to generic pointer, then cast to rtype instead */
2988       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2989         {
2990           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2991           rtype = operandType(right);
2992         }
2993     }
2994
2995   ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
2996
2997   ic = newiCode (op, left, right);
2998   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2999
3000   /* if comparing float
3001      and not a '==' || '!=' || '&&' || '||' (these
3002      will be inlined */
3003   if (IS_FLOAT(ctype) &&
3004       op != EQ_OP &&
3005       op != NE_OP &&
3006       op != AND_OP &&
3007       op != OR_OP)
3008    ic->supportRtn = 1;
3009
3010   /* if comparing a fixed type use support functions */
3011   if (IS_FIXED(ctype))
3012     ic->supportRtn = 1;
3013
3014   ADDTOCHAIN (ic);
3015   return IC_RESULT (ic);
3016 }
3017
3018 /*-----------------------------------------------------------------*/
3019 /* geniCodeLogicAndOr - && || operations                           */
3020 /*-----------------------------------------------------------------*/
3021 static operand *
3022 geniCodeLogicAndOr (ast *tree, int lvl)
3023 {
3024   iCode *ic;
3025   sym_link *type;
3026   symbol *falseLabel = newiTempLabel (NULL);
3027   symbol *trueLabel  = newiTempLabel (NULL);
3028   symbol *exitLabel  = newiTempLabel (NULL);
3029   operand *op, *result, *condition;
3030
3031   /* AND_OP and OR_OP are no longer generated because of bug-905492.
3032      They can be reenabled by executing the following block. If you find
3033      a decent optimization you could start right here:
3034   */
3035 #if 0
3036   if (0)
3037     {
3038        operand *leftOp, *rightOp;
3039
3040        leftOp  = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3041        rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3042
3043        return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3044     }
3045 #endif
3046
3047   /* generate two IFX for the '&&' or '||' op */
3048
3049   /* evaluate left operand */
3050   condition = ast2iCode (tree->left, lvl + 1);
3051   op = geniCodeRValue (condition, FALSE);
3052
3053   /* test left operand */
3054   if (tree->opval.op == AND_OP)
3055     ic = newiCodeCondition (op, NULL, falseLabel);
3056   else /* OR_OP */
3057     ic = newiCodeCondition (op, trueLabel, NULL);
3058   ADDTOCHAIN (ic);
3059
3060   /* evaluate right operand */
3061   condition = ast2iCode (tree->right, lvl + 1);
3062   op = geniCodeRValue (condition, FALSE);
3063
3064   /* test right operand */
3065   ic = newiCodeCondition (op, trueLabel, NULL);
3066   ADDTOCHAIN (ic);
3067
3068   /* store 0 or 1 in result */
3069   type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3070   result = newiTempOperand (type, 1);
3071
3072   geniCodeLabel (falseLabel);
3073   geniCodeAssign (result, operandFromLit (0), 0, 0);
3074   /* generate an unconditional goto */
3075   geniCodeGoto (exitLabel);
3076
3077   geniCodeLabel (trueLabel);
3078   geniCodeAssign (result, operandFromLit (1), 0, 0);
3079
3080   geniCodeLabel (exitLabel);
3081
3082   return result;
3083 }
3084
3085 /*-----------------------------------------------------------------*/
3086 /* geniCodeUnary - for a generic unary operation                   */
3087 /*-----------------------------------------------------------------*/
3088 operand *
3089 geniCodeUnary (operand * op, int oper)
3090 {
3091   iCode *ic = newiCode (oper, op, NULL);
3092
3093   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3094   ADDTOCHAIN (ic);
3095   return IC_RESULT (ic);
3096 }
3097
3098 /*-----------------------------------------------------------------*/
3099 /* geniCodeBinary - for a generic binary operation                 */
3100 /*-----------------------------------------------------------------*/
3101 operand *
3102 geniCodeBinary (operand * left, operand * right, int oper)
3103 {
3104   iCode *ic = newiCode (oper, left, right);
3105
3106   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3107   ADDTOCHAIN (ic);
3108   return IC_RESULT (ic);
3109 }
3110
3111 /*-----------------------------------------------------------------*/
3112 /* geniCodeConditional - geniCode for '?' ':' operation            */
3113 /*-----------------------------------------------------------------*/
3114 operand *
3115 geniCodeConditional (ast * tree,int lvl)
3116 {
3117   iCode *ic;
3118   symbol *falseLabel = newiTempLabel (NULL);
3119   symbol *exitLabel = newiTempLabel (NULL);
3120   operand *cond = ast2iCode (tree->left,lvl+1);
3121   operand *true, *false, *result;
3122
3123   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3124                           NULL, falseLabel);
3125   ADDTOCHAIN (ic);
3126
3127   true = ast2iCode (tree->right->left,lvl+1);
3128
3129   /* move the value to a new Operand */
3130   result = newiTempOperand (tree->right->ftype, 0);
3131   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3132
3133   /* generate an unconditional goto */
3134   geniCodeGoto (exitLabel);
3135
3136   /* now for the right side */
3137   geniCodeLabel (falseLabel);
3138
3139   false = ast2iCode (tree->right->right,lvl+1);
3140   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3141
3142   /* create the exit label */
3143   geniCodeLabel (exitLabel);
3144
3145   return result;
3146 }
3147
3148 /*-----------------------------------------------------------------*/
3149 /* geniCodeAssign - generate code for assignment                   */
3150 /*-----------------------------------------------------------------*/
3151 operand *
3152 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3153 {
3154   iCode *ic;
3155   sym_link *ltype = operandType (left);
3156   sym_link *rtype = operandType (right);
3157
3158   if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3159     {
3160       werror (E_LVALUE_REQUIRED, "assignment");
3161       return left;
3162     }
3163
3164   /* left is integral type and right is literal then
3165      check if the literal value is within bounds */
3166   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3167       checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3168       !options.lessPedantic)
3169     {
3170       werror (W_LIT_OVERFLOW);
3171     }
3172
3173   /* if the left & right type don't exactly match */
3174   /* if pointer set then make sure the check is
3175      done with the type & not the pointer */
3176   /* then cast rights type to left */
3177
3178   /* first check the type for pointer assignement */
3179   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3180       compareType (ltype, rtype) <= 0)
3181     {
3182       if (compareType (ltype->next, rtype) < 0)
3183         right = geniCodeCast (ltype->next, right, TRUE);
3184     }
3185   else if (compareType (ltype, rtype) < 0)
3186     right = geniCodeCast (ltype, right, TRUE);
3187
3188   /* If left is a true symbol & ! volatile
3189      create an assignment to temporary for
3190      the right & then assign this temporary
3191      to the symbol. This is SSA (static single
3192      assignment). Isn't it simple and folks have
3193      published mountains of paper on it */
3194   if (IS_TRUE_SYMOP (left) &&
3195       !isOperandVolatile (left, FALSE) &&
3196       isOperandGlobal (left))
3197     {
3198       symbol *sym = NULL;
3199       operand *newRight;
3200
3201       if (IS_TRUE_SYMOP (right))
3202         sym = OP_SYMBOL (right);
3203       ic = newiCode ('=', NULL, right);
3204       IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3205       /* avoid double fetch from volatile right, see bug 1369874 */
3206       if (!isOperandVolatile (right, FALSE))
3207         SPIL_LOC (newRight) = sym;
3208       right = newRight;
3209       ADDTOCHAIN (ic);
3210     }
3211
3212   ic = newiCode ('=', NULL, right);
3213   IC_RESULT (ic) = left;
3214   ADDTOCHAIN (ic);
3215
3216   /* if left isgptr flag is set then support
3217      routine will be required */
3218   if (left->isGptr)
3219     ic->supportRtn = 1;
3220
3221   ic->nosupdate = nosupdate;
3222   return left;
3223 }
3224
3225 /*-----------------------------------------------------------------*/
3226 /* geniCodeDummyRead - generate code for dummy read                */
3227 /*-----------------------------------------------------------------*/
3228 static void
3229 geniCodeDummyRead (operand * op)
3230 {
3231   iCode *ic;
3232   sym_link *type = operandType (op);
3233
3234   if (!IS_VOLATILE(type))
3235     return;
3236
3237   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3238   ADDTOCHAIN (ic);
3239
3240   ic->nosupdate = 1;
3241 }
3242
3243 /*-----------------------------------------------------------------*/
3244 /* geniCodeSEParms - generate code for side effecting fcalls       */
3245 /*-----------------------------------------------------------------*/
3246 static void
3247 geniCodeSEParms (ast * parms,int lvl)
3248 {
3249   if (!parms)
3250     return;
3251
3252   if (parms->type == EX_OP && parms->opval.op == PARAM)
3253     {
3254       geniCodeSEParms (parms->left,lvl);
3255       geniCodeSEParms (parms->right,lvl);
3256       return;
3257     }
3258
3259   /* hack don't like this but too lazy to think of
3260      something better */
3261   if (IS_ADDRESS_OF_OP (parms))
3262     parms->left->lvalue = 1;
3263
3264   if (IS_CAST_OP (parms) &&
3265       IS_PTR (parms->ftype) &&
3266       IS_ADDRESS_OF_OP (parms->right))
3267     parms->right->left->lvalue = 1;
3268
3269   parms->opval.oprnd =
3270     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3271
3272   parms->type = EX_OPERAND;
3273   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3274                 SPEC_ARGREG(parms->ftype);
3275 }
3276
3277 /*-----------------------------------------------------------------*/
3278 /* geniCodeParms - generates parameters                            */
3279 /*-----------------------------------------------------------------*/
3280 value *
3281 geniCodeParms (ast * parms, value *argVals, int *stack,
3282                sym_link * ftype, int lvl)
3283 {
3284   iCode *ic;
3285   operand *pval;
3286
3287   if (!parms)
3288     return argVals;
3289
3290   if (argVals==NULL) {
3291     // first argument
3292     argVals = FUNC_ARGS (ftype);
3293   }
3294
3295   /* if this is a param node then do the left & right */
3296   if (parms->type == EX_OP && parms->opval.op == PARAM)
3297     {
3298       argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3299       argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3300       return argVals;
3301     }
3302
3303   /* get the parameter value */
3304   if (parms->type == EX_OPERAND)
3305     pval = parms->opval.oprnd;
3306   else
3307     {
3308       /* maybe this else should go away ?? */
3309       /* hack don't like this but too lazy to think of
3310          something better */
3311       if (IS_ADDRESS_OF_OP (parms))
3312         parms->left->lvalue = 1;
3313
3314       if (IS_CAST_OP (parms) &&
3315           IS_PTR (parms->ftype) &&
3316           IS_ADDRESS_OF_OP (parms->right))
3317         parms->right->left->lvalue = 1;
3318
3319       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3320     }
3321
3322   /* if register parm then make it a send */
3323   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3324       IFFUNC_ISBUILTIN(ftype))
3325     {
3326       ic = newiCode (SEND, pval, NULL);
3327       ic->argreg = SPEC_ARGREG(parms->etype);
3328       ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3329       ADDTOCHAIN (ic);
3330     }
3331   else
3332     {
3333       /* now decide whether to push or assign */
3334       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3335         {
3336
3337           /* assign */
3338           operand *top = operandFromSymbol (argVals->sym);
3339           /* clear useDef and other bitVectors */
3340           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3341           geniCodeAssign (top, pval, 1, 0);
3342         }
3343       else
3344         {
3345           sym_link *p = operandType (pval);
3346           /* push */
3347           ic = newiCode (IPUSH, pval, NULL);
3348           ic->parmPush = 1;
3349           /* update the stack adjustment */
3350           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3351           ADDTOCHAIN (ic);
3352         }
3353     }
3354
3355   argVals=argVals->next;
3356   return argVals;
3357 }
3358
3359 /*-----------------------------------------------------------------*/
3360 /* geniCodeCall - generates temp code for calling                  */
3361 /*-----------------------------------------------------------------*/
3362 operand *
3363 geniCodeCall (operand * left, ast * parms,int lvl)
3364 {
3365   iCode *ic;
3366   operand *result;
3367   sym_link *type, *etype;
3368   sym_link *ftype;
3369   int stack = 0;
3370
3371   if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3372       !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3373     werror (E_FUNCTION_EXPECTED);
3374     return operandFromValue(valueFromLit(0));
3375   }
3376
3377   /* take care of parameters with side-effecting
3378      function calls in them, this is required to take care
3379      of overlaying function parameters */
3380   geniCodeSEParms (parms,lvl);
3381
3382   ftype = operandType (left);
3383   if (IS_FUNCPTR (ftype))
3384     ftype = ftype->next;
3385
3386   /* first the parameters */
3387   geniCodeParms (parms, NULL, &stack, ftype, lvl);
3388
3389   /* now call : if symbol then pcall */
3390   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3391     ic = newiCode (PCALL, left, NULL);
3392   } else {
3393     ic = newiCode (CALL, left, NULL);
3394   }
3395
3396   type = copyLinkChain (ftype->next);
3397   etype = getSpec (type);
3398   SPEC_EXTR (etype) = 0;
3399   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3400
3401   ADDTOCHAIN (ic);
3402
3403   /* stack adjustment after call */
3404   ic->parmBytes = stack;
3405
3406   return result;
3407 }
3408
3409 /*-----------------------------------------------------------------*/
3410 /* geniCodeReceive - generate intermediate code for "receive"      */
3411 /*-----------------------------------------------------------------*/
3412 static void
3413 geniCodeReceive (value * args, operand * func)
3414 {
3415   unsigned char paramByteCounter = 0;
3416
3417   /* for all arguments that are passed in registers */
3418   while (args)
3419     {
3420       if (IS_REGPARM (args->etype))
3421         {
3422           operand *opr = operandFromValue (args);
3423           operand *opl;
3424           symbol *sym = OP_SYMBOL (opr);
3425           iCode *ic;
3426
3427           /* we will use it after all optimizations
3428              and before liveRange calculation */
3429           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3430             {
3431
3432               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3433                   options.stackAuto == 0 &&
3434                   (!(options.model == MODEL_FLAT24)) )
3435                 {
3436                 }
3437               else
3438                 {
3439                   opl = newiTempOperand (args->type, 0);
3440                   sym->reqv = opl;
3441                   sym->reqv->key = sym->key;
3442                   OP_SYMBOL (sym->reqv)->key = sym->key;
3443                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3444                   OP_SYMBOL (sym->reqv)->islocal = 0;
3445                   SPIL_LOC (sym->reqv) = sym;
3446                 }
3447             }
3448
3449           ic = newiCode (RECEIVE, func, NULL);
3450           ic->argreg = SPEC_ARGREG(args->etype);
3451           if (ic->argreg == 1) {
3452               currFunc->recvSize = getSize (sym->type);
3453           }
3454           IC_RESULT (ic) = opr;
3455
3456           /* misuse of parmBytes (normally used for functions)
3457            * to save estimated stack position of this argument.
3458            * Normally this should be zero for RECEIVE iCodes.
3459            * No idea if this causes side effects on other ports. - dw
3460            */
3461           ic->parmBytes = paramByteCounter;
3462
3463           /* what stack position do we have? */
3464           paramByteCounter += getSize (sym->type);
3465
3466           ADDTOCHAIN (ic);
3467         }
3468
3469       args = args->next;
3470     }
3471 }
3472
3473 /*-----------------------------------------------------------------*/
3474 /* geniCodeFunctionBody - create the function body                 */
3475 /*-----------------------------------------------------------------*/
3476 void
3477 geniCodeFunctionBody (ast * tree,int lvl)
3478 {
3479   iCode *ic;
3480   operand *func;
3481   sym_link *fetype;
3482   int savelineno;
3483
3484   /* reset the auto generation */
3485   /* numbers */
3486   iTempNum = 0;
3487   iTempLblNum = 0;
3488   operandKey = 0;
3489   iCodeKey = 0;
3490   func = ast2iCode (tree->left,lvl+1);
3491   fetype = getSpec (operandType (func));
3492
3493   savelineno = lineno;
3494   lineno = OP_SYMBOL (func)->lineDef;
3495   /* create an entry label */
3496   geniCodeLabel (entryLabel);
3497   lineno = savelineno;
3498
3499   /* create a proc icode */
3500   ic = newiCode (FUNCTION, func, NULL);
3501   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3502   ic->tree = tree;
3503
3504   ADDTOCHAIN (ic);
3505
3506   /* for all parameters that are passed
3507      on registers add a "receive" */
3508   geniCodeReceive (tree->values.args, func);
3509
3510   /* generate code for the body */
3511   ast2iCode (tree->right,lvl+1);
3512
3513   /* create a label for return */
3514   geniCodeLabel (returnLabel);
3515
3516   /* now generate the end proc */
3517   ic = newiCode (ENDFUNCTION, func, NULL);
3518   ic->tree = tree;
3519   ADDTOCHAIN (ic);
3520   return;
3521 }
3522
3523 /*-----------------------------------------------------------------*/
3524 /* geniCodeReturn - gen icode for 'return' statement               */
3525 /*-----------------------------------------------------------------*/
3526 void
3527 geniCodeReturn (operand * op)
3528 {
3529   iCode *ic;
3530
3531   /* if the operand is present force an rvalue */
3532   if (op)
3533     op = geniCodeRValue (op, FALSE);
3534
3535   ic = newiCode (RETURN, op, NULL);
3536   ADDTOCHAIN (ic);
3537 }
3538
3539 /*-----------------------------------------------------------------*/
3540 /* geniCodeIfx - generates code for extended if statement          */
3541 /*-----------------------------------------------------------------*/
3542 void
3543 geniCodeIfx (ast * tree,int lvl)
3544 {
3545   iCode *ic;
3546   operand *condition = ast2iCode (tree->left,lvl+1);
3547   sym_link *cetype;
3548
3549   /* if condition is null then exit */
3550   if (!condition)
3551     goto exit;
3552   else
3553     condition = geniCodeRValue (condition, FALSE);
3554
3555   cetype = getSpec (operandType (condition));
3556   /* if the condition is a literal */
3557   if (IS_LITERAL (cetype))
3558     {
3559       if (floatFromVal (condition->operand.valOperand))
3560         {
3561           if (tree->trueLabel)
3562             geniCodeGoto (tree->trueLabel);
3563           else
3564             assert (0);
3565         }
3566       else
3567         {
3568           if (tree->falseLabel)
3569             geniCodeGoto (tree->falseLabel);
3570         }
3571       goto exit;
3572     }
3573
3574   if (tree->trueLabel)
3575     {
3576       ic = newiCodeCondition (condition,
3577                               tree->trueLabel,
3578                               NULL);
3579       ADDTOCHAIN (ic);
3580
3581       if (tree->falseLabel)
3582         geniCodeGoto (tree->falseLabel);
3583     }
3584   else
3585     {
3586       ic = newiCodeCondition (condition,
3587                               NULL,
3588                               tree->falseLabel);
3589       ADDTOCHAIN (ic);
3590     }
3591
3592 exit:
3593   ast2iCode (tree->right,lvl+1);
3594 }
3595
3596 /*-----------------------------------------------------------------*/
3597 /* geniCodeJumpTable - tries to create a jump table for switch     */
3598 /*-----------------------------------------------------------------*/
3599 int
3600 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3601 {
3602   int min, max, cnt = 1;
3603   int i, t;
3604   value *vch;
3605   iCode *ic;
3606   operand *boundary;
3607   symbol *falseLabel;
3608   set *labels = NULL;
3609   int needRangeCheck = !optimize.noJTabBoundary
3610                        || tree->values.switchVals.swDefault;
3611   sym_link *cetype = getSpec (operandType (cond));
3612   int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3613   int sizeofMatchJump, sizeofJumpTable;
3614   int sizeIndex;
3615
3616   if (!tree || !caseVals)
3617     return 0;
3618
3619   /* the criteria for creating a jump table is */
3620   /* all integer numbers between the maximum & minimum must */
3621   /* be present , the maximum value should not exceed 255 */
3622   /* If not all integer numbers are present the algorithm */
3623   /* inserts jumps to the default label for the missing numbers */
3624   /* and decides later whether it is worth it */
3625   min = (int) floatFromVal (vch = caseVals);
3626
3627   while (vch->next)
3628     {
3629       cnt++;
3630       vch = vch->next;
3631     }
3632   max = (int) floatFromVal (vch);
3633
3634   /* Exit if the range is too large to handle with a jump table. */
3635   if (1 + max - min > port->jumptableCost.maxCount)
3636     return 0;
3637
3638   switch (getSize (operandType (cond)))
3639     {
3640     case 1: sizeIndex = 0; break;
3641     case 2: sizeIndex = 1; break;
3642     case 4: sizeIndex = 2; break;
3643     default: return 0;
3644     }
3645
3646   /* Compute the size cost of the range check and subtraction. */
3647   sizeofMinCost = 0;
3648   sizeofZeroMinCost = 0;
3649   sizeofMaxCost = 0;
3650   if (needRangeCheck)
3651     {
3652       if (!(min==0 && IS_UNSIGNED (cetype)))
3653         sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3654       if (!IS_UNSIGNED (cetype))
3655         sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3656       sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3657     }
3658   if (min)
3659     sizeofMinCost += port->jumptableCost.sizeofSubtract;
3660
3661   /* If the size cost of handling a non-zero minimum exceeds the */
3662   /* cost of extending the range down to zero, then it might be */
3663   /* better to extend the range to zero. */
3664   if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3665                  >= (min * port->jumptableCost.sizeofElement))
3666     {
3667       /* Only extend the jump table if it would still be manageable. */
3668       if (1 + max <= port->jumptableCost.maxCount)
3669         {
3670           min = 0;
3671           if (IS_UNSIGNED (cetype))
3672             sizeofMinCost = 0;
3673           else
3674             sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3675         }
3676     }
3677
3678   /* Compute the total size cost of a jump table. */
3679   sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3680                      + port->jumptableCost.sizeofDispatch
3681                      + sizeofMinCost + sizeofMaxCost;
3682
3683   /* Compute the total size cost of a match & jump sequence */
3684   sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3685
3686   /* If the size cost of the jump table is uneconomical then exit */
3687   if (sizeofMatchJump <  sizeofJumpTable)
3688     return 0;
3689
3690   /* The jump table is preferable. */
3691
3692   /* First, a label for the default or missing cases. */
3693   if (tree->values.switchVals.swDefault)
3694     {
3695       SNPRINTF (buffer, sizeof(buffer),
3696                 "_default_%d",
3697                 tree->values.switchVals.swNum);
3698     }
3699   else
3700     {
3701       SNPRINTF (buffer, sizeof(buffer),
3702                 "_swBrk_%d",
3703                 tree->values.switchVals.swNum);
3704     }
3705   falseLabel = newiTempLabel (buffer);
3706
3707   /* Build the list of labels for the jump table. */
3708   vch = caseVals;
3709   t = (int) floatFromVal (vch);
3710   for (i=min; i<=max; i++)
3711     {
3712       if (vch && t==i)
3713         {
3714           /* Explicit case: make a new label for it. */
3715           SNPRINTF (buffer, sizeof(buffer),
3716                     "_case_%d_%d",
3717                     tree->values.switchVals.swNum,
3718                     i);
3719           addSet (&labels, newiTempLabel (buffer));
3720           vch = vch->next;
3721           if (vch)
3722             t = (int) floatFromVal (vch);
3723         }
3724       else
3725         {
3726           /* Implicit case: use the default label. */
3727           addSet (&labels, falseLabel);
3728         }
3729     }
3730
3731   /* first we rule out the boundary conditions */
3732   /* if only optimization says so */
3733   if (needRangeCheck)
3734     {
3735       sym_link *cetype = getSpec (operandType (cond));
3736       /* no need to check the lower bound if
3737          the condition is unsigned & minimum value is zero */
3738       if (!(min == 0 && IS_UNSIGNED (cetype)))
3739         {
3740           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3741           ic = newiCodeCondition (boundary, falseLabel, NULL);
3742           ADDTOCHAIN (ic);
3743         }
3744
3745       /* now for upper bounds */
3746       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3747       ic = newiCodeCondition (boundary, falseLabel, NULL);
3748       ADDTOCHAIN (ic);
3749     }
3750
3751   /* if the min is not zero then we no make it zero */
3752   if (min)
3753     {
3754       cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3755       if (!IS_LITERAL(getSpec(operandType(cond))))
3756         setOperandType (cond, UCHARTYPE);
3757     }
3758
3759   /* now create the jumptable */
3760   ic = newiCode (JUMPTABLE, NULL, NULL);
3761   IC_JTCOND (ic) = cond;
3762   IC_JTLABELS (ic) = labels;
3763   ADDTOCHAIN (ic);
3764   return 1;
3765 }
3766
3767 /*-----------------------------------------------------------------*/
3768 /* geniCodeSwitch - changes a switch to a if statement             */
3769 /*-----------------------------------------------------------------*/
3770 void
3771 geniCodeSwitch (ast * tree,int lvl)
3772 {
3773   iCode *ic;
3774   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3775   value *caseVals = tree->values.switchVals.swVals;
3776   symbol *trueLabel, *falseLabel;
3777
3778   /* If the condition is a literal, then just jump to the */
3779   /* appropriate case label. */
3780   if (IS_LITERAL(getSpec(operandType(cond))))
3781     {
3782       int switchVal, caseVal;
3783
3784       switchVal = (int) floatFromVal (cond->operand.valOperand);
3785       while (caseVals)
3786         {
3787           caseVal = (int) floatFromVal (caseVals);
3788           if (caseVal == switchVal)
3789             {
3790               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3791                         tree->values.switchVals.swNum, caseVal);
3792               trueLabel = newiTempLabel (buffer);
3793               geniCodeGoto (trueLabel);
3794               goto jumpTable;
3795             }
3796           caseVals = caseVals->next;
3797         }
3798       goto defaultOrBreak;
3799     }
3800
3801   /* If cond is volatile, it might change while we are trying to */
3802   /* find the matching case. To avoid this possibility, make a   */
3803   /* non-volatile copy to use instead. */
3804   if (IS_OP_VOLATILE (cond))
3805     {
3806       operand * newcond;
3807       iCode * ic;
3808
3809       newcond = newiTempOperand (operandType (cond), TRUE);
3810       newcond->isvolatile = 0;
3811       ic = newiCode ('=', NULL, cond);
3812       IC_RESULT (ic) = newcond;
3813       ADDTOCHAIN (ic);
3814       cond = newcond;
3815     }
3816
3817   /* if we can make this a jump table */
3818   if (geniCodeJumpTable (cond, caseVals, tree))
3819     goto jumpTable;             /* no need for the comparison */
3820
3821   /* for the cases defined do */
3822   while (caseVals)
3823     {
3824
3825       operand *compare = geniCodeLogic (cond,
3826                                         operandFromValue (caseVals),
3827                                         EQ_OP);
3828
3829       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3830                tree->values.switchVals.swNum,
3831                (int) floatFromVal (caseVals));
3832       trueLabel = newiTempLabel (buffer);
3833
3834       ic = newiCodeCondition (compare, trueLabel, NULL);
3835       ADDTOCHAIN (ic);
3836       caseVals = caseVals->next;
3837     }
3838
3839
3840 defaultOrBreak:
3841   /* if default is present then goto break else break */
3842   if (tree->values.switchVals.swDefault)
3843     {
3844         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3845     }
3846   else
3847     {
3848         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3849     }
3850
3851   falseLabel = newiTempLabel (buffer);
3852   geniCodeGoto (falseLabel);
3853
3854 jumpTable:
3855   ast2iCode (tree->right,lvl+1);
3856 }
3857
3858 /*-----------------------------------------------------------------*/
3859 /* geniCodeInline - intermediate code for inline assembler         */
3860 /*-----------------------------------------------------------------*/
3861 static void
3862 geniCodeInline (ast * tree)
3863 {
3864   iCode *ic;
3865
3866   ic = newiCode (INLINEASM, NULL, NULL);
3867   IC_INLINE (ic) = tree->values.inlineasm;
3868   ADDTOCHAIN (ic);
3869 }
3870
3871 /*-----------------------------------------------------------------*/
3872 /* geniCodeArrayInit - intermediate code for array initializer     */
3873 /*-----------------------------------------------------------------*/
3874 static void
3875 geniCodeArrayInit (ast * tree, operand *array)
3876 {
3877   iCode *ic;
3878
3879   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3880     ic = newiCode (ARRAYINIT, array, NULL);
3881     IC_ARRAYILIST (ic) = tree->values.constlist;
3882   } else {
3883     operand *left=newOperand(), *right=newOperand();
3884     left->type=right->type=SYMBOL;
3885     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3886     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3887     ic = newiCode (ARRAYINIT, left, right);
3888   }
3889   ADDTOCHAIN (ic);
3890 }
3891
3892 /*-----------------------------------------------------------------*/
3893 /* geniCodeCritical - intermediate code for a critical statement   */
3894 /*-----------------------------------------------------------------*/
3895 static void
3896 geniCodeCritical (ast *tree, int lvl)
3897 {
3898   iCode *ic;
3899   operand *op = NULL;
3900   sym_link *type;
3901
3902   if (!options.stackAuto)
3903     {
3904       type = newLink(SPECIFIER);
3905       SPEC_VOLATILE(type) = 1;
3906       SPEC_NOUN(type) = V_BIT;
3907       SPEC_SCLS(type) = S_BIT;
3908       SPEC_BLEN(type) = 1;
3909       SPEC_BSTR(type) = 0;
3910       op = newiTempOperand(type, 1);
3911     }
3912
3913   /* If op is NULL, the original interrupt state will saved on */
3914   /* the stack. Otherwise, it will be saved in op. */
3915
3916   /* Generate a save of the current interrupt state & disable */
3917   ic = newiCode (CRITICAL, NULL, NULL);
3918   IC_RESULT (ic) = op;
3919   ADDTOCHAIN (ic);
3920
3921   /* Generate the critical code sequence */
3922   if (tree->left && tree->left->type == EX_VALUE)
3923     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3924   else
3925     ast2iCode (tree->left,lvl+1);
3926
3927   /* Generate a restore of the original interrupt state */
3928   ic = newiCode (ENDCRITICAL, NULL, op);
3929   ADDTOCHAIN (ic);
3930 }
3931
3932 /*-----------------------------------------------------------------*/
3933 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3934 /* particular case. Ie : assigning or dereferencing array or ptr   */
3935 /*-----------------------------------------------------------------*/
3936 set * lvaluereqSet = NULL;
3937 typedef struct lvalItem
3938   {
3939     int req;
3940     int lvl;
3941   }
3942 lvalItem;
3943
3944 /*-----------------------------------------------------------------*/
3945 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3946 /*-----------------------------------------------------------------*/
3947 void addLvaluereq(int lvl)
3948 {
3949   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3950   lpItem->req=1;
3951   lpItem->lvl=lvl;
3952   addSetHead(&lvaluereqSet,lpItem);
3953
3954 }
3955 /*-----------------------------------------------------------------*/
3956 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3957 /*-----------------------------------------------------------------*/
3958 void delLvaluereq()
3959 {
3960   lvalItem * lpItem;
3961   lpItem = getSet(&lvaluereqSet);
3962   if(lpItem) Safe_free(lpItem);
3963 }
3964 /*-----------------------------------------------------------------*/
3965 /* clearLvaluereq - clear lvalreq flag                             */
3966 /*-----------------------------------------------------------------*/
3967 void clearLvaluereq()
3968 {
3969   lvalItem * lpItem;
3970   lpItem = peekSet(lvaluereqSet);
3971   if(lpItem) lpItem->req = 0;
3972 }
3973 /*-----------------------------------------------------------------*/
3974 /* getLvaluereq - get the last lvalreq level                       */
3975 /*-----------------------------------------------------------------*/
3976 int getLvaluereqLvl()
3977 {
3978   lvalItem * lpItem;
3979   lpItem = peekSet(lvaluereqSet);
3980   if(lpItem) return lpItem->lvl;
3981   return 0;
3982 }
3983 /*-----------------------------------------------------------------*/
3984 /* isLvaluereq - is lvalreq valid for this level ?                 */
3985 /*-----------------------------------------------------------------*/
3986 int isLvaluereq(int lvl)
3987 {
3988   lvalItem * lpItem;
3989   lpItem = peekSet(lvaluereqSet);
3990   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3991   return 0;
3992 }
3993
3994 /*-----------------------------------------------------------------*/
3995 /* ast2iCode - creates an icodeList from an ast                    */
3996 /*-----------------------------------------------------------------*/
3997 operand *
3998 ast2iCode (ast * tree,int lvl)
3999 {
4000   operand *left = NULL;
4001   operand *right = NULL;
4002   if (!tree)
4003     return NULL;
4004
4005   /* set the global variables for filename & line number */
4006   if (tree->filename)
4007     filename = tree->filename;
4008   if (tree->lineno)
4009     lineno = tree->lineno;
4010   if (tree->block)
4011     block = tree->block;
4012   if (tree->level)
4013     scopeLevel = tree->level;
4014   if (tree->seqPoint)
4015     seqPoint = tree->seqPoint;
4016
4017   if (tree->type == EX_VALUE)
4018     return operandFromValue (tree->opval.val);
4019
4020   if (tree->type == EX_LINK)
4021     return operandFromLink (tree->opval.lnk);
4022
4023   /* if we find a nullop */
4024   if (tree->type == EX_OP &&
4025      (tree->opval.op == NULLOP ||
4026      tree->opval.op == BLOCK))
4027     {
4028       if (tree->left && tree->left->type == EX_VALUE)
4029         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4030       else
4031         ast2iCode (tree->left,lvl+1);
4032       if (tree->right && tree->right->type == EX_VALUE)
4033         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4034       else
4035         ast2iCode (tree->right,lvl+1);
4036       return NULL;
4037     }
4038
4039   /* special cases for not evaluating */
4040   if (tree->opval.op != ':' &&
4041       tree->opval.op != '?' &&
4042       tree->opval.op != CALL &&
4043       tree->opval.op != IFX &&
4044       tree->opval.op != AND_OP &&
4045       tree->opval.op != OR_OP &&
4046       tree->opval.op != LABEL &&
4047       tree->opval.op != GOTO &&
4048       tree->opval.op != SWITCH &&
4049       tree->opval.op != FUNCTION &&
4050       tree->opval.op != INLINEASM &&
4051       tree->opval.op != CRITICAL)
4052     {
4053
4054         if (IS_ASSIGN_OP (tree->opval.op) ||
4055            IS_DEREF_OP (tree) ||
4056            (tree->opval.op == '&' && !tree->right) ||
4057            tree->opval.op == PTR_OP)
4058           {
4059             addLvaluereq(lvl);
4060             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4061                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4062               clearLvaluereq();
4063
4064             left = operandFromAst (tree->left,lvl);
4065             delLvaluereq();
4066             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4067               left = geniCodeRValue (left, TRUE);
4068           }
4069         else
4070           {
4071             left = operandFromAst (tree->left,lvl);
4072           }
4073         if (tree->opval.op == INC_OP ||
4074             tree->opval.op == DEC_OP)
4075           {
4076             addLvaluereq(lvl);
4077             right = operandFromAst (tree->right,lvl);
4078             delLvaluereq();
4079           }
4080         else
4081           {
4082             right = operandFromAst (tree->right,lvl);
4083           }
4084       }
4085
4086   /* now depending on the type of operand */
4087   /* this will be a biggy                 */
4088   switch (tree->opval.op)
4089     {
4090
4091     case '[':                   /* array operation */
4092       {
4093         //sym_link *ltype = operandType (left);
4094         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4095         left = geniCodeRValue (left, FALSE);
4096         right = geniCodeRValue (right, TRUE);
4097       }
4098
4099       return geniCodeArray (left, right,lvl);
4100
4101     case '.':                   /* structure dereference */
4102       if (IS_PTR (operandType (left)))
4103         left = geniCodeRValue (left, TRUE);
4104       else
4105         left = geniCodeRValue (left, FALSE);
4106
4107       return geniCodeStruct (left, right, tree->lvalue);
4108
4109     case PTR_OP:                /* structure pointer dereference */
4110       {
4111         sym_link *pType;
4112         pType = operandType (left);
4113         left = geniCodeRValue (left, TRUE);
4114
4115         setOClass (pType, getSpec (operandType (left)));
4116       }
4117
4118       return geniCodeStruct (left, right, tree->lvalue);
4119
4120     case INC_OP:                /* increment operator */
4121       if (left)
4122         return geniCodePostInc (left);
4123       else
4124         return geniCodePreInc (right, tree->lvalue);
4125
4126     case DEC_OP:                /* decrement operator */
4127       if (left)
4128         return geniCodePostDec (left);
4129       else
4130         return geniCodePreDec (right, tree->lvalue);
4131
4132     case '&':                   /* bitwise and or address of operator */
4133       if (right)
4134         {                       /* this is a bitwise operator   */
4135           left = geniCodeRValue (left, FALSE);
4136           right = geniCodeRValue (right, FALSE);
4137           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4138         }
4139       else
4140         return geniCodeAddressOf (left);
4141
4142     case '|':                   /* bitwise or & xor */
4143     case '^':
4144       return geniCodeBitwise (geniCodeRValue (left, FALSE),
4145                               geniCodeRValue (right, FALSE),
4146                               tree->opval.op,
4147                               tree->ftype);
4148
4149     case '/':
4150       return geniCodeDivision (geniCodeRValue (left, FALSE),
4151                                geniCodeRValue (right, FALSE),
4152                                getResultTypeFromType (tree->ftype));
4153
4154     case '%':
4155       return geniCodeModulus (geniCodeRValue (left, FALSE),
4156                               geniCodeRValue (right, FALSE),
4157                               getResultTypeFromType (tree->ftype));
4158     case '*':
4159       if (right)
4160         return geniCodeMultiply (geniCodeRValue (left, FALSE),
4161                                  geniCodeRValue (right, FALSE),
4162                                  getResultTypeFromType (tree->ftype));
4163       else
4164         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4165
4166     case '-':
4167       if (right)
4168         return geniCodeSubtract (geniCodeRValue (left, FALSE),
4169                                  geniCodeRValue (right, FALSE),
4170                                  getResultTypeFromType (tree->ftype));
4171       else
4172         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4173
4174     case '+':
4175       if (right)
4176         return geniCodeAdd (geniCodeRValue (left, FALSE),
4177                             geniCodeRValue (right, FALSE),
4178                             getResultTypeFromType (tree->ftype),
4179                             lvl);
4180       else
4181         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
4182
4183     case LEFT_OP:
4184       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4185                                 geniCodeRValue (right, FALSE),
4186                                 getResultTypeFromType (tree->ftype));
4187
4188     case RIGHT_OP:
4189       return geniCodeRightShift (geniCodeRValue (left, FALSE),
4190                                  geniCodeRValue (right, FALSE));
4191     case CAST:
4192 #if 0 // this indeed needs a second thought
4193       {
4194         operand *op;
4195
4196         // let's keep this simple: get the rvalue we need
4197         op=geniCodeRValue (right, FALSE);
4198         // now cast it to whatever we want
4199         op=geniCodeCast (operandType(left), op, FALSE);
4200         // if this is going to be used as an lvalue, make it so
4201         if (tree->lvalue) {
4202           op->isaddr=1;
4203         }
4204         return op;
4205       }
4206 #else // bug #604575, is it a bug ????
4207       return geniCodeCast (operandType (left),
4208                            geniCodeRValue (right, FALSE), FALSE);
4209 #endif
4210
4211     case '~':
4212     case RRC:
4213     case RLC:
4214     case SWAP:
4215       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4216
4217     case '!':
4218     case GETHBIT:
4219       {
4220         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4221         setOperandType (op, UCHARTYPE);
4222         return op;
4223       }
4224     case GETABIT:
4225     case GETBYTE:
4226     case GETWORD:
4227       {
4228         operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4229                                       geniCodeRValue (right, FALSE),
4230                                       tree->opval.op);
4231         setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4232         return op;
4233       }
4234     case AND_OP:
4235     case OR_OP:
4236       return geniCodeLogicAndOr (tree, lvl);
4237     case '>':
4238     case '<':
4239     case LE_OP:
4240     case GE_OP:
4241     case EQ_OP:
4242     case NE_OP:
4243       /* different compilers (even different gccs) evaluate
4244          the two calls in a different order. to get the same
4245          result on all machines we've to specify a clear sequence.
4246       return geniCodeLogic (geniCodeRValue (left, FALSE),
4247                             geniCodeRValue (right, FALSE),
4248                             tree->opval.op);
4249       */
4250       {
4251         operand *leftOp, *rightOp;
4252
4253         leftOp  = geniCodeRValue (left , FALSE);
4254         rightOp = geniCodeRValue (right, FALSE);
4255
4256         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4257       }
4258     case '?':
4259       return geniCodeConditional (tree,lvl);
4260
4261     case SIZEOF:
4262       return operandFromLit (getSize (tree->right->ftype));
4263
4264     case '=':
4265       {
4266         sym_link *rtype = operandType (right);
4267         sym_link *ltype = operandType (left);
4268         if (IS_PTR (rtype) && IS_ITEMP (right)
4269             && right->isaddr && compareType (rtype->next, ltype) == 1)
4270           right = geniCodeRValue (right, TRUE);
4271         else
4272           right = geniCodeRValue (right, FALSE);
4273
4274         geniCodeAssign (left, right, 0, 1);
4275         return right;
4276       }
4277     case MUL_ASSIGN:
4278       return
4279         geniCodeAssign (left,
4280                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4281                                                   FALSE),
4282                                   geniCodeRValue (right, FALSE),
4283                                   getResultTypeFromType (tree->ftype)),
4284                         0, 1);
4285
4286     case DIV_ASSIGN:
4287       return
4288         geniCodeAssign (left,
4289                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4290                                                   FALSE),
4291                                   geniCodeRValue (right, FALSE),
4292                                   getResultTypeFromType (tree->ftype)),
4293                         0, 1);
4294     case MOD_ASSIGN:
4295       return
4296         geniCodeAssign (left,
4297                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4298                                                   FALSE),
4299                                   geniCodeRValue (right, FALSE),
4300                                   getResultTypeFromType (tree->ftype)),
4301                         0, 1);
4302     case ADD_ASSIGN:
4303       {
4304         sym_link *rtype = operandType (right);
4305         sym_link *ltype = operandType (left);
4306         if (IS_PTR (rtype) && IS_ITEMP (right)
4307             && right->isaddr && compareType (rtype->next, ltype) == 1)
4308           right = geniCodeRValue (right, TRUE);
4309         else
4310           right = geniCodeRValue (right, FALSE);
4311
4312
4313         return geniCodeAssign (left,
4314                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4315                                                   FALSE),
4316                                   right,
4317                                   getResultTypeFromType (tree->ftype),
4318                                   lvl),
4319                                0, 1);
4320       }
4321     case SUB_ASSIGN:
4322       {
4323         sym_link *rtype = operandType (right);
4324         sym_link *ltype = operandType (left);
4325         if (IS_PTR (rtype) && IS_ITEMP (right)
4326             && right->isaddr && compareType (rtype->next, ltype) == 1)
4327           {
4328             right = geniCodeRValue (right, TRUE);
4329           }
4330         else
4331           {
4332             right = geniCodeRValue (right, FALSE);
4333           }
4334         return
4335           geniCodeAssign (left,
4336                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4337                                                   FALSE),
4338                                   right,
4339                                   getResultTypeFromType (tree->ftype)),
4340                           0, 1);
4341       }
4342     case LEFT_ASSIGN:
4343       return
4344         geniCodeAssign (left,
4345                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4346                                                    ,FALSE),
4347                                    geniCodeRValue (right, FALSE),
4348                                    getResultTypeFromType (tree->ftype)),
4349                         0, 1);
4350     case RIGHT_ASSIGN:
4351       return
4352         geniCodeAssign (left,
4353                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4354                                                    ,FALSE),
4355                                    geniCodeRValue (right, FALSE)), 0, 1);
4356     case AND_ASSIGN:
4357       return
4358         geniCodeAssign (left,
4359                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4360                                                   FALSE),
4361                                   geniCodeRValue (right, FALSE),
4362                                   BITWISEAND,
4363                                   operandType (left)), 0, 1);
4364     case XOR_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 OR_ASSIGN:
4373       return
4374         geniCodeAssign (left,
4375                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4376                                                    ,FALSE),
4377                                    geniCodeRValue (right, FALSE),
4378                                    '|',
4379                                    operandType (left)), 0, 1);
4380     case ',':
4381       return geniCodeRValue (right, FALSE);
4382
4383     case CALL:
4384       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4385                            tree->right,lvl);
4386     case LABEL:
4387       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4388       return ast2iCode (tree->right,lvl+1);
4389
4390     case GOTO:
4391       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4392       return ast2iCode (tree->right,lvl+1);
4393
4394     case FUNCTION:
4395       geniCodeFunctionBody (tree,lvl);
4396       return NULL;
4397
4398     case RETURN:
4399       geniCodeReturn (right);
4400       return NULL;
4401
4402     case IFX:
4403       geniCodeIfx (tree,lvl);
4404       return NULL;
4405
4406     case SWITCH:
4407       geniCodeSwitch (tree,lvl);
4408       return NULL;
4409
4410     case INLINEASM:
4411       geniCodeInline (tree);
4412       return NULL;
4413
4414     case ARRAYINIT:
4415         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4416         return NULL;
4417
4418     case CRITICAL:
4419         geniCodeCritical (tree, lvl);
4420     }
4421
4422   return NULL;
4423 }
4424
4425 /*-----------------------------------------------------------------*/
4426 /* reverseICChain - gets from the list and creates a linkedlist    */
4427 /*-----------------------------------------------------------------*/
4428 iCode *
4429 reverseiCChain ()
4430 {
4431   iCode *loop = NULL;
4432   iCode *prev = NULL;
4433
4434   while ((loop = getSet (&iCodeChain)))
4435     {
4436       loop->next = prev;
4437       if (prev)
4438         prev->prev = loop;
4439       prev = loop;
4440     }
4441
4442   return prev;
4443 }
4444
4445
4446 /*-----------------------------------------------------------------*/
4447 /* iCodeFromAst - given an ast will convert it to iCode            */
4448 /*-----------------------------------------------------------------*/
4449 iCode *
4450 iCodeFromAst (ast * tree)
4451 {
4452   returnLabel = newiTempLabel ("_return");
4453   entryLabel = newiTempLabel ("_entry");
4454   ast2iCode (tree,0);
4455   return reverseiCChain ();
4456 }
4457
4458 static const char *opTypeToStr(OPTYPE op)
4459 {
4460     switch(op)
4461     {
4462       case SYMBOL: return "symbol";
4463       case VALUE: return "value";
4464       case TYPE: return "type";
4465     }
4466     return "undefined type";
4467 }
4468
4469
4470 operand *validateOpType(operand         *op,
4471                         const char      *macro,
4472                         const char      *args,
4473                         OPTYPE          type,
4474                         const char      *file,
4475                         unsigned        line)
4476 {
4477     if (op && op->type == type)
4478     {
4479         return op;
4480     }
4481     fprintf(stderr,
4482             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4483             " expected %s, got %s\n",
4484             macro, args, file, line,
4485             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4486     exit(EXIT_FAILURE);
4487     return op; // never reached, makes compiler happy.
4488 }