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