* src/z80/gen.h,
[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 (!options.lessPedantic &&
1098                   ul != (TYPE_UWORD) ul)
1099                 werror (W_INT_OVL);
1100             }
1101           else /* signed int */
1102             {
1103               /* signed int is handled here in order to detect overflow */
1104               TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1105                              (TYPE_WORD) operandLitValue (right);
1106
1107               retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1108               if (!options.lessPedantic &&
1109                   l != (TYPE_WORD) l)
1110                 werror (W_INT_OVL);
1111             }
1112         }
1113       else
1114         /* all others go here: */
1115         retval = operandFromValue (valCastLiteral (type,
1116                                                    operandLitValue (left) *
1117                                                    operandLitValue (right)));
1118       break;
1119     case '/':
1120       if ((TYPE_UDWORD) operandLitValue (right) == 0)
1121         {
1122           werror (E_DIVIDE_BY_ZERO);
1123           retval = right;
1124
1125         }
1126       else
1127         retval = operandFromValue (valCastLiteral (type,
1128                                                    operandLitValue (left) /
1129                                                    operandLitValue (right)));
1130       break;
1131     case '%':
1132       if ((TYPE_UDWORD) operandLitValue (right) == 0) {
1133           werror (E_DIVIDE_BY_ZERO);
1134           retval = right;
1135       }
1136       else
1137         {
1138           if (SPEC_USIGN(let) || SPEC_USIGN(ret))
1139             /* one of the operands is unsigned */
1140             retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1141                                      (TYPE_UDWORD) operandLitValue (right));
1142           else
1143             /* both operands are signed */
1144             retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1145                                      (TYPE_DWORD) operandLitValue (right));
1146         }
1147       break;
1148     case LEFT_OP:
1149       /* The number of left shifts is always unsigned. Signed doesn't make
1150          sense here. Shifting by a negative number is impossible. */
1151       retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1152                                (TYPE_UDWORD) operandLitValue (right));
1153       break;
1154     case RIGHT_OP:
1155       /* The number of right shifts is always unsigned. Signed doesn't make
1156          sense here. Shifting by a negative number is impossible. */
1157       if (SPEC_USIGN(let))
1158         /* unsigned: logic shift right */
1159         retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1160                                  (TYPE_UDWORD) operandLitValue (right));
1161       else
1162         /* signed: arithmetic shift right */
1163         retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1164                                  (TYPE_UDWORD) operandLitValue (right));
1165       break;
1166     case EQ_OP:
1167       /* this op doesn't care about signedness */
1168       {
1169         TYPE_UDWORD l, r;
1170
1171         l = (TYPE_UDWORD) operandLitValue (left);
1172         if (SPEC_NOUN(OP_VALUE(left)->type) == V_CHAR)
1173           l &= 0xff;
1174         else if (!SPEC_LONG (OP_VALUE(left)->type))
1175           l &= 0xffff;
1176         r = (TYPE_UDWORD) operandLitValue (right);
1177         if (SPEC_NOUN(OP_VALUE(right)->type) == V_CHAR)
1178           r &= 0xff;
1179         else if (!SPEC_LONG (OP_VALUE(right)->type))
1180           r &= 0xffff;
1181         retval = operandFromLit (l == r);
1182       }
1183       break;
1184     case '<':
1185       retval = operandFromLit (operandLitValue (left) <
1186                                operandLitValue (right));
1187       break;
1188     case LE_OP:
1189       retval = operandFromLit (operandLitValue (left) <=
1190                                operandLitValue (right));
1191       break;
1192     case NE_OP:
1193       retval = operandFromLit (operandLitValue (left) !=
1194                                operandLitValue (right));
1195       break;
1196     case '>':
1197       retval = operandFromLit (operandLitValue (left) >
1198                                operandLitValue (right));
1199       break;
1200     case GE_OP:
1201       retval = operandFromLit (operandLitValue (left) >=
1202                                operandLitValue (right));
1203       break;
1204     case BITWISEAND:
1205       retval = operandFromValue (valCastLiteral (type,
1206                                                  (TYPE_UDWORD)operandLitValue(left) &
1207                                                  (TYPE_UDWORD)operandLitValue(right)));
1208       break;
1209     case '|':
1210       retval = operandFromValue (valCastLiteral (type,
1211                                                  (TYPE_UDWORD)operandLitValue(left) |
1212                                                  (TYPE_UDWORD)operandLitValue(right)));
1213       break;
1214     case '^':
1215       retval = operandFromValue (valCastLiteral (type,
1216                                                  (TYPE_UDWORD)operandLitValue(left) ^
1217                                                  (TYPE_UDWORD)operandLitValue(right)));
1218       break;
1219     case AND_OP:
1220       retval = operandFromLit (operandLitValue (left) &&
1221                                operandLitValue (right));
1222       break;
1223     case OR_OP:
1224       retval = operandFromLit (operandLitValue (left) ||
1225                                operandLitValue (right));
1226       break;
1227     case RRC:
1228       {
1229         TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1230
1231         retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1232                                  (i << 1));
1233       }
1234       break;
1235     case RLC:
1236       {
1237         TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1238
1239         retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1240                                  (i >> 1));
1241       }
1242       break;
1243
1244     case UNARYMINUS:
1245       retval = operandFromValue (valCastLiteral (type,
1246                                                  -1 * operandLitValue (left)));
1247       break;
1248
1249     case '~':
1250       retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1251       break;
1252
1253     case '!':
1254       retval = operandFromLit (!operandLitValue (left));
1255       break;
1256
1257     default:
1258       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1259               " operandOperation invalid operator ");
1260       assert (0);
1261     }
1262
1263   return retval;
1264 }
1265
1266
1267 /*-----------------------------------------------------------------*/
1268 /* isOperandEqual - compares two operand & return 1 if they r =    */
1269 /*-----------------------------------------------------------------*/
1270 int
1271 isOperandEqual (operand * left, operand * right)
1272 {
1273   /* if the pointers are equal then they are equal */
1274   if (left == right)
1275     return 1;
1276
1277   /* if either of them null then false */
1278   if (!left || !right)
1279     return 0;
1280
1281   if (left->type != right->type)
1282     return 0;
1283
1284   if (IS_SYMOP (left) && IS_SYMOP (right))
1285     return left->key == right->key;
1286
1287   /* if types are the same */
1288   switch (left->type)
1289     {
1290     case SYMBOL:
1291       return isSymbolEqual (left->operand.symOperand,
1292                             right->operand.symOperand);
1293     case VALUE:
1294       return (floatFromVal (left->operand.valOperand) ==
1295               floatFromVal (right->operand.valOperand));
1296     case TYPE:
1297       if (compareType (left->operand.typeOperand,
1298                      right->operand.typeOperand) == 1)
1299         return 1;
1300     }
1301
1302   return 0;
1303 }
1304
1305 /*-------------------------------------------------------------------*/
1306 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1307 /*-------------------------------------------------------------------*/
1308 int 
1309 isiCodeEqual (iCode * left, iCode * right)
1310 {
1311   /* if the same pointer */
1312   if (left == right)
1313     return 1;
1314
1315   /* if either of them null */
1316   if (!left || !right)
1317     return 0;
1318
1319   /* if operand are the same */
1320   if (left->op == right->op)
1321     {
1322
1323       /* compare all the elements depending on type */
1324       if (left->op != IFX)
1325         {
1326           if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1327             return 0;
1328           if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1329             return 0;
1330
1331         }
1332       else
1333         {
1334           if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1335             return 0;
1336           if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1337             return 0;
1338           if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1339             return 0;
1340         }
1341       
1342       return 1;
1343     }
1344   return 0;
1345 }
1346
1347 /*-----------------------------------------------------------------*/
1348 /* newiTempFromOp - create a temp Operand with same attributes     */
1349 /*-----------------------------------------------------------------*/
1350 operand *
1351 newiTempFromOp (operand * op)
1352 {
1353   operand *nop;
1354
1355   if (!op)
1356     return NULL;
1357
1358   if (!IS_ITEMP (op))
1359     return op;
1360
1361   nop = newiTempOperand (operandType (op), TRUE);
1362   nop->isaddr = op->isaddr;
1363   nop->isvolatile = op->isvolatile;
1364   nop->isGlobal = op->isGlobal;
1365   nop->isLiteral = op->isLiteral;
1366   nop->usesDefs = op->usesDefs;
1367   nop->isParm = op->isParm;
1368   return nop;
1369 }
1370
1371 /*-----------------------------------------------------------------*/
1372 /* operand from operand - creates an operand holder for the type   */
1373 /*-----------------------------------------------------------------*/
1374 operand *
1375 operandFromOperand (operand * op)
1376 {
1377   operand *nop;
1378
1379   if (!op)
1380     return NULL;
1381   nop = newOperand ();
1382   nop->type = op->type;
1383   nop->isaddr = op->isaddr;
1384   nop->key = op->key;
1385   nop->isvolatile = op->isvolatile;
1386   nop->isGlobal = op->isGlobal;
1387   nop->isLiteral = op->isLiteral;
1388   nop->usesDefs = op->usesDefs;
1389   nop->isParm = op->isParm;
1390
1391   switch (nop->type)
1392     {
1393     case SYMBOL:
1394       nop->operand.symOperand = op->operand.symOperand;
1395       break;
1396     case VALUE:
1397       nop->operand.valOperand = op->operand.valOperand;
1398       break;
1399     case TYPE:
1400       nop->operand.typeOperand = op->operand.typeOperand;
1401       break;
1402     }
1403
1404   return nop;
1405 }
1406
1407 /*-----------------------------------------------------------------*/
1408 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
1409 /*-----------------------------------------------------------------*/
1410 operand *
1411 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1412 {
1413   operand *nop = operandFromOperand (op);
1414
1415   if (nop->type == SYMBOL)
1416     {
1417       OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1418       OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1419     }
1420
1421   return nop;
1422 }
1423
1424 /*-----------------------------------------------------------------*/
1425 /* operandFromSymbol - creates an operand from a symbol            */
1426 /*-----------------------------------------------------------------*/
1427 operand *
1428 operandFromSymbol (symbol * sym)
1429 {
1430   operand *op;
1431   iCode *ic;
1432   int ok = 1;
1433   /* if the symbol's type is a literal */
1434   /* then it is an enumerator type     */
1435   if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1436     return operandFromValue (valFromType (sym->etype));
1437
1438   if (!sym->key)
1439     sym->key = ++operandKey;
1440
1441   /* if this an implicit variable, means struct/union */
1442   /* member so just return it                         */
1443   if (sym->implicit || IS_FUNC (sym->type))
1444     {
1445       op = newOperand ();
1446       op->type = SYMBOL;
1447       op->operand.symOperand = sym;
1448       op->key = sym->key;
1449       op->isvolatile = isOperandVolatile (op, TRUE);
1450       op->isGlobal = isOperandGlobal (op);
1451       return op;
1452     }
1453
1454   /* under the following conditions create a
1455      register equivalent for a local symbol */
1456   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1457       (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1458       (!(options.model == MODEL_FLAT24)) ) &&
1459       options.stackAuto == 0)
1460     ok = 0;
1461
1462   if (!IS_AGGREGATE (sym->type) &&      /* not an aggregate */
1463       !IS_FUNC (sym->type) &&   /* not a function   */
1464       !sym->_isparm &&          /* not a parameter  */
1465       sym->level &&             /* is a local variable */
1466       !sym->addrtaken &&        /* whose address has not been taken */
1467       !sym->reqv &&             /* does not already have a reg equivalence */
1468       !IS_VOLATILE (sym->etype) &&      /* not declared as volatile */
1469       !IS_STATIC (sym->etype) &&        /* and not declared static  */
1470       !sym->islbl &&            /* not a label */
1471       ok &&                     /* farspace check */
1472       !IS_BITVAR (sym->etype)   /* not a bit variable */
1473     )
1474     {                                   
1475
1476       /* we will use it after all optimizations
1477          and before liveRange calculation */
1478       sym->reqv = newiTempOperand (sym->type, 0);
1479       sym->reqv->key = sym->key;
1480       OP_SYMBOL (sym->reqv)->key = sym->key;
1481       OP_SYMBOL (sym->reqv)->isreqv = 1;
1482       OP_SYMBOL (sym->reqv)->islocal = 1;
1483       OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1484       SPIL_LOC (sym->reqv) = sym;
1485     }
1486
1487   if (!IS_AGGREGATE (sym->type))
1488     {
1489       op = newOperand ();
1490       op->type = SYMBOL;
1491       op->operand.symOperand = sym;
1492       op->isaddr = 1;
1493       op->key = sym->key;
1494       op->isvolatile = isOperandVolatile (op, TRUE);
1495       op->isGlobal = isOperandGlobal (op);
1496       op->isPtr = IS_PTR (operandType (op));
1497       op->isParm = sym->_isparm;
1498       return op;
1499     }
1500
1501   /* create :-                     */
1502   /*    itemp = &[_symbol]         */
1503
1504   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1505   IC_LEFT (ic)->type = SYMBOL;
1506   IC_LEFT (ic)->operand.symOperand = sym;
1507   IC_LEFT (ic)->key = sym->key;
1508   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1509   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1510   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1511
1512   /* create result */
1513   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1514   if (IS_ARRAY (sym->type))
1515     {
1516       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1517       IC_RESULT (ic)->isaddr = 0;
1518     }
1519   else
1520     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1521
1522   ADDTOCHAIN (ic);
1523
1524   return IC_RESULT (ic);
1525 }
1526
1527 /*-----------------------------------------------------------------*/
1528 /* operandFromValue - creates an operand from value                */
1529 /*-----------------------------------------------------------------*/
1530 operand *
1531 operandFromValue (value * val)
1532 {
1533   operand *op;
1534
1535   /* if this is a symbol then do the symbol thing */
1536   if (val->sym)
1537     return operandFromSymbol (val->sym);
1538
1539   /* this is not a symbol */
1540   op = newOperand ();
1541   op->type = VALUE;
1542   op->operand.valOperand = val;
1543   op->isLiteral = isOperandLiteral (op);
1544   return op;
1545 }
1546
1547 /*-----------------------------------------------------------------*/
1548 /* operandFromLink - operand from typeChain                        */
1549 /*-----------------------------------------------------------------*/
1550 operand *
1551 operandFromLink (sym_link * type)
1552 {
1553   operand *op;
1554
1555   /* operand from sym_link */
1556   if (!type)
1557     return NULL;
1558
1559   op = newOperand ();
1560   op->type = TYPE;
1561   op->operand.typeOperand = copyLinkChain (type);
1562   return op;
1563 }
1564
1565 /*-----------------------------------------------------------------*/
1566 /* operandFromLit - makes an operand from a literal value          */
1567 /*-----------------------------------------------------------------*/
1568 operand *
1569 operandFromLit (double i)
1570 {
1571   return operandFromValue (valueFromLit (i));
1572 }
1573
1574 /*-----------------------------------------------------------------*/
1575 /* operandFromAst - creates an operand from an ast                 */
1576 /*-----------------------------------------------------------------*/
1577 operand *
1578 operandFromAst (ast * tree,int lvl)
1579 {
1580
1581   if (!tree)
1582     return NULL;
1583
1584   /* depending on type do */
1585   switch (tree->type)
1586     {
1587     case EX_OP:
1588       return ast2iCode (tree,lvl+1);
1589       break;
1590
1591     case EX_VALUE:
1592       return operandFromValue (tree->opval.val);
1593       break;
1594
1595     case EX_LINK:
1596       return operandFromLink (tree->opval.lnk);
1597       break;
1598
1599     default:
1600       assert (0);
1601     }
1602   
1603   /*  Just to keep the compiler happy */
1604   return (operand *) 0;
1605 }
1606
1607 /*-----------------------------------------------------------------*/
1608 /* setOperandType - sets the operand's type to the given type      */
1609 /*-----------------------------------------------------------------*/
1610 void 
1611 setOperandType (operand * op, sym_link * type)
1612 {
1613   /* depending on the type of operand */
1614   switch (op->type)
1615     {
1616
1617     case VALUE:
1618       op->operand.valOperand->etype =
1619         getSpec (op->operand.valOperand->type =
1620                  copyLinkChain (type));
1621       return;
1622
1623     case SYMBOL:
1624       if (op->operand.symOperand->isitmp)
1625         op->operand.symOperand->etype =
1626           getSpec (op->operand.symOperand->type =
1627                    copyLinkChain (type));
1628       else
1629         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1630                 "attempt to modify type of source");
1631       return;
1632
1633     case TYPE:
1634       op->operand.typeOperand = copyLinkChain (type);
1635       return;
1636     }
1637
1638 }
1639 /*-----------------------------------------------------------------*/
1640 /* Get size in byte of ptr need to access an array                 */
1641 /*-----------------------------------------------------------------*/
1642 int
1643 getArraySizePtr (operand * op)
1644 {
1645   sym_link *ltype = operandType(op);
1646
1647   if(IS_PTR(ltype))
1648     {
1649       int size = getSize(ltype);
1650       return(IS_GENPTR(ltype)?(size-1):size);
1651     }
1652
1653   if(IS_ARRAY(ltype))
1654     {
1655       sym_link *letype = getSpec(ltype);
1656       switch (PTR_TYPE (SPEC_OCLS (letype)))
1657         {
1658         case IPOINTER:
1659         case PPOINTER:
1660         case POINTER:
1661           return (PTRSIZE);
1662         case EEPPOINTER:
1663         case FPOINTER:
1664         case CPOINTER:
1665         case FUNCTION:
1666           return (FPTRSIZE);
1667         case GPOINTER:
1668           return (GPTRSIZE-1);
1669
1670         default:
1671           return (FPTRSIZE);
1672         }
1673     }
1674   return (FPTRSIZE);
1675 }
1676
1677 /*-----------------------------------------------------------------*/
1678 /* perform "usual unary conversions"                               */
1679 /*-----------------------------------------------------------------*/
1680 operand *
1681 usualUnaryConversions (operand * op)
1682 {
1683   if (IS_INTEGRAL (operandType (op)))
1684     {
1685       if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1686         {
1687           /* Widen to int. */
1688           return geniCodeCast (INTTYPE, op, TRUE);
1689         }
1690     }
1691   return op;
1692 }
1693
1694 /*-----------------------------------------------------------------*/
1695 /* perform "usual binary conversions"                              */
1696 /*-----------------------------------------------------------------*/
1697 sym_link *
1698 usualBinaryConversions (operand ** op1, operand ** op2)
1699 {
1700   sym_link *ctype;
1701   sym_link *rtype = operandType (*op2);
1702   sym_link *ltype = operandType (*op1);
1703   
1704   ctype = computeType (ltype, rtype);
1705
1706   *op1 = geniCodeCast (ctype, *op1, TRUE);
1707   *op2 = geniCodeCast (ctype, *op2, TRUE);
1708   
1709   return ctype;
1710 }
1711
1712 /*-----------------------------------------------------------------*/
1713 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1714 /*                          at address                             */
1715 /*-----------------------------------------------------------------*/
1716 operand *
1717 geniCodeRValue (operand * op, bool force)
1718 {
1719   iCode *ic;
1720   sym_link *type = operandType (op);
1721   sym_link *etype = getSpec (type);
1722
1723   /* if this is an array & already */
1724   /* an address then return this   */
1725   if (IS_AGGREGATE (type) ||
1726       (IS_PTR (type) && !force && !op->isaddr))
1727     return operandFromOperand (op);
1728
1729   /* if this is not an address then must be */
1730   /* rvalue already so return this one      */
1731   if (!op->isaddr)
1732     return op;
1733
1734   /* if this is not a temp symbol then */
1735   if (!IS_ITEMP (op) &&
1736       !force &&
1737       !IN_FARSPACE (SPEC_OCLS (etype)))
1738     {
1739       op = operandFromOperand (op);
1740       op->isaddr = 0;
1741       return op;
1742     }
1743
1744   if (IS_SPEC (type) &&
1745       IS_TRUE_SYMOP (op) &&
1746       (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1747       (options.model == MODEL_FLAT24) ))
1748     {
1749       op = operandFromOperand (op);
1750       op->isaddr = 0;
1751       return op;
1752     }
1753
1754   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1755   if (IS_PTR (type) && op->isaddr && force)
1756     type = type->next;
1757
1758   type = copyLinkChain (type);
1759
1760   IC_RESULT (ic) = newiTempOperand (type, 1);
1761   IC_RESULT (ic)->isaddr = 0;
1762
1763 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1764
1765   ADDTOCHAIN (ic);
1766
1767   return IC_RESULT (ic);
1768 }
1769
1770 /*-----------------------------------------------------------------*/
1771 /* geniCodeCast - changes the value from one type to another       */
1772 /*-----------------------------------------------------------------*/
1773 operand *
1774 geniCodeCast (sym_link * type, operand * op, bool implicit)
1775 {
1776   iCode *ic;
1777   sym_link *optype;
1778   sym_link *opetype = getSpec (optype = operandType (op));
1779   sym_link *restype;
1780   int errors=0;
1781
1782   /* one of them has size zero then error */
1783   if (IS_VOID (optype))
1784     {
1785       werror (E_CAST_ZERO);
1786       return op;
1787     }
1788
1789   /* if the operand is already the desired type then do nothing */
1790   if (compareType (type, optype) == 1)
1791     return op;
1792
1793   /* if this is a literal then just change the type & return */
1794   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1795     return operandFromValue (valCastLiteral (type,
1796                                              operandLitValue (op)));
1797
1798   /* if casting to/from pointers, do some checking */
1799   if (IS_PTR(type)) { // to a pointer
1800     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1801       if (IS_INTEGRAL(optype)) { 
1802         // maybe this is NULL, than it's ok. 
1803         if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1804           if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1805             // no way to set the storage
1806             if (IS_LITERAL(optype)) {
1807               werror(E_LITERAL_GENERIC);
1808               errors++;
1809             } else {
1810               werror(E_NONPTR2_GENPTR);
1811               errors++;
1812             }
1813           } else if (implicit) {
1814             werror(W_INTEGRAL2PTR_NOCAST);
1815             errors++;
1816           }
1817         }
1818       } else { 
1819         // shouldn't do that with float, array or structure unless to void
1820         if (!IS_VOID(getSpec(type)) && 
1821             !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1822           werror(E_INCOMPAT_TYPES);
1823           errors++;
1824         }
1825       }
1826     } else { // from a pointer to a pointer
1827       if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1828         // if not a pointer to a function
1829         if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1830           if (implicit) { // if not to generic, they have to match 
1831             if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1832               werror(E_INCOMPAT_PTYPES);
1833               errors++;
1834             }
1835           }
1836         }
1837       }
1838     }
1839   } else { // to a non pointer
1840     if (IS_PTR(optype)) { // from a pointer
1841       if (implicit) { // sneaky
1842         if (IS_INTEGRAL(type)) {
1843           werror(W_PTR2INTEGRAL_NOCAST);
1844           errors++;
1845         } else { // shouldn't do that with float, array or structure
1846           werror(E_INCOMPAT_TYPES);
1847           errors++;
1848         }
1849       }
1850     }
1851   }
1852   if (errors) {
1853     printFromToType (optype, type);
1854   }
1855
1856   /* if they are the same size create an assignment */
1857   if (getSize (type) == getSize (optype) &&
1858       !IS_BITFIELD (type) &&
1859       !IS_FLOAT (type) &&
1860       !IS_FLOAT (optype) &&
1861       ((IS_SPEC (type) && IS_SPEC (optype)) ||
1862        (!IS_SPEC (type) && !IS_SPEC (optype))))
1863     {
1864
1865       ic = newiCode ('=', NULL, op);
1866       IC_RESULT (ic) = newiTempOperand (type, 0);
1867       SPIL_LOC (IC_RESULT (ic)) =
1868         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1869       IC_RESULT (ic)->isaddr = 0;
1870     }
1871   else
1872     {
1873       ic = newiCode (CAST, operandFromLink (type),
1874                      geniCodeRValue (op, FALSE));
1875
1876       IC_RESULT (ic) = newiTempOperand (type, 0);
1877     }
1878
1879   /* preserve the storage class & output class */
1880   /* of the original variable                  */
1881   restype = getSpec (operandType (IC_RESULT (ic)));
1882   if (!IS_LITERAL(opetype))
1883       SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1884   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1885
1886   ADDTOCHAIN (ic);
1887   return IC_RESULT (ic);
1888 }
1889
1890 /*-----------------------------------------------------------------*/
1891 /* geniCodeLabel - will create a Label                             */
1892 /*-----------------------------------------------------------------*/
1893 void 
1894 geniCodeLabel (symbol * label)
1895 {
1896   iCode *ic;
1897
1898   ic = newiCodeLabelGoto (LABEL, label);
1899   ADDTOCHAIN (ic);
1900 }
1901
1902 /*-----------------------------------------------------------------*/
1903 /* geniCodeGoto  - will create a Goto                              */
1904 /*-----------------------------------------------------------------*/
1905 void 
1906 geniCodeGoto (symbol * label)
1907 {
1908   iCode *ic;
1909
1910   ic = newiCodeLabelGoto (GOTO, label);
1911   ADDTOCHAIN (ic);
1912 }
1913
1914 /*-----------------------------------------------------------------*/
1915 /* geniCodeMultiply - gen intermediate code for multiplication     */
1916 /*-----------------------------------------------------------------*/
1917 operand *
1918 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1919 {
1920   iCode *ic;
1921   int p2 = 0;
1922   sym_link *resType;
1923   LRTYPE;
1924
1925   /* if they are both literal then we know the result */
1926   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1927     return operandFromValue (valMult (left->operand.valOperand,
1928                                       right->operand.valOperand));
1929
1930   if (IS_LITERAL(retype)) {
1931     p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1932   }
1933
1934   resType = usualBinaryConversions (&left, &right);
1935 #if 1
1936   rtype = operandType (right);
1937   retype = getSpec (rtype);
1938   ltype = operandType (left);
1939   letype = getSpec (ltype);
1940 #endif
1941   if (resultIsInt)
1942     {
1943       SPEC_NOUN(getSpec(resType))=V_INT;
1944     }
1945
1946   /* if the right is a literal & power of 2 */
1947   /* then make it a left shift              */
1948   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1949      efficient in most cases than 2 bytes result = 2 bytes << literal
1950      if port has 1 byte muldiv */
1951   if (p2 && !IS_FLOAT (letype) &&
1952       !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1953         (port->support.muldiv == 1)))
1954     {
1955       if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1956         {
1957           /* LEFT_OP need same size for left and result, */
1958           left = geniCodeCast (resType, left, TRUE);
1959           ltype = operandType (left);
1960         }
1961       ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1962     }
1963   else
1964     {
1965       ic = newiCode ('*', left, right);         /* normal multiplication */
1966       /* if the size left or right > 1 then support routine */
1967       if (getSize (ltype) > 1 || getSize (rtype) > 1)
1968         ic->supportRtn = 1;
1969
1970     }
1971   IC_RESULT (ic) = newiTempOperand (resType, 1);
1972
1973   ADDTOCHAIN (ic);
1974   return IC_RESULT (ic);
1975 }
1976
1977 /*-----------------------------------------------------------------*/
1978 /* geniCodeDivision - gen intermediate code for division           */
1979 /*-----------------------------------------------------------------*/
1980 operand *
1981 geniCodeDivision (operand * left, operand * right)
1982 {
1983   iCode *ic;
1984   int p2 = 0;
1985   sym_link *resType;
1986   sym_link *rtype = operandType (right);
1987   sym_link *retype = getSpec (rtype);
1988   sym_link *ltype = operandType (left);
1989   sym_link *letype = getSpec (ltype);
1990
1991   resType = usualBinaryConversions (&left, &right);
1992
1993   /* if the right is a literal & power of 2
1994      and left is unsigned then make it a
1995      right shift */
1996   if (IS_LITERAL (retype) &&
1997       !IS_FLOAT (letype) &&
1998       SPEC_USIGN(letype) &&
1999       (p2 = powof2 ((unsigned long)
2000                     floatFromVal (right->operand.valOperand)))) {
2001     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2002   }
2003   else
2004     {
2005       ic = newiCode ('/', left, right);         /* normal division */
2006       /* if the size left or right > 1 then support routine */
2007       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2008         ic->supportRtn = 1;
2009     }
2010   IC_RESULT (ic) = newiTempOperand (resType, 0);
2011
2012   ADDTOCHAIN (ic);
2013   return IC_RESULT (ic);
2014 }
2015 /*-----------------------------------------------------------------*/
2016 /* geniCodeModulus  - gen intermediate code for modulus            */
2017 /*-----------------------------------------------------------------*/
2018 operand *
2019 geniCodeModulus (operand * left, operand * right)
2020 {
2021   iCode *ic;
2022   sym_link *resType;
2023   LRTYPE;
2024
2025   /* if they are both literal then we know the result */
2026   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2027     return operandFromValue (valMod (left->operand.valOperand,
2028                                      right->operand.valOperand));
2029
2030   resType = usualBinaryConversions (&left, &right);
2031
2032   /* now they are the same size */
2033   ic = newiCode ('%', left, right);
2034
2035   /* if the size left or right > 1 then support routine */
2036   if (getSize (ltype) > 1 || getSize (rtype) > 1)
2037     ic->supportRtn = 1;
2038   IC_RESULT (ic) = newiTempOperand (resType, 0);
2039
2040   ADDTOCHAIN (ic);
2041   return IC_RESULT (ic);
2042 }
2043
2044 /*-----------------------------------------------------------------*/
2045 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
2046 /*-----------------------------------------------------------------*/
2047 operand *
2048 geniCodePtrPtrSubtract (operand * left, operand * right)
2049 {
2050   iCode *ic;
2051   operand *result;
2052   LRTYPE;
2053
2054   /* if they are both literals then */
2055   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2056     {
2057       result = operandFromValue (valMinus (left->operand.valOperand,
2058                                            right->operand.valOperand));
2059       goto subtractExit;
2060     }
2061
2062   ic = newiCode ('-', left, right);
2063
2064   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2065   ADDTOCHAIN (ic);
2066
2067 subtractExit:
2068   if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2069     return result;
2070   }
2071
2072   // should we really do this? is this ANSI?
2073   return geniCodeDivision (result,
2074                            operandFromLit (getSize (ltype->next)));
2075 }
2076
2077 /*-----------------------------------------------------------------*/
2078 /* geniCodeSubtract - generates code for subtraction               */
2079 /*-----------------------------------------------------------------*/
2080 operand *
2081 geniCodeSubtract (operand * left, operand * right)
2082 {
2083   iCode *ic;
2084   int isarray = 0;
2085   sym_link *resType;
2086   LRTYPE;
2087
2088   /* if they both pointers then */
2089   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2090       (IS_PTR (rtype) || IS_ARRAY (rtype)))
2091     return geniCodePtrPtrSubtract (left, right);
2092
2093   /* if they are both literal then we know the result */
2094   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2095       && left->isLiteral && right->isLiteral)
2096     return operandFromValue (valMinus (left->operand.valOperand,
2097                                        right->operand.valOperand));
2098
2099   /* if left is an array or pointer */
2100   if (IS_PTR (ltype) || IS_ARRAY (ltype))
2101     {
2102       isarray = left->isaddr;
2103       right = geniCodeMultiply (right,
2104                                 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2105       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2106     }
2107   else
2108     {                           /* make them the same size */
2109       resType = usualBinaryConversions (&left, &right);
2110     }
2111
2112   ic = newiCode ('-', left, right);
2113
2114   IC_RESULT (ic) = newiTempOperand (resType, 1);
2115   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2116
2117   /* if left or right is a float */
2118   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2119     ic->supportRtn = 1;
2120
2121   ADDTOCHAIN (ic);
2122   return IC_RESULT (ic);
2123 }
2124
2125 /*-----------------------------------------------------------------*/
2126 /* geniCodeAdd - generates iCode for addition                      */
2127 /*-----------------------------------------------------------------*/
2128 operand *
2129 geniCodeAdd (operand * left, operand * right, int lvl)
2130 {
2131   iCode *ic;
2132   sym_link *resType;
2133   operand *size;
2134   int isarray = 0;
2135   LRTYPE;
2136
2137   /* if the right side is LITERAL zero */
2138   /* return the left side              */
2139   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2140     return left;
2141
2142   /* if left is literal zero return right */
2143   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2144     return right;
2145
2146   /* if left is a pointer then size */
2147   if (IS_PTR (ltype) || IS_ARRAY(ltype))
2148     {
2149       isarray = left->isaddr;
2150       // there is no need to multiply with 1
2151       if (getSize(ltype->next)!=1) {
2152         size  = operandFromLit (getSize (ltype->next));
2153         right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2154       }
2155       resType = copyLinkChain (ltype);
2156     }
2157   else
2158     { // make them the same size
2159       resType = usualBinaryConversions (&left, &right);
2160     }
2161
2162   /* if they are both literals then we know */
2163   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2164       && left->isLiteral && right->isLiteral)
2165     return operandFromValue (valPlus (valFromType (letype),
2166                                       valFromType (retype)));
2167
2168   ic = newiCode ('+', left, right);
2169
2170   IC_RESULT (ic) = newiTempOperand (resType, 1);
2171   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2172
2173   /* if left or right is a float then support
2174      routine */
2175   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2176     ic->supportRtn = 1;
2177
2178   ADDTOCHAIN (ic);
2179
2180   return IC_RESULT (ic);
2181
2182 }
2183
2184 /*-----------------------------------------------------------------*/
2185 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
2186 /*-----------------------------------------------------------------*/
2187 sym_link *
2188 aggrToPtr (sym_link * type, bool force)
2189 {
2190   sym_link *etype;
2191   sym_link *ptype;
2192
2193   if (IS_PTR (type) && !force)
2194     return type;
2195
2196   etype = getSpec (type);
2197   ptype = newLink (DECLARATOR);
2198
2199   ptype->next = type;
2200
2201   /* set the pointer depending on the storage class */
2202   DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2203   return ptype;
2204 }
2205
2206 /*-----------------------------------------------------------------*/
2207 /* geniCodeArray2Ptr - array to pointer                            */
2208 /*-----------------------------------------------------------------*/
2209 operand *
2210 geniCodeArray2Ptr (operand * op)
2211 {
2212   sym_link *optype = operandType (op);
2213   sym_link *opetype = getSpec (optype);
2214
2215   /* set the pointer depending on the storage class */
2216   DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2217
2218   op->isaddr = 0;
2219   return op;
2220 }
2221
2222
2223 /*-----------------------------------------------------------------*/
2224 /* geniCodeArray - array access                                    */
2225 /*-----------------------------------------------------------------*/
2226 operand *
2227 geniCodeArray (operand * left, operand * right,int lvl)
2228 {
2229   iCode *ic;
2230   sym_link *ltype = operandType (left);
2231
2232   if (IS_PTR (ltype))
2233     {
2234       if (IS_PTR (ltype->next) && left->isaddr)
2235         {
2236           left = geniCodeRValue (left, FALSE);
2237         }
2238       return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2239     }
2240
2241   right = geniCodeMultiply (right,
2242                             operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2243
2244   /* we can check for limits here */
2245   if (isOperandLiteral (right) &&
2246       IS_ARRAY (ltype) &&
2247       DCL_ELEM (ltype) &&
2248       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2249     {
2250       werror (E_ARRAY_BOUND);
2251       right = operandFromLit (0);
2252     }
2253
2254   ic = newiCode ('+', left, right);
2255
2256   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2257                                       !IS_AGGREGATE (ltype->next) &&
2258                                       !IS_PTR (ltype->next))
2259                                      ? ltype : ltype->next), 0);
2260
2261   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2262   ADDTOCHAIN (ic);
2263   return IC_RESULT (ic);
2264 }
2265
2266 /*-----------------------------------------------------------------*/
2267 /* geniCodeStruct - generates intermediate code for structres      */
2268 /*-----------------------------------------------------------------*/
2269 operand *
2270 geniCodeStruct (operand * left, operand * right, bool islval)
2271 {
2272   iCode *ic;
2273   sym_link *type = operandType (left);
2274   sym_link *etype = getSpec (type);
2275   sym_link *retype;
2276   symbol *element = getStructElement (SPEC_STRUCT (etype),
2277                                       right->operand.symOperand);
2278
2279   wassert(IS_SYMOP(right));
2280     
2281   /* add the offset */
2282   ic = newiCode ('+', left, operandFromLit (element->offset));
2283
2284   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2285
2286   /* preserve the storage & output class of the struct */
2287   /* as well as the volatile attribute */
2288   retype = getSpec (operandType (IC_RESULT (ic)));
2289   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2290   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2291   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2292   SPEC_CONST (retype) |= SPEC_CONST (etype);
2293   
2294   if (IS_PTR (element->type))
2295     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2296   
2297   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2298
2299   ADDTOCHAIN (ic);
2300   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2301 }
2302
2303 /*-----------------------------------------------------------------*/
2304 /* geniCodePostInc - generate int code for Post increment          */
2305 /*-----------------------------------------------------------------*/
2306 operand *
2307 geniCodePostInc (operand * op)
2308 {
2309   iCode *ic;
2310   operand *rOp;
2311   sym_link *optype = operandType (op);
2312   operand *result;
2313   operand *rv = (IS_ITEMP (op) ?
2314                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2315                  op);
2316   sym_link *rvtype = operandType (rv);
2317   int size = 0;
2318
2319   /* if this is not an address we have trouble */
2320   if (!op->isaddr)
2321     {
2322       werror (E_LVALUE_REQUIRED, "++");
2323       return op;
2324     }
2325
2326   rOp = newiTempOperand (rvtype, 0);
2327   OP_SYMBOL(rOp)->noSpilLoc = 1;
2328
2329   if (IS_ITEMP (rv))
2330     OP_SYMBOL(rv)->noSpilLoc = 1;
2331
2332   geniCodeAssign (rOp, rv, 0);
2333
2334   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2335   if (IS_FLOAT (rvtype))
2336     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2337   else
2338     ic = newiCode ('+', rv, operandFromLit (size));
2339
2340   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2341   ADDTOCHAIN (ic);
2342
2343   geniCodeAssign (op, result, 0);
2344
2345   return rOp;
2346
2347 }
2348
2349 /*-----------------------------------------------------------------*/
2350 /* geniCodePreInc - generate code for preIncrement                 */
2351 /*-----------------------------------------------------------------*/
2352 operand *
2353 geniCodePreInc (operand * op)
2354 {
2355   iCode *ic;
2356   sym_link *optype = operandType (op);
2357   operand *rop = (IS_ITEMP (op) ?
2358                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2359                   op);
2360   sym_link *roptype = operandType (rop);
2361   operand *result;
2362   int size = 0;
2363
2364   if (!op->isaddr)
2365     {
2366       werror (E_LVALUE_REQUIRED, "++");
2367       return op;
2368     }
2369
2370
2371   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2372   if (IS_FLOAT (roptype))
2373     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2374   else
2375     ic = newiCode ('+', rop, operandFromLit (size));
2376   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2377   ADDTOCHAIN (ic);
2378
2379
2380   return geniCodeAssign (op, result, 0);
2381 }
2382
2383 /*-----------------------------------------------------------------*/
2384 /* geniCodePostDec - generates code for Post decrement             */
2385 /*-----------------------------------------------------------------*/
2386 operand *
2387 geniCodePostDec (operand * op)
2388 {
2389   iCode *ic;
2390   operand *rOp;
2391   sym_link *optype = operandType (op);
2392   operand *result;
2393   operand *rv = (IS_ITEMP (op) ?
2394                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2395                  op);
2396   sym_link *rvtype = operandType (rv);
2397   int size = 0;
2398
2399   /* if this is not an address we have trouble */
2400   if (!op->isaddr)
2401     {
2402       werror (E_LVALUE_REQUIRED, "--");
2403       return op;
2404     }
2405
2406   rOp = newiTempOperand (rvtype, 0);
2407   OP_SYMBOL(rOp)->noSpilLoc = 1;
2408
2409   if (IS_ITEMP (rv))
2410     OP_SYMBOL(rv)->noSpilLoc = 1;
2411
2412   geniCodeAssign (rOp, rv, 0);
2413
2414   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2415   if (IS_FLOAT (rvtype))
2416     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2417   else
2418     ic = newiCode ('-', rv, operandFromLit (size));
2419
2420   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2421   ADDTOCHAIN (ic);
2422
2423   geniCodeAssign (op, result, 0);
2424
2425   return rOp;
2426
2427 }
2428
2429 /*-----------------------------------------------------------------*/
2430 /* geniCodePreDec - generate code for pre  decrement               */
2431 /*-----------------------------------------------------------------*/
2432 operand *
2433 geniCodePreDec (operand * op)
2434 {
2435   iCode *ic;
2436   sym_link *optype = operandType (op);
2437   operand *rop = (IS_ITEMP (op) ?
2438                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2439                   op);
2440   sym_link *roptype = operandType (rop);
2441   operand *result;
2442   int size = 0;
2443
2444   if (!op->isaddr)
2445     {
2446       werror (E_LVALUE_REQUIRED, "--");
2447       return op;
2448     }
2449
2450
2451   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2452   if (IS_FLOAT (roptype))
2453     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2454   else
2455     ic = newiCode ('-', rop, operandFromLit (size));
2456   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2457   ADDTOCHAIN (ic);
2458
2459
2460   return geniCodeAssign (op, result, 0);
2461 }
2462
2463
2464 /*-----------------------------------------------------------------*/
2465 /* geniCodeBitwise - gen int code for bitWise  operators           */
2466 /*-----------------------------------------------------------------*/
2467 operand *
2468 geniCodeBitwise (operand * left, operand * right,
2469                  int oper, sym_link * resType)
2470 {
2471   iCode *ic;
2472
2473   left = geniCodeCast (resType, left, TRUE);
2474   right = geniCodeCast (resType, right, TRUE);
2475
2476   ic = newiCode (oper, left, right);
2477   IC_RESULT (ic) = newiTempOperand (resType, 0);
2478
2479   ADDTOCHAIN (ic);
2480   return IC_RESULT (ic);
2481 }
2482
2483 /*-----------------------------------------------------------------*/
2484 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2485 /*-----------------------------------------------------------------*/
2486 operand *
2487 geniCodeAddressOf (operand * op)
2488 {
2489   iCode *ic;
2490   sym_link *p;
2491   sym_link *optype = operandType (op);
2492   sym_link *opetype = getSpec (optype);
2493
2494   /* lvalue check already done in decorateType */
2495   /* this must be a lvalue */
2496 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2497 /*  werror (E_LVALUE_REQUIRED,"&"); */
2498 /*  return op; */
2499 /*     } */
2500
2501   p = newLink (DECLARATOR);
2502
2503   /* set the pointer depending on the storage class */
2504   DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2505
2506   p->next = copyLinkChain (optype);
2507
2508   /* if already a temp */
2509   if (IS_ITEMP (op))
2510     {
2511       setOperandType (op, p);
2512       op->isaddr = 0;
2513       return op;
2514     }
2515
2516   /* other wise make this of the type coming in */
2517   ic = newiCode (ADDRESS_OF, op, NULL);
2518   IC_RESULT (ic) = newiTempOperand (p, 1);
2519   IC_RESULT (ic)->isaddr = 0;
2520   ADDTOCHAIN (ic);
2521   return IC_RESULT (ic);
2522 }
2523 /*-----------------------------------------------------------------*/
2524 /* setOClass - sets the output class depending on the pointer type */
2525 /*-----------------------------------------------------------------*/
2526 void 
2527 setOClass (sym_link * ptr, sym_link * spec)
2528 {
2529   switch (DCL_TYPE (ptr))
2530     {
2531     case POINTER:
2532       SPEC_OCLS (spec) = data;
2533       break;
2534
2535     case GPOINTER:
2536       SPEC_OCLS (spec) = generic;
2537       break;
2538
2539     case FPOINTER:
2540       SPEC_OCLS (spec) = xdata;
2541       break;
2542
2543     case CPOINTER:
2544       SPEC_OCLS (spec) = code;
2545       break;
2546
2547     case IPOINTER:
2548       SPEC_OCLS (spec) = idata;
2549       break;
2550
2551     case PPOINTER:
2552       SPEC_OCLS (spec) = xstack;
2553       break;
2554
2555     case EEPPOINTER:
2556       SPEC_OCLS (spec) = eeprom;
2557       break;
2558
2559     default:
2560       break;
2561
2562     }
2563 }
2564
2565 /*-----------------------------------------------------------------*/
2566 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2567 /*-----------------------------------------------------------------*/
2568 operand *
2569 geniCodeDerefPtr (operand * op,int lvl)
2570 {
2571   sym_link *rtype, *retype;
2572   sym_link *optype = operandType (op);
2573
2574   // if this is an array then array access
2575   if (IS_ARRAY (optype)) {
2576     // don't worry, this will be optimized out later
2577     return geniCodeArray (op, operandFromLit (0), lvl);
2578   }
2579
2580   // just in case someone screws up
2581   wassert (IS_PTR (optype));
2582
2583   if (IS_TRUE_SYMOP (op))
2584     {
2585       op->isaddr = 1;
2586       op = geniCodeRValue (op, TRUE);
2587     }
2588
2589   /* now get rid of the pointer part */
2590   if (isLvaluereq(lvl) && IS_ITEMP (op))
2591     {
2592       retype = getSpec (rtype = copyLinkChain (optype));
2593     }
2594   else
2595     {
2596       retype = getSpec (rtype = copyLinkChain (optype->next));
2597       /* outputclass needs 2b updated */
2598       setOClass (optype, retype);
2599     }
2600   
2601   op->isGptr = IS_GENPTR (optype);
2602
2603   op->isaddr = (IS_PTR (rtype) ||
2604                 IS_STRUCT (rtype) ||
2605                 IS_INT (rtype) ||
2606                 IS_CHAR (rtype) ||
2607                 IS_FLOAT (rtype));
2608
2609   if (!isLvaluereq(lvl))
2610     op = geniCodeRValue (op, TRUE);
2611
2612   setOperandType (op, rtype);
2613
2614   return op;
2615 }
2616
2617 /*-----------------------------------------------------------------*/
2618 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2619 /*-----------------------------------------------------------------*/
2620 operand *
2621 geniCodeUnaryMinus (operand * op)
2622 {
2623   iCode *ic;
2624   sym_link *optype = operandType (op);
2625
2626   if (IS_LITERAL (optype))
2627     return operandFromLit (-floatFromVal (op->operand.valOperand));
2628
2629   ic = newiCode (UNARYMINUS, op, NULL);
2630   IC_RESULT (ic) = newiTempOperand (optype, 0);
2631   ADDTOCHAIN (ic);
2632   return IC_RESULT (ic);
2633 }
2634
2635 /*-----------------------------------------------------------------*/
2636 /* geniCodeLeftShift - gen i code for left shift                   */
2637 /*-----------------------------------------------------------------*/
2638 operand *
2639 geniCodeLeftShift (operand * left, operand * right)
2640 {
2641   iCode *ic;
2642
2643   ic = newiCode (LEFT_OP, left, right);
2644   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2645   ADDTOCHAIN (ic);
2646   return IC_RESULT (ic);
2647 }
2648
2649 /*-----------------------------------------------------------------*/
2650 /* geniCodeRightShift - gen i code for right shift                 */
2651 /*-----------------------------------------------------------------*/
2652 operand *
2653 geniCodeRightShift (operand * left, operand * right)
2654 {
2655   iCode *ic;
2656
2657   ic = newiCode (RIGHT_OP, left, right);
2658   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2659   ADDTOCHAIN (ic);
2660   return IC_RESULT (ic);
2661 }
2662
2663 /*-----------------------------------------------------------------*/
2664 /* geniCodeLogic- logic code                                       */
2665 /*-----------------------------------------------------------------*/
2666 operand *
2667 geniCodeLogic (operand * left, operand * right, int op)
2668 {
2669   iCode *ic;
2670   sym_link *ctype;
2671   sym_link *rtype = operandType (right);
2672   sym_link *ltype = operandType (left);
2673
2674   /* left is integral type and right is literal then
2675      check if the literal value is within bounds */
2676   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2677     {
2678       checkConstantRange(ltype,
2679                          OP_VALUE(right), "compare operation", 1);
2680     }
2681
2682   /* if one operand is a pointer and the other is a literal generic void pointer,
2683      change the type of the literal generic void pointer to match the other pointer */
2684   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2685       && IS_PTR (rtype) && !IS_GENPTR(rtype))
2686     {
2687       /* find left's definition */
2688       ic = (iCode *) setFirstItem (iCodeChain);
2689       while (ic)
2690         {
2691           if (((ic->op == CAST) || (ic->op == '='))
2692               && isOperandEqual(left, IC_RESULT (ic)))
2693             break;
2694           else
2695             ic = setNextItem (iCodeChain);
2696         }
2697       /* if casting literal to generic pointer, then cast to rtype instead */
2698       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2699         {
2700           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2701           ltype = operandType(left);
2702         }
2703     }
2704   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2705       && IS_PTR (ltype) && !IS_GENPTR(ltype))
2706     {
2707       /* find right's definition */
2708       ic = (iCode *) setFirstItem (iCodeChain);
2709       while (ic)
2710         {
2711           if (((ic->op == CAST) || (ic->op == '='))
2712               && isOperandEqual(right, IC_RESULT (ic)))
2713             break;
2714           else
2715             ic = setNextItem (iCodeChain);
2716         }
2717       /* if casting literal to generic pointer, then cast to rtype instead */
2718       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2719         {
2720           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2721           rtype = operandType(right);
2722         }
2723     }
2724
2725   ctype = usualBinaryConversions (&left, &right);
2726
2727   ic = newiCode (op, left, right);
2728   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2729
2730   /* if comparing float
2731      and not a '==' || '!=' || '&&' || '||' (these
2732      will be inlined */
2733   if (IS_FLOAT(ctype) &&
2734       op != EQ_OP &&
2735       op != NE_OP &&
2736       op != AND_OP &&
2737       op != OR_OP)
2738     ic->supportRtn = 1;
2739
2740   ADDTOCHAIN (ic);
2741   return IC_RESULT (ic);
2742 }
2743
2744 /*-----------------------------------------------------------------*/
2745 /* geniCodeUnary - for a a generic unary operation                 */
2746 /*-----------------------------------------------------------------*/
2747 operand *
2748 geniCodeUnary (operand * op, int oper)
2749 {
2750   iCode *ic = newiCode (oper, op, NULL);
2751
2752   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2753   ADDTOCHAIN (ic);
2754   return IC_RESULT (ic);
2755 }
2756
2757 /*-----------------------------------------------------------------*/
2758 /* geniCodeConditional - geniCode for '?' ':' operation            */
2759 /*-----------------------------------------------------------------*/
2760 operand *
2761 geniCodeConditional (ast * tree,int lvl)
2762 {
2763   iCode *ic;
2764   symbol *falseLabel = newiTempLabel (NULL);
2765   symbol *exitLabel = newiTempLabel (NULL);
2766   operand *cond = ast2iCode (tree->left,lvl+1);
2767   operand *true, *false, *result;
2768
2769   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2770                           NULL, falseLabel);
2771   ADDTOCHAIN (ic);
2772
2773   true = ast2iCode (tree->right->left,lvl+1);
2774
2775   /* move the value to a new Operand */
2776   result = newiTempOperand (tree->right->ftype, 0);
2777   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2778
2779   /* generate an unconditional goto */
2780   geniCodeGoto (exitLabel);
2781
2782   /* now for the right side */
2783   geniCodeLabel (falseLabel);
2784
2785   false = ast2iCode (tree->right->right,lvl+1);
2786   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2787
2788   /* create the exit label */
2789   geniCodeLabel (exitLabel);
2790
2791   return result;
2792 }
2793
2794 /*-----------------------------------------------------------------*/
2795 /* geniCodeAssign - generate code for assignment                   */
2796 /*-----------------------------------------------------------------*/
2797 operand *
2798 geniCodeAssign (operand * left, operand * right, int nosupdate)
2799 {
2800   iCode *ic;
2801   sym_link *ltype = operandType (left);
2802   sym_link *rtype = operandType (right);
2803
2804   if (!left->isaddr && !IS_ITEMP (left))
2805     {
2806       werror (E_LVALUE_REQUIRED, "assignment");
2807       return left;
2808     }
2809
2810   /* left is integral type and right is literal then
2811      check if the literal value is within bounds */
2812   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2813     {
2814       checkConstantRange(ltype, 
2815                          OP_VALUE(right), "= operation", 0);
2816     }
2817
2818   /* if the left & right type don't exactly match */
2819   /* if pointer set then make sure the check is
2820      done with the type & not the pointer */
2821   /* then cast rights type to left */
2822
2823   /* first check the type for pointer assignement */
2824   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2825       compareType (ltype, rtype) <= 0)
2826     {
2827       if (compareType (ltype->next, rtype) < 0)
2828         right = geniCodeCast (ltype->next, right, TRUE);
2829     }
2830   else if (compareType (ltype, rtype) < 0)
2831     right = geniCodeCast (ltype, right, TRUE);
2832
2833   /* if left is a true symbol & ! volatile
2834      create an assignment to temporary for
2835      the right & then assign this temporary
2836      to the symbol this is SSA . isn't it simple
2837      and folks have published mountains of paper on it */
2838   if (IS_TRUE_SYMOP (left) &&
2839       !isOperandVolatile (left, FALSE) &&
2840       isOperandGlobal (left))
2841     {
2842       symbol *sym = NULL;
2843
2844       if (IS_TRUE_SYMOP (right))
2845         sym = OP_SYMBOL (right);
2846       ic = newiCode ('=', NULL, right);
2847       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2848       SPIL_LOC (right) = sym;
2849       ADDTOCHAIN (ic);
2850     }
2851
2852   ic = newiCode ('=', NULL, right);
2853   IC_RESULT (ic) = left;
2854   ADDTOCHAIN (ic);
2855
2856   /* if left isgptr flag is set then support
2857      routine will be required */
2858   if (left->isGptr)
2859     ic->supportRtn = 1;
2860
2861   ic->nosupdate = nosupdate;
2862   return left;
2863 }
2864
2865 /*-----------------------------------------------------------------*/
2866 /* geniCodeDummyRead - generate code for dummy read                */
2867 /*-----------------------------------------------------------------*/
2868 static void
2869 geniCodeDummyRead (operand * op)
2870 {
2871   iCode *ic;
2872   sym_link *type = operandType (op);
2873
2874   if (!IS_VOLATILE(type))
2875     return;
2876     
2877   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2878   ADDTOCHAIN (ic);
2879
2880   ic->nosupdate = 1;
2881 }
2882
2883 /*-----------------------------------------------------------------*/
2884 /* geniCodeSEParms - generate code for side effecting fcalls       */
2885 /*-----------------------------------------------------------------*/
2886 static void 
2887 geniCodeSEParms (ast * parms,int lvl)
2888 {
2889   if (!parms)
2890     return;
2891
2892   if (parms->type == EX_OP && parms->opval.op == PARAM)
2893     {
2894       geniCodeSEParms (parms->left,lvl);
2895       geniCodeSEParms (parms->right,lvl);
2896       return;
2897     }
2898
2899   /* hack don't like this but too lazy to think of
2900      something better */
2901   if (IS_ADDRESS_OF_OP (parms))
2902     parms->left->lvalue = 1;
2903
2904   if (IS_CAST_OP (parms) &&
2905       IS_PTR (parms->ftype) &&
2906       IS_ADDRESS_OF_OP (parms->right))
2907     parms->right->left->lvalue = 1;
2908
2909   parms->opval.oprnd = 
2910     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2911                 
2912   parms->type = EX_OPERAND;
2913   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2914                 SPEC_ARGREG(parms->ftype);
2915 }
2916
2917 /*-----------------------------------------------------------------*/
2918 /* geniCodeParms - generates parameters                            */
2919 /*-----------------------------------------------------------------*/
2920 value *
2921 geniCodeParms (ast * parms, value *argVals, int *stack, 
2922                sym_link * fetype, symbol * func,int lvl)
2923 {
2924   iCode *ic;
2925   operand *pval;
2926
2927   if (!parms)
2928     return argVals;
2929
2930   if (argVals==NULL) {
2931     // first argument
2932     argVals=FUNC_ARGS(func->type);
2933   }
2934
2935   /* if this is a param node then do the left & right */
2936   if (parms->type == EX_OP && parms->opval.op == PARAM)
2937     {
2938       argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2939       argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2940       return argVals;
2941     }
2942
2943   /* get the parameter value */
2944   if (parms->type == EX_OPERAND)
2945     pval = parms->opval.oprnd;
2946   else
2947     {
2948       /* maybe this else should go away ?? */
2949       /* hack don't like this but too lazy to think of
2950          something better */
2951       if (IS_ADDRESS_OF_OP (parms))
2952         parms->left->lvalue = 1;
2953
2954       if (IS_CAST_OP (parms) &&
2955           IS_PTR (parms->ftype) &&
2956           IS_ADDRESS_OF_OP (parms->right))
2957         parms->right->left->lvalue = 1;
2958
2959       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2960     }
2961
2962   /* if register parm then make it a send */
2963   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2964       IFFUNC_ISBUILTIN(func->type))
2965     {
2966       ic = newiCode (SEND, pval, NULL);
2967       ic->argreg = SPEC_ARGREG(parms->etype);
2968       ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2969       ADDTOCHAIN (ic);
2970     }
2971   else
2972     {
2973       /* now decide whether to push or assign */
2974       if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2975         {
2976
2977           /* assign */
2978           operand *top = operandFromSymbol (argVals->sym);
2979           /* clear useDef and other bitVectors */
2980           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
2981           geniCodeAssign (top, pval, 1);
2982         }
2983       else
2984         {
2985           sym_link *p = operandType (pval);
2986           /* push */
2987           ic = newiCode (IPUSH, pval, NULL);
2988           ic->parmPush = 1;
2989           /* update the stack adjustment */
2990           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2991           ADDTOCHAIN (ic);
2992         }
2993     }
2994
2995   argVals=argVals->next;
2996   return argVals;
2997 }
2998
2999 /*-----------------------------------------------------------------*/
3000 /* geniCodeCall - generates temp code for calling                  */
3001 /*-----------------------------------------------------------------*/
3002 operand *
3003 geniCodeCall (operand * left, ast * parms,int lvl)
3004 {
3005   iCode *ic;
3006   operand *result;
3007   sym_link *type, *etype;
3008   int stack = 0;
3009
3010   if (!IS_FUNC(OP_SYMBOL(left)->type) && 
3011       !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3012     werror (E_FUNCTION_EXPECTED);
3013     return NULL;
3014   }
3015
3016   /* take care of parameters with side-effecting
3017      function calls in them, this is required to take care
3018      of overlaying function parameters */
3019   geniCodeSEParms (parms,lvl);
3020
3021   /* first the parameters */
3022   geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3023
3024   /* now call : if symbol then pcall */
3025   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3026     ic = newiCode (PCALL, left, NULL);
3027   } else {
3028     ic = newiCode (CALL, left, NULL);
3029   }
3030
3031   type = copyLinkChain (operandType (left)->next);
3032   etype = getSpec (type);
3033   SPEC_EXTR (etype) = 0;
3034   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3035
3036   ADDTOCHAIN (ic);
3037
3038   /* stack adjustment after call */
3039   ic->parmBytes = stack;
3040
3041   return result;
3042 }
3043
3044 /*-----------------------------------------------------------------*/
3045 /* geniCodeReceive - generate intermediate code for "receive"      */
3046 /*-----------------------------------------------------------------*/
3047 static void 
3048 geniCodeReceive (value * args)
3049 {
3050   /* for all arguments that are passed in registers */
3051   while (args)
3052     {
3053       int first = 1;
3054       if (IS_REGPARM (args->etype))
3055         {
3056           operand *opr = operandFromValue (args);
3057           operand *opl;
3058           symbol *sym = OP_SYMBOL (opr);
3059           iCode *ic;
3060
3061           /* we will use it after all optimizations
3062              and before liveRange calculation */
3063           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3064             {
3065
3066               if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
3067                   options.stackAuto == 0 &&
3068                   (!(options.model == MODEL_FLAT24)) )
3069                 {
3070                 }
3071               else
3072                 {
3073                   opl = newiTempOperand (args->type, 0);
3074                   sym->reqv = opl;
3075                   sym->reqv->key = sym->key;
3076                   OP_SYMBOL (sym->reqv)->key = sym->key;
3077                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3078                   OP_SYMBOL (sym->reqv)->islocal = 0;
3079                   SPIL_LOC (sym->reqv) = sym;
3080                 }
3081             }
3082
3083           ic = newiCode (RECEIVE, NULL, NULL);    
3084           ic->argreg = SPEC_ARGREG(args->etype);
3085           if (first) {
3086               currFunc->recvSize = getSize (sym->type);
3087               first = 0;
3088           }
3089           IC_RESULT (ic) = opr;
3090           ADDTOCHAIN (ic);
3091         }
3092
3093       args = args->next;
3094     }
3095 }
3096
3097 /*-----------------------------------------------------------------*/
3098 /* geniCodeFunctionBody - create the function body                 */
3099 /*-----------------------------------------------------------------*/
3100 void 
3101 geniCodeFunctionBody (ast * tree,int lvl)
3102 {
3103   iCode *ic;
3104   operand *func;
3105   sym_link *fetype;
3106   int savelineno;
3107
3108   /* reset the auto generation */
3109   /* numbers */
3110   iTempNum = 0;
3111   iTempLblNum = 0;
3112   operandKey = 0;
3113   iCodeKey = 0;
3114   func = ast2iCode (tree->left,lvl+1);
3115   fetype = getSpec (operandType (func));
3116
3117   savelineno = lineno;
3118   lineno = OP_SYMBOL (func)->lineDef;
3119   /* create an entry label */
3120   geniCodeLabel (entryLabel);
3121   lineno = savelineno;
3122
3123   /* create a proc icode */
3124   ic = newiCode (FUNCTION, func, NULL);
3125   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3126
3127   ADDTOCHAIN (ic);
3128
3129   /* for all parameters that are passed
3130      on registers add a "receive" */
3131   geniCodeReceive (tree->values.args);
3132
3133   /* generate code for the body */
3134   ast2iCode (tree->right,lvl+1);
3135
3136   /* create a label for return */
3137   geniCodeLabel (returnLabel);
3138
3139   /* now generate the end proc */
3140   ic = newiCode (ENDFUNCTION, func, NULL);
3141   ADDTOCHAIN (ic);
3142   return;
3143 }
3144
3145 /*-----------------------------------------------------------------*/
3146 /* geniCodeReturn - gen icode for 'return' statement               */
3147 /*-----------------------------------------------------------------*/
3148 void 
3149 geniCodeReturn (operand * op)
3150 {
3151   iCode *ic;
3152
3153   /* if the operand is present force an rvalue */
3154   if (op)
3155     op = geniCodeRValue (op, FALSE);
3156
3157   ic = newiCode (RETURN, op, NULL);
3158   ADDTOCHAIN (ic);
3159 }
3160
3161 /*-----------------------------------------------------------------*/
3162 /* geniCodeIfx - generates code for extended if statement          */
3163 /*-----------------------------------------------------------------*/
3164 void 
3165 geniCodeIfx (ast * tree,int lvl)
3166 {
3167   iCode *ic;
3168   operand *condition = ast2iCode (tree->left,lvl+1);
3169   sym_link *cetype;
3170
3171   /* if condition is null then exit */
3172   if (!condition)
3173     goto exit;
3174   else
3175     condition = geniCodeRValue (condition, FALSE);
3176
3177   cetype = getSpec (operandType (condition));
3178   /* if the condition is a literal */
3179   if (IS_LITERAL (cetype))
3180     {
3181       if (floatFromVal (condition->operand.valOperand))
3182         {
3183           if (tree->trueLabel)
3184             geniCodeGoto (tree->trueLabel);
3185           else
3186             assert (0);
3187         }
3188       else
3189         {
3190           if (tree->falseLabel)
3191             geniCodeGoto (tree->falseLabel);
3192           else
3193             assert (0);
3194         }
3195       goto exit;
3196     }
3197
3198   if (tree->trueLabel)
3199     {
3200       ic = newiCodeCondition (condition,
3201                               tree->trueLabel,
3202                               NULL);
3203       ADDTOCHAIN (ic);
3204
3205       if (tree->falseLabel)
3206         geniCodeGoto (tree->falseLabel);
3207     }
3208   else
3209     {
3210       ic = newiCodeCondition (condition,
3211                               NULL,
3212                               tree->falseLabel);
3213       ADDTOCHAIN (ic);
3214     }
3215
3216 exit:
3217   ast2iCode (tree->right,lvl+1);
3218 }
3219
3220 /*-----------------------------------------------------------------*/
3221 /* geniCodeJumpTable - tries to create a jump table for switch     */
3222 /*-----------------------------------------------------------------*/
3223 int 
3224 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3225 {
3226   int min = 0, max = 0, t, cnt = 0;
3227   value *vch;
3228   iCode *ic;
3229   operand *boundary;
3230   symbol *falseLabel;
3231   set *labels = NULL;
3232   int needRangeCheck = !optimize.noJTabBoundary
3233                        || tree->values.switchVals.swDefault;
3234
3235   if (!tree || !caseVals)
3236     return 0;
3237
3238   /* the criteria for creating a jump table is */
3239   /* all integer numbers between the maximum & minimum must */
3240   /* be present , the maximum value should not exceed 255 */
3241   min = max = (int) floatFromVal (vch = caseVals);
3242   SNPRINTF (buffer, sizeof(buffer), 
3243             "_case_%d_%d",
3244            tree->values.switchVals.swNum,
3245            min);
3246   addSet (&labels, newiTempLabel (buffer));
3247
3248   /* if there is only one case value then no need */
3249   if (!(vch = vch->next))
3250     return 0;
3251
3252   while (vch)
3253     {
3254       if (((t = (int) floatFromVal (vch)) - max) != 1)
3255         return 0;
3256       SNPRINTF (buffer, sizeof(buffer), 
3257                 "_case_%d_%d",
3258                tree->values.switchVals.swNum,
3259                t);
3260       addSet (&labels, newiTempLabel (buffer));
3261       max = t;
3262       cnt++;
3263       vch = vch->next;
3264     }
3265
3266   /* if the number of case statements <= 2 then */
3267   /* it is not economical to create the jump table */
3268   /* since two compares are needed for boundary conditions */
3269   if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3270     return 0;
3271
3272   if (tree->values.switchVals.swDefault)
3273     {
3274         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3275     }
3276   else
3277     {
3278         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3279     }
3280     
3281
3282   falseLabel = newiTempLabel (buffer);
3283
3284   /* so we can create a jumptable */
3285   /* first we rule out the boundary conditions */
3286   /* if only optimization says so */
3287   if (needRangeCheck)
3288     {
3289       sym_link *cetype = getSpec (operandType (cond));
3290       /* no need to check the lower bound if
3291          the condition is unsigned & minimum value is zero */
3292       if (!(min == 0 && SPEC_USIGN (cetype)))
3293         {
3294           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3295           ic = newiCodeCondition (boundary, falseLabel, NULL);
3296           ADDTOCHAIN (ic);
3297         }
3298
3299       /* now for upper bounds */
3300       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3301       ic = newiCodeCondition (boundary, falseLabel, NULL);
3302       ADDTOCHAIN (ic);
3303     }
3304
3305   /* if the min is not zero then we no make it zero */
3306   if (min)
3307     {
3308       cond = geniCodeSubtract (cond, operandFromLit (min));
3309       if (!IS_LITERAL(getSpec(operandType(cond))))
3310         setOperandType (cond, UCHARTYPE);
3311     }
3312
3313   /* now create the jumptable */
3314   ic = newiCode (JUMPTABLE, NULL, NULL);
3315   IC_JTCOND (ic) = cond;
3316   IC_JTLABELS (ic) = labels;
3317   ADDTOCHAIN (ic);
3318   return 1;
3319 }
3320
3321 /*-----------------------------------------------------------------*/
3322 /* geniCodeSwitch - changes a switch to a if statement             */
3323 /*-----------------------------------------------------------------*/
3324 void
3325 geniCodeSwitch (ast * tree,int lvl)
3326 {
3327   iCode *ic;
3328   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3329   value *caseVals = tree->values.switchVals.swVals;
3330   symbol *trueLabel, *falseLabel;
3331       
3332   /* If the condition is a literal, then just jump to the */
3333   /* appropriate case label. */
3334   if (IS_LITERAL(getSpec(operandType(cond))))
3335     {
3336       int switchVal, caseVal;
3337       
3338       switchVal = (int) floatFromVal (cond->operand.valOperand);
3339       while (caseVals)
3340         {
3341           caseVal = (int) floatFromVal (caseVals);
3342           if (caseVal == switchVal)
3343             {
3344               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3345                         tree->values.switchVals.swNum, caseVal);
3346               trueLabel = newiTempLabel (buffer);
3347               geniCodeGoto (trueLabel);
3348               goto jumpTable;
3349             }
3350           caseVals = caseVals->next;
3351         }
3352       goto defaultOrBreak;
3353     }
3354
3355   /* if we can make this a jump table */
3356   if (geniCodeJumpTable (cond, caseVals, tree))
3357     goto jumpTable;             /* no need for the comparison */
3358
3359   /* for the cases defined do */
3360   while (caseVals)
3361     {
3362
3363       operand *compare = geniCodeLogic (cond,
3364                                         operandFromValue (caseVals),
3365                                         EQ_OP);
3366
3367       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3368                tree->values.switchVals.swNum,
3369                (int) floatFromVal (caseVals));
3370       trueLabel = newiTempLabel (buffer);
3371
3372       ic = newiCodeCondition (compare, trueLabel, NULL);
3373       ADDTOCHAIN (ic);
3374       caseVals = caseVals->next;
3375     }
3376
3377
3378 defaultOrBreak:
3379   /* if default is present then goto break else break */
3380   if (tree->values.switchVals.swDefault)
3381     {
3382         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3383     }
3384   else
3385     {
3386         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3387     }
3388
3389   falseLabel = newiTempLabel (buffer);
3390   geniCodeGoto (falseLabel);
3391
3392 jumpTable:
3393   ast2iCode (tree->right,lvl+1);
3394 }
3395
3396 /*-----------------------------------------------------------------*/
3397 /* geniCodeInline - intermediate code for inline assembler         */
3398 /*-----------------------------------------------------------------*/
3399 static void 
3400 geniCodeInline (ast * tree)
3401 {
3402   iCode *ic;
3403
3404   ic = newiCode (INLINEASM, NULL, NULL);
3405   IC_INLINE (ic) = tree->values.inlineasm;
3406   ADDTOCHAIN (ic);
3407 }
3408
3409 /*-----------------------------------------------------------------*/
3410 /* geniCodeArrayInit - intermediate code for array initializer     */
3411 /*-----------------------------------------------------------------*/
3412 static void 
3413 geniCodeArrayInit (ast * tree, operand *array)
3414 {
3415   iCode *ic;
3416
3417   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3418     ic = newiCode (ARRAYINIT, array, NULL);
3419     IC_ARRAYILIST (ic) = tree->values.constlist;
3420   } else {
3421     operand *left=newOperand(), *right=newOperand();
3422     left->type=right->type=SYMBOL;
3423     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3424     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3425     ic = newiCode (ARRAYINIT, left, right);
3426   }
3427   ADDTOCHAIN (ic);
3428 }
3429
3430 /*-----------------------------------------------------------------*/
3431 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3432 /* particular case. Ie : assigning or dereferencing array or ptr   */
3433 /*-----------------------------------------------------------------*/
3434 set * lvaluereqSet = NULL;
3435 typedef struct lvalItem
3436   {
3437     int req;
3438     int lvl;
3439   }
3440 lvalItem;
3441
3442 /*-----------------------------------------------------------------*/
3443 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3444 /*-----------------------------------------------------------------*/
3445 void addLvaluereq(int lvl)
3446 {
3447   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3448   lpItem->req=1;
3449   lpItem->lvl=lvl;
3450   addSetHead(&lvaluereqSet,lpItem);
3451
3452 }
3453 /*-----------------------------------------------------------------*/
3454 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3455 /*-----------------------------------------------------------------*/
3456 void delLvaluereq()
3457 {
3458   lvalItem * lpItem;
3459   lpItem = getSet(&lvaluereqSet);
3460   if(lpItem) Safe_free(lpItem);
3461 }
3462 /*-----------------------------------------------------------------*/
3463 /* clearLvaluereq - clear lvalreq flag                             */
3464 /*-----------------------------------------------------------------*/
3465 void clearLvaluereq()
3466 {
3467   lvalItem * lpItem;
3468   lpItem = peekSet(lvaluereqSet);
3469   if(lpItem) lpItem->req = 0;
3470 }
3471 /*-----------------------------------------------------------------*/
3472 /* getLvaluereq - get the last lvalreq level                       */
3473 /*-----------------------------------------------------------------*/
3474 int getLvaluereqLvl()
3475 {
3476   lvalItem * lpItem;
3477   lpItem = peekSet(lvaluereqSet);
3478   if(lpItem) return lpItem->lvl;
3479   return 0;
3480 }
3481 /*-----------------------------------------------------------------*/
3482 /* isLvaluereq - is lvalreq valid for this level ?                 */
3483 /*-----------------------------------------------------------------*/
3484 int isLvaluereq(int lvl)
3485 {
3486   lvalItem * lpItem;
3487   lpItem = peekSet(lvaluereqSet);
3488   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3489   return 0;
3490 }
3491
3492 /*-----------------------------------------------------------------*/
3493 /* ast2iCode - creates an icodeList from an ast                    */
3494 /*-----------------------------------------------------------------*/
3495 operand *
3496 ast2iCode (ast * tree,int lvl)
3497 {
3498   operand *left = NULL;
3499   operand *right = NULL;
3500   if (!tree)
3501     return NULL;
3502
3503   /* set the global variables for filename & line number */
3504   if (tree->filename)
3505     filename = tree->filename;
3506   if (tree->lineno)
3507     lineno = tree->lineno;
3508   if (tree->block)
3509     block = tree->block;
3510   if (tree->level)
3511     scopeLevel = tree->level;
3512
3513   if (tree->type == EX_VALUE)
3514     return operandFromValue (tree->opval.val);
3515
3516   if (tree->type == EX_LINK)
3517     return operandFromLink (tree->opval.lnk);
3518
3519   /* if we find a nullop */
3520   if (tree->type == EX_OP &&
3521      (tree->opval.op == NULLOP ||
3522      tree->opval.op == BLOCK))
3523     {
3524       if (tree->left && tree->left->type == EX_VALUE)
3525         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3526       else
3527         ast2iCode (tree->left,lvl+1);
3528       if (tree->right && tree->right->type == EX_VALUE)
3529         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3530       else
3531         ast2iCode (tree->right,lvl+1);
3532       return NULL;
3533     }
3534
3535   /* special cases for not evaluating */
3536   if (tree->opval.op != ':' &&
3537       tree->opval.op != '?' &&
3538       tree->opval.op != CALL &&
3539       tree->opval.op != IFX &&
3540       tree->opval.op != LABEL &&
3541       tree->opval.op != GOTO &&
3542       tree->opval.op != SWITCH &&
3543       tree->opval.op != FUNCTION &&
3544       tree->opval.op != INLINEASM)
3545     {
3546
3547         if (IS_ASSIGN_OP (tree->opval.op) ||
3548            IS_DEREF_OP (tree) ||
3549            (tree->opval.op == '&' && !tree->right) ||
3550            tree->opval.op == PTR_OP)
3551           {
3552             addLvaluereq(lvl);
3553             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3554                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3555               clearLvaluereq();
3556
3557             left = operandFromAst (tree->left,lvl);
3558             delLvaluereq();
3559             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3560               left = geniCodeRValue (left, TRUE);
3561           }
3562         else
3563           {
3564             left = operandFromAst (tree->left,lvl);
3565           }
3566         if (tree->opval.op == INC_OP ||
3567             tree->opval.op == DEC_OP)
3568           {
3569             addLvaluereq(lvl);
3570             right = operandFromAst (tree->right,lvl);
3571             delLvaluereq();
3572           }
3573         else
3574           {
3575             right = operandFromAst (tree->right,lvl);
3576           }
3577       }
3578
3579   /* now depending on the type of operand */
3580   /* this will be a biggy                 */
3581   switch (tree->opval.op)
3582     {
3583
3584     case '[':                   /* array operation */
3585       {
3586         //sym_link *ltype = operandType (left);
3587         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3588         left = geniCodeRValue (left, FALSE);
3589         right = geniCodeRValue (right, TRUE);
3590       }
3591
3592       return geniCodeArray (left, right,lvl);
3593
3594     case '.':                   /* structure dereference */
3595       if (IS_PTR (operandType (left)))
3596         left = geniCodeRValue (left, TRUE);
3597       else
3598         left = geniCodeRValue (left, FALSE);
3599
3600       return geniCodeStruct (left, right, tree->lvalue);
3601
3602     case PTR_OP:                /* structure pointer dereference */
3603       {
3604         sym_link *pType;
3605         pType = operandType (left);
3606         left = geniCodeRValue (left, TRUE);
3607
3608         setOClass (pType, getSpec (operandType (left)));
3609       }
3610
3611       return geniCodeStruct (left, right, tree->lvalue);
3612
3613     case INC_OP:                /* increment operator */
3614       if (left)
3615         return geniCodePostInc (left);
3616       else
3617         return geniCodePreInc (right);
3618
3619     case DEC_OP:                /* decrement operator */
3620       if (left)
3621         return geniCodePostDec (left);
3622       else
3623         return geniCodePreDec (right);
3624
3625     case '&':                   /* bitwise and or address of operator */
3626       if (right)
3627         {                       /* this is a bitwise operator   */
3628           left = geniCodeRValue (left, FALSE);
3629           right = geniCodeRValue (right, FALSE);
3630           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3631         }
3632       else
3633         return geniCodeAddressOf (left);
3634
3635     case '|':                   /* bitwise or & xor */
3636     case '^':
3637       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3638                               geniCodeRValue (right, FALSE),
3639                               tree->opval.op,
3640                               tree->ftype);
3641
3642     case '/':
3643       return geniCodeDivision (geniCodeRValue (left, FALSE),
3644                                geniCodeRValue (right, FALSE));
3645
3646     case '%':
3647       return geniCodeModulus (geniCodeRValue (left, FALSE),
3648                               geniCodeRValue (right, FALSE));
3649     case '*':
3650       if (right)
3651         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3652                                  geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3653       else
3654         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3655
3656     case '-':
3657       if (right)
3658         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3659                                  geniCodeRValue (right, FALSE));
3660       else
3661         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3662
3663     case '+':
3664       if (right)
3665         return geniCodeAdd (geniCodeRValue (left, FALSE),
3666                             geniCodeRValue (right, FALSE),lvl);
3667       else
3668         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3669
3670     case LEFT_OP:
3671       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3672                                 geniCodeRValue (right, FALSE));
3673
3674     case RIGHT_OP:
3675       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3676                                  geniCodeRValue (right, FALSE));
3677     case CAST: 
3678 #if 0 // this indeed needs a second thought
3679       {
3680         operand *op;
3681         
3682         // let's keep this simple: get the rvalue we need
3683         op=geniCodeRValue (right, FALSE);
3684         // now cast it to whatever we want
3685         op=geniCodeCast (operandType(left), op, FALSE);
3686         // if this is going to be used as an lvalue, make it so
3687         if (tree->lvalue) {
3688           op->isaddr=1;
3689         }
3690         return op;
3691       }
3692 #else // bug #604575, is it a bug ????
3693       return geniCodeCast (operandType (left),
3694                            geniCodeRValue (right, FALSE), FALSE);
3695 #endif
3696
3697     case '~':
3698     case RRC:
3699     case RLC:
3700       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3701
3702     case '!':
3703     case GETHBIT:
3704       {
3705         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3706         setOperandType (op, UCHARTYPE);
3707         return op;
3708       }
3709     case '>':
3710     case '<':
3711     case LE_OP:
3712     case GE_OP:
3713     case EQ_OP:
3714     case NE_OP:
3715     case AND_OP:
3716     case OR_OP:
3717       /* different compilers (even different gccs) evaluate
3718          the two calls in a different order. to get the same
3719          result on all machines we've to specify a clear sequence.
3720       return geniCodeLogic (geniCodeRValue (left, FALSE),
3721                             geniCodeRValue (right, FALSE),
3722                             tree->opval.op);
3723       */
3724       {
3725         operand *leftOp, *rightOp;
3726
3727         rightOp = geniCodeRValue (right, FALSE);
3728         leftOp  = geniCodeRValue (left , FALSE);
3729
3730         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3731       }
3732     case '?':
3733       return geniCodeConditional (tree,lvl);
3734
3735     case SIZEOF:
3736       return operandFromLit (getSize (tree->right->ftype));
3737
3738     case '=':
3739       {
3740         sym_link *rtype = operandType (right);
3741         sym_link *ltype = operandType (left);
3742         if (IS_PTR (rtype) && IS_ITEMP (right)
3743             && right->isaddr && compareType (rtype->next, ltype) == 1)
3744           right = geniCodeRValue (right, TRUE);
3745         else
3746           right = geniCodeRValue (right, FALSE);
3747
3748         geniCodeAssign (left, right, 0);
3749         return right;
3750       }
3751     case MUL_ASSIGN:
3752       return
3753         geniCodeAssign (left,
3754                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3755                                                   FALSE),
3756                                   geniCodeRValue (right, FALSE),FALSE), 0);
3757
3758     case DIV_ASSIGN:
3759       return
3760         geniCodeAssign (left,
3761                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3762                                                   FALSE),
3763                                   geniCodeRValue (right, FALSE)), 0);
3764     case MOD_ASSIGN:
3765       return
3766         geniCodeAssign (left,
3767                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3768                                                   FALSE),
3769                                   geniCodeRValue (right, FALSE)), 0);
3770     case ADD_ASSIGN:
3771       {
3772         sym_link *rtype = operandType (right);
3773         sym_link *ltype = operandType (left);
3774         if (IS_PTR (rtype) && IS_ITEMP (right)
3775             && right->isaddr && compareType (rtype->next, ltype) == 1)
3776           right = geniCodeRValue (right, TRUE);
3777         else
3778           right = geniCodeRValue (right, FALSE);
3779
3780
3781         return geniCodeAssign (left,
3782                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3783                                                   FALSE),
3784                                   right,lvl), 0);
3785       }
3786     case SUB_ASSIGN:
3787       {
3788         sym_link *rtype = operandType (right);
3789         sym_link *ltype = operandType (left);
3790         if (IS_PTR (rtype) && IS_ITEMP (right)
3791             && right->isaddr && compareType (rtype->next, ltype) == 1)
3792           {
3793             right = geniCodeRValue (right, TRUE);
3794           }
3795         else
3796           {
3797             right = geniCodeRValue (right, FALSE);
3798           }
3799         return
3800           geniCodeAssign (left,
3801                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3802                                                   FALSE),
3803                                   right), 0);
3804       }
3805     case LEFT_ASSIGN:
3806       return
3807         geniCodeAssign (left,
3808                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3809                                                    ,FALSE),
3810                                    geniCodeRValue (right, FALSE)), 0);
3811     case RIGHT_ASSIGN:
3812       return
3813         geniCodeAssign (left,
3814                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3815                                                    ,FALSE),
3816                                    geniCodeRValue (right, FALSE)), 0);
3817     case AND_ASSIGN:
3818       return
3819         geniCodeAssign (left,
3820                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3821                                                   FALSE),
3822                                   geniCodeRValue (right, FALSE),
3823                                   BITWISEAND,
3824                                   operandType (left)), 0);
3825     case XOR_ASSIGN:
3826       return
3827         geniCodeAssign (left,
3828                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3829                                                   FALSE),
3830                                   geniCodeRValue (right, FALSE),
3831                                   '^',
3832                                   operandType (left)), 0);
3833     case OR_ASSIGN:
3834       return
3835         geniCodeAssign (left,
3836                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3837                                                    ,FALSE),
3838                                    geniCodeRValue (right, FALSE),
3839                                    '|',
3840                                    operandType (left)), 0);
3841     case ',':
3842       return geniCodeRValue (right, FALSE);
3843
3844     case CALL:
3845       return geniCodeCall (ast2iCode (tree->left,lvl+1),
3846                            tree->right,lvl);
3847     case LABEL:
3848       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3849       return ast2iCode (tree->right,lvl+1);
3850
3851     case GOTO:
3852       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3853       return ast2iCode (tree->right,lvl+1);
3854
3855     case FUNCTION:
3856       geniCodeFunctionBody (tree,lvl);
3857       return NULL;
3858
3859     case RETURN:
3860       geniCodeReturn (right);
3861       return NULL;
3862
3863     case IFX:
3864       geniCodeIfx (tree,lvl);
3865       return NULL;
3866
3867     case SWITCH:
3868       geniCodeSwitch (tree,lvl);
3869       return NULL;
3870
3871     case INLINEASM:
3872       geniCodeInline (tree);
3873       return NULL;
3874         
3875     case ARRAYINIT:
3876         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3877         return NULL;
3878     }
3879
3880   return NULL;
3881 }
3882
3883 /*-----------------------------------------------------------------*/
3884 /* reverseICChain - gets from the list and creates a linkedlist    */
3885 /*-----------------------------------------------------------------*/
3886 iCode *
3887 reverseiCChain ()
3888 {
3889   iCode *loop = NULL;
3890   iCode *prev = NULL;
3891
3892   while ((loop = getSet (&iCodeChain)))
3893     {
3894       loop->next = prev;
3895       if (prev)
3896         prev->prev = loop;
3897       prev = loop;
3898     }
3899
3900   return prev;
3901 }
3902
3903
3904 /*-----------------------------------------------------------------*/
3905 /* iCodeFromAst - given an ast will convert it to iCode            */
3906 /*-----------------------------------------------------------------*/
3907 iCode *
3908 iCodeFromAst (ast * tree)
3909 {
3910   returnLabel = newiTempLabel ("_return");
3911   entryLabel = newiTempLabel ("_entry");
3912   ast2iCode (tree,0);
3913   return reverseiCChain ();
3914 }
3915
3916 static const char *opTypeToStr(OPTYPE op)
3917 {
3918     switch(op)
3919     {
3920       case SYMBOL: return "symbol";
3921       case VALUE: return "value";
3922       case TYPE: return "type";
3923     }
3924     return "undefined type";    
3925 }
3926
3927
3928 operand *validateOpType(operand         *op, 
3929                         const char      *macro,
3930                         const char      *args,
3931                         OPTYPE          type,
3932                         const char      *file, 
3933                         unsigned        line)
3934 {    
3935     if (op && op->type == type)
3936     {
3937         return op;
3938     }
3939     fprintf(stderr, 
3940             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
3941             " expected %s, got %s\n",
3942             macro, args, file, line, 
3943             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
3944     exit(-1);
3945     return op; // never reached, makes compiler happy.
3946 }