* src/SDCCicode.c (geniCodeLogic): made it static,
[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);
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 /* geniCodeArray2Ptr - array to pointer                            */
2327 /*-----------------------------------------------------------------*/
2328 static operand *
2329 geniCodeArray2Ptr (operand * op)
2330 {
2331   sym_link *optype = operandType (op);
2332   sym_link *opetype = getSpec (optype);
2333
2334   /* set the pointer depending on the storage class */
2335   DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2336
2337   op->isaddr = 0;
2338   return op;
2339 }
2340
2341
2342 /*-----------------------------------------------------------------*/
2343 /* geniCodeArray - array access                                    */
2344 /*-----------------------------------------------------------------*/
2345 static operand *
2346 geniCodeArray (operand * left, operand * right, int lvl)
2347 {
2348   iCode *ic;
2349   operand *size;
2350   sym_link *ltype = operandType (left);
2351   bool indexUnsigned;
2352
2353   if (IS_PTR (ltype))
2354     {
2355       if (IS_PTR (ltype->next) && left->isaddr)
2356         {
2357           left = geniCodeRValue (left, FALSE);
2358         }
2359
2360       return geniCodeDerefPtr (geniCodeAdd (left,
2361                                             right,
2362                                             (getArraySizePtr(left) >= INTSIZE) ?
2363                                               RESULT_TYPE_INT :
2364                                               RESULT_TYPE_CHAR,
2365                                             lvl),
2366                                lvl);
2367     }
2368   size = operandFromLit (getSize (ltype->next));
2369   SPEC_USIGN (getSpec (operandType (size))) = 1;
2370   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2371   right = geniCodeMultiply (right,
2372                             size,
2373                             (getArraySizePtr(left) >= INTSIZE) ?
2374                               RESULT_TYPE_INT :
2375                               RESULT_TYPE_CHAR);
2376   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2377      It doesn't make sense when accessing arrays, so let's fix it here: */
2378   if (indexUnsigned)
2379     SPEC_USIGN (getSpec (operandType (right))) = 1;
2380   /* we can check for limits here */
2381   /* already done in SDCCast.c
2382   if (isOperandLiteral (right) &&
2383       IS_ARRAY (ltype) &&
2384       DCL_ELEM (ltype) &&
2385       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2386     {
2387       werror (W_IDX_OUT_OF_BOUNDS,
2388               (int) operandLitValue (right) / getSize (ltype->next),
2389               DCL_ELEM (ltype));
2390     }
2391   */
2392
2393   ic = newiCode ('+', left, right);
2394
2395   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2396                                       !IS_AGGREGATE (ltype->next) &&
2397                                       !IS_PTR (ltype->next))
2398                                      ? ltype : ltype->next), 0);
2399
2400   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2401   ADDTOCHAIN (ic);
2402
2403   return IC_RESULT (ic);
2404 }
2405
2406 /*-----------------------------------------------------------------*/
2407 /* geniCodeStruct - generates intermediate code for structures     */
2408 /*-----------------------------------------------------------------*/
2409 operand *
2410 geniCodeStruct (operand * left, operand * right, bool islval)
2411 {
2412   iCode *ic;
2413   sym_link *type = operandType (left);
2414   sym_link *etype = getSpec (type);
2415   sym_link *retype;
2416   symbol *element = getStructElement (SPEC_STRUCT (etype),
2417                                       right->operand.symOperand);
2418
2419   wassert(IS_SYMOP(right));
2420     
2421   /* add the offset */
2422   ic = newiCode ('+', left, operandFromLit (element->offset));
2423
2424   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2425
2426   /* preserve the storage & output class of the struct */
2427   /* as well as the volatile attribute */
2428   retype = getSpec (operandType (IC_RESULT (ic)));
2429   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2430   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2431   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2432   SPEC_CONST (retype) |= SPEC_CONST (etype);
2433   
2434   if (IS_PTR (element->type))
2435     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2436   
2437   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2438
2439   ADDTOCHAIN (ic);
2440   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2441 }
2442
2443 /*-----------------------------------------------------------------*/
2444 /* geniCodePostInc - generate int code for Post increment          */
2445 /*-----------------------------------------------------------------*/
2446 operand *
2447 geniCodePostInc (operand * op)
2448 {
2449   iCode *ic;
2450   operand *rOp;
2451   sym_link *optype = operandType (op);
2452   operand *result;
2453   operand *rv = (IS_ITEMP (op) ?
2454                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2455                  op);
2456   sym_link *rvtype = operandType (rv);
2457   int size = 0;
2458
2459   /* if this is not an address we have trouble */
2460   if (!op->isaddr)
2461     {
2462       werror (E_LVALUE_REQUIRED, "++");
2463       return op;
2464     }
2465
2466   rOp = newiTempOperand (rvtype, 0);
2467   OP_SYMBOL(rOp)->noSpilLoc = 1;
2468
2469   if (IS_ITEMP (rv))
2470     OP_SYMBOL(rv)->noSpilLoc = 1;
2471
2472   geniCodeAssign (rOp, rv, 0);
2473
2474   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2475   if (IS_FLOAT (rvtype))
2476     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2477   else
2478     ic = newiCode ('+', rv, operandFromLit (size));
2479
2480   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2481   ADDTOCHAIN (ic);
2482
2483   geniCodeAssign (op, result, 0);
2484
2485   return rOp;
2486
2487 }
2488
2489 /*-----------------------------------------------------------------*/
2490 /* geniCodePreInc - generate code for preIncrement                 */
2491 /*-----------------------------------------------------------------*/
2492 operand *
2493 geniCodePreInc (operand * op, bool lvalue)
2494 {
2495   iCode *ic;
2496   sym_link *optype = operandType (op);
2497   operand *rop = (IS_ITEMP (op) ?
2498                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2499                   op);
2500   sym_link *roptype = operandType (rop);
2501   operand *result;
2502   int size = 0;
2503
2504   if (!op->isaddr)
2505     {
2506       werror (E_LVALUE_REQUIRED, "++");
2507       return op;
2508     }
2509
2510
2511   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2512   if (IS_FLOAT (roptype))
2513     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2514   else
2515     ic = newiCode ('+', rop, operandFromLit (size));
2516   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2517   ADDTOCHAIN (ic);
2518
2519   (void) geniCodeAssign (op, result, 0);
2520   if (lvalue || IS_TRUE_SYMOP (op))
2521     return op;
2522   else
2523     return result;
2524 }
2525
2526 /*-----------------------------------------------------------------*/
2527 /* geniCodePostDec - generates code for Post decrement             */
2528 /*-----------------------------------------------------------------*/
2529 operand *
2530 geniCodePostDec (operand * op)
2531 {
2532   iCode *ic;
2533   operand *rOp;
2534   sym_link *optype = operandType (op);
2535   operand *result;
2536   operand *rv = (IS_ITEMP (op) ?
2537                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2538                  op);
2539   sym_link *rvtype = operandType (rv);
2540   int size = 0;
2541
2542   /* if this is not an address we have trouble */
2543   if (!op->isaddr)
2544     {
2545       werror (E_LVALUE_REQUIRED, "--");
2546       return op;
2547     }
2548
2549   rOp = newiTempOperand (rvtype, 0);
2550   OP_SYMBOL(rOp)->noSpilLoc = 1;
2551
2552   if (IS_ITEMP (rv))
2553     OP_SYMBOL(rv)->noSpilLoc = 1;
2554
2555   geniCodeAssign (rOp, rv, 0);
2556
2557   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2558   if (IS_FLOAT (rvtype))
2559     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2560   else
2561     ic = newiCode ('-', rv, operandFromLit (size));
2562
2563   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2564   ADDTOCHAIN (ic);
2565
2566   geniCodeAssign (op, result, 0);
2567
2568   return rOp;
2569
2570 }
2571
2572 /*-----------------------------------------------------------------*/
2573 /* geniCodePreDec - generate code for pre  decrement               */
2574 /*-----------------------------------------------------------------*/
2575 operand *
2576 geniCodePreDec (operand * op, bool lvalue)
2577 {
2578   iCode *ic;
2579   sym_link *optype = operandType (op);
2580   operand *rop = (IS_ITEMP (op) ?
2581                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2582                   op);
2583   sym_link *roptype = operandType (rop);
2584   operand *result;
2585   int size = 0;
2586
2587   if (!op->isaddr)
2588     {
2589       werror (E_LVALUE_REQUIRED, "--");
2590       return op;
2591     }
2592
2593
2594   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2595   if (IS_FLOAT (roptype))
2596     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2597   else
2598     ic = newiCode ('-', rop, operandFromLit (size));
2599   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2600   ADDTOCHAIN (ic);
2601
2602   (void) geniCodeAssign (op, result, 0);
2603   if (lvalue || IS_TRUE_SYMOP (op))
2604     return op;
2605   else
2606     return result;
2607 }
2608
2609
2610 /*-----------------------------------------------------------------*/
2611 /* geniCodeBitwise - gen int code for bitWise  operators           */
2612 /*-----------------------------------------------------------------*/
2613 operand *
2614 geniCodeBitwise (operand * left, operand * right,
2615                  int oper, sym_link * resType)
2616 {
2617   iCode *ic;
2618
2619   left = geniCodeCast (resType, left, TRUE);
2620   right = geniCodeCast (resType, right, TRUE);
2621
2622   ic = newiCode (oper, left, right);
2623   IC_RESULT (ic) = newiTempOperand (resType, 0);
2624
2625   ADDTOCHAIN (ic);
2626   return IC_RESULT (ic);
2627 }
2628
2629 /*-----------------------------------------------------------------*/
2630 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2631 /*-----------------------------------------------------------------*/
2632 operand *
2633 geniCodeAddressOf (operand * op)
2634 {
2635   iCode *ic;
2636   sym_link *p;
2637   sym_link *optype = operandType (op);
2638   sym_link *opetype = getSpec (optype);
2639
2640   if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2641     {
2642       op = operandFromOperand (op);
2643       op->isaddr = 0;
2644       return op;
2645     }
2646   
2647   /* lvalue check already done in decorateType */
2648   /* this must be a lvalue */
2649 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2650 /*  werror (E_LVALUE_REQUIRED,"&"); */
2651 /*  return op; */
2652 /*     } */
2653
2654   p = newLink (DECLARATOR);
2655
2656   /* set the pointer depending on the storage class */
2657   DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2658
2659   p->next = copyLinkChain (optype);
2660
2661   /* if already a temp */
2662   if (IS_ITEMP (op))
2663     {
2664       setOperandType (op, p);
2665       op->isaddr = 0;
2666       return op;
2667     }
2668
2669   /* other wise make this of the type coming in */
2670   ic = newiCode (ADDRESS_OF, op, NULL);
2671   IC_RESULT (ic) = newiTempOperand (p, 1);
2672   IC_RESULT (ic)->isaddr = 0;
2673   ADDTOCHAIN (ic);
2674   return IC_RESULT (ic);
2675 }
2676 /*-----------------------------------------------------------------*/
2677 /* setOClass - sets the output class depending on the pointer type */
2678 /*-----------------------------------------------------------------*/
2679 void 
2680 setOClass (sym_link * ptr, sym_link * spec)
2681 {
2682   switch (DCL_TYPE (ptr))
2683     {
2684     case POINTER:
2685       SPEC_OCLS (spec) = data;
2686       break;
2687
2688     case GPOINTER:
2689       SPEC_OCLS (spec) = generic;
2690       break;
2691
2692     case FPOINTER:
2693       SPEC_OCLS (spec) = xdata;
2694       break;
2695
2696     case CPOINTER:
2697       SPEC_OCLS (spec) = code;
2698       break;
2699
2700     case IPOINTER:
2701       SPEC_OCLS (spec) = idata;
2702       break;
2703
2704     case PPOINTER:
2705       SPEC_OCLS (spec) = xstack;
2706       break;
2707
2708     case EEPPOINTER:
2709       SPEC_OCLS (spec) = eeprom;
2710       break;
2711
2712     default:
2713       break;
2714
2715     }
2716 }
2717
2718 /*-----------------------------------------------------------------*/
2719 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2720 /*-----------------------------------------------------------------*/
2721 operand *
2722 geniCodeDerefPtr (operand * op,int lvl)
2723 {
2724   sym_link *rtype, *retype;
2725   sym_link *optype = operandType (op);
2726
2727   // if this is an array then array access
2728   if (IS_ARRAY (optype)) {
2729     // don't worry, this will be optimized out later
2730     return geniCodeArray (op, operandFromLit (0), lvl);
2731   }
2732
2733   // just in case someone screws up
2734   wassert (IS_PTR (optype));
2735
2736   if (IS_TRUE_SYMOP (op))
2737     {
2738       op->isaddr = 1;
2739       op = geniCodeRValue (op, TRUE);
2740     }
2741
2742   /* now get rid of the pointer part */
2743   if (isLvaluereq(lvl) && IS_ITEMP (op))
2744     {
2745       retype = getSpec (rtype = copyLinkChain (optype));
2746     }
2747   else
2748     {
2749       retype = getSpec (rtype = copyLinkChain (optype->next));
2750       /* outputclass needs 2b updated */
2751       setOClass (optype, retype);
2752     }
2753   
2754   op->isGptr = IS_GENPTR (optype);
2755
2756   op->isaddr = (IS_PTR (rtype) ||
2757                 IS_STRUCT (rtype) ||
2758                 IS_INT (rtype) ||
2759                 IS_CHAR (rtype) ||
2760                 IS_FLOAT (rtype));
2761
2762   if (!isLvaluereq(lvl))
2763     op = geniCodeRValue (op, TRUE);
2764
2765   setOperandType (op, rtype);
2766
2767   return op;
2768 }
2769
2770 /*-----------------------------------------------------------------*/
2771 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2772 /*-----------------------------------------------------------------*/
2773 operand *
2774 geniCodeUnaryMinus (operand * op)
2775 {
2776   iCode *ic;
2777   sym_link *optype = operandType (op);
2778
2779   if (IS_LITERAL (optype))
2780     return operandFromLit (-floatFromVal (op->operand.valOperand));
2781
2782   ic = newiCode (UNARYMINUS, op, NULL);
2783   IC_RESULT (ic) = newiTempOperand (optype, 0);
2784   ADDTOCHAIN (ic);
2785   return IC_RESULT (ic);
2786 }
2787
2788 /*-----------------------------------------------------------------*/
2789 /* geniCodeLeftShift - gen i code for left shift                   */
2790 /*-----------------------------------------------------------------*/
2791 operand *
2792 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2793 {
2794   iCode *ic;
2795   sym_link *resType;
2796
2797   ic = newiCode (LEFT_OP, left, right);
2798
2799   resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2800   IC_RESULT (ic) = newiTempOperand (resType, 0);
2801   ADDTOCHAIN (ic);
2802   return IC_RESULT (ic);
2803 }
2804
2805 /*-----------------------------------------------------------------*/
2806 /* geniCodeRightShift - gen i code for right shift                 */
2807 /*-----------------------------------------------------------------*/
2808 operand *
2809 geniCodeRightShift (operand * left, operand * right)
2810 {
2811   iCode *ic;
2812
2813   ic = newiCode (RIGHT_OP, left, right);
2814   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2815   ADDTOCHAIN (ic);
2816   return IC_RESULT (ic);
2817 }
2818
2819 /*-----------------------------------------------------------------*/
2820 /* geniCodeLogic- logic code                                       */
2821 /*-----------------------------------------------------------------*/
2822 static operand *
2823 geniCodeLogic (operand * left, operand * right, int op)
2824 {
2825   iCode *ic;
2826   sym_link *ctype;
2827   sym_link *rtype = operandType (right);
2828   sym_link *ltype = operandType (left);
2829
2830   /* left is integral type and right is literal then
2831      check if the literal value is within bounds */
2832   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2833     {
2834       checkConstantRange(ltype,
2835                          OP_VALUE(right), "compare operation", 1);
2836     }
2837
2838   /* if one operand is a pointer and the other is a literal generic void pointer,
2839      change the type of the literal generic void pointer to match the other pointer */
2840   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2841       && IS_PTR (rtype) && !IS_GENPTR(rtype))
2842     {
2843       /* find left's definition */
2844       ic = (iCode *) setFirstItem (iCodeChain);
2845       while (ic)
2846         {
2847           if (((ic->op == CAST) || (ic->op == '='))
2848               && isOperandEqual(left, IC_RESULT (ic)))
2849             break;
2850           else
2851             ic = setNextItem (iCodeChain);
2852         }
2853       /* if casting literal to generic pointer, then cast to rtype instead */
2854       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2855         {
2856           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2857           ltype = operandType(left);
2858         }
2859     }
2860   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2861       && IS_PTR (ltype) && !IS_GENPTR(ltype))
2862     {
2863       /* find right's definition */
2864       ic = (iCode *) setFirstItem (iCodeChain);
2865       while (ic)
2866         {
2867           if (((ic->op == CAST) || (ic->op == '='))
2868               && isOperandEqual(right, IC_RESULT (ic)))
2869             break;
2870           else
2871             ic = setNextItem (iCodeChain);
2872         }
2873       /* if casting literal to generic pointer, then cast to rtype instead */
2874       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2875         {
2876           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2877           rtype = operandType(right);
2878         }
2879     }
2880
2881   ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2882
2883   ic = newiCode (op, left, right);
2884   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2885
2886   /* if comparing float
2887      and not a '==' || '!=' || '&&' || '||' (these
2888      will be inlined */
2889   if (IS_FLOAT(ctype) &&
2890       op != EQ_OP &&
2891       op != NE_OP &&
2892       op != AND_OP &&
2893       op != OR_OP)
2894    ic->supportRtn = 1;
2895
2896   ADDTOCHAIN (ic);
2897   return IC_RESULT (ic);
2898 }
2899
2900 /*-----------------------------------------------------------------*/
2901 /* geniCodeLogicAndOr - && || operations                           */
2902 /*-----------------------------------------------------------------*/
2903 static operand *
2904 geniCodeLogicAndOr (ast *tree, int lvl)
2905 {
2906   iCode *ic;
2907   symbol *falseLabel = newiTempLabel (NULL);
2908   symbol *trueLabel  = newiTempLabel (NULL);
2909   symbol *exitLabel  = newiTempLabel (NULL);
2910   operand *op, *result, *condition;
2911
2912   /* AND_OP and OR_OP are no longer generated because of bug-905492.
2913      They can be reenabled by executing the following block. If you find
2914      a decent optimization you could start right here:
2915   */
2916 #if 0
2917   if (0)
2918     {
2919        operand *leftOp, *rightOp;
2920
2921        leftOp  = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
2922        rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
2923
2924        return geniCodeLogic (leftOp, rightOp, tree->opval.op);
2925     }
2926 #endif
2927
2928   /* generate two IFX for the '&&' or '||' op */
2929
2930   /* evaluate left operand */
2931   condition = ast2iCode (tree->left, lvl + 1);
2932   op = geniCodeRValue (condition, FALSE);
2933
2934   /* test left operand */
2935   if (tree->opval.op == AND_OP)
2936     ic = newiCodeCondition (op, NULL, falseLabel);
2937   else /* OR_OP */
2938     ic = newiCodeCondition (op, trueLabel, NULL);
2939   ADDTOCHAIN (ic);
2940   
2941   /* evaluate right operand */
2942   condition = ast2iCode (tree->right, lvl + 1);
2943   op = geniCodeRValue (condition, FALSE);
2944   
2945   /* test right operand */
2946   ic = newiCodeCondition (op, trueLabel, NULL);
2947   ADDTOCHAIN (ic);
2948   
2949   /* store 0 or 1 in result */
2950   result = newiTempOperand (newCharLink(), 1);
2951   
2952   geniCodeLabel (falseLabel);
2953   geniCodeAssign (result, operandFromLit (0), 0);
2954   /* generate an unconditional goto */
2955   geniCodeGoto (exitLabel);
2956
2957   geniCodeLabel (trueLabel);
2958   geniCodeAssign (result, operandFromLit (1), 0);
2959
2960   geniCodeLabel (exitLabel);
2961
2962   return result;
2963 }
2964
2965 /*-----------------------------------------------------------------*/
2966 /* geniCodeUnary - for a a generic unary operation                 */
2967 /*-----------------------------------------------------------------*/
2968 operand *
2969 geniCodeUnary (operand * op, int oper)
2970 {
2971   iCode *ic = newiCode (oper, op, NULL);
2972
2973   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2974   ADDTOCHAIN (ic);
2975   return IC_RESULT (ic);
2976 }
2977
2978 /*-----------------------------------------------------------------*/
2979 /* geniCodeConditional - geniCode for '?' ':' operation            */
2980 /*-----------------------------------------------------------------*/
2981 operand *
2982 geniCodeConditional (ast * tree,int lvl)
2983 {
2984   iCode *ic;
2985   symbol *falseLabel = newiTempLabel (NULL);
2986   symbol *exitLabel = newiTempLabel (NULL);
2987   operand *cond = ast2iCode (tree->left,lvl+1);
2988   operand *true, *false, *result;
2989
2990   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2991                           NULL, falseLabel);
2992   ADDTOCHAIN (ic);
2993
2994   true = ast2iCode (tree->right->left,lvl+1);
2995
2996   /* move the value to a new Operand */
2997   result = newiTempOperand (tree->right->ftype, 0);
2998   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2999
3000   /* generate an unconditional goto */
3001   geniCodeGoto (exitLabel);
3002
3003   /* now for the right side */
3004   geniCodeLabel (falseLabel);
3005
3006   false = ast2iCode (tree->right->right,lvl+1);
3007   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
3008
3009   /* create the exit label */
3010   geniCodeLabel (exitLabel);
3011
3012   return result;
3013 }
3014
3015 /*-----------------------------------------------------------------*/
3016 /* geniCodeAssign - generate code for assignment                   */
3017 /*-----------------------------------------------------------------*/
3018 operand *
3019 geniCodeAssign (operand * left, operand * right, int nosupdate)
3020 {
3021   iCode *ic;
3022   sym_link *ltype = operandType (left);
3023   sym_link *rtype = operandType (right);
3024
3025   if (!left->isaddr && !IS_ITEMP (left))
3026     {
3027       werror (E_LVALUE_REQUIRED, "assignment");
3028       return left;
3029     }
3030
3031   /* left is integral type and right is literal then
3032      check if the literal value is within bounds */
3033   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3034     {
3035       checkConstantRange(ltype, 
3036                          OP_VALUE(right), "= operation", 0);
3037     }
3038
3039   /* if the left & right type don't exactly match */
3040   /* if pointer set then make sure the check is
3041      done with the type & not the pointer */
3042   /* then cast rights type to left */
3043
3044   /* first check the type for pointer assignement */
3045   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3046       compareType (ltype, rtype) <= 0)
3047     {
3048       if (compareType (ltype->next, rtype) < 0)
3049         right = geniCodeCast (ltype->next, right, TRUE);
3050     }
3051   else if (compareType (ltype, rtype) < 0)
3052     right = geniCodeCast (ltype, right, TRUE);
3053
3054   /* If left is a true symbol & ! volatile
3055      create an assignment to temporary for
3056      the right & then assign this temporary
3057      to the symbol. This is SSA (static single
3058      assignment). Isn't it simple and folks have
3059      published mountains of paper on it */
3060   if (IS_TRUE_SYMOP (left) &&
3061       !isOperandVolatile (left, FALSE) &&
3062       isOperandGlobal (left))
3063     {
3064       symbol *sym = NULL;
3065
3066       if (IS_TRUE_SYMOP (right))
3067         sym = OP_SYMBOL (right);
3068       ic = newiCode ('=', NULL, right);
3069       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3070       SPIL_LOC (right) = sym;
3071       ADDTOCHAIN (ic);
3072     }
3073
3074   ic = newiCode ('=', NULL, right);
3075   IC_RESULT (ic) = left;
3076   ADDTOCHAIN (ic);
3077
3078   /* if left isgptr flag is set then support
3079      routine will be required */
3080   if (left->isGptr)
3081     ic->supportRtn = 1;
3082
3083   ic->nosupdate = nosupdate;
3084   return left;
3085 }
3086
3087 /*-----------------------------------------------------------------*/
3088 /* geniCodeDummyRead - generate code for dummy read                */
3089 /*-----------------------------------------------------------------*/
3090 static void
3091 geniCodeDummyRead (operand * op)
3092 {
3093   iCode *ic;
3094   sym_link *type = operandType (op);
3095
3096   if (!IS_VOLATILE(type))
3097     return;
3098     
3099   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3100   ADDTOCHAIN (ic);
3101
3102   ic->nosupdate = 1;
3103 }
3104
3105 /*-----------------------------------------------------------------*/
3106 /* geniCodeSEParms - generate code for side effecting fcalls       */
3107 /*-----------------------------------------------------------------*/
3108 static void 
3109 geniCodeSEParms (ast * parms,int lvl)
3110 {
3111   if (!parms)
3112     return;
3113
3114   if (parms->type == EX_OP && parms->opval.op == PARAM)
3115     {
3116       geniCodeSEParms (parms->left,lvl);
3117       geniCodeSEParms (parms->right,lvl);
3118       return;
3119     }
3120
3121   /* hack don't like this but too lazy to think of
3122      something better */
3123   if (IS_ADDRESS_OF_OP (parms))
3124     parms->left->lvalue = 1;
3125
3126   if (IS_CAST_OP (parms) &&
3127       IS_PTR (parms->ftype) &&
3128       IS_ADDRESS_OF_OP (parms->right))
3129     parms->right->left->lvalue = 1;
3130
3131   parms->opval.oprnd = 
3132     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3133                 
3134   parms->type = EX_OPERAND;
3135   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3136                 SPEC_ARGREG(parms->ftype);
3137 }
3138
3139 /*-----------------------------------------------------------------*/
3140 /* geniCodeParms - generates parameters                            */
3141 /*-----------------------------------------------------------------*/
3142 value *
3143 geniCodeParms (ast * parms, value *argVals, int *stack, 
3144                sym_link * ftype, int lvl)
3145 {
3146   iCode *ic;
3147   operand *pval;
3148
3149   if (!parms)
3150     return argVals;
3151
3152   if (argVals==NULL) {
3153     // first argument
3154     argVals = FUNC_ARGS (ftype);
3155   }
3156
3157   /* if this is a param node then do the left & right */
3158   if (parms->type == EX_OP && parms->opval.op == PARAM)
3159     {
3160       argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3161       argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3162       return argVals;
3163     }
3164
3165   /* get the parameter value */
3166   if (parms->type == EX_OPERAND)
3167     pval = parms->opval.oprnd;
3168   else
3169     {
3170       /* maybe this else should go away ?? */
3171       /* hack don't like this but too lazy to think of
3172          something better */
3173       if (IS_ADDRESS_OF_OP (parms))
3174         parms->left->lvalue = 1;
3175
3176       if (IS_CAST_OP (parms) &&
3177           IS_PTR (parms->ftype) &&
3178           IS_ADDRESS_OF_OP (parms->right))
3179         parms->right->left->lvalue = 1;
3180
3181       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3182     }
3183
3184   /* if register parm then make it a send */
3185   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3186       IFFUNC_ISBUILTIN(ftype))
3187     {
3188       ic = newiCode (SEND, pval, NULL);
3189       ic->argreg = SPEC_ARGREG(parms->etype);
3190       ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3191       ADDTOCHAIN (ic);
3192     }
3193   else
3194     {
3195       /* now decide whether to push or assign */
3196       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3197         {
3198
3199           /* assign */
3200           operand *top = operandFromSymbol (argVals->sym);
3201           /* clear useDef and other bitVectors */
3202           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3203           geniCodeAssign (top, pval, 1);
3204         }
3205       else
3206         {
3207           sym_link *p = operandType (pval);
3208           /* push */
3209           ic = newiCode (IPUSH, pval, NULL);
3210           ic->parmPush = 1;
3211           /* update the stack adjustment */
3212           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3213           ADDTOCHAIN (ic);
3214         }
3215     }
3216
3217   argVals=argVals->next;
3218   return argVals;
3219 }
3220
3221 /*-----------------------------------------------------------------*/
3222 /* geniCodeCall - generates temp code for calling                  */
3223 /*-----------------------------------------------------------------*/
3224 operand *
3225 geniCodeCall (operand * left, ast * parms,int lvl)
3226 {
3227   iCode *ic;
3228   operand *result;
3229   sym_link *type, *etype;
3230   sym_link *ftype;
3231   int stack = 0;
3232
3233   if (!IS_FUNC(OP_SYMBOL(left)->type) && 
3234       !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3235     werror (E_FUNCTION_EXPECTED);
3236     return operandFromValue(valueFromLit(0));
3237   }
3238
3239   /* take care of parameters with side-effecting
3240      function calls in them, this is required to take care
3241      of overlaying function parameters */
3242   geniCodeSEParms (parms,lvl);
3243
3244   ftype = operandType (left);
3245   if (IS_CODEPTR (ftype))
3246     ftype = ftype->next;
3247     
3248   /* first the parameters */
3249   geniCodeParms (parms, NULL, &stack, ftype, lvl);
3250
3251   /* now call : if symbol then pcall */
3252   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3253     ic = newiCode (PCALL, left, NULL);
3254   } else {
3255     ic = newiCode (CALL, left, NULL);
3256   }
3257
3258   type = copyLinkChain (ftype->next);
3259   etype = getSpec (type);
3260   SPEC_EXTR (etype) = 0;
3261   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3262
3263   ADDTOCHAIN (ic);
3264
3265   /* stack adjustment after call */
3266   ic->parmBytes = stack;
3267
3268   return result;
3269 }
3270
3271 /*-----------------------------------------------------------------*/
3272 /* geniCodeReceive - generate intermediate code for "receive"      */
3273 /*-----------------------------------------------------------------*/
3274 static void 
3275 geniCodeReceive (value * args)
3276 {
3277   /* for all arguments that are passed in registers */
3278   while (args)
3279     {
3280       int first = 1;
3281       if (IS_REGPARM (args->etype))
3282         {
3283           operand *opr = operandFromValue (args);
3284           operand *opl;
3285           symbol *sym = OP_SYMBOL (opr);
3286           iCode *ic;
3287
3288           /* we will use it after all optimizations
3289              and before liveRange calculation */
3290           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3291             {
3292
3293               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3294                   options.stackAuto == 0 &&
3295                   (!(options.model == MODEL_FLAT24)) )
3296                 {
3297                 }
3298               else
3299                 {
3300                   opl = newiTempOperand (args->type, 0);
3301                   sym->reqv = opl;
3302                   sym->reqv->key = sym->key;
3303                   OP_SYMBOL (sym->reqv)->key = sym->key;
3304                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3305                   OP_SYMBOL (sym->reqv)->islocal = 0;
3306                   SPIL_LOC (sym->reqv) = sym;
3307                 }
3308             }
3309
3310           ic = newiCode (RECEIVE, NULL, NULL);    
3311           ic->argreg = SPEC_ARGREG(args->etype);
3312           if (first) {
3313               currFunc->recvSize = getSize (sym->type);
3314               first = 0;
3315           }
3316           IC_RESULT (ic) = opr;
3317           ADDTOCHAIN (ic);
3318         }
3319
3320       args = args->next;
3321     }
3322 }
3323
3324 /*-----------------------------------------------------------------*/
3325 /* geniCodeFunctionBody - create the function body                 */
3326 /*-----------------------------------------------------------------*/
3327 void 
3328 geniCodeFunctionBody (ast * tree,int lvl)
3329 {
3330   iCode *ic;
3331   operand *func;
3332   sym_link *fetype;
3333   int savelineno;
3334
3335   /* reset the auto generation */
3336   /* numbers */
3337   iTempNum = 0;
3338   iTempLblNum = 0;
3339   operandKey = 0;
3340   iCodeKey = 0;
3341   func = ast2iCode (tree->left,lvl+1);
3342   fetype = getSpec (operandType (func));
3343
3344   savelineno = lineno;
3345   lineno = OP_SYMBOL (func)->lineDef;
3346   /* create an entry label */
3347   geniCodeLabel (entryLabel);
3348   lineno = savelineno;
3349
3350   /* create a proc icode */
3351   ic = newiCode (FUNCTION, func, NULL);
3352   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3353
3354   ADDTOCHAIN (ic);
3355
3356   /* for all parameters that are passed
3357      on registers add a "receive" */
3358   geniCodeReceive (tree->values.args);
3359
3360   /* generate code for the body */
3361   ast2iCode (tree->right,lvl+1);
3362
3363   /* create a label for return */
3364   geniCodeLabel (returnLabel);
3365
3366   /* now generate the end proc */
3367   ic = newiCode (ENDFUNCTION, func, NULL);
3368   ADDTOCHAIN (ic);
3369   return;
3370 }
3371
3372 /*-----------------------------------------------------------------*/
3373 /* geniCodeReturn - gen icode for 'return' statement               */
3374 /*-----------------------------------------------------------------*/
3375 void 
3376 geniCodeReturn (operand * op)
3377 {
3378   iCode *ic;
3379
3380   /* if the operand is present force an rvalue */
3381   if (op)
3382     op = geniCodeRValue (op, FALSE);
3383
3384   ic = newiCode (RETURN, op, NULL);
3385   ADDTOCHAIN (ic);
3386 }
3387
3388 /*-----------------------------------------------------------------*/
3389 /* geniCodeIfx - generates code for extended if statement          */
3390 /*-----------------------------------------------------------------*/
3391 void 
3392 geniCodeIfx (ast * tree,int lvl)
3393 {
3394   iCode *ic;
3395   operand *condition = ast2iCode (tree->left,lvl+1);
3396   sym_link *cetype;
3397
3398   /* if condition is null then exit */
3399   if (!condition)
3400     goto exit;
3401   else
3402     condition = geniCodeRValue (condition, FALSE);
3403
3404   cetype = getSpec (operandType (condition));
3405   /* if the condition is a literal */
3406   if (IS_LITERAL (cetype))
3407     {
3408       if (floatFromVal (condition->operand.valOperand))
3409         {
3410           if (tree->trueLabel)
3411             geniCodeGoto (tree->trueLabel);
3412           else
3413             assert (0);
3414         }
3415       else
3416         {
3417           if (tree->falseLabel)
3418             geniCodeGoto (tree->falseLabel);
3419           else
3420             assert (0);
3421         }
3422       goto exit;
3423     }
3424
3425   if (tree->trueLabel)
3426     {
3427       ic = newiCodeCondition (condition,
3428                               tree->trueLabel,
3429                               NULL);
3430       ADDTOCHAIN (ic);
3431
3432       if (tree->falseLabel)
3433         geniCodeGoto (tree->falseLabel);
3434     }
3435   else
3436     {
3437       ic = newiCodeCondition (condition,
3438                               NULL,
3439                               tree->falseLabel);
3440       ADDTOCHAIN (ic);
3441     }
3442
3443 exit:
3444   ast2iCode (tree->right,lvl+1);
3445 }
3446
3447 /*-----------------------------------------------------------------*/
3448 /* geniCodeJumpTable - tries to create a jump table for switch     */
3449 /*-----------------------------------------------------------------*/
3450 int 
3451 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3452 {
3453   int min = 0, max = 0, t, cnt = 0;
3454   value *vch;
3455   iCode *ic;
3456   operand *boundary;
3457   symbol *falseLabel;
3458   set *labels = NULL;
3459   int needRangeCheck = !optimize.noJTabBoundary
3460                        || tree->values.switchVals.swDefault;
3461
3462   if (!tree || !caseVals)
3463     return 0;
3464
3465   /* the criteria for creating a jump table is */
3466   /* all integer numbers between the maximum & minimum must */
3467   /* be present , the maximum value should not exceed 255 */
3468   min = max = (int) floatFromVal (vch = caseVals);
3469   SNPRINTF (buffer, sizeof(buffer), 
3470             "_case_%d_%d",
3471            tree->values.switchVals.swNum,
3472            min);
3473   addSet (&labels, newiTempLabel (buffer));
3474
3475   /* if there is only one case value then no need */
3476   if (!(vch = vch->next))
3477     return 0;
3478
3479   while (vch)
3480     {
3481       if (((t = (int) floatFromVal (vch)) - max) != 1)
3482         return 0;
3483       SNPRINTF (buffer, sizeof(buffer), 
3484                 "_case_%d_%d",
3485                tree->values.switchVals.swNum,
3486                t);
3487       addSet (&labels, newiTempLabel (buffer));
3488       max = t;
3489       cnt++;
3490       vch = vch->next;
3491     }
3492
3493   /* if the number of case statements <= 2 then */
3494   /* it is not economical to create the jump table */
3495   /* since two compares are needed for boundary conditions */
3496   if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3497     return 0;
3498
3499   if (tree->values.switchVals.swDefault)
3500     {
3501         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3502     }
3503   else
3504     {
3505         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3506     }
3507     
3508
3509   falseLabel = newiTempLabel (buffer);
3510
3511   /* so we can create a jumptable */
3512   /* first we rule out the boundary conditions */
3513   /* if only optimization says so */
3514   if (needRangeCheck)
3515     {
3516       sym_link *cetype = getSpec (operandType (cond));
3517       /* no need to check the lower bound if
3518          the condition is unsigned & minimum value is zero */
3519       if (!(min == 0 && IS_UNSIGNED (cetype)))
3520         {
3521           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3522           ic = newiCodeCondition (boundary, falseLabel, NULL);
3523           ADDTOCHAIN (ic);
3524         }
3525
3526       /* now for upper bounds */
3527       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3528       ic = newiCodeCondition (boundary, falseLabel, NULL);
3529       ADDTOCHAIN (ic);
3530     }
3531
3532   /* if the min is not zero then we no make it zero */
3533   if (min)
3534     {
3535       cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3536       if (!IS_LITERAL(getSpec(operandType(cond))))
3537         setOperandType (cond, UCHARTYPE);
3538     }
3539
3540   /* now create the jumptable */
3541   ic = newiCode (JUMPTABLE, NULL, NULL);
3542   IC_JTCOND (ic) = cond;
3543   IC_JTLABELS (ic) = labels;
3544   ADDTOCHAIN (ic);
3545   return 1;
3546 }
3547
3548 /*-----------------------------------------------------------------*/
3549 /* geniCodeSwitch - changes a switch to a if statement             */
3550 /*-----------------------------------------------------------------*/
3551 void
3552 geniCodeSwitch (ast * tree,int lvl)
3553 {
3554   iCode *ic;
3555   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3556   value *caseVals = tree->values.switchVals.swVals;
3557   symbol *trueLabel, *falseLabel;
3558       
3559   /* If the condition is a literal, then just jump to the */
3560   /* appropriate case label. */
3561   if (IS_LITERAL(getSpec(operandType(cond))))
3562     {
3563       int switchVal, caseVal;
3564       
3565       switchVal = (int) floatFromVal (cond->operand.valOperand);
3566       while (caseVals)
3567         {
3568           caseVal = (int) floatFromVal (caseVals);
3569           if (caseVal == switchVal)
3570             {
3571               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3572                         tree->values.switchVals.swNum, caseVal);
3573               trueLabel = newiTempLabel (buffer);
3574               geniCodeGoto (trueLabel);
3575               goto jumpTable;
3576             }
3577           caseVals = caseVals->next;
3578         }
3579       goto defaultOrBreak;
3580     }
3581
3582   /* if we can make this a jump table */
3583   if (geniCodeJumpTable (cond, caseVals, tree))
3584     goto jumpTable;             /* no need for the comparison */
3585
3586   /* for the cases defined do */
3587   while (caseVals)
3588     {
3589
3590       operand *compare = geniCodeLogic (cond,
3591                                         operandFromValue (caseVals),
3592                                         EQ_OP);
3593
3594       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3595                tree->values.switchVals.swNum,
3596                (int) floatFromVal (caseVals));
3597       trueLabel = newiTempLabel (buffer);
3598
3599       ic = newiCodeCondition (compare, trueLabel, NULL);
3600       ADDTOCHAIN (ic);
3601       caseVals = caseVals->next;
3602     }
3603
3604
3605 defaultOrBreak:
3606   /* if default is present then goto break else break */
3607   if (tree->values.switchVals.swDefault)
3608     {
3609         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3610     }
3611   else
3612     {
3613         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3614     }
3615
3616   falseLabel = newiTempLabel (buffer);
3617   geniCodeGoto (falseLabel);
3618
3619 jumpTable:
3620   ast2iCode (tree->right,lvl+1);
3621 }
3622
3623 /*-----------------------------------------------------------------*/
3624 /* geniCodeInline - intermediate code for inline assembler         */
3625 /*-----------------------------------------------------------------*/
3626 static void 
3627 geniCodeInline (ast * tree)
3628 {
3629   iCode *ic;
3630
3631   ic = newiCode (INLINEASM, NULL, NULL);
3632   IC_INLINE (ic) = tree->values.inlineasm;
3633   ADDTOCHAIN (ic);
3634 }
3635
3636 /*-----------------------------------------------------------------*/
3637 /* geniCodeArrayInit - intermediate code for array initializer     */
3638 /*-----------------------------------------------------------------*/
3639 static void
3640 geniCodeArrayInit (ast * tree, operand *array)
3641 {
3642   iCode *ic;
3643
3644   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3645     ic = newiCode (ARRAYINIT, array, NULL);
3646     IC_ARRAYILIST (ic) = tree->values.constlist;
3647   } else {
3648     operand *left=newOperand(), *right=newOperand();
3649     left->type=right->type=SYMBOL;
3650     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3651     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3652     ic = newiCode (ARRAYINIT, left, right);
3653   }
3654   ADDTOCHAIN (ic);
3655 }
3656         
3657 /*-----------------------------------------------------------------*/
3658 /* geniCodeCritical - intermediate code for a critical statement   */
3659 /*-----------------------------------------------------------------*/
3660 static void 
3661 geniCodeCritical (ast *tree, int lvl)
3662 {
3663   iCode *ic;
3664   operand *op = NULL;
3665
3666   /* If op is NULL, the original interrupt state will saved on */
3667   /* the stack. Otherwise, it will be saved in op. */
3668   
3669   /* Generate a save of the current interrupt state & disabled */
3670   ic = newiCode (CRITICAL, NULL, NULL);
3671   IC_RESULT (ic) = op;
3672   ADDTOCHAIN (ic);
3673   
3674   /* Generate the critical code sequence */
3675   if (tree->left && tree->left->type == EX_VALUE)
3676     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3677   else
3678     ast2iCode (tree->left,lvl+1);
3679   
3680   /* Generate a restore of the original interrupt state */
3681   ic = newiCode (ENDCRITICAL, NULL, op);
3682   ADDTOCHAIN (ic);
3683 }
3684
3685 /*-----------------------------------------------------------------*/
3686 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3687 /* particular case. Ie : assigning or dereferencing array or ptr   */
3688 /*-----------------------------------------------------------------*/
3689 set * lvaluereqSet = NULL;
3690 typedef struct lvalItem
3691   {
3692     int req;
3693     int lvl;
3694   }
3695 lvalItem;
3696
3697 /*-----------------------------------------------------------------*/
3698 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3699 /*-----------------------------------------------------------------*/
3700 void addLvaluereq(int lvl)
3701 {
3702   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3703   lpItem->req=1;
3704   lpItem->lvl=lvl;
3705   addSetHead(&lvaluereqSet,lpItem);
3706
3707 }
3708 /*-----------------------------------------------------------------*/
3709 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3710 /*-----------------------------------------------------------------*/
3711 void delLvaluereq()
3712 {
3713   lvalItem * lpItem;
3714   lpItem = getSet(&lvaluereqSet);
3715   if(lpItem) Safe_free(lpItem);
3716 }
3717 /*-----------------------------------------------------------------*/
3718 /* clearLvaluereq - clear lvalreq flag                             */
3719 /*-----------------------------------------------------------------*/
3720 void clearLvaluereq()
3721 {
3722   lvalItem * lpItem;
3723   lpItem = peekSet(lvaluereqSet);
3724   if(lpItem) lpItem->req = 0;
3725 }
3726 /*-----------------------------------------------------------------*/
3727 /* getLvaluereq - get the last lvalreq level                       */
3728 /*-----------------------------------------------------------------*/
3729 int getLvaluereqLvl()
3730 {
3731   lvalItem * lpItem;
3732   lpItem = peekSet(lvaluereqSet);
3733   if(lpItem) return lpItem->lvl;
3734   return 0;
3735 }
3736 /*-----------------------------------------------------------------*/
3737 /* isLvaluereq - is lvalreq valid for this level ?                 */
3738 /*-----------------------------------------------------------------*/
3739 int isLvaluereq(int lvl)
3740 {
3741   lvalItem * lpItem;
3742   lpItem = peekSet(lvaluereqSet);
3743   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3744   return 0;
3745 }
3746
3747 /*-----------------------------------------------------------------*/
3748 /* ast2iCode - creates an icodeList from an ast                    */
3749 /*-----------------------------------------------------------------*/
3750 operand *
3751 ast2iCode (ast * tree,int lvl)
3752 {
3753   operand *left = NULL;
3754   operand *right = NULL;
3755   if (!tree)
3756     return NULL;
3757
3758   /* set the global variables for filename & line number */
3759   if (tree->filename)
3760     filename = tree->filename;
3761   if (tree->lineno)
3762     lineno = tree->lineno;
3763   if (tree->block)
3764     block = tree->block;
3765   if (tree->level)
3766     scopeLevel = tree->level;
3767   if (tree->seqPoint)
3768     seqPoint = tree->seqPoint;
3769
3770   if (tree->type == EX_VALUE)
3771     return operandFromValue (tree->opval.val);
3772
3773   if (tree->type == EX_LINK)
3774     return operandFromLink (tree->opval.lnk);
3775
3776   /* if we find a nullop */
3777   if (tree->type == EX_OP &&
3778      (tree->opval.op == NULLOP ||
3779      tree->opval.op == BLOCK))
3780     {
3781       if (tree->left && tree->left->type == EX_VALUE)
3782         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3783       else
3784         ast2iCode (tree->left,lvl+1);
3785       if (tree->right && tree->right->type == EX_VALUE)
3786         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3787       else
3788         ast2iCode (tree->right,lvl+1);
3789       return NULL;
3790     }
3791
3792   /* special cases for not evaluating */
3793   if (tree->opval.op != ':' &&
3794       tree->opval.op != '?' &&
3795       tree->opval.op != CALL &&
3796       tree->opval.op != IFX &&
3797       tree->opval.op != AND_OP &&
3798       tree->opval.op != OR_OP &&
3799       tree->opval.op != LABEL &&
3800       tree->opval.op != GOTO &&
3801       tree->opval.op != SWITCH &&
3802       tree->opval.op != FUNCTION &&
3803       tree->opval.op != INLINEASM &&
3804       tree->opval.op != CRITICAL)
3805     {
3806
3807         if (IS_ASSIGN_OP (tree->opval.op) ||
3808            IS_DEREF_OP (tree) ||
3809            (tree->opval.op == '&' && !tree->right) ||
3810            tree->opval.op == PTR_OP)
3811           {
3812             addLvaluereq(lvl);
3813             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3814                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3815               clearLvaluereq();
3816
3817             left = operandFromAst (tree->left,lvl);
3818             delLvaluereq();
3819             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3820               left = geniCodeRValue (left, TRUE);
3821           }
3822         else
3823           {
3824             left = operandFromAst (tree->left,lvl);
3825           }
3826         if (tree->opval.op == INC_OP ||
3827             tree->opval.op == DEC_OP)
3828           {
3829             addLvaluereq(lvl);
3830             right = operandFromAst (tree->right,lvl);
3831             delLvaluereq();
3832           }
3833         else
3834           {
3835             right = operandFromAst (tree->right,lvl);
3836           }
3837       }
3838
3839   /* now depending on the type of operand */
3840   /* this will be a biggy                 */
3841   switch (tree->opval.op)
3842     {
3843
3844     case '[':                   /* array operation */
3845       {
3846         //sym_link *ltype = operandType (left);
3847         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3848         left = geniCodeRValue (left, FALSE);
3849         right = geniCodeRValue (right, TRUE);
3850       }
3851
3852       return geniCodeArray (left, right,lvl);
3853
3854     case '.':                   /* structure dereference */
3855       if (IS_PTR (operandType (left)))
3856         left = geniCodeRValue (left, TRUE);
3857       else
3858         left = geniCodeRValue (left, FALSE);
3859
3860       return geniCodeStruct (left, right, tree->lvalue);
3861
3862     case PTR_OP:                /* structure pointer dereference */
3863       {
3864         sym_link *pType;
3865         pType = operandType (left);
3866         left = geniCodeRValue (left, TRUE);
3867
3868         setOClass (pType, getSpec (operandType (left)));
3869       }
3870
3871       return geniCodeStruct (left, right, tree->lvalue);
3872
3873     case INC_OP:                /* increment operator */
3874       if (left)
3875         return geniCodePostInc (left);
3876       else
3877         return geniCodePreInc (right, tree->lvalue);
3878
3879     case DEC_OP:                /* decrement operator */
3880       if (left)
3881         return geniCodePostDec (left);
3882       else
3883         return geniCodePreDec (right, tree->lvalue);
3884
3885     case '&':                   /* bitwise and or address of operator */
3886       if (right)
3887         {                       /* this is a bitwise operator   */
3888           left = geniCodeRValue (left, FALSE);
3889           right = geniCodeRValue (right, FALSE);
3890           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3891         }
3892       else
3893         return geniCodeAddressOf (left);
3894
3895     case '|':                   /* bitwise or & xor */
3896     case '^':
3897       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3898                               geniCodeRValue (right, FALSE),
3899                               tree->opval.op,
3900                               tree->ftype);
3901
3902     case '/':
3903       return geniCodeDivision (geniCodeRValue (left, FALSE),
3904                                geniCodeRValue (right, FALSE),
3905                                getResultTypeFromType (tree->ftype));
3906
3907     case '%':
3908       return geniCodeModulus (geniCodeRValue (left, FALSE),
3909                               geniCodeRValue (right, FALSE),
3910                               getResultTypeFromType (tree->ftype));
3911     case '*':
3912       if (right)
3913         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3914                                  geniCodeRValue (right, FALSE),
3915                                  getResultTypeFromType (tree->ftype));
3916       else
3917         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3918
3919     case '-':
3920       if (right)
3921         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3922                                  geniCodeRValue (right, FALSE),
3923                                  getResultTypeFromType (tree->ftype));
3924       else
3925         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3926
3927     case '+':
3928       if (right)
3929         return geniCodeAdd (geniCodeRValue (left, FALSE),
3930                             geniCodeRValue (right, FALSE),
3931                             getResultTypeFromType (tree->ftype),
3932                             lvl);
3933       else
3934         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3935
3936     case LEFT_OP:
3937       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3938                                 geniCodeRValue (right, FALSE),
3939                                 getResultTypeFromType (tree->ftype));
3940
3941     case RIGHT_OP:
3942       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3943                                  geniCodeRValue (right, FALSE));
3944     case CAST:
3945 #if 0 // this indeed needs a second thought
3946       {
3947         operand *op;
3948
3949         // let's keep this simple: get the rvalue we need
3950         op=geniCodeRValue (right, FALSE);
3951         // now cast it to whatever we want
3952         op=geniCodeCast (operandType(left), op, FALSE);
3953         // if this is going to be used as an lvalue, make it so
3954         if (tree->lvalue) {
3955           op->isaddr=1;
3956         }
3957         return op;
3958       }
3959 #else // bug #604575, is it a bug ????
3960       return geniCodeCast (operandType (left),
3961                            geniCodeRValue (right, FALSE), FALSE);
3962 #endif
3963
3964     case '~':
3965     case RRC:
3966     case RLC:
3967     case SWAP:
3968       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3969
3970     case '!':
3971     case GETHBIT:
3972       {
3973         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3974         setOperandType (op, UCHARTYPE);
3975         return op;
3976       }
3977     case AND_OP:
3978     case OR_OP:
3979       return geniCodeLogicAndOr (tree, lvl);
3980     case '>':
3981     case '<':
3982     case LE_OP:
3983     case GE_OP:
3984     case EQ_OP:
3985     case NE_OP:
3986       /* different compilers (even different gccs) evaluate
3987          the two calls in a different order. to get the same
3988          result on all machines we've to specify a clear sequence.
3989       return geniCodeLogic (geniCodeRValue (left, FALSE),
3990                             geniCodeRValue (right, FALSE),
3991                             tree->opval.op);
3992       */
3993       {
3994         operand *leftOp, *rightOp;
3995
3996         leftOp  = geniCodeRValue (left , FALSE);
3997         rightOp = geniCodeRValue (right, FALSE);
3998
3999         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4000       }
4001     case '?':
4002       return geniCodeConditional (tree,lvl);
4003
4004     case SIZEOF:
4005       return operandFromLit (getSize (tree->right->ftype));
4006
4007     case '=':
4008       {
4009         sym_link *rtype = operandType (right);
4010         sym_link *ltype = operandType (left);
4011         if (IS_PTR (rtype) && IS_ITEMP (right)
4012             && right->isaddr && compareType (rtype->next, ltype) == 1)
4013           right = geniCodeRValue (right, TRUE);
4014         else
4015           right = geniCodeRValue (right, FALSE);
4016
4017         geniCodeAssign (left, right, 0);
4018         return right;
4019       }
4020     case MUL_ASSIGN:
4021       return
4022         geniCodeAssign (left,
4023                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4024                                                   FALSE),
4025                                   geniCodeRValue (right, FALSE), FALSE),
4026                                   getResultTypeFromType (tree->ftype));
4027
4028     case DIV_ASSIGN:
4029       return
4030         geniCodeAssign (left,
4031                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4032                                                   FALSE),
4033                                   geniCodeRValue (right, FALSE),
4034                                   getResultTypeFromType (tree->ftype)),
4035                         0);
4036     case MOD_ASSIGN:
4037       return
4038         geniCodeAssign (left,
4039                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4040                                                   FALSE),
4041                                   geniCodeRValue (right, FALSE),
4042                                   getResultTypeFromType (tree->ftype)),
4043                         0);
4044     case ADD_ASSIGN:
4045       {
4046         sym_link *rtype = operandType (right);
4047         sym_link *ltype = operandType (left);
4048         if (IS_PTR (rtype) && IS_ITEMP (right)
4049             && right->isaddr && compareType (rtype->next, ltype) == 1)
4050           right = geniCodeRValue (right, TRUE);
4051         else
4052           right = geniCodeRValue (right, FALSE);
4053
4054
4055         return geniCodeAssign (left,
4056                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4057                                                   FALSE),
4058                                   right,
4059                                   getResultTypeFromType (tree->ftype),
4060                                   lvl),
4061                                0);
4062       }
4063     case SUB_ASSIGN:
4064       {
4065         sym_link *rtype = operandType (right);
4066         sym_link *ltype = operandType (left);
4067         if (IS_PTR (rtype) && IS_ITEMP (right)
4068             && right->isaddr && compareType (rtype->next, ltype) == 1)
4069           {
4070             right = geniCodeRValue (right, TRUE);
4071           }
4072         else
4073           {
4074             right = geniCodeRValue (right, FALSE);
4075           }
4076         return
4077           geniCodeAssign (left,
4078                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4079                                                   FALSE),
4080                                   right,
4081                                   getResultTypeFromType (tree->ftype)),
4082                           0);
4083       }
4084     case LEFT_ASSIGN:
4085       return
4086         geniCodeAssign (left,
4087                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4088                                                    ,FALSE),
4089                                    geniCodeRValue (right, FALSE),
4090                                    getResultTypeFromType (tree->ftype)),
4091                         0);
4092     case RIGHT_ASSIGN:
4093       return
4094         geniCodeAssign (left,
4095                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4096                                                    ,FALSE),
4097                                    geniCodeRValue (right, FALSE)), 0);
4098     case AND_ASSIGN:
4099       return
4100         geniCodeAssign (left,
4101                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4102                                                   FALSE),
4103                                   geniCodeRValue (right, FALSE),
4104                                   BITWISEAND,
4105                                   operandType (left)), 0);
4106     case XOR_ASSIGN:
4107       return
4108         geniCodeAssign (left,
4109                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4110                                                   FALSE),
4111                                   geniCodeRValue (right, FALSE),
4112                                   '^',
4113                                   operandType (left)), 0);
4114     case OR_ASSIGN:
4115       return
4116         geniCodeAssign (left,
4117                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4118                                                    ,FALSE),
4119                                    geniCodeRValue (right, FALSE),
4120                                    '|',
4121                                    operandType (left)), 0);
4122     case ',':
4123       return geniCodeRValue (right, FALSE);
4124
4125     case CALL:
4126       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4127                            tree->right,lvl);
4128     case LABEL:
4129       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4130       return ast2iCode (tree->right,lvl+1);
4131
4132     case GOTO:
4133       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4134       return ast2iCode (tree->right,lvl+1);
4135
4136     case FUNCTION:
4137       geniCodeFunctionBody (tree,lvl);
4138       return NULL;
4139
4140     case RETURN:
4141       geniCodeReturn (right);
4142       return NULL;
4143
4144     case IFX:
4145       geniCodeIfx (tree,lvl);
4146       return NULL;
4147
4148     case SWITCH:
4149       geniCodeSwitch (tree,lvl);
4150       return NULL;
4151
4152     case INLINEASM:
4153       geniCodeInline (tree);
4154       return NULL;
4155         
4156     case ARRAYINIT:
4157         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4158         return NULL;
4159     
4160     case CRITICAL:
4161         geniCodeCritical (tree, lvl);
4162     }
4163
4164   return NULL;
4165 }
4166
4167 /*-----------------------------------------------------------------*/
4168 /* reverseICChain - gets from the list and creates a linkedlist    */
4169 /*-----------------------------------------------------------------*/
4170 iCode *
4171 reverseiCChain ()
4172 {
4173   iCode *loop = NULL;
4174   iCode *prev = NULL;
4175
4176   while ((loop = getSet (&iCodeChain)))
4177     {
4178       loop->next = prev;
4179       if (prev)
4180         prev->prev = loop;
4181       prev = loop;
4182     }
4183
4184   return prev;
4185 }
4186
4187
4188 /*-----------------------------------------------------------------*/
4189 /* iCodeFromAst - given an ast will convert it to iCode            */
4190 /*-----------------------------------------------------------------*/
4191 iCode *
4192 iCodeFromAst (ast * tree)
4193 {
4194   returnLabel = newiTempLabel ("_return");
4195   entryLabel = newiTempLabel ("_entry");
4196   ast2iCode (tree,0);
4197   return reverseiCChain ();
4198 }
4199
4200 static const char *opTypeToStr(OPTYPE op)
4201 {
4202     switch(op)
4203     {
4204       case SYMBOL: return "symbol";
4205       case VALUE: return "value";
4206       case TYPE: return "type";
4207     }
4208     return "undefined type";    
4209 }
4210
4211
4212 operand *validateOpType(operand         *op, 
4213                         const char      *macro,
4214                         const char      *args,
4215                         OPTYPE          type,
4216                         const char      *file, 
4217                         unsigned        line)
4218 {    
4219     if (op && op->type == type)
4220     {
4221         return op;
4222     }
4223     fprintf(stderr, 
4224             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4225             " expected %s, got %s\n",
4226             macro, args, file, line, 
4227             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4228     exit(-1);
4229     return op; // never reached, makes compiler happy.
4230 }