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