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