everything * 1 = everything
[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   if (!options.ANSIint)
1410     {
1411       /* "Classic" SDCC behavior. */
1412       sym_link *ctype;
1413       sym_link *rtype = operandType (*op2);
1414       sym_link *ltype = operandType (*op1);
1415
1416       ctype = computeType (ltype, rtype);
1417       *op1 = geniCodeCast (ctype, *op1, TRUE);
1418       *op2 = geniCodeCast (ctype, *op2, TRUE);
1419
1420       return ctype;
1421     }
1422
1423   *op1 = usualUnaryConversions (*op1);
1424   *op2 = usualUnaryConversions (*op2);
1425
1426   /* Try to make the two operands of the same type, following
1427    * the "usual binary conversions" promotion rules.
1428    *
1429    * NB: floating point types are not yet properly handled; we
1430    * follow the "classic" behavior.
1431    */
1432
1433   if (IS_FLOAT (operandType (*op1)) || IS_FLOAT (operandType (*op2)))
1434     {
1435       return newFloatLink ();
1436     }
1437
1438   if (!IS_INTEGRAL (operandType (*op1)) || !IS_INTEGRAL (operandType (*op2)))
1439     {
1440       /* if either is not an integer type, we're done. */
1441       return copyLinkChain (operandType (*op1));        /* Punt! we should never get here. */
1442     }
1443
1444   /* If either is an unsigned long, make sure both are. */
1445   if (SPEC_USIGN (operandType (*op1)) && IS_LONG (operandType (*op1)))
1446     {
1447       if (!SPEC_USIGN (operandType (*op2)) || !IS_LONG (operandType (*op2)))
1448         {
1449           *op2 = geniCodeCast (ULONGTYPE, *op2, TRUE);
1450         }
1451       return copyLinkChain (operandType (*op1));
1452     }
1453
1454   if (SPEC_USIGN (operandType (*op2)) && IS_LONG (operandType (*op2)))
1455     {
1456       if (!SPEC_USIGN (operandType (*op1)) || !IS_LONG (operandType (*op1)))
1457         {
1458           *op1 = geniCodeCast (ULONGTYPE, *op1, TRUE);
1459         }
1460       return copyLinkChain (operandType (*op2));
1461     }
1462
1463   /* Next, if one is long and the other is int (signed or un),
1464    * cast both to long.
1465    *
1466    * Note that because in our environment a long can hold all
1467    * the values of an unsigned int, the "long/unsigned int" pair
1468    * in the ANSI conversion table is unnecessary; this test
1469    * handles that case implicitly.
1470    */
1471   if (IS_LONG (operandType (*op1)))
1472     {
1473       /* NB: because of the unary conversions, op2 cannot
1474        * be smaller than int. Therefore, if it is not
1475        * long, it is a regular int.
1476        */
1477       if (!IS_LONG (operandType (*op2)))
1478         {
1479           *op2 = geniCodeCast (LONGTYPE, *op2, TRUE);
1480         }
1481       return copyLinkChain (operandType (*op1));
1482     }
1483
1484   if (IS_LONG (operandType (*op2)))
1485     {
1486       /* NB: because of the unary conversions, op2 cannot
1487        * be smaller than int. Therefore, if it is not
1488        * long, it is a regular int.
1489        */
1490       if (!IS_LONG (operandType (*op1)))
1491         {
1492           *op1 = geniCodeCast (LONGTYPE, *op1, TRUE);
1493         }
1494       return copyLinkChain (operandType (*op2));
1495     }
1496
1497   /* All right, neither is long; they must both be integers.
1498
1499    * Only remaining issue is signed vs. unsigned; if one is unsigned
1500    * and the other isn't, convert both to unsigned.
1501    */
1502   if (SPEC_USIGN (operandType (*op1)))
1503     {
1504       if (!SPEC_USIGN (operandType (*op2)))
1505         {
1506           *op2 = geniCodeCast (UINTTYPE, *op2, TRUE);
1507         }
1508       return copyLinkChain (operandType (*op1));
1509     }
1510
1511   if (SPEC_USIGN (operandType (*op2)))
1512     {
1513       if (!SPEC_USIGN (operandType (*op1)))
1514         {
1515           *op1 = geniCodeCast (UINTTYPE, *op1, TRUE);
1516         }
1517       return copyLinkChain (operandType (*op2));
1518     }
1519
1520   /* Done! */
1521   return copyLinkChain (operandType (*op1));
1522 }
1523
1524
1525 /*-----------------------------------------------------------------*/
1526 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1527 /*                          at address                             */
1528 /*-----------------------------------------------------------------*/
1529 operand *
1530 geniCodeRValue (operand * op, bool force)
1531 {
1532   iCode *ic;
1533   sym_link *type = operandType (op);
1534   sym_link *etype = getSpec (type);
1535
1536   /* if this is an array & already */
1537   /* an address then return this   */
1538   if (IS_AGGREGATE (type) ||
1539       (IS_PTR (type) && !force && !op->isaddr))
1540     return operandFromOperand (op);
1541
1542   /* if this is not an address then must be */
1543   /* rvalue already so return this one      */
1544   if (!op->isaddr)
1545     return op;
1546
1547   /* if this is not a temp symbol then */
1548   if (!IS_ITEMP (op) &&
1549       !force &&
1550       !IN_FARSPACE (SPEC_OCLS (etype)))
1551     {
1552       op = operandFromOperand (op);
1553       op->isaddr = 0;
1554       return op;
1555     }
1556
1557   if (IS_SPEC (type) &&
1558       IS_TRUE_SYMOP (op) &&
1559       (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
1560     {
1561       op = operandFromOperand (op);
1562       op->isaddr = 0;
1563       return op;
1564     }
1565
1566   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1567   if (IS_PTR (type) && op->isaddr && force)
1568     type = type->next;
1569
1570   type = copyLinkChain (type);
1571
1572   IC_RESULT (ic) = newiTempOperand (type, 1);
1573   IC_RESULT (ic)->isaddr = 0;
1574
1575 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1576
1577   /* if the right is a symbol */
1578   if (op->type == SYMBOL)
1579     IC_RESULT (ic)->operand.symOperand->args =
1580       op->operand.symOperand->args;
1581   ADDTOCHAIN (ic);
1582
1583   return IC_RESULT (ic);
1584 }
1585
1586 /*-----------------------------------------------------------------*/
1587 /* geniCodeCast - changes the value from one type to another       */
1588 /*-----------------------------------------------------------------*/
1589 operand *
1590 geniCodeCast (sym_link * type, operand * op, bool implicit)
1591 {
1592   iCode *ic;
1593   sym_link *optype;
1594   sym_link *opetype = getSpec (optype = operandType (op));
1595   sym_link *restype;
1596
1597   /* one of them has size zero then error */
1598   if (IS_VOID (optype))
1599     {
1600       werror (E_CAST_ZERO);
1601       return op;
1602     }
1603
1604   /* if the operand is already the desired type then do nothing */
1605   if (checkType (type, optype) == 1)
1606     return op;
1607
1608   /* if this is a literal then just change the type & return */
1609   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1610     return operandFromValue (valCastLiteral (type,
1611                                              operandLitValue (op)));
1612
1613   /* if casting to some pointer type &&
1614      the destination is not a generic pointer
1615      then give a warning : (only for implicit casts) */
1616   if (IS_PTR (optype) && implicit &&
1617       (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1618       !IS_GENPTR (type))
1619     {
1620       werror (E_INCOMPAT_CAST);
1621       werror (E_CONTINUE, "from type '");
1622       printTypeChain (optype, stderr);
1623       fprintf (stderr, "' to type '");
1624       printTypeChain (type, stderr);
1625       fprintf (stderr, "'\n");
1626     }
1627
1628   /* if they are the same size create an assignment */
1629   if (getSize (type) == getSize (optype) &&
1630       !IS_BITFIELD (type) &&
1631       !IS_FLOAT (type) &&
1632       !IS_FLOAT (optype) &&
1633       ((IS_SPEC (type) && IS_SPEC (optype)) ||
1634        (!IS_SPEC (type) && !IS_SPEC (optype))))
1635     {
1636
1637       ic = newiCode ('=', NULL, op);
1638       IC_RESULT (ic) = newiTempOperand (type, 0);
1639       SPIL_LOC (IC_RESULT (ic)) =
1640         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1641       IC_RESULT (ic)->isaddr = 0;
1642     }
1643   else
1644     {
1645       ic = newiCode (CAST, operandFromLink (type),
1646                      geniCodeRValue (op, FALSE));
1647
1648       IC_RESULT (ic) = newiTempOperand (type, 0);
1649     }
1650
1651   /* preserve the storage class & output class */
1652   /* of the original variable                  */
1653   restype = getSpec (operandType (IC_RESULT (ic)));
1654   SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1655   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1656
1657   ADDTOCHAIN (ic);
1658   return IC_RESULT (ic);
1659 }
1660
1661 /*-----------------------------------------------------------------*/
1662 /* geniCodeLabel - will create a Label                             */
1663 /*-----------------------------------------------------------------*/
1664 void 
1665 geniCodeLabel (symbol * label)
1666 {
1667   iCode *ic;
1668
1669   ic = newiCodeLabelGoto (LABEL, label);
1670   ADDTOCHAIN (ic);
1671 }
1672
1673 /*-----------------------------------------------------------------*/
1674 /* geniCodeGoto  - will create a Goto                              */
1675 /*-----------------------------------------------------------------*/
1676 void 
1677 geniCodeGoto (symbol * label)
1678 {
1679   iCode *ic;
1680
1681   ic = newiCodeLabelGoto (GOTO, label);
1682   ADDTOCHAIN (ic);
1683 }
1684
1685 /*-----------------------------------------------------------------*/
1686 /* geniCodeMultiply - gen intermediate code for multiplication     */
1687 /*-----------------------------------------------------------------*/
1688 operand *
1689 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1690 {
1691   iCode *ic;
1692   int p2 = 0;
1693   int saveOption=0;
1694   sym_link *resType;
1695   LRTYPE;
1696
1697   /* if they are both literal then we know the result */
1698   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1699     return operandFromValue (valMult (left->operand.valOperand,
1700                                       right->operand.valOperand));
1701
1702   if (resultIsInt)
1703     {
1704       saveOption = options.ANSIint;
1705       options.ANSIint = 0;
1706     }
1707   resType = usualBinaryConversions (&left, &right);
1708   if (resultIsInt)
1709     {
1710       options.ANSIint = saveOption;
1711       SPEC_NOUN(getSpec(resType))=V_INT;
1712       SPEC_SHORT(getSpec(resType))=0;
1713     }
1714
1715   /* if the right is a literal & power of 2 */
1716   /* then make it a left shift              */
1717   /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
1718   /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
1719   if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
1720       !((resultIsInt) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
1721    (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
1722     {
1723       if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1724         {
1725           /* LEFT_OP need same size for left and result, */
1726           left = geniCodeCast (resType, left, TRUE);
1727           ltype = operandType (left);
1728         }
1729       ic = newiCode (LEFT_OP, left, operandFromLit (p2));       /* left shift */
1730     }
1731   else
1732     {
1733       ic = newiCode ('*', left, right);         /* normal multiplication */
1734       /* if the size left or right > 1 then support routine */
1735       if (getSize (ltype) > 1 || getSize (rtype) > 1)
1736         ic->supportRtn = 1;
1737
1738     }
1739   IC_RESULT (ic) = newiTempOperand (resType, 1);
1740
1741   ADDTOCHAIN (ic);
1742   return IC_RESULT (ic);
1743 }
1744
1745 /*-----------------------------------------------------------------*/
1746 /* geniCodeDivision - gen intermediate code for division           */
1747 /*-----------------------------------------------------------------*/
1748 operand *
1749 geniCodeDivision (operand * left, operand * right)
1750 {
1751   iCode *ic;
1752   int p2 = 0;
1753   sym_link *resType;
1754   sym_link *rtype = operandType (right);
1755   sym_link *retype = getSpec (rtype);
1756   sym_link *ltype = operandType (left);
1757   sym_link *letype = getSpec (ltype);
1758
1759   resType = usualBinaryConversions (&left, &right);
1760
1761   /* if the right is a literal & power of 2 */
1762   /* then make it a right shift             */
1763   if (IS_LITERAL (retype) &&
1764       !IS_FLOAT (letype) &&
1765       (p2 = powof2 ((unsigned long)
1766                     floatFromVal (right->operand.valOperand))))
1767     ic = newiCode (RIGHT_OP, left, operandFromLit (p2));        /* right shift */
1768   else
1769     {
1770       ic = newiCode ('/', left, right);         /* normal division */
1771       /* if the size left or right > 1 then support routine */
1772       if (getSize (ltype) > 1 || getSize (rtype) > 1)
1773         ic->supportRtn = 1;
1774     }
1775   IC_RESULT (ic) = newiTempOperand (resType, 0);
1776
1777   ADDTOCHAIN (ic);
1778   return IC_RESULT (ic);
1779 }
1780 /*-----------------------------------------------------------------*/
1781 /* geniCodeModulus  - gen intermediate code for modulus            */
1782 /*-----------------------------------------------------------------*/
1783 operand *
1784 geniCodeModulus (operand * left, operand * right)
1785 {
1786   iCode *ic;
1787   sym_link *resType;
1788   LRTYPE;
1789
1790   /* if they are both literal then we know the result */
1791   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1792     return operandFromValue (valMod (left->operand.valOperand,
1793                                      right->operand.valOperand));
1794
1795   resType = usualBinaryConversions (&left, &right);
1796
1797   /* now they are the same size */
1798   ic = newiCode ('%', left, right);
1799
1800   /* if the size left or right > 1 then support routine */
1801   if (getSize (ltype) > 1 || getSize (rtype) > 1)
1802     ic->supportRtn = 1;
1803   IC_RESULT (ic) = newiTempOperand (resType, 0);
1804
1805   ADDTOCHAIN (ic);
1806   return IC_RESULT (ic);
1807 }
1808
1809 /*-----------------------------------------------------------------*/
1810 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
1811 /*-----------------------------------------------------------------*/
1812 operand *
1813 geniCodePtrPtrSubtract (operand * left, operand * right)
1814 {
1815   iCode *ic;
1816   operand *result;
1817   LRTYPE;
1818
1819   /* if they are both literals then */
1820   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1821     {
1822       result = operandFromValue (valMinus (left->operand.valOperand,
1823                                            right->operand.valOperand));
1824       goto subtractExit;
1825     }
1826
1827   ic = newiCode ('-', left, right);
1828
1829   IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1830   ADDTOCHAIN (ic);
1831
1832 subtractExit:
1833   return geniCodeDivision (result,
1834                            operandFromLit (getSize (ltype->next)));
1835 }
1836
1837 /*-----------------------------------------------------------------*/
1838 /* geniCodeSubtract - generates code for subtraction               */
1839 /*-----------------------------------------------------------------*/
1840 operand *
1841 geniCodeSubtract (operand * left, operand * right)
1842 {
1843   iCode *ic;
1844   int isarray = 0;
1845   sym_link *resType;
1846   LRTYPE;
1847
1848   /* if they both pointers then */
1849   if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1850       (IS_PTR (rtype) || IS_ARRAY (rtype)))
1851     return geniCodePtrPtrSubtract (left, right);
1852
1853   /* if they are both literal then we know the result */
1854   if (IS_LITERAL (letype) && IS_LITERAL (retype)
1855       && left->isLiteral && right->isLiteral)
1856     return operandFromValue (valMinus (left->operand.valOperand,
1857                                        right->operand.valOperand));
1858
1859   /* if left is an array or pointer */
1860   if (IS_PTR (ltype) || IS_ARRAY (ltype))
1861     {
1862       isarray = left->isaddr;
1863       right = geniCodeMultiply (right,
1864                                 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1865       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1866     }
1867   else
1868     {                           /* make them the same size */
1869       resType = usualBinaryConversions (&left, &right);
1870     }
1871
1872   ic = newiCode ('-', left, right);
1873
1874   IC_RESULT (ic) = newiTempOperand (resType, 1);
1875   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1876
1877   /* if left or right is a float */
1878   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1879     ic->supportRtn = 1;
1880
1881   ADDTOCHAIN (ic);
1882   return IC_RESULT (ic);
1883 }
1884
1885 /*-----------------------------------------------------------------*/
1886 /* geniCodeAdd - generates iCode for addition                      */
1887 /*-----------------------------------------------------------------*/
1888 operand *
1889 geniCodeAdd (operand * left, operand * right)
1890 {
1891   iCode *ic;
1892   sym_link *resType;
1893   operand *size;
1894   int isarray = 0;
1895   LRTYPE;
1896
1897   /* if left is an array then array access */
1898   if (IS_ARRAY (ltype))
1899     return geniCodeArray (left, right);
1900
1901   /* if the right side is LITERAL zero */
1902   /* return the left side              */
1903   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1904     return left;
1905
1906   /* if left is literal zero return right */
1907   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1908     return right;
1909
1910   /* if left is an array or pointer then size */
1911   if (IS_PTR (ltype))
1912     {
1913       isarray = left->isaddr;
1914       // there is no need to multiply with 1
1915       if (getSize(ltype->next)!=1) {
1916         size  = operandFromLit (getSize (ltype->next));
1917         right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1918       }
1919       resType = copyLinkChain (ltype);
1920     }
1921   else
1922     {                           /* make them the same size */
1923       resType = usualBinaryConversions (&left, &right);
1924     }
1925
1926   /* if they are both literals then we know */
1927   if (IS_LITERAL (letype) && IS_LITERAL (retype)
1928       && left->isLiteral && right->isLiteral)
1929     return operandFromValue (valPlus (valFromType (letype),
1930                                       valFromType (retype)));
1931
1932   ic = newiCode ('+', left, right);
1933
1934   IC_RESULT (ic) = newiTempOperand (resType, 1);
1935   IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1936
1937   /* if left or right is a float then support
1938      routine */
1939   if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1940     ic->supportRtn = 1;
1941
1942   ADDTOCHAIN (ic);
1943
1944   return IC_RESULT (ic);
1945
1946 }
1947
1948 /*-----------------------------------------------------------------*/
1949 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
1950 /*-----------------------------------------------------------------*/
1951 sym_link *
1952 aggrToPtr (sym_link * type, bool force)
1953 {
1954   sym_link *etype;
1955   sym_link *ptype;
1956
1957
1958   if (IS_PTR (type) && !force)
1959     return type;
1960
1961   etype = getSpec (type);
1962   ptype = newLink ();
1963
1964   ptype->next = type;
1965   /* if the output class is generic */
1966   if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1967     DCL_PTR_CONST (ptype) = port->mem.code_ro;
1968
1969   /* if the variable was declared a constant */
1970   /* then the pointer points to a constant */
1971   if (IS_CONSTANT (etype))
1972     DCL_PTR_CONST (ptype) = 1;
1973
1974   /* the variable was volatile then pointer to volatile */
1975   if (IS_VOLATILE (etype))
1976     DCL_PTR_VOLATILE (ptype) = 1;
1977   return ptype;
1978 }
1979
1980 /*-----------------------------------------------------------------*/
1981 /* geniCodeArray2Ptr - array to pointer                            */
1982 /*-----------------------------------------------------------------*/
1983 operand *
1984 geniCodeArray2Ptr (operand * op)
1985 {
1986   sym_link *optype = operandType (op);
1987   sym_link *opetype = getSpec (optype);
1988
1989   /* set the pointer depending on the storage class */
1990   if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1991     DCL_PTR_CONST (optype) = port->mem.code_ro;
1992
1993
1994   /* if the variable was declared a constant */
1995   /* then the pointer points to a constant */
1996   if (IS_CONSTANT (opetype))
1997     DCL_PTR_CONST (optype) = 1;
1998
1999   /* the variable was volatile then pointer to volatile */
2000   if (IS_VOLATILE (opetype))
2001     DCL_PTR_VOLATILE (optype) = 1;
2002   op->isaddr = 0;
2003   return op;
2004 }
2005
2006
2007 /*-----------------------------------------------------------------*/
2008 /* geniCodeArray - array access                                    */
2009 /*-----------------------------------------------------------------*/
2010 operand *
2011 geniCodeArray (operand * left, operand * right)
2012 {
2013   iCode *ic;
2014   sym_link *ltype = operandType (left);
2015
2016   if (IS_PTR (ltype))
2017     {
2018       if (IS_PTR (ltype->next) && left->isaddr)
2019         {
2020           left = geniCodeRValue (left, FALSE);
2021         }
2022       return geniCodeDerefPtr (geniCodeAdd (left, right));
2023     }
2024
2025   right = geniCodeMultiply (right,
2026                             operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2027
2028   /* we can check for limits here */
2029   if (isOperandLiteral (right) &&
2030       IS_ARRAY (ltype) &&
2031       DCL_ELEM (ltype) &&
2032       (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2033     {
2034       werror (E_ARRAY_BOUND);
2035       right = operandFromLit (0);
2036     }
2037
2038   ic = newiCode ('+', left, right);
2039
2040   IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2041                                       !IS_AGGREGATE (ltype->next) &&
2042                                       !IS_PTR (ltype->next))
2043                                      ? ltype : ltype->next), 0);
2044
2045   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2046   ADDTOCHAIN (ic);
2047   return IC_RESULT (ic);
2048 }
2049
2050 /*-----------------------------------------------------------------*/
2051 /* geniCodeStruct - generates intermediate code for structres      */
2052 /*-----------------------------------------------------------------*/
2053 operand *
2054 geniCodeStruct (operand * left, operand * right, bool islval)
2055 {
2056   iCode *ic;
2057   sym_link *type = operandType (left);
2058   sym_link *etype = getSpec (type);
2059   sym_link *retype;
2060   symbol *element = getStructElement (SPEC_STRUCT (etype),
2061                                       right->operand.symOperand);
2062
2063   /* add the offset */
2064   ic = newiCode ('+', left, operandFromLit (element->offset));
2065
2066   IC_RESULT (ic) = newiTempOperand (element->type, 0);
2067
2068   /* preserve the storage & output class of the struct */
2069   /* as well as the volatile attribute */
2070   retype = getSpec (operandType (IC_RESULT (ic)));
2071   SPEC_SCLS (retype) = SPEC_SCLS (etype);
2072   SPEC_OCLS (retype) = SPEC_OCLS (etype);
2073   SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2074
2075   if (IS_PTR (element->type))
2076     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2077
2078   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2079
2080
2081   ADDTOCHAIN (ic);
2082   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2083 }
2084
2085 /*-----------------------------------------------------------------*/
2086 /* geniCodePostInc - generate int code for Post increment          */
2087 /*-----------------------------------------------------------------*/
2088 operand *
2089 geniCodePostInc (operand * op)
2090 {
2091   iCode *ic;
2092   operand *rOp;
2093   sym_link *optype = operandType (op);
2094   operand *result;
2095   operand *rv = (IS_ITEMP (op) ?
2096                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2097                  op);
2098   sym_link *rvtype = operandType (rv);
2099   int size = 0;
2100
2101   /* if this is not an address we have trouble */
2102   if (!op->isaddr)
2103     {
2104       werror (E_LVALUE_REQUIRED, "++");
2105       return op;
2106     }
2107
2108   rOp = newiTempOperand (rvtype, 0);
2109   rOp->noSpilLoc = 1;
2110
2111   if (IS_ITEMP (rv))
2112     rv->noSpilLoc = 1;
2113
2114   geniCodeAssign (rOp, rv, 0);
2115
2116   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2117   if (IS_FLOAT (rvtype))
2118     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2119   else
2120     ic = newiCode ('+', rv, operandFromLit (size));
2121
2122   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2123   ADDTOCHAIN (ic);
2124
2125   geniCodeAssign (op, result, 0);
2126
2127   return rOp;
2128
2129 }
2130
2131 /*-----------------------------------------------------------------*/
2132 /* geniCodePreInc - generate code for preIncrement                 */
2133 /*-----------------------------------------------------------------*/
2134 operand *
2135 geniCodePreInc (operand * op)
2136 {
2137   iCode *ic;
2138   sym_link *optype = operandType (op);
2139   operand *rop = (IS_ITEMP (op) ?
2140                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2141                   op);
2142   sym_link *roptype = operandType (rop);
2143   operand *result;
2144   int size = 0;
2145
2146   if (!op->isaddr)
2147     {
2148       werror (E_LVALUE_REQUIRED, "++");
2149       return op;
2150     }
2151
2152
2153   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2154   if (IS_FLOAT (roptype))
2155     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2156   else
2157     ic = newiCode ('+', rop, operandFromLit (size));
2158   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2159   ADDTOCHAIN (ic);
2160
2161
2162   return geniCodeAssign (op, result, 0);
2163 }
2164
2165 /*-----------------------------------------------------------------*/
2166 /* geniCodePostDec - generates code for Post decrement             */
2167 /*-----------------------------------------------------------------*/
2168 operand *
2169 geniCodePostDec (operand * op)
2170 {
2171   iCode *ic;
2172   operand *rOp;
2173   sym_link *optype = operandType (op);
2174   operand *result;
2175   operand *rv = (IS_ITEMP (op) ?
2176                  geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2177                  op);
2178   sym_link *rvtype = operandType (rv);
2179   int size = 0;
2180
2181   /* if this is not an address we have trouble */
2182   if (!op->isaddr)
2183     {
2184       werror (E_LVALUE_REQUIRED, "++");
2185       return op;
2186     }
2187
2188   rOp = newiTempOperand (rvtype, 0);
2189   rOp->noSpilLoc = 1;
2190
2191   if (IS_ITEMP (rv))
2192     rv->noSpilLoc = 1;
2193
2194   geniCodeAssign (rOp, rv, 0);
2195
2196   size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2197   if (IS_FLOAT (rvtype))
2198     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2199   else
2200     ic = newiCode ('-', rv, operandFromLit (size));
2201
2202   IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2203   ADDTOCHAIN (ic);
2204
2205   geniCodeAssign (op, result, 0);
2206
2207   return rOp;
2208
2209 }
2210
2211 /*-----------------------------------------------------------------*/
2212 /* geniCodePreDec - generate code for pre  decrement               */
2213 /*-----------------------------------------------------------------*/
2214 operand *
2215 geniCodePreDec (operand * op)
2216 {
2217   iCode *ic;
2218   sym_link *optype = operandType (op);
2219   operand *rop = (IS_ITEMP (op) ?
2220                   geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2221                   op);
2222   sym_link *roptype = operandType (rop);
2223   operand *result;
2224   int size = 0;
2225
2226   if (!op->isaddr)
2227     {
2228       werror (E_LVALUE_REQUIRED, "++");
2229       return op;
2230     }
2231
2232
2233   size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2234   if (IS_FLOAT (roptype))
2235     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2236   else
2237     ic = newiCode ('-', rop, operandFromLit (size));
2238   IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2239   ADDTOCHAIN (ic);
2240
2241
2242   return geniCodeAssign (op, result, 0);
2243 }
2244
2245
2246 /*-----------------------------------------------------------------*/
2247 /* geniCodeBitwise - gen int code for bitWise  operators           */
2248 /*-----------------------------------------------------------------*/
2249 operand *
2250 geniCodeBitwise (operand * left, operand * right,
2251                  int oper, sym_link * resType)
2252 {
2253   iCode *ic;
2254
2255   left = geniCodeCast (resType, left, TRUE);
2256   right = geniCodeCast (resType, right, TRUE);
2257
2258   ic = newiCode (oper, left, right);
2259   IC_RESULT (ic) = newiTempOperand (resType, 0);
2260
2261   ADDTOCHAIN (ic);
2262   return IC_RESULT (ic);
2263 }
2264
2265 /*-----------------------------------------------------------------*/
2266 /* geniCodeAddressOf - gens icode for '&' address of operator      */
2267 /*-----------------------------------------------------------------*/
2268 operand *
2269 geniCodeAddressOf (operand * op)
2270 {
2271   iCode *ic;
2272   sym_link *p;
2273   sym_link *optype = operandType (op);
2274   sym_link *opetype = getSpec (optype);
2275
2276   /* lvalue check already done in decorateType */
2277   /* this must be a lvalue */
2278 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2279 /*  werror (E_LVALUE_REQUIRED,"&"); */
2280 /*  return op; */
2281 /*     } */
2282
2283   p = newLink ();
2284   p->class = DECLARATOR;
2285
2286   /* set the pointer depending on the storage class */
2287   if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2288     DCL_PTR_CONST (p) = port->mem.code_ro;
2289
2290   /* make sure we preserve the const & volatile */
2291   if (IS_CONSTANT (opetype))
2292     DCL_PTR_CONST (p) = 1;
2293
2294   if (IS_VOLATILE (opetype))
2295     DCL_PTR_VOLATILE (p) = 1;
2296
2297   p->next = copyLinkChain (optype);
2298
2299   /* if already a temp */
2300   if (IS_ITEMP (op))
2301     {
2302       setOperandType (op, p);
2303       op->isaddr = 0;
2304       return op;
2305     }
2306
2307   /* other wise make this of the type coming in */
2308   ic = newiCode (ADDRESS_OF, op, NULL);
2309   IC_RESULT (ic) = newiTempOperand (p, 1);
2310   IC_RESULT (ic)->isaddr = 0;
2311   ADDTOCHAIN (ic);
2312   return IC_RESULT (ic);
2313 }
2314 /*-----------------------------------------------------------------*/
2315 /* setOClass - sets the output class depending on the pointer type */
2316 /*-----------------------------------------------------------------*/
2317 void 
2318 setOClass (sym_link * ptr, sym_link * spec)
2319 {
2320   switch (DCL_TYPE (ptr))
2321     {
2322     case POINTER:
2323       SPEC_OCLS (spec) = data;
2324       break;
2325
2326     case GPOINTER:
2327       SPEC_OCLS (spec) = generic;
2328       break;
2329
2330     case FPOINTER:
2331       SPEC_OCLS (spec) = xdata;
2332       break;
2333
2334     case CPOINTER:
2335       SPEC_OCLS (spec) = code;
2336       break;
2337
2338     case IPOINTER:
2339       SPEC_OCLS (spec) = idata;
2340       break;
2341
2342     case PPOINTER:
2343       SPEC_OCLS (spec) = xstack;
2344       break;
2345
2346     case EEPPOINTER:
2347       SPEC_OCLS (spec) = eeprom;
2348       break;
2349
2350     default:
2351       break;
2352
2353     }
2354 }
2355
2356 /*-----------------------------------------------------------------*/
2357 /* geniCodeDerefPtr - dereference pointer with '*'                 */
2358 /*-----------------------------------------------------------------*/
2359 operand *
2360 geniCodeDerefPtr (operand * op)
2361 {
2362   sym_link *rtype, *retype;
2363   sym_link *optype = operandType (op);
2364
2365   /* if this is a pointer then generate the rvalue */
2366   if (IS_PTR (optype))
2367     {
2368       if (IS_TRUE_SYMOP (op))
2369         {
2370           op->isaddr = 1;
2371           op = geniCodeRValue (op, TRUE);
2372         }
2373       else
2374         op = geniCodeRValue (op, TRUE);
2375     }
2376
2377   /* now get rid of the pointer part */
2378   if (lvaluereq && IS_ITEMP (op))
2379     {
2380       retype = getSpec (rtype = copyLinkChain (optype));
2381     }
2382   else
2383     {
2384       retype = getSpec (rtype = copyLinkChain (optype->next));
2385     }
2386
2387   /* if this is a pointer then outputclass needs 2b updated */
2388   if (IS_PTR (optype))
2389     setOClass (optype, retype);
2390
2391   op->isGptr = IS_GENPTR (optype);
2392
2393   /* if the pointer was declared as a constant */
2394   /* then we cannot allow assignment to the derefed */
2395   if (IS_PTR_CONST (optype))
2396     SPEC_CONST (retype) = 1;
2397
2398   op->isaddr = (IS_PTR (rtype) ||
2399                 IS_STRUCT (rtype) ||
2400                 IS_INT (rtype) ||
2401                 IS_CHAR (rtype) ||
2402                 IS_FLOAT (rtype));
2403
2404   if (!lvaluereq)
2405     op = geniCodeRValue (op, TRUE);
2406
2407   setOperandType (op, rtype);
2408
2409   return op;
2410 }
2411
2412 /*-----------------------------------------------------------------*/
2413 /* geniCodeUnaryMinus - does a unary minus of the operand          */
2414 /*-----------------------------------------------------------------*/
2415 operand *
2416 geniCodeUnaryMinus (operand * op)
2417 {
2418   iCode *ic;
2419   sym_link *optype = operandType (op);
2420
2421   if (IS_LITERAL (optype))
2422     return operandFromLit (-floatFromVal (op->operand.valOperand));
2423
2424   ic = newiCode (UNARYMINUS, op, NULL);
2425   IC_RESULT (ic) = newiTempOperand (optype, 0);
2426   ADDTOCHAIN (ic);
2427   return IC_RESULT (ic);
2428 }
2429
2430 /*-----------------------------------------------------------------*/
2431 /* geniCodeLeftShift - gen i code for left shift                   */
2432 /*-----------------------------------------------------------------*/
2433 operand *
2434 geniCodeLeftShift (operand * left, operand * right)
2435 {
2436   iCode *ic;
2437
2438
2439   /* Note that we don't use the usual binary conversions for the
2440    * shift operations, in accordance with our ANSI friends.
2441    */
2442   if (options.ANSIint)
2443     {
2444       right = usualUnaryConversions (right);
2445       left = usualUnaryConversions (left);
2446     }
2447
2448   ic = newiCode (LEFT_OP, left, right);
2449   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2450   ADDTOCHAIN (ic);
2451   return IC_RESULT (ic);
2452 }
2453
2454 /*-----------------------------------------------------------------*/
2455 /* geniCodeRightShift - gen i code for right shift                 */
2456 /*-----------------------------------------------------------------*/
2457 operand *
2458 geniCodeRightShift (operand * left, operand * right)
2459 {
2460   iCode *ic;
2461
2462
2463   /* Note that we don't use the usual binary conversions for the
2464    * shift operations, in accordance with our ANSI friends.
2465    */
2466   if (options.ANSIint)
2467     {
2468       right = usualUnaryConversions (right);
2469       left = usualUnaryConversions (left);
2470     }
2471
2472   ic = newiCode (RIGHT_OP, left, right);
2473   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2474   ADDTOCHAIN (ic);
2475   return IC_RESULT (ic);
2476 }
2477
2478 #if defined(__BORLANDC__) || defined(_MSC_VER)
2479 #define LONG_LONG __int64
2480 #else
2481 #define LONG_LONG long long
2482 #endif
2483
2484 /*-----------------------------------------------------------------*/
2485 /* geniCodeLogic- logic code                                       */
2486 /*-----------------------------------------------------------------*/
2487 operand *
2488 geniCodeLogic (operand * left, operand * right, int op)
2489 {
2490   iCode *ic;
2491   sym_link *ctype;
2492   sym_link *rtype = operandType (right);
2493   sym_link *ltype = operandType (left);
2494
2495   /* left is integral type and right is literal then
2496      check if the literal value is within bounds */
2497   if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2498     {
2499       int nbits = bitsForType (ltype);
2500       long v = operandLitValue (right);
2501
2502       if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2503         werror (W_CONST_RANGE, " compare operation ");
2504     }
2505
2506   ctype = usualBinaryConversions (&left, &right);
2507
2508   ic = newiCode (op, left, right);
2509   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2510
2511   /* if comparing float
2512      and not a '==' || '!=' || '&&' || '||' (these
2513      will be inlined */
2514   if (IS_FLOAT(ctype) &&
2515       op != EQ_OP &&
2516       op != NE_OP &&
2517       op != AND_OP &&
2518       op != OR_OP)
2519     ic->supportRtn = 1;
2520
2521   ADDTOCHAIN (ic);
2522   return IC_RESULT (ic);
2523 }
2524
2525 /*-----------------------------------------------------------------*/
2526 /* geniCodeUnary - for a a generic unary operation                 */
2527 /*-----------------------------------------------------------------*/
2528 operand *
2529 geniCodeUnary (operand * op, int oper)
2530 {
2531   iCode *ic = newiCode (oper, op, NULL);
2532
2533   IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2534   ADDTOCHAIN (ic);
2535   return IC_RESULT (ic);
2536 }
2537
2538 /*-----------------------------------------------------------------*/
2539 /* geniCodeConditional - geniCode for '?' ':' operation            */
2540 /*-----------------------------------------------------------------*/
2541 operand *
2542 geniCodeConditional (ast * tree)
2543 {
2544   iCode *ic;
2545   symbol *falseLabel = newiTempLabel (NULL);
2546   symbol *exitLabel = newiTempLabel (NULL);
2547   operand *cond = ast2iCode (tree->left);
2548   operand *true, *false, *result;
2549
2550   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2551                           NULL, falseLabel);
2552   ADDTOCHAIN (ic);
2553
2554   true = ast2iCode (tree->right->left);
2555
2556   /* move the value to a new Operand */
2557   result = newiTempOperand (operandType (true), 0);
2558   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2559
2560   /* generate an unconditional goto */
2561   geniCodeGoto (exitLabel);
2562
2563   /* now for the right side */
2564   geniCodeLabel (falseLabel);
2565
2566   false = ast2iCode (tree->right->right);
2567   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2568
2569   /* create the exit label */
2570   geniCodeLabel (exitLabel);
2571
2572   return result;
2573 }
2574
2575 /*-----------------------------------------------------------------*/
2576 /* geniCodeAssign - generate code for assignment                   */
2577 /*-----------------------------------------------------------------*/
2578 operand *
2579 geniCodeAssign (operand * left, operand * right, int nosupdate)
2580 {
2581   iCode *ic;
2582   sym_link *ltype = operandType (left);
2583   sym_link *rtype = operandType (right);
2584
2585   if (!left->isaddr && !IS_ITEMP (left))
2586     {
2587       werror (E_LVALUE_REQUIRED, "assignment");
2588       return left;
2589     }
2590
2591   /* left is integral type and right is literal then
2592      check if the literal value is within bounds */
2593   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2594     {
2595       int nbits = bitsForType (ltype);
2596       long v = operandLitValue (right);
2597
2598       if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2599         werror (W_CONST_RANGE, " = operation");
2600     }
2601
2602   /* if the left & right type don't exactly match */
2603   /* if pointer set then make sure the check is
2604      done with the type & not the pointer */
2605   /* then cast rights type to left */
2606
2607   /* first check the type for pointer assignement */
2608   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2609       checkType (ltype, rtype) < 0)
2610     {
2611       if (checkType (ltype->next, rtype) < 0)
2612         right = geniCodeCast (ltype->next, right, TRUE);
2613     }
2614   else if (checkType (ltype, rtype) < 0)
2615     right = geniCodeCast (ltype, right, TRUE);
2616
2617   /* if left is a true symbol & ! volatile
2618      create an assignment to temporary for
2619      the right & then assign this temporary
2620      to the symbol this is SSA . isn't it simple
2621      and folks have published mountains of paper on it */
2622   if (IS_TRUE_SYMOP (left) &&
2623       !isOperandVolatile (left, FALSE) &&
2624       isOperandGlobal (left))
2625     {
2626       symbol *sym = NULL;
2627
2628       if (IS_TRUE_SYMOP (right))
2629         sym = OP_SYMBOL (right);
2630       ic = newiCode ('=', NULL, right);
2631       IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2632       SPIL_LOC (right) = sym;
2633       ADDTOCHAIN (ic);
2634     }
2635
2636   ic = newiCode ('=', NULL, right);
2637   IC_RESULT (ic) = left;
2638   ADDTOCHAIN (ic);
2639
2640   /* if left isgptr flag is set then support
2641      routine will be required */
2642   if (left->isGptr)
2643     ic->supportRtn = 1;
2644
2645   ic->nosupdate = nosupdate;
2646   return left;
2647 }
2648
2649 /*-----------------------------------------------------------------*/
2650 /* geniCodeSEParms - generate code for side effecting fcalls       */
2651 /*-----------------------------------------------------------------*/
2652 static void 
2653 geniCodeSEParms (ast * parms)
2654 {
2655   if (!parms)
2656     return;
2657
2658   if (parms->type == EX_OP && parms->opval.op == PARAM)
2659     {
2660       geniCodeSEParms (parms->left);
2661       geniCodeSEParms (parms->right);
2662       return;
2663     }
2664
2665   /* hack don't like this but too lazy to think of
2666      something better */
2667   if (IS_ADDRESS_OF_OP (parms))
2668     parms->left->lvalue = 1;
2669
2670   if (IS_CAST_OP (parms) &&
2671       IS_PTR (parms->ftype) &&
2672       IS_ADDRESS_OF_OP (parms->right))
2673     parms->right->left->lvalue = 1;
2674
2675   parms->opval.oprnd =
2676     geniCodeRValue (ast2iCode (parms), FALSE);
2677
2678   parms->type = EX_OPERAND;
2679 }
2680
2681 /*-----------------------------------------------------------------*/
2682 /* geniCodeParms - generates parameters                            */
2683 /*-----------------------------------------------------------------*/
2684 static void 
2685 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
2686 {
2687   iCode *ic;
2688   operand *pval;
2689
2690   if (!parms)
2691     return;
2692
2693   /* if this is a param node then do the left & right */
2694   if (parms->type == EX_OP && parms->opval.op == PARAM)
2695     {
2696       geniCodeParms (parms->left, stack, fetype, func);
2697       geniCodeParms (parms->right, stack, fetype, func);
2698       return;
2699     }
2700
2701   /* get the parameter value */
2702   if (parms->type == EX_OPERAND)
2703     pval = parms->opval.oprnd;
2704   else
2705     {
2706       /* maybe this else should go away ?? */
2707       /* hack don't like this but too lazy to think of
2708          something better */
2709       if (IS_ADDRESS_OF_OP (parms))
2710         parms->left->lvalue = 1;
2711
2712       if (IS_CAST_OP (parms) &&
2713           IS_PTR (parms->ftype) &&
2714           IS_ADDRESS_OF_OP (parms->right))
2715         parms->right->left->lvalue = 1;
2716
2717       pval = geniCodeRValue (ast2iCode (parms), FALSE);
2718     }
2719
2720   /* if register parm then make it a send */
2721   if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2722        IS_REGPARM (parms->etype)) && !func->hasVargs)
2723     {
2724       ic = newiCode (SEND, pval, NULL);
2725       ADDTOCHAIN (ic);
2726     }
2727   else
2728     {
2729       /* now decide whether to push or assign */
2730       if (!(options.stackAuto || IS_RENT (fetype)))
2731         {
2732
2733           /* assign */
2734           operand *top = operandFromSymbol (parms->argSym);
2735           geniCodeAssign (top, pval, 1);
2736         }
2737       else
2738         {
2739           sym_link *p = operandType (pval);
2740           /* push */
2741           ic = newiCode (IPUSH, pval, NULL);
2742           ic->parmPush = 1;
2743           /* update the stack adjustment */
2744           *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2745           ADDTOCHAIN (ic);
2746         }
2747     }
2748
2749 }
2750
2751 /*-----------------------------------------------------------------*/
2752 /* geniCodeCall - generates temp code for calling                  */
2753 /*-----------------------------------------------------------------*/
2754 operand *
2755 geniCodeCall (operand * left, ast * parms)
2756 {
2757   iCode *ic;
2758   operand *result;
2759   sym_link *type, *etype;
2760   int stack = 0;
2761
2762   /* take care of parameters with side-effecting
2763      function calls in them, this is required to take care
2764      of overlaying function parameters */
2765   geniCodeSEParms (parms);
2766
2767   /* first the parameters */
2768   geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
2769
2770   /* now call : if symbol then pcall */
2771   if (IS_OP_POINTER (left) || IS_ITEMP(left))
2772     ic = newiCode (PCALL, left, NULL);
2773   else
2774     ic = newiCode (CALL, left, NULL);
2775
2776   IC_ARGS (ic) = left->operand.symOperand->args;
2777   type = copyLinkChain (operandType (left)->next);
2778   etype = getSpec (type);
2779   SPEC_EXTR (etype) = 0;
2780   IC_RESULT (ic) = result = newiTempOperand (type, 1);
2781
2782   ADDTOCHAIN (ic);
2783
2784   /* stack adjustment after call */
2785   ic->parmBytes = stack;
2786
2787   return result;
2788 }
2789
2790 /*-----------------------------------------------------------------*/
2791 /* geniCodeReceive - generate intermediate code for "receive"      */
2792 /*-----------------------------------------------------------------*/
2793 static void 
2794 geniCodeReceive (value * args)
2795 {
2796   /* for all arguments that are passed in registers */
2797   while (args)
2798     {
2799
2800       if (IS_REGPARM (args->etype))
2801         {
2802           operand *opr = operandFromValue (args);
2803           operand *opl;
2804           symbol *sym = OP_SYMBOL (opr);
2805           iCode *ic;
2806
2807           /* we will use it after all optimizations
2808              and before liveRange calculation */
2809           if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2810             {
2811
2812               if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2813                   options.stackAuto == 0 &&
2814                   !TARGET_IS_DS390)
2815                 {
2816                 }
2817               else
2818                 {
2819                   opl = newiTempOperand (args->type, 0);
2820                   sym->reqv = opl;
2821                   sym->reqv->key = sym->key;
2822                   OP_SYMBOL (sym->reqv)->key = sym->key;
2823                   OP_SYMBOL (sym->reqv)->isreqv = 1;
2824                   OP_SYMBOL (sym->reqv)->islocal = 0;
2825                   SPIL_LOC (sym->reqv) = sym;
2826                 }
2827             }
2828
2829           ic = newiCode (RECEIVE, NULL, NULL);
2830           currFunc->recvSize = getSize (sym->etype);
2831           IC_RESULT (ic) = opr;
2832           ADDTOCHAIN (ic);
2833         }
2834
2835       args = args->next;
2836     }
2837 }
2838
2839 /*-----------------------------------------------------------------*/
2840 /* geniCodeFunctionBody - create the function body                 */
2841 /*-----------------------------------------------------------------*/
2842 void 
2843 geniCodeFunctionBody (ast * tree)
2844 {
2845   iCode *ic;
2846   operand *func;
2847   sym_link *fetype;
2848   int savelineno;
2849
2850   /* reset the auto generation */
2851   /* numbers */
2852   iTempNum = 0;
2853   iTempLblNum = 0;
2854   operandKey = 0;
2855   iCodeKey = 0;
2856   func = ast2iCode (tree->left);
2857   fetype = getSpec (operandType (func));
2858
2859   savelineno = lineno;
2860   lineno = OP_SYMBOL (func)->lineDef;
2861   /* create an entry label */
2862   geniCodeLabel (entryLabel);
2863   lineno = savelineno;
2864
2865   /* create a proc icode */
2866   ic = newiCode (FUNCTION, func, NULL);
2867   /* if the function has parmas   then */
2868   /* save the parameters information    */
2869   ic->argLabel.args = tree->values.args;
2870   ic->lineno = OP_SYMBOL (func)->lineDef;
2871
2872   ADDTOCHAIN (ic);
2873
2874   /* for all parameters that are passed
2875      on registers add a "receive" */
2876   geniCodeReceive (tree->values.args);
2877
2878   /* generate code for the body */
2879   ast2iCode (tree->right);
2880
2881   /* create a label for return */
2882   geniCodeLabel (returnLabel);
2883
2884   /* now generate the end proc */
2885   ic = newiCode (ENDFUNCTION, func, NULL);
2886   ADDTOCHAIN (ic);
2887   return;
2888 }
2889
2890 /*-----------------------------------------------------------------*/
2891 /* geniCodeReturn - gen icode for 'return' statement               */
2892 /*-----------------------------------------------------------------*/
2893 void 
2894 geniCodeReturn (operand * op)
2895 {
2896   iCode *ic;
2897
2898   /* if the operand is present force an rvalue */
2899   if (op)
2900     op = geniCodeRValue (op, FALSE);
2901
2902   ic = newiCode (RETURN, op, NULL);
2903   ADDTOCHAIN (ic);
2904 }
2905
2906 /*-----------------------------------------------------------------*/
2907 /* geniCodeIfx - generates code for extended if statement          */
2908 /*-----------------------------------------------------------------*/
2909 void 
2910 geniCodeIfx (ast * tree)
2911 {
2912   iCode *ic;
2913   operand *condition = ast2iCode (tree->left);
2914   sym_link *cetype;
2915
2916   /* if condition is null then exit */
2917   if (!condition)
2918     goto exit;
2919   else
2920     condition = geniCodeRValue (condition, FALSE);
2921
2922   cetype = getSpec (operandType (condition));
2923   /* if the condition is a literal */
2924   if (IS_LITERAL (cetype))
2925     {
2926       if (floatFromVal (condition->operand.valOperand))
2927         {
2928           if (tree->trueLabel)
2929             geniCodeGoto (tree->trueLabel);
2930           else
2931             assert (1);
2932         }
2933       else
2934         {
2935           if (tree->falseLabel)
2936             geniCodeGoto (tree->falseLabel);
2937           else
2938             assert (1);
2939         }
2940       goto exit;
2941     }
2942
2943   if (tree->trueLabel)
2944     {
2945       ic = newiCodeCondition (condition,
2946                               tree->trueLabel,
2947                               NULL);
2948       ADDTOCHAIN (ic);
2949
2950       if (tree->falseLabel)
2951         geniCodeGoto (tree->falseLabel);
2952     }
2953   else
2954     {
2955       ic = newiCodeCondition (condition,
2956                               NULL,
2957                               tree->falseLabel);
2958       ADDTOCHAIN (ic);
2959     }
2960
2961 exit:
2962   ast2iCode (tree->right);
2963 }
2964
2965 /*-----------------------------------------------------------------*/
2966 /* geniCodeJumpTable - tries to create a jump table for switch     */
2967 /*-----------------------------------------------------------------*/
2968 int 
2969 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2970 {
2971   int min = 0, max = 0, t, cnt = 0;
2972   value *vch;
2973   iCode *ic;
2974   operand *boundary;
2975   symbol *falseLabel;
2976   set *labels = NULL;
2977
2978   if (!tree || !caseVals)
2979     return 0;
2980
2981   /* the criteria for creating a jump table is */
2982   /* all integer numbers between the maximum & minimum must */
2983   /* be present , the maximum value should not exceed 255 */
2984   min = max = (int) floatFromVal (vch = caseVals);
2985   sprintf (buffer, "_case_%d_%d",
2986            tree->values.switchVals.swNum,
2987            min);
2988   addSet (&labels, newiTempLabel (buffer));
2989
2990   /* if there is only one case value then no need */
2991   if (!(vch = vch->next))
2992     return 0;
2993
2994   while (vch)
2995     {
2996       if (((t = (int) floatFromVal (vch)) - max) != 1)
2997         return 0;
2998       sprintf (buffer, "_case_%d_%d",
2999                tree->values.switchVals.swNum,
3000                t);
3001       addSet (&labels, newiTempLabel (buffer));
3002       max = t;
3003       cnt++;
3004       vch = vch->next;
3005     }
3006
3007   /* if the number of case statements <= 2 then */
3008   /* it is not economical to create the jump table */
3009   /* since two compares are needed for boundary conditions */
3010   if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3011     return 0;
3012
3013   if (tree->values.switchVals.swDefault)
3014     sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3015   else
3016     sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3017
3018   falseLabel = newiTempLabel (buffer);
3019
3020   /* so we can create a jumptable */
3021   /* first we rule out the boundary conditions */
3022   /* if only optimization says so */
3023   if (!optimize.noJTabBoundary)
3024     {
3025       sym_link *cetype = getSpec (operandType (cond));
3026       /* no need to check the lower bound if
3027          the condition is unsigned & minimum value is zero */
3028       if (!(min == 0 && SPEC_USIGN (cetype)))
3029         {
3030           boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3031           ic = newiCodeCondition (boundary, falseLabel, NULL);
3032           ADDTOCHAIN (ic);
3033         }
3034
3035       /* now for upper bounds */
3036       boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3037       ic = newiCodeCondition (boundary, falseLabel, NULL);
3038       ADDTOCHAIN (ic);
3039     }
3040
3041   /* if the min is not zero then we no make it zero */
3042   if (min)
3043     {
3044       cond = geniCodeSubtract (cond, operandFromLit (min));
3045       setOperandType (cond, UCHARTYPE);
3046     }
3047
3048   /* now create the jumptable */
3049   ic = newiCode (JUMPTABLE, NULL, NULL);
3050   IC_JTCOND (ic) = cond;
3051   IC_JTLABELS (ic) = labels;
3052   ADDTOCHAIN (ic);
3053   return 1;
3054 }
3055
3056 /*-----------------------------------------------------------------*/
3057 /* geniCodeSwitch - changes a switch to a if statement             */
3058 /*-----------------------------------------------------------------*/
3059 void 
3060 geniCodeSwitch (ast * tree)
3061 {
3062   iCode *ic;
3063   operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
3064   value *caseVals = tree->values.switchVals.swVals;
3065   symbol *trueLabel, *falseLabel;
3066
3067   /* if we can make this a jump table */
3068   if (geniCodeJumpTable (cond, caseVals, tree))
3069     goto jumpTable;             /* no need for the comparison */
3070
3071   /* for the cases defined do */
3072   while (caseVals)
3073     {
3074
3075       operand *compare = geniCodeLogic (cond,
3076                                         operandFromValue (caseVals),
3077                                         EQ_OP);
3078
3079       sprintf (buffer, "_case_%d_%d",
3080                tree->values.switchVals.swNum,
3081                (int) floatFromVal (caseVals));
3082       trueLabel = newiTempLabel (buffer);
3083
3084       ic = newiCodeCondition (compare, trueLabel, NULL);
3085       ADDTOCHAIN (ic);
3086       caseVals = caseVals->next;
3087     }
3088
3089
3090
3091   /* if default is present then goto break else break */
3092   if (tree->values.switchVals.swDefault)
3093     sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3094   else
3095     sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3096
3097   falseLabel = newiTempLabel (buffer);
3098   geniCodeGoto (falseLabel);
3099
3100 jumpTable:
3101   ast2iCode (tree->right);
3102 }
3103
3104 /*-----------------------------------------------------------------*/
3105 /* geniCodeInline - intermediate code for inline assembler         */
3106 /*-----------------------------------------------------------------*/
3107 static void 
3108 geniCodeInline (ast * tree)
3109 {
3110   iCode *ic;
3111
3112   ic = newiCode (INLINEASM, NULL, NULL);
3113   IC_INLINE (ic) = tree->values.inlineasm;
3114   ADDTOCHAIN (ic);
3115 }
3116
3117 /*-----------------------------------------------------------------*/
3118 /* ast2iCode - creates an icodeList from an ast                    */
3119 /*-----------------------------------------------------------------*/
3120 operand *
3121 ast2iCode (ast * tree)
3122 {
3123   operand *left = NULL;
3124   operand *right = NULL;
3125
3126   if (!tree)
3127     return NULL;
3128
3129   /* set the global variables for filename & line number */
3130   if (tree->filename)
3131     filename = tree->filename;
3132   if (tree->lineno)
3133     lineno = tree->lineno;
3134   if (tree->block)
3135     block = tree->block;
3136   if (tree->level)
3137     scopeLevel = tree->level;
3138
3139   if (tree->type == EX_VALUE)
3140     return operandFromValue (tree->opval.val);
3141
3142   if (tree->type == EX_LINK)
3143     return operandFromLink (tree->opval.lnk);
3144
3145   /* if we find a nullop */
3146   if (tree->type == EX_OP &&
3147       (tree->opval.op == NULLOP ||
3148        tree->opval.op == BLOCK))
3149     {
3150       ast2iCode (tree->left);
3151       ast2iCode (tree->right);
3152       return NULL;
3153     }
3154
3155   /* special cases for not evaluating */
3156   if (tree->opval.op != ':' &&
3157       tree->opval.op != '?' &&
3158       tree->opval.op != CALL &&
3159       tree->opval.op != IFX &&
3160       tree->opval.op != LABEL &&
3161       tree->opval.op != GOTO &&
3162       tree->opval.op != SWITCH &&
3163       tree->opval.op != FUNCTION &&
3164       tree->opval.op != INLINEASM)
3165     {
3166
3167       if (IS_ASSIGN_OP (tree->opval.op) ||
3168           IS_DEREF_OP (tree) ||
3169           (tree->opval.op == '&' && !tree->right) ||
3170           tree->opval.op == PTR_OP)
3171         {
3172           lvaluereq++;
3173           if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3174               (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3175             {
3176               int olvr = lvaluereq;
3177               lvaluereq = 0;
3178               left = operandFromAst (tree->left);
3179               lvaluereq = olvr - 1;
3180             }
3181           else
3182             {
3183               left = operandFromAst (tree->left);
3184               lvaluereq--;
3185             }
3186           if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3187             left = geniCodeRValue (left, TRUE);
3188         }
3189       else
3190         {
3191           left = operandFromAst (tree->left);
3192         }
3193       if (tree->opval.op == INC_OP ||
3194           tree->opval.op == DEC_OP)
3195         {
3196           lvaluereq++;
3197           right = operandFromAst (tree->right);
3198           lvaluereq--;
3199         }
3200       else
3201         {
3202           right = operandFromAst (tree->right);
3203         }
3204     }
3205
3206   /* now depending on the type of operand */
3207   /* this will be a biggy                 */
3208   switch (tree->opval.op)
3209     {
3210
3211     case '[':                   /* array operation */
3212       {
3213         sym_link *ltype = operandType (left);
3214         left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3215         right = geniCodeRValue (right, TRUE);
3216       }
3217
3218       return geniCodeArray (left, right);
3219
3220     case '.':                   /* structure dereference */
3221       if (IS_PTR (operandType (left)))
3222         left = geniCodeRValue (left, TRUE);
3223       else
3224         left = geniCodeRValue (left, FALSE);
3225
3226       return geniCodeStruct (left, right, tree->lvalue);
3227
3228     case PTR_OP:                /* structure pointer dereference */
3229       {
3230         sym_link *pType;
3231         pType = operandType (left);
3232         left = geniCodeRValue (left, TRUE);
3233
3234         setOClass (pType, getSpec (operandType (left)));
3235       }
3236
3237       return geniCodeStruct (left, right, tree->lvalue);
3238
3239     case INC_OP:                /* increment operator */
3240       if (left)
3241         return geniCodePostInc (left);
3242       else
3243         return geniCodePreInc (right);
3244
3245     case DEC_OP:                /* decrement operator */
3246       if (left)
3247         return geniCodePostDec (left);
3248       else
3249         return geniCodePreDec (right);
3250
3251     case '&':                   /* bitwise and or address of operator */
3252       if (right)
3253         {                       /* this is a bitwise operator   */
3254           left = geniCodeRValue (left, FALSE);
3255           right = geniCodeRValue (right, FALSE);
3256           return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3257         }
3258       else
3259         return geniCodeAddressOf (left);
3260
3261     case '|':                   /* bitwise or & xor */
3262     case '^':
3263       return geniCodeBitwise (geniCodeRValue (left, FALSE),
3264                               geniCodeRValue (right, FALSE),
3265                               tree->opval.op,
3266                               tree->ftype);
3267
3268     case '/':
3269       return geniCodeDivision (geniCodeRValue (left, FALSE),
3270                                geniCodeRValue (right, FALSE));
3271
3272     case '%':
3273       return geniCodeModulus (geniCodeRValue (left, FALSE),
3274                               geniCodeRValue (right, FALSE));
3275     case '*':
3276       if (right)
3277         return geniCodeMultiply (geniCodeRValue (left, FALSE),
3278                                  geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3279       else
3280         return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
3281
3282     case '-':
3283       if (right)
3284         return geniCodeSubtract (geniCodeRValue (left, FALSE),
3285                                  geniCodeRValue (right, FALSE));
3286       else
3287         return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3288
3289     case '+':
3290       if (right)
3291         return geniCodeAdd (geniCodeRValue (left, FALSE),
3292                             geniCodeRValue (right, FALSE));
3293       else
3294         return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
3295
3296     case LEFT_OP:
3297       return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3298                                 geniCodeRValue (right, FALSE));
3299
3300     case RIGHT_OP:
3301       return geniCodeRightShift (geniCodeRValue (left, FALSE),
3302                                  geniCodeRValue (right, FALSE));
3303     case CAST:
3304       return geniCodeCast (operandType (left),
3305                            geniCodeRValue (right, FALSE), FALSE);
3306
3307     case '~':
3308     case '!':
3309     case RRC:
3310     case RLC:
3311       return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3312
3313     case GETHBIT:
3314       {
3315         operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3316         setOperandType (op, UCHARTYPE);
3317         return op;
3318       }
3319     case '>':
3320     case '<':
3321     case LE_OP:
3322     case GE_OP:
3323     case EQ_OP:
3324     case NE_OP:
3325     case AND_OP:
3326     case OR_OP:
3327       return geniCodeLogic (geniCodeRValue (left, FALSE),
3328                             geniCodeRValue (right, FALSE),
3329                             tree->opval.op);
3330     case '?':
3331       return geniCodeConditional (tree);
3332
3333     case SIZEOF:
3334       return operandFromLit (getSize (tree->right->ftype));
3335
3336     case '=':
3337       {
3338         sym_link *rtype = operandType (right);
3339         sym_link *ltype = operandType (left);
3340         if (IS_PTR (rtype) && IS_ITEMP (right)
3341             && right->isaddr && checkType (rtype->next, ltype) == 1)
3342           right = geniCodeRValue (right, TRUE);
3343         else
3344           right = geniCodeRValue (right, FALSE);
3345
3346         geniCodeAssign (left, right, 0);
3347         return right;
3348       }
3349     case MUL_ASSIGN:
3350       return
3351         geniCodeAssign (left,
3352                 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3353                                                   FALSE),
3354                                   geniCodeRValue (right, FALSE),FALSE), 0);
3355
3356     case DIV_ASSIGN:
3357       return
3358         geniCodeAssign (left,
3359                 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3360                                                   FALSE),
3361                                   geniCodeRValue (right, FALSE)), 0);
3362     case MOD_ASSIGN:
3363       return
3364         geniCodeAssign (left,
3365                  geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3366                                                   FALSE),
3367                                   geniCodeRValue (right, FALSE)), 0);
3368     case ADD_ASSIGN:
3369       {
3370         sym_link *rtype = operandType (right);
3371         sym_link *ltype = operandType (left);
3372         if (IS_PTR (rtype) && IS_ITEMP (right)
3373             && right->isaddr && checkType (rtype->next, ltype) == 1)
3374           right = geniCodeRValue (right, TRUE);
3375         else
3376           right = geniCodeRValue (right, FALSE);
3377
3378
3379         return geniCodeAssign (left,
3380                      geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3381                                                   FALSE),
3382                                   right), 0);
3383       }
3384     case SUB_ASSIGN:
3385       {
3386         sym_link *rtype = operandType (right);
3387         sym_link *ltype = operandType (left);
3388         if (IS_PTR (rtype) && IS_ITEMP (right)
3389             && right->isaddr && checkType (rtype->next, ltype) == 1)
3390           {
3391             right = geniCodeRValue (right, TRUE);
3392           }
3393         else
3394           {
3395             right = geniCodeRValue (right, FALSE);
3396           }
3397         return
3398           geniCodeAssign (left,
3399                 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3400                                                   FALSE),
3401                                   right), 0);
3402       }
3403     case LEFT_ASSIGN:
3404       return
3405         geniCodeAssign (left,
3406                 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3407                                                    ,FALSE),
3408                                    geniCodeRValue (right, FALSE)), 0);
3409     case RIGHT_ASSIGN:
3410       return
3411         geniCodeAssign (left,
3412                geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3413                                                    ,FALSE),
3414                                    geniCodeRValue (right, FALSE)), 0);
3415     case AND_ASSIGN:
3416       return
3417         geniCodeAssign (left,
3418                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3419                                                   FALSE),
3420                                   geniCodeRValue (right, FALSE),
3421                                   BITWISEAND,
3422                                   operandType (left)), 0);
3423     case XOR_ASSIGN:
3424       return
3425         geniCodeAssign (left,
3426                  geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3427                                                   FALSE),
3428                                   geniCodeRValue (right, FALSE),
3429                                   '^',
3430                                   operandType (left)), 0);
3431     case OR_ASSIGN:
3432       return
3433         geniCodeAssign (left,
3434                   geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3435                                                    ,FALSE),
3436                                    geniCodeRValue (right, FALSE),
3437                                    '|',
3438                                    operandType (left)), 0);
3439     case ',':
3440       return geniCodeRValue (right, FALSE);
3441
3442     case CALL:
3443       return geniCodeCall (ast2iCode (tree->left),
3444                            tree->right);
3445     case LABEL:
3446       geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
3447       return ast2iCode (tree->right);
3448
3449     case GOTO:
3450       geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
3451       return ast2iCode (tree->right);
3452
3453     case FUNCTION:
3454       geniCodeFunctionBody (tree);
3455       return NULL;
3456
3457     case RETURN:
3458       geniCodeReturn (right);
3459       return NULL;
3460
3461     case IFX:
3462       geniCodeIfx (tree);
3463       return NULL;
3464
3465     case SWITCH:
3466       geniCodeSwitch (tree);
3467       return NULL;
3468
3469     case INLINEASM:
3470       geniCodeInline (tree);
3471       return NULL;
3472     }
3473
3474   return NULL;
3475 }
3476
3477 /*-----------------------------------------------------------------*/
3478 /* reverseICChain - gets from the list and creates a linkedlist    */
3479 /*-----------------------------------------------------------------*/
3480 iCode *
3481 reverseiCChain ()
3482 {
3483   iCode *loop = NULL;
3484   iCode *prev = NULL;
3485
3486   while ((loop = getSet (&iCodeChain)))
3487     {
3488       loop->next = prev;
3489       if (prev)
3490         prev->prev = loop;
3491       prev = loop;
3492     }
3493
3494   return prev;
3495 }
3496
3497
3498 /*-----------------------------------------------------------------*/
3499 /* iCodeFromAst - given an ast will convert it to iCode            */
3500 /*-----------------------------------------------------------------*/
3501 iCode *
3502 iCodeFromAst (ast * tree)
3503 {
3504   returnLabel = newiTempLabel ("_return");
3505   entryLabel = newiTempLabel ("_entry");
3506   ast2iCode (tree);
3507   return reverseiCChain ();
3508 }