fixed bug #467893
[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
28 /*-----------------------------------------------------------------*/
29 /* global variables       */
30
31 set *iCodeChain = NULL;
32 int iTempNum = 0;
33 int iTempLblNum = 0;
34 int operandKey = 0;
35 int iCodeKey = 0;
36 char *filename;
37 int lineno;
38 int block;
39 int scopeLevel;
40
41 symbol *returnLabel;            /* function return label */
42 symbol *entryLabel;             /* function entry  label */
43
44 #if defined(__BORLANDC__) || defined(_MSC_VER)
45 #define LONG_LONG __int64
46 #else
47 #define LONG_LONG long long
48 #endif
49
50 /*-----------------------------------------------------------------*/
51 /* forward definition of some functions */
52 operand *geniCodeDivision (operand *, operand *);
53 operand *geniCodeAssign (operand *, operand *, int);
54 operand *geniCodeArray (operand *, operand *,int);
55 operand *geniCodeArray2Ptr (operand *);
56 operand *geniCodeRValue (operand *, bool);
57 operand *geniCodeDerefPtr (operand *,int);
58 int isLvaluereq(int lvl);
59
60 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
61 /* forward definition of ic print functions */
62 PRINTFUNC (picGetValueAtAddr);
63 PRINTFUNC (picSetValueAtAddr);
64 PRINTFUNC (picAddrOf);
65 PRINTFUNC (picGeneric);
66 PRINTFUNC (picGenericOne);
67 PRINTFUNC (picCast);
68 PRINTFUNC (picAssign);
69 PRINTFUNC (picLabel);
70 PRINTFUNC (picGoto);
71 PRINTFUNC (picIfx);
72 PRINTFUNC (picJumpTable);
73 PRINTFUNC (picInline);
74 PRINTFUNC (picReceive);
75
76 iCodeTable codeTable[] =
77 {
78   {'!', "not", picGenericOne, NULL},
79   {'~', "~", picGenericOne, NULL},
80   {RRC, "rrc", picGenericOne, NULL},
81   {RLC, "rlc", picGenericOne, NULL},
82   {GETHBIT, "ghbit", picGenericOne, NULL},
83   {UNARYMINUS, "-", picGenericOne, NULL},
84   {IPUSH, "push", picGenericOne, NULL},
85   {IPOP, "pop", picGenericOne, NULL},
86   {CALL, "call", picGenericOne, NULL},
87   {PCALL, "pcall", picGenericOne, NULL},
88   {FUNCTION, "proc", picGenericOne, NULL},
89   {ENDFUNCTION, "eproc", picGenericOne, NULL},
90   {RETURN, "ret", picGenericOne, NULL},
91   {'+', "+", picGeneric, NULL},
92   {'-', "-", picGeneric, NULL},
93   {'*', "*", picGeneric, NULL},
94   {'/', "/", picGeneric, NULL},
95   {'%', "%", picGeneric, NULL},
96   {'>', ">", picGeneric, NULL},
97   {'<', "<", picGeneric, NULL},
98   {LE_OP, "<=", picGeneric, NULL},
99   {GE_OP, ">=", picGeneric, NULL},
100   {EQ_OP, "==", picGeneric, NULL},
101   {NE_OP, "!=", picGeneric, NULL},
102   {AND_OP, "&&", picGeneric, NULL},
103   {OR_OP, "||", picGeneric, NULL},
104   {'^', "^", picGeneric, NULL},
105   {'|', "|", picGeneric, NULL},
106   {BITWISEAND, "&", picGeneric, NULL},
107   {LEFT_OP, "<<", picGeneric, NULL},
108   {RIGHT_OP, ">>", picGeneric, NULL},
109   {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110   {ADDRESS_OF, "&", picAddrOf, NULL},
111   {CAST, "<>", picCast, NULL},
112   {'=', ":=", picAssign, NULL},
113   {LABEL, "", picLabel, NULL},
114   {GOTO, "", picGoto, NULL},
115   {JUMPTABLE, "jtab", picJumpTable, NULL},
116   {IFX, "if", picIfx, NULL},
117   {INLINEASM, "", picInline, NULL},
118   {RECEIVE, "recv", picReceive, NULL},
119   {SEND, "send", picGenericOne, NULL},
120   {ARRAYINIT, "arrayInit", picGenericOne, NULL},
121 };
122
123 /*-----------------------------------------------------------------*/
124 /* checkConstantRange: check a constant against the type           */
125 /*-----------------------------------------------------------------*/
126
127 /*   pedantic=0: allmost anything is allowed as long as the absolute
128        value is within the bit range of the type, and -1 is treated as
129        0xf..f for unsigned types (e.g. in assign)
130      pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
131      pedantic>1: "char c=200" is not allowed (evaluates to -56)
132 */
133
134 void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
135   LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype);
136   char message[132]="";
137   int warnings=0;
138   int negative=0;
139   long v=SPEC_CVAL(val->type).v_long;
140
141 #if 0
142   // this could be a good idea
143   if (options.pedantic)
144     pedantic=2;
145 #endif
146
147   if (SPEC_NOUN(ltype)==FLOAT) {
148     // anything will do
149     return;
150   }
151
152   if (!SPEC_USIGN(val->type) && v<0) {
153     negative=1;
154     if (SPEC_USIGN(ltype) && (pedantic>1)) {
155       warnings++;
156     }
157     v=-v;
158   }
159
160   // if very pedantic: "char c=200" is not allowed
161   if (pedantic>1 && !SPEC_USIGN(ltype)) {
162     max = max/2 + negative;
163   }
164
165   if (v >= max) {
166     warnings++;
167   }
168
169   if (warnings) {
170     sprintf (message, "for %s %s in %s", 
171              SPEC_USIGN(ltype) ? "unsigned" : "signed",
172              nounName(ltype), msg);
173     werror (W_CONST_RANGE, message);
174
175     if (pedantic>1)
176       fatalError++;
177   }
178 }
179
180 /*-----------------------------------------------------------------*/
181 /* operandName - returns the name of the operand                   */
182 /*-----------------------------------------------------------------*/
183 int 
184 printOperand (operand * op, FILE * file)
185 {
186   sym_link *opetype;
187   int pnl = 0;
188
189   if (!op)
190     return 1;
191
192   if (!file)
193     {
194       file = stdout;
195       pnl = 1;
196     }
197   switch (op->type)
198     {
199
200     case VALUE:
201       opetype = getSpec (operandType (op));
202       if (SPEC_NOUN (opetype) == V_FLOAT)
203         fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
204       else
205         fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
206       printTypeChain (operandType (op), file);
207       fprintf (file, "}");
208       break;
209
210     case SYMBOL:
211 #define REGA 1
212 #ifdef REGA
213       fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}",           /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
214                (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
215                op->key,
216                OP_LIVEFROM (op), OP_LIVETO (op),
217                OP_SYMBOL (op)->stack,
218                op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
219         );
220       {
221         fprintf (file, "{");
222         printTypeChain (operandType (op), file);
223         if (SPIL_LOC (op) && IS_ITEMP (op))
224           fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
225         fprintf (file, "}");
226
227       }
228
229       /* if assigned to registers */
230       if (OP_SYMBOL (op)->nRegs)
231         {
232           if (OP_SYMBOL (op)->isspilt)
233             {
234               if (!OP_SYMBOL (op)->remat)
235                 if (OP_SYMBOL (op)->usl.spillLoc)
236                   fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
237                                        OP_SYMBOL (op)->usl.spillLoc->rname :
238                                        OP_SYMBOL (op)->usl.spillLoc->name));
239                 else
240                   fprintf (file, "[err]");
241               else
242                 fprintf (file, "[remat]");
243             }
244           else
245             {
246               int i;
247               fprintf (file, "[");
248               for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
249                 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
250               fprintf (file, "]");
251             }
252         }
253 #else
254       fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
255                             OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
256       /* if assigned to registers */
257       if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
258         {
259           int i;
260           fprintf (file, "[");
261           for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
262             fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
263                                    OP_SYMBOL (op)->regs[i]->name :
264                                    "err"));
265           fprintf (file, "]");
266         }
267 #endif
268       break;
269
270     case TYPE:
271       fprintf (file, "(");
272       printTypeChain (op->operand.typeOperand, file);
273       fprintf (file, ")");
274       break;
275     }
276
277   if (pnl)
278     fprintf (file, "\n");
279   return 0;
280 }
281
282
283 /*-----------------------------------------------------------------*/
284 /*                    print functions                              */
285 /*-----------------------------------------------------------------*/
286 PRINTFUNC (picGetValueAtAddr)
287 {
288   fprintf (of, "\t");
289   printOperand (IC_RESULT (ic), of);
290   fprintf (of, " = ");
291   fprintf (of, "@[");
292   printOperand (IC_LEFT (ic), of);
293   fprintf (of, "]");
294
295   fprintf (of, "\n");
296 }
297
298 PRINTFUNC (picSetValueAtAddr)
299 {
300   fprintf (of, "\t");
301   fprintf (of, "*[");
302   printOperand (IC_LEFT (ic), of);
303   fprintf (of, "] = ");
304   printOperand (IC_RIGHT (ic), of);
305   fprintf (of, "\n");
306 }
307
308 PRINTFUNC (picAddrOf)
309 {
310   fprintf (of, "\t");
311   printOperand (IC_RESULT (ic), of);
312   if (IS_ITEMP (IC_LEFT (ic)))
313     fprintf (of, " = ");
314   else
315     fprintf (of, " = &[");
316   printOperand (IC_LEFT (ic), of);
317   if (IC_RIGHT (ic))
318     {
319       if (IS_ITEMP (IC_LEFT (ic)))
320         fprintf (of, " offsetAdd ");
321       else
322         fprintf (of, " , ");
323       printOperand (IC_RIGHT (ic), of);
324     }
325   if (IS_ITEMP (IC_LEFT (ic)))
326     fprintf (of, "\n");
327   else
328     fprintf (of, "]\n");
329 }
330
331 PRINTFUNC (picJumpTable)
332 {
333   symbol *sym;
334
335   fprintf (of, "\t");
336   fprintf (of, "%s\t", s);
337   printOperand (IC_JTCOND (ic), of);
338   fprintf (of, "\n");
339   for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
340        sym = setNextItem (IC_JTLABELS (ic)))
341     fprintf (of, "\t\t\t%s\n", sym->name);
342 }
343
344 PRINTFUNC (picGeneric)
345 {
346   fprintf (of, "\t");
347   printOperand (IC_RESULT (ic), of);
348   fprintf (of, " = ");
349   printOperand (IC_LEFT (ic), of);
350   fprintf (of, " %s ", s);
351   printOperand (IC_RIGHT (ic), of);
352   fprintf (of, "\n");
353 }
354
355 PRINTFUNC (picGenericOne)
356 {
357   fprintf (of, "\t");
358   if (IC_RESULT (ic))
359     {
360       printOperand (IC_RESULT (ic), of);
361       fprintf (of, " = ");
362     }
363
364   if (IC_LEFT (ic))
365     {
366       fprintf (of, "%s ", s);
367       printOperand (IC_LEFT (ic), of);
368     }
369
370   if (!IC_RESULT (ic) && !IC_LEFT (ic))
371     fprintf (of, s);
372
373   fprintf (of, "\n");
374 }
375
376 PRINTFUNC (picCast)
377 {
378   fprintf (of, "\t");
379   printOperand (IC_RESULT (ic), of);
380   fprintf (of, " = ");
381   printOperand (IC_LEFT (ic), of);
382   printOperand (IC_RIGHT (ic), of);
383   fprintf (of, "\n");
384 }
385
386
387 PRINTFUNC (picAssign)
388 {
389   fprintf (of, "\t");
390
391   if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
392     fprintf (of, "*(");
393
394   printOperand (IC_RESULT (ic), of);
395
396   if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
397     fprintf (of, ")");
398
399   fprintf (of, " %s ", s);
400   printOperand (IC_RIGHT (ic), of);
401
402   fprintf (of, "\n");
403 }
404
405 PRINTFUNC (picLabel)
406 {
407   fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
408 }
409
410 PRINTFUNC (picGoto)
411 {
412   fprintf (of, "\t");
413   fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
414 }
415
416 PRINTFUNC (picIfx)
417 {
418   fprintf (of, "\t");
419   fprintf (of, "if ");
420   printOperand (IC_COND (ic), of);
421
422   if (!IC_TRUE (ic))
423     fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
424   else
425     {
426       fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
427       if (IC_FALSE (ic))
428         fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
429     }
430 }
431
432 PRINTFUNC (picInline)
433 {
434   fprintf (of, "%s", IC_INLINE (ic));
435 }
436
437 PRINTFUNC (picReceive)
438 {
439   printOperand (IC_RESULT (ic), of);
440   fprintf (of, " = %s ", s);
441   printOperand (IC_LEFT (ic), of);
442   fprintf (of, "\n");
443 }
444
445 /*-----------------------------------------------------------------*/
446 /* piCode - prints one iCode                                       */
447 /*-----------------------------------------------------------------*/
448 int 
449 piCode (void *item, FILE * of)
450 {
451   iCode *ic = item;
452   iCodeTable *icTab;
453
454   if (!of)
455     of = stdout;
456
457   icTab = getTableEntry (ic->op);
458   fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
459            ic->filename, ic->lineno,
460            ic->seq, ic->key, ic->depth, ic->supportRtn);
461   icTab->iCodePrint (of, ic, icTab->printName);
462   return 1;
463 }
464
465 void PICC(iCode *ic)
466 {
467         printiCChain(ic,stdout);
468 }
469 /*-----------------------------------------------------------------*/
470 /* printiCChain - prints intermediate code for humans              */
471 /*-----------------------------------------------------------------*/
472 void 
473 printiCChain (iCode * icChain, FILE * of)
474 {
475   iCode *loop;
476   iCodeTable *icTab;
477
478   if (!of)
479     of = stdout;
480   for (loop = icChain; loop; loop = loop->next)
481     {
482       if ((icTab = getTableEntry (loop->op)))
483         {
484           fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
485                    loop->filename, loop->lineno,
486                    loop->seq, loop->key, loop->depth, loop->supportRtn);
487
488           icTab->iCodePrint (of, loop, icTab->printName);
489         }
490     }
491 }
492
493
494 /*-----------------------------------------------------------------*/
495 /* newOperand - allocate, init & return a new iCode                */
496 /*-----------------------------------------------------------------*/
497 operand *
498 newOperand ()
499 {
500   operand *op;
501
502   op = Safe_alloc ( sizeof (operand));
503
504   op->key = 0;
505   return op;
506 }
507
508 /*-----------------------------------------------------------------*/
509 /* newiCode - create and return a new iCode entry initialised      */
510 /*-----------------------------------------------------------------*/
511 iCode *
512 newiCode (int op, operand * left, operand * right)
513 {
514   iCode *ic;
515
516   ic = Safe_alloc ( sizeof (iCode));
517
518   ic->lineno = lineno;
519   ic->filename = filename;
520   ic->block = block;
521   ic->level = scopeLevel;
522   ic->op = op;
523   ic->key = iCodeKey++;
524   IC_LEFT (ic) = left;
525   IC_RIGHT (ic) = right;
526
527   return ic;
528 }
529
530 /*-----------------------------------------------------------------*/
531 /* newiCode for conditional statements                             */
532 /*-----------------------------------------------------------------*/
533 iCode *
534 newiCodeCondition (operand * condition,
535                    symbol * trueLabel,
536                    symbol * falseLabel)
537 {
538   iCode *ic;
539
540   if (IS_VOID(OP_SYMBOL(condition)->type)) {
541     werror(E_VOID_VALUE_USED);
542   }
543
544   ic = newiCode (IFX, NULL, NULL);
545   IC_COND (ic) = condition;
546   IC_TRUE (ic) = trueLabel;
547   IC_FALSE (ic) = falseLabel;
548   return ic;
549 }
550
551 /*-----------------------------------------------------------------*/
552 /* newiCodeLabelGoto - unconditional goto statement| label stmnt   */
553 /*-----------------------------------------------------------------*/
554 iCode *
555 newiCodeLabelGoto (int op, symbol * label)
556 {
557   iCode *ic;
558
559   ic = newiCode (op, NULL, NULL);
560   ic->op = op;
561   ic->argLabel.label = label;
562   IC_LEFT (ic) = NULL;
563   IC_RIGHT (ic) = NULL;
564   IC_RESULT (ic) = NULL;
565   return ic;
566 }
567
568 /*-----------------------------------------------------------------*/
569 /* newiTemp - allocate & return a newItemp Variable                */
570 /*-----------------------------------------------------------------*/
571 symbol *
572 newiTemp (char *s)
573 {
574   symbol *itmp;
575
576   if (s)
577     sprintf (buffer, "%s", s);
578   else
579     sprintf (buffer, "iTemp%d", iTempNum++);
580   itmp = newSymbol (buffer, 1);
581   strcpy (itmp->rname, itmp->name);
582   itmp->isitmp = 1;
583
584   return itmp;
585 }
586
587 /*-----------------------------------------------------------------*/
588 /* newiTempLabel - creates a temp variable label                   */
589 /*-----------------------------------------------------------------*/
590 symbol *
591 newiTempLabel (char *s)
592 {
593   symbol *itmplbl;
594
595   /* check if this alredy exists */
596   if (s && (itmplbl = findSym (LabelTab, NULL, s)))
597     return itmplbl;
598
599   if (s)
600     itmplbl = newSymbol (s, 1);
601   else
602     {
603       sprintf (buffer, "iTempLbl%d", iTempLblNum++);
604       itmplbl = newSymbol (buffer, 1);
605     }
606
607   itmplbl->isitmp = 1;
608   itmplbl->islbl = 1;
609   itmplbl->key = labelKey++;
610   addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
611   return itmplbl;
612 }
613
614 /*-----------------------------------------------------------------*/
615 /* newiTempPreheaderLabel - creates a new preheader label          */
616 /*-----------------------------------------------------------------*/
617 symbol *
618 newiTempPreheaderLabel ()
619 {
620   symbol *itmplbl;
621
622   sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
623   itmplbl = newSymbol (buffer, 1);
624
625   itmplbl->isitmp = 1;
626   itmplbl->islbl = 1;
627   itmplbl->key = labelKey++;
628   addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
629   return itmplbl;
630 }
631
632
633 /*-----------------------------------------------------------------*/
634 /* initiCode - initialises some iCode related stuff                */
635 /*-----------------------------------------------------------------*/
636 void 
637 initiCode ()
638 {
639
640 }
641
642 /*-----------------------------------------------------------------*/
643 /* copyiCode - make a copy of the iCode given                      */
644 /*-----------------------------------------------------------------*/
645 iCode *
646 copyiCode (iCode * ic)
647 {
648   iCode *nic = newiCode (ic->op, NULL, NULL);
649
650   nic->lineno = ic->lineno;
651   nic->filename = ic->filename;
652   nic->block = ic->block;
653   nic->level = ic->level;
654   nic->parmBytes = ic->parmBytes;
655
656   /* deal with the special cases first */
657   switch (ic->op)
658     {
659     case IFX:
660       IC_COND (nic) = operandFromOperand (IC_COND (ic));
661       IC_TRUE (nic) = IC_TRUE (ic);
662       IC_FALSE (nic) = IC_FALSE (ic);
663       break;
664
665     case JUMPTABLE:
666       IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
667       IC_JTLABELS (nic) = IC_JTLABELS (ic);
668       break;
669
670     case CALL:
671     case PCALL:
672       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
673       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
674       IC_ARGS (nic) = IC_ARGS (ic);
675       break;
676
677     case INLINEASM:
678       IC_INLINE (nic) = IC_INLINE (ic);
679       break;
680
681     case ARRAYINIT:
682       IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
683       break;
684
685     default:
686       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
687       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
688       IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
689     }
690
691   return nic;
692 }
693
694 /*-----------------------------------------------------------------*/
695 /* getTableEntry - gets the table entry for the given operator     */
696 /*-----------------------------------------------------------------*/
697 iCodeTable *
698 getTableEntry (int oper)
699 {
700   int i;
701
702   for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
703     if (oper == codeTable[i].icode)
704       return &codeTable[i];
705
706   return NULL;
707 }
708
709 /*-----------------------------------------------------------------*/
710 /* newiTempOperand - new intermediate temp operand                 */
711 /*-----------------------------------------------------------------*/
712 operand *
713 newiTempOperand (sym_link * type, char throwType)
714 {
715   symbol *itmp;
716   operand *op = newOperand ();
717   sym_link *etype;
718
719   op->type = SYMBOL;
720   itmp = newiTemp (NULL);
721
722   etype = getSpec (type);
723
724   if (IS_LITERAL (etype))
725     throwType = 0;
726
727   /* copy the type information */
728   if (type)
729     itmp->etype = getSpec (itmp->type = (throwType ? type :
730                                          copyLinkChain (type)));
731   if (IS_LITERAL (itmp->etype))
732     {
733       SPEC_SCLS (itmp->etype) = S_REGISTER;
734       SPEC_OCLS (itmp->etype) = reg;
735     }
736
737   op->operand.symOperand = itmp;
738   op->key = itmp->key = ++operandKey;
739   return op;
740 }
741
742 /*-----------------------------------------------------------------*/
743 /* operandType - returns the type chain for an operand             */
744 /*-----------------------------------------------------------------*/
745 sym_link *
746 operandType (operand * op)
747 {
748   /* depending on type of operand */
749   switch (op->type)
750     {
751
752     case VALUE:
753       return op->operand.valOperand->type;
754
755     case SYMBOL:
756       return op->operand.symOperand->type;
757
758     case TYPE:
759       return op->operand.typeOperand;
760     default:
761       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
762               " operand type not known ");
763       assert (0);               /* should never come here */
764       /*  Just to keep the compiler happy */
765       return (sym_link *) 0;
766     }
767 }
768
769 /*-----------------------------------------------------------------*/
770 /* isParamterToCall - will return 1 if op is a parameter to args   */
771 /*-----------------------------------------------------------------*/
772 int 
773 isParameterToCall (value * args, operand * op)
774 {
775   value *tval = args;
776
777   while (tval)
778     {
779       if (tval->sym &&
780           isSymbolEqual (op->operand.symOperand, tval->sym))
781         return 1;
782       tval = tval->next;
783     }
784   return 0;
785 }
786
787 /*-----------------------------------------------------------------*/
788 /* isOperandGlobal   - return 1 if operand is a global variable    */
789 /*-----------------------------------------------------------------*/
790 int 
791 isOperandGlobal (operand * op)
792 {
793   if (!op)
794     return 0;
795
796   if (IS_ITEMP (op))
797     return 0;
798
799   if (op->type == SYMBOL &&
800       (op->operand.symOperand->level == 0 ||
801        IS_STATIC (op->operand.symOperand->etype) ||
802        IS_EXTERN (op->operand.symOperand->etype))
803     )
804     return 1;
805
806   return 0;
807 }
808
809 /*-----------------------------------------------------------------*/
810 /* isOperandVolatile - return 1 if the operand is volatile         */
811 /*-----------------------------------------------------------------*/
812 int 
813 isOperandVolatile (operand * op, bool chkTemp)
814 {
815   sym_link *optype;
816   sym_link *opetype;
817
818   if (IS_ITEMP (op) && !chkTemp)
819     return 0;
820
821   opetype = getSpec (optype = operandType (op));
822
823   if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
824     return 1;
825
826   if (IS_VOLATILE (opetype))
827     return 1;
828   return 0;
829 }
830
831 /*-----------------------------------------------------------------*/
832 /* isOperandLiteral - returns 1 if an operand contains a literal   */
833 /*-----------------------------------------------------------------*/
834 int 
835 isOperandLiteral (operand * op)
836 {
837   sym_link *opetype;
838
839   if (!op)
840     return 0;
841
842   opetype = getSpec (operandType (op));
843
844   if (IS_LITERAL (opetype))
845     return 1;
846
847   return 0;
848 }
849 /*-----------------------------------------------------------------*/
850 /* isOperandInFarSpace - will return true if operand is in farSpace */
851 /*-----------------------------------------------------------------*/
852 bool 
853 isOperandInFarSpace (operand * op)
854 {
855   sym_link *etype;
856
857   if (!op)
858     return FALSE;
859
860   if (!IS_SYMOP (op))
861     return FALSE;
862
863   if (!IS_TRUE_SYMOP (op))
864     {
865       if (SPIL_LOC (op))
866         etype = SPIL_LOC (op)->etype;
867       else
868         return FALSE;
869     }
870   else
871     {
872       etype = getSpec (operandType (op));
873     }
874   return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
875 }
876
877 /*-----------------------------------------------------------------*/
878 /* isOperandOnStack - will return true if operand is on stack      */
879 /*-----------------------------------------------------------------*/
880 bool 
881 isOperandOnStack (operand * op)
882 {
883   sym_link *etype;
884
885   if (!op)
886     return FALSE;
887
888   if (!IS_SYMOP (op))
889     return FALSE;
890
891   etype = getSpec (operandType (op));
892
893   return ((IN_STACK (etype)) ? TRUE : FALSE);
894 }
895
896 /*-----------------------------------------------------------------*/
897 /* operandLitValue - literal value of an operand                   */
898 /*-----------------------------------------------------------------*/
899 double 
900 operandLitValue (operand * op)
901 {
902   assert (isOperandLiteral (op));
903
904   return floatFromVal (op->operand.valOperand);
905 }
906
907 /*-----------------------------------------------------------------*/
908 /* operandOperation - perforoms operations on operands             */
909 /*-----------------------------------------------------------------*/
910 operand *
911 operandOperation (operand * left, operand * right,
912                   int op, sym_link * type)
913 {
914   sym_link *let , *ret=NULL;
915   operand *retval = (operand *) 0;
916   
917   assert (isOperandLiteral (left));
918   let = getSpec(operandType(left));
919   if (right) {
920     assert (isOperandLiteral (right));
921     ret = getSpec(operandType(left));
922   }
923
924   switch (op)
925     {
926     case '+':
927       retval = operandFromValue (valCastLiteral (type,
928                                                  operandLitValue (left) +
929                                                  operandLitValue (right)));
930       break;
931     case '-':
932       retval = operandFromValue (valCastLiteral (type,
933                                                  operandLitValue (left) -
934                                                  operandLitValue (right)));
935       break;
936     case '*':
937       retval = operandFromValue (valCastLiteral (type,
938                                                  operandLitValue (left) *
939                                                  operandLitValue (right)));
940       break;
941     case '/':
942       if ((unsigned long) operandLitValue (right) == 0)
943         {
944           werror (E_DIVIDE_BY_ZERO);
945           retval = right;
946
947         }
948       else
949         retval = operandFromValue (valCastLiteral (type,
950                                                    operandLitValue (left) /
951                                                    operandLitValue (right)));
952       break;
953     case '%':
954       if ((unsigned long) operandLitValue (right) == 0) {
955           werror (E_DIVIDE_BY_ZERO);
956           retval = right;
957       }
958       else 
959         retval = operandFromLit ((SPEC_USIGN(let) ? 
960                                   (unsigned long) operandLitValue (left) :
961                                   (long) operandLitValue (left)) %
962                                  (SPEC_USIGN(ret) ? 
963                                   (unsigned long) operandLitValue (right) :
964                                   (long) operandLitValue (right)));
965
966       break;
967     case LEFT_OP:
968       retval = operandFromLit ((SPEC_USIGN(let) ? 
969                                   (unsigned long) operandLitValue (left) :
970                                   (long) operandLitValue (left)) <<
971                                  (SPEC_USIGN(ret) ? 
972                                   (unsigned long) operandLitValue (right) :
973                                   (long) operandLitValue (right)));
974       break;
975     case RIGHT_OP:
976       retval = operandFromLit ((SPEC_USIGN(let) ? 
977                                   (unsigned long) operandLitValue (left) :
978                                   (long) operandLitValue (left)) >>
979                                  (SPEC_USIGN(ret) ? 
980                                   (unsigned long) operandLitValue (right) :
981                                   (long) operandLitValue (right)));
982       break;
983     case EQ_OP:
984       retval = operandFromLit (operandLitValue (left) ==
985                                operandLitValue (right));
986       break;
987     case '<':
988       retval = operandFromLit (operandLitValue (left) <
989                                operandLitValue (right));
990       break;
991     case LE_OP:
992       retval = operandFromLit (operandLitValue (left) <=
993                                operandLitValue (right));
994       break;
995     case NE_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 GE_OP:
1004       retval = operandFromLit (operandLitValue (left) >=
1005                                operandLitValue (right));
1006       break;
1007     case BITWISEAND:
1008       retval = operandFromLit ((long)operandLitValue(left) & 
1009                                (long)operandLitValue(right));
1010       break;
1011     case '|':
1012       retval = operandFromLit ((long)operandLitValue (left) |
1013                                (long)operandLitValue (right));
1014       break;
1015     case '^':
1016       retval = operandFromLit ((long)operandLitValue (left) ^
1017                                (long)operandLitValue (right));
1018       break;
1019     case AND_OP:
1020       retval = operandFromLit (operandLitValue (left) &&
1021                                operandLitValue (right));
1022       break;
1023     case OR_OP:
1024       retval = operandFromLit (operandLitValue (left) ||
1025                                operandLitValue (right));
1026       break;
1027     case RRC:
1028       {
1029         long i = (long) operandLitValue (left);
1030
1031         retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1032                                  (i << 1));
1033       }
1034       break;
1035     case RLC:
1036       {
1037         long i = (long) operandLitValue (left);
1038
1039         retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1040                                  (i >> 1));
1041       }
1042       break;
1043
1044     case UNARYMINUS:
1045       retval = operandFromLit (-1 * operandLitValue (left));
1046       break;
1047
1048     case '~':
1049       retval = operandFromLit (~((long) operandLitValue (left)));
1050       break;
1051
1052     case '!':
1053       retval = operandFromLit (!operandLitValue (left));
1054       break;
1055
1056     default:
1057       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1058               " operandOperation invalid operator ");
1059       assert (0);
1060     }
1061
1062   return retval;
1063 }
1064
1065
1066 /*-----------------------------------------------------------------*/
1067 /* isOperandEqual - compares two operand & return 1 if they r =    */
1068 /*-----------------------------------------------------------------*/
1069 int 
1070 isOperandEqual (operand * left, operand * right)
1071 {
1072   /* if the pointers are equal then they are equal */
1073   if (left == right)
1074     return 1;
1075
1076   /* if either of them null then false */
1077   if (!left || !right)
1078     return 0;
1079
1080   if (left->type != right->type)
1081     return 0;
1082
1083   if (IS_SYMOP (left) && IS_SYMOP (right))
1084     return left->key == right->key;
1085
1086   /* if types are the same */
1087   switch (left->type)
1088     {
1089     case SYMBOL:
1090       return isSymbolEqual (left->operand.symOperand,
1091                             right->operand.symOperand);
1092     case VALUE:
1093       return (floatFromVal (left->operand.valOperand) ==
1094               floatFromVal (right->operand.valOperand));
1095     case TYPE:
1096       if (compareType (left->operand.typeOperand,
1097                      right->operand.typeOperand) == 1)
1098         return 1;
1099     }
1100
1101   return 0;
1102 }
1103
1104 /*-------------------------------------------------------------------*/
1105 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1106 /*-------------------------------------------------------------------*/
1107 int 
1108 isiCodeEqual (iCode * left, iCode * right)
1109 {
1110   /* if the same pointer */
1111   if (left == right)
1112     return 1;
1113
1114   /* if either of them null */
1115   if (!left || !right)
1116     return 0;
1117
1118   /* if operand are the same */
1119   if (left->op == right->op)
1120     {
1121
1122       /* compare all the elements depending on type */
1123       if (left->op != IFX)
1124         {
1125           if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1126             return 0;
1127           if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1128             return 0;
1129
1130         }
1131       else
1132         {
1133           if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1134             return 0;
1135           if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1136             return 0;
1137           if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1138             return 0;
1139         }
1140       
1141       return 1;
1142     }
1143   return 0;
1144 }
1145
1146 /*-----------------------------------------------------------------*/
1147 /* newiTempFromOp - create a temp Operand with same attributes     */
1148 /*-----------------------------------------------------------------*/
1149 operand *
1150 newiTempFromOp (operand * op)
1151 {
1152   operand *nop;
1153
1154   if (!op)
1155     return NULL;
1156
1157   if (!IS_ITEMP (op))
1158     return op;
1159
1160   nop = newiTempOperand (operandType (op), TRUE);
1161   nop->isaddr = op->isaddr;
1162   nop->isvolatile = op->isvolatile;
1163   nop->isGlobal = op->isGlobal;
1164   nop->isLiteral = op->isLiteral;
1165   nop->usesDefs = op->usesDefs;
1166   nop->isParm = op->isParm;
1167   return nop;
1168 }
1169
1170 /*-----------------------------------------------------------------*/
1171 /* operand from operand - creates an operand holder for the type   */
1172 /*-----------------------------------------------------------------*/
1173 operand *
1174 operandFromOperand (operand * op)
1175 {
1176   operand *nop;
1177
1178   if (!op)
1179     return NULL;
1180   nop = newOperand ();
1181   nop->type = op->type;
1182   nop->isaddr = op->isaddr;
1183   nop->key = op->key;
1184   nop->isvolatile = op->isvolatile;
1185   nop->isGlobal = op->isGlobal;
1186   nop->isLiteral = op->isLiteral;
1187   nop->usesDefs = op->usesDefs;
1188   nop->isParm = op->isParm;
1189
1190   switch (nop->type)
1191     {
1192     case SYMBOL:
1193       nop->operand.symOperand = op->operand.symOperand;
1194       break;
1195     case VALUE:
1196       nop->operand.valOperand = op->operand.valOperand;
1197       break;
1198     case TYPE:
1199       nop->operand.typeOperand = op->operand.typeOperand;
1200       break;
1201     }
1202
1203   return nop;
1204 }
1205
1206 /*-----------------------------------------------------------------*/
1207 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
1208 /*-----------------------------------------------------------------*/
1209 operand *
1210 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1211 {
1212   operand *nop = operandFromOperand (op);
1213
1214   if (nop->type == SYMBOL)
1215     {
1216       OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1217       OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1218     }
1219
1220   return nop;
1221 }
1222
1223 /*-----------------------------------------------------------------*/
1224 /* operandFromSymbol - creates an operand from a symbol            */
1225 /*-----------------------------------------------------------------*/
1226 operand *
1227 operandFromSymbol (symbol * sym)
1228 {
1229   operand *op;
1230   iCode *ic;
1231   int ok = 1;
1232   /* if the symbol's type is a literal */
1233   /* then it is an enumerator type     */
1234   if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1235     return operandFromValue (valFromType (sym->etype));
1236
1237   if (!sym->key)
1238     sym->key = ++operandKey;
1239
1240   /* if this an implicit variable, means struct/union */
1241   /* member so just return it                         */
1242   if (sym->implicit || IS_FUNC (sym->type))
1243     {
1244       op = newOperand ();
1245       op->type = SYMBOL;
1246       op->operand.symOperand = sym;
1247       op->key = sym->key;
1248       op->isvolatile = isOperandVolatile (op, TRUE);
1249       op->isGlobal = isOperandGlobal (op);
1250       return op;
1251     }
1252
1253   /* under the following conditions create a
1254      register equivalent for a local symbol */
1255   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1256       (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1257       /* (!TARGET_IS_DS390)) && */
1258       (!(options.model == MODEL_FLAT24)) ) &&
1259       options.stackAuto == 0)
1260     ok = 0;
1261
1262   if (!IS_AGGREGATE (sym->type) &&      /* not an aggregate */
1263       !IS_FUNC (sym->type) &&   /* not a function   */
1264       !sym->_isparm &&          /* not a parameter  */
1265       sym->level &&             /* is a local variable */
1266       !sym->addrtaken &&        /* whose address has not been taken */
1267       !sym->reqv &&             /* does not already have a register euivalence */
1268       !IS_VOLATILE (sym->etype) &&      /* not declared as volatile */
1269       !IS_STATIC (sym->etype) &&        /* and not declared static  */
1270       !sym->islbl &&            /* not a label */
1271       ok &&                     /* farspace check */
1272       !IS_BITVAR (sym->etype)   /* not a bit variable */
1273     )
1274     {
1275
1276       /* we will use it after all optimizations
1277          and before liveRange calculation */
1278       sym->reqv = newiTempOperand (sym->type, 0);
1279       sym->reqv->key = sym->key;
1280       OP_SYMBOL (sym->reqv)->key = sym->key;
1281       OP_SYMBOL (sym->reqv)->isreqv = 1;
1282       OP_SYMBOL (sym->reqv)->islocal = 1;
1283       SPIL_LOC (sym->reqv) = sym;
1284     }
1285
1286   if (!IS_AGGREGATE (sym->type))
1287     {
1288       op = newOperand ();
1289       op->type = SYMBOL;
1290       op->operand.symOperand = sym;
1291       op->isaddr = 1;
1292       op->key = sym->key;
1293       op->isvolatile = isOperandVolatile (op, TRUE);
1294       op->isGlobal = isOperandGlobal (op);
1295       op->isPtr = IS_PTR (operandType (op));
1296       op->isParm = sym->_isparm;
1297       return op;
1298     }
1299
1300   /* create :-                     */
1301   /*    itemp = &[_symbol]         */
1302
1303   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1304   IC_LEFT (ic)->type = SYMBOL;
1305   IC_LEFT (ic)->operand.symOperand = sym;
1306   IC_LEFT (ic)->key = sym->key;
1307   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1308   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1309   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1310
1311   /* create result */
1312   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1313   if (IS_ARRAY (sym->type))
1314     {
1315       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1316       IC_RESULT (ic)->isaddr = 0;
1317     }
1318   else
1319     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1320
1321   IC_RESULT (ic)->operand.symOperand->args = sym->args;
1322
1323   ADDTOCHAIN (ic);
1324
1325   return IC_RESULT (ic);
1326 }
1327
1328 /*-----------------------------------------------------------------*/
1329 /* operandFromValue - creates an operand from value                */
1330 /*-----------------------------------------------------------------*/
1331 operand *
1332 operandFromValue (value * val)
1333 {
1334   operand *op;
1335
1336   /* if this is a symbol then do the symbol thing */
1337   if (val->sym)
1338     return operandFromSymbol (val->sym);
1339
1340   /* this is not a symbol */
1341   op = newOperand ();
1342   op->type = VALUE;
1343   op->operand.valOperand = val;
1344   op->isLiteral = isOperandLiteral (op);
1345   return op;
1346 }
1347
1348 /*-----------------------------------------------------------------*/
1349 /* operandFromLink - operand from typeChain                        */
1350 /*-----------------------------------------------------------------*/
1351 operand *
1352 operandFromLink (sym_link * type)
1353 {
1354   operand *op;
1355
1356   /* operand from sym_link */
1357   if (!type)
1358     return NULL;
1359
1360   op = newOperand ();
1361   op->type = TYPE;
1362   op->operand.typeOperand = copyLinkChain (type);
1363   return op;
1364 }
1365
1366 /*-----------------------------------------------------------------*/
1367 /* operandFromLit - makes an operand from a literal value          */
1368 /*-----------------------------------------------------------------*/
1369 operand *
1370 operandFromLit (double i)
1371 {
1372   return operandFromValue (valueFromLit (i));
1373 }
1374
1375 /*-----------------------------------------------------------------*/
1376 /* operandFromAst - creates an operand from an ast                 */
1377 /*-----------------------------------------------------------------*/
1378 operand *
1379 operandFromAst (ast * tree,int lvl)
1380 {
1381
1382   if (!tree)
1383     return NULL;
1384
1385   /* depending on type do */
1386   switch (tree->type)
1387     {
1388     case EX_OP:
1389       return ast2iCode (tree,lvl+1);
1390       break;
1391
1392     case EX_VALUE:
1393       return operandFromValue (tree->opval.val);
1394       break;
1395
1396     case EX_LINK:
1397       return operandFromLink (tree->opval.lnk);
1398     }
1399
1400   assert (0);
1401   /*  Just to keep the comiler happy */
1402   return (operand *) 0;
1403 }
1404
1405 /*-----------------------------------------------------------------*/
1406 /* setOperandType - sets the operand's type to the given type      */
1407 /*-----------------------------------------------------------------*/
1408 void 
1409 setOperandType (operand * op, sym_link * type)
1410 {
1411   /* depending on the type of operand */
1412   switch (op->type)
1413     {
1414
1415     case VALUE:
1416       op->operand.valOperand->etype =
1417         getSpec (op->operand.valOperand->type =
1418                  copyLinkChain (type));
1419       return;
1420
1421     case SYMBOL:
1422       if (op->operand.symOperand->isitmp)
1423         op->operand.symOperand->etype =
1424           getSpec (op->operand.symOperand->type =
1425                    copyLinkChain (type));
1426       else
1427         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1428                 "attempt to modify type of source");
1429       return;
1430
1431     case TYPE:
1432       op->operand.typeOperand = copyLinkChain (type);
1433       return;
1434     }
1435
1436 }
1437 /*-----------------------------------------------------------------*/
1438 /* Get size in byte of ptr need to access an array                 */
1439 /*-----------------------------------------------------------------*/
1440 int
1441 getArraySizePtr (operand * op)
1442 {
1443   sym_link *ltype = operandType(op);
1444
1445   if(IS_PTR(ltype))
1446     {
1447       int size = getSize(ltype);
1448       return(IS_GENPTR(ltype)?(size-1):size);
1449     }
1450
1451   if(IS_ARRAY(ltype))
1452     {
1453       sym_link *letype = getSpec(ltype);
1454       switch (PTR_TYPE (SPEC_OCLS (letype)))
1455         {
1456         case IPOINTER:
1457         case PPOINTER:
1458         case POINTER:
1459           return (PTRSIZE);
1460         case EEPPOINTER:
1461         case FPOINTER:
1462         case CPOINTER:
1463         case FUNCTION:
1464           return (FPTRSIZE);
1465         case GPOINTER:
1466           return (GPTRSIZE-1);
1467
1468         default:
1469           return (FPTRSIZE);
1470         }
1471     }
1472   return (FPTRSIZE);
1473 }
1474
1475 /*-----------------------------------------------------------------*/
1476 /* perform "usual unary conversions"                               */
1477 /*-----------------------------------------------------------------*/
1478 operand *
1479 usualUnaryConversions (operand * op)
1480 {
1481   if (IS_INTEGRAL (operandType (op)))
1482     {
1483       if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1484         {
1485           /* Widen to int. */
1486           return geniCodeCast (INTTYPE, op, TRUE);
1487         }
1488     }
1489   return op;
1490 }
1491
1492 /*-----------------------------------------------------------------*/
1493 /* perform "usual binary conversions"                              */
1494 /*-----------------------------------------------------------------*/
1495 sym_link *
1496 usualBinaryConversions (operand ** op1, operand ** op2)
1497 {
1498   sym_link *ctype;
1499   sym_link *rtype = operandType (*op2);
1500   sym_link *ltype = operandType (*op1);
1501   
1502   ctype = computeType (ltype, rtype);
1503   *op1 = geniCodeCast (ctype, *op1, TRUE);
1504   *op2 = geniCodeCast (ctype, *op2, TRUE);
1505   
1506   return ctype;
1507 }
1508
1509 /*-----------------------------------------------------------------*/
1510 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1511 /*                          at address                             */
1512 /*-----------------------------------------------------------------*/
1513 operand *
1514 geniCodeRValue (operand * op, bool force)
1515 {
1516   iCode *ic;
1517   sym_link *type = operandType (op);
1518   sym_link *etype = getSpec (type);
1519
1520   /* if this is an array & already */
1521   /* an address then return this   */
1522   if (IS_AGGREGATE (type) ||
1523       (IS_PTR (type) && !force && !op->isaddr))
1524     return operandFromOperand (op);
1525
1526   /* if this is not an address then must be */
1527   /* rvalue already so return this one      */
1528   if (!op->isaddr)
1529     return op;
1530
1531   /* if this is not a temp symbol then */
1532   if (!IS_ITEMP (op) &&
1533       !force &&
1534       !IN_FARSPACE (SPEC_OCLS (etype)))
1535     {
1536       op = operandFromOperand (op);
1537       op->isaddr = 0;
1538       return op;
1539     }
1540
1541   if (IS_SPEC (type) &&
1542       IS_TRUE_SYMOP (op) &&
1543       (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1544       /* TARGET_IS_DS390)) */
1545       (options.model == MODEL_FLAT24) ))
1546     {
1547       op = operandFromOperand (op);
1548       op->isaddr = 0;
1549       return op;
1550     }
1551
1552   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1553   if (IS_PTR (type) && op->isaddr && force)
1554     type = type->next;
1555
1556   type = copyLinkChain (type);
1557
1558   IC_RESULT (ic) = newiTempOperand (type, 1);
1559   IC_RESULT (ic)->isaddr = 0;
1560
1561 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1562
1563   /* if the right is a symbol */
1564   if (op->type == SYMBOL)
1565     IC_RESULT (ic)->operand.symOperand->args =
1566       op->operand.symOperand->args;
1567   ADDTOCHAIN (ic);
1568
1569   return IC_RESULT (ic);
1570 }
1571
1572 /*-----------------------------------------------------------------*/
1573 /* geniCodeCast - changes the value from one type to another       */
1574 /*-----------------------------------------------------------------*/
1575 operand *
1576 geniCodeCast (sym_link * type, operand * op, bool implicit)
1577 {
1578   iCode *ic;
1579   sym_link *optype;
1580   sym_link *opetype = getSpec (optype = operandType (op));
1581   sym_link *restype;
1582   int errors=0;
1583
1584   /* one of them has size zero then error */
1585   if (IS_VOID (optype))
1586     {
1587       werror (E_CAST_ZERO);
1588       return op;
1589     }
1590
1591   /* if the operand is already the desired type then do nothing */
1592   if (compareType (type, optype) == 1)
1593     return op;
1594
1595   /* if this is a literal then just change the type & return */
1596   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1597     return operandFromValue (valCastLiteral (type,
1598                                              operandLitValue (op)));
1599
1600   /* if casting to/from pointers, do some checking */
1601   if (IS_PTR(type)) { // to a pointer
1602     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1603       if (IS_INTEGRAL(optype)) { 
1604         // maybe this is NULL, than it's ok.
1605         if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1606           if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1607             // no way to set the storage
1608             if (IS_LITERAL(optype)) {
1609               werror(E_LITERAL_GENERIC);
1610               errors++;
1611             } else {
1612               werror(E_NONPTR2_GENPTR);
1613               errors++;
1614             }
1615           } else if (implicit) {
1616             werror(W_INTEGRAL2PTR_NOCAST);
1617             errors++;
1618           }
1619         }
1620       } else { 
1621         // shouldn't do that with float, array or structure unless to void
1622         if (!IS_VOID(getSpec(type)) && 
1623             !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1624           werror(E_INCOMPAT_TYPES);
1625           errors++;
1626         }
1627       }
1628     } else { // from a pointer to a pointer
1629       if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1630         // if not a pointer to a function
1631         if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1632           if (implicit) { // if not to generic, they have to match 
1633             if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1634               werror(E_INCOMPAT_PTYPES);
1635               errors++;
1636             }
1637           }
1638         }
1639       }
1640     }
1641   } else { // to a non pointer
1642     if (IS_PTR(optype)) { // from a pointer
1643       if (implicit) { // sneaky
1644         if (IS_INTEGRAL(type)) {
1645           werror(W_PTR2INTEGRAL_NOCAST);
1646           errors++;
1647         } else { // shouldn't do that with float, array or structure
1648           werror(E_INCOMPAT_TYPES);
1649           errors++;
1650         }
1651       }
1652     }
1653   }
1654   if (errors) {
1655     /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
1656        implicit?"(implicit)":"", errors); */
1657     fprintf (stderr, "from type '");
1658     printTypeChain (optype, stderr);
1659     fprintf (stderr, "' to type '");
1660     printTypeChain (type, stderr);
1661     fprintf (stderr, "'\n");
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 (operandType (true), 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 static void 
2693 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2694 {
2695   iCode *ic;
2696   operand *pval;
2697
2698   if (!parms)
2699     return;
2700
2701   /* if this is a param node then do the left & right */
2702   if (parms->type == EX_OP && parms->opval.op == PARAM)
2703     {
2704       geniCodeParms (parms->left, stack, fetype, func,lvl);
2705       geniCodeParms (parms->right, stack, fetype, func,lvl);
2706       return;
2707     }
2708
2709   /* get the parameter value */
2710   if (parms->type == EX_OPERAND)
2711     pval = parms->opval.oprnd;
2712   else
2713     {
2714       /* maybe this else should go away ?? */
2715       /* hack don't like this but too lazy to think of
2716          something better */
2717       if (IS_ADDRESS_OF_OP (parms))
2718         parms->left->lvalue = 1;
2719
2720       if (IS_CAST_OP (parms) &&
2721           IS_PTR (parms->ftype) &&
2722           IS_ADDRESS_OF_OP (parms->right))
2723         parms->right->left->lvalue = 1;
2724
2725       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2726     }
2727
2728   /* if register parm then make it a send */
2729   if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2730        IS_REGPARM (parms->etype)) && !func->hasVargs)
2731     {
2732       ic = newiCode (SEND, pval, NULL);
2733       ADDTOCHAIN (ic);
2734     }
2735   else
2736     {
2737       /* now decide whether to push or assign */
2738       if (!(options.stackAuto || IS_RENT (fetype)))
2739         {
2740
2741           /* assign */
2742           operand *top = operandFromSymbol (parms->argSym);
2743           geniCodeAssign (top, pval, 1);
2744         }
2745       else
2746         {
2747           sym_link *p = operandType (pval);
2748           /* push */
2749           ic = newiCode (IPUSH, pval, NULL);
2750           ic->parmPush = 1;
2751           /* update the stack adjustment */
2752           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2753           ADDTOCHAIN (ic);
2754         }
2755     }
2756
2757 }
2758
2759 /*-----------------------------------------------------------------*/
2760 /* geniCodeCall - generates temp code for calling                  */
2761 /*-----------------------------------------------------------------*/
2762 operand *
2763 geniCodeCall (operand * left, ast * parms,int lvl)
2764 {
2765   iCode *ic;
2766   operand *result;
2767   sym_link *type, *etype;
2768   int stack = 0;
2769
2770   if (!IS_FUNC(OP_SYMBOL(left)->type) && 
2771       !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2772     werror (E_FUNCTION_EXPECTED);
2773     return NULL;
2774   }
2775
2776   /* take care of parameters with side-effecting
2777      function calls in them, this is required to take care
2778      of overlaying function parameters */
2779   geniCodeSEParms (parms,lvl);
2780
2781   /* first the parameters */
2782   geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2783
2784   /* now call : if symbol then pcall */
2785   if (IS_OP_POINTER (left) || IS_ITEMP(left))
2786     ic = newiCode (PCALL, left, NULL);
2787   else
2788     ic = newiCode (CALL, left, NULL);
2789
2790   IC_ARGS (ic) = left->operand.symOperand->args;
2791   type = copyLinkChain (operandType (left)->next);
2792   etype = getSpec (type);
2793   SPEC_EXTR (etype) = 0;
2794   IC_RESULT (ic) = result = newiTempOperand (type, 1);
2795
2796   ADDTOCHAIN (ic);
2797
2798   /* stack adjustment after call */
2799   ic->parmBytes = stack;
2800
2801   return result;
2802 }
2803
2804 /*-----------------------------------------------------------------*/
2805 /* geniCodeReceive - generate intermediate code for "receive"      */
2806 /*-----------------------------------------------------------------*/
2807 static void 
2808 geniCodeReceive (value * args)
2809 {
2810   /* for all arguments that are passed in registers */
2811   while (args)
2812     {
2813
2814       if (IS_REGPARM (args->etype))
2815         {
2816           operand *opr = operandFromValue (args);
2817           operand *opl;
2818           symbol *sym = OP_SYMBOL (opr);
2819           iCode *ic;
2820
2821           /* we will use it after all optimizations
2822              and before liveRange calculation */
2823           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2824             {
2825
2826               if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2827                   options.stackAuto == 0 &&
2828                   /* !TARGET_IS_DS390) */
2829                   (!(options.model == MODEL_FLAT24)) )
2830                 {
2831                 }
2832               else
2833                 {
2834                   opl = newiTempOperand (args->type, 0);
2835                   sym->reqv = opl;
2836                   sym->reqv->key = sym->key;
2837                   OP_SYMBOL (sym->reqv)->key = sym->key;
2838                   OP_SYMBOL (sym->reqv)->isreqv = 1;
2839                   OP_SYMBOL (sym->reqv)->islocal = 0;
2840                   SPIL_LOC (sym->reqv) = sym;
2841                 }
2842             }
2843
2844           ic = newiCode (RECEIVE, NULL, NULL);
2845           currFunc->recvSize = getSize (sym->etype);
2846           IC_RESULT (ic) = opr;
2847           ADDTOCHAIN (ic);
2848         }
2849
2850       args = args->next;
2851     }
2852 }
2853
2854 /*-----------------------------------------------------------------*/
2855 /* geniCodeFunctionBody - create the function body                 */
2856 /*-----------------------------------------------------------------*/
2857 void 
2858 geniCodeFunctionBody (ast * tree,int lvl)
2859 {
2860   iCode *ic;
2861   operand *func;
2862   sym_link *fetype;
2863   int savelineno;
2864
2865   /* reset the auto generation */
2866   /* numbers */
2867   iTempNum = 0;
2868   iTempLblNum = 0;
2869   operandKey = 0;
2870   iCodeKey = 0;
2871   func = ast2iCode (tree->left,lvl+1);
2872   fetype = getSpec (operandType (func));
2873
2874   savelineno = lineno;
2875   lineno = OP_SYMBOL (func)->lineDef;
2876   /* create an entry label */
2877   geniCodeLabel (entryLabel);
2878   lineno = savelineno;
2879
2880   /* create a proc icode */
2881   ic = newiCode (FUNCTION, func, NULL);
2882   /* if the function has parmas   then */
2883   /* save the parameters information    */
2884   ic->argLabel.args = tree->values.args;
2885   ic->lineno = OP_SYMBOL (func)->lineDef;
2886
2887   ADDTOCHAIN (ic);
2888
2889   /* for all parameters that are passed
2890      on registers add a "receive" */
2891   geniCodeReceive (tree->values.args);
2892
2893   /* generate code for the body */
2894   ast2iCode (tree->right,lvl+1);
2895
2896   /* create a label for return */
2897   geniCodeLabel (returnLabel);
2898
2899   /* now generate the end proc */
2900   ic = newiCode (ENDFUNCTION, func, NULL);
2901   ADDTOCHAIN (ic);
2902   return;
2903 }
2904
2905 /*-----------------------------------------------------------------*/
2906 /* geniCodeReturn - gen icode for 'return' statement               */
2907 /*-----------------------------------------------------------------*/
2908 void 
2909 geniCodeReturn (operand * op)
2910 {
2911   iCode *ic;
2912
2913   /* if the operand is present force an rvalue */
2914   if (op)
2915     op = geniCodeRValue (op, FALSE);
2916
2917   ic = newiCode (RETURN, op, NULL);
2918   ADDTOCHAIN (ic);
2919 }
2920
2921 /*-----------------------------------------------------------------*/
2922 /* geniCodeIfx - generates code for extended if statement          */
2923 /*-----------------------------------------------------------------*/
2924 void 
2925 geniCodeIfx (ast * tree,int lvl)
2926 {
2927   iCode *ic;
2928   operand *condition = ast2iCode (tree->left,lvl+1);
2929   sym_link *cetype;
2930
2931   /* if condition is null then exit */
2932   if (!condition)
2933     goto exit;
2934   else
2935     condition = geniCodeRValue (condition, FALSE);
2936
2937   cetype = getSpec (operandType (condition));
2938   /* if the condition is a literal */
2939   if (IS_LITERAL (cetype))
2940     {
2941       if (floatFromVal (condition->operand.valOperand))
2942         {
2943           if (tree->trueLabel)
2944             geniCodeGoto (tree->trueLabel);
2945           else
2946             assert (1);
2947         }
2948       else
2949         {
2950           if (tree->falseLabel)
2951             geniCodeGoto (tree->falseLabel);
2952           else
2953             assert (1);
2954         }
2955       goto exit;
2956     }
2957
2958   if (tree->trueLabel)
2959     {
2960       ic = newiCodeCondition (condition,
2961                               tree->trueLabel,
2962                               NULL);
2963       ADDTOCHAIN (ic);
2964
2965       if (tree->falseLabel)
2966         geniCodeGoto (tree->falseLabel);
2967     }
2968   else
2969     {
2970       ic = newiCodeCondition (condition,
2971                               NULL,
2972                               tree->falseLabel);
2973       ADDTOCHAIN (ic);
2974     }
2975
2976 exit:
2977   ast2iCode (tree->right,lvl+1);
2978 }
2979
2980 /*-----------------------------------------------------------------*/
2981 /* geniCodeJumpTable - tries to create a jump table for switch     */
2982 /*-----------------------------------------------------------------*/
2983 int 
2984 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2985 {
2986   int min = 0, max = 0, t, cnt = 0;
2987   value *vch;
2988   iCode *ic;
2989   operand *boundary;
2990   symbol *falseLabel;
2991   set *labels = NULL;
2992
2993   if (!tree || !caseVals)
2994     return 0;
2995
2996   /* the criteria for creating a jump table is */
2997   /* all integer numbers between the maximum & minimum must */
2998   /* be present , the maximum value should not exceed 255 */
2999   min = max = (int) floatFromVal (vch = caseVals);
3000   sprintf (buffer, "_case_%d_%d",
3001            tree->values.switchVals.swNum,
3002            min);
3003   addSet (&labels, newiTempLabel (buffer));
3004
3005   /* if there is only one case value then no need */
3006   if (!(vch = vch->next))
3007     return 0;
3008
3009   while (vch)
3010     {
3011       if (((t = (int) floatFromVal (vch)) - max) != 1)
3012         return 0;
3013       sprintf (buffer, "_case_%d_%d",
3014                tree->values.switchVals.swNum,
3015                t);
3016       addSet (&labels, newiTempLabel (buffer));
3017       max = t;
3018       cnt++;
3019       vch = vch->next;
3020     }
3021
3022   /* if the number of case statements <= 2 then */
3023   /* it is not economical to create the jump table */
3024   /* since two compares are needed for boundary conditions */
3025   if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3026     return 0;
3027
3028   if (tree->values.switchVals.swDefault)
3029     sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3030   else
3031     sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3032
3033   falseLabel = newiTempLabel (buffer);
3034
3035   /* so we can create a jumptable */
3036   /* first we rule out the boundary conditions */
3037   /* if only optimization says so */
3038   if (!optimize.noJTabBoundary)
3039     {
3040       sym_link *cetype = getSpec (operandType (cond));
3041       /* no need to check the lower bound if
3042          the condition is unsigned & minimum value is zero */
3043       if (!(min == 0 && SPEC_USIGN (cetype)))
3044         {
3045           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3046           ic = newiCodeCondition (boundary, falseLabel, NULL);
3047           ADDTOCHAIN (ic);
3048         }
3049
3050       /* now for upper bounds */
3051       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3052       ic = newiCodeCondition (boundary, falseLabel, NULL);
3053       ADDTOCHAIN (ic);
3054     }
3055
3056   /* if the min is not zero then we no make it zero */
3057   if (min)
3058     {
3059       cond = geniCodeSubtract (cond, operandFromLit (min));
3060       setOperandType (cond, UCHARTYPE);
3061     }
3062
3063   /* now create the jumptable */
3064   ic = newiCode (JUMPTABLE, NULL, NULL);
3065   IC_JTCOND (ic) = cond;
3066   IC_JTLABELS (ic) = labels;
3067   ADDTOCHAIN (ic);
3068   return 1;
3069 }
3070
3071 /*-----------------------------------------------------------------*/
3072 /* geniCodeSwitch - changes a switch to a if statement             */
3073 /*-----------------------------------------------------------------*/
3074 void 
3075 geniCodeSwitch (ast * tree,int lvl)
3076 {
3077   iCode *ic;
3078   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3079   value *caseVals = tree->values.switchVals.swVals;
3080   symbol *trueLabel, *falseLabel;
3081
3082   /* if we can make this a jump table */
3083   if (geniCodeJumpTable (cond, caseVals, tree))
3084     goto jumpTable;             /* no need for the comparison */
3085
3086   /* for the cases defined do */
3087   while (caseVals)
3088     {
3089
3090       operand *compare = geniCodeLogic (cond,
3091                                         operandFromValue (caseVals),
3092                                         EQ_OP);
3093
3094       sprintf (buffer, "_case_%d_%d",
3095                tree->values.switchVals.swNum,
3096                (int) floatFromVal (caseVals));
3097       trueLabel = newiTempLabel (buffer);
3098
3099       ic = newiCodeCondition (compare, trueLabel, NULL);
3100       ADDTOCHAIN (ic);
3101       caseVals = caseVals->next;
3102     }
3103
3104
3105
3106   /* if default is present then goto break else break */
3107   if (tree->values.switchVals.swDefault)
3108     sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3109   else
3110     sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3111
3112   falseLabel = newiTempLabel (buffer);
3113   geniCodeGoto (falseLabel);
3114
3115 jumpTable:
3116   ast2iCode (tree->right,lvl+1);
3117 }
3118
3119 /*-----------------------------------------------------------------*/
3120 /* geniCodeInline - intermediate code for inline assembler         */
3121 /*-----------------------------------------------------------------*/
3122 static void 
3123 geniCodeInline (ast * tree)
3124 {
3125   iCode *ic;
3126
3127   ic = newiCode (INLINEASM, NULL, NULL);
3128   IC_INLINE (ic) = tree->values.inlineasm;
3129   ADDTOCHAIN (ic);
3130 }
3131
3132 /*-----------------------------------------------------------------*/
3133 /* geniCodeArrayInit - intermediate code for array initializer     */
3134 /*-----------------------------------------------------------------*/
3135 static void 
3136 geniCodeArrayInit (ast * tree, operand *array)
3137 {
3138   iCode *ic;
3139
3140   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3141     ic = newiCode (ARRAYINIT, array, NULL);
3142     IC_ARRAYILIST (ic) = tree->values.constlist;
3143   } else {
3144     operand *left=newOperand(), *right=newOperand();
3145     left->type=right->type=SYMBOL;
3146     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3147     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3148     ic = newiCode (ARRAYINIT, left, right);
3149   }
3150   ADDTOCHAIN (ic);
3151 }
3152
3153 /*-----------------------------------------------------------------*/
3154 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3155 /* particular case. Ie : assigning or dereferencing array or ptr   */
3156 /*-----------------------------------------------------------------*/
3157 set * lvaluereqSet = NULL;
3158 typedef struct lvalItem
3159   {
3160     int req;
3161     int lvl;
3162   }
3163 lvalItem;
3164
3165 /*-----------------------------------------------------------------*/
3166 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3167 /*-----------------------------------------------------------------*/
3168 void addLvaluereq(int lvl)
3169 {
3170   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3171   lpItem->req=1;
3172   lpItem->lvl=lvl;
3173   addSetHead(&lvaluereqSet,lpItem);
3174
3175 }
3176 /*-----------------------------------------------------------------*/
3177 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3178 /*-----------------------------------------------------------------*/
3179 void delLvaluereq()
3180 {
3181   lvalItem * lpItem;
3182   lpItem = getSet(&lvaluereqSet);
3183   if(lpItem) Safe_free(lpItem);
3184 }
3185 /*-----------------------------------------------------------------*/
3186 /* clearLvaluereq - clear lvalreq flag                             */
3187 /*-----------------------------------------------------------------*/
3188 void clearLvaluereq()
3189 {
3190   lvalItem * lpItem;
3191   lpItem = peekSet(lvaluereqSet);
3192   if(lpItem) lpItem->req = 0;
3193 }
3194 /*-----------------------------------------------------------------*/
3195 /* getLvaluereq - get the last lvalreq level                       */
3196 /*-----------------------------------------------------------------*/
3197 int getLvaluereqLvl()
3198 {
3199   lvalItem * lpItem;
3200   lpItem = peekSet(lvaluereqSet);
3201   if(lpItem) return lpItem->lvl;
3202   return 0;
3203 }
3204 /*-----------------------------------------------------------------*/
3205 /* isLvaluereq - is lvalreq valid for this level ?                 */
3206 /*-----------------------------------------------------------------*/
3207 int isLvaluereq(int lvl)
3208 {
3209   lvalItem * lpItem;
3210   lpItem = peekSet(lvaluereqSet);
3211   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3212   return 0;
3213 }
3214
3215 /*-----------------------------------------------------------------*/
3216 /* ast2iCode - creates an icodeList from an ast                    */
3217 /*-----------------------------------------------------------------*/
3218 operand *
3219 ast2iCode (ast * tree,int lvl)
3220 {
3221   operand *left = NULL;
3222   operand *right = NULL;
3223   if (!tree)
3224     return NULL;
3225   /* set the global variables for filename & line number */
3226   if (tree->filename)
3227     filename = tree->filename;
3228   if (tree->lineno)
3229     lineno = tree->lineno;
3230   if (tree->block)
3231     block = tree->block;
3232   if (tree->level)
3233     scopeLevel = tree->level;
3234
3235   if (tree->type == EX_VALUE)
3236     return operandFromValue (tree->opval.val);
3237
3238   if (tree->type == EX_LINK)
3239     return operandFromLink (tree->opval.lnk);
3240
3241   /* if we find a nullop */
3242   if (tree->type == EX_OP &&
3243      (tree->opval.op == NULLOP ||
3244      tree->opval.op == BLOCK))
3245     {
3246       ast2iCode (tree->left,lvl+1);
3247       ast2iCode (tree->right,lvl+1);
3248       return NULL;
3249     }
3250
3251   /* special cases for not evaluating */
3252   if (tree->opval.op != ':' &&
3253       tree->opval.op != '?' &&
3254       tree->opval.op != CALL &&
3255       tree->opval.op != IFX &&
3256       tree->opval.op != LABEL &&
3257       tree->opval.op != GOTO &&
3258       tree->opval.op != SWITCH &&
3259       tree->opval.op != FUNCTION &&
3260       tree->opval.op != INLINEASM)
3261     {
3262
3263         if (IS_ASSIGN_OP (tree->opval.op) ||
3264            IS_DEREF_OP (tree) ||
3265            (tree->opval.op == '&' && !tree->right) ||
3266            tree->opval.op == PTR_OP)
3267           {
3268             addLvaluereq(lvl);
3269             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3270                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3271               clearLvaluereq();
3272
3273             left = operandFromAst (tree->left,lvl);
3274             delLvaluereq();
3275             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3276               left = geniCodeRValue (left, TRUE);
3277           }
3278         else
3279           {
3280             left = operandFromAst (tree->left,lvl);
3281           }
3282         if (tree->opval.op == INC_OP ||
3283             tree->opval.op == DEC_OP)
3284           {
3285             addLvaluereq(lvl);
3286             right = operandFromAst (tree->right,lvl);
3287             delLvaluereq();
3288           }
3289         else
3290           {
3291             right = operandFromAst (tree->right,lvl);
3292           }
3293       }
3294
3295   /* now depending on the type of operand */
3296   /* this will be a biggy                 */
3297   switch (tree->opval.op)
3298     {
3299
3300     case '[':                   /* array operation */
3301       {
3302         //sym_link *ltype = operandType (left);
3303         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3304         left = geniCodeRValue (left, FALSE);
3305         right = geniCodeRValue (right, TRUE);
3306       }
3307
3308       return geniCodeArray (left, right,lvl);
3309
3310     case '.':                   /* structure dereference */
3311       if (IS_PTR (operandType (left)))
3312         left = geniCodeRValue (left, TRUE);
3313       else
3314         left = geniCodeRValue (left, FALSE);
3315
3316       return geniCodeStruct (left, right, tree->lvalue);
3317
3318     case PTR_OP:                /* structure pointer dereference */
3319       {
3320         sym_link *pType;
3321         pType = operandType (left);
3322         left = geniCodeRValue (left, TRUE);
3323
3324         setOClass (pType, getSpec (operandType (left)));
3325       }
3326
3327       return geniCodeStruct (left, right, tree->lvalue);
3328
3329     case INC_OP:                /* increment operator */
3330       if (left)
3331         return geniCodePostInc (left);
3332       else
3333         return geniCodePreInc (right);
3334
3335     case DEC_OP:                /* decrement operator */
3336       if (left)
3337         return geniCodePostDec (left);
3338       else
3339         return geniCodePreDec (right);
3340
3341     case '&':                   /* bitwise and or address of operator */
3342       if (right)
3343         {                       /* this is a bitwise operator   */
3344           left = geniCodeRValue (left, FALSE);
3345           right = geniCodeRValue (right, FALSE);
3346           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3347         }
3348       else
3349         return geniCodeAddressOf (left);
3350
3351     case '|':                   /* bitwise or & xor */
3352     case '^':
3353       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3354                               geniCodeRValue (right, FALSE),
3355                               tree->opval.op,
3356                               tree->ftype);
3357
3358     case '/':
3359       return geniCodeDivision (geniCodeRValue (left, FALSE),
3360                                geniCodeRValue (right, FALSE));
3361
3362     case '%':
3363       return geniCodeModulus (geniCodeRValue (left, FALSE),
3364                               geniCodeRValue (right, FALSE));
3365     case '*':
3366       if (right)
3367         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3368                                  geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3369       else
3370         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3371
3372     case '-':
3373       if (right)
3374         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3375                                  geniCodeRValue (right, FALSE));
3376       else
3377         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3378
3379     case '+':
3380       if (right)
3381         return geniCodeAdd (geniCodeRValue (left, FALSE),
3382                             geniCodeRValue (right, FALSE),lvl);
3383       else
3384         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3385
3386     case LEFT_OP:
3387       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3388                                 geniCodeRValue (right, FALSE));
3389
3390     case RIGHT_OP:
3391       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3392                                  geniCodeRValue (right, FALSE));
3393     case CAST:
3394       return geniCodeCast (operandType (left),
3395                            geniCodeRValue (right, FALSE), FALSE);
3396
3397     case '~':
3398     case '!':
3399     case RRC:
3400     case RLC:
3401       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3402
3403     case GETHBIT:
3404       {
3405         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3406         setOperandType (op, UCHARTYPE);
3407         return op;
3408       }
3409     case '>':
3410     case '<':
3411     case LE_OP:
3412     case GE_OP:
3413     case EQ_OP:
3414     case NE_OP:
3415     case AND_OP:
3416     case OR_OP:
3417       return geniCodeLogic (geniCodeRValue (left, FALSE),
3418                             geniCodeRValue (right, FALSE),
3419                             tree->opval.op);
3420     case '?':
3421       return geniCodeConditional (tree,lvl);
3422
3423     case SIZEOF:
3424       return operandFromLit (getSize (tree->right->ftype));
3425
3426     case '=':
3427       {
3428         sym_link *rtype = operandType (right);
3429         sym_link *ltype = operandType (left);
3430         if (IS_PTR (rtype) && IS_ITEMP (right)
3431             && right->isaddr && compareType (rtype->next, ltype) == 1)
3432           right = geniCodeRValue (right, TRUE);
3433         else
3434           right = geniCodeRValue (right, FALSE);
3435
3436         geniCodeAssign (left, right, 0);
3437         return right;
3438       }
3439     case MUL_ASSIGN:
3440       return
3441         geniCodeAssign (left,
3442                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3443                                                   FALSE),
3444                                   geniCodeRValue (right, FALSE),FALSE), 0);
3445
3446     case DIV_ASSIGN:
3447       return
3448         geniCodeAssign (left,
3449                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3450                                                   FALSE),
3451                                   geniCodeRValue (right, FALSE)), 0);
3452     case MOD_ASSIGN:
3453       return
3454         geniCodeAssign (left,
3455                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3456                                                   FALSE),
3457                                   geniCodeRValue (right, FALSE)), 0);
3458     case ADD_ASSIGN:
3459       {
3460         sym_link *rtype = operandType (right);
3461         sym_link *ltype = operandType (left);
3462         if (IS_PTR (rtype) && IS_ITEMP (right)
3463             && right->isaddr && compareType (rtype->next, ltype) == 1)
3464           right = geniCodeRValue (right, TRUE);
3465         else
3466           right = geniCodeRValue (right, FALSE);
3467
3468
3469         return geniCodeAssign (left,
3470                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3471                                                   FALSE),
3472                                   right,lvl), 0);
3473       }
3474     case SUB_ASSIGN:
3475       {
3476         sym_link *rtype = operandType (right);
3477         sym_link *ltype = operandType (left);
3478         if (IS_PTR (rtype) && IS_ITEMP (right)
3479             && right->isaddr && compareType (rtype->next, ltype) == 1)
3480           {
3481             right = geniCodeRValue (right, TRUE);
3482           }
3483         else
3484           {
3485             right = geniCodeRValue (right, FALSE);
3486           }
3487         return
3488           geniCodeAssign (left,
3489                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3490                                                   FALSE),
3491                                   right), 0);
3492       }
3493     case LEFT_ASSIGN:
3494       return
3495         geniCodeAssign (left,
3496                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3497                                                    ,FALSE),
3498                                    geniCodeRValue (right, FALSE)), 0);
3499     case RIGHT_ASSIGN:
3500       return
3501         geniCodeAssign (left,
3502                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3503                                                    ,FALSE),
3504                                    geniCodeRValue (right, FALSE)), 0);
3505     case AND_ASSIGN:
3506       return
3507         geniCodeAssign (left,
3508                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3509                                                   FALSE),
3510                                   geniCodeRValue (right, FALSE),
3511                                   BITWISEAND,
3512                                   operandType (left)), 0);
3513     case XOR_ASSIGN:
3514       return
3515         geniCodeAssign (left,
3516                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3517                                                   FALSE),
3518                                   geniCodeRValue (right, FALSE),
3519                                   '^',
3520                                   operandType (left)), 0);
3521     case OR_ASSIGN:
3522       return
3523         geniCodeAssign (left,
3524                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3525                                                    ,FALSE),
3526                                    geniCodeRValue (right, FALSE),
3527                                    '|',
3528                                    operandType (left)), 0);
3529     case ',':
3530       return geniCodeRValue (right, FALSE);
3531
3532     case CALL:
3533       return geniCodeCall (ast2iCode (tree->left,lvl+1),
3534                            tree->right,lvl);
3535     case LABEL:
3536       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3537       return ast2iCode (tree->right,lvl+1);
3538
3539     case GOTO:
3540       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3541       return ast2iCode (tree->right,lvl+1);
3542
3543     case FUNCTION:
3544       geniCodeFunctionBody (tree,lvl);
3545       return NULL;
3546
3547     case RETURN:
3548       geniCodeReturn (right);
3549       return NULL;
3550
3551     case IFX:
3552       geniCodeIfx (tree,lvl);
3553       return NULL;
3554
3555     case SWITCH:
3556       geniCodeSwitch (tree,lvl);
3557       return NULL;
3558
3559     case INLINEASM:
3560       geniCodeInline (tree);
3561       return NULL;
3562         
3563     case ARRAYINIT:
3564         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3565         return NULL;
3566     }
3567
3568   return NULL;
3569 }
3570
3571 /*-----------------------------------------------------------------*/
3572 /* reverseICChain - gets from the list and creates a linkedlist    */
3573 /*-----------------------------------------------------------------*/
3574 iCode *
3575 reverseiCChain ()
3576 {
3577   iCode *loop = NULL;
3578   iCode *prev = NULL;
3579
3580   while ((loop = getSet (&iCodeChain)))
3581     {
3582       loop->next = prev;
3583       if (prev)
3584         prev->prev = loop;
3585       prev = loop;
3586     }
3587
3588   return prev;
3589 }
3590
3591
3592 /*-----------------------------------------------------------------*/
3593 /* iCodeFromAst - given an ast will convert it to iCode            */
3594 /*-----------------------------------------------------------------*/
3595 iCode *
3596 iCodeFromAst (ast * tree)
3597 {
3598   returnLabel = newiTempLabel ("_return");
3599   entryLabel = newiTempLabel ("_entry");
3600   ast2iCode (tree,0);
3601   return reverseiCChain ();
3602 }