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