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