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