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