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