* src/pic16/ralloc.c (packRegsForAccUse): disabled functions with #if to eliminate...
[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 *, bool);
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)->prereqv = sym;
1537       OP_SYMBOL (sym->reqv)->key = sym->key;
1538       OP_SYMBOL (sym->reqv)->isreqv = 1;
1539       OP_SYMBOL (sym->reqv)->islocal = 1;
1540       OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1541       SPIL_LOC (sym->reqv) = sym;
1542     }
1543
1544   if (!IS_AGGREGATE (sym->type))
1545     {
1546       op = newOperand ();
1547       op->type = SYMBOL;
1548       op->operand.symOperand = sym;
1549       op->isaddr = 1;
1550       op->key = sym->key;
1551       op->isvolatile = isOperandVolatile (op, TRUE);
1552       op->isGlobal = isOperandGlobal (op);
1553       op->isPtr = IS_PTR (operandType (op));
1554       op->isParm = sym->_isparm;
1555       return op;
1556     }
1557
1558   /* create :-                     */
1559   /*    itemp = &[_symbol]         */
1560
1561   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1562   IC_LEFT (ic)->type = SYMBOL;
1563   IC_LEFT (ic)->operand.symOperand = sym;
1564   IC_LEFT (ic)->key = sym->key;
1565   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1566   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1567   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1568
1569   /* create result */
1570   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1571   if (IS_ARRAY (sym->type))
1572     {
1573       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1574       IC_RESULT (ic)->isaddr = 0;
1575     }
1576   else
1577     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1578
1579   ADDTOCHAIN (ic);
1580
1581   return IC_RESULT (ic);
1582 }
1583
1584 /*-----------------------------------------------------------------*/
1585 /* operandFromValue - creates an operand from value                */
1586 /*-----------------------------------------------------------------*/
1587 operand *
1588 operandFromValue (value * val)
1589 {
1590   operand *op;
1591
1592   /* if this is a symbol then do the symbol thing */
1593   if (val->sym)
1594     return operandFromSymbol (val->sym);
1595
1596   /* this is not a symbol */
1597   op = newOperand ();
1598   op->type = VALUE;
1599   op->operand.valOperand = val;
1600   op->isLiteral = isOperandLiteral (op);
1601   return op;
1602 }
1603
1604 /*-----------------------------------------------------------------*/
1605 /* operandFromLink - operand from typeChain                        */
1606 /*-----------------------------------------------------------------*/
1607 operand *
1608 operandFromLink (sym_link * type)
1609 {
1610   operand *op;
1611
1612   /* operand from sym_link */
1613   if (!type)
1614     return NULL;
1615
1616   op = newOperand ();
1617   op->type = TYPE;
1618   op->operand.typeOperand = copyLinkChain (type);
1619   return op;
1620 }
1621
1622 /*-----------------------------------------------------------------*/
1623 /* operandFromLit - makes an operand from a literal value          */
1624 /*-----------------------------------------------------------------*/
1625 operand *
1626 operandFromLit (double i)
1627 {
1628   return operandFromValue (valueFromLit (i));
1629 }
1630
1631 /*-----------------------------------------------------------------*/
1632 /* operandFromAst - creates an operand from an ast                 */
1633 /*-----------------------------------------------------------------*/
1634 operand *
1635 operandFromAst (ast * tree,int lvl)
1636 {
1637
1638   if (!tree)
1639     return NULL;
1640
1641   /* depending on type do */
1642   switch (tree->type)
1643     {
1644     case EX_OP:
1645       return ast2iCode (tree,lvl+1);
1646       break;
1647
1648     case EX_VALUE:
1649       return operandFromValue (tree->opval.val);
1650       break;
1651
1652     case EX_LINK:
1653       return operandFromLink (tree->opval.lnk);
1654       break;
1655
1656     default:
1657       assert (0);
1658     }
1659   
1660   /*  Just to keep the compiler happy */
1661   return (operand *) 0;
1662 }
1663
1664 /*-----------------------------------------------------------------*/
1665 /* setOperandType - sets the operand's type to the given type      */
1666 /*-----------------------------------------------------------------*/
1667 void 
1668 setOperandType (operand * op, sym_link * type)
1669 {
1670   /* depending on the type of operand */
1671   switch (op->type)
1672     {
1673
1674     case VALUE:
1675       op->operand.valOperand->etype =
1676         getSpec (op->operand.valOperand->type =
1677                  copyLinkChain (type));
1678       return;
1679
1680     case SYMBOL:
1681       if (op->operand.symOperand->isitmp)
1682         op->operand.symOperand->etype =
1683           getSpec (op->operand.symOperand->type =
1684                    copyLinkChain (type));
1685       else
1686         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1687                 "attempt to modify type of source");
1688       return;
1689
1690     case TYPE:
1691       op->operand.typeOperand = copyLinkChain (type);
1692       return;
1693     }
1694
1695 }
1696 /*-----------------------------------------------------------------*/
1697 /* Get size in byte of ptr need to access an array                 */
1698 /*-----------------------------------------------------------------*/
1699 int
1700 getArraySizePtr (operand * op)
1701 {
1702   sym_link *ltype = operandType(op);
1703
1704   if(IS_PTR(ltype))
1705     {
1706       int size = getSize(ltype);
1707       return(IS_GENPTR(ltype)?(size-1):size);
1708     }
1709
1710   if(IS_ARRAY(ltype))
1711     {
1712       sym_link *letype = getSpec(ltype);
1713       switch (PTR_TYPE (SPEC_OCLS (letype)))
1714         {
1715         case IPOINTER:
1716         case PPOINTER:
1717         case POINTER:
1718           return (PTRSIZE);
1719         case EEPPOINTER:
1720         case FPOINTER:
1721         case CPOINTER:
1722         case FUNCTION:
1723           return (FPTRSIZE);
1724         case GPOINTER:
1725           return (GPTRSIZE-1);
1726
1727         default:
1728           return (FPTRSIZE);
1729         }
1730     }
1731   return (FPTRSIZE);
1732 }
1733
1734 /*-----------------------------------------------------------------*/
1735 /* perform "usual unary conversions"                               */
1736 /*-----------------------------------------------------------------*/
1737 #if 0
1738 static operand *
1739 usualUnaryConversions (operand * op)
1740 {
1741   if (IS_INTEGRAL (operandType (op)))
1742     {
1743       if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1744         {
1745           /* Widen to int. */
1746           return geniCodeCast (INTTYPE, op, TRUE);
1747         }
1748     }
1749   return op;
1750 }
1751 #endif
1752
1753 /*-----------------------------------------------------------------*/
1754 /* perform "usual binary conversions"                              */
1755 /*-----------------------------------------------------------------*/
1756
1757 static sym_link *
1758 usualBinaryConversions (operand ** op1, operand ** op2,
1759                         bool resultIsInt, char op)
1760 {
1761   sym_link *ctype;
1762   sym_link *rtype = operandType (*op2);
1763   sym_link *ltype = operandType (*op1);
1764
1765 #define OLDONEBYTEOPS 1
1766
1767 #ifdef OLDONEBYTEOPS  
1768   bool oldOneByteOps = FALSE;
1769   static bool saidHello = FALSE;
1770   
1771   if (strcmp (port->target, "pic14") == 0)
1772     oldOneByteOps = TRUE;
1773   if (getenv ("SDCC_NEWONEBYTEOPS"))
1774     {
1775       if (!saidHello)
1776         {
1777           fprintf (stderr, "Override: oldOneByteOps = FALSE\n");
1778           saidHello = TRUE;
1779         }
1780       oldOneByteOps = FALSE;
1781     }
1782   else if (getenv ("SDCC_OLDONEBYTEOPS"))
1783     {
1784       if (!saidHello)
1785         {
1786           fprintf (stderr, "Override: oldOneByteOps = TRUE\n");
1787           saidHello = TRUE;
1788         }
1789       oldOneByteOps = TRUE;
1790     }
1791
1792
1793   if (   oldOneByteOps
1794       && (   (IS_CHAR (getSpec (ltype)) && !IS_UNSIGNED (getSpec (ltype)))
1795           || (IS_CHAR (getSpec (rtype)) && !IS_UNSIGNED (getSpec (rtype)))))
1796     /* one or two signed char operands: promote to int */
1797     resultIsInt = TRUE;
1798 #endif
1799   
1800   ctype = computeType (ltype, rtype, resultIsInt);
1801
1802 #ifdef OLDONEBYTEOPS
1803
1804   if (oldOneByteOps)
1805     {
1806       if (   op == '*'
1807           && IS_CHAR (getSpec (ltype)) && IS_UNSIGNED (getSpec (ltype))
1808           && IS_CHAR (getSpec (rtype)) && IS_UNSIGNED (getSpec (rtype)))
1809           {
1810             /* two unsigned char operands and Mult: no promotion */
1811             return ctype;
1812           }
1813       *op1 = geniCodeCast (ctype, *op1, TRUE);
1814       *op2 = geniCodeCast (ctype, *op2, TRUE);
1815
1816       return ctype;
1817     }
1818
1819 #endif
1820
1821   switch (op)
1822     {
1823       case '*':
1824       case '/':
1825       case '%':
1826         if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1827           {
1828             /* one byte operations: keep signedness for code generator */
1829             return ctype;
1830           }
1831         break;
1832       default:
1833         break;
1834     }
1835
1836   *op1 = geniCodeCast (ctype, *op1, TRUE);
1837   *op2 = geniCodeCast (ctype, *op2, TRUE);
1838         
1839   return ctype;
1840 }
1841
1842 /*-----------------------------------------------------------------*/
1843 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1844 /*                          at address                             */
1845 /*-----------------------------------------------------------------*/
1846 operand *
1847 geniCodeRValue (operand * op, bool force)
1848 {
1849   iCode *ic;
1850   sym_link *type = operandType (op);
1851   sym_link *etype = getSpec (type);
1852
1853   /* if this is an array & already */
1854   /* an address then return this   */
1855   if (IS_AGGREGATE (type) ||
1856       (IS_PTR (type) && !force && !op->isaddr))
1857     return operandFromOperand (op);
1858
1859   /* if this is not an address then must be */
1860   /* rvalue already so return this one      */
1861   if (!op->isaddr)
1862     return op;
1863
1864   /* if this is not a temp symbol then */
1865   if (!IS_ITEMP (op) &&
1866       !force &&
1867       !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1868     {
1869       op = operandFromOperand (op);
1870       op->isaddr = 0;
1871       return op;
1872     }
1873
1874   if (IS_SPEC (type) &&
1875       IS_TRUE_SYMOP (op) &&
1876       (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1877       (options.model == MODEL_FLAT24) ))
1878     {
1879       op = operandFromOperand (op);
1880       op->isaddr = 0;
1881       return op;
1882     }
1883
1884   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1885   if (IS_PTR (type) && op->isaddr && force)
1886     type = type->next;
1887
1888   type = copyLinkChain (type);
1889
1890   IC_RESULT (ic) = newiTempOperand (type, 1);
1891   IC_RESULT (ic)->isaddr = 0;
1892
1893 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1894
1895   ADDTOCHAIN (ic);
1896
1897   return IC_RESULT (ic);
1898 }
1899
1900 /*-----------------------------------------------------------------*/
1901 /* geniCodeCast - changes the value from one type to another       */
1902 /*-----------------------------------------------------------------*/
1903 static operand *
1904 geniCodeCast (sym_link * type, operand * op, bool implicit)
1905 {
1906   iCode *ic;
1907   sym_link *optype;
1908   sym_link *opetype = getSpec (optype = operandType (op));
1909   sym_link *restype;
1910   int errors=0;
1911
1912   /* one of them has size zero then error */
1913   if (IS_VOID (optype))
1914     {
1915       werror (E_CAST_ZERO);
1916       return op;
1917     }
1918
1919   if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1920     {
1921       geniCodeArray2Ptr (op);
1922       op->isaddr = 0;
1923     }
1924     
1925   /* if the operand is already the desired type then do nothing */
1926   if (compareType (type, optype) == 1)
1927     return op;
1928
1929   /* if this is a literal then just change the type & return */
1930   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1931     {
1932       return operandFromValue (valCastLiteral (type,
1933                                                operandLitValue (op)));
1934     }
1935
1936   /* if casting to/from pointers, do some checking */
1937   if (IS_PTR(type)) { // to a pointer
1938     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1939       if (IS_INTEGRAL(optype)) {
1940         // maybe this is NULL, than it's ok.
1941         if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1942           if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1943             // no way to set the storage
1944             if (IS_LITERAL(optype)) {
1945               werror(E_LITERAL_GENERIC);
1946               errors++;
1947             } else {
1948               werror(E_NONPTR2_GENPTR);
1949               errors++;
1950             }
1951           } else if (implicit) {
1952             werror(W_INTEGRAL2PTR_NOCAST);
1953             errors++;
1954           }
1955         }
1956       } else {
1957         // shouldn't do that with float, array or structure unless to void
1958         if (!IS_VOID(getSpec(type)) &&
1959             !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1960           werror(E_INCOMPAT_TYPES);
1961           errors++;
1962         }
1963       }
1964     } else { // from a pointer to a pointer
1965       if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1966         // if not a pointer to a function
1967         if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1968           if (implicit) { // if not to generic, they have to match
1969             if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1970               werror(E_INCOMPAT_PTYPES);
1971               errors++;
1972             }
1973           }
1974         }
1975       }
1976     }
1977   } else { // to a non pointer
1978     if (IS_PTR(optype)) { // from a pointer
1979       if (implicit) { // sneaky
1980         if (IS_INTEGRAL(type)) {
1981           werror(W_PTR2INTEGRAL_NOCAST);
1982           errors++;
1983         } else { // shouldn't do that with float, array or structure
1984           werror(E_INCOMPAT_TYPES);
1985           errors++;
1986         }
1987       }
1988     }
1989   }
1990   if (errors) {
1991     printFromToType (optype, type);
1992   }
1993
1994   /* if they are the same size create an assignment */
1995   
1996   /* This seems very dangerous to me, since there are several */
1997   /* optimizations (for example, gcse) that don't notice the  */
1998   /* cast hidden in this assignement and may simplify an      */
1999   /* iCode to use the original (uncasted) operand.            */
2000   /* Unfortunately, other things break when this cast is      */
2001   /* made explicit. Need to fix this someday.                 */
2002   /* -- EEP, 2004/01/21                                       */
2003   if (getSize (type) == getSize (optype) &&
2004       !IS_BITFIELD (type) &&
2005       !IS_FLOAT (type) &&
2006       !IS_FLOAT (optype) &&
2007       ((IS_SPEC (type) && IS_SPEC (optype)) ||
2008        (!IS_SPEC (type) && !IS_SPEC (optype))))
2009     {
2010       ic = newiCode ('=', NULL, op);
2011       IC_RESULT (ic) = newiTempOperand (type, 0);
2012       SPIL_LOC (IC_RESULT (ic)) =
2013         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2014       IC_RESULT (ic)->isaddr = 0;
2015     }
2016   else
2017     {
2018       ic = newiCode (CAST, operandFromLink (type),
2019                      geniCodeRValue (op, FALSE));
2020
2021       IC_RESULT (ic) = newiTempOperand (type, 0);
2022     }
2023
2024   /* preserve the storage class & output class */
2025   /* of the original variable                  */
2026   restype = getSpec (operandType (IC_RESULT (ic)));
2027   if (!IS_LITERAL(opetype))
2028       SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2029   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2030
2031   ADDTOCHAIN (ic);
2032   return IC_RESULT (ic);
2033 }
2034
2035 /*-----------------------------------------------------------------*/
2036 /* geniCodeLabel - will create a Label                             */
2037 /*-----------------------------------------------------------------*/
2038 void
2039 geniCodeLabel (symbol * label)
2040 {
2041   iCode *ic;
2042
2043   ic = newiCodeLabelGoto (LABEL, label);
2044   ADDTOCHAIN (ic);
2045 }
2046
2047 /*-----------------------------------------------------------------*/
2048 /* geniCodeGoto  - will create a Goto                              */
2049 /*-----------------------------------------------------------------*/
2050 void
2051 geniCodeGoto (symbol * label)
2052 {
2053   iCode *ic;
2054
2055   ic = newiCodeLabelGoto (GOTO, label);
2056   ADDTOCHAIN (ic);
2057 }
2058
2059 /*-----------------------------------------------------------------*/
2060 /* geniCodeMultiply - gen intermediate code for multiplication     */
2061 /*-----------------------------------------------------------------*/
2062 operand *
2063 geniCodeMultiply (operand * left, operand * right, bool resultIsInt)
2064 {
2065   iCode *ic;
2066   int p2 = 0;
2067   sym_link *resType;
2068   LRTYPE;
2069
2070   /* if they are both literal then we know the result */
2071   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2072     return operandFromValue (valMult (left->operand.valOperand,
2073                                       right->operand.valOperand));
2074
2075   if (IS_LITERAL(retype)) {
2076     p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2077   }
2078
2079   resType = usualBinaryConversions (&left, &right, resultIsInt, '*');
2080 #if 1
2081   rtype = operandType (right);
2082   retype = getSpec (rtype);
2083   ltype = operandType (left);
2084   letype = getSpec (ltype);
2085 #endif
2086
2087   /* if the right is a literal & power of 2 */
2088   /* then make it a left shift              */
2089   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2090      efficient in most cases than 2 bytes result = 2 bytes << literal
2091      if port has 1 byte muldiv */
2092   if (p2 && !IS_FLOAT (letype)
2093       && !((resultIsInt) && (getSize (resType) != getSize (ltype))
2094            && (port->support.muldiv == 1))
2095       && strcmp (port->target, "pic14") != 0  /* don't shift for pic */
2096       && strcmp (port->target, "pic16") != 0)
2097     {
2098       if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2099         {
2100           /* LEFT_OP need same size for left and result, */
2101           left = geniCodeCast (resType, left, TRUE);
2102           ltype = operandType (left);
2103         }
2104       ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2105     }
2106   else
2107     {
2108       ic = newiCode ('*', left, right);         /* normal multiplication */
2109       /* if the size left or right > 1 then support routine */
2110       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2111         ic->supportRtn = 1;
2112
2113     }
2114   IC_RESULT (ic) = newiTempOperand (resType, 1);
2115
2116   ADDTOCHAIN (ic);
2117   return IC_RESULT (ic);
2118 }
2119
2120 /*-----------------------------------------------------------------*/
2121 /* geniCodeDivision - gen intermediate code for division           */
2122 /*-----------------------------------------------------------------*/
2123 operand *
2124 geniCodeDivision (operand * left, operand * right, bool resultIsInt)
2125 {
2126   iCode *ic;
2127   int p2 = 0;
2128   sym_link *resType;
2129   sym_link *rtype = operandType (right);
2130   sym_link *retype = getSpec (rtype);
2131   sym_link *ltype = operandType (left);
2132   sym_link *letype = getSpec (ltype);
2133
2134   resType = usualBinaryConversions (&left, &right, resultIsInt, '/');
2135
2136   /* if the right is a literal & power of 2
2137      and left is unsigned then make it a
2138      right shift */
2139   if (IS_LITERAL (retype) &&
2140       !IS_FLOAT (letype) &&
2141       IS_UNSIGNED(letype) &&
2142       (p2 = powof2 ((TYPE_UDWORD)
2143                     floatFromVal (right->operand.valOperand)))) {
2144     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2145   }
2146   else
2147     {
2148       ic = newiCode ('/', left, right);         /* normal division */
2149       /* if the size left or right > 1 then support routine */
2150       if (getSize (ltype) > 1 || getSize (rtype) > 1)
2151         ic->supportRtn = 1;
2152     }
2153   IC_RESULT (ic) = newiTempOperand (resType, 0);
2154
2155   ADDTOCHAIN (ic);
2156   return IC_RESULT (ic);
2157 }
2158 /*-----------------------------------------------------------------*/
2159 /* geniCodeModulus  - gen intermediate code for modulus            */
2160 /*-----------------------------------------------------------------*/
2161 operand *
2162 geniCodeModulus (operand * left, operand * right, bool resultIsInt)
2163 {
2164   iCode *ic;
2165   sym_link *resType;
2166   LRTYPE;
2167
2168   /* if they are both literal then we know the result */
2169   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2170     return operandFromValue (valMod (left->operand.valOperand,
2171                                      right->operand.valOperand));
2172
2173   resType = usualBinaryConversions (&left, &right, resultIsInt, '%');
2174
2175   /* now they are the same size */
2176   ic = newiCode ('%', left, right);
2177
2178   /* if the size left or right > 1 then support routine */
2179   if (getSize (ltype) > 1 || getSize (rtype) > 1)
2180     ic->supportRtn = 1;
2181   IC_RESULT (ic) = newiTempOperand (resType, 0);
2182
2183   ADDTOCHAIN (ic);
2184   return IC_RESULT (ic);
2185 }
2186
2187 /*-----------------------------------------------------------------*/
2188 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
2189 /*-----------------------------------------------------------------*/
2190 operand *
2191 geniCodePtrPtrSubtract (operand * left, operand * right)
2192 {
2193   iCode *ic;
2194   operand *result;
2195   LRTYPE;
2196
2197   /* if they are both literals then */
2198   if (IS_LITERAL (letype) && IS_LITERAL (retype))
2199     {
2200       result = operandFromValue (valMinus (left->operand.valOperand,
2201                                            right->operand.valOperand));
2202       goto subtractExit;
2203     }
2204
2205   ic = newiCode ('-', left, right);
2206
2207   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2208   ADDTOCHAIN (ic);
2209
2210 subtractExit:
2211   if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2212     return result;
2213   }
2214   
2215   // should we really do this? is this ANSI?
2216   return geniCodeDivision (result,
2217                            operandFromLit (getSize (ltype->next)),
2218                            FALSE);
2219 }
2220
2221 /*-----------------------------------------------------------------*/
2222 /* geniCodeSubtract - generates code for subtraction               */
2223 /*-----------------------------------------------------------------*/
2224 operand *
2225 geniCodeSubtract (operand * left, operand * right)
2226 {
2227   iCode *ic;
2228   int isarray = 0;
2229   sym_link *resType;
2230   LRTYPE;
2231
2232   /* if they both pointers then */
2233   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2234       (IS_PTR (rtype) || IS_ARRAY (rtype)))
2235     return geniCodePtrPtrSubtract (left, right);
2236
2237   /* if they are both literal then we know the result */
2238   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2239       && left->isLiteral && right->isLiteral)
2240     return operandFromValue (valMinus (left->operand.valOperand,
2241                                        right->operand.valOperand));
2242
2243   /* if left is an array or pointer */
2244   if (IS_PTR (ltype) || IS_ARRAY (ltype))
2245     {
2246       isarray = left->isaddr;
2247       right = geniCodeMultiply (right,
2248                                 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2249       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2250     }
2251   else
2252     {                           /* make them the same size */
2253       resType = usualBinaryConversions (&left, &right, FALSE, '-');
2254     }
2255
2256   ic = newiCode ('-', left, right);
2257
2258   IC_RESULT (ic) = newiTempOperand (resType, 1);
2259   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2260
2261   /* if left or right is a float */
2262   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2263     ic->supportRtn = 1;
2264
2265   ADDTOCHAIN (ic);
2266   return IC_RESULT (ic);
2267 }
2268
2269 /*-----------------------------------------------------------------*/
2270 /* geniCodeAdd - generates iCode for addition                      */
2271 /*-----------------------------------------------------------------*/
2272 operand *
2273 geniCodeAdd (operand * left, operand * right, int lvl)
2274 {
2275   iCode *ic;
2276   sym_link *resType;
2277   operand *size;
2278   int isarray = 0;
2279   bool indexUnsigned;
2280   LRTYPE;
2281
2282   /* if the right side is LITERAL zero */
2283   /* return the left side              */
2284   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2285     return left;
2286
2287   /* if left is literal zero return right */
2288   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2289     return right;
2290
2291   /* if left is a pointer then size */
2292   if (IS_PTR (ltype) || IS_ARRAY(ltype))
2293     {
2294       isarray = left->isaddr;
2295       // there is no need to multiply with 1
2296       if (getSize (ltype->next) != 1)
2297         {
2298           size  = operandFromLit (getSize (ltype->next));
2299           SPEC_USIGN (getSpec (operandType (size))) = 1;
2300           indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2301           right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2302           /* Even if right is a 'unsigned char',
2303              the result will be a 'signed int' due to the promotion rules.
2304              It doesn't make sense when accessing arrays, so let's fix it here: */
2305           if (indexUnsigned)
2306             SPEC_USIGN (getSpec (operandType (right))) = 1;
2307         }
2308       resType = copyLinkChain (ltype);
2309     }
2310   else
2311     { // make them the same size
2312       resType = usualBinaryConversions (&left, &right, FALSE, '+');
2313     }
2314
2315   /* if they are both literals then we know */
2316   if (IS_LITERAL (letype) && IS_LITERAL (retype)
2317       && left->isLiteral && right->isLiteral)
2318     return operandFromValue (valPlus (valFromType (ltype),
2319                                       valFromType (rtype)));
2320
2321   ic = newiCode ('+', left, right);
2322
2323   IC_RESULT (ic) = newiTempOperand (resType, 1);
2324   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2325
2326   /* if left or right is a float then support
2327      routine */
2328   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2329     ic->supportRtn = 1;
2330
2331   ADDTOCHAIN (ic);
2332
2333   return IC_RESULT (ic);
2334
2335 }
2336
2337 /*-----------------------------------------------------------------*/
2338 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
2339 /*-----------------------------------------------------------------*/
2340 sym_link *
2341 aggrToPtr (sym_link * type, bool force)
2342 {
2343   sym_link *etype;
2344   sym_link *ptype;
2345
2346   if (IS_PTR (type) && !force)
2347     return type;
2348
2349   etype = getSpec (type);
2350   ptype = newLink (DECLARATOR);
2351
2352   ptype->next = type;
2353
2354   /* set the pointer depending on the storage class */
2355   DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2356   return ptype;
2357 }
2358
2359 /*-----------------------------------------------------------------*/
2360 /* geniCodeArray2Ptr - array to pointer                            */
2361 /*-----------------------------------------------------------------*/
2362 static operand *
2363 geniCodeArray2Ptr (operand * op)
2364 {
2365   sym_link *optype = operandType (op);
2366   sym_link *opetype = getSpec (optype);
2367
2368   /* set the pointer depending on the storage class */
2369   DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2370
2371   op->isaddr = 0;
2372   return op;
2373 }
2374
2375
2376 /*-----------------------------------------------------------------*/
2377 /* geniCodeArray - array access                                    */
2378 /*-----------------------------------------------------------------*/
2379 static operand *
2380 geniCodeArray (operand * left, operand * right, int lvl)
2381 {
2382   iCode *ic;
2383   operand *size;
2384   sym_link *ltype = operandType (left);
2385   bool indexUnsigned;
2386
2387   if (IS_PTR (ltype))
2388     {
2389       if (IS_PTR (ltype->next) && left->isaddr)
2390         {
2391           left = geniCodeRValue (left, FALSE);
2392         }
2393
2394       return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2395     }
2396   size = operandFromLit (getSize (ltype->next));
2397   SPEC_USIGN (getSpec (operandType (size))) = 1;
2398   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2399   right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2400   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2401      It doesn't make sense when accessing arrays, so let's fix it here: */
2402   if (indexUnsigned)
2403     SPEC_USIGN (getSpec (operandType (right))) = 1;
2404   /* we can check for limits here */
2405   /* already done in SDCCast.c
2406   if (isOperandLiteral (right) &&
2407       IS_ARRAY (ltype) &&
2408       DCL_ELEM (ltype) &&
2409       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2410     {
2411       werror (W_IDX_OUT_OF_BOUNDS,
2412               (int) operandLitValue (right) / getSize (ltype->next),
2413               DCL_ELEM (ltype));
2414     }
2415   */
2416
2417   ic = newiCode ('+', left, right);
2418
2419   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2420                                       !IS_AGGREGATE (ltype->next) &&
2421                                       !IS_PTR (ltype->next))
2422                                      ? ltype : ltype->next), 0);
2423
2424   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2425   ADDTOCHAIN (ic);
2426
2427   return IC_RESULT (ic);
2428 }
2429
2430 /*-----------------------------------------------------------------*/
2431 /* geniCodeStruct - generates intermediate code for structures     */
2432 /*-----------------------------------------------------------------*/
2433 operand *
2434 geniCodeStruct (operand * left, operand * right, bool islval)
2435 {
2436   iCode *ic;
2437   sym_link *type = operandType (left);
2438   sym_link *etype = getSpec (type);
2439   sym_link *retype;
2440   symbol *element = getStructElement (SPEC_STRUCT (etype),
2441                                       right->operand.symOperand);
2442
2443   wassert(IS_SYMOP(right));
2444     
2445   /* add the offset */
2446   ic = newiCode ('+', left, operandFromLit (element->offset));
2447
2448   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2449
2450   /* preserve the storage & output class of the struct */
2451   /* as well as the volatile attribute */
2452   retype = getSpec (operandType (IC_RESULT (ic)));
2453   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2454   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2455   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2456   SPEC_CONST (retype) |= SPEC_CONST (etype);
2457   
2458   if (IS_PTR (element->type))
2459     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2460   
2461   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2462
2463   ADDTOCHAIN (ic);
2464   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2465 }
2466
2467 /*-----------------------------------------------------------------*/
2468 /* geniCodePostInc - generate int code for Post increment          */
2469 /*-----------------------------------------------------------------*/
2470 operand *
2471 geniCodePostInc (operand * op)
2472 {
2473   iCode *ic;
2474   operand *rOp;
2475   sym_link *optype = operandType (op);
2476   operand *result;
2477   operand *rv = (IS_ITEMP (op) ?
2478                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2479                  op);
2480   sym_link *rvtype = operandType (rv);
2481   int size = 0;
2482
2483   /* if this is not an address we have trouble */
2484   if (!op->isaddr)
2485     {
2486       werror (E_LVALUE_REQUIRED, "++");
2487       return op;
2488     }
2489
2490   rOp = newiTempOperand (rvtype, 0);
2491   OP_SYMBOL(rOp)->noSpilLoc = 1;
2492
2493   if (IS_ITEMP (rv))
2494     OP_SYMBOL(rv)->noSpilLoc = 1;
2495
2496   geniCodeAssign (rOp, rv, 0);
2497
2498   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2499   if (IS_FLOAT (rvtype))
2500     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2501   else
2502     ic = newiCode ('+', rv, operandFromLit (size));
2503
2504   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2505   ADDTOCHAIN (ic);
2506
2507   geniCodeAssign (op, result, 0);
2508
2509   return rOp;
2510
2511 }
2512
2513 /*-----------------------------------------------------------------*/
2514 /* geniCodePreInc - generate code for preIncrement                 */
2515 /*-----------------------------------------------------------------*/
2516 operand *
2517 geniCodePreInc (operand * op, bool lvalue)
2518 {
2519   iCode *ic;
2520   sym_link *optype = operandType (op);
2521   operand *rop = (IS_ITEMP (op) ?
2522                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2523                   op);
2524   sym_link *roptype = operandType (rop);
2525   operand *result;
2526   int size = 0;
2527
2528   if (!op->isaddr)
2529     {
2530       werror (E_LVALUE_REQUIRED, "++");
2531       return op;
2532     }
2533
2534
2535   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2536   if (IS_FLOAT (roptype))
2537     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2538   else
2539     ic = newiCode ('+', rop, operandFromLit (size));
2540   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2541   ADDTOCHAIN (ic);
2542
2543   (void) geniCodeAssign (op, result, 0);
2544   if (lvalue || IS_TRUE_SYMOP (op))
2545     return op;
2546   else
2547     return result;
2548 }
2549
2550 /*-----------------------------------------------------------------*/
2551 /* geniCodePostDec - generates code for Post decrement             */
2552 /*-----------------------------------------------------------------*/
2553 operand *
2554 geniCodePostDec (operand * op)
2555 {
2556   iCode *ic;
2557   operand *rOp;
2558   sym_link *optype = operandType (op);
2559   operand *result;
2560   operand *rv = (IS_ITEMP (op) ?
2561                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2562                  op);
2563   sym_link *rvtype = operandType (rv);
2564   int size = 0;
2565
2566   /* if this is not an address we have trouble */
2567   if (!op->isaddr)
2568     {
2569       werror (E_LVALUE_REQUIRED, "--");
2570       return op;
2571     }
2572
2573   rOp = newiTempOperand (rvtype, 0);
2574   OP_SYMBOL(rOp)->noSpilLoc = 1;
2575
2576   if (IS_ITEMP (rv))
2577     OP_SYMBOL(rv)->noSpilLoc = 1;
2578
2579   geniCodeAssign (rOp, rv, 0);
2580
2581   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2582   if (IS_FLOAT (rvtype))
2583     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2584   else
2585     ic = newiCode ('-', rv, operandFromLit (size));
2586
2587   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2588   ADDTOCHAIN (ic);
2589
2590   geniCodeAssign (op, result, 0);
2591
2592   return rOp;
2593
2594 }
2595
2596 /*-----------------------------------------------------------------*/
2597 /* geniCodePreDec - generate code for pre  decrement               */
2598 /*-----------------------------------------------------------------*/
2599 operand *
2600 geniCodePreDec (operand * op, bool lvalue)
2601 {
2602   iCode *ic;
2603   sym_link *optype = operandType (op);
2604   operand *rop = (IS_ITEMP (op) ?
2605                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2606                   op);
2607   sym_link *roptype = operandType (rop);
2608   operand *result;
2609   int size = 0;
2610
2611   if (!op->isaddr)
2612     {
2613       werror (E_LVALUE_REQUIRED, "--");
2614       return op;
2615     }
2616
2617
2618   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2619   if (IS_FLOAT (roptype))
2620     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2621   else
2622     ic = newiCode ('-', rop, operandFromLit (size));
2623   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2624   ADDTOCHAIN (ic);
2625
2626   (void) geniCodeAssign (op, result, 0);
2627   if (lvalue || IS_TRUE_SYMOP (op))
2628     return op;
2629   else
2630     return result;
2631 }
2632
2633
2634 /*-----------------------------------------------------------------*/
2635 /* geniCodeBitwise - gen int code for bitWise  operators           */
2636 /*-----------------------------------------------------------------*/
2637 operand *
2638 geniCodeBitwise (operand * left, operand * right,
2639                  int oper, sym_link * resType)
2640 {
2641   iCode *ic;
2642
2643   left = geniCodeCast (resType, left, TRUE);
2644   right = geniCodeCast (resType, right, TRUE);
2645
2646   ic = newiCode (oper, left, right);
2647   IC_RESULT (ic) = newiTempOperand (resType, 0);
2648
2649   ADDTOCHAIN (ic);
2650   return IC_RESULT (ic);
2651 }
2652
2653 /*-----------------------------------------------------------------*/
2654 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2655 /*-----------------------------------------------------------------*/
2656 operand *
2657 geniCodeAddressOf (operand * op)
2658 {
2659   iCode *ic;
2660   sym_link *p;
2661   sym_link *optype = operandType (op);
2662   sym_link *opetype = getSpec (optype);
2663
2664   if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2665     {
2666       op = operandFromOperand (op);
2667       op->isaddr = 0;
2668       return op;
2669     }
2670   
2671   /* lvalue check already done in decorateType */
2672   /* this must be a lvalue */
2673 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2674 /*  werror (E_LVALUE_REQUIRED,"&"); */
2675 /*  return op; */
2676 /*     } */
2677
2678   p = newLink (DECLARATOR);
2679
2680   /* set the pointer depending on the storage class */
2681   DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2682
2683   p->next = copyLinkChain (optype);
2684
2685   /* if already a temp */
2686   if (IS_ITEMP (op))
2687     {
2688       setOperandType (op, p);
2689       op->isaddr = 0;
2690       return op;
2691     }
2692
2693   /* other wise make this of the type coming in */
2694   ic = newiCode (ADDRESS_OF, op, NULL);
2695   IC_RESULT (ic) = newiTempOperand (p, 1);
2696   IC_RESULT (ic)->isaddr = 0;
2697   ADDTOCHAIN (ic);
2698   return IC_RESULT (ic);
2699 }
2700 /*-----------------------------------------------------------------*/
2701 /* setOClass - sets the output class depending on the pointer type */
2702 /*-----------------------------------------------------------------*/
2703 void 
2704 setOClass (sym_link * ptr, sym_link * spec)
2705 {
2706   switch (DCL_TYPE (ptr))
2707     {
2708     case POINTER:
2709       SPEC_OCLS (spec) = data;
2710       break;
2711
2712     case GPOINTER:
2713       SPEC_OCLS (spec) = generic;
2714       break;
2715
2716     case FPOINTER:
2717       SPEC_OCLS (spec) = xdata;
2718       break;
2719
2720     case CPOINTER:
2721       SPEC_OCLS (spec) = code;
2722       break;
2723
2724     case IPOINTER:
2725       SPEC_OCLS (spec) = idata;
2726       break;
2727
2728     case PPOINTER:
2729       SPEC_OCLS (spec) = xstack;
2730       break;
2731
2732     case EEPPOINTER:
2733       SPEC_OCLS (spec) = eeprom;
2734       break;
2735
2736     default:
2737       break;
2738
2739     }
2740 }
2741
2742 /*-----------------------------------------------------------------*/
2743 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2744 /*-----------------------------------------------------------------*/
2745 operand *
2746 geniCodeDerefPtr (operand * op,int lvl)
2747 {
2748   sym_link *rtype, *retype;
2749   sym_link *optype = operandType (op);
2750
2751   // if this is an array then array access
2752   if (IS_ARRAY (optype)) {
2753     // don't worry, this will be optimized out later
2754     return geniCodeArray (op, operandFromLit (0), lvl);
2755   }
2756
2757   // just in case someone screws up
2758   wassert (IS_PTR (optype));
2759
2760   if (IS_TRUE_SYMOP (op))
2761     {
2762       op->isaddr = 1;
2763       op = geniCodeRValue (op, TRUE);
2764     }
2765
2766   /* now get rid of the pointer part */
2767   if (isLvaluereq(lvl) && IS_ITEMP (op))
2768     {
2769       retype = getSpec (rtype = copyLinkChain (optype));
2770     }
2771   else
2772     {
2773       retype = getSpec (rtype = copyLinkChain (optype->next));
2774       /* outputclass needs 2b updated */
2775       setOClass (optype, retype);
2776     }
2777   
2778   op->isGptr = IS_GENPTR (optype);
2779
2780   op->isaddr = (IS_PTR (rtype) ||
2781                 IS_STRUCT (rtype) ||
2782                 IS_INT (rtype) ||
2783                 IS_CHAR (rtype) ||
2784                 IS_FLOAT (rtype));
2785
2786   if (!isLvaluereq(lvl))
2787     op = geniCodeRValue (op, TRUE);
2788
2789   setOperandType (op, rtype);
2790
2791   return op;
2792 }
2793
2794 /*-----------------------------------------------------------------*/
2795 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2796 /*-----------------------------------------------------------------*/
2797 operand *
2798 geniCodeUnaryMinus (operand * op)
2799 {
2800   iCode *ic;
2801   sym_link *optype = operandType (op);
2802
2803   if (IS_LITERAL (optype))
2804     return operandFromLit (-floatFromVal (op->operand.valOperand));
2805
2806   ic = newiCode (UNARYMINUS, op, NULL);
2807   IC_RESULT (ic) = newiTempOperand (optype, 0);
2808   ADDTOCHAIN (ic);
2809   return IC_RESULT (ic);
2810 }
2811
2812 /*-----------------------------------------------------------------*/
2813 /* geniCodeLeftShift - gen i code for left shift                   */
2814 /*-----------------------------------------------------------------*/
2815 operand *
2816 geniCodeLeftShift (operand * left, operand * right)
2817 {
2818   iCode *ic;
2819
2820   ic = newiCode (LEFT_OP, left, right);
2821   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2822   ADDTOCHAIN (ic);
2823   return IC_RESULT (ic);
2824 }
2825
2826 /*-----------------------------------------------------------------*/
2827 /* geniCodeRightShift - gen i code for right shift                 */
2828 /*-----------------------------------------------------------------*/
2829 operand *
2830 geniCodeRightShift (operand * left, operand * right)
2831 {
2832   iCode *ic;
2833
2834   ic = newiCode (RIGHT_OP, left, right);
2835   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2836   ADDTOCHAIN (ic);
2837   return IC_RESULT (ic);
2838 }
2839
2840 /*-----------------------------------------------------------------*/
2841 /* geniCodeLogic- logic code                                       */
2842 /*-----------------------------------------------------------------*/
2843 operand *
2844 geniCodeLogic (operand * left, operand * right, int op)
2845 {
2846   iCode *ic;
2847   sym_link *ctype;
2848   sym_link *rtype = operandType (right);
2849   sym_link *ltype = operandType (left);
2850
2851   /* left is integral type and right is literal then
2852      check if the literal value is within bounds */
2853   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2854     {
2855       checkConstantRange(ltype,
2856                          OP_VALUE(right), "compare operation", 1);
2857     }
2858
2859   /* if one operand is a pointer and the other is a literal generic void pointer,
2860      change the type of the literal generic void pointer to match the other pointer */
2861   if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2862       && IS_PTR (rtype) && !IS_GENPTR(rtype))
2863     {
2864       /* find left's definition */
2865       ic = (iCode *) setFirstItem (iCodeChain);
2866       while (ic)
2867         {
2868           if (((ic->op == CAST) || (ic->op == '='))
2869               && isOperandEqual(left, IC_RESULT (ic)))
2870             break;
2871           else
2872             ic = setNextItem (iCodeChain);
2873         }
2874       /* if casting literal to generic pointer, then cast to rtype instead */
2875       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2876         {
2877           left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2878           ltype = operandType(left);
2879         }
2880     }
2881   if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2882       && IS_PTR (ltype) && !IS_GENPTR(ltype))
2883     {
2884       /* find right's definition */
2885       ic = (iCode *) setFirstItem (iCodeChain);
2886       while (ic)
2887         {
2888           if (((ic->op == CAST) || (ic->op == '='))
2889               && isOperandEqual(right, IC_RESULT (ic)))
2890             break;
2891           else
2892             ic = setNextItem (iCodeChain);
2893         }
2894       /* if casting literal to generic pointer, then cast to rtype instead */
2895       if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
2896         {
2897           right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2898           rtype = operandType(right);
2899         }
2900     }
2901
2902   ctype = usualBinaryConversions (&left, &right, FALSE, ' ');
2903
2904   ic = newiCode (op, left, right);
2905   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2906
2907   /* if comparing float
2908      and not a '==' || '!=' || '&&' || '||' (these
2909      will be inlined */
2910   if (IS_FLOAT(ctype) &&
2911       op != EQ_OP &&
2912       op != NE_OP &&
2913       op != AND_OP &&
2914       op != OR_OP)
2915     ic->supportRtn = 1;
2916
2917   ADDTOCHAIN (ic);
2918   return IC_RESULT (ic);
2919 }
2920
2921 /*-----------------------------------------------------------------*/
2922 /* geniCodeUnary - for a a generic unary operation                 */
2923 /*-----------------------------------------------------------------*/
2924 operand *
2925 geniCodeUnary (operand * op, int oper)
2926 {
2927   iCode *ic = newiCode (oper, op, NULL);
2928
2929   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2930   ADDTOCHAIN (ic);
2931   return IC_RESULT (ic);
2932 }
2933
2934 /*-----------------------------------------------------------------*/
2935 /* geniCodeConditional - geniCode for '?' ':' operation            */
2936 /*-----------------------------------------------------------------*/
2937 operand *
2938 geniCodeConditional (ast * tree,int lvl)
2939 {
2940   iCode *ic;
2941   symbol *falseLabel = newiTempLabel (NULL);
2942   symbol *exitLabel = newiTempLabel (NULL);
2943   operand *cond = ast2iCode (tree->left,lvl+1);
2944   operand *true, *false, *result;
2945
2946   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2947                           NULL, falseLabel);
2948   ADDTOCHAIN (ic);
2949
2950   true = ast2iCode (tree->right->left,lvl+1);
2951
2952   /* move the value to a new Operand */
2953   result = newiTempOperand (tree->right->ftype, 0);
2954   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2955
2956   /* generate an unconditional goto */
2957   geniCodeGoto (exitLabel);
2958
2959   /* now for the right side */
2960   geniCodeLabel (falseLabel);
2961
2962   false = ast2iCode (tree->right->right,lvl+1);
2963   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2964
2965   /* create the exit label */
2966   geniCodeLabel (exitLabel);
2967
2968   return result;
2969 }
2970
2971 /*-----------------------------------------------------------------*/
2972 /* geniCodeAssign - generate code for assignment                   */
2973 /*-----------------------------------------------------------------*/
2974 operand *
2975 geniCodeAssign (operand * left, operand * right, int nosupdate)
2976 {
2977   iCode *ic;
2978   sym_link *ltype = operandType (left);
2979   sym_link *rtype = operandType (right);
2980
2981   if (!left->isaddr && !IS_ITEMP (left))
2982     {
2983       werror (E_LVALUE_REQUIRED, "assignment");
2984       return left;
2985     }
2986
2987   /* left is integral type and right is literal then
2988      check if the literal value is within bounds */
2989   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2990     {
2991       checkConstantRange(ltype, 
2992                          OP_VALUE(right), "= operation", 0);
2993     }
2994
2995   /* if the left & right type don't exactly match */
2996   /* if pointer set then make sure the check is
2997      done with the type & not the pointer */
2998   /* then cast rights type to left */
2999
3000   /* first check the type for pointer assignement */
3001   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3002       compareType (ltype, rtype) <= 0)
3003     {
3004       if (compareType (ltype->next, rtype) < 0)
3005         right = geniCodeCast (ltype->next, right, TRUE);
3006     }
3007   else if (compareType (ltype, rtype) < 0)
3008     right = geniCodeCast (ltype, right, TRUE);
3009
3010   /* If left is a true symbol & ! volatile
3011      create an assignment to temporary for
3012      the right & then assign this temporary
3013      to the symbol. This is SSA (static single
3014      assignment). Isn't it simple and folks have
3015      published mountains of paper on it */
3016   if (IS_TRUE_SYMOP (left) &&
3017       !isOperandVolatile (left, FALSE) &&
3018       isOperandGlobal (left))
3019     {
3020       symbol *sym = NULL;
3021
3022       if (IS_TRUE_SYMOP (right))
3023         sym = OP_SYMBOL (right);
3024       ic = newiCode ('=', NULL, right);
3025       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3026       SPIL_LOC (right) = sym;
3027       ADDTOCHAIN (ic);
3028     }
3029
3030   ic = newiCode ('=', NULL, right);
3031   IC_RESULT (ic) = left;
3032   ADDTOCHAIN (ic);
3033
3034   /* if left isgptr flag is set then support
3035      routine will be required */
3036   if (left->isGptr)
3037     ic->supportRtn = 1;
3038
3039   ic->nosupdate = nosupdate;
3040   return left;
3041 }
3042
3043 /*-----------------------------------------------------------------*/
3044 /* geniCodeDummyRead - generate code for dummy read                */
3045 /*-----------------------------------------------------------------*/
3046 static void
3047 geniCodeDummyRead (operand * op)
3048 {
3049   iCode *ic;
3050   sym_link *type = operandType (op);
3051
3052   if (!IS_VOLATILE(type))
3053     return;
3054     
3055   ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3056   ADDTOCHAIN (ic);
3057
3058   ic->nosupdate = 1;
3059 }
3060
3061 /*-----------------------------------------------------------------*/
3062 /* geniCodeSEParms - generate code for side effecting fcalls       */
3063 /*-----------------------------------------------------------------*/
3064 static void 
3065 geniCodeSEParms (ast * parms,int lvl)
3066 {
3067   if (!parms)
3068     return;
3069
3070   if (parms->type == EX_OP && parms->opval.op == PARAM)
3071     {
3072       geniCodeSEParms (parms->left,lvl);
3073       geniCodeSEParms (parms->right,lvl);
3074       return;
3075     }
3076
3077   /* hack don't like this but too lazy to think of
3078      something better */
3079   if (IS_ADDRESS_OF_OP (parms))
3080     parms->left->lvalue = 1;
3081
3082   if (IS_CAST_OP (parms) &&
3083       IS_PTR (parms->ftype) &&
3084       IS_ADDRESS_OF_OP (parms->right))
3085     parms->right->left->lvalue = 1;
3086
3087   parms->opval.oprnd = 
3088     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3089                 
3090   parms->type = EX_OPERAND;
3091   AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3092                 SPEC_ARGREG(parms->ftype);
3093 }
3094
3095 /*-----------------------------------------------------------------*/
3096 /* geniCodeParms - generates parameters                            */
3097 /*-----------------------------------------------------------------*/
3098 value *
3099 geniCodeParms (ast * parms, value *argVals, int *stack, 
3100                sym_link * ftype, int lvl)
3101 {
3102   iCode *ic;
3103   operand *pval;
3104
3105   if (!parms)
3106     return argVals;
3107
3108   if (argVals==NULL) {
3109     // first argument
3110     argVals = FUNC_ARGS (ftype);
3111   }
3112
3113   /* if this is a param node then do the left & right */
3114   if (parms->type == EX_OP && parms->opval.op == PARAM)
3115     {
3116       argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3117       argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3118       return argVals;
3119     }
3120
3121   /* get the parameter value */
3122   if (parms->type == EX_OPERAND)
3123     pval = parms->opval.oprnd;
3124   else
3125     {
3126       /* maybe this else should go away ?? */
3127       /* hack don't like this but too lazy to think of
3128          something better */
3129       if (IS_ADDRESS_OF_OP (parms))
3130         parms->left->lvalue = 1;
3131
3132       if (IS_CAST_OP (parms) &&
3133           IS_PTR (parms->ftype) &&
3134           IS_ADDRESS_OF_OP (parms->right))
3135         parms->right->left->lvalue = 1;
3136
3137       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3138     }
3139
3140   /* if register parm then make it a send */
3141   if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3142       IFFUNC_ISBUILTIN(ftype))
3143     {
3144       ic = newiCode (SEND, pval, NULL);
3145       ic->argreg = SPEC_ARGREG(parms->etype);
3146       ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3147       ADDTOCHAIN (ic);
3148     }
3149   else
3150     {
3151       /* now decide whether to push or assign */
3152       if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3153         {
3154
3155           /* assign */
3156           operand *top = operandFromSymbol (argVals->sym);
3157           /* clear useDef and other bitVectors */
3158           OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3159           geniCodeAssign (top, pval, 1);
3160         }
3161       else
3162         {
3163           sym_link *p = operandType (pval);
3164           /* push */
3165           ic = newiCode (IPUSH, pval, NULL);
3166           ic->parmPush = 1;
3167           /* update the stack adjustment */
3168           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3169           ADDTOCHAIN (ic);
3170         }
3171     }
3172
3173   argVals=argVals->next;
3174   return argVals;
3175 }
3176
3177 /*-----------------------------------------------------------------*/
3178 /* geniCodeCall - generates temp code for calling                  */
3179 /*-----------------------------------------------------------------*/
3180 operand *
3181 geniCodeCall (operand * left, ast * parms,int lvl)
3182 {
3183   iCode *ic;
3184   operand *result;
3185   sym_link *type, *etype;
3186   sym_link *ftype;
3187   int stack = 0;
3188
3189   if (!IS_FUNC(OP_SYMBOL(left)->type) && 
3190       !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3191     werror (E_FUNCTION_EXPECTED);
3192     return operandFromValue(valueFromLit(0));
3193   }
3194
3195   /* take care of parameters with side-effecting
3196      function calls in them, this is required to take care
3197      of overlaying function parameters */
3198   geniCodeSEParms (parms,lvl);
3199
3200   ftype = operandType (left);
3201   if (IS_CODEPTR (ftype))
3202     ftype = ftype->next;
3203     
3204   /* first the parameters */
3205   geniCodeParms (parms, NULL, &stack, ftype, lvl);
3206
3207   /* now call : if symbol then pcall */
3208   if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3209     ic = newiCode (PCALL, left, NULL);
3210   } else {
3211     ic = newiCode (CALL, left, NULL);
3212   }
3213
3214   type = copyLinkChain (ftype->next);
3215   etype = getSpec (type);
3216   SPEC_EXTR (etype) = 0;
3217   IC_RESULT (ic) = result = newiTempOperand (type, 1);
3218
3219   ADDTOCHAIN (ic);
3220
3221   /* stack adjustment after call */
3222   ic->parmBytes = stack;
3223
3224   return result;
3225 }
3226
3227 /*-----------------------------------------------------------------*/
3228 /* geniCodeReceive - generate intermediate code for "receive"      */
3229 /*-----------------------------------------------------------------*/
3230 static void 
3231 geniCodeReceive (value * args)
3232 {
3233   /* for all arguments that are passed in registers */
3234   while (args)
3235     {
3236       int first = 1;
3237       if (IS_REGPARM (args->etype))
3238         {
3239           operand *opr = operandFromValue (args);
3240           operand *opl;
3241           symbol *sym = OP_SYMBOL (opr);
3242           iCode *ic;
3243
3244           /* we will use it after all optimizations
3245              and before liveRange calculation */
3246           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3247             {
3248
3249               if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3250                   options.stackAuto == 0 &&
3251                   (!(options.model == MODEL_FLAT24)) )
3252                 {
3253                 }
3254               else
3255                 {
3256                   opl = newiTempOperand (args->type, 0);
3257                   sym->reqv = opl;
3258                   sym->reqv->key = sym->key;
3259                   OP_SYMBOL (sym->reqv)->key = sym->key;
3260                   OP_SYMBOL (sym->reqv)->isreqv = 1;
3261                   OP_SYMBOL (sym->reqv)->islocal = 0;
3262                   SPIL_LOC (sym->reqv) = sym;
3263                 }
3264             }
3265
3266           ic = newiCode (RECEIVE, NULL, NULL);    
3267           ic->argreg = SPEC_ARGREG(args->etype);
3268           if (first) {
3269               currFunc->recvSize = getSize (sym->type);
3270               first = 0;
3271           }
3272           IC_RESULT (ic) = opr;
3273           ADDTOCHAIN (ic);
3274         }
3275
3276       args = args->next;
3277     }
3278 }
3279
3280 /*-----------------------------------------------------------------*/
3281 /* geniCodeFunctionBody - create the function body                 */
3282 /*-----------------------------------------------------------------*/
3283 void 
3284 geniCodeFunctionBody (ast * tree,int lvl)
3285 {
3286   iCode *ic;
3287   operand *func;
3288   sym_link *fetype;
3289   int savelineno;
3290
3291   /* reset the auto generation */
3292   /* numbers */
3293   iTempNum = 0;
3294   iTempLblNum = 0;
3295   operandKey = 0;
3296   iCodeKey = 0;
3297   func = ast2iCode (tree->left,lvl+1);
3298   fetype = getSpec (operandType (func));
3299
3300   savelineno = lineno;
3301   lineno = OP_SYMBOL (func)->lineDef;
3302   /* create an entry label */
3303   geniCodeLabel (entryLabel);
3304   lineno = savelineno;
3305
3306   /* create a proc icode */
3307   ic = newiCode (FUNCTION, func, NULL);
3308   lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3309
3310   ADDTOCHAIN (ic);
3311
3312   /* for all parameters that are passed
3313      on registers add a "receive" */
3314   geniCodeReceive (tree->values.args);
3315
3316   /* generate code for the body */
3317   ast2iCode (tree->right,lvl+1);
3318
3319   /* create a label for return */
3320   geniCodeLabel (returnLabel);
3321
3322   /* now generate the end proc */
3323   ic = newiCode (ENDFUNCTION, func, NULL);
3324   ADDTOCHAIN (ic);
3325   return;
3326 }
3327
3328 /*-----------------------------------------------------------------*/
3329 /* geniCodeReturn - gen icode for 'return' statement               */
3330 /*-----------------------------------------------------------------*/
3331 void 
3332 geniCodeReturn (operand * op)
3333 {
3334   iCode *ic;
3335
3336   /* if the operand is present force an rvalue */
3337   if (op)
3338     op = geniCodeRValue (op, FALSE);
3339
3340   ic = newiCode (RETURN, op, NULL);
3341   ADDTOCHAIN (ic);
3342 }
3343
3344 /*-----------------------------------------------------------------*/
3345 /* geniCodeIfx - generates code for extended if statement          */
3346 /*-----------------------------------------------------------------*/
3347 void 
3348 geniCodeIfx (ast * tree,int lvl)
3349 {
3350   iCode *ic;
3351   operand *condition = ast2iCode (tree->left,lvl+1);
3352   sym_link *cetype;
3353
3354   /* if condition is null then exit */
3355   if (!condition)
3356     goto exit;
3357   else
3358     condition = geniCodeRValue (condition, FALSE);
3359
3360   cetype = getSpec (operandType (condition));
3361   /* if the condition is a literal */
3362   if (IS_LITERAL (cetype))
3363     {
3364       if (floatFromVal (condition->operand.valOperand))
3365         {
3366           if (tree->trueLabel)
3367             geniCodeGoto (tree->trueLabel);
3368           else
3369             assert (0);
3370         }
3371       else
3372         {
3373           if (tree->falseLabel)
3374             geniCodeGoto (tree->falseLabel);
3375           else
3376             assert (0);
3377         }
3378       goto exit;
3379     }
3380
3381   if (tree->trueLabel)
3382     {
3383       ic = newiCodeCondition (condition,
3384                               tree->trueLabel,
3385                               NULL);
3386       ADDTOCHAIN (ic);
3387
3388       if (tree->falseLabel)
3389         geniCodeGoto (tree->falseLabel);
3390     }
3391   else
3392     {
3393       ic = newiCodeCondition (condition,
3394                               NULL,
3395                               tree->falseLabel);
3396       ADDTOCHAIN (ic);
3397     }
3398
3399 exit:
3400   ast2iCode (tree->right,lvl+1);
3401 }
3402
3403 /*-----------------------------------------------------------------*/
3404 /* geniCodeJumpTable - tries to create a jump table for switch     */
3405 /*-----------------------------------------------------------------*/
3406 int 
3407 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3408 {
3409   int min = 0, max = 0, t, cnt = 0;
3410   value *vch;
3411   iCode *ic;
3412   operand *boundary;
3413   symbol *falseLabel;
3414   set *labels = NULL;
3415   int needRangeCheck = !optimize.noJTabBoundary
3416                        || tree->values.switchVals.swDefault;
3417
3418   if (!tree || !caseVals)
3419     return 0;
3420
3421   /* the criteria for creating a jump table is */
3422   /* all integer numbers between the maximum & minimum must */
3423   /* be present , the maximum value should not exceed 255 */
3424   min = max = (int) floatFromVal (vch = caseVals);
3425   SNPRINTF (buffer, sizeof(buffer), 
3426             "_case_%d_%d",
3427            tree->values.switchVals.swNum,
3428            min);
3429   addSet (&labels, newiTempLabel (buffer));
3430
3431   /* if there is only one case value then no need */
3432   if (!(vch = vch->next))
3433     return 0;
3434
3435   while (vch)
3436     {
3437       if (((t = (int) floatFromVal (vch)) - max) != 1)
3438         return 0;
3439       SNPRINTF (buffer, sizeof(buffer), 
3440                 "_case_%d_%d",
3441                tree->values.switchVals.swNum,
3442                t);
3443       addSet (&labels, newiTempLabel (buffer));
3444       max = t;
3445       cnt++;
3446       vch = vch->next;
3447     }
3448
3449   /* if the number of case statements <= 2 then */
3450   /* it is not economical to create the jump table */
3451   /* since two compares are needed for boundary conditions */
3452   if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3453     return 0;
3454
3455   if (tree->values.switchVals.swDefault)
3456     {
3457         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3458     }
3459   else
3460     {
3461         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3462     }
3463     
3464
3465   falseLabel = newiTempLabel (buffer);
3466
3467   /* so we can create a jumptable */
3468   /* first we rule out the boundary conditions */
3469   /* if only optimization says so */
3470   if (needRangeCheck)
3471     {
3472       sym_link *cetype = getSpec (operandType (cond));
3473       /* no need to check the lower bound if
3474          the condition is unsigned & minimum value is zero */
3475       if (!(min == 0 && IS_UNSIGNED (cetype)))
3476         {
3477           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3478           ic = newiCodeCondition (boundary, falseLabel, NULL);
3479           ADDTOCHAIN (ic);
3480         }
3481
3482       /* now for upper bounds */
3483       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3484       ic = newiCodeCondition (boundary, falseLabel, NULL);
3485       ADDTOCHAIN (ic);
3486     }
3487
3488   /* if the min is not zero then we no make it zero */
3489   if (min)
3490     {
3491       cond = geniCodeSubtract (cond, operandFromLit (min));
3492       if (!IS_LITERAL(getSpec(operandType(cond))))
3493         setOperandType (cond, UCHARTYPE);
3494     }
3495
3496   /* now create the jumptable */
3497   ic = newiCode (JUMPTABLE, NULL, NULL);
3498   IC_JTCOND (ic) = cond;
3499   IC_JTLABELS (ic) = labels;
3500   ADDTOCHAIN (ic);
3501   return 1;
3502 }
3503
3504 /*-----------------------------------------------------------------*/
3505 /* geniCodeSwitch - changes a switch to a if statement             */
3506 /*-----------------------------------------------------------------*/
3507 void
3508 geniCodeSwitch (ast * tree,int lvl)
3509 {
3510   iCode *ic;
3511   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3512   value *caseVals = tree->values.switchVals.swVals;
3513   symbol *trueLabel, *falseLabel;
3514       
3515   /* If the condition is a literal, then just jump to the */
3516   /* appropriate case label. */
3517   if (IS_LITERAL(getSpec(operandType(cond))))
3518     {
3519       int switchVal, caseVal;
3520       
3521       switchVal = (int) floatFromVal (cond->operand.valOperand);
3522       while (caseVals)
3523         {
3524           caseVal = (int) floatFromVal (caseVals);
3525           if (caseVal == switchVal)
3526             {
3527               SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3528                         tree->values.switchVals.swNum, caseVal);
3529               trueLabel = newiTempLabel (buffer);
3530               geniCodeGoto (trueLabel);
3531               goto jumpTable;
3532             }
3533           caseVals = caseVals->next;
3534         }
3535       goto defaultOrBreak;
3536     }
3537
3538   /* if we can make this a jump table */
3539   if (geniCodeJumpTable (cond, caseVals, tree))
3540     goto jumpTable;             /* no need for the comparison */
3541
3542   /* for the cases defined do */
3543   while (caseVals)
3544     {
3545
3546       operand *compare = geniCodeLogic (cond,
3547                                         operandFromValue (caseVals),
3548                                         EQ_OP);
3549
3550       SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3551                tree->values.switchVals.swNum,
3552                (int) floatFromVal (caseVals));
3553       trueLabel = newiTempLabel (buffer);
3554
3555       ic = newiCodeCondition (compare, trueLabel, NULL);
3556       ADDTOCHAIN (ic);
3557       caseVals = caseVals->next;
3558     }
3559
3560
3561 defaultOrBreak:
3562   /* if default is present then goto break else break */
3563   if (tree->values.switchVals.swDefault)
3564     {
3565         SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3566     }
3567   else
3568     {
3569         SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3570     }
3571
3572   falseLabel = newiTempLabel (buffer);
3573   geniCodeGoto (falseLabel);
3574
3575 jumpTable:
3576   ast2iCode (tree->right,lvl+1);
3577 }
3578
3579 /*-----------------------------------------------------------------*/
3580 /* geniCodeInline - intermediate code for inline assembler         */
3581 /*-----------------------------------------------------------------*/
3582 static void 
3583 geniCodeInline (ast * tree)
3584 {
3585   iCode *ic;
3586
3587   ic = newiCode (INLINEASM, NULL, NULL);
3588   IC_INLINE (ic) = tree->values.inlineasm;
3589   ADDTOCHAIN (ic);
3590 }
3591
3592 /*-----------------------------------------------------------------*/
3593 /* geniCodeArrayInit - intermediate code for array initializer     */
3594 /*-----------------------------------------------------------------*/
3595 static void
3596 geniCodeArrayInit (ast * tree, operand *array)
3597 {
3598   iCode *ic;
3599
3600   if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3601     ic = newiCode (ARRAYINIT, array, NULL);
3602     IC_ARRAYILIST (ic) = tree->values.constlist;
3603   } else {
3604     operand *left=newOperand(), *right=newOperand();
3605     left->type=right->type=SYMBOL;
3606     OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3607     OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3608     ic = newiCode (ARRAYINIT, left, right);
3609   }
3610   ADDTOCHAIN (ic);
3611 }
3612         
3613 /*-----------------------------------------------------------------*/
3614 /* geniCodeCritical - intermediate code for a critical statement   */
3615 /*-----------------------------------------------------------------*/
3616 static void 
3617 geniCodeCritical (ast *tree, int lvl)
3618 {
3619   iCode *ic;
3620   operand *op = NULL;
3621
3622   /* If op is NULL, the original interrupt state will saved on */
3623   /* the stack. Otherwise, it will be saved in op. */
3624   
3625   /* Generate a save of the current interrupt state & disabled */
3626   ic = newiCode (CRITICAL, NULL, NULL);
3627   IC_RESULT (ic) = op;
3628   ADDTOCHAIN (ic);
3629   
3630   /* Generate the critical code sequence */
3631   if (tree->left && tree->left->type == EX_VALUE)
3632     geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3633   else
3634     ast2iCode (tree->left,lvl+1);
3635   
3636   /* Generate a restore of the original interrupt state */
3637   ic = newiCode (ENDCRITICAL, NULL, op);
3638   ADDTOCHAIN (ic);
3639 }
3640
3641 /*-----------------------------------------------------------------*/
3642 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
3643 /* particular case. Ie : assigning or dereferencing array or ptr   */
3644 /*-----------------------------------------------------------------*/
3645 set * lvaluereqSet = NULL;
3646 typedef struct lvalItem
3647   {
3648     int req;
3649     int lvl;
3650   }
3651 lvalItem;
3652
3653 /*-----------------------------------------------------------------*/
3654 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3655 /*-----------------------------------------------------------------*/
3656 void addLvaluereq(int lvl)
3657 {
3658   lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3659   lpItem->req=1;
3660   lpItem->lvl=lvl;
3661   addSetHead(&lvaluereqSet,lpItem);
3662
3663 }
3664 /*-----------------------------------------------------------------*/
3665 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3666 /*-----------------------------------------------------------------*/
3667 void delLvaluereq()
3668 {
3669   lvalItem * lpItem;
3670   lpItem = getSet(&lvaluereqSet);
3671   if(lpItem) Safe_free(lpItem);
3672 }
3673 /*-----------------------------------------------------------------*/
3674 /* clearLvaluereq - clear lvalreq flag                             */
3675 /*-----------------------------------------------------------------*/
3676 void clearLvaluereq()
3677 {
3678   lvalItem * lpItem;
3679   lpItem = peekSet(lvaluereqSet);
3680   if(lpItem) lpItem->req = 0;
3681 }
3682 /*-----------------------------------------------------------------*/
3683 /* getLvaluereq - get the last lvalreq level                       */
3684 /*-----------------------------------------------------------------*/
3685 int getLvaluereqLvl()
3686 {
3687   lvalItem * lpItem;
3688   lpItem = peekSet(lvaluereqSet);
3689   if(lpItem) return lpItem->lvl;
3690   return 0;
3691 }
3692 /*-----------------------------------------------------------------*/
3693 /* isLvaluereq - is lvalreq valid for this level ?                 */
3694 /*-----------------------------------------------------------------*/
3695 int isLvaluereq(int lvl)
3696 {
3697   lvalItem * lpItem;
3698   lpItem = peekSet(lvaluereqSet);
3699   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3700   return 0;
3701 }
3702
3703 /*-----------------------------------------------------------------*/
3704 /* ast2iCode - creates an icodeList from an ast                    */
3705 /*-----------------------------------------------------------------*/
3706 operand *
3707 ast2iCode (ast * tree,int lvl)
3708 {
3709   operand *left = NULL;
3710   operand *right = NULL;
3711   if (!tree)
3712     return NULL;
3713
3714   /* set the global variables for filename & line number */
3715   if (tree->filename)
3716     filename = tree->filename;
3717   if (tree->lineno)
3718     lineno = tree->lineno;
3719   if (tree->block)
3720     block = tree->block;
3721   if (tree->level)
3722     scopeLevel = tree->level;
3723   if (tree->seqPoint)
3724     seqPoint = tree->seqPoint;
3725
3726   if (tree->type == EX_VALUE)
3727     return operandFromValue (tree->opval.val);
3728
3729   if (tree->type == EX_LINK)
3730     return operandFromLink (tree->opval.lnk);
3731
3732   /* if we find a nullop */
3733   if (tree->type == EX_OP &&
3734      (tree->opval.op == NULLOP ||
3735      tree->opval.op == BLOCK))
3736     {
3737       if (tree->left && tree->left->type == EX_VALUE)
3738         geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3739       else
3740         ast2iCode (tree->left,lvl+1);
3741       if (tree->right && tree->right->type == EX_VALUE)
3742         geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3743       else
3744         ast2iCode (tree->right,lvl+1);
3745       return NULL;
3746     }
3747
3748   /* special cases for not evaluating */
3749   if (tree->opval.op != ':' &&
3750       tree->opval.op != '?' &&
3751       tree->opval.op != CALL &&
3752       tree->opval.op != IFX &&
3753       tree->opval.op != LABEL &&
3754       tree->opval.op != GOTO &&
3755       tree->opval.op != SWITCH &&
3756       tree->opval.op != FUNCTION &&
3757       tree->opval.op != INLINEASM &&
3758       tree->opval.op != CRITICAL)
3759     {
3760
3761         if (IS_ASSIGN_OP (tree->opval.op) ||
3762            IS_DEREF_OP (tree) ||
3763            (tree->opval.op == '&' && !tree->right) ||
3764            tree->opval.op == PTR_OP)
3765           {
3766             addLvaluereq(lvl);
3767             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3768                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3769               clearLvaluereq();
3770
3771             left = operandFromAst (tree->left,lvl);
3772             delLvaluereq();
3773             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3774               left = geniCodeRValue (left, TRUE);
3775           }
3776         else
3777           {
3778             left = operandFromAst (tree->left,lvl);
3779           }
3780         if (tree->opval.op == INC_OP ||
3781             tree->opval.op == DEC_OP)
3782           {
3783             addLvaluereq(lvl);
3784             right = operandFromAst (tree->right,lvl);
3785             delLvaluereq();
3786           }
3787         else
3788           {
3789             right = operandFromAst (tree->right,lvl);
3790           }
3791       }
3792
3793   /* now depending on the type of operand */
3794   /* this will be a biggy                 */
3795   switch (tree->opval.op)
3796     {
3797
3798     case '[':                   /* array operation */
3799       {
3800         //sym_link *ltype = operandType (left);
3801         //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3802         left = geniCodeRValue (left, FALSE);
3803         right = geniCodeRValue (right, TRUE);
3804       }
3805
3806       return geniCodeArray (left, right,lvl);
3807
3808     case '.':                   /* structure dereference */
3809       if (IS_PTR (operandType (left)))
3810         left = geniCodeRValue (left, TRUE);
3811       else
3812         left = geniCodeRValue (left, FALSE);
3813
3814       return geniCodeStruct (left, right, tree->lvalue);
3815
3816     case PTR_OP:                /* structure pointer dereference */
3817       {
3818         sym_link *pType;
3819         pType = operandType (left);
3820         left = geniCodeRValue (left, TRUE);
3821
3822         setOClass (pType, getSpec (operandType (left)));
3823       }
3824
3825       return geniCodeStruct (left, right, tree->lvalue);
3826
3827     case INC_OP:                /* increment operator */
3828       if (left)
3829         return geniCodePostInc (left);
3830       else
3831         return geniCodePreInc (right, tree->lvalue);
3832
3833     case DEC_OP:                /* decrement operator */
3834       if (left)
3835         return geniCodePostDec (left);
3836       else
3837         return geniCodePreDec (right, tree->lvalue);
3838
3839     case '&':                   /* bitwise and or address of operator */
3840       if (right)
3841         {                       /* this is a bitwise operator   */
3842           left = geniCodeRValue (left, FALSE);
3843           right = geniCodeRValue (right, FALSE);
3844           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3845         }
3846       else
3847         return geniCodeAddressOf (left);
3848
3849     case '|':                   /* bitwise or & xor */
3850     case '^':
3851       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3852                               geniCodeRValue (right, FALSE),
3853                               tree->opval.op,
3854                               tree->ftype);
3855
3856     case '/':
3857       return geniCodeDivision (geniCodeRValue (left, FALSE),
3858                                geniCodeRValue (right, FALSE),
3859                                IS_INT (tree->ftype));
3860
3861     case '%':
3862       return geniCodeModulus (geniCodeRValue (left, FALSE),
3863                               geniCodeRValue (right, FALSE),
3864                               IS_INT (tree->ftype));
3865     case '*':
3866       if (right)
3867         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3868                                  geniCodeRValue (right, FALSE),
3869                                  IS_INT (tree->ftype));
3870       else
3871         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3872
3873     case '-':
3874       if (right)
3875         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3876                                  geniCodeRValue (right, FALSE));
3877       else
3878         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3879
3880     case '+':
3881       if (right)
3882         return geniCodeAdd (geniCodeRValue (left, FALSE),
3883                             geniCodeRValue (right, FALSE),lvl);
3884       else
3885         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3886
3887     case LEFT_OP:
3888       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3889                                 geniCodeRValue (right, FALSE));
3890
3891     case RIGHT_OP:
3892       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3893                                  geniCodeRValue (right, FALSE));
3894     case CAST:
3895 #if 0 // this indeed needs a second thought
3896       {
3897         operand *op;
3898
3899         // let's keep this simple: get the rvalue we need
3900         op=geniCodeRValue (right, FALSE);
3901         // now cast it to whatever we want
3902         op=geniCodeCast (operandType(left), op, FALSE);
3903         // if this is going to be used as an lvalue, make it so
3904         if (tree->lvalue) {
3905           op->isaddr=1;
3906         }
3907         return op;
3908       }
3909 #else // bug #604575, is it a bug ????
3910       return geniCodeCast (operandType (left),
3911                            geniCodeRValue (right, FALSE), FALSE);
3912 #endif
3913
3914     case '~':
3915     case RRC:
3916     case RLC:
3917     case SWAP:
3918       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3919
3920     case '!':
3921     case GETHBIT:
3922       {
3923         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3924         setOperandType (op, UCHARTYPE);
3925         return op;
3926       }
3927     case '>':
3928     case '<':
3929     case LE_OP:
3930     case GE_OP:
3931     case EQ_OP:
3932     case NE_OP:
3933     case AND_OP:
3934     case OR_OP:
3935       /* different compilers (even different gccs) evaluate
3936          the two calls in a different order. to get the same
3937          result on all machines we've to specify a clear sequence.
3938       return geniCodeLogic (geniCodeRValue (left, FALSE),
3939                             geniCodeRValue (right, FALSE),
3940                             tree->opval.op);
3941       */
3942       {
3943         operand *leftOp, *rightOp;
3944
3945         rightOp = geniCodeRValue (right, FALSE);
3946         leftOp  = geniCodeRValue (left , FALSE);
3947
3948         return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3949       }
3950     case '?':
3951       return geniCodeConditional (tree,lvl);
3952
3953     case SIZEOF:
3954       return operandFromLit (getSize (tree->right->ftype));
3955
3956     case '=':
3957       {
3958         sym_link *rtype = operandType (right);
3959         sym_link *ltype = operandType (left);
3960         if (IS_PTR (rtype) && IS_ITEMP (right)
3961             && right->isaddr && compareType (rtype->next, ltype) == 1)
3962           right = geniCodeRValue (right, TRUE);
3963         else
3964           right = geniCodeRValue (right, FALSE);
3965
3966         geniCodeAssign (left, right, 0);
3967         return right;
3968       }
3969     case MUL_ASSIGN:
3970       return
3971         geniCodeAssign (left,
3972                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3973                                                   FALSE),
3974                                   geniCodeRValue (right, FALSE),FALSE), 0);
3975
3976     case DIV_ASSIGN:
3977       return
3978         geniCodeAssign (left,
3979                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3980                                                   FALSE),
3981                                   geniCodeRValue (right, FALSE),
3982                                   IS_INT (tree->ftype)),
3983                         0);
3984     case MOD_ASSIGN:
3985       return
3986         geniCodeAssign (left,
3987                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3988                                                   FALSE),
3989                                   geniCodeRValue (right, FALSE),
3990                                   IS_INT (tree->ftype)),
3991                         0);
3992     case ADD_ASSIGN:
3993       {
3994         sym_link *rtype = operandType (right);
3995         sym_link *ltype = operandType (left);
3996         if (IS_PTR (rtype) && IS_ITEMP (right)
3997             && right->isaddr && compareType (rtype->next, ltype) == 1)
3998           right = geniCodeRValue (right, TRUE);
3999         else
4000           right = geniCodeRValue (right, FALSE);
4001
4002
4003         return geniCodeAssign (left,
4004                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4005                                                   FALSE),
4006                                   right,lvl), 0);
4007       }
4008     case SUB_ASSIGN:
4009       {
4010         sym_link *rtype = operandType (right);
4011         sym_link *ltype = operandType (left);
4012         if (IS_PTR (rtype) && IS_ITEMP (right)
4013             && right->isaddr && compareType (rtype->next, ltype) == 1)
4014           {
4015             right = geniCodeRValue (right, TRUE);
4016           }
4017         else
4018           {
4019             right = geniCodeRValue (right, FALSE);
4020           }
4021         return
4022           geniCodeAssign (left,
4023                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4024                                                   FALSE),
4025                                   right), 0);
4026       }
4027     case LEFT_ASSIGN:
4028       return
4029         geniCodeAssign (left,
4030                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4031                                                    ,FALSE),
4032                                    geniCodeRValue (right, FALSE)), 0);
4033     case RIGHT_ASSIGN:
4034       return
4035         geniCodeAssign (left,
4036                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4037                                                    ,FALSE),
4038                                    geniCodeRValue (right, FALSE)), 0);
4039     case AND_ASSIGN:
4040       return
4041         geniCodeAssign (left,
4042                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4043                                                   FALSE),
4044                                   geniCodeRValue (right, FALSE),
4045                                   BITWISEAND,
4046                                   operandType (left)), 0);
4047     case XOR_ASSIGN:
4048       return
4049         geniCodeAssign (left,
4050                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4051                                                   FALSE),
4052                                   geniCodeRValue (right, FALSE),
4053                                   '^',
4054                                   operandType (left)), 0);
4055     case OR_ASSIGN:
4056       return
4057         geniCodeAssign (left,
4058                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4059                                                    ,FALSE),
4060                                    geniCodeRValue (right, FALSE),
4061                                    '|',
4062                                    operandType (left)), 0);
4063     case ',':
4064       return geniCodeRValue (right, FALSE);
4065
4066     case CALL:
4067       return geniCodeCall (ast2iCode (tree->left,lvl+1),
4068                            tree->right,lvl);
4069     case LABEL:
4070       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4071       return ast2iCode (tree->right,lvl+1);
4072
4073     case GOTO:
4074       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4075       return ast2iCode (tree->right,lvl+1);
4076
4077     case FUNCTION:
4078       geniCodeFunctionBody (tree,lvl);
4079       return NULL;
4080
4081     case RETURN:
4082       geniCodeReturn (right);
4083       return NULL;
4084
4085     case IFX:
4086       geniCodeIfx (tree,lvl);
4087       return NULL;
4088
4089     case SWITCH:
4090       geniCodeSwitch (tree,lvl);
4091       return NULL;
4092
4093     case INLINEASM:
4094       geniCodeInline (tree);
4095       return NULL;
4096         
4097     case ARRAYINIT:
4098         geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4099         return NULL;
4100     
4101     case CRITICAL:
4102         geniCodeCritical (tree, lvl);
4103     }
4104
4105   return NULL;
4106 }
4107
4108 /*-----------------------------------------------------------------*/
4109 /* reverseICChain - gets from the list and creates a linkedlist    */
4110 /*-----------------------------------------------------------------*/
4111 iCode *
4112 reverseiCChain ()
4113 {
4114   iCode *loop = NULL;
4115   iCode *prev = NULL;
4116
4117   while ((loop = getSet (&iCodeChain)))
4118     {
4119       loop->next = prev;
4120       if (prev)
4121         prev->prev = loop;
4122       prev = loop;
4123     }
4124
4125   return prev;
4126 }
4127
4128
4129 /*-----------------------------------------------------------------*/
4130 /* iCodeFromAst - given an ast will convert it to iCode            */
4131 /*-----------------------------------------------------------------*/
4132 iCode *
4133 iCodeFromAst (ast * tree)
4134 {
4135   returnLabel = newiTempLabel ("_return");
4136   entryLabel = newiTempLabel ("_entry");
4137   ast2iCode (tree,0);
4138   return reverseiCChain ();
4139 }
4140
4141 static const char *opTypeToStr(OPTYPE op)
4142 {
4143     switch(op)
4144     {
4145       case SYMBOL: return "symbol";
4146       case VALUE: return "value";
4147       case TYPE: return "type";
4148     }
4149     return "undefined type";    
4150 }
4151
4152
4153 operand *validateOpType(operand         *op, 
4154                         const char      *macro,
4155                         const char      *args,
4156                         OPTYPE          type,
4157                         const char      *file, 
4158                         unsigned        line)
4159 {    
4160     if (op && op->type == type)
4161     {
4162         return op;
4163     }
4164     fprintf(stderr, 
4165             "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4166             " expected %s, got %s\n",
4167             macro, args, file, line, 
4168             opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4169     exit(-1);
4170     return op; // never reached, makes compiler happy.
4171 }