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