* src/SDCCicode.c (geniCodePreInc, geniCodePreDec): fixed bug #942130
[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
3367   ADDTOCHAIN (ic);
3368
3369   /* for all parameters that are passed
3370      on registers add a "receive" */
3371   geniCodeReceive (tree->values.args);
3372
3373   /* generate code for the body */
3374   ast2iCode (tree->right,lvl+1);
3375
3376   /* create a label for return */
3377   geniCodeLabel (returnLabel);
3378
3379   /* now generate the end proc */
3380   ic = newiCode (ENDFUNCTION, func, NULL);
3381   ADDTOCHAIN (ic);
3382   return;
3383 }
3384
3385 /*-----------------------------------------------------------------*/
3386 /* geniCodeReturn - gen icode for 'return' statement               */
3387 /*-----------------------------------------------------------------*/
3388 void 
3389 geniCodeReturn (operand * op)
3390 {
3391   iCode *ic;
3392
3393   /* if the operand is present force an rvalue */
3394   if (op)
3395     op = geniCodeRValue (op, FALSE);
3396
3397   ic = newiCode (RETURN, op, NULL);
3398   ADDTOCHAIN (ic);
3399 }
3400
3401 /*-----------------------------------------------------------------*/
3402 /* geniCodeIfx - generates code for extended if statement          */
3403 /*-----------------------------------------------------------------*/
3404 void 
3405 geniCodeIfx (ast * tree,int lvl)
3406 {
3407   iCode *ic;
3408   operand *condition = ast2iCode (tree->left,lvl+1);
3409   sym_link *cetype;
3410
3411   /* if condition is null then exit */
3412   if (!condition)
3413     goto exit;
3414   else
3415     condition = geniCodeRValue (condition, FALSE);
3416
3417   cetype = getSpec (operandType (condition));
3418   /* if the condition is a literal */
3419   if (IS_LITERAL (cetype))
3420     {
3421       if (floatFromVal (condition->operand.valOperand))
3422         {
3423           if (tree->trueLabel)
3424             geniCodeGoto (tree->trueLabel);
3425           else
3426             assert (0);
3427         }
3428       else
3429         {
3430           if (tree->falseLabel)
3431             geniCodeGoto (tree->falseLabel);
3432           else
3433             assert (0);
3434         }
3435       goto exit;
3436     }
3437
3438   if (tree->trueLabel)
3439     {
3440       ic = newiCodeCondition (condition,
3441                               tree->trueLabel,
3442                               NULL);
3443       ADDTOCHAIN (ic);
3444
3445       if (tree->falseLabel)
3446         geniCodeGoto (tree->falseLabel);
3447     }
3448   else
3449     {
3450       ic = newiCodeCondition (condition,
3451                               NULL,
3452                               tree->falseLabel);
3453       ADDTOCHAIN (ic);
3454     }
3455
3456 exit:
3457   ast2iCode (tree->right,lvl+1);
3458 }
3459
3460 /*-----------------------------------------------------------------*/
3461 /* geniCodeJumpTable - tries to create a jump table for switch     */
3462 /*-----------------------------------------------------------------*/
3463 int 
3464 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3465 {
3466   int min = 0, max = 0, t, cnt = 0;
3467   value *vch;
3468   iCode *ic;
3469   operand *boundary;
3470   symbol *falseLabel;
3471   set *labels = NULL;
3472   int needRangeCheck = !optimize.noJTabBoundary
3473                        || tree->values.switchVals.swDefault;
3474
3475   if (!tree || !caseVals)
3476     return 0;
3477
3478   /* the criteria for creating a jump table is */
3479   /* all integer numbers between the maximum & minimum must */
3480   /* be present , the maximum value should not exceed 255 */
3481   min = max = (int) floatFromVal (vch = caseVals);
3482   SNPRINTF (buffer, sizeof(buffer), 
3483             "_case_%d_%d",
3484            tree->values.switchVals.swNum,
3485            min);
3486   addSet (&labels, newiTempLabel (buffer));
3487
3488   /* if there is only one case value then no need */
3489   if (!(vch = vch->next))
3490     return 0;
3491
3492   while (vch)
3493     {
3494       if (((t = (int) floatFromVal (vch)) - max) != 1)
3495         return 0;
3496       SNPRINTF (buffer, sizeof(buffer), 
3497                 "_case_%d_%d",
3498                tree->values.switchVals.swNum,
3499                t);
3500       addSet (&labels, newiTempLabel (buffer));
3501       max = t;
3502       cnt++;
3503       vch = vch->next;
3504     }
3505
3506   /* if the number of case statements <= 2 then */
3507   /* it is not economical to create the jump table */
3508   /* since two compares are needed for boundary conditions */
3509   if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3510     return 0;
3511
3512   if (tree->values.switchVals.swDefault)
3513     {
3514         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3515     }
3516   else
3517     {
3518         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3519     }
3520     
3521
3522   falseLabel = newiTempLabel (buffer);
3523
3524   /* so we can create a jumptable */
3525   /* first we rule out the boundary conditions */
3526   /* if only optimization says so */
3527   if (needRangeCheck)
3528     {
3529       sym_link *cetype = getSpec (operandType (cond));
3530       /* no need to check the lower bound if
3531          the condition is unsigned & minimum value is zero */
3532       if (!(min == 0 && IS_UNSIGNED (cetype)))
3533         {
3534           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3535           ic = newiCodeCondition (boundary, falseLabel, NULL);
3536           ADDTOCHAIN (ic);
3537         }
3538
3539       /* now for upper bounds */
3540       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3541       ic = newiCodeCondition (boundary, falseLabel, NULL);
3542       ADDTOCHAIN (ic);
3543     }
3544
3545   /* if the min is not zero then we no make it zero */
3546   if (min)
3547     {
3548       cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3549       if (!IS_LITERAL(getSpec(operandType(cond))))
3550         setOperandType (cond, UCHARTYPE);
3551     }
3552
3553   /* now create the jumptable */
3554   ic = newiCode (JUMPTABLE, NULL, NULL);
3555   IC_JTCOND (ic) = cond;
3556   IC_JTLABELS (ic) = labels;
3557   ADDTOCHAIN (ic);
3558   return 1;
3559 }
3560
3561 /*-----------------------------------------------------------------*/
3562 /* geniCodeSwitch - changes a switch to a if statement             */
3563 /*-----------------------------------------------------------------*/
3564 void
3565 geniCodeSwitch (ast * tree,int lvl)
3566 {
3567   iCode *ic;
3568   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3569   value *caseVals = tree->values.switchVals.swVals;
3570   symbol *trueLabel, *falseLabel;
3571       
3572   /* If the condition is a literal, then just jump to the */
3573   /* appropriate case label. */
3574   if (IS_LITERAL(getSpec(operandType(cond))))
3575     {
3576       int switchVal, caseVal;
3577       
3578       switchVal = (int) floatFromVal (cond->operand.valOperand);
3579       while (caseVals)
3580         {
3581           caseVal = (int) floatFromVal (caseVals);
3582           if (caseVal == switchVal)
3583             {
3584               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3585                         tree->values.switchVals.swNum, caseVal);
3586               trueLabel = newiTempLabel (buffer);
3587               geniCodeGoto (trueLabel);
3588               goto jumpTable;
3589             }
3590           caseVals = caseVals->next;
3591         }
3592       goto defaultOrBreak;
3593     }
3594
3595   /* if we can make this a jump table */
3596   if (geniCodeJumpTable (cond, caseVals, tree))
3597     goto jumpTable;             /* no need for the comparison */
3598
3599   /* for the cases defined do */
3600   while (caseVals)
3601     {
3602
3603       operand *compare = geniCodeLogic (cond,
3604                                         operandFromValue (caseVals),
3605                                         EQ_OP);
3606
3607       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3608                tree->values.switchVals.swNum,
3609                (int) floatFromVal (caseVals));
3610       trueLabel = newiTempLabel (buffer);
3611
3612       ic = newiCodeCondition (compare, trueLabel, NULL);
3613       ADDTOCHAIN (ic);
3614       caseVals = caseVals->next;
3615     }
3616
3617
3618 defaultOrBreak:
3619   /* if default is present then goto break else break */
3620   if (tree->values.switchVals.swDefault)
3621     {
3622         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3623     }
3624   else
3625     {
3626         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3627     }
3628
3629   falseLabel = newiTempLabel (buffer);
3630   geniCodeGoto (falseLabel);
3631
3632 jumpTable:
3633   ast2iCode (tree->right,lvl+1);
3634 }
3635
3636 /*-----------------------------------------------------------------*/
3637 /* geniCodeInline - intermediate code for inline assembler         */
3638 /*-----------------------------------------------------------------*/
3639 static void 
3640 geniCodeInline (ast * tree)
3641 {
3642   iCode *ic;
3643
3644   ic = newiCode (INLINEASM, NULL, NULL);
3645   IC_INLINE (ic) = tree->values.inlineasm;
3646   ADDTOCHAIN (ic);
3647 }
3648
3649 /*-----------------------------------------------------------------*/
3650 /* geniCodeArrayInit - intermediate code for array initializer     */
3651 /*-----------------------------------------------------------------*/
3652 static void
3653 geniCodeArrayInit (ast * tree, operand *array)
3654 {
3655   iCode *ic;
3656
3657   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3658     ic = newiCode (ARRAYINIT, array, NULL);
3659     IC_ARRAYILIST (ic) = tree->values.constlist;
3660   } else {
3661     operand *left=newOperand(), *right=newOperand();
3662     left->type=right->type=SYMBOL;
3663     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3664     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3665     ic = newiCode (ARRAYINIT, left, right);
3666   }
3667   ADDTOCHAIN (ic);
3668 }
3669         
3670 /*-----------------------------------------------------------------*/
3671 /* geniCodeCritical - intermediate code for a critical statement   */
3672 /*-----------------------------------------------------------------*/
3673 static void 
3674 geniCodeCritical (ast *tree, int lvl)
3675 {
3676   iCode *ic;
3677   operand *op = NULL;
3678
3679   /* If op is NULL, the original interrupt state will saved on */
3680   /* the stack. Otherwise, it will be saved in op. */
3681   
3682   /* Generate a save of the current interrupt state & disabled */
3683   ic = newiCode (CRITICAL, NULL, NULL);
3684   IC_RESULT (ic) = op;
3685   ADDTOCHAIN (ic);
3686   
3687   /* Generate the critical code sequence */
3688   if (tree->left && tree->left->type == EX_VALUE)
3689     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3690   else
3691     ast2iCode (tree->left,lvl+1);
3692   
3693   /* Generate a restore of the original interrupt state */
3694   ic = newiCode (ENDCRITICAL, NULL, op);
3695   ADDTOCHAIN (ic);
3696 }
3697
3698 /*-----------------------------------------------------------------*/
3699 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3700 /* particular case. Ie : assigning or dereferencing array or ptr   */
3701 /*-----------------------------------------------------------------*/
3702 set * lvaluereqSet = NULL;
3703 typedef struct lvalItem
3704   {
3705     int req;
3706     int lvl;
3707   }
3708 lvalItem;
3709
3710 /*-----------------------------------------------------------------*/
3711 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3712 /*-----------------------------------------------------------------*/
3713 void addLvaluereq(int lvl)
3714 {
3715   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3716   lpItem->req=1;
3717   lpItem->lvl=lvl;
3718   addSetHead(&lvaluereqSet,lpItem);
3719
3720 }
3721 /*-----------------------------------------------------------------*/
3722 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3723 /*-----------------------------------------------------------------*/
3724 void delLvaluereq()
3725 {
3726   lvalItem * lpItem;
3727   lpItem = getSet(&lvaluereqSet);
3728   if(lpItem) Safe_free(lpItem);
3729 }
3730 /*-----------------------------------------------------------------*/
3731 /* clearLvaluereq - clear lvalreq flag                             */
3732 /*-----------------------------------------------------------------*/
3733 void clearLvaluereq()
3734 {
3735   lvalItem * lpItem;
3736   lpItem = peekSet(lvaluereqSet);
3737   if(lpItem) lpItem->req = 0;
3738 }
3739 /*-----------------------------------------------------------------*/
3740 /* getLvaluereq - get the last lvalreq level                       */
3741 /*-----------------------------------------------------------------*/
3742 int getLvaluereqLvl()
3743 {
3744   lvalItem * lpItem;
3745   lpItem = peekSet(lvaluereqSet);
3746   if(lpItem) return lpItem->lvl;
3747   return 0;
3748 }
3749 /*-----------------------------------------------------------------*/
3750 /* isLvaluereq - is lvalreq valid for this level ?                 */
3751 /*-----------------------------------------------------------------*/
3752 int isLvaluereq(int lvl)
3753 {
3754   lvalItem * lpItem;
3755   lpItem = peekSet(lvaluereqSet);
3756   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3757   return 0;
3758 }
3759
3760 /*-----------------------------------------------------------------*/
3761 /* ast2iCode - creates an icodeList from an ast                    */
3762 /*-----------------------------------------------------------------*/
3763 operand *
3764 ast2iCode (ast * tree,int lvl)
3765 {
3766   operand *left = NULL;
3767   operand *right = NULL;
3768   if (!tree)
3769     return NULL;
3770
3771   /* set the global variables for filename & line number */
3772   if (tree->filename)
3773     filename = tree->filename;
3774   if (tree->lineno)
3775     lineno = tree->lineno;
3776   if (tree->block)
3777     block = tree->block;
3778   if (tree->level)
3779     scopeLevel = tree->level;
3780   if (tree->seqPoint)
3781     seqPoint = tree->seqPoint;
3782
3783   if (tree->type == EX_VALUE)
3784     return operandFromValue (tree->opval.val);
3785
3786   if (tree->type == EX_LINK)
3787     return operandFromLink (tree->opval.lnk);
3788
3789   /* if we find a nullop */
3790   if (tree->type == EX_OP &&
3791      (tree->opval.op == NULLOP ||
3792      tree->opval.op == BLOCK))
3793     {
3794       if (tree->left && tree->left->type == EX_VALUE)
3795         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3796       else
3797         ast2iCode (tree->left,lvl+1);
3798       if (tree->right && tree->right->type == EX_VALUE)
3799         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3800       else
3801         ast2iCode (tree->right,lvl+1);
3802       return NULL;
3803     }
3804
3805   /* special cases for not evaluating */
3806   if (tree->opval.op != ':' &&
3807       tree->opval.op != '?' &&
3808       tree->opval.op != CALL &&
3809       tree->opval.op != IFX &&
3810       tree->opval.op != AND_OP &&
3811       tree->opval.op != OR_OP &&
3812       tree->opval.op != LABEL &&
3813       tree->opval.op != GOTO &&
3814       tree->opval.op != SWITCH &&
3815       tree->opval.op != FUNCTION &&
3816       tree->opval.op != INLINEASM &&
3817       tree->opval.op != CRITICAL)
3818     {
3819
3820         if (IS_ASSIGN_OP (tree->opval.op) ||
3821            IS_DEREF_OP (tree) ||
3822            (tree->opval.op == '&' && !tree->right) ||
3823            tree->opval.op == PTR_OP)
3824           {
3825             addLvaluereq(lvl);
3826             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3827                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3828               clearLvaluereq();
3829
3830             left = operandFromAst (tree->left,lvl);
3831             delLvaluereq();
3832             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3833               left = geniCodeRValue (left, TRUE);
3834           }
3835         else
3836           {
3837             left = operandFromAst (tree->left,lvl);
3838           }
3839         if (tree->opval.op == INC_OP ||
3840             tree->opval.op == DEC_OP)
3841           {
3842             addLvaluereq(lvl);
3843             right = operandFromAst (tree->right,lvl);
3844             delLvaluereq();
3845           }
3846         else
3847           {
3848             right = operandFromAst (tree->right,lvl);
3849           }
3850       }
3851
3852   /* now depending on the type of operand */
3853   /* this will be a biggy                 */
3854   switch (tree->opval.op)
3855     {
3856
3857     case '[':                   /* array operation */
3858       {
3859         //sym_link *ltype = operandType (left);
3860         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3861         left = geniCodeRValue (left, FALSE);
3862         right = geniCodeRValue (right, TRUE);
3863       }
3864
3865       return geniCodeArray (left, right,lvl);
3866
3867     case '.':                   /* structure dereference */
3868       if (IS_PTR (operandType (left)))
3869         left = geniCodeRValue (left, TRUE);
3870       else
3871         left = geniCodeRValue (left, FALSE);
3872
3873       return geniCodeStruct (left, right, tree->lvalue);
3874
3875     case PTR_OP:                /* structure pointer dereference */
3876       {
3877         sym_link *pType;
3878         pType = operandType (left);
3879         left = geniCodeRValue (left, TRUE);
3880
3881         setOClass (pType, getSpec (operandType (left)));
3882       }
3883
3884       return geniCodeStruct (left, right, tree->lvalue);
3885
3886     case INC_OP:                /* increment operator */
3887       if (left)
3888         return geniCodePostInc (left);
3889       else
3890         return geniCodePreInc (right, tree->lvalue);
3891
3892     case DEC_OP:                /* decrement operator */
3893       if (left)
3894         return geniCodePostDec (left);
3895       else
3896         return geniCodePreDec (right, tree->lvalue);
3897
3898     case '&':                   /* bitwise and or address of operator */
3899       if (right)
3900         {                       /* this is a bitwise operator   */
3901           left = geniCodeRValue (left, FALSE);
3902           right = geniCodeRValue (right, FALSE);
3903           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3904         }
3905       else
3906         return geniCodeAddressOf (left);
3907
3908     case '|':                   /* bitwise or & xor */
3909     case '^':
3910       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3911                               geniCodeRValue (right, FALSE),
3912                               tree->opval.op,
3913                               tree->ftype);
3914
3915     case '/':
3916       return geniCodeDivision (geniCodeRValue (left, FALSE),
3917                                geniCodeRValue (right, FALSE),
3918                                getResultTypeFromType (tree->ftype));
3919
3920     case '%':
3921       return geniCodeModulus (geniCodeRValue (left, FALSE),
3922                               geniCodeRValue (right, FALSE),
3923                               getResultTypeFromType (tree->ftype));
3924     case '*':
3925       if (right)
3926         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3927                                  geniCodeRValue (right, FALSE),
3928                                  getResultTypeFromType (tree->ftype));
3929       else
3930         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3931
3932     case '-':
3933       if (right)
3934         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3935                                  geniCodeRValue (right, FALSE),
3936                                  getResultTypeFromType (tree->ftype));
3937       else
3938         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3939
3940     case '+':
3941       if (right)
3942         return geniCodeAdd (geniCodeRValue (left, FALSE),
3943                             geniCodeRValue (right, FALSE),
3944                             getResultTypeFromType (tree->ftype),
3945                             lvl);
3946       else
3947         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3948
3949     case LEFT_OP:
3950       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3951                                 geniCodeRValue (right, FALSE),
3952                                 getResultTypeFromType (tree->ftype));
3953
3954     case RIGHT_OP:
3955       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3956                                  geniCodeRValue (right, FALSE));
3957     case CAST:
3958 #if 0 // this indeed needs a second thought
3959       {
3960         operand *op;
3961
3962         // let's keep this simple: get the rvalue we need
3963         op=geniCodeRValue (right, FALSE);
3964         // now cast it to whatever we want
3965         op=geniCodeCast (operandType(left), op, FALSE);
3966         // if this is going to be used as an lvalue, make it so
3967         if (tree->lvalue) {
3968           op->isaddr=1;
3969         }
3970         return op;
3971       }
3972 #else // bug #604575, is it a bug ????
3973       return geniCodeCast (operandType (left),
3974                            geniCodeRValue (right, FALSE), FALSE);
3975 #endif
3976
3977     case '~':
3978     case RRC:
3979     case RLC:
3980     case SWAP:
3981       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3982
3983     case '!':
3984     case GETHBIT:
3985       {
3986         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3987         setOperandType (op, UCHARTYPE);
3988         return op;
3989       }
3990     case AND_OP:
3991     case OR_OP:
3992       return geniCodeLogicAndOr (tree, lvl);
3993     case '>':
3994     case '<':
3995     case LE_OP:
3996     case GE_OP:
3997     case EQ_OP:
3998     case NE_OP:
3999       /* different compilers (even different gccs) evaluate
4000          the two calls in a different order. to get the same
4001          result on all machines we've to specify a clear sequence.
4002       return geniCodeLogic (geniCodeRValue (left, FALSE),
4003                             geniCodeRValue (right, FALSE),
4004                             tree->opval.op);
4005       */
4006       {
4007         operand *leftOp, *rightOp;
4008
4009         leftOp  = geniCodeRValue (left , FALSE);
4010         rightOp = geniCodeRValue (right, FALSE);
4011
4012         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4013       }
4014     case '?':
4015       return geniCodeConditional (tree,lvl);
4016
4017     case SIZEOF:
4018       return operandFromLit (getSize (tree->right->ftype));
4019
4020     case '=':
4021       {
4022         sym_link *rtype = operandType (right);
4023         sym_link *ltype = operandType (left);
4024         if (IS_PTR (rtype) && IS_ITEMP (right)
4025             && right->isaddr && compareType (rtype->next, ltype) == 1)
4026           right = geniCodeRValue (right, TRUE);
4027         else
4028           right = geniCodeRValue (right, FALSE);
4029
4030         geniCodeAssign (left, right, 0, 1);
4031         return right;
4032       }
4033     case MUL_ASSIGN:
4034       return
4035         geniCodeAssign (left,
4036                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4037                                                   FALSE),
4038                                   geniCodeRValue (right, FALSE), 
4039                                   getResultTypeFromType (tree->ftype)),
4040                         0, 1);
4041
4042     case DIV_ASSIGN:
4043       return
4044         geniCodeAssign (left,
4045                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4046                                                   FALSE),
4047                                   geniCodeRValue (right, FALSE),
4048                                   getResultTypeFromType (tree->ftype)),
4049                         0, 1);
4050     case MOD_ASSIGN:
4051       return
4052         geniCodeAssign (left,
4053                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4054                                                   FALSE),
4055                                   geniCodeRValue (right, FALSE),
4056                                   getResultTypeFromType (tree->ftype)),
4057                         0, 1);
4058     case ADD_ASSIGN:
4059       {
4060         sym_link *rtype = operandType (right);
4061         sym_link *ltype = operandType (left);
4062         if (IS_PTR (rtype) && IS_ITEMP (right)
4063             && right->isaddr && compareType (rtype->next, ltype) == 1)
4064           right = geniCodeRValue (right, TRUE);
4065         else
4066           right = geniCodeRValue (right, FALSE);
4067
4068
4069         return geniCodeAssign (left,
4070                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4071                                                   FALSE),
4072                                   right,
4073                                   getResultTypeFromType (tree->ftype),
4074                                   lvl),
4075                                0, 1);
4076       }
4077     case SUB_ASSIGN:
4078       {
4079         sym_link *rtype = operandType (right);
4080         sym_link *ltype = operandType (left);
4081         if (IS_PTR (rtype) && IS_ITEMP (right)
4082             && right->isaddr && compareType (rtype->next, ltype) == 1)
4083           {
4084             right = geniCodeRValue (right, TRUE);
4085           }
4086         else
4087           {
4088             right = geniCodeRValue (right, FALSE);
4089           }
4090         return
4091           geniCodeAssign (left,
4092                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4093                                                   FALSE),
4094                                   right,
4095                                   getResultTypeFromType (tree->ftype)),
4096                           0, 1);
4097       }
4098     case LEFT_ASSIGN:
4099       return
4100         geniCodeAssign (left,
4101                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4102                                                    ,FALSE),
4103                                    geniCodeRValue (right, FALSE),
4104                                    getResultTypeFromType (tree->ftype)),
4105                         0, 1);
4106     case RIGHT_ASSIGN:
4107       return
4108         geniCodeAssign (left,
4109                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4110                                                    ,FALSE),
4111                                    geniCodeRValue (right, FALSE)), 0, 1);
4112     case AND_ASSIGN:
4113       return
4114         geniCodeAssign (left,
4115                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4116                                                   FALSE),
4117                                   geniCodeRValue (right, FALSE),
4118                                   BITWISEAND,
4119                                   operandType (left)), 0, 1);
4120     case XOR_ASSIGN:
4121       return
4122         geniCodeAssign (left,
4123                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4124                                                   FALSE),
4125                                   geniCodeRValue (right, FALSE),
4126                                   '^',
4127                                   operandType (left)), 0, 1);
4128     case OR_ASSIGN:
4129       return
4130         geniCodeAssign (left,
4131                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4132                                                    ,FALSE),
4133                                    geniCodeRValue (right, FALSE),
4134                                    '|',
4135                                    operandType (left)), 0, 1);
4136     case ',':
4137       return geniCodeRValue (right, FALSE);
4138
4139     case CALL:
4140       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4141                            tree->right,lvl);
4142     case LABEL:
4143       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4144       return ast2iCode (tree->right,lvl+1);
4145
4146     case GOTO:
4147       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4148       return ast2iCode (tree->right,lvl+1);
4149
4150     case FUNCTION:
4151       geniCodeFunctionBody (tree,lvl);
4152       return NULL;
4153
4154     case RETURN:
4155       geniCodeReturn (right);
4156       return NULL;
4157
4158     case IFX:
4159       geniCodeIfx (tree,lvl);
4160       return NULL;
4161
4162     case SWITCH:
4163       geniCodeSwitch (tree,lvl);
4164       return NULL;
4165
4166     case INLINEASM:
4167       geniCodeInline (tree);
4168       return NULL;
4169         
4170     case ARRAYINIT:
4171         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4172         return NULL;
4173     
4174     case CRITICAL:
4175         geniCodeCritical (tree, lvl);
4176     }
4177
4178   return NULL;
4179 }
4180
4181 /*-----------------------------------------------------------------*/
4182 /* reverseICChain - gets from the list and creates a linkedlist    */
4183 /*-----------------------------------------------------------------*/
4184 iCode *
4185 reverseiCChain ()
4186 {
4187   iCode *loop = NULL;
4188   iCode *prev = NULL;
4189
4190   while ((loop = getSet (&iCodeChain)))
4191     {
4192       loop->next = prev;
4193       if (prev)
4194         prev->prev = loop;
4195       prev = loop;
4196     }
4197
4198   return prev;
4199 }
4200
4201
4202 /*-----------------------------------------------------------------*/
4203 /* iCodeFromAst - given an ast will convert it to iCode            */
4204 /*-----------------------------------------------------------------*/
4205 iCode *
4206 iCodeFromAst (ast * tree)
4207 {
4208   returnLabel = newiTempLabel ("_return");
4209   entryLabel = newiTempLabel ("_entry");
4210   ast2iCode (tree,0);
4211   return reverseiCChain ();
4212 }
4213
4214 static const char *opTypeToStr(OPTYPE op)
4215 {
4216     switch(op)
4217     {
4218       case SYMBOL: return "symbol";
4219       case VALUE: return "value";
4220       case TYPE: return "type";
4221     }
4222     return "undefined type";    
4223 }
4224
4225
4226 operand *validateOpType(operand         *op, 
4227                         const char      *macro,
4228                         const char      *args,
4229                         OPTYPE          type,
4230                         const char      *file, 
4231                         unsigned        line)
4232 {    
4233     if (op && op->type == type)
4234     {
4235         return op;
4236     }
4237     fprintf(stderr, 
4238             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4239             " expected %s, got %s\n",
4240             macro, args, file, line, 
4241             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4242     exit(-1);
4243     return op; // never reached, makes compiler happy.
4244 }