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