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