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