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