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