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