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