fixed the "void (*i)(void) = f" case
[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_calloc (1, 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_calloc (1, 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 ((unsigned long) operandLitValue (left) &
1009                                (unsigned long) operandLitValue (right));
1010       break;
1011     case '|':
1012       retval = operandFromLit ((unsigned long) operandLitValue (left) |
1013                                (unsigned long) operandLitValue (right));
1014       break;
1015     case '^':
1016       retval = operandFromLit ((unsigned long) operandLitValue (left) ^
1017                                (unsigned 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 - comapres two iCodes are 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       return 1;
1141     }
1142   return 0;
1143 }
1144
1145 /*-----------------------------------------------------------------*/
1146 /* newiTempFromOp - create a temp Operand with same attributes     */
1147 /*-----------------------------------------------------------------*/
1148 operand *
1149 newiTempFromOp (operand * op)
1150 {
1151   operand *nop;
1152
1153   if (!op)
1154     return NULL;
1155
1156   if (!IS_ITEMP (op))
1157     return op;
1158
1159   nop = newiTempOperand (operandType (op), TRUE);
1160   nop->isaddr = op->isaddr;
1161   nop->isvolatile = op->isvolatile;
1162   nop->isGlobal = op->isGlobal;
1163   nop->isLiteral = op->isLiteral;
1164   nop->usesDefs = op->usesDefs;
1165   nop->isParm = op->isParm;
1166   return nop;
1167 }
1168
1169 /*-----------------------------------------------------------------*/
1170 /* operand from operand - creates an operand holder for the type   */
1171 /*-----------------------------------------------------------------*/
1172 operand *
1173 operandFromOperand (operand * op)
1174 {
1175   operand *nop;
1176
1177   if (!op)
1178     return NULL;
1179   nop = newOperand ();
1180   nop->type = op->type;
1181   nop->isaddr = op->isaddr;
1182   nop->key = op->key;
1183   nop->isvolatile = op->isvolatile;
1184   nop->isGlobal = op->isGlobal;
1185   nop->isLiteral = op->isLiteral;
1186   nop->usesDefs = op->usesDefs;
1187   nop->isParm = op->isParm;
1188
1189   switch (nop->type)
1190     {
1191     case SYMBOL:
1192       nop->operand.symOperand = op->operand.symOperand;
1193       break;
1194     case VALUE:
1195       nop->operand.valOperand = op->operand.valOperand;
1196       break;
1197     case TYPE:
1198       nop->operand.typeOperand = op->operand.typeOperand;
1199       break;
1200     }
1201
1202   return nop;
1203 }
1204
1205 /*-----------------------------------------------------------------*/
1206 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
1207 /*-----------------------------------------------------------------*/
1208 operand *
1209 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1210 {
1211   operand *nop = operandFromOperand (op);
1212
1213   if (nop->type == SYMBOL)
1214     {
1215       OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1216       OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1217     }
1218
1219   return nop;
1220 }
1221
1222 /*-----------------------------------------------------------------*/
1223 /* operandFromSymbol - creates an operand from a symbol            */
1224 /*-----------------------------------------------------------------*/
1225 operand *
1226 operandFromSymbol (symbol * sym)
1227 {
1228   operand *op;
1229   iCode *ic;
1230   int ok = 1;
1231   /* if the symbol's type is a literal */
1232   /* then it is an enumerator type     */
1233   if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1234     return operandFromValue (valFromType (sym->etype));
1235
1236   if (!sym->key)
1237     sym->key = ++operandKey;
1238
1239   /* if this an implicit variable, means struct/union */
1240   /* member so just return it                         */
1241   if (sym->implicit || IS_FUNC (sym->type))
1242     {
1243       op = newOperand ();
1244       op->type = SYMBOL;
1245       op->operand.symOperand = sym;
1246       op->key = sym->key;
1247       op->isvolatile = isOperandVolatile (op, TRUE);
1248       op->isGlobal = isOperandGlobal (op);
1249       return op;
1250     }
1251
1252   /* under the following conditions create a
1253      register equivalent for a local symbol */
1254   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1255       (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1256       /* (!TARGET_IS_DS390)) && */
1257       (!(options.model == MODEL_FLAT24)) ) &&
1258       options.stackAuto == 0)
1259     ok = 0;
1260
1261   if (!IS_AGGREGATE (sym->type) &&      /* not an aggregate */
1262       !IS_FUNC (sym->type) &&   /* not a function   */
1263       !sym->_isparm &&          /* not a parameter  */
1264       sym->level &&             /* is a local variable */
1265       !sym->addrtaken &&        /* whose address has not been taken */
1266       !sym->reqv &&             /* does not already have a register euivalence */
1267       !IS_VOLATILE (sym->etype) &&      /* not declared as volatile */
1268       !IS_STATIC (sym->etype) &&        /* and not declared static  */
1269       !sym->islbl &&            /* not a label */
1270       ok &&                     /* farspace check */
1271       !IS_BITVAR (sym->etype)   /* not a bit variable */
1272     )
1273     {
1274
1275       /* we will use it after all optimizations
1276          and before liveRange calculation */
1277       sym->reqv = newiTempOperand (sym->type, 0);
1278       sym->reqv->key = sym->key;
1279       OP_SYMBOL (sym->reqv)->key = sym->key;
1280       OP_SYMBOL (sym->reqv)->isreqv = 1;
1281       OP_SYMBOL (sym->reqv)->islocal = 1;
1282       SPIL_LOC (sym->reqv) = sym;
1283     }
1284
1285   if (!IS_AGGREGATE (sym->type))
1286     {
1287       op = newOperand ();
1288       op->type = SYMBOL;
1289       op->operand.symOperand = sym;
1290       op->isaddr = 1;
1291       op->key = sym->key;
1292       op->isvolatile = isOperandVolatile (op, TRUE);
1293       op->isGlobal = isOperandGlobal (op);
1294       op->isPtr = IS_PTR (operandType (op));
1295       op->isParm = sym->_isparm;
1296       return op;
1297     }
1298
1299   /* create :-                     */
1300   /*    itemp = &[_symbol]         */
1301
1302   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1303   IC_LEFT (ic)->type = SYMBOL;
1304   IC_LEFT (ic)->operand.symOperand = sym;
1305   IC_LEFT (ic)->key = sym->key;
1306   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1307   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1308   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1309
1310   /* create result */
1311   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1312   if (IS_ARRAY (sym->type))
1313     {
1314       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1315       IC_RESULT (ic)->isaddr = 0;
1316     }
1317   else
1318     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1319
1320   IC_RESULT (ic)->operand.symOperand->args = sym->args;
1321
1322   ADDTOCHAIN (ic);
1323
1324   return IC_RESULT (ic);
1325 }
1326
1327 /*-----------------------------------------------------------------*/
1328 /* operandFromValue - creates an operand from value                */
1329 /*-----------------------------------------------------------------*/
1330 operand *
1331 operandFromValue (value * val)
1332 {
1333   operand *op;
1334
1335   /* if this is a symbol then do the symbol thing */
1336   if (val->sym)
1337     return operandFromSymbol (val->sym);
1338
1339   /* this is not a symbol */
1340   op = newOperand ();
1341   op->type = VALUE;
1342   op->operand.valOperand = val;
1343   op->isLiteral = isOperandLiteral (op);
1344   return op;
1345 }
1346
1347 /*-----------------------------------------------------------------*/
1348 /* operandFromLink - operand from typeChain                        */
1349 /*-----------------------------------------------------------------*/
1350 operand *
1351 operandFromLink (sym_link * type)
1352 {
1353   operand *op;
1354
1355   /* operand from sym_link */
1356   if (!type)
1357     return NULL;
1358
1359   op = newOperand ();
1360   op->type = TYPE;
1361   op->operand.typeOperand = copyLinkChain (type);
1362   return op;
1363 }
1364
1365 /*-----------------------------------------------------------------*/
1366 /* operandFromLit - makes an operand from a literal value          */
1367 /*-----------------------------------------------------------------*/
1368 operand *
1369 operandFromLit (double i)
1370 {
1371   return operandFromValue (valueFromLit (i));
1372 }
1373
1374 /*-----------------------------------------------------------------*/
1375 /* operandFromAst - creates an operand from an ast                 */
1376 /*-----------------------------------------------------------------*/
1377 operand *
1378 operandFromAst (ast * tree,int lvl)
1379 {
1380
1381   if (!tree)
1382     return NULL;
1383
1384   /* depending on type do */
1385   switch (tree->type)
1386     {
1387     case EX_OP:
1388       return ast2iCode (tree,lvl+1);
1389       break;
1390
1391     case EX_VALUE:
1392       return operandFromValue (tree->opval.val);
1393       break;
1394
1395     case EX_LINK:
1396       return operandFromLink (tree->opval.lnk);
1397     }
1398
1399   assert (0);
1400   /*  Just to keep the comiler happy */
1401   return (operand *) 0;
1402 }
1403
1404 /*-----------------------------------------------------------------*/
1405 /* setOperandType - sets the operand's type to the given type      */
1406 /*-----------------------------------------------------------------*/
1407 void 
1408 setOperandType (operand * op, sym_link * type)
1409 {
1410   /* depending on the type of operand */
1411   switch (op->type)
1412     {
1413
1414     case VALUE:
1415       op->operand.valOperand->etype =
1416         getSpec (op->operand.valOperand->type =
1417                  copyLinkChain (type));
1418       return;
1419
1420     case SYMBOL:
1421       if (op->operand.symOperand->isitmp)
1422         op->operand.symOperand->etype =
1423           getSpec (op->operand.symOperand->type =
1424                    copyLinkChain (type));
1425       else
1426         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1427                 "attempt to modify type of source");
1428       return;
1429
1430     case TYPE:
1431       op->operand.typeOperand = copyLinkChain (type);
1432       return;
1433     }
1434
1435 }
1436 /*-----------------------------------------------------------------*/
1437 /* Get size in byte of ptr need to access an array                 */
1438 /*-----------------------------------------------------------------*/
1439 int
1440 getArraySizePtr (operand * op)
1441 {
1442   sym_link *ltype = operandType(op);
1443
1444   if(IS_PTR(ltype))
1445     {
1446       int size = getSize(ltype);
1447       return(IS_GENPTR(ltype)?(size-1):size);
1448     }
1449
1450   if(IS_ARRAY(ltype))
1451     {
1452       sym_link *letype = getSpec(ltype);
1453       switch (PTR_TYPE (SPEC_OCLS (letype)))
1454         {
1455         case IPOINTER:
1456         case PPOINTER:
1457         case POINTER:
1458           return (PTRSIZE);
1459         case EEPPOINTER:
1460         case FPOINTER:
1461         case CPOINTER:
1462         case FUNCTION:
1463           return (FPTRSIZE);
1464         case GPOINTER:
1465           return (GPTRSIZE-1);
1466
1467         default:
1468           return (FPTRSIZE);
1469         }
1470     }
1471   return (FPTRSIZE);
1472 }
1473
1474 /*-----------------------------------------------------------------*/
1475 /* perform "usual unary conversions"                               */
1476 /*-----------------------------------------------------------------*/
1477 operand *
1478 usualUnaryConversions (operand * op)
1479 {
1480   if (IS_INTEGRAL (operandType (op)))
1481     {
1482       if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1483         {
1484           /* Widen to int. */
1485           return geniCodeCast (INTTYPE, op, TRUE);
1486         }
1487     }
1488   return op;
1489 }
1490
1491 /*-----------------------------------------------------------------*/
1492 /* perform "usual binary conversions"                              */
1493 /*-----------------------------------------------------------------*/
1494 sym_link *
1495 usualBinaryConversions (operand ** op1, operand ** op2)
1496 {
1497   sym_link *ctype;
1498   sym_link *rtype = operandType (*op2);
1499   sym_link *ltype = operandType (*op1);
1500   
1501   ctype = computeType (ltype, rtype);
1502   *op1 = geniCodeCast (ctype, *op1, TRUE);
1503   *op2 = geniCodeCast (ctype, *op2, TRUE);
1504   
1505   return ctype;
1506 }
1507
1508 /*-----------------------------------------------------------------*/
1509 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1510 /*                          at address                             */
1511 /*-----------------------------------------------------------------*/
1512 operand *
1513 geniCodeRValue (operand * op, bool force)
1514 {
1515   iCode *ic;
1516   sym_link *type = operandType (op);
1517   sym_link *etype = getSpec (type);
1518
1519   /* if this is an array & already */
1520   /* an address then return this   */
1521   if (IS_AGGREGATE (type) ||
1522       (IS_PTR (type) && !force && !op->isaddr))
1523     return operandFromOperand (op);
1524
1525   /* if this is not an address then must be */
1526   /* rvalue already so return this one      */
1527   if (!op->isaddr)
1528     return op;
1529
1530   /* if this is not a temp symbol then */
1531   if (!IS_ITEMP (op) &&
1532       !force &&
1533       !IN_FARSPACE (SPEC_OCLS (etype)))
1534     {
1535       op = operandFromOperand (op);
1536       op->isaddr = 0;
1537       return op;
1538     }
1539
1540   if (IS_SPEC (type) &&
1541       IS_TRUE_SYMOP (op) &&
1542       (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1543       /* TARGET_IS_DS390)) */
1544       (options.model == MODEL_FLAT24) ))
1545     {
1546       op = operandFromOperand (op);
1547       op->isaddr = 0;
1548       return op;
1549     }
1550
1551   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1552   if (IS_PTR (type) && op->isaddr && force)
1553     type = type->next;
1554
1555   type = copyLinkChain (type);
1556
1557   IC_RESULT (ic) = newiTempOperand (type, 1);
1558   IC_RESULT (ic)->isaddr = 0;
1559
1560 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1561
1562   /* if the right is a symbol */
1563   if (op->type == SYMBOL)
1564     IC_RESULT (ic)->operand.symOperand->args =
1565       op->operand.symOperand->args;
1566   ADDTOCHAIN (ic);
1567
1568   return IC_RESULT (ic);
1569 }
1570
1571 /*-----------------------------------------------------------------*/
1572 /* geniCodeCast - changes the value from one type to another       */
1573 /*-----------------------------------------------------------------*/
1574 operand *
1575 geniCodeCast (sym_link * type, operand * op, bool implicit)
1576 {
1577   iCode *ic;
1578   sym_link *optype;
1579   sym_link *opetype = getSpec (optype = operandType (op));
1580   sym_link *restype;
1581   int errors=0;
1582
1583   /* one of them has size zero then error */
1584   if (IS_VOID (optype))
1585     {
1586       werror (E_CAST_ZERO);
1587       return op;
1588     }
1589
1590   /* if the operand is already the desired type then do nothing */
1591   if (compareType (type, optype) == 1)
1592     return op;
1593
1594   /* if this is a literal then just change the type & return */
1595   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1596     return operandFromValue (valCastLiteral (type,
1597                                              operandLitValue (op)));
1598
1599   /* if casting to/from pointers, do some checking */
1600   if (IS_PTR(type)) { // to a pointer
1601     if (!IS_PTR(optype) && !IS_FUNC(optype)) { // from a non pointer
1602       if (IS_INTEGRAL(optype)) { 
1603         // maybe this is NULL, than it's ok.
1604         if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1605           if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1606             // no way to set the storage
1607             if (IS_LITERAL(optype)) {
1608               werror(E_LITERAL_GENERIC);
1609               errors++;
1610             } else {
1611               werror(E_NONPTR2_GENPTR);
1612               errors++;
1613             }
1614           } else if (implicit) {
1615             werror(W_INTEGRAL2PTR_NOCAST);
1616             errors++;
1617           }
1618         }
1619       } else { 
1620         // shouldn't do that with float, array or structure unless to void
1621         if (!IS_VOID(getSpec(type)) && 
1622             !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1623           werror(E_INCOMPAT_TYPES);
1624           errors++;
1625         }
1626       }
1627     } else { // from a pointer to a pointer
1628       if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1629         // if not a pointer to a function
1630         if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1631           if (implicit) { // if not to generic, they have to match 
1632             if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1633               werror(E_INCOMPAT_PTYPES);
1634               errors++;
1635             }
1636           }
1637         }
1638       }
1639     }
1640   } else { // to a non pointer
1641     if (IS_PTR(optype)) { // from a pointer
1642       if (implicit) { // sneaky
1643         if (IS_INTEGRAL(type)) {
1644           werror(W_PTR2INTEGRAL_NOCAST);
1645           errors++;
1646         } else { // shouldn't do that with float, array or structure
1647           werror(E_INCOMPAT_TYPES);
1648           errors++;
1649         }
1650       }
1651     }
1652   }
1653   if (errors) {
1654     /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
1655        implicit?"(implicit)":"", errors); */
1656     fprintf (stderr, "from type '");
1657     printTypeChain (optype, stderr);
1658     fprintf (stderr, "' to type '");
1659     printTypeChain (type, stderr);
1660     fprintf (stderr, "'\n");
1661   }
1662
1663   /* if they are the same size create an assignment */
1664   if (getSize (type) == getSize (optype) &&
1665       !IS_BITFIELD (type) &&
1666       !IS_FLOAT (type) &&
1667       !IS_FLOAT (optype) &&
1668       ((IS_SPEC (type) && IS_SPEC (optype)) ||
1669        (!IS_SPEC (type) && !IS_SPEC (optype))))
1670     {
1671
1672       ic = newiCode ('=', NULL, op);
1673       IC_RESULT (ic) = newiTempOperand (type, 0);
1674       SPIL_LOC (IC_RESULT (ic)) =
1675         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1676       IC_RESULT (ic)->isaddr = 0;
1677     }
1678   else
1679     {
1680       ic = newiCode (CAST, operandFromLink (type),
1681                      geniCodeRValue (op, FALSE));
1682
1683       IC_RESULT (ic) = newiTempOperand (type, 0);
1684     }
1685
1686   /* preserve the storage class & output class */
1687   /* of the original variable                  */
1688   restype = getSpec (operandType (IC_RESULT (ic)));
1689   SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1690   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1691
1692   ADDTOCHAIN (ic);
1693   return IC_RESULT (ic);
1694 }
1695
1696 /*-----------------------------------------------------------------*/
1697 /* geniCodeLabel - will create a Label                             */
1698 /*-----------------------------------------------------------------*/
1699 void 
1700 geniCodeLabel (symbol * label)
1701 {
1702   iCode *ic;
1703
1704   ic = newiCodeLabelGoto (LABEL, label);
1705   ADDTOCHAIN (ic);
1706 }
1707
1708 /*-----------------------------------------------------------------*/
1709 /* geniCodeGoto  - will create a Goto                              */
1710 /*-----------------------------------------------------------------*/
1711 void 
1712 geniCodeGoto (symbol * label)
1713 {
1714   iCode *ic;
1715
1716   ic = newiCodeLabelGoto (GOTO, label);
1717   ADDTOCHAIN (ic);
1718 }
1719
1720 /*-----------------------------------------------------------------*/
1721 /* geniCodeMultiply - gen intermediate code for multiplication     */
1722 /*-----------------------------------------------------------------*/
1723 operand *
1724 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1725 {
1726   iCode *ic;
1727   int p2 = 0;
1728   sym_link *resType;
1729   LRTYPE;
1730
1731   /* if they are both literal then we know the result */
1732   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1733     return operandFromValue (valMult (left->operand.valOperand,
1734                                       right->operand.valOperand));
1735
1736   if (IS_LITERAL(retype)) {
1737     p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1738   }
1739
1740   resType = usualBinaryConversions (&left, &right);
1741 #if 1
1742   rtype = operandType (right);
1743   retype = getSpec (rtype);
1744   ltype = operandType (left);
1745   letype = getSpec (ltype);
1746 #endif
1747   if (resultIsInt)
1748     {
1749       SPEC_NOUN(getSpec(resType))=V_INT;
1750     }
1751
1752   /* if the right is a literal & power of 2 */
1753   /* then make it a left shift              */
1754   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more 
1755      efficient in most cases than 2 bytes result = 2 bytes << literal 
1756      if port has 1 byte muldiv */
1757   if (p2 && !IS_FLOAT (letype) &&
1758       !((resultIsInt) && (getSize (resType) != getSize (ltype)) && 
1759         (port->support.muldiv == 1)))
1760     {
1761       if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1762         {
1763           /* LEFT_OP need same size for left and result, */
1764           left = geniCodeCast (resType, left, TRUE);
1765           ltype = operandType (left);
1766         }
1767       ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1768     }
1769   else
1770     {
1771       ic = newiCode ('*', left, right);         /* normal multiplication */
1772       /* if the size left or right > 1 then support routine */
1773       if (getSize (ltype) > 1 || getSize (rtype) > 1)
1774         ic->supportRtn = 1;
1775
1776     }
1777   IC_RESULT (ic) = newiTempOperand (resType, 1);
1778
1779   ADDTOCHAIN (ic);
1780   return IC_RESULT (ic);
1781 }
1782
1783 /*-----------------------------------------------------------------*/
1784 /* geniCodeDivision - gen intermediate code for division           */
1785 /*-----------------------------------------------------------------*/
1786 operand *
1787 geniCodeDivision (operand * left, operand * right)
1788 {
1789   iCode *ic;
1790   int p2 = 0;
1791   sym_link *resType;
1792   sym_link *rtype = operandType (right);
1793   sym_link *retype = getSpec (rtype);
1794   sym_link *ltype = operandType (left);
1795   sym_link *letype = getSpec (ltype);
1796
1797   resType = usualBinaryConversions (&left, &right);
1798
1799   /* if the right is a literal & power of 2 */
1800   /* then make it a right shift             */
1801   if (IS_LITERAL (retype) &&
1802       !IS_FLOAT (letype) &&
1803       (p2 = powof2 ((unsigned long)
1804                     floatFromVal (right->operand.valOperand)))) {
1805     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1806   }
1807   else
1808     {
1809       ic = newiCode ('/', left, right);         /* normal division */
1810       /* if the size left or right > 1 then support routine */
1811       if (getSize (ltype) > 1 || getSize (rtype) > 1)
1812         ic->supportRtn = 1;
1813     }
1814   IC_RESULT (ic) = newiTempOperand (resType, 0);
1815
1816   ADDTOCHAIN (ic);
1817   return IC_RESULT (ic);
1818 }
1819 /*-----------------------------------------------------------------*/
1820 /* geniCodeModulus  - gen intermediate code for modulus            */
1821 /*-----------------------------------------------------------------*/
1822 operand *
1823 geniCodeModulus (operand * left, operand * right)
1824 {
1825   iCode *ic;
1826   sym_link *resType;
1827   LRTYPE;
1828
1829   /* if they are both literal then we know the result */
1830   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1831     return operandFromValue (valMod (left->operand.valOperand,
1832                                      right->operand.valOperand));
1833
1834   resType = usualBinaryConversions (&left, &right);
1835
1836   /* now they are the same size */
1837   ic = newiCode ('%', left, right);
1838
1839   /* if the size left or right > 1 then support routine */
1840   if (getSize (ltype) > 1 || getSize (rtype) > 1)
1841     ic->supportRtn = 1;
1842   IC_RESULT (ic) = newiTempOperand (resType, 0);
1843
1844   ADDTOCHAIN (ic);
1845   return IC_RESULT (ic);
1846 }
1847
1848 /*-----------------------------------------------------------------*/
1849 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
1850 /*-----------------------------------------------------------------*/
1851 operand *
1852 geniCodePtrPtrSubtract (operand * left, operand * right)
1853 {
1854   iCode *ic;
1855   operand *result;
1856   LRTYPE;
1857
1858   /* if they are both literals then */
1859   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1860     {
1861       result = operandFromValue (valMinus (left->operand.valOperand,
1862                                            right->operand.valOperand));
1863       goto subtractExit;
1864     }
1865
1866   ic = newiCode ('-', left, right);
1867
1868   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1869   ADDTOCHAIN (ic);
1870
1871 subtractExit:
1872   return geniCodeDivision (result,
1873                            operandFromLit (getSize (ltype->next)));
1874 }
1875
1876 /*-----------------------------------------------------------------*/
1877 /* geniCodeSubtract - generates code for subtraction               */
1878 /*-----------------------------------------------------------------*/
1879 operand *
1880 geniCodeSubtract (operand * left, operand * right)
1881 {
1882   iCode *ic;
1883   int isarray = 0;
1884   sym_link *resType;
1885   LRTYPE;
1886
1887   /* if they both pointers then */
1888   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1889       (IS_PTR (rtype) || IS_ARRAY (rtype)))
1890     return geniCodePtrPtrSubtract (left, right);
1891
1892   /* if they are both literal then we know the result */
1893   if (IS_LITERAL (letype) && IS_LITERAL (retype)
1894       && left->isLiteral && right->isLiteral)
1895     return operandFromValue (valMinus (left->operand.valOperand,
1896                                        right->operand.valOperand));
1897
1898   /* if left is an array or pointer */
1899   if (IS_PTR (ltype) || IS_ARRAY (ltype))
1900     {
1901       isarray = left->isaddr;
1902       right = geniCodeMultiply (right,
1903                                 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1904       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1905     }
1906   else
1907     {                           /* make them the same size */
1908       resType = usualBinaryConversions (&left, &right);
1909     }
1910
1911   ic = newiCode ('-', left, right);
1912
1913   IC_RESULT (ic) = newiTempOperand (resType, 1);
1914   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1915
1916   /* if left or right is a float */
1917   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1918     ic->supportRtn = 1;
1919
1920   ADDTOCHAIN (ic);
1921   return IC_RESULT (ic);
1922 }
1923
1924 /*-----------------------------------------------------------------*/
1925 /* geniCodeAdd - generates iCode for addition                      */
1926 /*-----------------------------------------------------------------*/
1927 operand *
1928 geniCodeAdd (operand * left, operand * right,int lvl)
1929 {
1930   iCode *ic;
1931   sym_link *resType;
1932   operand *size;
1933   int isarray = 0;
1934   LRTYPE;
1935
1936   /* if left is an array then array access */
1937   if (IS_ARRAY (ltype))
1938     return geniCodeArray (left, right,lvl);
1939
1940   /* if the right side is LITERAL zero */
1941   /* return the left side              */
1942   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1943     return left;
1944
1945   /* if left is literal zero return right */
1946   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1947     return right;
1948
1949   /* if left is an array or pointer then size */
1950   if (IS_PTR (ltype))
1951     {
1952       isarray = left->isaddr;
1953       // there is no need to multiply with 1
1954       if (getSize(ltype->next)!=1) {
1955         size  = operandFromLit (getSize (ltype->next));
1956         right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1957       }
1958       resType = copyLinkChain (ltype);
1959     }
1960   else
1961     {                           /* make them the same size */
1962       resType = usualBinaryConversions (&left, &right);
1963     }
1964
1965   /* if they are both literals then we know */
1966   if (IS_LITERAL (letype) && IS_LITERAL (retype)
1967       && left->isLiteral && right->isLiteral)
1968     return operandFromValue (valPlus (valFromType (letype),
1969                                       valFromType (retype)));
1970
1971   ic = newiCode ('+', left, right);
1972
1973   IC_RESULT (ic) = newiTempOperand (resType, 1);
1974   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1975
1976   /* if left or right is a float then support
1977      routine */
1978   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1979     ic->supportRtn = 1;
1980
1981   ADDTOCHAIN (ic);
1982
1983   return IC_RESULT (ic);
1984
1985 }
1986
1987 /*-----------------------------------------------------------------*/
1988 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
1989 /*-----------------------------------------------------------------*/
1990 sym_link *
1991 aggrToPtr (sym_link * type, bool force)
1992 {
1993   sym_link *etype;
1994   sym_link *ptype;
1995
1996
1997   if (IS_PTR (type) && !force)
1998     return type;
1999
2000   etype = getSpec (type);
2001   ptype = newLink ();
2002
2003   ptype->next = type;
2004   /* if the output class is generic */
2005   if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2006     DCL_PTR_CONST (ptype) = port->mem.code_ro;
2007
2008   /* if the variable was declared a constant */
2009   /* then the pointer points to a constant */
2010   if (IS_CONSTANT (etype))
2011     DCL_PTR_CONST (ptype) = 1;
2012
2013   /* the variable was volatile then pointer to volatile */
2014   if (IS_VOLATILE (etype))
2015     DCL_PTR_VOLATILE (ptype) = 1;
2016   return ptype;
2017 }
2018
2019 /*-----------------------------------------------------------------*/
2020 /* geniCodeArray2Ptr - array to pointer                            */
2021 /*-----------------------------------------------------------------*/
2022 operand *
2023 geniCodeArray2Ptr (operand * op)
2024 {
2025   sym_link *optype = operandType (op);
2026   sym_link *opetype = getSpec (optype);
2027
2028   /* set the pointer depending on the storage class */
2029   if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2030     DCL_PTR_CONST (optype) = port->mem.code_ro;
2031
2032
2033   /* if the variable was declared a constant */
2034   /* then the pointer points to a constant */
2035   if (IS_CONSTANT (opetype))
2036     DCL_PTR_CONST (optype) = 1;
2037
2038   /* the variable was volatile then pointer to volatile */
2039   if (IS_VOLATILE (opetype))
2040     DCL_PTR_VOLATILE (optype) = 1;
2041   op->isaddr = 0;
2042   return op;
2043 }
2044
2045
2046 /*-----------------------------------------------------------------*/
2047 /* geniCodeArray - array access                                    */
2048 /*-----------------------------------------------------------------*/
2049 operand *
2050 geniCodeArray (operand * left, operand * right,int lvl)
2051 {
2052   iCode *ic;
2053   sym_link *ltype = operandType (left);
2054
2055   if (IS_PTR (ltype))
2056     {
2057       if (IS_PTR (ltype->next) && left->isaddr)
2058         {
2059           left = geniCodeRValue (left, FALSE);
2060         }
2061       return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2062     }
2063
2064   right = geniCodeMultiply (right,
2065                             operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2066
2067   /* we can check for limits here */
2068   if (isOperandLiteral (right) &&
2069       IS_ARRAY (ltype) &&
2070       DCL_ELEM (ltype) &&
2071       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2072     {
2073       werror (E_ARRAY_BOUND);
2074       right = operandFromLit (0);
2075     }
2076
2077   ic = newiCode ('+', left, right);
2078
2079   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2080                                       !IS_AGGREGATE (ltype->next) &&
2081                                       !IS_PTR (ltype->next))
2082                                      ? ltype : ltype->next), 0);
2083
2084   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2085   ADDTOCHAIN (ic);
2086   return IC_RESULT (ic);
2087 }
2088
2089 /*-----------------------------------------------------------------*/
2090 /* geniCodeStruct - generates intermediate code for structres      */
2091 /*-----------------------------------------------------------------*/
2092 operand *
2093 geniCodeStruct (operand * left, operand * right, bool islval)
2094 {
2095   iCode *ic;
2096   sym_link *type = operandType (left);
2097   sym_link *etype = getSpec (type);
2098   sym_link *retype;
2099   symbol *element = getStructElement (SPEC_STRUCT (etype),
2100                                       right->operand.symOperand);
2101
2102   /* add the offset */
2103   ic = newiCode ('+', left, operandFromLit (element->offset));
2104
2105   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2106
2107   /* preserve the storage & output class of the struct */
2108   /* as well as the volatile attribute */
2109   retype = getSpec (operandType (IC_RESULT (ic)));
2110   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2111   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2112   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2113
2114   if (IS_PTR (element->type))
2115     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2116
2117   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2118
2119
2120   ADDTOCHAIN (ic);
2121   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2122 }
2123
2124 /*-----------------------------------------------------------------*/
2125 /* geniCodePostInc - generate int code for Post increment          */
2126 /*-----------------------------------------------------------------*/
2127 operand *
2128 geniCodePostInc (operand * op)
2129 {
2130   iCode *ic;
2131   operand *rOp;
2132   sym_link *optype = operandType (op);
2133   operand *result;
2134   operand *rv = (IS_ITEMP (op) ?
2135                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2136                  op);
2137   sym_link *rvtype = operandType (rv);
2138   int size = 0;
2139
2140   /* if this is not an address we have trouble */
2141   if (!op->isaddr)
2142     {
2143       werror (E_LVALUE_REQUIRED, "++");
2144       return op;
2145     }
2146
2147   rOp = newiTempOperand (rvtype, 0);
2148   OP_SYMBOL(rOp)->noSpilLoc = 1;
2149
2150   if (IS_ITEMP (rv))
2151     OP_SYMBOL(rv)->noSpilLoc = 1;
2152
2153   geniCodeAssign (rOp, rv, 0);
2154
2155   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2156   if (IS_FLOAT (rvtype))
2157     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2158   else
2159     ic = newiCode ('+', rv, operandFromLit (size));
2160
2161   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2162   ADDTOCHAIN (ic);
2163
2164   geniCodeAssign (op, result, 0);
2165
2166   return rOp;
2167
2168 }
2169
2170 /*-----------------------------------------------------------------*/
2171 /* geniCodePreInc - generate code for preIncrement                 */
2172 /*-----------------------------------------------------------------*/
2173 operand *
2174 geniCodePreInc (operand * op)
2175 {
2176   iCode *ic;
2177   sym_link *optype = operandType (op);
2178   operand *rop = (IS_ITEMP (op) ?
2179                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2180                   op);
2181   sym_link *roptype = operandType (rop);
2182   operand *result;
2183   int size = 0;
2184
2185   if (!op->isaddr)
2186     {
2187       werror (E_LVALUE_REQUIRED, "++");
2188       return op;
2189     }
2190
2191
2192   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2193   if (IS_FLOAT (roptype))
2194     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2195   else
2196     ic = newiCode ('+', rop, operandFromLit (size));
2197   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2198   ADDTOCHAIN (ic);
2199
2200
2201   return geniCodeAssign (op, result, 0);
2202 }
2203
2204 /*-----------------------------------------------------------------*/
2205 /* geniCodePostDec - generates code for Post decrement             */
2206 /*-----------------------------------------------------------------*/
2207 operand *
2208 geniCodePostDec (operand * op)
2209 {
2210   iCode *ic;
2211   operand *rOp;
2212   sym_link *optype = operandType (op);
2213   operand *result;
2214   operand *rv = (IS_ITEMP (op) ?
2215                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2216                  op);
2217   sym_link *rvtype = operandType (rv);
2218   int size = 0;
2219
2220   /* if this is not an address we have trouble */
2221   if (!op->isaddr)
2222     {
2223       werror (E_LVALUE_REQUIRED, "--");
2224       return op;
2225     }
2226
2227   rOp = newiTempOperand (rvtype, 0);
2228   OP_SYMBOL(rOp)->noSpilLoc = 1;
2229
2230   if (IS_ITEMP (rv))
2231     OP_SYMBOL(rv)->noSpilLoc = 1;
2232
2233   geniCodeAssign (rOp, rv, 0);
2234
2235   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2236   if (IS_FLOAT (rvtype))
2237     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2238   else
2239     ic = newiCode ('-', rv, operandFromLit (size));
2240
2241   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2242   ADDTOCHAIN (ic);
2243
2244   geniCodeAssign (op, result, 0);
2245
2246   return rOp;
2247
2248 }
2249
2250 /*-----------------------------------------------------------------*/
2251 /* geniCodePreDec - generate code for pre  decrement               */
2252 /*-----------------------------------------------------------------*/
2253 operand *
2254 geniCodePreDec (operand * op)
2255 {
2256   iCode *ic;
2257   sym_link *optype = operandType (op);
2258   operand *rop = (IS_ITEMP (op) ?
2259                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2260                   op);
2261   sym_link *roptype = operandType (rop);
2262   operand *result;
2263   int size = 0;
2264
2265   if (!op->isaddr)
2266     {
2267       werror (E_LVALUE_REQUIRED, "--");
2268       return op;
2269     }
2270
2271
2272   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2273   if (IS_FLOAT (roptype))
2274     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2275   else
2276     ic = newiCode ('-', rop, operandFromLit (size));
2277   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2278   ADDTOCHAIN (ic);
2279
2280
2281   return geniCodeAssign (op, result, 0);
2282 }
2283
2284
2285 /*-----------------------------------------------------------------*/
2286 /* geniCodeBitwise - gen int code for bitWise  operators           */
2287 /*-----------------------------------------------------------------*/
2288 operand *
2289 geniCodeBitwise (operand * left, operand * right,
2290                  int oper, sym_link * resType)
2291 {
2292   iCode *ic;
2293
2294   left = geniCodeCast (resType, left, TRUE);
2295   right = geniCodeCast (resType, right, TRUE);
2296
2297   ic = newiCode (oper, left, right);
2298   IC_RESULT (ic) = newiTempOperand (resType, 0);
2299
2300   ADDTOCHAIN (ic);
2301   return IC_RESULT (ic);
2302 }
2303
2304 /*-----------------------------------------------------------------*/
2305 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2306 /*-----------------------------------------------------------------*/
2307 operand *
2308 geniCodeAddressOf (operand * op)
2309 {
2310   iCode *ic;
2311   sym_link *p;
2312   sym_link *optype = operandType (op);
2313   sym_link *opetype = getSpec (optype);
2314
2315   /* lvalue check already done in decorateType */
2316   /* this must be a lvalue */
2317 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2318 /*  werror (E_LVALUE_REQUIRED,"&"); */
2319 /*  return op; */
2320 /*     } */
2321
2322   p = newLink ();
2323   p->class = DECLARATOR;
2324
2325   /* set the pointer depending on the storage class */
2326   if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2327     DCL_PTR_CONST (p) = port->mem.code_ro;
2328
2329   /* make sure we preserve the const & volatile */
2330   if (IS_CONSTANT (opetype))
2331     DCL_PTR_CONST (p) = 1;
2332
2333   if (IS_VOLATILE (opetype))
2334     DCL_PTR_VOLATILE (p) = 1;
2335
2336   p->next = copyLinkChain (optype);
2337
2338   /* if already a temp */
2339   if (IS_ITEMP (op))
2340     {
2341       setOperandType (op, p);
2342       op->isaddr = 0;
2343       return op;
2344     }
2345
2346   /* other wise make this of the type coming in */
2347   ic = newiCode (ADDRESS_OF, op, NULL);
2348   IC_RESULT (ic) = newiTempOperand (p, 1);
2349   IC_RESULT (ic)->isaddr = 0;
2350   ADDTOCHAIN (ic);
2351   return IC_RESULT (ic);
2352 }
2353 /*-----------------------------------------------------------------*/
2354 /* setOClass - sets the output class depending on the pointer type */
2355 /*-----------------------------------------------------------------*/
2356 void 
2357 setOClass (sym_link * ptr, sym_link * spec)
2358 {
2359   switch (DCL_TYPE (ptr))
2360     {
2361     case POINTER:
2362       SPEC_OCLS (spec) = data;
2363       break;
2364
2365     case GPOINTER:
2366       SPEC_OCLS (spec) = generic;
2367       break;
2368
2369     case FPOINTER:
2370       SPEC_OCLS (spec) = xdata;
2371       break;
2372
2373     case CPOINTER:
2374       SPEC_OCLS (spec) = code;
2375       break;
2376
2377     case IPOINTER:
2378       SPEC_OCLS (spec) = idata;
2379       break;
2380
2381     case PPOINTER:
2382       SPEC_OCLS (spec) = xstack;
2383       break;
2384
2385     case EEPPOINTER:
2386       SPEC_OCLS (spec) = eeprom;
2387       break;
2388
2389     default:
2390       break;
2391
2392     }
2393 }
2394
2395 /*-----------------------------------------------------------------*/
2396 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2397 /*-----------------------------------------------------------------*/
2398 operand *
2399 geniCodeDerefPtr (operand * op,int lvl)
2400 {
2401   sym_link *rtype, *retype;
2402   sym_link *optype = operandType (op);
2403
2404   /* if this is a pointer then generate the rvalue */
2405   if (IS_PTR (optype))
2406     {
2407       if (IS_TRUE_SYMOP (op))
2408         {
2409           op->isaddr = 1;
2410           op = geniCodeRValue (op, TRUE);
2411         }
2412       else
2413         op = geniCodeRValue (op, TRUE);
2414     }
2415
2416   /* now get rid of the pointer part */
2417   if (isLvaluereq(lvl) && IS_ITEMP (op))
2418     {
2419       retype = getSpec (rtype = copyLinkChain (optype));
2420     }
2421   else
2422     {
2423       retype = getSpec (rtype = copyLinkChain (optype->next));
2424     }
2425
2426   /* if this is a pointer then outputclass needs 2b updated */
2427   if (IS_PTR (optype))
2428     setOClass (optype, retype);
2429
2430   op->isGptr = IS_GENPTR (optype);
2431
2432   /* if the pointer was declared as a constant */
2433   /* then we cannot allow assignment to the derefed */
2434   if (IS_PTR_CONST (optype))
2435     SPEC_CONST (retype) = 1;
2436
2437   op->isaddr = (IS_PTR (rtype) ||
2438                 IS_STRUCT (rtype) ||
2439                 IS_INT (rtype) ||
2440                 IS_CHAR (rtype) ||
2441                 IS_FLOAT (rtype));
2442
2443   if (!isLvaluereq(lvl))
2444     op = geniCodeRValue (op, TRUE);
2445
2446   setOperandType (op, rtype);
2447
2448   return op;
2449 }
2450
2451 /*-----------------------------------------------------------------*/
2452 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2453 /*-----------------------------------------------------------------*/
2454 operand *
2455 geniCodeUnaryMinus (operand * op)
2456 {
2457   iCode *ic;
2458   sym_link *optype = operandType (op);
2459
2460   if (IS_LITERAL (optype))
2461     return operandFromLit (-floatFromVal (op->operand.valOperand));
2462
2463   ic = newiCode (UNARYMINUS, op, NULL);
2464   IC_RESULT (ic) = newiTempOperand (optype, 0);
2465   ADDTOCHAIN (ic);
2466   return IC_RESULT (ic);
2467 }
2468
2469 /*-----------------------------------------------------------------*/
2470 /* geniCodeLeftShift - gen i code for left shift                   */
2471 /*-----------------------------------------------------------------*/
2472 operand *
2473 geniCodeLeftShift (operand * left, operand * right)
2474 {
2475   iCode *ic;
2476
2477   ic = newiCode (LEFT_OP, left, right);
2478   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2479   ADDTOCHAIN (ic);
2480   return IC_RESULT (ic);
2481 }
2482
2483 /*-----------------------------------------------------------------*/
2484 /* geniCodeRightShift - gen i code for right shift                 */
2485 /*-----------------------------------------------------------------*/
2486 operand *
2487 geniCodeRightShift (operand * left, operand * right)
2488 {
2489   iCode *ic;
2490
2491   ic = newiCode (RIGHT_OP, left, right);
2492   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2493   ADDTOCHAIN (ic);
2494   return IC_RESULT (ic);
2495 }
2496
2497 /*-----------------------------------------------------------------*/
2498 /* geniCodeLogic- logic code                                       */
2499 /*-----------------------------------------------------------------*/
2500 operand *
2501 geniCodeLogic (operand * left, operand * right, int op)
2502 {
2503   iCode *ic;
2504   sym_link *ctype;
2505   sym_link *rtype = operandType (right);
2506   sym_link *ltype = operandType (left);
2507
2508   /* left is integral type and right is literal then
2509      check if the literal value is within bounds */
2510   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2511     {
2512       checkConstantRange(ltype, 
2513                          OP_VALUE(right), "compare operation", 1);
2514     }
2515
2516   ctype = usualBinaryConversions (&left, &right);
2517
2518   ic = newiCode (op, left, right);
2519   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2520
2521   /* if comparing float
2522      and not a '==' || '!=' || '&&' || '||' (these
2523      will be inlined */
2524   if (IS_FLOAT(ctype) &&
2525       op != EQ_OP &&
2526       op != NE_OP &&
2527       op != AND_OP &&
2528       op != OR_OP)
2529     ic->supportRtn = 1;
2530
2531   ADDTOCHAIN (ic);
2532   return IC_RESULT (ic);
2533 }
2534
2535 /*-----------------------------------------------------------------*/
2536 /* geniCodeUnary - for a a generic unary operation                 */
2537 /*-----------------------------------------------------------------*/
2538 operand *
2539 geniCodeUnary (operand * op, int oper)
2540 {
2541   iCode *ic = newiCode (oper, op, NULL);
2542
2543   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2544   ADDTOCHAIN (ic);
2545   return IC_RESULT (ic);
2546 }
2547
2548 /*-----------------------------------------------------------------*/
2549 /* geniCodeConditional - geniCode for '?' ':' operation            */
2550 /*-----------------------------------------------------------------*/
2551 operand *
2552 geniCodeConditional (ast * tree,int lvl)
2553 {
2554   iCode *ic;
2555   symbol *falseLabel = newiTempLabel (NULL);
2556   symbol *exitLabel = newiTempLabel (NULL);
2557   operand *cond = ast2iCode (tree->left,lvl+1);
2558   operand *true, *false, *result;
2559
2560   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2561                           NULL, falseLabel);
2562   ADDTOCHAIN (ic);
2563
2564   true = ast2iCode (tree->right->left,lvl+1);
2565
2566   /* move the value to a new Operand */
2567   result = newiTempOperand (operandType (true), 0);
2568   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2569
2570   /* generate an unconditional goto */
2571   geniCodeGoto (exitLabel);
2572
2573   /* now for the right side */
2574   geniCodeLabel (falseLabel);
2575
2576   false = ast2iCode (tree->right->right,lvl+1);
2577   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2578
2579   /* create the exit label */
2580   geniCodeLabel (exitLabel);
2581
2582   return result;
2583 }
2584
2585 /*-----------------------------------------------------------------*/
2586 /* geniCodeAssign - generate code for assignment                   */
2587 /*-----------------------------------------------------------------*/
2588 operand *
2589 geniCodeAssign (operand * left, operand * right, int nosupdate)
2590 {
2591   iCode *ic;
2592   sym_link *ltype = operandType (left);
2593   sym_link *rtype = operandType (right);
2594
2595   if (!left->isaddr && !IS_ITEMP (left))
2596     {
2597       werror (E_LVALUE_REQUIRED, "assignment");
2598       return left;
2599     }
2600
2601   /* left is integral type and right is literal then
2602      check if the literal value is within bounds */
2603   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2604     {
2605       checkConstantRange(ltype, 
2606                          OP_VALUE(right), "= operation", 0);
2607     }
2608
2609   /* if the left & right type don't exactly match */
2610   /* if pointer set then make sure the check is
2611      done with the type & not the pointer */
2612   /* then cast rights type to left */
2613
2614   /* first check the type for pointer assignement */
2615   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2616       compareType (ltype, rtype) < 0)
2617     {
2618       if (compareType (ltype->next, rtype) < 0)
2619         right = geniCodeCast (ltype->next, right, TRUE);
2620     }
2621   else if (compareType (ltype, rtype) < 0)
2622     right = geniCodeCast (ltype, right, TRUE);
2623
2624   /* if left is a true symbol & ! volatile
2625      create an assignment to temporary for
2626      the right & then assign this temporary
2627      to the symbol this is SSA . isn't it simple
2628      and folks have published mountains of paper on it */
2629   if (IS_TRUE_SYMOP (left) &&
2630       !isOperandVolatile (left, FALSE) &&
2631       isOperandGlobal (left))
2632     {
2633       symbol *sym = NULL;
2634
2635       if (IS_TRUE_SYMOP (right))
2636         sym = OP_SYMBOL (right);
2637       ic = newiCode ('=', NULL, right);
2638       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2639       SPIL_LOC (right) = sym;
2640       ADDTOCHAIN (ic);
2641     }
2642
2643   ic = newiCode ('=', NULL, right);
2644   IC_RESULT (ic) = left;
2645   ADDTOCHAIN (ic);
2646
2647   /* if left isgptr flag is set then support
2648      routine will be required */
2649   if (left->isGptr)
2650     ic->supportRtn = 1;
2651
2652   ic->nosupdate = nosupdate;
2653   return left;
2654 }
2655
2656 /*-----------------------------------------------------------------*/
2657 /* geniCodeSEParms - generate code for side effecting fcalls       */
2658 /*-----------------------------------------------------------------*/
2659 static void 
2660 geniCodeSEParms (ast * parms,int lvl)
2661 {
2662   if (!parms)
2663     return;
2664
2665   if (parms->type == EX_OP && parms->opval.op == PARAM)
2666     {
2667       geniCodeSEParms (parms->left,lvl);
2668       geniCodeSEParms (parms->right,lvl);
2669       return;
2670     }
2671
2672   /* hack don't like this but too lazy to think of
2673      something better */
2674   if (IS_ADDRESS_OF_OP (parms))
2675     parms->left->lvalue = 1;
2676
2677   if (IS_CAST_OP (parms) &&
2678       IS_PTR (parms->ftype) &&
2679       IS_ADDRESS_OF_OP (parms->right))
2680     parms->right->left->lvalue = 1;
2681
2682   parms->opval.oprnd =
2683     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2684
2685   parms->type = EX_OPERAND;
2686 }
2687
2688 /*-----------------------------------------------------------------*/
2689 /* geniCodeParms - generates parameters                            */
2690 /*-----------------------------------------------------------------*/
2691 static void 
2692 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2693 {
2694   iCode *ic;
2695   operand *pval;
2696
2697   if (!parms)
2698     return;
2699
2700   /* if this is a param node then do the left & right */
2701   if (parms->type == EX_OP && parms->opval.op == PARAM)
2702     {
2703       geniCodeParms (parms->left, stack, fetype, func,lvl);
2704       geniCodeParms (parms->right, stack, fetype, func,lvl);
2705       return;
2706     }
2707
2708   /* get the parameter value */
2709   if (parms->type == EX_OPERAND)
2710     pval = parms->opval.oprnd;
2711   else
2712     {
2713       /* maybe this else should go away ?? */
2714       /* hack don't like this but too lazy to think of
2715          something better */
2716       if (IS_ADDRESS_OF_OP (parms))
2717         parms->left->lvalue = 1;
2718
2719       if (IS_CAST_OP (parms) &&
2720           IS_PTR (parms->ftype) &&
2721           IS_ADDRESS_OF_OP (parms->right))
2722         parms->right->left->lvalue = 1;
2723
2724       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2725     }
2726
2727   /* if register parm then make it a send */
2728   if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2729        IS_REGPARM (parms->etype)) && !func->hasVargs)
2730     {
2731       ic = newiCode (SEND, pval, NULL);
2732       ADDTOCHAIN (ic);
2733     }
2734   else
2735     {
2736       /* now decide whether to push or assign */
2737       if (!(options.stackAuto || IS_RENT (fetype)))
2738         {
2739
2740           /* assign */
2741           operand *top = operandFromSymbol (parms->argSym);
2742           geniCodeAssign (top, pval, 1);
2743         }
2744       else
2745         {
2746           sym_link *p = operandType (pval);
2747           /* push */
2748           ic = newiCode (IPUSH, pval, NULL);
2749           ic->parmPush = 1;
2750           /* update the stack adjustment */
2751           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2752           ADDTOCHAIN (ic);
2753         }
2754     }
2755
2756 }
2757
2758 /*-----------------------------------------------------------------*/
2759 /* geniCodeCall - generates temp code for calling                  */
2760 /*-----------------------------------------------------------------*/
2761 operand *
2762 geniCodeCall (operand * left, ast * parms,int lvl)
2763 {
2764   iCode *ic;
2765   operand *result;
2766   sym_link *type, *etype;
2767   int stack = 0;
2768
2769   if (!IS_FUNC(OP_SYMBOL(left)->type) && 
2770       !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2771     werror (E_FUNCTION_EXPECTED);
2772     return NULL;
2773   }
2774
2775   /* take care of parameters with side-effecting
2776      function calls in them, this is required to take care
2777      of overlaying function parameters */
2778   geniCodeSEParms (parms,lvl);
2779
2780   /* first the parameters */
2781   geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2782
2783   /* now call : if symbol then pcall */
2784   if (IS_OP_POINTER (left) || IS_ITEMP(left))
2785     ic = newiCode (PCALL, left, NULL);
2786   else
2787     ic = newiCode (CALL, left, NULL);
2788
2789   IC_ARGS (ic) = left->operand.symOperand->args;
2790   type = copyLinkChain (operandType (left)->next);
2791   etype = getSpec (type);
2792   SPEC_EXTR (etype) = 0;
2793   IC_RESULT (ic) = result = newiTempOperand (type, 1);
2794
2795   ADDTOCHAIN (ic);
2796
2797   /* stack adjustment after call */
2798   ic->parmBytes = stack;
2799
2800   return result;
2801 }
2802
2803 /*-----------------------------------------------------------------*/
2804 /* geniCodeReceive - generate intermediate code for "receive"      */
2805 /*-----------------------------------------------------------------*/
2806 static void 
2807 geniCodeReceive (value * args)
2808 {
2809   /* for all arguments that are passed in registers */
2810   while (args)
2811     {
2812
2813       if (IS_REGPARM (args->etype))
2814         {
2815           operand *opr = operandFromValue (args);
2816           operand *opl;
2817           symbol *sym = OP_SYMBOL (opr);
2818           iCode *ic;
2819
2820           /* we will use it after all optimizations
2821              and before liveRange calculation */
2822           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2823             {
2824
2825               if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2826                   options.stackAuto == 0 &&
2827                   /* !TARGET_IS_DS390) */
2828                   (!(options.model == MODEL_FLAT24)) )
2829                 {
2830                 }
2831               else
2832                 {
2833                   opl = newiTempOperand (args->type, 0);
2834                   sym->reqv = opl;
2835                   sym->reqv->key = sym->key;
2836                   OP_SYMBOL (sym->reqv)->key = sym->key;
2837                   OP_SYMBOL (sym->reqv)->isreqv = 1;
2838                   OP_SYMBOL (sym->reqv)->islocal = 0;
2839                   SPIL_LOC (sym->reqv) = sym;
2840                 }
2841             }
2842
2843           ic = newiCode (RECEIVE, NULL, NULL);
2844           currFunc->recvSize = getSize (sym->etype);
2845           IC_RESULT (ic) = opr;
2846           ADDTOCHAIN (ic);
2847         }
2848
2849       args = args->next;
2850     }
2851 }
2852
2853 /*-----------------------------------------------------------------*/
2854 /* geniCodeFunctionBody - create the function body                 */
2855 /*-----------------------------------------------------------------*/
2856 void 
2857 geniCodeFunctionBody (ast * tree,int lvl)
2858 {
2859   iCode *ic;
2860   operand *func;
2861   sym_link *fetype;
2862   int savelineno;
2863
2864   /* reset the auto generation */
2865   /* numbers */
2866   iTempNum = 0;
2867   iTempLblNum = 0;
2868   operandKey = 0;
2869   iCodeKey = 0;
2870   func = ast2iCode (tree->left,lvl+1);
2871   fetype = getSpec (operandType (func));
2872
2873   savelineno = lineno;
2874   lineno = OP_SYMBOL (func)->lineDef;
2875   /* create an entry label */
2876   geniCodeLabel (entryLabel);
2877   lineno = savelineno;
2878
2879   /* create a proc icode */
2880   ic = newiCode (FUNCTION, func, NULL);
2881   /* if the function has parmas   then */
2882   /* save the parameters information    */
2883   ic->argLabel.args = tree->values.args;
2884   ic->lineno = OP_SYMBOL (func)->lineDef;
2885
2886   ADDTOCHAIN (ic);
2887
2888   /* for all parameters that are passed
2889      on registers add a "receive" */
2890   geniCodeReceive (tree->values.args);
2891
2892   /* generate code for the body */
2893   ast2iCode (tree->right,lvl+1);
2894
2895   /* create a label for return */
2896   geniCodeLabel (returnLabel);
2897
2898   /* now generate the end proc */
2899   ic = newiCode (ENDFUNCTION, func, NULL);
2900   ADDTOCHAIN (ic);
2901   return;
2902 }
2903
2904 /*-----------------------------------------------------------------*/
2905 /* geniCodeReturn - gen icode for 'return' statement               */
2906 /*-----------------------------------------------------------------*/
2907 void 
2908 geniCodeReturn (operand * op)
2909 {
2910   iCode *ic;
2911
2912   /* if the operand is present force an rvalue */
2913   if (op)
2914     op = geniCodeRValue (op, FALSE);
2915
2916   ic = newiCode (RETURN, op, NULL);
2917   ADDTOCHAIN (ic);
2918 }
2919
2920 /*-----------------------------------------------------------------*/
2921 /* geniCodeIfx - generates code for extended if statement          */
2922 /*-----------------------------------------------------------------*/
2923 void 
2924 geniCodeIfx (ast * tree,int lvl)
2925 {
2926   iCode *ic;
2927   operand *condition = ast2iCode (tree->left,lvl+1);
2928   sym_link *cetype;
2929
2930   /* if condition is null then exit */
2931   if (!condition)
2932     goto exit;
2933   else
2934     condition = geniCodeRValue (condition, FALSE);
2935
2936   cetype = getSpec (operandType (condition));
2937   /* if the condition is a literal */
2938   if (IS_LITERAL (cetype))
2939     {
2940       if (floatFromVal (condition->operand.valOperand))
2941         {
2942           if (tree->trueLabel)
2943             geniCodeGoto (tree->trueLabel);
2944           else
2945             assert (1);
2946         }
2947       else
2948         {
2949           if (tree->falseLabel)
2950             geniCodeGoto (tree->falseLabel);
2951           else
2952             assert (1);
2953         }
2954       goto exit;
2955     }
2956
2957   if (tree->trueLabel)
2958     {
2959       ic = newiCodeCondition (condition,
2960                               tree->trueLabel,
2961                               NULL);
2962       ADDTOCHAIN (ic);
2963
2964       if (tree->falseLabel)
2965         geniCodeGoto (tree->falseLabel);
2966     }
2967   else
2968     {
2969       ic = newiCodeCondition (condition,
2970                               NULL,
2971                               tree->falseLabel);
2972       ADDTOCHAIN (ic);
2973     }
2974
2975 exit:
2976   ast2iCode (tree->right,lvl+1);
2977 }
2978
2979 /*-----------------------------------------------------------------*/
2980 /* geniCodeJumpTable - tries to create a jump table for switch     */
2981 /*-----------------------------------------------------------------*/
2982 int 
2983 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2984 {
2985   int min = 0, max = 0, t, cnt = 0;
2986   value *vch;
2987   iCode *ic;
2988   operand *boundary;
2989   symbol *falseLabel;
2990   set *labels = NULL;
2991
2992   if (!tree || !caseVals)
2993     return 0;
2994
2995   /* the criteria for creating a jump table is */
2996   /* all integer numbers between the maximum & minimum must */
2997   /* be present , the maximum value should not exceed 255 */
2998   min = max = (int) floatFromVal (vch = caseVals);
2999   sprintf (buffer, "_case_%d_%d",
3000            tree->values.switchVals.swNum,
3001            min);
3002   addSet (&labels, newiTempLabel (buffer));
3003
3004   /* if there is only one case value then no need */
3005   if (!(vch = vch->next))
3006     return 0;
3007
3008   while (vch)
3009     {
3010       if (((t = (int) floatFromVal (vch)) - max) != 1)
3011         return 0;
3012       sprintf (buffer, "_case_%d_%d",
3013                tree->values.switchVals.swNum,
3014                t);
3015       addSet (&labels, newiTempLabel (buffer));
3016       max = t;
3017       cnt++;
3018       vch = vch->next;
3019     }
3020
3021   /* if the number of case statements <= 2 then */
3022   /* it is not economical to create the jump table */
3023   /* since two compares are needed for boundary conditions */
3024   if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3025     return 0;
3026
3027   if (tree->values.switchVals.swDefault)
3028     sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3029   else
3030     sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3031
3032   falseLabel = newiTempLabel (buffer);
3033
3034   /* so we can create a jumptable */
3035   /* first we rule out the boundary conditions */
3036   /* if only optimization says so */
3037   if (!optimize.noJTabBoundary)
3038     {
3039       sym_link *cetype = getSpec (operandType (cond));
3040       /* no need to check the lower bound if
3041          the condition is unsigned & minimum value is zero */
3042       if (!(min == 0 && SPEC_USIGN (cetype)))
3043         {
3044           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3045           ic = newiCodeCondition (boundary, falseLabel, NULL);
3046           ADDTOCHAIN (ic);
3047         }
3048
3049       /* now for upper bounds */
3050       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3051       ic = newiCodeCondition (boundary, falseLabel, NULL);
3052       ADDTOCHAIN (ic);
3053     }
3054
3055   /* if the min is not zero then we no make it zero */
3056   if (min)
3057     {
3058       cond = geniCodeSubtract (cond, operandFromLit (min));
3059       setOperandType (cond, UCHARTYPE);
3060     }
3061
3062   /* now create the jumptable */
3063   ic = newiCode (JUMPTABLE, NULL, NULL);
3064   IC_JTCOND (ic) = cond;
3065   IC_JTLABELS (ic) = labels;
3066   ADDTOCHAIN (ic);
3067   return 1;
3068 }
3069
3070 /*-----------------------------------------------------------------*/
3071 /* geniCodeSwitch - changes a switch to a if statement             */
3072 /*-----------------------------------------------------------------*/
3073 void 
3074 geniCodeSwitch (ast * tree,int lvl)
3075 {
3076   iCode *ic;
3077   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3078   value *caseVals = tree->values.switchVals.swVals;
3079   symbol *trueLabel, *falseLabel;
3080
3081   /* if we can make this a jump table */
3082   if (geniCodeJumpTable (cond, caseVals, tree))
3083     goto jumpTable;             /* no need for the comparison */
3084
3085   /* for the cases defined do */
3086   while (caseVals)
3087     {
3088
3089       operand *compare = geniCodeLogic (cond,
3090                                         operandFromValue (caseVals),
3091                                         EQ_OP);
3092
3093       sprintf (buffer, "_case_%d_%d",
3094                tree->values.switchVals.swNum,
3095                (int) floatFromVal (caseVals));
3096       trueLabel = newiTempLabel (buffer);
3097
3098       ic = newiCodeCondition (compare, trueLabel, NULL);
3099       ADDTOCHAIN (ic);
3100       caseVals = caseVals->next;
3101     }
3102
3103
3104
3105   /* if default is present then goto break else break */
3106   if (tree->values.switchVals.swDefault)
3107     sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3108   else
3109     sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3110
3111   falseLabel = newiTempLabel (buffer);
3112   geniCodeGoto (falseLabel);
3113
3114 jumpTable:
3115   ast2iCode (tree->right,lvl+1);
3116 }
3117
3118 /*-----------------------------------------------------------------*/
3119 /* geniCodeInline - intermediate code for inline assembler         */
3120 /*-----------------------------------------------------------------*/
3121 static void 
3122 geniCodeInline (ast * tree)
3123 {
3124   iCode *ic;
3125
3126   ic = newiCode (INLINEASM, NULL, NULL);
3127   IC_INLINE (ic) = tree->values.inlineasm;
3128   ADDTOCHAIN (ic);
3129 }
3130
3131 /*-----------------------------------------------------------------*/
3132 /* geniCodeArrayInit - intermediate code for array initializer     */
3133 /*-----------------------------------------------------------------*/
3134 static void 
3135 geniCodeArrayInit (ast * tree, operand *array)
3136 {
3137   iCode *ic;
3138
3139   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3140     ic = newiCode (ARRAYINIT, array, NULL);
3141     IC_ARRAYILIST (ic) = tree->values.constlist;
3142   } else {
3143     operand *left=newOperand(), *right=newOperand();
3144     left->type=right->type=SYMBOL;
3145     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3146     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3147     ic = newiCode (ARRAYINIT, left, right);
3148   }
3149   ADDTOCHAIN (ic);
3150 }
3151
3152 /*-----------------------------------------------------------------*/
3153 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3154 /* particular case. Ie : assigning or dereferencing array or ptr   */
3155 /*-----------------------------------------------------------------*/
3156 set * lvaluereqSet = NULL;
3157 typedef struct lvalItem
3158   {
3159     int req;
3160     int lvl;
3161   }
3162 lvalItem;
3163
3164 /*-----------------------------------------------------------------*/
3165 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3166 /*-----------------------------------------------------------------*/
3167 void addLvaluereq(int lvl)
3168 {
3169   lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3170   lpItem->req=1;
3171   lpItem->lvl=lvl;
3172   addSetHead(&lvaluereqSet,lpItem);
3173
3174 }
3175 /*-----------------------------------------------------------------*/
3176 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3177 /*-----------------------------------------------------------------*/
3178 void delLvaluereq()
3179 {
3180   lvalItem * lpItem;
3181   lpItem = getSet(&lvaluereqSet);
3182   if(lpItem) free(lpItem);
3183 }
3184 /*-----------------------------------------------------------------*/
3185 /* clearLvaluereq - clear lvalreq flag                             */
3186 /*-----------------------------------------------------------------*/
3187 void clearLvaluereq()
3188 {
3189   lvalItem * lpItem;
3190   lpItem = peekSet(lvaluereqSet);
3191   if(lpItem) lpItem->req = 0;
3192 }
3193 /*-----------------------------------------------------------------*/
3194 /* getLvaluereq - get the last lvalreq level                       */
3195 /*-----------------------------------------------------------------*/
3196 int getLvaluereqLvl()
3197 {
3198   lvalItem * lpItem;
3199   lpItem = peekSet(lvaluereqSet);
3200   if(lpItem) return lpItem->lvl;
3201   return 0;
3202 }
3203 /*-----------------------------------------------------------------*/
3204 /* isLvaluereq - is lvalreq valid for this level ?                 */
3205 /*-----------------------------------------------------------------*/
3206 int isLvaluereq(int lvl)
3207 {
3208   lvalItem * lpItem;
3209   lpItem = peekSet(lvaluereqSet);
3210   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3211   return 0;
3212 }
3213
3214 /*-----------------------------------------------------------------*/
3215 /* ast2iCode - creates an icodeList from an ast                    */
3216 /*-----------------------------------------------------------------*/
3217 operand *
3218 ast2iCode (ast * tree,int lvl)
3219 {
3220   operand *left = NULL;
3221   operand *right = NULL;
3222   if (!tree)
3223     return NULL;
3224   /* set the global variables for filename & line number */
3225   if (tree->filename)
3226     filename = tree->filename;
3227   if (tree->lineno)
3228     lineno = tree->lineno;
3229   if (tree->block)
3230     block = tree->block;
3231   if (tree->level)
3232     scopeLevel = tree->level;
3233
3234   if (tree->type == EX_VALUE)
3235     return operandFromValue (tree->opval.val);
3236
3237   if (tree->type == EX_LINK)
3238     return operandFromLink (tree->opval.lnk);
3239
3240   /* if we find a nullop */
3241   if (tree->type == EX_OP &&
3242      (tree->opval.op == NULLOP ||
3243      tree->opval.op == BLOCK))
3244     {
3245       ast2iCode (tree->left,lvl+1);
3246       ast2iCode (tree->right,lvl+1);
3247       return NULL;
3248     }
3249
3250   /* special cases for not evaluating */
3251   if (tree->opval.op != ':' &&
3252       tree->opval.op != '?' &&
3253       tree->opval.op != CALL &&
3254       tree->opval.op != IFX &&
3255       tree->opval.op != LABEL &&
3256       tree->opval.op != GOTO &&
3257       tree->opval.op != SWITCH &&
3258       tree->opval.op != FUNCTION &&
3259       tree->opval.op != INLINEASM)
3260     {
3261
3262         if (IS_ASSIGN_OP (tree->opval.op) ||
3263            IS_DEREF_OP (tree) ||
3264            (tree->opval.op == '&' && !tree->right) ||
3265            tree->opval.op == PTR_OP)
3266           {
3267             addLvaluereq(lvl);
3268             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3269                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3270               clearLvaluereq();
3271
3272             left = operandFromAst (tree->left,lvl);
3273             delLvaluereq();
3274             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3275               left = geniCodeRValue (left, TRUE);
3276           }
3277         else
3278           {
3279             left = operandFromAst (tree->left,lvl);
3280           }
3281         if (tree->opval.op == INC_OP ||
3282             tree->opval.op == DEC_OP)
3283           {
3284             addLvaluereq(lvl);
3285             right = operandFromAst (tree->right,lvl);
3286             delLvaluereq();
3287           }
3288         else
3289           {
3290             right = operandFromAst (tree->right,lvl);
3291           }
3292       }
3293
3294   /* now depending on the type of operand */
3295   /* this will be a biggy                 */
3296   switch (tree->opval.op)
3297     {
3298
3299     case '[':                   /* array operation */
3300       {
3301         //sym_link *ltype = operandType (left);
3302         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3303         left = geniCodeRValue (left, FALSE);
3304         right = geniCodeRValue (right, TRUE);
3305       }
3306
3307       return geniCodeArray (left, right,lvl);
3308
3309     case '.':                   /* structure dereference */
3310       if (IS_PTR (operandType (left)))
3311         left = geniCodeRValue (left, TRUE);
3312       else
3313         left = geniCodeRValue (left, FALSE);
3314
3315       return geniCodeStruct (left, right, tree->lvalue);
3316
3317     case PTR_OP:                /* structure pointer dereference */
3318       {
3319         sym_link *pType;
3320         pType = operandType (left);
3321         left = geniCodeRValue (left, TRUE);
3322
3323         setOClass (pType, getSpec (operandType (left)));
3324       }
3325
3326       return geniCodeStruct (left, right, tree->lvalue);
3327
3328     case INC_OP:                /* increment operator */
3329       if (left)
3330         return geniCodePostInc (left);
3331       else
3332         return geniCodePreInc (right);
3333
3334     case DEC_OP:                /* decrement operator */
3335       if (left)
3336         return geniCodePostDec (left);
3337       else
3338         return geniCodePreDec (right);
3339
3340     case '&':                   /* bitwise and or address of operator */
3341       if (right)
3342         {                       /* this is a bitwise operator   */
3343           left = geniCodeRValue (left, FALSE);
3344           right = geniCodeRValue (right, FALSE);
3345           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3346         }
3347       else
3348         return geniCodeAddressOf (left);
3349
3350     case '|':                   /* bitwise or & xor */
3351     case '^':
3352       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3353                               geniCodeRValue (right, FALSE),
3354                               tree->opval.op,
3355                               tree->ftype);
3356
3357     case '/':
3358       return geniCodeDivision (geniCodeRValue (left, FALSE),
3359                                geniCodeRValue (right, FALSE));
3360
3361     case '%':
3362       return geniCodeModulus (geniCodeRValue (left, FALSE),
3363                               geniCodeRValue (right, FALSE));
3364     case '*':
3365       if (right)
3366         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3367                                  geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3368       else
3369         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3370
3371     case '-':
3372       if (right)
3373         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3374                                  geniCodeRValue (right, FALSE));
3375       else
3376         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3377
3378     case '+':
3379       if (right)
3380         return geniCodeAdd (geniCodeRValue (left, FALSE),
3381                             geniCodeRValue (right, FALSE),lvl);
3382       else
3383         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3384
3385     case LEFT_OP:
3386       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3387                                 geniCodeRValue (right, FALSE));
3388
3389     case RIGHT_OP:
3390       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3391                                  geniCodeRValue (right, FALSE));
3392     case CAST:
3393       return geniCodeCast (operandType (left),
3394                            geniCodeRValue (right, FALSE), FALSE);
3395
3396     case '~':
3397     case '!':
3398     case RRC:
3399     case RLC:
3400       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3401
3402     case GETHBIT:
3403       {
3404         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3405         setOperandType (op, UCHARTYPE);
3406         return op;
3407       }
3408     case '>':
3409     case '<':
3410     case LE_OP:
3411     case GE_OP:
3412     case EQ_OP:
3413     case NE_OP:
3414     case AND_OP:
3415     case OR_OP:
3416       return geniCodeLogic (geniCodeRValue (left, FALSE),
3417                             geniCodeRValue (right, FALSE),
3418                             tree->opval.op);
3419     case '?':
3420       return geniCodeConditional (tree,lvl);
3421
3422     case SIZEOF:
3423       return operandFromLit (getSize (tree->right->ftype));
3424
3425     case '=':
3426       {
3427         sym_link *rtype = operandType (right);
3428         sym_link *ltype = operandType (left);
3429         if (IS_PTR (rtype) && IS_ITEMP (right)
3430             && right->isaddr && compareType (rtype->next, ltype) == 1)
3431           right = geniCodeRValue (right, TRUE);
3432         else
3433           right = geniCodeRValue (right, FALSE);
3434
3435         geniCodeAssign (left, right, 0);
3436         return right;
3437       }
3438     case MUL_ASSIGN:
3439       return
3440         geniCodeAssign (left,
3441                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3442                                                   FALSE),
3443                                   geniCodeRValue (right, FALSE),FALSE), 0);
3444
3445     case DIV_ASSIGN:
3446       return
3447         geniCodeAssign (left,
3448                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3449                                                   FALSE),
3450                                   geniCodeRValue (right, FALSE)), 0);
3451     case MOD_ASSIGN:
3452       return
3453         geniCodeAssign (left,
3454                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3455                                                   FALSE),
3456                                   geniCodeRValue (right, FALSE)), 0);
3457     case ADD_ASSIGN:
3458       {
3459         sym_link *rtype = operandType (right);
3460         sym_link *ltype = operandType (left);
3461         if (IS_PTR (rtype) && IS_ITEMP (right)
3462             && right->isaddr && compareType (rtype->next, ltype) == 1)
3463           right = geniCodeRValue (right, TRUE);
3464         else
3465           right = geniCodeRValue (right, FALSE);
3466
3467
3468         return geniCodeAssign (left,
3469                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3470                                                   FALSE),
3471                                   right,lvl), 0);
3472       }
3473     case SUB_ASSIGN:
3474       {
3475         sym_link *rtype = operandType (right);
3476         sym_link *ltype = operandType (left);
3477         if (IS_PTR (rtype) && IS_ITEMP (right)
3478             && right->isaddr && compareType (rtype->next, ltype) == 1)
3479           {
3480             right = geniCodeRValue (right, TRUE);
3481           }
3482         else
3483           {
3484             right = geniCodeRValue (right, FALSE);
3485           }
3486         return
3487           geniCodeAssign (left,
3488                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3489                                                   FALSE),
3490                                   right), 0);
3491       }
3492     case LEFT_ASSIGN:
3493       return
3494         geniCodeAssign (left,
3495                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3496                                                    ,FALSE),
3497                                    geniCodeRValue (right, FALSE)), 0);
3498     case RIGHT_ASSIGN:
3499       return
3500         geniCodeAssign (left,
3501                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3502                                                    ,FALSE),
3503                                    geniCodeRValue (right, FALSE)), 0);
3504     case AND_ASSIGN:
3505       return
3506         geniCodeAssign (left,
3507                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3508                                                   FALSE),
3509                                   geniCodeRValue (right, FALSE),
3510                                   BITWISEAND,
3511                                   operandType (left)), 0);
3512     case XOR_ASSIGN:
3513       return
3514         geniCodeAssign (left,
3515                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3516                                                   FALSE),
3517                                   geniCodeRValue (right, FALSE),
3518                                   '^',
3519                                   operandType (left)), 0);
3520     case OR_ASSIGN:
3521       return
3522         geniCodeAssign (left,
3523                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3524                                                    ,FALSE),
3525                                    geniCodeRValue (right, FALSE),
3526                                    '|',
3527                                    operandType (left)), 0);
3528     case ',':
3529       return geniCodeRValue (right, FALSE);
3530
3531     case CALL:
3532       return geniCodeCall (ast2iCode (tree->left,lvl+1),
3533                            tree->right,lvl);
3534     case LABEL:
3535       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3536       return ast2iCode (tree->right,lvl+1);
3537
3538     case GOTO:
3539       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3540       return ast2iCode (tree->right,lvl+1);
3541
3542     case FUNCTION:
3543       geniCodeFunctionBody (tree,lvl);
3544       return NULL;
3545
3546     case RETURN:
3547       geniCodeReturn (right);
3548       return NULL;
3549
3550     case IFX:
3551       geniCodeIfx (tree,lvl);
3552       return NULL;
3553
3554     case SWITCH:
3555       geniCodeSwitch (tree,lvl);
3556       return NULL;
3557
3558     case INLINEASM:
3559       geniCodeInline (tree);
3560       return NULL;
3561         
3562     case ARRAYINIT:
3563         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3564         return NULL;
3565     }
3566
3567   return NULL;
3568 }
3569
3570 /*-----------------------------------------------------------------*/
3571 /* reverseICChain - gets from the list and creates a linkedlist    */
3572 /*-----------------------------------------------------------------*/
3573 iCode *
3574 reverseiCChain ()
3575 {
3576   iCode *loop = NULL;
3577   iCode *prev = NULL;
3578
3579   while ((loop = getSet (&iCodeChain)))
3580     {
3581       loop->next = prev;
3582       if (prev)
3583         prev->prev = loop;
3584       prev = loop;
3585     }
3586
3587   return prev;
3588 }
3589
3590
3591 /*-----------------------------------------------------------------*/
3592 /* iCodeFromAst - given an ast will convert it to iCode            */
3593 /*-----------------------------------------------------------------*/
3594 iCode *
3595 iCodeFromAst (ast * tree)
3596 {
3597   returnLabel = newiTempLabel ("_return");
3598   entryLabel = newiTempLabel ("_entry");
3599   ast2iCode (tree,0);
3600   return reverseiCChain ();
3601 }