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