* src/hc08/gen.c (hc08_emitDebuggerSymbol),
[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       sym->level &&             /* is a local 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       !IS_STATIC (sym->etype) &&        /* and not declared static  */
1537       !sym->islbl &&            /* not a label */
1538       ok &&                     /* farspace check */
1539       !IS_BITVAR (sym->etype)   /* not a bit variable */
1540     )
1541     {                                   
1542
1543       /* we will use it after all optimizations
1544          and before liveRange calculation */
1545       sym->reqv = newiTempOperand (sym->type, 0);
1546       sym->reqv->key = sym->key;
1547       OP_SYMBOL (sym->reqv)->prereqv = sym;
1548       OP_SYMBOL (sym->reqv)->key = sym->key;
1549       OP_SYMBOL (sym->reqv)->isreqv = 1;
1550       OP_SYMBOL (sym->reqv)->islocal = 1;
1551       OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1552       SPIL_LOC (sym->reqv) = sym;
1553     }
1554
1555   if (!IS_AGGREGATE (sym->type))
1556     {
1557       op = newOperand ();
1558       op->type = SYMBOL;
1559       op->operand.symOperand = sym;
1560       op->isaddr = 1;
1561       op->key = sym->key;
1562       op->isvolatile = isOperandVolatile (op, TRUE);
1563       op->isGlobal = isOperandGlobal (op);
1564       op->isPtr = IS_PTR (operandType (op));
1565       op->isParm = sym->_isparm;
1566       return op;
1567     }
1568
1569   /* create :-                     */
1570   /*    itemp = &[_symbol]         */
1571
1572   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1573   IC_LEFT (ic)->type = SYMBOL;
1574   IC_LEFT (ic)->operand.symOperand = sym;
1575   IC_LEFT (ic)->key = sym->key;
1576   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1577   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1578   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1579
1580   /* create result */
1581   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1582   if (IS_ARRAY (sym->type))
1583     {
1584       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1585       IC_RESULT (ic)->isaddr = 0;
1586     }
1587   else
1588     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1589
1590   ADDTOCHAIN (ic);
1591
1592   return IC_RESULT (ic);
1593 }
1594
1595 /*-----------------------------------------------------------------*/
1596 /* operandFromValue - creates an operand from value                */
1597 /*-----------------------------------------------------------------*/
1598 operand *
1599 operandFromValue (value * val)
1600 {
1601   operand *op;
1602
1603   /* if this is a symbol then do the symbol thing */
1604   if (val->sym)
1605     return operandFromSymbol (val->sym);
1606
1607   /* this is not a symbol */
1608   op = newOperand ();
1609   op->type = VALUE;
1610   op->operand.valOperand = val;
1611   op->isLiteral = isOperandLiteral (op);
1612   return op;
1613 }
1614
1615 /*-----------------------------------------------------------------*/
1616 /* operandFromLink - operand from typeChain                        */
1617 /*-----------------------------------------------------------------*/
1618 operand *
1619 operandFromLink (sym_link * type)
1620 {
1621   operand *op;
1622
1623   /* operand from sym_link */
1624   if (!type)
1625     return NULL;
1626
1627   op = newOperand ();
1628   op->type = TYPE;
1629   op->operand.typeOperand = copyLinkChain (type);
1630   return op;
1631 }
1632
1633 /*-----------------------------------------------------------------*/
1634 /* operandFromLit - makes an operand from a literal value          */
1635 /*-----------------------------------------------------------------*/
1636 operand *
1637 operandFromLit (double i)
1638 {
1639   return operandFromValue (valueFromLit (i));
1640 }
1641
1642 /*-----------------------------------------------------------------*/
1643 /* operandFromAst - creates an operand from an ast                 */
1644 /*-----------------------------------------------------------------*/
1645 operand *
1646 operandFromAst (ast * tree,int lvl)
1647 {
1648
1649   if (!tree)
1650     return NULL;
1651
1652   /* depending on type do */
1653   switch (tree->type)
1654     {
1655     case EX_OP:
1656       return ast2iCode (tree,lvl+1);
1657       break;
1658
1659     case EX_VALUE:
1660       return operandFromValue (tree->opval.val);
1661       break;
1662
1663     case EX_LINK:
1664       return operandFromLink (tree->opval.lnk);
1665       break;
1666
1667     default:
1668       assert (0);
1669     }
1670   
1671   /*  Just to keep the compiler happy */
1672   return (operand *) 0;
1673 }
1674
1675 /*-----------------------------------------------------------------*/
1676 /* setOperandType - sets the operand's type to the given type      */
1677 /*-----------------------------------------------------------------*/
1678 void 
1679 setOperandType (operand * op, sym_link * type)
1680 {
1681   /* depending on the type of operand */
1682   switch (op->type)
1683     {
1684
1685     case VALUE:
1686       op->operand.valOperand->etype =
1687         getSpec (op->operand.valOperand->type =
1688                  copyLinkChain (type));
1689       return;
1690
1691     case SYMBOL:
1692       if (op->operand.symOperand->isitmp)
1693         op->operand.symOperand->etype =
1694           getSpec (op->operand.symOperand->type =
1695                    copyLinkChain (type));
1696       else
1697         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1698                 "attempt to modify type of source");
1699       return;
1700
1701     case TYPE:
1702       op->operand.typeOperand = copyLinkChain (type);
1703       return;
1704     }
1705
1706 }
1707
1708 /*-----------------------------------------------------------------*/
1709 /* Get size in byte of ptr need to access an array                 */
1710 /*-----------------------------------------------------------------*/
1711 static int
1712 getArraySizePtr (operand * op)
1713 {
1714   sym_link *ltype = operandType(op);
1715
1716   if(IS_PTR(ltype))
1717     {
1718       int size = getSize(ltype);
1719       return(IS_GENPTR(ltype)?(size-1):size);
1720     }
1721
1722   if(IS_ARRAY(ltype))
1723     {
1724       sym_link *letype = getSpec(ltype);
1725       switch (PTR_TYPE (SPEC_OCLS (letype)))
1726         {
1727         case IPOINTER:
1728         case PPOINTER:
1729         case POINTER:
1730           return (PTRSIZE);
1731         case EEPPOINTER:
1732         case FPOINTER:
1733         case CPOINTER:
1734         case FUNCTION:
1735           return (FPTRSIZE);
1736         case GPOINTER:
1737           return (GPTRSIZE-1);
1738
1739         default:
1740           return (FPTRSIZE);
1741         }
1742     }
1743   return (FPTRSIZE);
1744 }
1745
1746 /*-----------------------------------------------------------------*/
1747 /* perform "usual unary conversions"                               */
1748 /*-----------------------------------------------------------------*/
1749 #if 0
1750 static operand *
1751 usualUnaryConversions (operand * op)
1752 {
1753   if (IS_INTEGRAL (operandType (op)))
1754     {
1755       if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1756         {
1757           /* Widen to int. */
1758           return geniCodeCast (INTTYPE, op, TRUE);
1759         }
1760     }
1761   return op;
1762 }
1763 #endif
1764
1765 /*-----------------------------------------------------------------*/
1766 /* perform "usual binary conversions"                              */
1767 /*-----------------------------------------------------------------*/
1768
1769 static sym_link *
1770 usualBinaryConversions (operand ** op1, operand ** op2,
1771                         RESULT_TYPE resultType, int op)
1772 {
1773   sym_link *ctype;
1774   sym_link *rtype = operandType (*op2);
1775   sym_link *ltype = operandType (*op1);
1776
1777   ctype = computeType (ltype, rtype, resultType, op);
1778
1779   switch (op)
1780     {
1781       case '*':
1782       case '/':
1783       case '%':
1784         if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1785           {
1786             /* one byte operations: keep signedness for code generator */
1787             return ctype;
1788           }
1789         break;
1790       default:
1791         break;
1792     }
1793
1794   *op1 = geniCodeCast (ctype, *op1, TRUE);
1795   *op2 = geniCodeCast (ctype, *op2, TRUE);
1796         
1797   return ctype;
1798 }
1799
1800 /*-----------------------------------------------------------------*/
1801 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1802 /*                          at address                             */
1803 /*-----------------------------------------------------------------*/
1804 operand *
1805 geniCodeRValue (operand * op, bool force)
1806 {
1807   iCode *ic;
1808   sym_link *type = operandType (op);
1809   sym_link *etype = getSpec (type);
1810
1811   /* if this is an array & already */
1812   /* an address then return this   */
1813   if (IS_AGGREGATE (type) ||
1814       (IS_PTR (type) && !force && !op->isaddr))
1815     return operandFromOperand (op);
1816
1817   /* if this is not an address then must be */
1818   /* rvalue already so return this one      */
1819   if (!op->isaddr)
1820     return op;
1821
1822   /* if this is not a temp symbol then */
1823   if (!IS_ITEMP (op) &&
1824       !force &&
1825       !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1826     {
1827       op = operandFromOperand (op);
1828       op->isaddr = 0;
1829       return op;
1830     }
1831
1832   if (IS_SPEC (type) &&
1833       IS_TRUE_SYMOP (op) &&
1834       (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1835       (options.model == MODEL_FLAT24) ))
1836     {
1837       op = operandFromOperand (op);
1838       op->isaddr = 0;
1839       return op;
1840     }
1841
1842   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1843   if (IS_PTR (type) && op->isaddr && force)
1844     type = type->next;
1845
1846   type = copyLinkChain (type);
1847
1848   IC_RESULT (ic) = newiTempOperand (type, 1);
1849   IC_RESULT (ic)->isaddr = 0;
1850
1851 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1852
1853   ADDTOCHAIN (ic);
1854
1855   return IC_RESULT (ic);
1856 }
1857
1858 /*-----------------------------------------------------------------*/
1859 /* geniCodeCast - changes the value from one type to another       */
1860 /*-----------------------------------------------------------------*/
1861 static operand *
1862 geniCodeCast (sym_link * type, operand * op, bool implicit)
1863 {
1864   iCode *ic;
1865   sym_link *optype;
1866   sym_link *opetype = getSpec (optype = operandType (op));
1867   sym_link *restype;
1868   int errors=0;
1869
1870   /* one of them has size zero then error */
1871   if (IS_VOID (optype))
1872     {
1873       werror (E_CAST_ZERO);
1874       return op;
1875     }
1876
1877   if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1878     {
1879       geniCodeArray2Ptr (op);
1880       op->isaddr = 0;
1881     }
1882     
1883   /* if the operand is already the desired type then do nothing */
1884   if (compareType (type, optype) == 1)
1885     return op;
1886
1887   /* if this is a literal then just change the type & return */
1888   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1889     {
1890       return operandFromValue (valCastLiteral (type,
1891                                                operandLitValue (op)));
1892     }
1893
1894   /* if casting to/from pointers, do some checking */
1895   if (IS_PTR(type)) { // to a pointer
1896     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1897       if (IS_INTEGRAL(optype)) {
1898         // maybe this is NULL, than it's ok.
1899         if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1900           if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1901             // no way to set the storage
1902             if (IS_LITERAL(optype)) {
1903               werror(E_LITERAL_GENERIC);
1904               errors++;
1905             } else {
1906               werror(E_NONPTR2_GENPTR);
1907               errors++;
1908             }
1909           } else if (implicit) {
1910             werror(W_INTEGRAL2PTR_NOCAST);
1911             errors++;
1912           }
1913         }
1914       } else {
1915         // shouldn't do that with float, array or structure unless to void
1916         if (!IS_VOID(getSpec(type)) &&
1917             !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1918           werror(E_INCOMPAT_TYPES);
1919           errors++;
1920         }
1921       }
1922     } else { // from a pointer to a pointer
1923       if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1924         // if not a pointer to a function
1925         if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1926           if (implicit) { // if not to generic, they have to match
1927             if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1928               werror(E_INCOMPAT_PTYPES);
1929               errors++;
1930             }
1931           }
1932         }
1933       }
1934     }
1935   } else { // to a non pointer
1936     if (IS_PTR(optype)) { // from a pointer
1937       if (implicit) { // sneaky
1938         if (IS_INTEGRAL(type)) {
1939           werror(W_PTR2INTEGRAL_NOCAST);
1940           errors++;
1941         } else { // shouldn't do that with float, array or structure
1942           werror(E_INCOMPAT_TYPES);
1943           errors++;
1944         }
1945       }
1946     }
1947   }
1948   if (errors) {
1949     printFromToType (optype, type);
1950   }
1951
1952   /* if they are the same size create an assignment */
1953   
1954   /* This seems very dangerous to me, since there are several */
1955   /* optimizations (for example, gcse) that don't notice the  */
1956   /* cast hidden in this assignement and may simplify an      */
1957   /* iCode to use the original (uncasted) operand.            */
1958   /* Unfortunately, other things break when this cast is      */
1959   /* made explicit. Need to fix this someday.                 */
1960   /* -- EEP, 2004/01/21                                       */
1961   if (getSize (type) == getSize (optype) &&
1962       !IS_BITFIELD (type) &&
1963       !IS_FLOAT (type) &&
1964       !IS_FLOAT (optype) &&
1965       ((IS_SPEC (type) && IS_SPEC (optype)) ||
1966        (!IS_SPEC (type) && !IS_SPEC (optype))))
1967     {
1968       ic = newiCode ('=', NULL, op);
1969       IC_RESULT (ic) = newiTempOperand (type, 0);
1970       SPIL_LOC (IC_RESULT (ic)) =
1971         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1972       IC_RESULT (ic)->isaddr = 0;
1973     }
1974   else
1975     {
1976       ic = newiCode (CAST, operandFromLink (type),
1977                      geniCodeRValue (op, FALSE));
1978
1979       IC_RESULT (ic) = newiTempOperand (type, 0);
1980     }
1981
1982   /* preserve the storage class & output class */
1983   /* of the original variable                  */
1984   restype = getSpec (operandType (IC_RESULT (ic)));
1985   if (!IS_LITERAL(opetype) &&
1986       !IS_BIT(opetype))
1987       SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1988   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1989
1990   ADDTOCHAIN (ic);
1991   return IC_RESULT (ic);
1992 }
1993
1994 /*-----------------------------------------------------------------*/
1995 /* geniCodeLabel - will create a Label                             */
1996 /*-----------------------------------------------------------------*/
1997 void
1998 geniCodeLabel (symbol * label)
1999 {
2000   iCode *ic;
2001
2002   ic = newiCodeLabelGoto (LABEL, label);
2003   ADDTOCHAIN (ic);
2004 }
2005
2006 /*-----------------------------------------------------------------*/
2007 /* geniCodeGoto  - will create a Goto                              */
2008 /*-----------------------------------------------------------------*/
2009 void
2010 geniCodeGoto (symbol * label)
2011 {
2012   iCode *ic;
2013
2014   ic = newiCodeLabelGoto (GOTO, label);
2015   ADDTOCHAIN (ic);
2016 }
2017
2018 /*-----------------------------------------------------------------*/
2019 /* geniCodeMultiply - gen intermediate code for multiplication     */
2020 /*-----------------------------------------------------------------*/
2021 static operand *
2022 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2023 {
2024   iCode *ic;
2025   int p2 = 0;
2026   sym_link *resType;
2027   LRTYPE;
2028
2029   /* if they are both literal then we know the result */
2030   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2031     return operandFromValue (valMult (left->operand.valOperand,
2032                                       right->operand.valOperand));
2033
2034   if (IS_LITERAL(retype)) {
2035     p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2036   }
2037
2038   resType = usualBinaryConversions (&left, &right, resultType, '*');
2039 #if 1
2040   rtype = operandType (right);
2041   retype = getSpec (rtype);
2042   ltype = operandType (left);
2043   letype = getSpec (ltype);
2044 #endif
2045
2046   /* if the right is a literal & power of 2 */
2047   /* then make it a left shift              */
2048   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2049      efficient in most cases than 2 bytes result = 2 bytes << literal
2050      if port has 1 byte muldiv */
2051   if (p2 && !IS_FLOAT (letype)
2052       && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2053            && (port->support.muldiv == 1))
2054       && strcmp (port->target, "pic14") != 0  /* don't shift for pic */
2055       && strcmp (port->target, "pic16") != 0)
2056     {
2057       if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2058         {
2059           /* LEFT_OP need same size for left and result, */
2060           left = geniCodeCast (resType, left, TRUE);
2061           ltype = operandType (left);
2062         }
2063       ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2064     }
2065   else
2066     {
2067       ic = newiCode ('*', left, right);         /* normal multiplication */
2068       /* if the size left or right > 1 then support routine */
2069       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2070         ic->supportRtn = 1;
2071
2072     }
2073   IC_RESULT (ic) = newiTempOperand (resType, 1);
2074
2075   ADDTOCHAIN (ic);
2076   return IC_RESULT (ic);
2077 }
2078
2079 /*-----------------------------------------------------------------*/
2080 /* geniCodeDivision - gen intermediate code for division           */
2081 /*-----------------------------------------------------------------*/
2082 static operand *
2083 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2084 {
2085   iCode *ic;
2086   int p2 = 0;
2087   sym_link *resType;
2088   sym_link *rtype = operandType (right);
2089   sym_link *retype = getSpec (rtype);
2090   sym_link *ltype = operandType (left);
2091   sym_link *letype = getSpec (ltype);
2092
2093   resType = usualBinaryConversions (&left, &right, resultType, '/');
2094
2095   /* if the right is a literal & power of 2
2096      and left is unsigned then make it a
2097      right shift */
2098   if (IS_LITERAL (retype) &&
2099       !IS_FLOAT (letype) &&
2100       IS_UNSIGNED(letype) &&
2101       (p2 = powof2 ((TYPE_UDWORD)
2102                     floatFromVal (right->operand.valOperand)))) {
2103     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2104   }
2105   else
2106     {
2107       ic = newiCode ('/', left, right);         /* normal division */
2108       /* if the size left or right > 1 then support routine */
2109       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2110         ic->supportRtn = 1;
2111     }
2112   IC_RESULT (ic) = newiTempOperand (resType, 0);
2113
2114   ADDTOCHAIN (ic);
2115   return IC_RESULT (ic);
2116 }
2117 /*-----------------------------------------------------------------*/
2118 /* geniCodeModulus  - gen intermediate code for modulus            */
2119 /*-----------------------------------------------------------------*/
2120 static operand *
2121 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2122 {
2123   iCode *ic;
2124   sym_link *resType;
2125   LRTYPE;
2126
2127   /* if they are both literal then we know the result */
2128   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2129     return operandFromValue (valMod (left->operand.valOperand,
2130                                      right->operand.valOperand));
2131
2132   resType = usualBinaryConversions (&left, &right, resultType, '%');
2133
2134   /* now they are the same size */
2135   ic = newiCode ('%', left, right);
2136
2137   /* if the size left or right > 1 then support routine */
2138   if (getSize (ltype) > 1 || getSize (rtype) > 1)
2139     ic->supportRtn = 1;
2140   IC_RESULT (ic) = newiTempOperand (resType, 0);
2141
2142   ADDTOCHAIN (ic);
2143   return IC_RESULT (ic);
2144 }
2145
2146 /*-----------------------------------------------------------------*/
2147 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
2148 /*-----------------------------------------------------------------*/
2149 operand *
2150 geniCodePtrPtrSubtract (operand * left, operand * right)
2151 {
2152   iCode *ic;
2153   operand *result;
2154   LRTYPE;
2155
2156   /* if they are both literals then */
2157   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2158     {
2159       result = operandFromValue (valMinus (left->operand.valOperand,
2160                                            right->operand.valOperand));
2161       goto subtractExit;
2162     }
2163
2164   ic = newiCode ('-', left, right);
2165
2166   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2167   ADDTOCHAIN (ic);
2168
2169 subtractExit:
2170   if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2171     return result;
2172   }
2173   
2174   // should we really do this? is this ANSI?
2175   return geniCodeDivision (result,
2176                            operandFromLit (getSize (ltype->next)),
2177                            FALSE);
2178 }
2179
2180 /*-----------------------------------------------------------------*/
2181 /* geniCodeSubtract - generates code for subtraction               */
2182 /*-----------------------------------------------------------------*/
2183 static operand *
2184 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2185 {
2186   iCode *ic;
2187   int isarray = 0;
2188   sym_link *resType;
2189   LRTYPE;
2190
2191   /* if they both pointers then */
2192   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2193       (IS_PTR (rtype) || IS_ARRAY (rtype)))
2194     return geniCodePtrPtrSubtract (left, right);
2195
2196   /* if they are both literal then we know the result */
2197   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2198       && left->isLiteral && right->isLiteral)
2199     return operandFromValue (valMinus (left->operand.valOperand,
2200                                        right->operand.valOperand));
2201
2202   /* if left is an array or pointer */
2203   if (IS_PTR (ltype) || IS_ARRAY (ltype))
2204     {
2205       isarray = left->isaddr;
2206       right = geniCodeMultiply (right,
2207                                 operandFromLit (getSize (ltype->next)),
2208                                 (getArraySizePtr(left) >= INTSIZE) ?
2209                                   RESULT_TYPE_INT :
2210                                   RESULT_TYPE_CHAR);
2211       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2212     }
2213   else
2214     {                           /* make them the same size */
2215       resType = usualBinaryConversions (&left, &right, resultType, '-');
2216     }
2217
2218   ic = newiCode ('-', left, right);
2219
2220   IC_RESULT (ic) = newiTempOperand (resType, 1);
2221   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2222
2223   /* if left or right is a float */
2224   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2225     ic->supportRtn = 1;
2226
2227   ADDTOCHAIN (ic);
2228   return IC_RESULT (ic);
2229 }
2230
2231 /*-----------------------------------------------------------------*/
2232 /* geniCodeAdd - generates iCode for addition                      */
2233 /*-----------------------------------------------------------------*/
2234 static operand *
2235 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2236 {
2237   iCode *ic;
2238   sym_link *resType;
2239   operand *size;
2240   int isarray = 0;
2241   bool indexUnsigned;
2242   LRTYPE;
2243
2244   /* if the right side is LITERAL zero */
2245   /* return the left side              */
2246   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2247     return left;
2248
2249   /* if left is literal zero return right */
2250   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2251     return right;
2252
2253   /* if left is a pointer then size */
2254   if (IS_PTR (ltype) || IS_ARRAY(ltype))
2255     {
2256       isarray = left->isaddr;
2257       // there is no need to multiply with 1
2258       if (getSize (ltype->next) != 1)
2259         {
2260           size  = operandFromLit (getSize (ltype->next));
2261           SPEC_USIGN (getSpec (operandType (size))) = 1;
2262           indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2263           right = geniCodeMultiply (right,
2264                                     size,
2265                                     (getArraySizePtr(left) >= INTSIZE) ?
2266                                       RESULT_TYPE_INT :
2267                                       RESULT_TYPE_CHAR);
2268           /* Even if right is a 'unsigned char',
2269              the result will be a 'signed int' due to the promotion rules.
2270              It doesn't make sense when accessing arrays, so let's fix it here: */
2271           if (indexUnsigned)
2272             SPEC_USIGN (getSpec (operandType (right))) = 1;
2273         }
2274       resType = copyLinkChain (ltype);
2275     }
2276   else
2277     { // make them the same size
2278       resType = usualBinaryConversions (&left, &right, resultType, '+');
2279     }
2280
2281   /* if they are both literals then we know */
2282   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2283       && left->isLiteral && right->isLiteral)
2284     return operandFromValue (valPlus (valFromType (ltype),
2285                                       valFromType (rtype)));
2286
2287   ic = newiCode ('+', left, right);
2288
2289   IC_RESULT (ic) = newiTempOperand (resType, 1);
2290   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2291
2292   /* if left or right is a float then support
2293      routine */
2294   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2295     ic->supportRtn = 1;
2296
2297   ADDTOCHAIN (ic);
2298
2299   return IC_RESULT (ic);
2300
2301 }
2302
2303 /*-----------------------------------------------------------------*/
2304 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
2305 /*-----------------------------------------------------------------*/
2306 sym_link *
2307 aggrToPtr (sym_link * type, bool force)
2308 {
2309   sym_link *etype;
2310   sym_link *ptype;
2311
2312   if (IS_PTR (type) && !force)
2313     return type;
2314
2315   etype = getSpec (type);
2316   ptype = newLink (DECLARATOR);
2317
2318   ptype->next = type;
2319
2320   /* set the pointer depending on the storage class */
2321   DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2322   return ptype;
2323 }
2324
2325 /*------------------------------------------------------------------*/
2326 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2327 /*------------------------------------------------------------------*/
2328 int
2329 aggrToPtrDclType (sym_link * type, bool force)
2330 {
2331   if (IS_PTR (type) && !force)
2332     return DCL_TYPE (type);
2333
2334   /* return the pointer depending on the storage class */
2335   return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2336 }
2337
2338 /*-----------------------------------------------------------------*/
2339 /* geniCodeArray2Ptr - array to pointer                            */
2340 /*-----------------------------------------------------------------*/
2341 static operand *
2342 geniCodeArray2Ptr (operand * op)
2343 {
2344   sym_link *optype = operandType (op);
2345   sym_link *opetype = getSpec (optype);
2346
2347   /* set the pointer depending on the storage class */
2348   DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2349
2350   op->isaddr = 0;
2351   return op;
2352 }
2353
2354
2355 /*-----------------------------------------------------------------*/
2356 /* geniCodeArray - array access                                    */
2357 /*-----------------------------------------------------------------*/
2358 static operand *
2359 geniCodeArray (operand * left, operand * right, int lvl)
2360 {
2361   iCode *ic;
2362   operand *size;
2363   sym_link *ltype = operandType (left);
2364   bool indexUnsigned;
2365
2366   if (IS_PTR (ltype))
2367     {
2368       if (IS_PTR (ltype->next) && left->isaddr)
2369         {
2370           left = geniCodeRValue (left, FALSE);
2371         }
2372
2373       return geniCodeDerefPtr (geniCodeAdd (left,
2374                                             right,
2375                                             (getArraySizePtr(left) >= INTSIZE) ?
2376                                               RESULT_TYPE_INT :
2377                                               RESULT_TYPE_CHAR,
2378                                             lvl),
2379                                lvl);
2380     }
2381   size = operandFromLit (getSize (ltype->next));
2382   SPEC_USIGN (getSpec (operandType (size))) = 1;
2383   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2384   right = geniCodeMultiply (right,
2385                             size,
2386                             (getArraySizePtr(left) >= INTSIZE) ?
2387                               RESULT_TYPE_INT :
2388                               RESULT_TYPE_CHAR);
2389   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2390      It doesn't make sense when accessing arrays, so let's fix it here: */
2391   if (indexUnsigned)
2392     SPEC_USIGN (getSpec (operandType (right))) = 1;
2393   /* we can check for limits here */
2394   /* already done in SDCCast.c
2395   if (isOperandLiteral (right) &&
2396       IS_ARRAY (ltype) &&
2397       DCL_ELEM (ltype) &&
2398       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2399     {
2400       werror (W_IDX_OUT_OF_BOUNDS,
2401               (int) operandLitValue (right) / getSize (ltype->next),
2402               DCL_ELEM (ltype));
2403     }
2404   */
2405
2406   ic = newiCode ('+', left, right);
2407
2408   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2409                                       !IS_AGGREGATE (ltype->next) &&
2410                                       !IS_PTR (ltype->next))
2411                                      ? ltype : ltype->next), 0);
2412
2413   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2414   ADDTOCHAIN (ic);
2415
2416   return IC_RESULT (ic);
2417 }
2418
2419 /*-----------------------------------------------------------------*/
2420 /* geniCodeStruct - generates intermediate code for structures     */
2421 /*-----------------------------------------------------------------*/
2422 operand *
2423 geniCodeStruct (operand * left, operand * right, bool islval)
2424 {
2425   iCode *ic;
2426   sym_link *type = operandType (left);
2427   sym_link *etype = getSpec (type);
2428   sym_link *retype;
2429   symbol *element = getStructElement (SPEC_STRUCT (etype),
2430                                       right->operand.symOperand);
2431
2432   wassert(IS_SYMOP(right));
2433     
2434   /* add the offset */
2435   ic = newiCode ('+', left, operandFromLit (element->offset));
2436
2437   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2438
2439   /* preserve the storage & output class of the struct */
2440   /* as well as the volatile attribute */
2441   retype = getSpec (operandType (IC_RESULT (ic)));
2442   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2443   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2444   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2445   SPEC_CONST (retype) |= SPEC_CONST (etype);
2446   
2447   if (IS_PTR (element->type))
2448     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2449   
2450   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2451
2452   ADDTOCHAIN (ic);
2453   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2454 }
2455
2456 /*-----------------------------------------------------------------*/
2457 /* geniCodePostInc - generate int code for Post increment          */
2458 /*-----------------------------------------------------------------*/
2459 operand *
2460 geniCodePostInc (operand * op)
2461 {
2462   iCode *ic;
2463   operand *rOp;
2464   sym_link *optype = operandType (op);
2465   operand *result;
2466   operand *rv = (IS_ITEMP (op) ?
2467                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2468                  op);
2469   sym_link *rvtype = operandType (rv);
2470   int size = 0;
2471
2472   /* if this is not an address we have trouble */
2473   if (!op->isaddr)
2474     {
2475       werror (E_LVALUE_REQUIRED, "++");
2476       return op;
2477     }
2478
2479   rOp = newiTempOperand (rvtype, 0);
2480   OP_SYMBOL(rOp)->noSpilLoc = 1;
2481
2482   if (IS_ITEMP (rv))
2483     OP_SYMBOL(rv)->noSpilLoc = 1;
2484
2485   geniCodeAssign (rOp, rv, 0, 0);
2486
2487   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2488   if (IS_FLOAT (rvtype))
2489     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2490   else
2491     ic = newiCode ('+', rv, operandFromLit (size));
2492
2493   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2494   ADDTOCHAIN (ic);
2495
2496   geniCodeAssign (op, result, 0, 0);
2497
2498   return rOp;
2499
2500 }
2501
2502 /*-----------------------------------------------------------------*/
2503 /* geniCodePreInc - generate code for preIncrement                 */
2504 /*-----------------------------------------------------------------*/
2505 operand *
2506 geniCodePreInc (operand * op, bool lvalue)
2507 {
2508   iCode *ic;
2509   sym_link *optype = operandType (op);
2510   operand *rop = (IS_ITEMP (op) ?
2511                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2512                   op);
2513   sym_link *roptype = operandType (rop);
2514   operand *result;
2515   int size = 0;
2516
2517   if (!op->isaddr)
2518     {
2519       werror (E_LVALUE_REQUIRED, "++");
2520       return op;
2521     }
2522
2523
2524   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2525   if (IS_FLOAT (roptype))
2526     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2527   else
2528     ic = newiCode ('+', rop, operandFromLit (size));
2529   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2530   ADDTOCHAIN (ic);
2531
2532   (void) geniCodeAssign (op, result, 0, 0);
2533   if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2534     return op;
2535   else
2536     return result;
2537 }
2538
2539 /*-----------------------------------------------------------------*/
2540 /* geniCodePostDec - generates code for Post decrement             */
2541 /*-----------------------------------------------------------------*/
2542 operand *
2543 geniCodePostDec (operand * op)
2544 {
2545   iCode *ic;
2546   operand *rOp;
2547   sym_link *optype = operandType (op);
2548   operand *result;
2549   operand *rv = (IS_ITEMP (op) ?
2550                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2551                  op);
2552   sym_link *rvtype = operandType (rv);
2553   int size = 0;
2554
2555   /* if this is not an address we have trouble */
2556   if (!op->isaddr)
2557     {
2558       werror (E_LVALUE_REQUIRED, "--");
2559       return op;
2560     }
2561
2562   rOp = newiTempOperand (rvtype, 0);
2563   OP_SYMBOL(rOp)->noSpilLoc = 1;
2564
2565   if (IS_ITEMP (rv))
2566     OP_SYMBOL(rv)->noSpilLoc = 1;
2567
2568   geniCodeAssign (rOp, rv, 0, 0);
2569
2570   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2571   if (IS_FLOAT (rvtype))
2572     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2573   else
2574     ic = newiCode ('-', rv, operandFromLit (size));
2575
2576   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2577   ADDTOCHAIN (ic);
2578
2579   geniCodeAssign (op, result, 0, 0);
2580
2581   return rOp;
2582
2583 }
2584
2585 /*-----------------------------------------------------------------*/
2586 /* geniCodePreDec - generate code for pre  decrement               */
2587 /*-----------------------------------------------------------------*/
2588 operand *
2589 geniCodePreDec (operand * op, bool lvalue)
2590 {
2591   iCode *ic;
2592   sym_link *optype = operandType (op);
2593   operand *rop = (IS_ITEMP (op) ?
2594                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2595                   op);
2596   sym_link *roptype = operandType (rop);
2597   operand *result;
2598   int size = 0;
2599
2600   if (!op->isaddr)
2601     {
2602       werror (E_LVALUE_REQUIRED, "--");
2603       return op;
2604     }
2605
2606
2607   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2608   if (IS_FLOAT (roptype))
2609     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2610   else
2611     ic = newiCode ('-', rop, operandFromLit (size));
2612   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2613   ADDTOCHAIN (ic);
2614
2615   (void) geniCodeAssign (op, result, 0, 0);
2616   if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2617     return op;
2618   else
2619     return result;
2620 }
2621
2622
2623 /*-----------------------------------------------------------------*/
2624 /* geniCodeBitwise - gen int code for bitWise  operators           */
2625 /*-----------------------------------------------------------------*/
2626 operand *
2627 geniCodeBitwise (operand * left, operand * right,
2628                  int oper, sym_link * resType)
2629 {
2630   iCode *ic;
2631
2632   left = geniCodeCast (resType, left, TRUE);
2633   right = geniCodeCast (resType, right, TRUE);
2634
2635   ic = newiCode (oper, left, right);
2636   IC_RESULT (ic) = newiTempOperand (resType, 0);
2637
2638   ADDTOCHAIN (ic);
2639   return IC_RESULT (ic);
2640 }
2641
2642 /*-----------------------------------------------------------------*/
2643 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2644 /*-----------------------------------------------------------------*/
2645 operand *
2646 geniCodeAddressOf (operand * op)
2647 {
2648   iCode *ic;
2649   sym_link *p;
2650   sym_link *optype = operandType (op);
2651   sym_link *opetype = getSpec (optype);
2652
2653   if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2654     {
2655       op = operandFromOperand (op);
2656       op->isaddr = 0;
2657       return op;
2658     }
2659   
2660   /* lvalue check already done in decorateType */
2661   /* this must be a lvalue */
2662 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2663 /*  werror (E_LVALUE_REQUIRED,"&"); */
2664 /*  return op; */
2665 /*     } */
2666
2667   p = newLink (DECLARATOR);
2668
2669   /* set the pointer depending on the storage class */
2670   DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2671
2672   p->next = copyLinkChain (optype);
2673
2674   /* if already a temp */
2675   if (IS_ITEMP (op))
2676     {
2677       setOperandType (op, p);
2678       op->isaddr = 0;
2679       return op;
2680     }
2681
2682   /* other wise make this of the type coming in */
2683   ic = newiCode (ADDRESS_OF, op, NULL);
2684   IC_RESULT (ic) = newiTempOperand (p, 1);
2685   IC_RESULT (ic)->isaddr = 0;
2686   ADDTOCHAIN (ic);
2687   return IC_RESULT (ic);
2688 }
2689 /*-----------------------------------------------------------------*/
2690 /* setOClass - sets the output class depending on the pointer type */
2691 /*-----------------------------------------------------------------*/
2692 void 
2693 setOClass (sym_link * ptr, sym_link * spec)
2694 {
2695   switch (DCL_TYPE (ptr))
2696     {
2697     case POINTER:
2698       SPEC_OCLS (spec) = data;
2699       break;
2700
2701     case GPOINTER:
2702       SPEC_OCLS (spec) = generic;
2703       break;
2704
2705     case FPOINTER:
2706       SPEC_OCLS (spec) = xdata;
2707       break;
2708
2709     case CPOINTER:
2710       SPEC_OCLS (spec) = code;
2711       break;
2712
2713     case IPOINTER:
2714       SPEC_OCLS (spec) = idata;
2715       break;
2716
2717     case PPOINTER:
2718       SPEC_OCLS (spec) = xstack;
2719       break;
2720
2721     case EEPPOINTER:
2722       SPEC_OCLS (spec) = eeprom;
2723       break;
2724
2725     default:
2726       break;
2727
2728     }
2729 }
2730
2731 /*-----------------------------------------------------------------*/
2732 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2733 /*-----------------------------------------------------------------*/
2734 operand *
2735 geniCodeDerefPtr (operand * op,int lvl)
2736 {
2737   sym_link *rtype, *retype;
2738   sym_link *optype = operandType (op);
2739
2740   // if this is an array then array access
2741   if (IS_ARRAY (optype)) {
2742     // don't worry, this will be optimized out later
2743     return geniCodeArray (op, operandFromLit (0), lvl);
2744   }
2745
2746   // just in case someone screws up
2747   wassert (IS_PTR (optype));
2748
2749   if (IS_TRUE_SYMOP (op))
2750     {
2751       op->isaddr = 1;
2752       op = geniCodeRValue (op, TRUE);
2753     }
2754
2755   /* now get rid of the pointer part */
2756   if (isLvaluereq(lvl) && IS_ITEMP (op))
2757     {
2758       retype = getSpec (rtype = copyLinkChain (optype));
2759     }
2760   else
2761     {
2762       retype = getSpec (rtype = copyLinkChain (optype->next));
2763       /* outputclass needs 2b updated */
2764       setOClass (optype, retype);
2765     }
2766   
2767   op->isGptr = IS_GENPTR (optype);
2768
2769   op->isaddr = (IS_PTR (rtype) ||
2770                 IS_STRUCT (rtype) ||
2771                 IS_INT (rtype) ||
2772                 IS_CHAR (rtype) ||
2773                 IS_FLOAT (rtype));
2774
2775   if (!isLvaluereq(lvl))
2776     op = geniCodeRValue (op, TRUE);
2777
2778   setOperandType (op, rtype);
2779
2780   return op;
2781 }
2782
2783 /*-----------------------------------------------------------------*/
2784 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2785 /*-----------------------------------------------------------------*/
2786 operand *
2787 geniCodeUnaryMinus (operand * op)
2788 {
2789   iCode *ic;
2790   sym_link *optype = operandType (op);
2791
2792   if (IS_LITERAL (optype))
2793     return operandFromLit (-floatFromVal (op->operand.valOperand));
2794
2795   ic = newiCode (UNARYMINUS, op, NULL);
2796   IC_RESULT (ic) = newiTempOperand (optype, 0);
2797   ADDTOCHAIN (ic);
2798   return IC_RESULT (ic);
2799 }
2800
2801 /*-----------------------------------------------------------------*/
2802 /* geniCodeLeftShift - gen i code for left shift                   */
2803 /*-----------------------------------------------------------------*/
2804 operand *
2805 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2806 {
2807   iCode *ic;
2808   sym_link *resType;
2809
2810   ic = newiCode (LEFT_OP, left, right);
2811
2812   resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2813   IC_RESULT (ic) = newiTempOperand (resType, 0);
2814   ADDTOCHAIN (ic);
2815   return IC_RESULT (ic);
2816 }
2817
2818 /*-----------------------------------------------------------------*/
2819 /* geniCodeRightShift - gen i code for right shift                 */
2820 /*-----------------------------------------------------------------*/
2821 operand *
2822 geniCodeRightShift (operand * left, operand * right)
2823 {
2824   iCode *ic;
2825
2826   ic = newiCode (RIGHT_OP, left, right);
2827   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2828   ADDTOCHAIN (ic);
2829   return IC_RESULT (ic);
2830 }
2831
2832 /*-----------------------------------------------------------------*/
2833 /* geniCodeLogic- logic code                                       */
2834 /*-----------------------------------------------------------------*/
2835 static operand *
2836 geniCodeLogic (operand * left, operand * right, int op)
2837 {
2838   iCode *ic;
2839   sym_link *ctype;
2840   sym_link *rtype = operandType (right);
2841   sym_link *ltype = operandType (left);
2842
2843   /* left is integral type and right is literal then
2844      check if the literal value is within bounds */
2845   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2846     {
2847       checkConstantRange(ltype,
2848                          OP_VALUE(right), "compare operation", 1);
2849     }
2850
2851   /* if one operand is a pointer and the other is a literal generic void pointer,
2852      change the type of the literal generic void pointer to match the other pointer */
2853   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2854       && IS_PTR (rtype) && !IS_GENPTR(rtype))
2855     {
2856       /* find left's definition */
2857       ic = (iCode *) setFirstItem (iCodeChain);
2858       while (ic)
2859         {
2860           if (((ic->op == CAST) || (ic->op == '='))
2861               && isOperandEqual(left, IC_RESULT (ic)))
2862             break;
2863           else
2864             ic = setNextItem (iCodeChain);
2865         }
2866       /* if casting literal to generic pointer, then cast to rtype instead */
2867       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2868         {
2869           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2870           ltype = operandType(left);
2871         }
2872     }
2873   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2874       && IS_PTR (ltype) && !IS_GENPTR(ltype))
2875     {
2876       /* find right's definition */
2877       ic = (iCode *) setFirstItem (iCodeChain);
2878       while (ic)
2879         {
2880           if (((ic->op == CAST) || (ic->op == '='))
2881               && isOperandEqual(right, IC_RESULT (ic)))
2882             break;
2883           else
2884             ic = setNextItem (iCodeChain);
2885         }
2886       /* if casting literal to generic pointer, then cast to rtype instead */
2887       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2888         {
2889           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2890           rtype = operandType(right);
2891         }
2892     }
2893
2894   ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2895
2896   ic = newiCode (op, left, right);
2897   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2898
2899   /* if comparing float
2900      and not a '==' || '!=' || '&&' || '||' (these
2901      will be inlined */
2902   if (IS_FLOAT(ctype) &&
2903       op != EQ_OP &&
2904       op != NE_OP &&
2905       op != AND_OP &&
2906       op != OR_OP)
2907    ic->supportRtn = 1;
2908
2909   ADDTOCHAIN (ic);
2910   return IC_RESULT (ic);
2911 }
2912
2913 /*-----------------------------------------------------------------*/
2914 /* geniCodeLogicAndOr - && || operations                           */
2915 /*-----------------------------------------------------------------*/
2916 static operand *
2917 geniCodeLogicAndOr (ast *tree, int lvl)
2918 {
2919   iCode *ic;
2920   symbol *falseLabel = newiTempLabel (NULL);
2921   symbol *trueLabel  = newiTempLabel (NULL);
2922   symbol *exitLabel  = newiTempLabel (NULL);
2923   operand *op, *result, *condition;
2924
2925   /* AND_OP and OR_OP are no longer generated because of bug-905492.
2926      They can be reenabled by executing the following block. If you find
2927      a decent optimization you could start right here:
2928   */
2929 #if 0
2930   if (0)
2931     {
2932        operand *leftOp, *rightOp;
2933
2934        leftOp  = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
2935        rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
2936
2937        return geniCodeLogic (leftOp, rightOp, tree->opval.op);
2938     }
2939 #endif
2940
2941   /* generate two IFX for the '&&' or '||' op */
2942
2943   /* evaluate left operand */
2944   condition = ast2iCode (tree->left, lvl + 1);
2945   op = geniCodeRValue (condition, FALSE);
2946
2947   /* test left operand */
2948   if (tree->opval.op == AND_OP)
2949     ic = newiCodeCondition (op, NULL, falseLabel);
2950   else /* OR_OP */
2951     ic = newiCodeCondition (op, trueLabel, NULL);
2952   ADDTOCHAIN (ic);
2953   
2954   /* evaluate right operand */
2955   condition = ast2iCode (tree->right, lvl + 1);
2956   op = geniCodeRValue (condition, FALSE);
2957   
2958   /* test right operand */
2959   ic = newiCodeCondition (op, trueLabel, NULL);
2960   ADDTOCHAIN (ic);
2961   
2962   /* store 0 or 1 in result */
2963   result = newiTempOperand (newCharLink(), 1);
2964   
2965   geniCodeLabel (falseLabel);
2966   geniCodeAssign (result, operandFromLit (0), 0, 0);
2967   /* generate an unconditional goto */
2968   geniCodeGoto (exitLabel);
2969
2970   geniCodeLabel (trueLabel);
2971   geniCodeAssign (result, operandFromLit (1), 0, 0);
2972
2973   geniCodeLabel (exitLabel);
2974
2975   return result;
2976 }
2977
2978 /*-----------------------------------------------------------------*/
2979 /* geniCodeUnary - for a a generic unary operation                 */
2980 /*-----------------------------------------------------------------*/
2981 operand *
2982 geniCodeUnary (operand * op, int oper)
2983 {
2984   iCode *ic = newiCode (oper, op, NULL);
2985
2986   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2987   ADDTOCHAIN (ic);
2988   return IC_RESULT (ic);
2989 }
2990
2991 /*-----------------------------------------------------------------*/
2992 /* geniCodeConditional - geniCode for '?' ':' operation            */
2993 /*-----------------------------------------------------------------*/
2994 operand *
2995 geniCodeConditional (ast * tree,int lvl)
2996 {
2997   iCode *ic;
2998   symbol *falseLabel = newiTempLabel (NULL);
2999   symbol *exitLabel = newiTempLabel (NULL);
3000   operand *cond = ast2iCode (tree->left,lvl+1);
3001   operand *true, *false, *result;
3002
3003   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3004                           NULL, falseLabel);
3005   ADDTOCHAIN (ic);
3006
3007   true = ast2iCode (tree->right->left,lvl+1);
3008
3009   /* move the value to a new Operand */
3010   result = newiTempOperand (tree->right->ftype, 0);
3011   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3012
3013   /* generate an unconditional goto */
3014   geniCodeGoto (exitLabel);
3015
3016   /* now for the right side */
3017   geniCodeLabel (falseLabel);
3018
3019   false = ast2iCode (tree->right->right,lvl+1);
3020   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3021
3022   /* create the exit label */
3023   geniCodeLabel (exitLabel);
3024
3025   return result;
3026 }
3027
3028 /*-----------------------------------------------------------------*/
3029 /* geniCodeAssign - generate code for assignment                   */
3030 /*-----------------------------------------------------------------*/
3031 operand *
3032 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3033 {
3034   iCode *ic;
3035   sym_link *ltype = operandType (left);
3036   sym_link *rtype = operandType (right);
3037
3038   if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3039     {
3040       werror (E_LVALUE_REQUIRED, "assignment");
3041       return left;
3042     }
3043
3044   /* left is integral type and right is literal then
3045      check if the literal value is within bounds */
3046   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3047     {
3048       checkConstantRange(ltype, 
3049                          OP_VALUE(right), "= operation", 0);
3050     }
3051
3052   /* if the left & right type don't exactly match */
3053   /* if pointer set then make sure the check is
3054      done with the type & not the pointer */
3055   /* then cast rights type to left */
3056
3057   /* first check the type for pointer assignement */
3058   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3059       compareType (ltype, rtype) <= 0)
3060     {
3061       if (compareType (ltype->next, rtype) < 0)
3062         right = geniCodeCast (ltype->next, right, TRUE);
3063     }
3064   else if (compareType (ltype, rtype) < 0)
3065     right = geniCodeCast (ltype, right, TRUE);
3066
3067   /* If left is a true symbol & ! volatile
3068      create an assignment to temporary for
3069      the right & then assign this temporary
3070      to the symbol. This is SSA (static single
3071      assignment). Isn't it simple and folks have
3072      published mountains of paper on it */
3073   if (IS_TRUE_SYMOP (left) &&
3074       !isOperandVolatile (left, FALSE) &&
3075       isOperandGlobal (left))
3076     {
3077       symbol *sym = NULL;
3078
3079       if (IS_TRUE_SYMOP (right))
3080         sym = OP_SYMBOL (right);
3081       ic = newiCode ('=', NULL, right);
3082       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3083       SPIL_LOC (right) = sym;
3084       ADDTOCHAIN (ic);
3085     }
3086
3087   ic = newiCode ('=', NULL, right);
3088   IC_RESULT (ic) = left;
3089   ADDTOCHAIN (ic);
3090
3091   /* if left isgptr flag is set then support
3092      routine will be required */
3093   if (left->isGptr)
3094     ic->supportRtn = 1;
3095
3096   ic->nosupdate = nosupdate;
3097   return left;
3098 }
3099
3100 /*-----------------------------------------------------------------*/
3101 /* geniCodeDummyRead - generate code for dummy read                */
3102 /*-----------------------------------------------------------------*/
3103 static void
3104 geniCodeDummyRead (operand * op)
3105 {
3106   iCode *ic;
3107   sym_link *type = operandType (op);
3108
3109   if (!IS_VOLATILE(type))
3110     return;
3111     
3112   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3113   ADDTOCHAIN (ic);
3114
3115   ic->nosupdate = 1;
3116 }
3117
3118 /*-----------------------------------------------------------------*/
3119 /* geniCodeSEParms - generate code for side effecting fcalls       */
3120 /*-----------------------------------------------------------------*/
3121 static void 
3122 geniCodeSEParms (ast * parms,int lvl)
3123 {
3124   if (!parms)
3125     return;
3126
3127   if (parms->type == EX_OP && parms->opval.op == PARAM)
3128     {
3129       geniCodeSEParms (parms->left,lvl);
3130       geniCodeSEParms (parms->right,lvl);
3131       return;
3132     }
3133
3134   /* hack don't like this but too lazy to think of
3135      something better */
3136   if (IS_ADDRESS_OF_OP (parms))
3137     parms->left->lvalue = 1;
3138
3139   if (IS_CAST_OP (parms) &&
3140       IS_PTR (parms->ftype) &&
3141       IS_ADDRESS_OF_OP (parms->right))
3142     parms->right->left->lvalue = 1;
3143
3144   parms->opval.oprnd = 
3145     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3146                 
3147   parms->type = EX_OPERAND;
3148   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3149                 SPEC_ARGREG(parms->ftype);
3150 }
3151
3152 /*-----------------------------------------------------------------*/
3153 /* geniCodeParms - generates parameters                            */
3154 /*-----------------------------------------------------------------*/
3155 value *
3156 geniCodeParms (ast * parms, value *argVals, int *stack, 
3157                sym_link * ftype, int lvl)
3158 {
3159   iCode *ic;
3160   operand *pval;
3161
3162   if (!parms)
3163     return argVals;
3164
3165   if (argVals==NULL) {
3166     // first argument
3167     argVals = FUNC_ARGS (ftype);
3168   }
3169
3170   /* if this is a param node then do the left & right */
3171   if (parms->type == EX_OP && parms->opval.op == PARAM)
3172     {
3173       argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3174       argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3175       return argVals;
3176     }
3177
3178   /* get the parameter value */
3179   if (parms->type == EX_OPERAND)
3180     pval = parms->opval.oprnd;
3181   else
3182     {
3183       /* maybe this else should go away ?? */
3184       /* hack don't like this but too lazy to think of
3185          something better */
3186       if (IS_ADDRESS_OF_OP (parms))
3187         parms->left->lvalue = 1;
3188
3189       if (IS_CAST_OP (parms) &&
3190           IS_PTR (parms->ftype) &&
3191           IS_ADDRESS_OF_OP (parms->right))
3192         parms->right->left->lvalue = 1;
3193
3194       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3195     }
3196
3197   /* if register parm then make it a send */
3198   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3199       IFFUNC_ISBUILTIN(ftype))
3200     {
3201       ic = newiCode (SEND, pval, NULL);
3202       ic->argreg = SPEC_ARGREG(parms->etype);
3203       ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3204       ADDTOCHAIN (ic);
3205     }
3206   else
3207     {
3208       /* now decide whether to push or assign */
3209       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3210         {
3211
3212           /* assign */
3213           operand *top = operandFromSymbol (argVals->sym);
3214           /* clear useDef and other bitVectors */
3215           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3216           geniCodeAssign (top, pval, 1, 0);
3217         }
3218       else
3219         {
3220           sym_link *p = operandType (pval);
3221           /* push */
3222           ic = newiCode (IPUSH, pval, NULL);
3223           ic->parmPush = 1;
3224           /* update the stack adjustment */
3225           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3226           ADDTOCHAIN (ic);
3227         }
3228     }
3229
3230   argVals=argVals->next;
3231   return argVals;
3232 }
3233
3234 /*-----------------------------------------------------------------*/
3235 /* geniCodeCall - generates temp code for calling                  */
3236 /*-----------------------------------------------------------------*/
3237 operand *
3238 geniCodeCall (operand * left, ast * parms,int lvl)
3239 {
3240   iCode *ic;
3241   operand *result;
3242   sym_link *type, *etype;
3243   sym_link *ftype;
3244   int stack = 0;
3245
3246   if (!IS_FUNC(OP_SYMBOL(left)->type) && 
3247       !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3248     werror (E_FUNCTION_EXPECTED);
3249     return operandFromValue(valueFromLit(0));
3250   }
3251
3252   /* take care of parameters with side-effecting
3253      function calls in them, this is required to take care
3254      of overlaying function parameters */
3255   geniCodeSEParms (parms,lvl);
3256
3257   ftype = operandType (left);
3258   if (IS_CODEPTR (ftype))
3259     ftype = ftype->next;
3260     
3261   /* first the parameters */
3262   geniCodeParms (parms, NULL, &stack, ftype, lvl);
3263
3264   /* now call : if symbol then pcall */
3265   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3266     ic = newiCode (PCALL, left, NULL);
3267   } else {
3268     ic = newiCode (CALL, left, NULL);
3269   }
3270
3271   type = copyLinkChain (ftype->next);
3272   etype = getSpec (type);
3273   SPEC_EXTR (etype) = 0;
3274   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3275
3276   ADDTOCHAIN (ic);
3277
3278   /* stack adjustment after call */
3279   ic->parmBytes = stack;
3280
3281   return result;
3282 }
3283
3284 /*-----------------------------------------------------------------*/
3285 /* geniCodeReceive - generate intermediate code for "receive"      */
3286 /*-----------------------------------------------------------------*/
3287 static void 
3288 geniCodeReceive (value * args)
3289 {
3290   /* for all arguments that are passed in registers */
3291   while (args)
3292     {
3293       int first = 1;
3294       if (IS_REGPARM (args->etype))
3295         {
3296           operand *opr = operandFromValue (args);
3297           operand *opl;
3298           symbol *sym = OP_SYMBOL (opr);
3299           iCode *ic;
3300
3301           /* we will use it after all optimizations
3302              and before liveRange calculation */
3303           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3304             {
3305
3306               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3307                   options.stackAuto == 0 &&
3308                   (!(options.model == MODEL_FLAT24)) )
3309                 {
3310                 }
3311               else
3312                 {
3313                   opl = newiTempOperand (args->type, 0);
3314                   sym->reqv = opl;
3315                   sym->reqv->key = sym->key;
3316                   OP_SYMBOL (sym->reqv)->key = sym->key;
3317                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3318                   OP_SYMBOL (sym->reqv)->islocal = 0;
3319                   SPIL_LOC (sym->reqv) = sym;
3320                 }
3321             }
3322
3323           ic = newiCode (RECEIVE, NULL, NULL);    
3324           ic->argreg = SPEC_ARGREG(args->etype);
3325           if (first) {
3326               currFunc->recvSize = getSize (sym->type);
3327               first = 0;
3328           }
3329           IC_RESULT (ic) = opr;
3330           ADDTOCHAIN (ic);
3331         }
3332
3333       args = args->next;
3334     }
3335 }
3336
3337 /*-----------------------------------------------------------------*/
3338 /* geniCodeFunctionBody - create the function body                 */
3339 /*-----------------------------------------------------------------*/
3340 void 
3341 geniCodeFunctionBody (ast * tree,int lvl)
3342 {
3343   iCode *ic;
3344   operand *func;
3345   sym_link *fetype;
3346   int savelineno;
3347
3348   /* reset the auto generation */
3349   /* numbers */
3350   iTempNum = 0;
3351   iTempLblNum = 0;
3352   operandKey = 0;
3353   iCodeKey = 0;
3354   func = ast2iCode (tree->left,lvl+1);
3355   fetype = getSpec (operandType (func));
3356
3357   savelineno = lineno;
3358   lineno = OP_SYMBOL (func)->lineDef;
3359   /* create an entry label */
3360   geniCodeLabel (entryLabel);
3361   lineno = savelineno;
3362
3363   /* create a proc icode */
3364   ic = newiCode (FUNCTION, func, NULL);
3365   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3366   ic->tree = tree;
3367
3368   ADDTOCHAIN (ic);
3369
3370   /* for all parameters that are passed
3371      on registers add a "receive" */
3372   geniCodeReceive (tree->values.args);
3373
3374   /* generate code for the body */
3375   ast2iCode (tree->right,lvl+1);
3376
3377   /* create a label for return */
3378   geniCodeLabel (returnLabel);
3379
3380   /* now generate the end proc */
3381   ic = newiCode (ENDFUNCTION, func, NULL);
3382   ic->tree = tree;
3383   ADDTOCHAIN (ic);
3384   return;
3385 }
3386
3387 /*-----------------------------------------------------------------*/
3388 /* geniCodeReturn - gen icode for 'return' statement               */
3389 /*-----------------------------------------------------------------*/
3390 void 
3391 geniCodeReturn (operand * op)
3392 {
3393   iCode *ic;
3394
3395   /* if the operand is present force an rvalue */
3396   if (op)
3397     op = geniCodeRValue (op, FALSE);
3398
3399   ic = newiCode (RETURN, op, NULL);
3400   ADDTOCHAIN (ic);
3401 }
3402
3403 /*-----------------------------------------------------------------*/
3404 /* geniCodeIfx - generates code for extended if statement          */
3405 /*-----------------------------------------------------------------*/
3406 void 
3407 geniCodeIfx (ast * tree,int lvl)
3408 {
3409   iCode *ic;
3410   operand *condition = ast2iCode (tree->left,lvl+1);
3411   sym_link *cetype;
3412
3413   /* if condition is null then exit */
3414   if (!condition)
3415     goto exit;
3416   else
3417     condition = geniCodeRValue (condition, FALSE);
3418
3419   cetype = getSpec (operandType (condition));
3420   /* if the condition is a literal */
3421   if (IS_LITERAL (cetype))
3422     {
3423       if (floatFromVal (condition->operand.valOperand))
3424         {
3425           if (tree->trueLabel)
3426             geniCodeGoto (tree->trueLabel);
3427           else
3428             assert (0);
3429         }
3430       else
3431         {
3432           if (tree->falseLabel)
3433             geniCodeGoto (tree->falseLabel);
3434           else
3435             assert (0);
3436         }
3437       goto exit;
3438     }
3439
3440   if (tree->trueLabel)
3441     {
3442       ic = newiCodeCondition (condition,
3443                               tree->trueLabel,
3444                               NULL);
3445       ADDTOCHAIN (ic);
3446
3447       if (tree->falseLabel)
3448         geniCodeGoto (tree->falseLabel);
3449     }
3450   else
3451     {
3452       ic = newiCodeCondition (condition,
3453                               NULL,
3454                               tree->falseLabel);
3455       ADDTOCHAIN (ic);
3456     }
3457
3458 exit:
3459   ast2iCode (tree->right,lvl+1);
3460 }
3461
3462 /*-----------------------------------------------------------------*/
3463 /* geniCodeJumpTable - tries to create a jump table for switch     */
3464 /*-----------------------------------------------------------------*/
3465 int 
3466 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3467 {
3468   int min = 0, max = 0, t, cnt = 0;
3469   value *vch;
3470   iCode *ic;
3471   operand *boundary;
3472   symbol *falseLabel;
3473   set *labels = NULL;
3474   int needRangeCheck = !optimize.noJTabBoundary
3475                        || tree->values.switchVals.swDefault;
3476
3477   if (!tree || !caseVals)
3478     return 0;
3479
3480   /* the criteria for creating a jump table is */
3481   /* all integer numbers between the maximum & minimum must */
3482   /* be present , the maximum value should not exceed 255 */
3483   min = max = (int) floatFromVal (vch = caseVals);
3484   SNPRINTF (buffer, sizeof(buffer), 
3485             "_case_%d_%d",
3486            tree->values.switchVals.swNum,
3487            min);
3488   addSet (&labels, newiTempLabel (buffer));
3489
3490   /* if there is only one case value then no need */
3491   if (!(vch = vch->next))
3492     return 0;
3493
3494   while (vch)
3495     {
3496       if (((t = (int) floatFromVal (vch)) - max) != 1)
3497         return 0;
3498       SNPRINTF (buffer, sizeof(buffer), 
3499                 "_case_%d_%d",
3500                tree->values.switchVals.swNum,
3501                t);
3502       addSet (&labels, newiTempLabel (buffer));
3503       max = t;
3504       cnt++;
3505       vch = vch->next;
3506     }
3507
3508   /* if the number of case statements <= 2 then */
3509   /* it is not economical to create the jump table */
3510   /* since two compares are needed for boundary conditions */
3511   if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3512     return 0;
3513
3514   if (tree->values.switchVals.swDefault)
3515     {
3516         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3517     }
3518   else
3519     {
3520         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3521     }
3522     
3523
3524   falseLabel = newiTempLabel (buffer);
3525
3526   /* so we can create a jumptable */
3527   /* first we rule out the boundary conditions */
3528   /* if only optimization says so */
3529   if (needRangeCheck)
3530     {
3531       sym_link *cetype = getSpec (operandType (cond));
3532       /* no need to check the lower bound if
3533          the condition is unsigned & minimum value is zero */
3534       if (!(min == 0 && IS_UNSIGNED (cetype)))
3535         {
3536           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3537           ic = newiCodeCondition (boundary, falseLabel, NULL);
3538           ADDTOCHAIN (ic);
3539         }
3540
3541       /* now for upper bounds */
3542       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3543       ic = newiCodeCondition (boundary, falseLabel, NULL);
3544       ADDTOCHAIN (ic);
3545     }
3546
3547   /* if the min is not zero then we no make it zero */
3548   if (min)
3549     {
3550       cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3551       if (!IS_LITERAL(getSpec(operandType(cond))))
3552         setOperandType (cond, UCHARTYPE);
3553     }
3554
3555   /* now create the jumptable */
3556   ic = newiCode (JUMPTABLE, NULL, NULL);
3557   IC_JTCOND (ic) = cond;
3558   IC_JTLABELS (ic) = labels;
3559   ADDTOCHAIN (ic);
3560   return 1;
3561 }
3562
3563 /*-----------------------------------------------------------------*/
3564 /* geniCodeSwitch - changes a switch to a if statement             */
3565 /*-----------------------------------------------------------------*/
3566 void
3567 geniCodeSwitch (ast * tree,int lvl)
3568 {
3569   iCode *ic;
3570   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3571   value *caseVals = tree->values.switchVals.swVals;
3572   symbol *trueLabel, *falseLabel;
3573       
3574   /* If the condition is a literal, then just jump to the */
3575   /* appropriate case label. */
3576   if (IS_LITERAL(getSpec(operandType(cond))))
3577     {
3578       int switchVal, caseVal;
3579       
3580       switchVal = (int) floatFromVal (cond->operand.valOperand);
3581       while (caseVals)
3582         {
3583           caseVal = (int) floatFromVal (caseVals);
3584           if (caseVal == switchVal)
3585             {
3586               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3587                         tree->values.switchVals.swNum, caseVal);
3588               trueLabel = newiTempLabel (buffer);
3589               geniCodeGoto (trueLabel);
3590               goto jumpTable;
3591             }
3592           caseVals = caseVals->next;
3593         }
3594       goto defaultOrBreak;
3595     }
3596
3597   /* if we can make this a jump table */
3598   if (geniCodeJumpTable (cond, caseVals, tree))
3599     goto jumpTable;             /* no need for the comparison */
3600
3601   /* for the cases defined do */
3602   while (caseVals)
3603     {
3604
3605       operand *compare = geniCodeLogic (cond,
3606                                         operandFromValue (caseVals),
3607                                         EQ_OP);
3608
3609       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3610                tree->values.switchVals.swNum,
3611                (int) floatFromVal (caseVals));
3612       trueLabel = newiTempLabel (buffer);
3613
3614       ic = newiCodeCondition (compare, trueLabel, NULL);
3615       ADDTOCHAIN (ic);
3616       caseVals = caseVals->next;
3617     }
3618
3619
3620 defaultOrBreak:
3621   /* if default is present then goto break else break */
3622   if (tree->values.switchVals.swDefault)
3623     {
3624         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3625     }
3626   else
3627     {
3628         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3629     }
3630
3631   falseLabel = newiTempLabel (buffer);
3632   geniCodeGoto (falseLabel);
3633
3634 jumpTable:
3635   ast2iCode (tree->right,lvl+1);
3636 }
3637
3638 /*-----------------------------------------------------------------*/
3639 /* geniCodeInline - intermediate code for inline assembler         */
3640 /*-----------------------------------------------------------------*/
3641 static void 
3642 geniCodeInline (ast * tree)
3643 {
3644   iCode *ic;
3645
3646   ic = newiCode (INLINEASM, NULL, NULL);
3647   IC_INLINE (ic) = tree->values.inlineasm;
3648   ADDTOCHAIN (ic);
3649 }
3650
3651 /*-----------------------------------------------------------------*/
3652 /* geniCodeArrayInit - intermediate code for array initializer     */
3653 /*-----------------------------------------------------------------*/
3654 static void
3655 geniCodeArrayInit (ast * tree, operand *array)
3656 {
3657   iCode *ic;
3658
3659   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3660     ic = newiCode (ARRAYINIT, array, NULL);
3661     IC_ARRAYILIST (ic) = tree->values.constlist;
3662   } else {
3663     operand *left=newOperand(), *right=newOperand();
3664     left->type=right->type=SYMBOL;
3665     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3666     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3667     ic = newiCode (ARRAYINIT, left, right);
3668   }
3669   ADDTOCHAIN (ic);
3670 }
3671         
3672 /*-----------------------------------------------------------------*/
3673 /* geniCodeCritical - intermediate code for a critical statement   */
3674 /*-----------------------------------------------------------------*/
3675 static void 
3676 geniCodeCritical (ast *tree, int lvl)
3677 {
3678   iCode *ic;
3679   operand *op = NULL;
3680
3681   /* If op is NULL, the original interrupt state will saved on */
3682   /* the stack. Otherwise, it will be saved in op. */
3683   
3684   /* Generate a save of the current interrupt state & disabled */
3685   ic = newiCode (CRITICAL, NULL, NULL);
3686   IC_RESULT (ic) = op;
3687   ADDTOCHAIN (ic);
3688   
3689   /* Generate the critical code sequence */
3690   if (tree->left && tree->left->type == EX_VALUE)
3691     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3692   else
3693     ast2iCode (tree->left,lvl+1);
3694   
3695   /* Generate a restore of the original interrupt state */
3696   ic = newiCode (ENDCRITICAL, NULL, op);
3697   ADDTOCHAIN (ic);
3698 }
3699
3700 /*-----------------------------------------------------------------*/
3701 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3702 /* particular case. Ie : assigning or dereferencing array or ptr   */
3703 /*-----------------------------------------------------------------*/
3704 set * lvaluereqSet = NULL;
3705 typedef struct lvalItem
3706   {
3707     int req;
3708     int lvl;
3709   }
3710 lvalItem;
3711
3712 /*-----------------------------------------------------------------*/
3713 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3714 /*-----------------------------------------------------------------*/
3715 void addLvaluereq(int lvl)
3716 {
3717   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3718   lpItem->req=1;
3719   lpItem->lvl=lvl;
3720   addSetHead(&lvaluereqSet,lpItem);
3721
3722 }
3723 /*-----------------------------------------------------------------*/
3724 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3725 /*-----------------------------------------------------------------*/
3726 void delLvaluereq()
3727 {
3728   lvalItem * lpItem;
3729   lpItem = getSet(&lvaluereqSet);
3730   if(lpItem) Safe_free(lpItem);
3731 }
3732 /*-----------------------------------------------------------------*/
3733 /* clearLvaluereq - clear lvalreq flag                             */
3734 /*-----------------------------------------------------------------*/
3735 void clearLvaluereq()
3736 {
3737   lvalItem * lpItem;
3738   lpItem = peekSet(lvaluereqSet);
3739   if(lpItem) lpItem->req = 0;
3740 }
3741 /*-----------------------------------------------------------------*/
3742 /* getLvaluereq - get the last lvalreq level                       */
3743 /*-----------------------------------------------------------------*/
3744 int getLvaluereqLvl()
3745 {
3746   lvalItem * lpItem;
3747   lpItem = peekSet(lvaluereqSet);
3748   if(lpItem) return lpItem->lvl;
3749   return 0;
3750 }
3751 /*-----------------------------------------------------------------*/
3752 /* isLvaluereq - is lvalreq valid for this level ?                 */
3753 /*-----------------------------------------------------------------*/
3754 int isLvaluereq(int lvl)
3755 {
3756   lvalItem * lpItem;
3757   lpItem = peekSet(lvaluereqSet);
3758   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3759   return 0;
3760 }
3761
3762 /*-----------------------------------------------------------------*/
3763 /* ast2iCode - creates an icodeList from an ast                    */
3764 /*-----------------------------------------------------------------*/
3765 operand *
3766 ast2iCode (ast * tree,int lvl)
3767 {
3768   operand *left = NULL;
3769   operand *right = NULL;
3770   if (!tree)
3771     return NULL;
3772
3773   /* set the global variables for filename & line number */
3774   if (tree->filename)
3775     filename = tree->filename;
3776   if (tree->lineno)
3777     lineno = tree->lineno;
3778   if (tree->block)
3779     block = tree->block;
3780   if (tree->level)
3781     scopeLevel = tree->level;
3782   if (tree->seqPoint)
3783     seqPoint = tree->seqPoint;
3784
3785   if (tree->type == EX_VALUE)
3786     return operandFromValue (tree->opval.val);
3787
3788   if (tree->type == EX_LINK)
3789     return operandFromLink (tree->opval.lnk);
3790
3791   /* if we find a nullop */
3792   if (tree->type == EX_OP &&
3793      (tree->opval.op == NULLOP ||
3794      tree->opval.op == BLOCK))
3795     {
3796       if (tree->left && tree->left->type == EX_VALUE)
3797         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3798       else
3799         ast2iCode (tree->left,lvl+1);
3800       if (tree->right && tree->right->type == EX_VALUE)
3801         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3802       else
3803         ast2iCode (tree->right,lvl+1);
3804       return NULL;
3805     }
3806
3807   /* special cases for not evaluating */
3808   if (tree->opval.op != ':' &&
3809       tree->opval.op != '?' &&
3810       tree->opval.op != CALL &&
3811       tree->opval.op != IFX &&
3812       tree->opval.op != AND_OP &&
3813       tree->opval.op != OR_OP &&
3814       tree->opval.op != LABEL &&
3815       tree->opval.op != GOTO &&
3816       tree->opval.op != SWITCH &&
3817       tree->opval.op != FUNCTION &&
3818       tree->opval.op != INLINEASM &&
3819       tree->opval.op != CRITICAL)
3820     {
3821
3822         if (IS_ASSIGN_OP (tree->opval.op) ||
3823            IS_DEREF_OP (tree) ||
3824            (tree->opval.op == '&' && !tree->right) ||
3825            tree->opval.op == PTR_OP)
3826           {
3827             addLvaluereq(lvl);
3828             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3829                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3830               clearLvaluereq();
3831
3832             left = operandFromAst (tree->left,lvl);
3833             delLvaluereq();
3834             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3835               left = geniCodeRValue (left, TRUE);
3836           }
3837         else
3838           {
3839             left = operandFromAst (tree->left,lvl);
3840           }
3841         if (tree->opval.op == INC_OP ||
3842             tree->opval.op == DEC_OP)
3843           {
3844             addLvaluereq(lvl);
3845             right = operandFromAst (tree->right,lvl);
3846             delLvaluereq();
3847           }
3848         else
3849           {
3850             right = operandFromAst (tree->right,lvl);
3851           }
3852       }
3853
3854   /* now depending on the type of operand */
3855   /* this will be a biggy                 */
3856   switch (tree->opval.op)
3857     {
3858
3859     case '[':                   /* array operation */
3860       {
3861         //sym_link *ltype = operandType (left);
3862         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3863         left = geniCodeRValue (left, FALSE);
3864         right = geniCodeRValue (right, TRUE);
3865       }
3866
3867       return geniCodeArray (left, right,lvl);
3868
3869     case '.':                   /* structure dereference */
3870       if (IS_PTR (operandType (left)))
3871         left = geniCodeRValue (left, TRUE);
3872       else
3873         left = geniCodeRValue (left, FALSE);
3874
3875       return geniCodeStruct (left, right, tree->lvalue);
3876
3877     case PTR_OP:                /* structure pointer dereference */
3878       {
3879         sym_link *pType;
3880         pType = operandType (left);
3881         left = geniCodeRValue (left, TRUE);
3882
3883         setOClass (pType, getSpec (operandType (left)));
3884       }
3885
3886       return geniCodeStruct (left, right, tree->lvalue);
3887
3888     case INC_OP:                /* increment operator */
3889       if (left)
3890         return geniCodePostInc (left);
3891       else
3892         return geniCodePreInc (right, tree->lvalue);
3893
3894     case DEC_OP:                /* decrement operator */
3895       if (left)
3896         return geniCodePostDec (left);
3897       else
3898         return geniCodePreDec (right, tree->lvalue);
3899
3900     case '&':                   /* bitwise and or address of operator */
3901       if (right)
3902         {                       /* this is a bitwise operator   */
3903           left = geniCodeRValue (left, FALSE);
3904           right = geniCodeRValue (right, FALSE);
3905           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3906         }
3907       else
3908         return geniCodeAddressOf (left);
3909
3910     case '|':                   /* bitwise or & xor */
3911     case '^':
3912       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3913                               geniCodeRValue (right, FALSE),
3914                               tree->opval.op,
3915                               tree->ftype);
3916
3917     case '/':
3918       return geniCodeDivision (geniCodeRValue (left, FALSE),
3919                                geniCodeRValue (right, FALSE),
3920                                getResultTypeFromType (tree->ftype));
3921
3922     case '%':
3923       return geniCodeModulus (geniCodeRValue (left, FALSE),
3924                               geniCodeRValue (right, FALSE),
3925                               getResultTypeFromType (tree->ftype));
3926     case '*':
3927       if (right)
3928         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3929                                  geniCodeRValue (right, FALSE),
3930                                  getResultTypeFromType (tree->ftype));
3931       else
3932         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3933
3934     case '-':
3935       if (right)
3936         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3937                                  geniCodeRValue (right, FALSE),
3938                                  getResultTypeFromType (tree->ftype));
3939       else
3940         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3941
3942     case '+':
3943       if (right)
3944         return geniCodeAdd (geniCodeRValue (left, FALSE),
3945                             geniCodeRValue (right, FALSE),
3946                             getResultTypeFromType (tree->ftype),
3947                             lvl);
3948       else
3949         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3950
3951     case LEFT_OP:
3952       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3953                                 geniCodeRValue (right, FALSE),
3954                                 getResultTypeFromType (tree->ftype));
3955
3956     case RIGHT_OP:
3957       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3958                                  geniCodeRValue (right, FALSE));
3959     case CAST:
3960 #if 0 // this indeed needs a second thought
3961       {
3962         operand *op;
3963
3964         // let's keep this simple: get the rvalue we need
3965         op=geniCodeRValue (right, FALSE);
3966         // now cast it to whatever we want
3967         op=geniCodeCast (operandType(left), op, FALSE);
3968         // if this is going to be used as an lvalue, make it so
3969         if (tree->lvalue) {
3970           op->isaddr=1;
3971         }
3972         return op;
3973       }
3974 #else // bug #604575, is it a bug ????
3975       return geniCodeCast (operandType (left),
3976                            geniCodeRValue (right, FALSE), FALSE);
3977 #endif
3978
3979     case '~':
3980     case RRC:
3981     case RLC:
3982     case SWAP:
3983       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3984
3985     case '!':
3986     case GETHBIT:
3987       {
3988         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3989         setOperandType (op, UCHARTYPE);
3990         return op;
3991       }
3992     case AND_OP:
3993     case OR_OP:
3994       return geniCodeLogicAndOr (tree, lvl);
3995     case '>':
3996     case '<':
3997     case LE_OP:
3998     case GE_OP:
3999     case EQ_OP:
4000     case NE_OP:
4001       /* different compilers (even different gccs) evaluate
4002          the two calls in a different order. to get the same
4003          result on all machines we've to specify a clear sequence.
4004       return geniCodeLogic (geniCodeRValue (left, FALSE),
4005                             geniCodeRValue (right, FALSE),
4006                             tree->opval.op);
4007       */
4008       {
4009         operand *leftOp, *rightOp;
4010
4011         leftOp  = geniCodeRValue (left , FALSE);
4012         rightOp = geniCodeRValue (right, FALSE);
4013
4014         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4015       }
4016     case '?':
4017       return geniCodeConditional (tree,lvl);
4018
4019     case SIZEOF:
4020       return operandFromLit (getSize (tree->right->ftype));
4021
4022     case '=':
4023       {
4024         sym_link *rtype = operandType (right);
4025         sym_link *ltype = operandType (left);
4026         if (IS_PTR (rtype) && IS_ITEMP (right)
4027             && right->isaddr && compareType (rtype->next, ltype) == 1)
4028           right = geniCodeRValue (right, TRUE);
4029         else
4030           right = geniCodeRValue (right, FALSE);
4031
4032         geniCodeAssign (left, right, 0, 1);
4033         return right;
4034       }
4035     case MUL_ASSIGN:
4036       return
4037         geniCodeAssign (left,
4038                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4039                                                   FALSE),
4040                                   geniCodeRValue (right, FALSE), 
4041                                   getResultTypeFromType (tree->ftype)),
4042                         0, 1);
4043
4044     case DIV_ASSIGN:
4045       return
4046         geniCodeAssign (left,
4047                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4048                                                   FALSE),
4049                                   geniCodeRValue (right, FALSE),
4050                                   getResultTypeFromType (tree->ftype)),
4051                         0, 1);
4052     case MOD_ASSIGN:
4053       return
4054         geniCodeAssign (left,
4055                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4056                                                   FALSE),
4057                                   geniCodeRValue (right, FALSE),
4058                                   getResultTypeFromType (tree->ftype)),
4059                         0, 1);
4060     case ADD_ASSIGN:
4061       {
4062         sym_link *rtype = operandType (right);
4063         sym_link *ltype = operandType (left);
4064         if (IS_PTR (rtype) && IS_ITEMP (right)
4065             && right->isaddr && compareType (rtype->next, ltype) == 1)
4066           right = geniCodeRValue (right, TRUE);
4067         else
4068           right = geniCodeRValue (right, FALSE);
4069
4070
4071         return geniCodeAssign (left,
4072                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4073                                                   FALSE),
4074                                   right,
4075                                   getResultTypeFromType (tree->ftype),
4076                                   lvl),
4077                                0, 1);
4078       }
4079     case SUB_ASSIGN:
4080       {
4081         sym_link *rtype = operandType (right);
4082         sym_link *ltype = operandType (left);
4083         if (IS_PTR (rtype) && IS_ITEMP (right)
4084             && right->isaddr && compareType (rtype->next, ltype) == 1)
4085           {
4086             right = geniCodeRValue (right, TRUE);
4087           }
4088         else
4089           {
4090             right = geniCodeRValue (right, FALSE);
4091           }
4092         return
4093           geniCodeAssign (left,
4094                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4095                                                   FALSE),
4096                                   right,
4097                                   getResultTypeFromType (tree->ftype)),
4098                           0, 1);
4099       }
4100     case LEFT_ASSIGN:
4101       return
4102         geniCodeAssign (left,
4103                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4104                                                    ,FALSE),
4105                                    geniCodeRValue (right, FALSE),
4106                                    getResultTypeFromType (tree->ftype)),
4107                         0, 1);
4108     case RIGHT_ASSIGN:
4109       return
4110         geniCodeAssign (left,
4111                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4112                                                    ,FALSE),
4113                                    geniCodeRValue (right, FALSE)), 0, 1);
4114     case AND_ASSIGN:
4115       return
4116         geniCodeAssign (left,
4117                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4118                                                   FALSE),
4119                                   geniCodeRValue (right, FALSE),
4120                                   BITWISEAND,
4121                                   operandType (left)), 0, 1);
4122     case XOR_ASSIGN:
4123       return
4124         geniCodeAssign (left,
4125                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4126                                                   FALSE),
4127                                   geniCodeRValue (right, FALSE),
4128                                   '^',
4129                                   operandType (left)), 0, 1);
4130     case OR_ASSIGN:
4131       return
4132         geniCodeAssign (left,
4133                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4134                                                    ,FALSE),
4135                                    geniCodeRValue (right, FALSE),
4136                                    '|',
4137                                    operandType (left)), 0, 1);
4138     case ',':
4139       return geniCodeRValue (right, FALSE);
4140
4141     case CALL:
4142       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4143                            tree->right,lvl);
4144     case LABEL:
4145       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4146       return ast2iCode (tree->right,lvl+1);
4147
4148     case GOTO:
4149       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4150       return ast2iCode (tree->right,lvl+1);
4151
4152     case FUNCTION:
4153       geniCodeFunctionBody (tree,lvl);
4154       return NULL;
4155
4156     case RETURN:
4157       geniCodeReturn (right);
4158       return NULL;
4159
4160     case IFX:
4161       geniCodeIfx (tree,lvl);
4162       return NULL;
4163
4164     case SWITCH:
4165       geniCodeSwitch (tree,lvl);
4166       return NULL;
4167
4168     case INLINEASM:
4169       geniCodeInline (tree);
4170       return NULL;
4171         
4172     case ARRAYINIT:
4173         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4174         return NULL;
4175     
4176     case CRITICAL:
4177         geniCodeCritical (tree, lvl);
4178     }
4179
4180   return NULL;
4181 }
4182
4183 /*-----------------------------------------------------------------*/
4184 /* reverseICChain - gets from the list and creates a linkedlist    */
4185 /*-----------------------------------------------------------------*/
4186 iCode *
4187 reverseiCChain ()
4188 {
4189   iCode *loop = NULL;
4190   iCode *prev = NULL;
4191
4192   while ((loop = getSet (&iCodeChain)))
4193     {
4194       loop->next = prev;
4195       if (prev)
4196         prev->prev = loop;
4197       prev = loop;
4198     }
4199
4200   return prev;
4201 }
4202
4203
4204 /*-----------------------------------------------------------------*/
4205 /* iCodeFromAst - given an ast will convert it to iCode            */
4206 /*-----------------------------------------------------------------*/
4207 iCode *
4208 iCodeFromAst (ast * tree)
4209 {
4210   returnLabel = newiTempLabel ("_return");
4211   entryLabel = newiTempLabel ("_entry");
4212   ast2iCode (tree,0);
4213   return reverseiCChain ();
4214 }
4215
4216 static const char *opTypeToStr(OPTYPE op)
4217 {
4218     switch(op)
4219     {
4220       case SYMBOL: return "symbol";
4221       case VALUE: return "value";
4222       case TYPE: return "type";
4223     }
4224     return "undefined type";    
4225 }
4226
4227
4228 operand *validateOpType(operand         *op, 
4229                         const char      *macro,
4230                         const char      *args,
4231                         OPTYPE          type,
4232                         const char      *file, 
4233                         unsigned        line)
4234 {    
4235     if (op && op->type == type)
4236     {
4237         return op;
4238     }
4239     fprintf(stderr, 
4240             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4241             " expected %s, got %s\n",
4242             macro, args, file, line, 
4243             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4244     exit(-1);
4245     return op; // never reached, makes compiler happy.
4246 }