Fix array bug < foo[foo[3]+2]=10>
[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
28 /*-----------------------------------------------------------------*/
29 /* global variables       */
30
31 set *iCodeChain = NULL;
32 int iTempNum = 0;
33 int iTempLblNum = 0;
34 int operandKey = 0;
35 int iCodeKey = 0;
36 char *filename;
37 int lineno;
38 int block;
39 int scopeLevel;
40
41 symbol *returnLabel;            /* function return label */
42 symbol *entryLabel;             /* function entry  label */
43 /*-----------------------------------------------------------------*/
44 /* forward definition of some functions */
45 operand *geniCodeDivision (operand *, operand *);
46 operand *geniCodeAssign (operand *, operand *, int);
47 operand *geniCodeArray (operand *, operand *,int);
48 operand *geniCodeArray2Ptr (operand *);
49 operand *geniCodeRValue (operand *, bool);
50 operand *geniCodeDerefPtr (operand *,int);
51
52 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
53 /* forward definition of ic print functions */
54 PRINTFUNC (picGetValueAtAddr);
55 PRINTFUNC (picSetValueAtAddr);
56 PRINTFUNC (picAddrOf);
57 PRINTFUNC (picGeneric);
58 PRINTFUNC (picGenericOne);
59 PRINTFUNC (picCast);
60 PRINTFUNC (picAssign);
61 PRINTFUNC (picLabel);
62 PRINTFUNC (picGoto);
63 PRINTFUNC (picIfx);
64 PRINTFUNC (picJumpTable);
65 PRINTFUNC (picInline);
66 PRINTFUNC (picReceive);
67
68 iCodeTable codeTable[] =
69 {
70   {'!', "not", picGenericOne, NULL},
71   {'~', "~", picGenericOne, NULL},
72   {RRC, "rrc", picGenericOne, NULL},
73   {RLC, "rlc", picGenericOne, NULL},
74   {GETHBIT, "ghbit", picGenericOne, NULL},
75   {UNARYMINUS, "-", picGenericOne, NULL},
76   {IPUSH, "push", picGenericOne, NULL},
77   {IPOP, "pop", picGenericOne, NULL},
78   {CALL, "call", picGenericOne, NULL},
79   {PCALL, "pcall", picGenericOne, NULL},
80   {FUNCTION, "proc", picGenericOne, NULL},
81   {ENDFUNCTION, "eproc", picGenericOne, NULL},
82   {RETURN, "ret", picGenericOne, NULL},
83   {'+', "+", picGeneric, NULL},
84   {'-', "-", picGeneric, NULL},
85   {'*', "*", picGeneric, NULL},
86   {'/', "/", picGeneric, NULL},
87   {'%', "%", picGeneric, NULL},
88   {'>', ">", picGeneric, NULL},
89   {'<', "<", picGeneric, NULL},
90   {LE_OP, "<=", picGeneric, NULL},
91   {GE_OP, ">=", picGeneric, NULL},
92   {EQ_OP, "==", picGeneric, NULL},
93   {NE_OP, "!=", picGeneric, NULL},
94   {AND_OP, "&&", picGeneric, NULL},
95   {OR_OP, "||", picGeneric, NULL},
96   {'^', "^", picGeneric, NULL},
97   {'|', "|", picGeneric, NULL},
98   {BITWISEAND, "&", picGeneric, NULL},
99   {LEFT_OP, "<<", picGeneric, NULL},
100   {RIGHT_OP, ">>", picGeneric, NULL},
101   {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
102   {ADDRESS_OF, "&", picAddrOf, NULL},
103   {CAST, "<>", picCast, NULL},
104   {'=', ":=", picAssign, NULL},
105   {LABEL, "", picLabel, NULL},
106   {GOTO, "", picGoto, NULL},
107   {JUMPTABLE, "jtab", picJumpTable, NULL},
108   {IFX, "if", picIfx, NULL},
109   {INLINEASM, "", picInline, NULL},
110   {RECEIVE, "recv", picReceive, NULL},
111   {SEND, "send", picGenericOne, NULL}
112 };
113
114
115 /*-----------------------------------------------------------------*/
116 /* operandName - returns the name of the operand                   */
117 /*-----------------------------------------------------------------*/
118 int 
119 printOperand (operand * op, FILE * file)
120 {
121   sym_link *opetype;
122   int pnl = 0;
123
124   if (!op)
125     return 1;
126
127   if (!file)
128     {
129       file = stdout;
130       pnl = 1;
131     }
132   switch (op->type)
133     {
134
135     case VALUE:
136       opetype = getSpec (operandType (op));
137       if (SPEC_NOUN (opetype) == V_FLOAT)
138         fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
139       else
140         fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
141       printTypeChain (operandType (op), file);
142       fprintf (file, "}");
143       break;
144
145     case SYMBOL:
146 #define REGA 1
147 #ifdef REGA
148       fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}",         /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
149                (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
150                op->key,
151                OP_LIVEFROM (op), OP_LIVETO (op),
152                OP_SYMBOL (op)->stack,
153                op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat
154         );
155       {
156         fprintf (file, "{");
157         printTypeChain (operandType (op), file);
158         if (SPIL_LOC (op) && IS_ITEMP (op))
159           fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
160         fprintf (file, "}");
161
162       }
163
164       /* if assigned to registers */
165       if (OP_SYMBOL (op)->nRegs)
166         {
167           if (OP_SYMBOL (op)->isspilt)
168             {
169               if (!OP_SYMBOL (op)->remat)
170                 if (OP_SYMBOL (op)->usl.spillLoc)
171                   fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
172                                        OP_SYMBOL (op)->usl.spillLoc->rname :
173                                        OP_SYMBOL (op)->usl.spillLoc->name));
174                 else
175                   fprintf (file, "[err]");
176               else
177                 fprintf (file, "[remat]");
178             }
179           else
180             {
181               int i;
182               fprintf (file, "[");
183               for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
184                 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
185               fprintf (file, "]");
186             }
187         }
188 #else
189       fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
190                             OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
191       /* if assigned to registers */
192       if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
193         {
194           int i;
195           fprintf (file, "[");
196           for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
197             fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
198                                    OP_SYMBOL (op)->regs[i]->name :
199                                    "err"));
200           fprintf (file, "]");
201         }
202 #endif
203       break;
204
205     case TYPE:
206       fprintf (file, "(");
207       printTypeChain (op->operand.typeOperand, file);
208       fprintf (file, ")");
209       break;
210     }
211
212   if (pnl)
213     fprintf (file, "\n");
214   return 0;
215 }
216
217
218 /*-----------------------------------------------------------------*/
219 /*                    print functions                              */
220 /*-----------------------------------------------------------------*/
221 PRINTFUNC (picGetValueAtAddr)
222 {
223   fprintf (of, "\t");
224   printOperand (IC_RESULT (ic), of);
225   fprintf (of, " = ");
226   fprintf (of, "@[");
227   printOperand (IC_LEFT (ic), of);
228   fprintf (of, "]");
229
230   fprintf (of, "\n");
231 }
232
233 PRINTFUNC (picSetValueAtAddr)
234 {
235   fprintf (of, "\t");
236   fprintf (of, "*[");
237   printOperand (IC_LEFT (ic), of);
238   fprintf (of, "] = ");
239   printOperand (IC_RIGHT (ic), of);
240   fprintf (of, "\n");
241 }
242
243 PRINTFUNC (picAddrOf)
244 {
245   fprintf (of, "\t");
246   printOperand (IC_RESULT (ic), of);
247   if (IS_ITEMP (IC_LEFT (ic)))
248     fprintf (of, " = ");
249   else
250     fprintf (of, " = &[");
251   printOperand (IC_LEFT (ic), of);
252   if (IC_RIGHT (ic))
253     {
254       if (IS_ITEMP (IC_LEFT (ic)))
255         fprintf (of, " offsetAdd ");
256       else
257         fprintf (of, " , ");
258       printOperand (IC_RIGHT (ic), of);
259     }
260   if (IS_ITEMP (IC_LEFT (ic)))
261     fprintf (of, "\n");
262   else
263     fprintf (of, "]\n");
264 }
265
266 PRINTFUNC (picJumpTable)
267 {
268   symbol *sym;
269
270   fprintf (of, "\t");
271   fprintf (of, "%s\t", s);
272   printOperand (IC_JTCOND (ic), of);
273   fprintf (of, "\n");
274   for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
275        sym = setNextItem (IC_JTLABELS (ic)))
276     fprintf (of, "\t\t\t%s\n", sym->name);
277 }
278
279 PRINTFUNC (picGeneric)
280 {
281   fprintf (of, "\t");
282   printOperand (IC_RESULT (ic), of);
283   fprintf (of, " = ");
284   printOperand (IC_LEFT (ic), of);
285   fprintf (of, " %s ", s);
286   printOperand (IC_RIGHT (ic), of);
287   fprintf (of, "\n");
288 }
289
290 PRINTFUNC (picGenericOne)
291 {
292   fprintf (of, "\t");
293   if (IC_RESULT (ic))
294     {
295       printOperand (IC_RESULT (ic), of);
296       fprintf (of, " = ");
297     }
298
299   if (IC_LEFT (ic))
300     {
301       fprintf (of, "%s ", s);
302       printOperand (IC_LEFT (ic), of);
303     }
304
305   if (!IC_RESULT (ic) && !IC_LEFT (ic))
306     fprintf (of, s);
307
308   fprintf (of, "\n");
309 }
310
311 PRINTFUNC (picCast)
312 {
313   fprintf (of, "\t");
314   printOperand (IC_RESULT (ic), of);
315   fprintf (of, " = ");
316   printOperand (IC_LEFT (ic), of);
317   printOperand (IC_RIGHT (ic), of);
318   fprintf (of, "\n");
319 }
320
321
322 PRINTFUNC (picAssign)
323 {
324   fprintf (of, "\t");
325
326   if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
327     fprintf (of, "*(");
328
329   printOperand (IC_RESULT (ic), of);
330
331   if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
332     fprintf (of, ")");
333
334   fprintf (of, " %s ", s);
335   printOperand (IC_RIGHT (ic), of);
336
337   fprintf (of, "\n");
338 }
339
340 PRINTFUNC (picLabel)
341 {
342   fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
343 }
344
345 PRINTFUNC (picGoto)
346 {
347   fprintf (of, "\t");
348   fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
349 }
350
351 PRINTFUNC (picIfx)
352 {
353   fprintf (of, "\t");
354   fprintf (of, "if ");
355   printOperand (IC_COND (ic), of);
356
357   if (!IC_TRUE (ic))
358     fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
359   else
360     {
361       fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
362       if (IC_FALSE (ic))
363         fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
364     }
365 }
366
367 PRINTFUNC (picInline)
368 {
369   fprintf (of, "%s", IC_INLINE (ic));
370 }
371
372 PRINTFUNC (picReceive)
373 {
374   printOperand (IC_RESULT (ic), of);
375   fprintf (of, " = %s ", s);
376   printOperand (IC_LEFT (ic), of);
377   fprintf (of, "\n");
378 }
379
380 /*-----------------------------------------------------------------*/
381 /* piCode - prints one iCode                                       */
382 /*-----------------------------------------------------------------*/
383 int 
384 piCode (void *item, FILE * of)
385 {
386   iCode *ic = item;
387   iCodeTable *icTab;
388
389   if (!of)
390     of = stdout;
391
392   icTab = getTableEntry (ic->op);
393   fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
394            ic->filename, ic->lineno,
395            ic->seq, ic->key, ic->depth, ic->supportRtn);
396   icTab->iCodePrint (of, ic, icTab->printName);
397   return 1;
398 }
399
400 void PICC(iCode *ic)
401 {
402         printiCChain(ic,stdout);
403 }
404 /*-----------------------------------------------------------------*/
405 /* printiCChain - prints intermediate code for humans              */
406 /*-----------------------------------------------------------------*/
407 void 
408 printiCChain (iCode * icChain, FILE * of)
409 {
410   iCode *loop;
411   iCodeTable *icTab;
412
413   if (!of)
414     of = stdout;
415   for (loop = icChain; loop; loop = loop->next)
416     {
417       if ((icTab = getTableEntry (loop->op)))
418         {
419           fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
420                    loop->filename, loop->lineno,
421                    loop->seq, loop->key, loop->depth, loop->supportRtn);
422
423           icTab->iCodePrint (of, loop, icTab->printName);
424         }
425     }
426 }
427
428
429 /*-----------------------------------------------------------------*/
430 /* newOperand - allocate, init & return a new iCode                */
431 /*-----------------------------------------------------------------*/
432 operand *
433 newOperand ()
434 {
435   operand *op;
436
437   op = Safe_calloc (1, sizeof (operand));
438
439   op->key = 0;
440   return op;
441 }
442
443 /*-----------------------------------------------------------------*/
444 /* newiCode - create and return a new iCode entry initialised      */
445 /*-----------------------------------------------------------------*/
446 iCode *
447 newiCode (int op, operand * left, operand * right)
448 {
449   iCode *ic;
450
451   ic = Safe_calloc (1, sizeof (iCode));
452
453   ic->lineno = lineno;
454   ic->filename = filename;
455   ic->block = block;
456   ic->level = scopeLevel;
457   ic->op = op;
458   ic->key = iCodeKey++;
459   IC_LEFT (ic) = left;
460   IC_RIGHT (ic) = right;
461
462   return ic;
463 }
464
465 /*-----------------------------------------------------------------*/
466 /* newiCode for conditional statements                             */
467 /*-----------------------------------------------------------------*/
468 iCode *
469 newiCodeCondition (operand * condition,
470                    symbol * trueLabel,
471                    symbol * falseLabel)
472 {
473   iCode *ic;
474
475   ic = newiCode (IFX, NULL, NULL);
476   IC_COND (ic) = condition;
477   IC_TRUE (ic) = trueLabel;
478   IC_FALSE (ic) = falseLabel;
479   return ic;
480 }
481
482 /*-----------------------------------------------------------------*/
483 /* newiCodeLabelGoto - unconditional goto statement| label stmnt   */
484 /*-----------------------------------------------------------------*/
485 iCode *
486 newiCodeLabelGoto (int op, symbol * label)
487 {
488   iCode *ic;
489
490   ic = newiCode (op, NULL, NULL);
491   ic->op = op;
492   ic->argLabel.label = label;
493   IC_LEFT (ic) = NULL;
494   IC_RIGHT (ic) = NULL;
495   IC_RESULT (ic) = NULL;
496   return ic;
497 }
498
499 /*-----------------------------------------------------------------*/
500 /* newiTemp - allocate & return a newItemp Variable                */
501 /*-----------------------------------------------------------------*/
502 symbol *
503 newiTemp (char *s)
504 {
505   symbol *itmp;
506
507   if (s)
508     sprintf (buffer, "%s", s);
509   else
510     sprintf (buffer, "iTemp%d", iTempNum++);
511   itmp = newSymbol (buffer, 1);
512   strcpy (itmp->rname, itmp->name);
513   itmp->isitmp = 1;
514
515   return itmp;
516 }
517
518 /*-----------------------------------------------------------------*/
519 /* newiTempLabel - creates a temp variable label                   */
520 /*-----------------------------------------------------------------*/
521 symbol *
522 newiTempLabel (char *s)
523 {
524   symbol *itmplbl;
525
526   /* check if this alredy exists */
527   if (s && (itmplbl = findSym (LabelTab, NULL, s)))
528     return itmplbl;
529
530   if (s)
531     itmplbl = newSymbol (s, 1);
532   else
533     {
534       sprintf (buffer, "iTempLbl%d", iTempLblNum++);
535       itmplbl = newSymbol (buffer, 1);
536     }
537
538   itmplbl->isitmp = 1;
539   itmplbl->islbl = 1;
540   itmplbl->key = labelKey++;
541   addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
542   return itmplbl;
543 }
544
545 /*-----------------------------------------------------------------*/
546 /* newiTempPreheaderLabel - creates a new preheader label          */
547 /*-----------------------------------------------------------------*/
548 symbol *
549 newiTempPreheaderLabel ()
550 {
551   symbol *itmplbl;
552
553   sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
554   itmplbl = newSymbol (buffer, 1);
555
556   itmplbl->isitmp = 1;
557   itmplbl->islbl = 1;
558   itmplbl->key = labelKey++;
559   addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
560   return itmplbl;
561 }
562
563
564 /*-----------------------------------------------------------------*/
565 /* initiCode - initialises some iCode related stuff                */
566 /*-----------------------------------------------------------------*/
567 void 
568 initiCode ()
569 {
570
571 }
572
573 /*-----------------------------------------------------------------*/
574 /* copyiCode - make a copy of the iCode given                      */
575 /*-----------------------------------------------------------------*/
576 iCode *
577 copyiCode (iCode * ic)
578 {
579   iCode *nic = newiCode (ic->op, NULL, NULL);
580
581   nic->lineno = ic->lineno;
582   nic->filename = ic->filename;
583   nic->block = ic->block;
584   nic->level = ic->level;
585   nic->parmBytes = ic->parmBytes;
586
587   /* deal with the special cases first */
588   switch (ic->op)
589     {
590     case IFX:
591       IC_COND (nic) = operandFromOperand (IC_COND (ic));
592       IC_TRUE (nic) = IC_TRUE (ic);
593       IC_FALSE (nic) = IC_FALSE (ic);
594       break;
595
596     case JUMPTABLE:
597       IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
598       IC_JTLABELS (nic) = IC_JTLABELS (ic);
599       break;
600
601     case CALL:
602     case PCALL:
603       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
604       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
605       IC_ARGS (nic) = IC_ARGS (ic);
606       break;
607
608     case INLINEASM:
609       IC_INLINE (nic) = IC_INLINE (ic);
610       break;
611
612     default:
613       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
614       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
615       IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
616     }
617
618   return nic;
619 }
620
621 /*-----------------------------------------------------------------*/
622 /* getTableEntry - gets the table entry for the given operator     */
623 /*-----------------------------------------------------------------*/
624 iCodeTable *
625 getTableEntry (int oper)
626 {
627   int i;
628
629   for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
630     if (oper == codeTable[i].icode)
631       return &codeTable[i];
632
633   return NULL;
634 }
635
636 /*-----------------------------------------------------------------*/
637 /* newiTempOperand - new intermediate temp operand                 */
638 /*-----------------------------------------------------------------*/
639 operand *
640 newiTempOperand (sym_link * type, char throwType)
641 {
642   symbol *itmp;
643   operand *op = newOperand ();
644   sym_link *etype;
645
646   op->type = SYMBOL;
647   itmp = newiTemp (NULL);
648
649   etype = getSpec (type);
650
651   if (IS_LITERAL (etype))
652     throwType = 0;
653
654   /* copy the type information */
655   if (type)
656     itmp->etype = getSpec (itmp->type = (throwType ? type :
657                                          copyLinkChain (type)));
658   if (IS_LITERAL (itmp->etype))
659     {
660       SPEC_SCLS (itmp->etype) = S_REGISTER;
661       SPEC_OCLS (itmp->etype) = reg;
662     }
663
664   op->operand.symOperand = itmp;
665   op->key = itmp->key = ++operandKey;
666   return op;
667 }
668
669 /*-----------------------------------------------------------------*/
670 /* operandType - returns the type chain for an operand             */
671 /*-----------------------------------------------------------------*/
672 sym_link *
673 operandType (operand * op)
674 {
675   /* depending on type of operand */
676   switch (op->type)
677     {
678
679     case VALUE:
680       return op->operand.valOperand->type;
681
682     case SYMBOL:
683       return op->operand.symOperand->type;
684
685     case TYPE:
686       return op->operand.typeOperand;
687     default:
688       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
689               " operand type not known ");
690       assert (0);               /* should never come here */
691       /*  Just to keep the compiler happy */
692       return (sym_link *) 0;
693     }
694 }
695
696 /*-----------------------------------------------------------------*/
697 /* isParamterToCall - will return 1 if op is a parameter to args   */
698 /*-----------------------------------------------------------------*/
699 int 
700 isParameterToCall (value * args, operand * op)
701 {
702   value *tval = args;
703
704   while (tval)
705     {
706       if (tval->sym &&
707           isSymbolEqual (op->operand.symOperand, tval->sym))
708         return 1;
709       tval = tval->next;
710     }
711   return 0;
712 }
713
714 /*-----------------------------------------------------------------*/
715 /* isOperandGlobal   - return 1 if operand is a global variable    */
716 /*-----------------------------------------------------------------*/
717 int 
718 isOperandGlobal (operand * op)
719 {
720   if (!op)
721     return 0;
722
723   if (IS_ITEMP (op))
724     return 0;
725
726   if (op->type == SYMBOL &&
727       (op->operand.symOperand->level == 0 ||
728        IS_STATIC (op->operand.symOperand->etype) ||
729        IS_EXTERN (op->operand.symOperand->etype))
730     )
731     return 1;
732
733   return 0;
734 }
735
736 /*-----------------------------------------------------------------*/
737 /* isOperandVolatile - return 1 if the operand is volatile         */
738 /*-----------------------------------------------------------------*/
739 int 
740 isOperandVolatile (operand * op, bool chkTemp)
741 {
742   sym_link *optype;
743   sym_link *opetype;
744
745   if (IS_ITEMP (op) && !chkTemp)
746     return 0;
747
748   opetype = getSpec (optype = operandType (op));
749
750   if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
751     return 1;
752
753   if (IS_VOLATILE (opetype))
754     return 1;
755   return 0;
756 }
757
758 /*-----------------------------------------------------------------*/
759 /* isOperandLiteral - returns 1 if an operand contains a literal   */
760 /*-----------------------------------------------------------------*/
761 int 
762 isOperandLiteral (operand * op)
763 {
764   sym_link *opetype;
765
766   if (!op)
767     return 0;
768
769   opetype = getSpec (operandType (op));
770
771   if (IS_LITERAL (opetype))
772     return 1;
773
774   return 0;
775 }
776 /*-----------------------------------------------------------------*/
777 /* isOperandInFarSpace - will return true if operand is in farSpace */
778 /*-----------------------------------------------------------------*/
779 bool 
780 isOperandInFarSpace (operand * op)
781 {
782   sym_link *etype;
783
784   if (!op)
785     return FALSE;
786
787   if (!IS_SYMOP (op))
788     return FALSE;
789
790   if (!IS_TRUE_SYMOP (op))
791     {
792       if (SPIL_LOC (op))
793         etype = SPIL_LOC (op)->etype;
794       else
795         return FALSE;
796     }
797   else
798     {
799       etype = getSpec (operandType (op));
800     }
801   return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
802 }
803
804 /*-----------------------------------------------------------------*/
805 /* isOperandOnStack - will return true if operand is on stack      */
806 /*-----------------------------------------------------------------*/
807 bool 
808 isOperandOnStack (operand * op)
809 {
810   sym_link *etype;
811
812   if (!op)
813     return FALSE;
814
815   if (!IS_SYMOP (op))
816     return FALSE;
817
818   etype = getSpec (operandType (op));
819
820   return ((IN_STACK (etype)) ? TRUE : FALSE);
821 }
822
823 /*-----------------------------------------------------------------*/
824 /* operandLitValue - literal value of an operand                   */
825 /*-----------------------------------------------------------------*/
826 double 
827 operandLitValue (operand * op)
828 {
829   assert (isOperandLiteral (op));
830
831   return floatFromVal (op->operand.valOperand);
832 }
833
834 /*-----------------------------------------------------------------*/
835 /* operandOperation - perforoms operations on operands             */
836 /*-----------------------------------------------------------------*/
837 operand *
838 operandOperation (operand * left, operand * right,
839                   int op, sym_link * type)
840 {
841   operand *retval = (operand *) 0;
842
843   assert (isOperandLiteral (left));
844   if (right)
845     assert (isOperandLiteral (right));
846
847   switch (op)
848     {
849     case '+':
850       retval = operandFromValue (valCastLiteral (type,
851                                                  operandLitValue (left) +
852                                                  operandLitValue (right)));
853       break;
854     case '-':
855       retval = operandFromValue (valCastLiteral (type,
856                                                  operandLitValue (left) -
857                                                  operandLitValue (right)));
858       break;
859     case '*':
860       retval = operandFromValue (valCastLiteral (type,
861                                                  operandLitValue (left) *
862                                                  operandLitValue (right)));
863       break;
864     case '/':
865       if ((unsigned long) operandLitValue (right) == 0)
866         {
867           werror (E_DIVIDE_BY_ZERO);
868           retval = right;
869
870         }
871       else
872         retval = operandFromValue (valCastLiteral (type,
873                                                    operandLitValue (left) /
874                                                    operandLitValue (right)));
875       break;
876     case '%':
877       if ((unsigned long) operandLitValue (right) == 0)
878         {
879           werror (E_DIVIDE_BY_ZERO);
880           retval = right;
881         }
882       else
883         retval = operandFromLit ((unsigned long) operandLitValue (left) %
884                                  (unsigned long) operandLitValue (right));
885       break;
886     case LEFT_OP:
887       retval = operandFromLit ((unsigned long) operandLitValue (left) <<
888                                (unsigned long) operandLitValue (right));
889       break;
890     case RIGHT_OP:
891       retval = operandFromLit ((unsigned long) operandLitValue (left) >>
892                                (unsigned long) operandLitValue (right));
893       break;
894     case EQ_OP:
895       retval = operandFromLit (operandLitValue (left) ==
896                                operandLitValue (right));
897       break;
898     case '<':
899       retval = operandFromLit (operandLitValue (left) <
900                                operandLitValue (right));
901       break;
902     case LE_OP:
903       retval = operandFromLit (operandLitValue (left) <=
904                                operandLitValue (right));
905       break;
906     case NE_OP:
907       retval = operandFromLit (operandLitValue (left) !=
908                                operandLitValue (right));
909       break;
910     case '>':
911       retval = operandFromLit (operandLitValue (left) >
912                                operandLitValue (right));
913       break;
914     case GE_OP:
915       retval = operandFromLit (operandLitValue (left) >=
916                                operandLitValue (right));
917       break;
918     case BITWISEAND:
919       retval = operandFromLit ((unsigned long) operandLitValue (left) &
920                                (unsigned long) operandLitValue (right));
921       break;
922     case '|':
923       retval = operandFromLit ((unsigned long) operandLitValue (left) |
924                                (unsigned long) operandLitValue (right));
925       break;
926     case '^':
927       retval = operandFromLit ((unsigned long) operandLitValue (left) ^
928                                (unsigned long) operandLitValue (right));
929       break;
930     case AND_OP:
931       retval = operandFromLit (operandLitValue (left) &&
932                                operandLitValue (right));
933       break;
934     case OR_OP:
935       retval = operandFromLit (operandLitValue (left) ||
936                                operandLitValue (right));
937       break;
938     case RRC:
939       {
940         long i = operandLitValue (left);
941
942         retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
943                                  (i << 1));
944       }
945       break;
946     case RLC:
947       {
948         long i = operandLitValue (left);
949
950         retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
951                                  (i >> 1));
952       }
953       break;
954
955     case UNARYMINUS:
956       retval = operandFromLit (-1 * operandLitValue (left));
957       break;
958
959     case '~':
960       retval = operandFromLit (~((long) operandLitValue (left)));
961       break;
962
963     case '!':
964       retval = operandFromLit (!operandLitValue (left));
965       break;
966
967     default:
968       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
969               " operandOperation invalid operator ");
970       assert (0);
971     }
972
973   return retval;
974 }
975
976
977 /*-----------------------------------------------------------------*/
978 /* isOperandEqual - compares two operand & return 1 if they r =    */
979 /*-----------------------------------------------------------------*/
980 int 
981 isOperandEqual (operand * left, operand * right)
982 {
983   /* if the pointers are equal then they are equal */
984   if (left == right)
985     return 1;
986
987   /* if either of them null then false */
988   if (!left || !right)
989     return 0;
990
991   if (left->type != right->type)
992     return 0;
993
994   if (IS_SYMOP (left) && IS_SYMOP (right))
995     return left->key == right->key;
996
997   /* if types are the same */
998   switch (left->type)
999     {
1000     case SYMBOL:
1001       return isSymbolEqual (left->operand.symOperand,
1002                             right->operand.symOperand);
1003     case VALUE:
1004       return (floatFromVal (left->operand.valOperand) ==
1005               floatFromVal (right->operand.valOperand));
1006     case TYPE:
1007       if (checkType (left->operand.typeOperand,
1008                      right->operand.typeOperand) == 1)
1009         return 1;
1010     }
1011
1012   return 0;
1013 }
1014
1015 /*-----------------------------------------------------------------*/
1016 /* isiCodeEqual - comapres two iCodes are returns true if yes      */
1017 /*-----------------------------------------------------------------*/
1018 int 
1019 isiCodeEqual (iCode * left, iCode * right)
1020 {
1021   /* if the same pointer */
1022   if (left == right)
1023     return 1;
1024
1025   /* if either of them null */
1026   if (!left || !right)
1027     return 0;
1028
1029   /* if operand are the same */
1030   if (left->op == right->op)
1031     {
1032
1033       /* compare all the elements depending on type */
1034       if (left->op != IFX)
1035         {
1036           if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1037             return 0;
1038           if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1039             return 0;
1040
1041         }
1042       else
1043         {
1044           if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1045             return 0;
1046           if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1047             return 0;
1048           if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1049             return 0;
1050         }
1051       return 1;
1052     }
1053   return 0;
1054 }
1055
1056 /*-----------------------------------------------------------------*/
1057 /* newiTempFromOp - create a temp Operand with same attributes     */
1058 /*-----------------------------------------------------------------*/
1059 operand *
1060 newiTempFromOp (operand * op)
1061 {
1062   operand *nop;
1063
1064   if (!op)
1065     return NULL;
1066
1067   if (!IS_ITEMP (op))
1068     return op;
1069
1070   nop = newiTempOperand (operandType (op), TRUE);
1071   nop->isaddr = op->isaddr;
1072   nop->isvolatile = op->isvolatile;
1073   nop->isGlobal = op->isGlobal;
1074   nop->isLiteral = op->isLiteral;
1075   nop->noSpilLoc = op->noSpilLoc;
1076   nop->usesDefs = op->usesDefs;
1077   nop->isParm = op->isParm;
1078   return nop;
1079 }
1080
1081 /*-----------------------------------------------------------------*/
1082 /* operand from operand - creates an operand holder for the type   */
1083 /*-----------------------------------------------------------------*/
1084 operand *
1085 operandFromOperand (operand * op)
1086 {
1087   operand *nop;
1088
1089   if (!op)
1090     return NULL;
1091   nop = newOperand ();
1092   nop->type = op->type;
1093   nop->isaddr = op->isaddr;
1094   nop->key = op->key;
1095   nop->isvolatile = op->isvolatile;
1096   nop->isGlobal = op->isGlobal;
1097   nop->isLiteral = op->isLiteral;
1098   nop->noSpilLoc = op->noSpilLoc;
1099   nop->usesDefs = op->usesDefs;
1100   nop->isParm = op->isParm;
1101
1102   switch (nop->type)
1103     {
1104     case SYMBOL:
1105       nop->operand.symOperand = op->operand.symOperand;
1106       break;
1107     case VALUE:
1108       nop->operand.valOperand = op->operand.valOperand;
1109       break;
1110     case TYPE:
1111       nop->operand.typeOperand = op->operand.typeOperand;
1112       break;
1113     }
1114
1115   return nop;
1116 }
1117
1118 /*-----------------------------------------------------------------*/
1119 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
1120 /*-----------------------------------------------------------------*/
1121 operand *
1122 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1123 {
1124   operand *nop = operandFromOperand (op);
1125
1126   if (nop->type == SYMBOL)
1127     {
1128       OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1129       OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1130     }
1131
1132   return nop;
1133 }
1134
1135 /*-----------------------------------------------------------------*/
1136 /* operandFromSymbol - creates an operand from a symbol            */
1137 /*-----------------------------------------------------------------*/
1138 operand *
1139 operandFromSymbol (symbol * sym)
1140 {
1141   operand *op;
1142   iCode *ic;
1143   int ok = 1;
1144   /* if the symbol's type is a literal */
1145   /* then it is an enumerator type     */
1146   if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1147     return operandFromValue (valFromType (sym->etype));
1148
1149   if (!sym->key)
1150     sym->key = ++operandKey;
1151
1152   /* if this an implicit variable, means struct/union */
1153   /* member so just return it                         */
1154   if (sym->implicit || IS_FUNC (sym->type))
1155     {
1156       op = newOperand ();
1157       op->type = SYMBOL;
1158       op->operand.symOperand = sym;
1159       op->key = sym->key;
1160       op->isvolatile = isOperandVolatile (op, TRUE);
1161       op->isGlobal = isOperandGlobal (op);
1162       return op;
1163     }
1164
1165   /* under the following conditions create a
1166      register equivalent for a local symbol */
1167   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1168       (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) &&
1169       options.stackAuto == 0)
1170     ok = 0;
1171
1172   if (!IS_AGGREGATE (sym->type) &&      /* not an aggregate */
1173       !IS_FUNC (sym->type) &&   /* not a function   */
1174       !sym->_isparm &&          /* not a parameter  */
1175       sym->level &&             /* is a local variable */
1176       !sym->addrtaken &&        /* whose address has not been taken */
1177       !sym->reqv &&             /* does not already have a register euivalence */
1178       !IS_VOLATILE (sym->etype) &&      /* not declared as volatile */
1179       !IS_STATIC (sym->etype) &&        /* and not declared static  */
1180       !sym->islbl &&            /* not a label */
1181       ok &&                     /* farspace check */
1182       !IS_BITVAR (sym->etype)   /* not a bit variable */
1183     )
1184     {
1185
1186       /* we will use it after all optimizations
1187          and before liveRange calculation */
1188       sym->reqv = newiTempOperand (sym->type, 0);
1189       sym->reqv->key = sym->key;
1190       OP_SYMBOL (sym->reqv)->key = sym->key;
1191       OP_SYMBOL (sym->reqv)->isreqv = 1;
1192       OP_SYMBOL (sym->reqv)->islocal = 1;
1193       SPIL_LOC (sym->reqv) = sym;
1194     }
1195
1196   if (!IS_AGGREGATE (sym->type))
1197     {
1198       op = newOperand ();
1199       op->type = SYMBOL;
1200       op->operand.symOperand = sym;
1201       op->isaddr = 1;
1202       op->key = sym->key;
1203       op->isvolatile = isOperandVolatile (op, TRUE);
1204       op->isGlobal = isOperandGlobal (op);
1205       op->isPtr = IS_PTR (operandType (op));
1206       op->isParm = sym->_isparm;
1207       return op;
1208     }
1209
1210   /* create :-                     */
1211   /*    itemp = &[_symbol]         */
1212
1213   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1214   IC_LEFT (ic)->type = SYMBOL;
1215   IC_LEFT (ic)->operand.symOperand = sym;
1216   IC_LEFT (ic)->key = sym->key;
1217   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1218   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1219   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1220
1221   /* create result */
1222   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1223   if (IS_ARRAY (sym->type))
1224     {
1225       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1226       IC_RESULT (ic)->isaddr = 0;
1227     }
1228   else
1229     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1230
1231   IC_RESULT (ic)->operand.symOperand->args = sym->args;
1232
1233   ADDTOCHAIN (ic);
1234
1235   return IC_RESULT (ic);
1236 }
1237
1238 /*-----------------------------------------------------------------*/
1239 /* operandFromValue - creates an operand from value                */
1240 /*-----------------------------------------------------------------*/
1241 operand *
1242 operandFromValue (value * val)
1243 {
1244   operand *op;
1245
1246   /* if this is a symbol then do the symbol thing */
1247   if (val->sym)
1248     return operandFromSymbol (val->sym);
1249
1250   /* this is not a symbol */
1251   op = newOperand ();
1252   op->type = VALUE;
1253   op->operand.valOperand = val;
1254   op->isLiteral = isOperandLiteral (op);
1255   return op;
1256 }
1257
1258 /*-----------------------------------------------------------------*/
1259 /* operandFromLink - operand from typeChain                        */
1260 /*-----------------------------------------------------------------*/
1261 operand *
1262 operandFromLink (sym_link * type)
1263 {
1264   operand *op;
1265
1266   /* operand from sym_link */
1267   if (!type)
1268     return NULL;
1269
1270   op = newOperand ();
1271   op->type = TYPE;
1272   op->operand.typeOperand = copyLinkChain (type);
1273   return op;
1274 }
1275
1276 /*-----------------------------------------------------------------*/
1277 /* operandFromLit - makes an operand from a literal value          */
1278 /*-----------------------------------------------------------------*/
1279 operand *
1280 operandFromLit (float i)
1281 {
1282   return operandFromValue (valueFromLit (i));
1283 }
1284
1285 /*-----------------------------------------------------------------*/
1286 /* operandFromAst - creates an operand from an ast                 */
1287 /*-----------------------------------------------------------------*/
1288 operand *
1289 operandFromAst (ast * tree,int lvl)
1290 {
1291
1292   if (!tree)
1293     return NULL;
1294
1295   /* depending on type do */
1296   switch (tree->type)
1297     {
1298     case EX_OP:
1299       return ast2iCode (tree,lvl+1);
1300       break;
1301
1302     case EX_VALUE:
1303       return operandFromValue (tree->opval.val);
1304       break;
1305
1306     case EX_LINK:
1307       return operandFromLink (tree->opval.lnk);
1308     }
1309
1310   assert (0);
1311   /*  Just to keep the comiler happy */
1312   return (operand *) 0;
1313 }
1314
1315 /*-----------------------------------------------------------------*/
1316 /* setOperandType - sets the operand's type to the given type      */
1317 /*-----------------------------------------------------------------*/
1318 void 
1319 setOperandType (operand * op, sym_link * type)
1320 {
1321   /* depending on the type of operand */
1322   switch (op->type)
1323     {
1324
1325     case VALUE:
1326       op->operand.valOperand->etype =
1327         getSpec (op->operand.valOperand->type =
1328                  copyLinkChain (type));
1329       return;
1330
1331     case SYMBOL:
1332       if (op->operand.symOperand->isitmp)
1333         op->operand.symOperand->etype =
1334           getSpec (op->operand.symOperand->type =
1335                    copyLinkChain (type));
1336       else
1337         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1338                 "attempt to modify type of source");
1339       return;
1340
1341     case TYPE:
1342       op->operand.typeOperand = copyLinkChain (type);
1343       return;
1344     }
1345
1346 }
1347 /*-----------------------------------------------------------------*/
1348 /* Get size in byte of ptr need to access an array                 */
1349 /*-----------------------------------------------------------------*/
1350 int
1351 getArraySizePtr (operand * op)
1352 {
1353   sym_link *ltype = operandType(op);
1354
1355   if(IS_PTR(ltype))
1356     {
1357       int size = getSize(ltype);
1358       return(IS_GENPTR(ltype)?(size-1):size);
1359     }
1360
1361   if(IS_ARRAY(ltype))
1362     {
1363       sym_link *letype = getSpec(ltype);
1364       switch (PTR_TYPE (SPEC_OCLS (letype)))
1365         {
1366         case IPOINTER:
1367         case PPOINTER:
1368         case POINTER:
1369           return (PTRSIZE);
1370         case EEPPOINTER:
1371         case FPOINTER:
1372         case CPOINTER:
1373         case FUNCTION:
1374           return (FPTRSIZE);
1375         case GPOINTER:
1376           return (GPTRSIZE-1);
1377
1378         default:
1379           return (FPTRSIZE);
1380         }
1381     }
1382   return (FPTRSIZE);
1383 }
1384
1385 /*-----------------------------------------------------------------*/
1386 /* perform "usual unary conversions"                               */
1387 /*-----------------------------------------------------------------*/
1388 operand *
1389 usualUnaryConversions (operand * op)
1390 {
1391   if (IS_INTEGRAL (operandType (op)))
1392     {
1393       if (getSize (operandType (op)) < INTSIZE)
1394         {
1395           /* Widen to int. */
1396           return geniCodeCast (INTTYPE, op, TRUE);
1397         }
1398     }
1399   return op;
1400 }
1401
1402 /*-----------------------------------------------------------------*/
1403 /* perform "usual binary conversions"                              */
1404 /*-----------------------------------------------------------------*/
1405 sym_link *
1406 usualBinaryConversions (operand ** op1, operand ** op2)
1407 {
1408   sym_link *ctype;
1409   sym_link *rtype = operandType (*op2);
1410   sym_link *ltype = operandType (*op1);
1411   
1412   ctype = computeType (ltype, rtype);
1413   *op1 = geniCodeCast (ctype, *op1, TRUE);
1414   *op2 = geniCodeCast (ctype, *op2, TRUE);
1415   
1416   return ctype;
1417 }
1418
1419 /*-----------------------------------------------------------------*/
1420 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1421 /*                          at address                             */
1422 /*-----------------------------------------------------------------*/
1423 operand *
1424 geniCodeRValue (operand * op, bool force)
1425 {
1426   iCode *ic;
1427   sym_link *type = operandType (op);
1428   sym_link *etype = getSpec (type);
1429
1430   /* if this is an array & already */
1431   /* an address then return this   */
1432   if (IS_AGGREGATE (type) ||
1433       (IS_PTR (type) && !force && !op->isaddr))
1434     return operandFromOperand (op);
1435
1436   /* if this is not an address then must be */
1437   /* rvalue already so return this one      */
1438   if (!op->isaddr)
1439     return op;
1440
1441   /* if this is not a temp symbol then */
1442   if (!IS_ITEMP (op) &&
1443       !force &&
1444       !IN_FARSPACE (SPEC_OCLS (etype)))
1445     {
1446       op = operandFromOperand (op);
1447       op->isaddr = 0;
1448       return op;
1449     }
1450
1451   if (IS_SPEC (type) &&
1452       IS_TRUE_SYMOP (op) &&
1453       (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
1454     {
1455       op = operandFromOperand (op);
1456       op->isaddr = 0;
1457       return op;
1458     }
1459
1460   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1461   if (IS_PTR (type) && op->isaddr && force)
1462     type = type->next;
1463
1464   type = copyLinkChain (type);
1465
1466   IC_RESULT (ic) = newiTempOperand (type, 1);
1467   IC_RESULT (ic)->isaddr = 0;
1468
1469 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1470
1471   /* if the right is a symbol */
1472   if (op->type == SYMBOL)
1473     IC_RESULT (ic)->operand.symOperand->args =
1474       op->operand.symOperand->args;
1475   ADDTOCHAIN (ic);
1476
1477   return IC_RESULT (ic);
1478 }
1479
1480 /*-----------------------------------------------------------------*/
1481 /* geniCodeCast - changes the value from one type to another       */
1482 /*-----------------------------------------------------------------*/
1483 operand *
1484 geniCodeCast (sym_link * type, operand * op, bool implicit)
1485 {
1486   iCode *ic;
1487   sym_link *optype;
1488   sym_link *opetype = getSpec (optype = operandType (op));
1489   sym_link *restype;
1490
1491   /* one of them has size zero then error */
1492   if (IS_VOID (optype))
1493     {
1494       werror (E_CAST_ZERO);
1495       return op;
1496     }
1497
1498   /* if the operand is already the desired type then do nothing */
1499   if (checkType (type, optype) == 1)
1500     return op;
1501
1502   /* if this is a literal then just change the type & return */
1503   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1504     return operandFromValue (valCastLiteral (type,
1505                                              operandLitValue (op)));
1506
1507   /* if casting to some pointer type &&
1508      the destination is not a generic pointer
1509      then give a warning : (only for implicit casts) */
1510   if (IS_PTR (optype) && implicit &&
1511       (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1512       !IS_GENPTR (type))
1513     {
1514       werror (E_INCOMPAT_CAST);
1515       werror (E_CONTINUE, "from type '");
1516       printTypeChain (optype, stderr);
1517       fprintf (stderr, "' to type '");
1518       printTypeChain (type, stderr);
1519       fprintf (stderr, "'\n");
1520     }
1521
1522   /* if they are the same size create an assignment */
1523   if (getSize (type) == getSize (optype) &&
1524       !IS_BITFIELD (type) &&
1525       !IS_FLOAT (type) &&
1526       !IS_FLOAT (optype) &&
1527       ((IS_SPEC (type) && IS_SPEC (optype)) ||
1528        (!IS_SPEC (type) && !IS_SPEC (optype))))
1529     {
1530
1531       ic = newiCode ('=', NULL, op);
1532       IC_RESULT (ic) = newiTempOperand (type, 0);
1533       SPIL_LOC (IC_RESULT (ic)) =
1534         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1535       IC_RESULT (ic)->isaddr = 0;
1536     }
1537   else
1538     {
1539       ic = newiCode (CAST, operandFromLink (type),
1540                      geniCodeRValue (op, FALSE));
1541
1542       IC_RESULT (ic) = newiTempOperand (type, 0);
1543     }
1544
1545   /* preserve the storage class & output class */
1546   /* of the original variable                  */
1547   restype = getSpec (operandType (IC_RESULT (ic)));
1548   SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1549   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1550
1551   ADDTOCHAIN (ic);
1552   return IC_RESULT (ic);
1553 }
1554
1555 /*-----------------------------------------------------------------*/
1556 /* geniCodeLabel - will create a Label                             */
1557 /*-----------------------------------------------------------------*/
1558 void 
1559 geniCodeLabel (symbol * label)
1560 {
1561   iCode *ic;
1562
1563   ic = newiCodeLabelGoto (LABEL, label);
1564   ADDTOCHAIN (ic);
1565 }
1566
1567 /*-----------------------------------------------------------------*/
1568 /* geniCodeGoto  - will create a Goto                              */
1569 /*-----------------------------------------------------------------*/
1570 void 
1571 geniCodeGoto (symbol * label)
1572 {
1573   iCode *ic;
1574
1575   ic = newiCodeLabelGoto (GOTO, label);
1576   ADDTOCHAIN (ic);
1577 }
1578
1579 /*-----------------------------------------------------------------*/
1580 /* geniCodeMultiply - gen intermediate code for multiplication     */
1581 /*-----------------------------------------------------------------*/
1582 operand *
1583 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1584 {
1585   iCode *ic;
1586   int p2 = 0;
1587   sym_link *resType;
1588   LRTYPE;
1589
1590   /* if they are both literal then we know the result */
1591   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1592     return operandFromValue (valMult (left->operand.valOperand,
1593                                       right->operand.valOperand));
1594
1595   if (IS_LITERAL(retype)) {
1596     p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1597   }
1598
1599   resType = usualBinaryConversions (&left, &right);
1600 #if 1
1601   rtype = operandType (right);
1602   retype = getSpec (rtype);
1603   ltype = operandType (left);
1604   letype = getSpec (ltype);
1605 #endif
1606   if (resultIsInt)
1607     {
1608       SPEC_NOUN(getSpec(resType))=V_INT;
1609       SPEC_SHORT(getSpec(resType))=0;
1610     }
1611
1612   /* if the right is a literal & power of 2 */
1613   /* then make it a left shift              */
1614   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more 
1615      efficient in most cases than 2 bytes result = 2 bytes << literal 
1616      if port has 1 byte muldiv */
1617   if (p2 && !IS_FLOAT (letype) &&
1618       !((resultIsInt) && (getSize (resType) != getSize (ltype)) && 
1619         (port->muldiv.native_below == 1)))
1620     {
1621       if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1622         {
1623           /* LEFT_OP need same size for left and result, */
1624           left = geniCodeCast (resType, left, TRUE);
1625           ltype = operandType (left);
1626         }
1627       ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1628     }
1629   else
1630     {
1631       ic = newiCode ('*', left, right);         /* normal multiplication */
1632       /* if the size left or right > 1 then support routine */
1633       if (getSize (ltype) > 1 || getSize (rtype) > 1)
1634         ic->supportRtn = 1;
1635
1636     }
1637   IC_RESULT (ic) = newiTempOperand (resType, 1);
1638
1639   ADDTOCHAIN (ic);
1640   return IC_RESULT (ic);
1641 }
1642
1643 /*-----------------------------------------------------------------*/
1644 /* geniCodeDivision - gen intermediate code for division           */
1645 /*-----------------------------------------------------------------*/
1646 operand *
1647 geniCodeDivision (operand * left, operand * right)
1648 {
1649   iCode *ic;
1650   int p2 = 0;
1651   sym_link *resType;
1652   sym_link *rtype = operandType (right);
1653   sym_link *retype = getSpec (rtype);
1654   sym_link *ltype = operandType (left);
1655   sym_link *letype = getSpec (ltype);
1656
1657   resType = usualBinaryConversions (&left, &right);
1658
1659   /* if the right is a literal & power of 2 */
1660   /* then make it a right shift             */
1661   if (IS_LITERAL (retype) &&
1662       !IS_FLOAT (letype) &&
1663       (p2 = powof2 ((unsigned long)
1664                     floatFromVal (right->operand.valOperand))))
1665     ic = newiCode (RIGHT_OP, left, operandFromLit (p2));        /* right shift */
1666   else
1667     {
1668       ic = newiCode ('/', left, right);         /* normal division */
1669       /* if the size left or right > 1 then support routine */
1670       if (getSize (ltype) > 1 || getSize (rtype) > 1)
1671         ic->supportRtn = 1;
1672     }
1673   IC_RESULT (ic) = newiTempOperand (resType, 0);
1674
1675   ADDTOCHAIN (ic);
1676   return IC_RESULT (ic);
1677 }
1678 /*-----------------------------------------------------------------*/
1679 /* geniCodeModulus  - gen intermediate code for modulus            */
1680 /*-----------------------------------------------------------------*/
1681 operand *
1682 geniCodeModulus (operand * left, operand * right)
1683 {
1684   iCode *ic;
1685   sym_link *resType;
1686   LRTYPE;
1687
1688   /* if they are both literal then we know the result */
1689   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1690     return operandFromValue (valMod (left->operand.valOperand,
1691                                      right->operand.valOperand));
1692
1693   resType = usualBinaryConversions (&left, &right);
1694
1695   /* now they are the same size */
1696   ic = newiCode ('%', left, right);
1697
1698   /* if the size left or right > 1 then support routine */
1699   if (getSize (ltype) > 1 || getSize (rtype) > 1)
1700     ic->supportRtn = 1;
1701   IC_RESULT (ic) = newiTempOperand (resType, 0);
1702
1703   ADDTOCHAIN (ic);
1704   return IC_RESULT (ic);
1705 }
1706
1707 /*-----------------------------------------------------------------*/
1708 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
1709 /*-----------------------------------------------------------------*/
1710 operand *
1711 geniCodePtrPtrSubtract (operand * left, operand * right)
1712 {
1713   iCode *ic;
1714   operand *result;
1715   LRTYPE;
1716
1717   /* if they are both literals then */
1718   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1719     {
1720       result = operandFromValue (valMinus (left->operand.valOperand,
1721                                            right->operand.valOperand));
1722       goto subtractExit;
1723     }
1724
1725   ic = newiCode ('-', left, right);
1726
1727   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1728   ADDTOCHAIN (ic);
1729
1730 subtractExit:
1731   return geniCodeDivision (result,
1732                            operandFromLit (getSize (ltype->next)));
1733 }
1734
1735 /*-----------------------------------------------------------------*/
1736 /* geniCodeSubtract - generates code for subtraction               */
1737 /*-----------------------------------------------------------------*/
1738 operand *
1739 geniCodeSubtract (operand * left, operand * right)
1740 {
1741   iCode *ic;
1742   int isarray = 0;
1743   sym_link *resType;
1744   LRTYPE;
1745
1746   /* if they both pointers then */
1747   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1748       (IS_PTR (rtype) || IS_ARRAY (rtype)))
1749     return geniCodePtrPtrSubtract (left, right);
1750
1751   /* if they are both literal then we know the result */
1752   if (IS_LITERAL (letype) && IS_LITERAL (retype)
1753       && left->isLiteral && right->isLiteral)
1754     return operandFromValue (valMinus (left->operand.valOperand,
1755                                        right->operand.valOperand));
1756
1757   /* if left is an array or pointer */
1758   if (IS_PTR (ltype) || IS_ARRAY (ltype))
1759     {
1760       isarray = left->isaddr;
1761       right = geniCodeMultiply (right,
1762                                 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1763       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1764     }
1765   else
1766     {                           /* make them the same size */
1767       resType = usualBinaryConversions (&left, &right);
1768     }
1769
1770   ic = newiCode ('-', left, right);
1771
1772   IC_RESULT (ic) = newiTempOperand (resType, 1);
1773   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1774
1775   /* if left or right is a float */
1776   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1777     ic->supportRtn = 1;
1778
1779   ADDTOCHAIN (ic);
1780   return IC_RESULT (ic);
1781 }
1782
1783 /*-----------------------------------------------------------------*/
1784 /* geniCodeAdd - generates iCode for addition                      */
1785 /*-----------------------------------------------------------------*/
1786 operand *
1787 geniCodeAdd (operand * left, operand * right,int lvl)
1788 {
1789   iCode *ic;
1790   sym_link *resType;
1791   operand *size;
1792   int isarray = 0;
1793   LRTYPE;
1794
1795   /* if left is an array then array access */
1796   if (IS_ARRAY (ltype))
1797     return geniCodeArray (left, right,lvl);
1798
1799   /* if the right side is LITERAL zero */
1800   /* return the left side              */
1801   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1802     return left;
1803
1804   /* if left is literal zero return right */
1805   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1806     return right;
1807
1808   /* if left is an array or pointer then size */
1809   if (IS_PTR (ltype))
1810     {
1811       isarray = left->isaddr;
1812       // there is no need to multiply with 1
1813       if (getSize(ltype->next)!=1) {
1814         size  = operandFromLit (getSize (ltype->next));
1815         right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1816       }
1817       resType = copyLinkChain (ltype);
1818     }
1819   else
1820     {                           /* make them the same size */
1821       resType = usualBinaryConversions (&left, &right);
1822     }
1823
1824   /* if they are both literals then we know */
1825   if (IS_LITERAL (letype) && IS_LITERAL (retype)
1826       && left->isLiteral && right->isLiteral)
1827     return operandFromValue (valPlus (valFromType (letype),
1828                                       valFromType (retype)));
1829
1830   ic = newiCode ('+', left, right);
1831
1832   IC_RESULT (ic) = newiTempOperand (resType, 1);
1833   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1834
1835   /* if left or right is a float then support
1836      routine */
1837   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1838     ic->supportRtn = 1;
1839
1840   ADDTOCHAIN (ic);
1841
1842   return IC_RESULT (ic);
1843
1844 }
1845
1846 /*-----------------------------------------------------------------*/
1847 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
1848 /*-----------------------------------------------------------------*/
1849 sym_link *
1850 aggrToPtr (sym_link * type, bool force)
1851 {
1852   sym_link *etype;
1853   sym_link *ptype;
1854
1855
1856   if (IS_PTR (type) && !force)
1857     return type;
1858
1859   etype = getSpec (type);
1860   ptype = newLink ();
1861
1862   ptype->next = type;
1863   /* if the output class is generic */
1864   if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1865     DCL_PTR_CONST (ptype) = port->mem.code_ro;
1866
1867   /* if the variable was declared a constant */
1868   /* then the pointer points to a constant */
1869   if (IS_CONSTANT (etype))
1870     DCL_PTR_CONST (ptype) = 1;
1871
1872   /* the variable was volatile then pointer to volatile */
1873   if (IS_VOLATILE (etype))
1874     DCL_PTR_VOLATILE (ptype) = 1;
1875   return ptype;
1876 }
1877
1878 /*-----------------------------------------------------------------*/
1879 /* geniCodeArray2Ptr - array to pointer                            */
1880 /*-----------------------------------------------------------------*/
1881 operand *
1882 geniCodeArray2Ptr (operand * op)
1883 {
1884   sym_link *optype = operandType (op);
1885   sym_link *opetype = getSpec (optype);
1886
1887   /* set the pointer depending on the storage class */
1888   if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1889     DCL_PTR_CONST (optype) = port->mem.code_ro;
1890
1891
1892   /* if the variable was declared a constant */
1893   /* then the pointer points to a constant */
1894   if (IS_CONSTANT (opetype))
1895     DCL_PTR_CONST (optype) = 1;
1896
1897   /* the variable was volatile then pointer to volatile */
1898   if (IS_VOLATILE (opetype))
1899     DCL_PTR_VOLATILE (optype) = 1;
1900   op->isaddr = 0;
1901   return op;
1902 }
1903
1904
1905 /*-----------------------------------------------------------------*/
1906 /* geniCodeArray - array access                                    */
1907 /*-----------------------------------------------------------------*/
1908 operand *
1909 geniCodeArray (operand * left, operand * right,int lvl)
1910 {
1911   iCode *ic;
1912   sym_link *ltype = operandType (left);
1913
1914   if (IS_PTR (ltype))
1915     {
1916       if (IS_PTR (ltype->next) && left->isaddr)
1917         {
1918           left = geniCodeRValue (left, FALSE);
1919         }
1920       return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
1921     }
1922
1923   right = geniCodeMultiply (right,
1924                             operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1925
1926   /* we can check for limits here */
1927   if (isOperandLiteral (right) &&
1928       IS_ARRAY (ltype) &&
1929       DCL_ELEM (ltype) &&
1930       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
1931     {
1932       werror (E_ARRAY_BOUND);
1933       right = operandFromLit (0);
1934     }
1935
1936   ic = newiCode ('+', left, right);
1937
1938   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
1939                                       !IS_AGGREGATE (ltype->next) &&
1940                                       !IS_PTR (ltype->next))
1941                                      ? ltype : ltype->next), 0);
1942
1943   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
1944   ADDTOCHAIN (ic);
1945   return IC_RESULT (ic);
1946 }
1947
1948 /*-----------------------------------------------------------------*/
1949 /* geniCodeStruct - generates intermediate code for structres      */
1950 /*-----------------------------------------------------------------*/
1951 operand *
1952 geniCodeStruct (operand * left, operand * right, bool islval)
1953 {
1954   iCode *ic;
1955   sym_link *type = operandType (left);
1956   sym_link *etype = getSpec (type);
1957   sym_link *retype;
1958   symbol *element = getStructElement (SPEC_STRUCT (etype),
1959                                       right->operand.symOperand);
1960
1961   /* add the offset */
1962   ic = newiCode ('+', left, operandFromLit (element->offset));
1963
1964   IC_RESULT (ic) = newiTempOperand (element->type, 0);
1965
1966   /* preserve the storage & output class of the struct */
1967   /* as well as the volatile attribute */
1968   retype = getSpec (operandType (IC_RESULT (ic)));
1969   SPEC_SCLS (retype) = SPEC_SCLS (etype);
1970   SPEC_OCLS (retype) = SPEC_OCLS (etype);
1971   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
1972
1973   if (IS_PTR (element->type))
1974     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1975
1976   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
1977
1978
1979   ADDTOCHAIN (ic);
1980   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
1981 }
1982
1983 /*-----------------------------------------------------------------*/
1984 /* geniCodePostInc - generate int code for Post increment          */
1985 /*-----------------------------------------------------------------*/
1986 operand *
1987 geniCodePostInc (operand * op)
1988 {
1989   iCode *ic;
1990   operand *rOp;
1991   sym_link *optype = operandType (op);
1992   operand *result;
1993   operand *rv = (IS_ITEMP (op) ?
1994                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
1995                  op);
1996   sym_link *rvtype = operandType (rv);
1997   int size = 0;
1998
1999   /* if this is not an address we have trouble */
2000   if (!op->isaddr)
2001     {
2002       werror (E_LVALUE_REQUIRED, "++");
2003       return op;
2004     }
2005
2006   rOp = newiTempOperand (rvtype, 0);
2007   rOp->noSpilLoc = 1;
2008
2009   if (IS_ITEMP (rv))
2010     rv->noSpilLoc = 1;
2011
2012   geniCodeAssign (rOp, rv, 0);
2013
2014   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2015   if (IS_FLOAT (rvtype))
2016     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2017   else
2018     ic = newiCode ('+', rv, operandFromLit (size));
2019
2020   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2021   ADDTOCHAIN (ic);
2022
2023   geniCodeAssign (op, result, 0);
2024
2025   return rOp;
2026
2027 }
2028
2029 /*-----------------------------------------------------------------*/
2030 /* geniCodePreInc - generate code for preIncrement                 */
2031 /*-----------------------------------------------------------------*/
2032 operand *
2033 geniCodePreInc (operand * op)
2034 {
2035   iCode *ic;
2036   sym_link *optype = operandType (op);
2037   operand *rop = (IS_ITEMP (op) ?
2038                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2039                   op);
2040   sym_link *roptype = operandType (rop);
2041   operand *result;
2042   int size = 0;
2043
2044   if (!op->isaddr)
2045     {
2046       werror (E_LVALUE_REQUIRED, "++");
2047       return op;
2048     }
2049
2050
2051   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2052   if (IS_FLOAT (roptype))
2053     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2054   else
2055     ic = newiCode ('+', rop, operandFromLit (size));
2056   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2057   ADDTOCHAIN (ic);
2058
2059
2060   return geniCodeAssign (op, result, 0);
2061 }
2062
2063 /*-----------------------------------------------------------------*/
2064 /* geniCodePostDec - generates code for Post decrement             */
2065 /*-----------------------------------------------------------------*/
2066 operand *
2067 geniCodePostDec (operand * op)
2068 {
2069   iCode *ic;
2070   operand *rOp;
2071   sym_link *optype = operandType (op);
2072   operand *result;
2073   operand *rv = (IS_ITEMP (op) ?
2074                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2075                  op);
2076   sym_link *rvtype = operandType (rv);
2077   int size = 0;
2078
2079   /* if this is not an address we have trouble */
2080   if (!op->isaddr)
2081     {
2082       werror (E_LVALUE_REQUIRED, "++");
2083       return op;
2084     }
2085
2086   rOp = newiTempOperand (rvtype, 0);
2087   rOp->noSpilLoc = 1;
2088
2089   if (IS_ITEMP (rv))
2090     rv->noSpilLoc = 1;
2091
2092   geniCodeAssign (rOp, rv, 0);
2093
2094   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2095   if (IS_FLOAT (rvtype))
2096     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2097   else
2098     ic = newiCode ('-', rv, operandFromLit (size));
2099
2100   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2101   ADDTOCHAIN (ic);
2102
2103   geniCodeAssign (op, result, 0);
2104
2105   return rOp;
2106
2107 }
2108
2109 /*-----------------------------------------------------------------*/
2110 /* geniCodePreDec - generate code for pre  decrement               */
2111 /*-----------------------------------------------------------------*/
2112 operand *
2113 geniCodePreDec (operand * op)
2114 {
2115   iCode *ic;
2116   sym_link *optype = operandType (op);
2117   operand *rop = (IS_ITEMP (op) ?
2118                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2119                   op);
2120   sym_link *roptype = operandType (rop);
2121   operand *result;
2122   int size = 0;
2123
2124   if (!op->isaddr)
2125     {
2126       werror (E_LVALUE_REQUIRED, "++");
2127       return op;
2128     }
2129
2130
2131   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2132   if (IS_FLOAT (roptype))
2133     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2134   else
2135     ic = newiCode ('-', rop, operandFromLit (size));
2136   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2137   ADDTOCHAIN (ic);
2138
2139
2140   return geniCodeAssign (op, result, 0);
2141 }
2142
2143
2144 /*-----------------------------------------------------------------*/
2145 /* geniCodeBitwise - gen int code for bitWise  operators           */
2146 /*-----------------------------------------------------------------*/
2147 operand *
2148 geniCodeBitwise (operand * left, operand * right,
2149                  int oper, sym_link * resType)
2150 {
2151   iCode *ic;
2152
2153   left = geniCodeCast (resType, left, TRUE);
2154   right = geniCodeCast (resType, right, TRUE);
2155
2156   ic = newiCode (oper, left, right);
2157   IC_RESULT (ic) = newiTempOperand (resType, 0);
2158
2159   ADDTOCHAIN (ic);
2160   return IC_RESULT (ic);
2161 }
2162
2163 /*-----------------------------------------------------------------*/
2164 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2165 /*-----------------------------------------------------------------*/
2166 operand *
2167 geniCodeAddressOf (operand * op)
2168 {
2169   iCode *ic;
2170   sym_link *p;
2171   sym_link *optype = operandType (op);
2172   sym_link *opetype = getSpec (optype);
2173
2174   /* lvalue check already done in decorateType */
2175   /* this must be a lvalue */
2176 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2177 /*  werror (E_LVALUE_REQUIRED,"&"); */
2178 /*  return op; */
2179 /*     } */
2180
2181   p = newLink ();
2182   p->class = DECLARATOR;
2183
2184   /* set the pointer depending on the storage class */
2185   if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2186     DCL_PTR_CONST (p) = port->mem.code_ro;
2187
2188   /* make sure we preserve the const & volatile */
2189   if (IS_CONSTANT (opetype))
2190     DCL_PTR_CONST (p) = 1;
2191
2192   if (IS_VOLATILE (opetype))
2193     DCL_PTR_VOLATILE (p) = 1;
2194
2195   p->next = copyLinkChain (optype);
2196
2197   /* if already a temp */
2198   if (IS_ITEMP (op))
2199     {
2200       setOperandType (op, p);
2201       op->isaddr = 0;
2202       return op;
2203     }
2204
2205   /* other wise make this of the type coming in */
2206   ic = newiCode (ADDRESS_OF, op, NULL);
2207   IC_RESULT (ic) = newiTempOperand (p, 1);
2208   IC_RESULT (ic)->isaddr = 0;
2209   ADDTOCHAIN (ic);
2210   return IC_RESULT (ic);
2211 }
2212 /*-----------------------------------------------------------------*/
2213 /* setOClass - sets the output class depending on the pointer type */
2214 /*-----------------------------------------------------------------*/
2215 void 
2216 setOClass (sym_link * ptr, sym_link * spec)
2217 {
2218   switch (DCL_TYPE (ptr))
2219     {
2220     case POINTER:
2221       SPEC_OCLS (spec) = data;
2222       break;
2223
2224     case GPOINTER:
2225       SPEC_OCLS (spec) = generic;
2226       break;
2227
2228     case FPOINTER:
2229       SPEC_OCLS (spec) = xdata;
2230       break;
2231
2232     case CPOINTER:
2233       SPEC_OCLS (spec) = code;
2234       break;
2235
2236     case IPOINTER:
2237       SPEC_OCLS (spec) = idata;
2238       break;
2239
2240     case PPOINTER:
2241       SPEC_OCLS (spec) = xstack;
2242       break;
2243
2244     case EEPPOINTER:
2245       SPEC_OCLS (spec) = eeprom;
2246       break;
2247
2248     default:
2249       break;
2250
2251     }
2252 }
2253
2254 /*-----------------------------------------------------------------*/
2255 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2256 /*-----------------------------------------------------------------*/
2257 operand *
2258 geniCodeDerefPtr (operand * op,int lvl)
2259 {
2260   sym_link *rtype, *retype;
2261   sym_link *optype = operandType (op);
2262
2263   /* if this is a pointer then generate the rvalue */
2264   if (IS_PTR (optype))
2265     {
2266       if (IS_TRUE_SYMOP (op))
2267         {
2268           op->isaddr = 1;
2269           op = geniCodeRValue (op, TRUE);
2270         }
2271       else
2272         op = geniCodeRValue (op, TRUE);
2273     }
2274
2275   /* now get rid of the pointer part */
2276   if (isLvaluereq(lvl) && IS_ITEMP (op))
2277     {
2278       retype = getSpec (rtype = copyLinkChain (optype));
2279     }
2280   else
2281     {
2282       retype = getSpec (rtype = copyLinkChain (optype->next));
2283     }
2284
2285   /* if this is a pointer then outputclass needs 2b updated */
2286   if (IS_PTR (optype))
2287     setOClass (optype, retype);
2288
2289   op->isGptr = IS_GENPTR (optype);
2290
2291   /* if the pointer was declared as a constant */
2292   /* then we cannot allow assignment to the derefed */
2293   if (IS_PTR_CONST (optype))
2294     SPEC_CONST (retype) = 1;
2295
2296   op->isaddr = (IS_PTR (rtype) ||
2297                 IS_STRUCT (rtype) ||
2298                 IS_INT (rtype) ||
2299                 IS_CHAR (rtype) ||
2300                 IS_FLOAT (rtype));
2301
2302   if (!isLvaluereq(lvl))
2303     op = geniCodeRValue (op, TRUE);
2304
2305   setOperandType (op, rtype);
2306
2307   return op;
2308 }
2309
2310 /*-----------------------------------------------------------------*/
2311 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2312 /*-----------------------------------------------------------------*/
2313 operand *
2314 geniCodeUnaryMinus (operand * op)
2315 {
2316   iCode *ic;
2317   sym_link *optype = operandType (op);
2318
2319   if (IS_LITERAL (optype))
2320     return operandFromLit (-floatFromVal (op->operand.valOperand));
2321
2322   ic = newiCode (UNARYMINUS, op, NULL);
2323   IC_RESULT (ic) = newiTempOperand (optype, 0);
2324   ADDTOCHAIN (ic);
2325   return IC_RESULT (ic);
2326 }
2327
2328 /*-----------------------------------------------------------------*/
2329 /* geniCodeLeftShift - gen i code for left shift                   */
2330 /*-----------------------------------------------------------------*/
2331 operand *
2332 geniCodeLeftShift (operand * left, operand * right)
2333 {
2334   iCode *ic;
2335
2336   ic = newiCode (LEFT_OP, left, right);
2337   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2338   ADDTOCHAIN (ic);
2339   return IC_RESULT (ic);
2340 }
2341
2342 /*-----------------------------------------------------------------*/
2343 /* geniCodeRightShift - gen i code for right shift                 */
2344 /*-----------------------------------------------------------------*/
2345 operand *
2346 geniCodeRightShift (operand * left, operand * right)
2347 {
2348   iCode *ic;
2349
2350   ic = newiCode (RIGHT_OP, left, right);
2351   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2352   ADDTOCHAIN (ic);
2353   return IC_RESULT (ic);
2354 }
2355
2356 #if defined(__BORLANDC__) || defined(_MSC_VER)
2357 #define LONG_LONG __int64
2358 #else
2359 #define LONG_LONG long long
2360 #endif
2361
2362 /*-----------------------------------------------------------------*/
2363 /* geniCodeLogic- logic code                                       */
2364 /*-----------------------------------------------------------------*/
2365 operand *
2366 geniCodeLogic (operand * left, operand * right, int op)
2367 {
2368   iCode *ic;
2369   sym_link *ctype;
2370   sym_link *rtype = operandType (right);
2371   sym_link *ltype = operandType (left);
2372
2373   /* left is integral type and right is literal then
2374      check if the literal value is within bounds */
2375   if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2376     {
2377       int nbits = bitsForType (ltype);
2378       long v = operandLitValue (right);
2379
2380       if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2381         werror (W_CONST_RANGE, " compare operation ");
2382     }
2383
2384   ctype = usualBinaryConversions (&left, &right);
2385
2386   ic = newiCode (op, left, right);
2387   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2388
2389   /* if comparing float
2390      and not a '==' || '!=' || '&&' || '||' (these
2391      will be inlined */
2392   if (IS_FLOAT(ctype) &&
2393       op != EQ_OP &&
2394       op != NE_OP &&
2395       op != AND_OP &&
2396       op != OR_OP)
2397     ic->supportRtn = 1;
2398
2399   ADDTOCHAIN (ic);
2400   return IC_RESULT (ic);
2401 }
2402
2403 /*-----------------------------------------------------------------*/
2404 /* geniCodeUnary - for a a generic unary operation                 */
2405 /*-----------------------------------------------------------------*/
2406 operand *
2407 geniCodeUnary (operand * op, int oper)
2408 {
2409   iCode *ic = newiCode (oper, op, NULL);
2410
2411   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2412   ADDTOCHAIN (ic);
2413   return IC_RESULT (ic);
2414 }
2415
2416 /*-----------------------------------------------------------------*/
2417 /* geniCodeConditional - geniCode for '?' ':' operation            */
2418 /*-----------------------------------------------------------------*/
2419 operand *
2420 geniCodeConditional (ast * tree,int lvl)
2421 {
2422   iCode *ic;
2423   symbol *falseLabel = newiTempLabel (NULL);
2424   symbol *exitLabel = newiTempLabel (NULL);
2425   operand *cond = ast2iCode (tree->left,lvl+1);
2426   operand *true, *false, *result;
2427
2428   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2429                           NULL, falseLabel);
2430   ADDTOCHAIN (ic);
2431
2432   true = ast2iCode (tree->right->left,lvl+1);
2433
2434   /* move the value to a new Operand */
2435   result = newiTempOperand (operandType (true), 0);
2436   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2437
2438   /* generate an unconditional goto */
2439   geniCodeGoto (exitLabel);
2440
2441   /* now for the right side */
2442   geniCodeLabel (falseLabel);
2443
2444   false = ast2iCode (tree->right->right,lvl+1);
2445   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2446
2447   /* create the exit label */
2448   geniCodeLabel (exitLabel);
2449
2450   return result;
2451 }
2452
2453 /*-----------------------------------------------------------------*/
2454 /* geniCodeAssign - generate code for assignment                   */
2455 /*-----------------------------------------------------------------*/
2456 operand *
2457 geniCodeAssign (operand * left, operand * right, int nosupdate)
2458 {
2459   iCode *ic;
2460   sym_link *ltype = operandType (left);
2461   sym_link *rtype = operandType (right);
2462
2463   if (!left->isaddr && !IS_ITEMP (left))
2464     {
2465       werror (E_LVALUE_REQUIRED, "assignment");
2466       return left;
2467     }
2468
2469   /* left is integral type and right is literal then
2470      check if the literal value is within bounds */
2471   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2472     {
2473       int nbits = bitsForType (ltype);
2474       long v = operandLitValue (right);
2475
2476       if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2477         werror (W_CONST_RANGE, " = operation");
2478     }
2479
2480   /* if the left & right type don't exactly match */
2481   /* if pointer set then make sure the check is
2482      done with the type & not the pointer */
2483   /* then cast rights type to left */
2484
2485   /* first check the type for pointer assignement */
2486   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2487       checkType (ltype, rtype) < 0)
2488     {
2489       if (checkType (ltype->next, rtype) < 0)
2490         right = geniCodeCast (ltype->next, right, TRUE);
2491     }
2492   else if (checkType (ltype, rtype) < 0)
2493     right = geniCodeCast (ltype, right, TRUE);
2494
2495   /* if left is a true symbol & ! volatile
2496      create an assignment to temporary for
2497      the right & then assign this temporary
2498      to the symbol this is SSA . isn't it simple
2499      and folks have published mountains of paper on it */
2500   if (IS_TRUE_SYMOP (left) &&
2501       !isOperandVolatile (left, FALSE) &&
2502       isOperandGlobal (left))
2503     {
2504       symbol *sym = NULL;
2505
2506       if (IS_TRUE_SYMOP (right))
2507         sym = OP_SYMBOL (right);
2508       ic = newiCode ('=', NULL, right);
2509       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2510       SPIL_LOC (right) = sym;
2511       ADDTOCHAIN (ic);
2512     }
2513
2514   ic = newiCode ('=', NULL, right);
2515   IC_RESULT (ic) = left;
2516   ADDTOCHAIN (ic);
2517
2518   /* if left isgptr flag is set then support
2519      routine will be required */
2520   if (left->isGptr)
2521     ic->supportRtn = 1;
2522
2523   ic->nosupdate = nosupdate;
2524   return left;
2525 }
2526
2527 /*-----------------------------------------------------------------*/
2528 /* geniCodeSEParms - generate code for side effecting fcalls       */
2529 /*-----------------------------------------------------------------*/
2530 static void 
2531 geniCodeSEParms (ast * parms,int lvl)
2532 {
2533   if (!parms)
2534     return;
2535
2536   if (parms->type == EX_OP && parms->opval.op == PARAM)
2537     {
2538       geniCodeSEParms (parms->left,lvl);
2539       geniCodeSEParms (parms->right,lvl);
2540       return;
2541     }
2542
2543   /* hack don't like this but too lazy to think of
2544      something better */
2545   if (IS_ADDRESS_OF_OP (parms))
2546     parms->left->lvalue = 1;
2547
2548   if (IS_CAST_OP (parms) &&
2549       IS_PTR (parms->ftype) &&
2550       IS_ADDRESS_OF_OP (parms->right))
2551     parms->right->left->lvalue = 1;
2552
2553   parms->opval.oprnd =
2554     geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2555
2556   parms->type = EX_OPERAND;
2557 }
2558
2559 /*-----------------------------------------------------------------*/
2560 /* geniCodeParms - generates parameters                            */
2561 /*-----------------------------------------------------------------*/
2562 static void 
2563 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2564 {
2565   iCode *ic;
2566   operand *pval;
2567
2568   if (!parms)
2569     return;
2570
2571   /* if this is a param node then do the left & right */
2572   if (parms->type == EX_OP && parms->opval.op == PARAM)
2573     {
2574       geniCodeParms (parms->left, stack, fetype, func,lvl);
2575       geniCodeParms (parms->right, stack, fetype, func,lvl);
2576       return;
2577     }
2578
2579   /* get the parameter value */
2580   if (parms->type == EX_OPERAND)
2581     pval = parms->opval.oprnd;
2582   else
2583     {
2584       /* maybe this else should go away ?? */
2585       /* hack don't like this but too lazy to think of
2586          something better */
2587       if (IS_ADDRESS_OF_OP (parms))
2588         parms->left->lvalue = 1;
2589
2590       if (IS_CAST_OP (parms) &&
2591           IS_PTR (parms->ftype) &&
2592           IS_ADDRESS_OF_OP (parms->right))
2593         parms->right->left->lvalue = 1;
2594
2595       pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2596     }
2597
2598   /* if register parm then make it a send */
2599   if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2600        IS_REGPARM (parms->etype)) && !func->hasVargs)
2601     {
2602       ic = newiCode (SEND, pval, NULL);
2603       ADDTOCHAIN (ic);
2604     }
2605   else
2606     {
2607       /* now decide whether to push or assign */
2608       if (!(options.stackAuto || IS_RENT (fetype)))
2609         {
2610
2611           /* assign */
2612           operand *top = operandFromSymbol (parms->argSym);
2613           geniCodeAssign (top, pval, 1);
2614         }
2615       else
2616         {
2617           sym_link *p = operandType (pval);
2618           /* push */
2619           ic = newiCode (IPUSH, pval, NULL);
2620           ic->parmPush = 1;
2621           /* update the stack adjustment */
2622           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2623           ADDTOCHAIN (ic);
2624         }
2625     }
2626
2627 }
2628
2629 /*-----------------------------------------------------------------*/
2630 /* geniCodeCall - generates temp code for calling                  */
2631 /*-----------------------------------------------------------------*/
2632 operand *
2633 geniCodeCall (operand * left, ast * parms,int lvl)
2634 {
2635   iCode *ic;
2636   operand *result;
2637   sym_link *type, *etype;
2638   int stack = 0;
2639
2640   /* take care of parameters with side-effecting
2641      function calls in them, this is required to take care
2642      of overlaying function parameters */
2643   geniCodeSEParms (parms,lvl);
2644
2645   /* first the parameters */
2646   geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2647
2648   /* now call : if symbol then pcall */
2649   if (IS_OP_POINTER (left) || IS_ITEMP(left))
2650     ic = newiCode (PCALL, left, NULL);
2651   else
2652     ic = newiCode (CALL, left, NULL);
2653
2654   IC_ARGS (ic) = left->operand.symOperand->args;
2655   type = copyLinkChain (operandType (left)->next);
2656   etype = getSpec (type);
2657   SPEC_EXTR (etype) = 0;
2658   IC_RESULT (ic) = result = newiTempOperand (type, 1);
2659
2660   ADDTOCHAIN (ic);
2661
2662   /* stack adjustment after call */
2663   ic->parmBytes = stack;
2664
2665   return result;
2666 }
2667
2668 /*-----------------------------------------------------------------*/
2669 /* geniCodeReceive - generate intermediate code for "receive"      */
2670 /*-----------------------------------------------------------------*/
2671 static void 
2672 geniCodeReceive (value * args)
2673 {
2674   /* for all arguments that are passed in registers */
2675   while (args)
2676     {
2677
2678       if (IS_REGPARM (args->etype))
2679         {
2680           operand *opr = operandFromValue (args);
2681           operand *opl;
2682           symbol *sym = OP_SYMBOL (opr);
2683           iCode *ic;
2684
2685           /* we will use it after all optimizations
2686              and before liveRange calculation */
2687           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2688             {
2689
2690               if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2691                   options.stackAuto == 0 &&
2692                   !TARGET_IS_DS390)
2693                 {
2694                 }
2695               else
2696                 {
2697                   opl = newiTempOperand (args->type, 0);
2698                   sym->reqv = opl;
2699                   sym->reqv->key = sym->key;
2700                   OP_SYMBOL (sym->reqv)->key = sym->key;
2701                   OP_SYMBOL (sym->reqv)->isreqv = 1;
2702                   OP_SYMBOL (sym->reqv)->islocal = 0;
2703                   SPIL_LOC (sym->reqv) = sym;
2704                 }
2705             }
2706
2707           ic = newiCode (RECEIVE, NULL, NULL);
2708           currFunc->recvSize = getSize (sym->etype);
2709           IC_RESULT (ic) = opr;
2710           ADDTOCHAIN (ic);
2711         }
2712
2713       args = args->next;
2714     }
2715 }
2716
2717 /*-----------------------------------------------------------------*/
2718 /* geniCodeFunctionBody - create the function body                 */
2719 /*-----------------------------------------------------------------*/
2720 void 
2721 geniCodeFunctionBody (ast * tree,int lvl)
2722 {
2723   iCode *ic;
2724   operand *func;
2725   sym_link *fetype;
2726   int savelineno;
2727
2728   /* reset the auto generation */
2729   /* numbers */
2730   iTempNum = 0;
2731   iTempLblNum = 0;
2732   operandKey = 0;
2733   iCodeKey = 0;
2734   func = ast2iCode (tree->left,lvl+1);
2735   fetype = getSpec (operandType (func));
2736
2737   savelineno = lineno;
2738   lineno = OP_SYMBOL (func)->lineDef;
2739   /* create an entry label */
2740   geniCodeLabel (entryLabel);
2741   lineno = savelineno;
2742
2743   /* create a proc icode */
2744   ic = newiCode (FUNCTION, func, NULL);
2745   /* if the function has parmas   then */
2746   /* save the parameters information    */
2747   ic->argLabel.args = tree->values.args;
2748   ic->lineno = OP_SYMBOL (func)->lineDef;
2749
2750   ADDTOCHAIN (ic);
2751
2752   /* for all parameters that are passed
2753      on registers add a "receive" */
2754   geniCodeReceive (tree->values.args);
2755
2756   /* generate code for the body */
2757   ast2iCode (tree->right,lvl+1);
2758
2759   /* create a label for return */
2760   geniCodeLabel (returnLabel);
2761
2762   /* now generate the end proc */
2763   ic = newiCode (ENDFUNCTION, func, NULL);
2764   ADDTOCHAIN (ic);
2765   return;
2766 }
2767
2768 /*-----------------------------------------------------------------*/
2769 /* geniCodeReturn - gen icode for 'return' statement               */
2770 /*-----------------------------------------------------------------*/
2771 void 
2772 geniCodeReturn (operand * op)
2773 {
2774   iCode *ic;
2775
2776   /* if the operand is present force an rvalue */
2777   if (op)
2778     op = geniCodeRValue (op, FALSE);
2779
2780   ic = newiCode (RETURN, op, NULL);
2781   ADDTOCHAIN (ic);
2782 }
2783
2784 /*-----------------------------------------------------------------*/
2785 /* geniCodeIfx - generates code for extended if statement          */
2786 /*-----------------------------------------------------------------*/
2787 void 
2788 geniCodeIfx (ast * tree,int lvl)
2789 {
2790   iCode *ic;
2791   operand *condition = ast2iCode (tree->left,lvl+1);
2792   sym_link *cetype;
2793
2794   /* if condition is null then exit */
2795   if (!condition)
2796     goto exit;
2797   else
2798     condition = geniCodeRValue (condition, FALSE);
2799
2800   cetype = getSpec (operandType (condition));
2801   /* if the condition is a literal */
2802   if (IS_LITERAL (cetype))
2803     {
2804       if (floatFromVal (condition->operand.valOperand))
2805         {
2806           if (tree->trueLabel)
2807             geniCodeGoto (tree->trueLabel);
2808           else
2809             assert (1);
2810         }
2811       else
2812         {
2813           if (tree->falseLabel)
2814             geniCodeGoto (tree->falseLabel);
2815           else
2816             assert (1);
2817         }
2818       goto exit;
2819     }
2820
2821   if (tree->trueLabel)
2822     {
2823       ic = newiCodeCondition (condition,
2824                               tree->trueLabel,
2825                               NULL);
2826       ADDTOCHAIN (ic);
2827
2828       if (tree->falseLabel)
2829         geniCodeGoto (tree->falseLabel);
2830     }
2831   else
2832     {
2833       ic = newiCodeCondition (condition,
2834                               NULL,
2835                               tree->falseLabel);
2836       ADDTOCHAIN (ic);
2837     }
2838
2839 exit:
2840   ast2iCode (tree->right,lvl+1);
2841 }
2842
2843 /*-----------------------------------------------------------------*/
2844 /* geniCodeJumpTable - tries to create a jump table for switch     */
2845 /*-----------------------------------------------------------------*/
2846 int 
2847 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2848 {
2849   int min = 0, max = 0, t, cnt = 0;
2850   value *vch;
2851   iCode *ic;
2852   operand *boundary;
2853   symbol *falseLabel;
2854   set *labels = NULL;
2855
2856   if (!tree || !caseVals)
2857     return 0;
2858
2859   /* the criteria for creating a jump table is */
2860   /* all integer numbers between the maximum & minimum must */
2861   /* be present , the maximum value should not exceed 255 */
2862   min = max = (int) floatFromVal (vch = caseVals);
2863   sprintf (buffer, "_case_%d_%d",
2864            tree->values.switchVals.swNum,
2865            min);
2866   addSet (&labels, newiTempLabel (buffer));
2867
2868   /* if there is only one case value then no need */
2869   if (!(vch = vch->next))
2870     return 0;
2871
2872   while (vch)
2873     {
2874       if (((t = (int) floatFromVal (vch)) - max) != 1)
2875         return 0;
2876       sprintf (buffer, "_case_%d_%d",
2877                tree->values.switchVals.swNum,
2878                t);
2879       addSet (&labels, newiTempLabel (buffer));
2880       max = t;
2881       cnt++;
2882       vch = vch->next;
2883     }
2884
2885   /* if the number of case statements <= 2 then */
2886   /* it is not economical to create the jump table */
2887   /* since two compares are needed for boundary conditions */
2888   if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2889     return 0;
2890
2891   if (tree->values.switchVals.swDefault)
2892     sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2893   else
2894     sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2895
2896   falseLabel = newiTempLabel (buffer);
2897
2898   /* so we can create a jumptable */
2899   /* first we rule out the boundary conditions */
2900   /* if only optimization says so */
2901   if (!optimize.noJTabBoundary)
2902     {
2903       sym_link *cetype = getSpec (operandType (cond));
2904       /* no need to check the lower bound if
2905          the condition is unsigned & minimum value is zero */
2906       if (!(min == 0 && SPEC_USIGN (cetype)))
2907         {
2908           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2909           ic = newiCodeCondition (boundary, falseLabel, NULL);
2910           ADDTOCHAIN (ic);
2911         }
2912
2913       /* now for upper bounds */
2914       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
2915       ic = newiCodeCondition (boundary, falseLabel, NULL);
2916       ADDTOCHAIN (ic);
2917     }
2918
2919   /* if the min is not zero then we no make it zero */
2920   if (min)
2921     {
2922       cond = geniCodeSubtract (cond, operandFromLit (min));
2923       setOperandType (cond, UCHARTYPE);
2924     }
2925
2926   /* now create the jumptable */
2927   ic = newiCode (JUMPTABLE, NULL, NULL);
2928   IC_JTCOND (ic) = cond;
2929   IC_JTLABELS (ic) = labels;
2930   ADDTOCHAIN (ic);
2931   return 1;
2932 }
2933
2934 /*-----------------------------------------------------------------*/
2935 /* geniCodeSwitch - changes a switch to a if statement             */
2936 /*-----------------------------------------------------------------*/
2937 void 
2938 geniCodeSwitch (ast * tree,int lvl)
2939 {
2940   iCode *ic;
2941   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
2942   value *caseVals = tree->values.switchVals.swVals;
2943   symbol *trueLabel, *falseLabel;
2944
2945   /* if we can make this a jump table */
2946   if (geniCodeJumpTable (cond, caseVals, tree))
2947     goto jumpTable;             /* no need for the comparison */
2948
2949   /* for the cases defined do */
2950   while (caseVals)
2951     {
2952
2953       operand *compare = geniCodeLogic (cond,
2954                                         operandFromValue (caseVals),
2955                                         EQ_OP);
2956
2957       sprintf (buffer, "_case_%d_%d",
2958                tree->values.switchVals.swNum,
2959                (int) floatFromVal (caseVals));
2960       trueLabel = newiTempLabel (buffer);
2961
2962       ic = newiCodeCondition (compare, trueLabel, NULL);
2963       ADDTOCHAIN (ic);
2964       caseVals = caseVals->next;
2965     }
2966
2967
2968
2969   /* if default is present then goto break else break */
2970   if (tree->values.switchVals.swDefault)
2971     sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2972   else
2973     sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2974
2975   falseLabel = newiTempLabel (buffer);
2976   geniCodeGoto (falseLabel);
2977
2978 jumpTable:
2979   ast2iCode (tree->right,lvl+1);
2980 }
2981
2982 /*-----------------------------------------------------------------*/
2983 /* geniCodeInline - intermediate code for inline assembler         */
2984 /*-----------------------------------------------------------------*/
2985 static void 
2986 geniCodeInline (ast * tree)
2987 {
2988   iCode *ic;
2989
2990   ic = newiCode (INLINEASM, NULL, NULL);
2991   IC_INLINE (ic) = tree->values.inlineasm;
2992   ADDTOCHAIN (ic);
2993 }
2994
2995 /*-----------------------------------------------------------------*/
2996 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
2997 /* particular case. Ie : assigning or dereferencing array or ptr   */
2998 /*-----------------------------------------------------------------*/
2999 set * lvaluereqSet = NULL;
3000 typedef struct lvalItem
3001   {
3002     int req;
3003     int lvl;
3004   }
3005 lvalItem;
3006
3007 /*-----------------------------------------------------------------*/
3008 /* addLvaluereq - add a flag for lvalreq for current ast level     */
3009 /*-----------------------------------------------------------------*/
3010 void addLvaluereq(int lvl)
3011 {
3012   lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3013   lpItem->req=1;
3014   lpItem->lvl=lvl;
3015   addSetHead(&lvaluereqSet,lpItem);
3016
3017 }
3018 /*-----------------------------------------------------------------*/
3019 /* delLvaluereq - del a flag for lvalreq for current ast level     */
3020 /*-----------------------------------------------------------------*/
3021 void delLvaluereq()
3022 {
3023   lvalItem * lpItem;
3024   lpItem = getSet(&lvaluereqSet);
3025   if(lpItem) free(lpItem);
3026 }
3027 /*-----------------------------------------------------------------*/
3028 /* clearLvaluereq - clear lvalreq flag                             */
3029 /*-----------------------------------------------------------------*/
3030 void clearLvaluereq()
3031 {
3032   lvalItem * lpItem;
3033   lpItem = peekSet(lvaluereqSet);
3034   if(lpItem) lpItem->req = 0;
3035 }
3036 /*-----------------------------------------------------------------*/
3037 /* getLvaluereq - get the last lvalreq level                       */
3038 /*-----------------------------------------------------------------*/
3039 int getLvaluereqLvl()
3040 {
3041   lvalItem * lpItem;
3042   lpItem = peekSet(lvaluereqSet);
3043   if(lpItem) return lpItem->lvl;
3044   return 0;
3045 }
3046 /*-----------------------------------------------------------------*/
3047 /* isLvaluereq - is lvalreq valid for this level ?                 */
3048 /*-----------------------------------------------------------------*/
3049 int isLvaluereq(int lvl)
3050 {
3051   lvalItem * lpItem;
3052   lpItem = peekSet(lvaluereqSet);
3053   if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3054   return 0;
3055 }
3056
3057 /*-----------------------------------------------------------------*/
3058 /* ast2iCode - creates an icodeList from an ast                    */
3059 /*-----------------------------------------------------------------*/
3060 operand *
3061 ast2iCode (ast * tree,int lvl)
3062 {
3063   operand *left = NULL;
3064   operand *right = NULL;
3065   if (!tree)
3066     return NULL;
3067   /* set the global variables for filename & line number */
3068   if (tree->filename)
3069     filename = tree->filename;
3070   if (tree->lineno)
3071     lineno = tree->lineno;
3072   if (tree->block)
3073     block = tree->block;
3074   if (tree->level)
3075     scopeLevel = tree->level;
3076
3077   if (tree->type == EX_VALUE)
3078     return operandFromValue (tree->opval.val);
3079
3080   if (tree->type == EX_LINK)
3081     return operandFromLink (tree->opval.lnk);
3082
3083   /* if we find a nullop */
3084   if (tree->type == EX_OP &&
3085      (tree->opval.op == NULLOP ||
3086      tree->opval.op == BLOCK))
3087     {
3088       ast2iCode (tree->left,lvl+1);
3089       ast2iCode (tree->right,lvl+1);
3090       return NULL;
3091     }
3092
3093   /* special cases for not evaluating */
3094   if (tree->opval.op != ':' &&
3095       tree->opval.op != '?' &&
3096       tree->opval.op != CALL &&
3097       tree->opval.op != IFX &&
3098       tree->opval.op != LABEL &&
3099       tree->opval.op != GOTO &&
3100       tree->opval.op != SWITCH &&
3101       tree->opval.op != FUNCTION &&
3102       tree->opval.op != INLINEASM)
3103     {
3104
3105         if (IS_ASSIGN_OP (tree->opval.op) ||
3106            IS_DEREF_OP (tree) ||
3107            (tree->opval.op == '&' && !tree->right) ||
3108            tree->opval.op == PTR_OP)
3109           {
3110             addLvaluereq(lvl);
3111             if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3112                (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3113               clearLvaluereq();
3114
3115             left = operandFromAst (tree->left,lvl);
3116             delLvaluereq();
3117             if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3118               left = geniCodeRValue (left, TRUE);
3119           }
3120         else
3121           {
3122             left = operandFromAst (tree->left,lvl);
3123           }
3124         if (tree->opval.op == INC_OP ||
3125             tree->opval.op == DEC_OP)
3126           {
3127             addLvaluereq(lvl);
3128             right = operandFromAst (tree->right,lvl);
3129             delLvaluereq();
3130           }
3131         else
3132           {
3133             right = operandFromAst (tree->right,lvl);
3134           }
3135       }
3136
3137   /* now depending on the type of operand */
3138   /* this will be a biggy                 */
3139   switch (tree->opval.op)
3140     {
3141
3142     case '[':                   /* array operation */
3143       {
3144         sym_link *ltype = operandType (left);
3145         left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3146         right = geniCodeRValue (right, TRUE);
3147       }
3148
3149       return geniCodeArray (left, right,lvl);
3150
3151     case '.':                   /* structure dereference */
3152       if (IS_PTR (operandType (left)))
3153         left = geniCodeRValue (left, TRUE);
3154       else
3155         left = geniCodeRValue (left, FALSE);
3156
3157       return geniCodeStruct (left, right, tree->lvalue);
3158
3159     case PTR_OP:                /* structure pointer dereference */
3160       {
3161         sym_link *pType;
3162         pType = operandType (left);
3163         left = geniCodeRValue (left, TRUE);
3164
3165         setOClass (pType, getSpec (operandType (left)));
3166       }
3167
3168       return geniCodeStruct (left, right, tree->lvalue);
3169
3170     case INC_OP:                /* increment operator */
3171       if (left)
3172         return geniCodePostInc (left);
3173       else
3174         return geniCodePreInc (right);
3175
3176     case DEC_OP:                /* decrement operator */
3177       if (left)
3178         return geniCodePostDec (left);
3179       else
3180         return geniCodePreDec (right);
3181
3182     case '&':                   /* bitwise and or address of operator */
3183       if (right)
3184         {                       /* this is a bitwise operator   */
3185           left = geniCodeRValue (left, FALSE);
3186           right = geniCodeRValue (right, FALSE);
3187           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3188         }
3189       else
3190         return geniCodeAddressOf (left);
3191
3192     case '|':                   /* bitwise or & xor */
3193     case '^':
3194       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3195                               geniCodeRValue (right, FALSE),
3196                               tree->opval.op,
3197                               tree->ftype);
3198
3199     case '/':
3200       return geniCodeDivision (geniCodeRValue (left, FALSE),
3201                                geniCodeRValue (right, FALSE));
3202
3203     case '%':
3204       return geniCodeModulus (geniCodeRValue (left, FALSE),
3205                               geniCodeRValue (right, FALSE));
3206     case '*':
3207       if (right)
3208         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3209                                  geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3210       else
3211         return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3212
3213     case '-':
3214       if (right)
3215         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3216                                  geniCodeRValue (right, FALSE));
3217       else
3218         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3219
3220     case '+':
3221       if (right)
3222         return geniCodeAdd (geniCodeRValue (left, FALSE),
3223                             geniCodeRValue (right, FALSE),lvl);
3224       else
3225         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3226
3227     case LEFT_OP:
3228       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3229                                 geniCodeRValue (right, FALSE));
3230
3231     case RIGHT_OP:
3232       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3233                                  geniCodeRValue (right, FALSE));
3234     case CAST:
3235       return geniCodeCast (operandType (left),
3236                            geniCodeRValue (right, FALSE), FALSE);
3237
3238     case '~':
3239     case '!':
3240     case RRC:
3241     case RLC:
3242       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3243
3244     case GETHBIT:
3245       {
3246         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3247         setOperandType (op, UCHARTYPE);
3248         return op;
3249       }
3250     case '>':
3251     case '<':
3252     case LE_OP:
3253     case GE_OP:
3254     case EQ_OP:
3255     case NE_OP:
3256     case AND_OP:
3257     case OR_OP:
3258       return geniCodeLogic (geniCodeRValue (left, FALSE),
3259                             geniCodeRValue (right, FALSE),
3260                             tree->opval.op);
3261     case '?':
3262       return geniCodeConditional (tree,lvl);
3263
3264     case SIZEOF:
3265       return operandFromLit (getSize (tree->right->ftype));
3266
3267     case '=':
3268       {
3269         sym_link *rtype = operandType (right);
3270         sym_link *ltype = operandType (left);
3271         if (IS_PTR (rtype) && IS_ITEMP (right)
3272             && right->isaddr && checkType (rtype->next, ltype) == 1)
3273           right = geniCodeRValue (right, TRUE);
3274         else
3275           right = geniCodeRValue (right, FALSE);
3276
3277         geniCodeAssign (left, right, 0);
3278         return right;
3279       }
3280     case MUL_ASSIGN:
3281       return
3282         geniCodeAssign (left,
3283                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3284                                                   FALSE),
3285                                   geniCodeRValue (right, FALSE),FALSE), 0);
3286
3287     case DIV_ASSIGN:
3288       return
3289         geniCodeAssign (left,
3290                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3291                                                   FALSE),
3292                                   geniCodeRValue (right, FALSE)), 0);
3293     case MOD_ASSIGN:
3294       return
3295         geniCodeAssign (left,
3296                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3297                                                   FALSE),
3298                                   geniCodeRValue (right, FALSE)), 0);
3299     case ADD_ASSIGN:
3300       {
3301         sym_link *rtype = operandType (right);
3302         sym_link *ltype = operandType (left);
3303         if (IS_PTR (rtype) && IS_ITEMP (right)
3304             && right->isaddr && checkType (rtype->next, ltype) == 1)
3305           right = geniCodeRValue (right, TRUE);
3306         else
3307           right = geniCodeRValue (right, FALSE);
3308
3309
3310         return geniCodeAssign (left,
3311                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3312                                                   FALSE),
3313                                   right,lvl), 0);
3314       }
3315     case SUB_ASSIGN:
3316       {
3317         sym_link *rtype = operandType (right);
3318         sym_link *ltype = operandType (left);
3319         if (IS_PTR (rtype) && IS_ITEMP (right)
3320             && right->isaddr && checkType (rtype->next, ltype) == 1)
3321           {
3322             right = geniCodeRValue (right, TRUE);
3323           }
3324         else
3325           {
3326             right = geniCodeRValue (right, FALSE);
3327           }
3328         return
3329           geniCodeAssign (left,
3330                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3331                                                   FALSE),
3332                                   right), 0);
3333       }
3334     case LEFT_ASSIGN:
3335       return
3336         geniCodeAssign (left,
3337                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3338                                                    ,FALSE),
3339                                    geniCodeRValue (right, FALSE)), 0);
3340     case RIGHT_ASSIGN:
3341       return
3342         geniCodeAssign (left,
3343                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3344                                                    ,FALSE),
3345                                    geniCodeRValue (right, FALSE)), 0);
3346     case AND_ASSIGN:
3347       return
3348         geniCodeAssign (left,
3349                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3350                                                   FALSE),
3351                                   geniCodeRValue (right, FALSE),
3352                                   BITWISEAND,
3353                                   operandType (left)), 0);
3354     case XOR_ASSIGN:
3355       return
3356         geniCodeAssign (left,
3357                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3358                                                   FALSE),
3359                                   geniCodeRValue (right, FALSE),
3360                                   '^',
3361                                   operandType (left)), 0);
3362     case OR_ASSIGN:
3363       return
3364         geniCodeAssign (left,
3365                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3366                                                    ,FALSE),
3367                                    geniCodeRValue (right, FALSE),
3368                                    '|',
3369                                    operandType (left)), 0);
3370     case ',':
3371       return geniCodeRValue (right, FALSE);
3372
3373     case CALL:
3374       return geniCodeCall (ast2iCode (tree->left,lvl+1),
3375                            tree->right,lvl);
3376     case LABEL:
3377       geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3378       return ast2iCode (tree->right,lvl+1);
3379
3380     case GOTO:
3381       geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3382       return ast2iCode (tree->right,lvl+1);
3383
3384     case FUNCTION:
3385       geniCodeFunctionBody (tree,lvl);
3386       return NULL;
3387
3388     case RETURN:
3389       geniCodeReturn (right);
3390       return NULL;
3391
3392     case IFX:
3393       geniCodeIfx (tree,lvl);
3394       return NULL;
3395
3396     case SWITCH:
3397       geniCodeSwitch (tree,lvl);
3398       return NULL;
3399
3400     case INLINEASM:
3401       geniCodeInline (tree);
3402       return NULL;
3403     }
3404
3405   return NULL;
3406 }
3407
3408 /*-----------------------------------------------------------------*/
3409 /* reverseICChain - gets from the list and creates a linkedlist    */
3410 /*-----------------------------------------------------------------*/
3411 iCode *
3412 reverseiCChain ()
3413 {
3414   iCode *loop = NULL;
3415   iCode *prev = NULL;
3416
3417   while ((loop = getSet (&iCodeChain)))
3418     {
3419       loop->next = prev;
3420       if (prev)
3421         prev->prev = loop;
3422       prev = loop;
3423     }
3424
3425   return prev;
3426 }
3427
3428
3429 /*-----------------------------------------------------------------*/
3430 /* iCodeFromAst - given an ast will convert it to iCode            */
3431 /*-----------------------------------------------------------------*/
3432 iCode *
3433 iCodeFromAst (ast * tree)
3434 {
3435   returnLabel = newiTempLabel ("_return");
3436   entryLabel = newiTempLabel ("_entry");
3437   ast2iCode (tree,0);
3438   return reverseiCChain ();
3439 }