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