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