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