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