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