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