fixed: 100*200=32, only for the ds390 port right now
[fw/sdcc] / src / SDCCicode.c
1 /*-------------------------------------------------------------------------
2
3   SDCCicode.c - intermediate code generation etc.
4                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #include "common.h"
26 #include "newalloc.h"
27
28 /*-----------------------------------------------------------------*/
29 /* global variables       */
30
31 set *iCodeChain = NULL;
32 int iTempNum = 0;
33 int iTempLblNum = 0;
34 int operandKey = 0;
35 int iCodeKey = 0;
36 char *filename;
37 int lineno;
38 int block;
39 int scopeLevel;
40 int lvaluereq;
41
42 symbol *returnLabel;            /* function return label */
43 symbol *entryLabel;             /* function entry  label */
44 /*-----------------------------------------------------------------*/
45 /* forward definition of some functions */
46 operand *geniCodeDivision (operand *, operand *);
47 operand *geniCodeAssign (operand *, operand *, int);
48 operand *geniCodeArray (operand *, operand *);
49 operand *geniCodeArray2Ptr (operand *);
50 operand *geniCodeRValue (operand *, bool);
51 operand *geniCodeDerefPtr (operand *);
52
53 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
54 /* forward definition of print functions */
55 PRINTFUNC (picGetValueAtAddr);
56 PRINTFUNC (picSetValueAtAddr);
57 PRINTFUNC (picAddrOf);
58 PRINTFUNC (picGeneric);
59 PRINTFUNC (picGenericOne);
60 PRINTFUNC (picCast);
61 PRINTFUNC (picAssign);
62 PRINTFUNC (picLabel);
63 PRINTFUNC (picGoto);
64 PRINTFUNC (picIfx);
65 PRINTFUNC (picJumpTable);
66 PRINTFUNC (picInline);
67 PRINTFUNC (picReceive);
68
69 iCodeTable codeTable[] =
70 {
71   {'!', "not", picGenericOne, NULL},
72   {'~', "~", picGenericOne, NULL},
73   {RRC, "rrc", picGenericOne, NULL},
74   {RLC, "rlc", picGenericOne, NULL},
75   {GETHBIT, "ghbit", picGenericOne, NULL},
76   {UNARYMINUS, "-", picGenericOne, NULL},
77   {IPUSH, "push", picGenericOne, NULL},
78   {IPOP, "pop", picGenericOne, NULL},
79   {CALL, "call", picGenericOne, NULL},
80   {PCALL, "pcall", picGenericOne, NULL},
81   {FUNCTION, "proc", picGenericOne, NULL},
82   {ENDFUNCTION, "eproc", picGenericOne, NULL},
83   {RETURN, "ret", picGenericOne, NULL},
84   {'+', "+", picGeneric, NULL},
85   {'-', "-", picGeneric, NULL},
86   {'*', "*", picGeneric, NULL},
87   {'/', "/", picGeneric, NULL},
88   {'%', "%", picGeneric, NULL},
89   {'>', ">", picGeneric, NULL},
90   {'<', "<", picGeneric, NULL},
91   {LE_OP, "<=", picGeneric, NULL},
92   {GE_OP, ">=", picGeneric, NULL},
93   {EQ_OP, "==", picGeneric, NULL},
94   {NE_OP, "!=", picGeneric, NULL},
95   {AND_OP, "&&", picGeneric, NULL},
96   {OR_OP, "||", picGeneric, NULL},
97   {'^', "^", picGeneric, NULL},
98   {'|', "|", picGeneric, NULL},
99   {BITWISEAND, "&", picGeneric, NULL},
100   {LEFT_OP, "<<", picGeneric, NULL},
101   {RIGHT_OP, ">>", picGeneric, NULL},
102   {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
103   {ADDRESS_OF, "&", picAddrOf, NULL},
104   {CAST, "<>", picCast, NULL},
105   {'=', ":=", picAssign, NULL},
106   {LABEL, "", picLabel, NULL},
107   {GOTO, "", picGoto, NULL},
108   {JUMPTABLE, "jtab", picJumpTable, NULL},
109   {IFX, "if", picIfx, NULL},
110   {INLINEASM, "", picInline, NULL},
111   {RECEIVE, "recv", picReceive, NULL},
112   {SEND, "send", picGenericOne, NULL}
113 };
114
115
116 /*-----------------------------------------------------------------*/
117 /* operandName - returns the name of the operand                   */
118 /*-----------------------------------------------------------------*/
119 int 
120 printOperand (operand * op, FILE * file)
121 {
122   sym_link *opetype;
123   int pnl = 0;
124
125   if (!op)
126     return 1;
127
128   if (!file)
129     {
130       file = stdout;
131       pnl = 1;
132     }
133   switch (op->type)
134     {
135
136     case VALUE:
137       opetype = getSpec (operandType (op));
138       if (SPEC_NOUN (opetype) == V_FLOAT)
139         fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
140       else
141         fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
142       printTypeChain (operandType (op), file);
143       fprintf (file, "}");
144       break;
145
146     case SYMBOL:
147 #define REGA 1
148 #ifdef REGA
149       fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}",         /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
150                (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
151                op->key,
152                OP_LIVEFROM (op), OP_LIVETO (op),
153                OP_SYMBOL (op)->stack,
154                op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat
155         );
156       {
157         fprintf (file, "{");
158         printTypeChain (operandType (op), file);
159         if (SPIL_LOC (op) && IS_ITEMP (op))
160           fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
161         fprintf (file, "}");
162
163       }
164
165       /* if assigned to registers */
166       if (OP_SYMBOL (op)->nRegs)
167         {
168           if (OP_SYMBOL (op)->isspilt)
169             {
170               if (!OP_SYMBOL (op)->remat)
171                 if (OP_SYMBOL (op)->usl.spillLoc)
172                   fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
173                                        OP_SYMBOL (op)->usl.spillLoc->rname :
174                                        OP_SYMBOL (op)->usl.spillLoc->name));
175                 else
176                   fprintf (file, "[err]");
177               else
178                 fprintf (file, "[remat]");
179             }
180           else
181             {
182               int i;
183               fprintf (file, "[");
184               for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
185                 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
186               fprintf (file, "]");
187             }
188         }
189 #else
190       fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
191                             OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
192       /* if assigned to registers */
193       if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
194         {
195           int i;
196           fprintf (file, "[");
197           for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
198             fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
199                                    OP_SYMBOL (op)->regs[i]->name :
200                                    "err"));
201           fprintf (file, "]");
202         }
203 #endif
204       break;
205
206     case TYPE:
207       fprintf (file, "(");
208       printTypeChain (op->operand.typeOperand, file);
209       fprintf (file, ")");
210       break;
211     }
212
213   if (pnl)
214     fprintf (file, "\n");
215   return 0;
216 }
217
218
219 /*-----------------------------------------------------------------*/
220 /*                    print functions                              */
221 /*-----------------------------------------------------------------*/
222 PRINTFUNC (picGetValueAtAddr)
223 {
224   fprintf (of, "\t");
225   printOperand (IC_RESULT (ic), of);
226   fprintf (of, " = ");
227   fprintf (of, "@[");
228   printOperand (IC_LEFT (ic), of);
229   fprintf (of, "]");
230
231   fprintf (of, "\n");
232 }
233
234 PRINTFUNC (picSetValueAtAddr)
235 {
236   fprintf (of, "\t");
237   fprintf (of, "*[");
238   printOperand (IC_LEFT (ic), of);
239   fprintf (of, "] = ");
240   printOperand (IC_RIGHT (ic), of);
241   fprintf (of, "\n");
242 }
243
244 PRINTFUNC (picAddrOf)
245 {
246   fprintf (of, "\t");
247   printOperand (IC_RESULT (ic), of);
248   if (IS_ITEMP (IC_LEFT (ic)))
249     fprintf (of, " = ");
250   else
251     fprintf (of, " = &[");
252   printOperand (IC_LEFT (ic), of);
253   if (IC_RIGHT (ic))
254     {
255       if (IS_ITEMP (IC_LEFT (ic)))
256         fprintf (of, " offsetAdd ");
257       else
258         fprintf (of, " , ");
259       printOperand (IC_RIGHT (ic), of);
260     }
261   if (IS_ITEMP (IC_LEFT (ic)))
262     fprintf (of, "\n");
263   else
264     fprintf (of, "]\n");
265 }
266
267 PRINTFUNC (picJumpTable)
268 {
269   symbol *sym;
270
271   fprintf (of, "\t");
272   fprintf (of, "%s\t", s);
273   printOperand (IC_JTCOND (ic), of);
274   fprintf (of, "\n");
275   for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
276        sym = setNextItem (IC_JTLABELS (ic)))
277     fprintf (of, "\t\t\t%s\n", sym->name);
278 }
279
280 PRINTFUNC (picGeneric)
281 {
282   fprintf (of, "\t");
283   printOperand (IC_RESULT (ic), of);
284   fprintf (of, " = ");
285   printOperand (IC_LEFT (ic), of);
286   fprintf (of, " %s ", s);
287   printOperand (IC_RIGHT (ic), of);
288   fprintf (of, "\n");
289 }
290
291 PRINTFUNC (picGenericOne)
292 {
293   fprintf (of, "\t");
294   if (IC_RESULT (ic))
295     {
296       printOperand (IC_RESULT (ic), of);
297       fprintf (of, " = ");
298     }
299
300   if (IC_LEFT (ic))
301     {
302       fprintf (of, "%s ", s);
303       printOperand (IC_LEFT (ic), of);
304     }
305
306   if (!IC_RESULT (ic) && !IC_LEFT (ic))
307     fprintf (of, s);
308
309   fprintf (of, "\n");
310 }
311
312 PRINTFUNC (picCast)
313 {
314   fprintf (of, "\t");
315   printOperand (IC_RESULT (ic), of);
316   fprintf (of, " = ");
317   printOperand (IC_LEFT (ic), of);
318   printOperand (IC_RIGHT (ic), of);
319   fprintf (of, "\n");
320 }
321
322
323 PRINTFUNC (picAssign)
324 {
325   fprintf (of, "\t");
326
327   if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
328     fprintf (of, "*(");
329
330   printOperand (IC_RESULT (ic), of);
331
332   if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
333     fprintf (of, ")");
334
335   fprintf (of, " %s ", s);
336   printOperand (IC_RIGHT (ic), of);
337
338   fprintf (of, "\n");
339 }
340
341 PRINTFUNC (picLabel)
342 {
343   fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
344 }
345
346 PRINTFUNC (picGoto)
347 {
348   fprintf (of, "\t");
349   fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
350 }
351
352 PRINTFUNC (picIfx)
353 {
354   fprintf (of, "\t");
355   fprintf (of, "if ");
356   printOperand (IC_COND (ic), of);
357
358   if (!IC_TRUE (ic))
359     fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
360   else
361     {
362       fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
363       if (IC_FALSE (ic))
364         fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
365     }
366 }
367
368 PRINTFUNC (picInline)
369 {
370   fprintf (of, "%s", IC_INLINE (ic));
371 }
372
373 PRINTFUNC (picReceive)
374 {
375   printOperand (IC_RESULT (ic), of);
376   fprintf (of, " = %s ", s);
377   printOperand (IC_LEFT (ic), of);
378   fprintf (of, "\n");
379 }
380
381 /*-----------------------------------------------------------------*/
382 /* piCode - prints one iCode                                       */
383 /*-----------------------------------------------------------------*/
384 int 
385 piCode (void *item, FILE * of)
386 {
387   iCode *ic = item;
388   iCodeTable *icTab;
389
390   if (!of)
391     of = stdout;
392
393   icTab = getTableEntry (ic->op);
394   fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
395            ic->filename, ic->lineno,
396            ic->seq, ic->key, ic->depth, ic->supportRtn);
397   icTab->iCodePrint (of, ic, icTab->printName);
398   return 1;
399 }
400
401 /*-----------------------------------------------------------------*/
402 /* printiCChain - prints intermediate code for humans              */
403 /*-----------------------------------------------------------------*/
404 void 
405 printiCChain (iCode * icChain, FILE * of)
406 {
407   iCode *loop;
408   iCodeTable *icTab;
409
410   if (!of)
411     of = stdout;
412   for (loop = icChain; loop; loop = loop->next)
413     {
414       if ((icTab = getTableEntry (loop->op)))
415         {
416           fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
417                    loop->filename, loop->lineno,
418                    loop->seq, loop->key, loop->depth, loop->supportRtn);
419
420           icTab->iCodePrint (of, loop, icTab->printName);
421         }
422     }
423 }
424
425
426 /*-----------------------------------------------------------------*/
427 /* newOperand - allocate, init & return a new iCode                */
428 /*-----------------------------------------------------------------*/
429 operand *
430 newOperand ()
431 {
432   operand *op;
433
434   op = Safe_calloc (1, sizeof (operand));
435
436   op->key = 0;
437   return op;
438 }
439
440 /*-----------------------------------------------------------------*/
441 /* newiCode - create and return a new iCode entry initialised      */
442 /*-----------------------------------------------------------------*/
443 iCode *
444 newiCode (int op, operand * left, operand * right)
445 {
446   iCode *ic;
447
448   ic = Safe_calloc (1, sizeof (iCode));
449
450   ic->lineno = lineno;
451   ic->filename = filename;
452   ic->block = block;
453   ic->level = scopeLevel;
454   ic->op = op;
455   ic->key = iCodeKey++;
456   IC_LEFT (ic) = left;
457   IC_RIGHT (ic) = right;
458
459   return ic;
460 }
461
462 /*-----------------------------------------------------------------*/
463 /* newiCode for conditional statements                             */
464 /*-----------------------------------------------------------------*/
465 iCode *
466 newiCodeCondition (operand * condition,
467                    symbol * trueLabel,
468                    symbol * falseLabel)
469 {
470   iCode *ic;
471
472   ic = newiCode (IFX, NULL, NULL);
473   IC_COND (ic) = condition;
474   IC_TRUE (ic) = trueLabel;
475   IC_FALSE (ic) = falseLabel;
476   return ic;
477 }
478
479 /*-----------------------------------------------------------------*/
480 /* newiCodeLabelGoto - unconditional goto statement| label stmnt   */
481 /*-----------------------------------------------------------------*/
482 iCode *
483 newiCodeLabelGoto (int op, symbol * label)
484 {
485   iCode *ic;
486
487   ic = newiCode (op, NULL, NULL);
488   ic->op = op;
489   ic->argLabel.label = label;
490   IC_LEFT (ic) = NULL;
491   IC_RIGHT (ic) = NULL;
492   IC_RESULT (ic) = NULL;
493   return ic;
494 }
495
496 /*-----------------------------------------------------------------*/
497 /* newiTemp - allocate & return a newItemp Variable                */
498 /*-----------------------------------------------------------------*/
499 symbol *
500 newiTemp (char *s)
501 {
502   symbol *itmp;
503
504   if (s)
505     sprintf (buffer, "%s", s);
506   else
507     sprintf (buffer, "iTemp%d", iTempNum++);
508   itmp = newSymbol (buffer, 1);
509   strcpy (itmp->rname, itmp->name);
510   itmp->isitmp = 1;
511
512   return itmp;
513 }
514
515 /*-----------------------------------------------------------------*/
516 /* newiTempLabel - creates a temp variable label                   */
517 /*-----------------------------------------------------------------*/
518 symbol *
519 newiTempLabel (char *s)
520 {
521   symbol *itmplbl;
522
523   /* check if this alredy exists */
524   if (s && (itmplbl = findSym (LabelTab, NULL, s)))
525     return itmplbl;
526
527   if (s)
528     itmplbl = newSymbol (s, 1);
529   else
530     {
531       sprintf (buffer, "iTempLbl%d", iTempLblNum++);
532       itmplbl = newSymbol (buffer, 1);
533     }
534
535   itmplbl->isitmp = 1;
536   itmplbl->islbl = 1;
537   itmplbl->key = labelKey++;
538   addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
539   return itmplbl;
540 }
541
542 /*-----------------------------------------------------------------*/
543 /* newiTempPreheaderLabel - creates a new preheader label          */
544 /*-----------------------------------------------------------------*/
545 symbol *
546 newiTempPreheaderLabel ()
547 {
548   symbol *itmplbl;
549
550   sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
551   itmplbl = newSymbol (buffer, 1);
552
553   itmplbl->isitmp = 1;
554   itmplbl->islbl = 1;
555   itmplbl->key = labelKey++;
556   addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
557   return itmplbl;
558 }
559
560
561 /*-----------------------------------------------------------------*/
562 /* initiCode - initialises some iCode related stuff                */
563 /*-----------------------------------------------------------------*/
564 void 
565 initiCode ()
566 {
567
568 }
569
570 /*-----------------------------------------------------------------*/
571 /* copyiCode - make a copy of the iCode given                      */
572 /*-----------------------------------------------------------------*/
573 iCode *
574 copyiCode (iCode * ic)
575 {
576   iCode *nic = newiCode (ic->op, NULL, NULL);
577
578   nic->lineno = ic->lineno;
579   nic->filename = ic->filename;
580   nic->block = ic->block;
581   nic->level = ic->level;
582
583   /* deal with the special cases first */
584   switch (ic->op)
585     {
586     case IFX:
587       IC_COND (nic) = operandFromOperand (IC_COND (ic));
588       IC_TRUE (nic) = IC_TRUE (ic);
589       IC_FALSE (nic) = IC_FALSE (ic);
590       break;
591
592     case JUMPTABLE:
593       IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
594       IC_JTLABELS (nic) = IC_JTLABELS (ic);
595       break;
596
597     case CALL:
598     case PCALL:
599       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
600       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
601       IC_ARGS (nic) = IC_ARGS (ic);
602       break;
603
604     case INLINEASM:
605       IC_INLINE (nic) = IC_INLINE (ic);
606       break;
607
608     default:
609       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
610       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
611       IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
612     }
613
614   return nic;
615 }
616
617 /*-----------------------------------------------------------------*/
618 /* getTableEntry - gets the table entry for the given operator     */
619 /*-----------------------------------------------------------------*/
620 iCodeTable *
621 getTableEntry (int oper)
622 {
623   int i;
624
625   for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
626     if (oper == codeTable[i].icode)
627       return &codeTable[i];
628
629   return NULL;
630 }
631
632 /*-----------------------------------------------------------------*/
633 /* newiTempOperand - new intermediate temp operand                 */
634 /*-----------------------------------------------------------------*/
635 operand *
636 newiTempOperand (sym_link * type, char throwType)
637 {
638   symbol *itmp;
639   operand *op = newOperand ();
640   sym_link *etype;
641
642   op->type = SYMBOL;
643   itmp = newiTemp (NULL);
644
645   etype = getSpec (type);
646
647   if (IS_LITERAL (etype))
648     throwType = 0;
649
650   /* copy the type information */
651   if (type)
652     itmp->etype = getSpec (itmp->type = (throwType ? type :
653                                          copyLinkChain (type)));
654   if (IS_LITERAL (itmp->etype))
655     {
656       SPEC_SCLS (itmp->etype) = S_REGISTER;
657       SPEC_OCLS (itmp->etype) = reg;
658     }
659
660   op->operand.symOperand = itmp;
661   op->key = itmp->key = ++operandKey;
662   return op;
663 }
664
665 /*-----------------------------------------------------------------*/
666 /* operandType - returns the type chain for an operand             */
667 /*-----------------------------------------------------------------*/
668 sym_link *
669 operandType (operand * op)
670 {
671   /* depending on type of operand */
672   switch (op->type)
673     {
674
675     case VALUE:
676       return op->operand.valOperand->type;
677
678     case SYMBOL:
679       return op->operand.symOperand->type;
680
681     case TYPE:
682       return op->operand.typeOperand;
683     default:
684       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
685               " operand type not known ");
686       assert (0);               /* should never come here */
687       /*  Just to keep the compiler happy */
688       return (sym_link *) 0;
689     }
690 }
691
692 /*-----------------------------------------------------------------*/
693 /* isParamterToCall - will return 1 if op is a parameter to args   */
694 /*-----------------------------------------------------------------*/
695 int 
696 isParameterToCall (value * args, operand * op)
697 {
698   value *tval = args;
699
700   while (tval)
701     {
702       if (tval->sym &&
703           isSymbolEqual (op->operand.symOperand, tval->sym))
704         return 1;
705       tval = tval->next;
706     }
707   return 0;
708 }
709
710 /*-----------------------------------------------------------------*/
711 /* isOperandGlobal   - return 1 if operand is a global variable    */
712 /*-----------------------------------------------------------------*/
713 int 
714 isOperandGlobal (operand * op)
715 {
716   if (!op)
717     return 0;
718
719   if (IS_ITEMP (op))
720     return 0;
721
722   if (op->type == SYMBOL &&
723       (op->operand.symOperand->level == 0 ||
724        IS_STATIC (op->operand.symOperand->etype) ||
725        IS_EXTERN (op->operand.symOperand->etype))
726     )
727     return 1;
728
729   return 0;
730 }
731
732 /*-----------------------------------------------------------------*/
733 /* isOperandVolatile - return 1 if the operand is volatile         */
734 /*-----------------------------------------------------------------*/
735 int 
736 isOperandVolatile (operand * op, bool chkTemp)
737 {
738   sym_link *optype;
739   sym_link *opetype;
740
741   if (IS_ITEMP (op) && !chkTemp)
742     return 0;
743
744   opetype = getSpec (optype = operandType (op));
745
746   if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
747     return 1;
748
749   if (IS_VOLATILE (opetype))
750     return 1;
751   return 0;
752 }
753
754 /*-----------------------------------------------------------------*/
755 /* isOperandLiteral - returns 1 if an operand contains a literal   */
756 /*-----------------------------------------------------------------*/
757 int 
758 isOperandLiteral (operand * op)
759 {
760   sym_link *opetype;
761
762   if (!op)
763     return 0;
764
765   opetype = getSpec (operandType (op));
766
767   if (IS_LITERAL (opetype))
768     return 1;
769
770   return 0;
771 }
772 /*-----------------------------------------------------------------*/
773 /* isOperandInFarSpace - will return true if operand is in farSpace */
774 /*-----------------------------------------------------------------*/
775 bool 
776 isOperandInFarSpace (operand * op)
777 {
778   sym_link *etype;
779
780   if (!op)
781     return FALSE;
782
783   if (!IS_SYMOP (op))
784     return FALSE;
785
786   if (!IS_TRUE_SYMOP (op))
787     {
788       if (SPIL_LOC (op))
789         etype = SPIL_LOC (op)->etype;
790       else
791         return FALSE;
792     }
793   else
794     {
795       etype = getSpec (operandType (op));
796     }
797   return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
798 }
799
800 /*-----------------------------------------------------------------*/
801 /* isOperandOnStack - will return true if operand is on stack      */
802 /*-----------------------------------------------------------------*/
803 bool 
804 isOperandOnStack (operand * op)
805 {
806   sym_link *etype;
807
808   if (!op)
809     return FALSE;
810
811   if (!IS_SYMOP (op))
812     return FALSE;
813
814   etype = getSpec (operandType (op));
815
816   return ((IN_STACK (etype)) ? TRUE : FALSE);
817 }
818
819 /*-----------------------------------------------------------------*/
820 /* operandLitValue - literal value of an operand                   */
821 /*-----------------------------------------------------------------*/
822 double 
823 operandLitValue (operand * op)
824 {
825   assert (isOperandLiteral (op));
826
827   return floatFromVal (op->operand.valOperand);
828 }
829
830 /*-----------------------------------------------------------------*/
831 /* operandOperation - perforoms operations on operands             */
832 /*-----------------------------------------------------------------*/
833 operand *
834 operandOperation (operand * left, operand * right,
835                   int op, sym_link * type)
836 {
837   operand *retval = (operand *) 0;
838
839   assert (isOperandLiteral (left));
840   if (right)
841     assert (isOperandLiteral (right));
842
843   switch (op)
844     {
845     case '+':
846       retval = operandFromValue (valCastLiteral (type,
847                                                  operandLitValue (left) +
848                                                  operandLitValue (right)));
849       break;
850     case '-':
851       retval = operandFromValue (valCastLiteral (type,
852                                                  operandLitValue (left) -
853                                                  operandLitValue (right)));
854       break;
855     case '*':
856       retval = operandFromValue (valCastLiteral (type,
857                                                  operandLitValue (left) *
858                                                  operandLitValue (right)));
859       break;
860     case '/':
861       if ((unsigned long) operandLitValue (right) == 0)
862         {
863           werror (E_DIVIDE_BY_ZERO);
864           retval = right;
865
866         }
867       else
868         retval = operandFromValue (valCastLiteral (type,
869                                                    operandLitValue (left) /
870                                                    operandLitValue (right)));
871       break;
872     case '%':
873       if ((unsigned long) operandLitValue (right) == 0)
874         {
875           werror (E_DIVIDE_BY_ZERO);
876           retval = right;
877         }
878       else
879         retval = operandFromLit ((unsigned long) operandLitValue (left) %
880                                  (unsigned long) operandLitValue (right));
881       break;
882     case LEFT_OP:
883       retval = operandFromLit ((unsigned long) operandLitValue (left) <<
884                                (unsigned long) operandLitValue (right));
885       break;
886     case RIGHT_OP:
887       retval = operandFromLit ((unsigned long) operandLitValue (left) >>
888                                (unsigned long) operandLitValue (right));
889       break;
890     case EQ_OP:
891       retval = operandFromLit (operandLitValue (left) ==
892                                operandLitValue (right));
893       break;
894     case '<':
895       retval = operandFromLit (operandLitValue (left) <
896                                operandLitValue (right));
897       break;
898     case LE_OP:
899       retval = operandFromLit (operandLitValue (left) <=
900                                operandLitValue (right));
901       break;
902     case NE_OP:
903       retval = operandFromLit (operandLitValue (left) !=
904                                operandLitValue (right));
905       break;
906     case '>':
907       retval = operandFromLit (operandLitValue (left) >
908                                operandLitValue (right));
909       break;
910     case GE_OP:
911       retval = operandFromLit (operandLitValue (left) >=
912                                operandLitValue (right));
913       break;
914     case BITWISEAND:
915       retval = operandFromLit ((unsigned long) operandLitValue (left) &
916                                (unsigned long) operandLitValue (right));
917       break;
918     case '|':
919       retval = operandFromLit ((unsigned long) operandLitValue (left) |
920                                (unsigned long) operandLitValue (right));
921       break;
922     case '^':
923       retval = operandFromLit ((unsigned long) operandLitValue (left) ^
924                                (unsigned long) operandLitValue (right));
925       break;
926     case AND_OP:
927       retval = operandFromLit (operandLitValue (left) &&
928                                operandLitValue (right));
929       break;
930     case OR_OP:
931       retval = operandFromLit (operandLitValue (left) ||
932                                operandLitValue (right));
933       break;
934     case RRC:
935       {
936         long i = operandLitValue (left);
937
938         retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
939                                  (i << 1));
940       }
941       break;
942     case RLC:
943       {
944         long i = operandLitValue (left);
945
946         retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
947                                  (i >> 1));
948       }
949       break;
950
951     case UNARYMINUS:
952       retval = operandFromLit (-1 * operandLitValue (left));
953       break;
954
955     case '~':
956       retval = operandFromLit (~((long) operandLitValue (left)));
957       break;
958
959     case '!':
960       retval = operandFromLit (!operandLitValue (left));
961       break;
962
963     default:
964       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
965               " operandOperation invalid operator ");
966       assert (0);
967     }
968
969   return retval;
970 }
971
972
973 /*-----------------------------------------------------------------*/
974 /* isOperandEqual - compares two operand & return 1 if they r =    */
975 /*-----------------------------------------------------------------*/
976 int 
977 isOperandEqual (operand * left, operand * right)
978 {
979   /* if the pointers are equal then they are equal */
980   if (left == right)
981     return 1;
982
983   /* if either of them null then false */
984   if (!left || !right)
985     return 0;
986
987   if (left->type != right->type)
988     return 0;
989
990   if (IS_SYMOP (left) && IS_SYMOP (right))
991     return left->key == right->key;
992
993   /* if types are the same */
994   switch (left->type)
995     {
996     case SYMBOL:
997       return isSymbolEqual (left->operand.symOperand,
998                             right->operand.symOperand);
999     case VALUE:
1000       return (floatFromVal (left->operand.valOperand) ==
1001               floatFromVal (right->operand.valOperand));
1002     case TYPE:
1003       if (checkType (left->operand.typeOperand,
1004                      right->operand.typeOperand) == 1)
1005         return 1;
1006     }
1007
1008   return 0;
1009 }
1010
1011 /*-----------------------------------------------------------------*/
1012 /* isiCodeEqual - comapres two iCodes are returns true if yes      */
1013 /*-----------------------------------------------------------------*/
1014 int 
1015 isiCodeEqual (iCode * left, iCode * right)
1016 {
1017   /* if the same pointer */
1018   if (left == right)
1019     return 1;
1020
1021   /* if either of them null */
1022   if (!left || !right)
1023     return 0;
1024
1025   /* if operand are the same */
1026   if (left->op == right->op)
1027     {
1028
1029       /* compare all the elements depending on type */
1030       if (left->op != IFX)
1031         {
1032           if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1033             return 0;
1034           if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1035             return 0;
1036
1037         }
1038       else
1039         {
1040           if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1041             return 0;
1042           if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1043             return 0;
1044           if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1045             return 0;
1046         }
1047       return 1;
1048     }
1049   return 0;
1050 }
1051
1052 /*-----------------------------------------------------------------*/
1053 /* newiTempFromOp - create a temp Operand with same attributes     */
1054 /*-----------------------------------------------------------------*/
1055 operand *
1056 newiTempFromOp (operand * op)
1057 {
1058   operand *nop;
1059
1060   if (!op)
1061     return NULL;
1062
1063   if (!IS_ITEMP (op))
1064     return op;
1065
1066   nop = newiTempOperand (operandType (op), TRUE);
1067   nop->isaddr = op->isaddr;
1068   nop->isvolatile = op->isvolatile;
1069   nop->isGlobal = op->isGlobal;
1070   nop->isLiteral = op->isLiteral;
1071   nop->noSpilLoc = op->noSpilLoc;
1072   nop->usesDefs = op->usesDefs;
1073   nop->isParm = op->isParm;
1074   nop->parmBytes = op->parmBytes;
1075   return nop;
1076 }
1077
1078 /*-----------------------------------------------------------------*/
1079 /* operand from operand - creates an operand holder for the type   */
1080 /*-----------------------------------------------------------------*/
1081 operand *
1082 operandFromOperand (operand * op)
1083 {
1084   operand *nop;
1085
1086   if (!op)
1087     return NULL;
1088   nop = newOperand ();
1089   nop->type = op->type;
1090   nop->isaddr = op->isaddr;
1091   nop->key = op->key;
1092   nop->isvolatile = op->isvolatile;
1093   nop->isGlobal = op->isGlobal;
1094   nop->isLiteral = op->isLiteral;
1095   nop->noSpilLoc = op->noSpilLoc;
1096   nop->usesDefs = op->usesDefs;
1097   nop->isParm = op->isParm;
1098   nop->parmBytes = op->parmBytes;
1099
1100   switch (nop->type)
1101     {
1102     case SYMBOL:
1103       nop->operand.symOperand = op->operand.symOperand;
1104       break;
1105     case VALUE:
1106       nop->operand.valOperand = op->operand.valOperand;
1107       break;
1108     case TYPE:
1109       nop->operand.typeOperand = op->operand.typeOperand;
1110       break;
1111     }
1112
1113   return nop;
1114 }
1115
1116 /*-----------------------------------------------------------------*/
1117 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
1118 /*-----------------------------------------------------------------*/
1119 operand *
1120 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1121 {
1122   operand *nop = operandFromOperand (op);
1123
1124   if (nop->type == SYMBOL)
1125     {
1126       OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1127       OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1128     }
1129
1130   return nop;
1131 }
1132
1133 /*-----------------------------------------------------------------*/
1134 /* operandFromSymbol - creates an operand from a symbol            */
1135 /*-----------------------------------------------------------------*/
1136 operand *
1137 operandFromSymbol (symbol * sym)
1138 {
1139   operand *op;
1140   iCode *ic;
1141   int ok = 1;
1142   /* if the symbol's type is a literal */
1143   /* then it is an enumerator type     */
1144   if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1145     return operandFromValue (valFromType (sym->etype));
1146
1147   if (!sym->key)
1148     sym->key = ++operandKey;
1149
1150   /* if this an implicit variable, means struct/union */
1151   /* member so just return it                         */
1152   if (sym->implicit || IS_FUNC (sym->type))
1153     {
1154       op = newOperand ();
1155       op->type = SYMBOL;
1156       op->operand.symOperand = sym;
1157       op->key = sym->key;
1158       op->isvolatile = isOperandVolatile (op, TRUE);
1159       op->isGlobal = isOperandGlobal (op);
1160       op->parmBytes = sym->argStack;
1161       return op;
1162     }
1163
1164   /* under the following conditions create a
1165      register equivalent for a local symbol */
1166   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1167       (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!IS_DS390_PORT)) &&
1168       options.stackAuto == 0)
1169     ok = 0;
1170
1171   if (!IS_AGGREGATE (sym->type) &&      /* not an aggregate */
1172       !IS_FUNC (sym->type) &&   /* not a function   */
1173       !sym->_isparm &&          /* not a parameter  */
1174       sym->level &&             /* is a local variable */
1175       !sym->addrtaken &&        /* whose address has not been taken */
1176       !sym->reqv &&             /* does not already have a register euivalence */
1177       !IS_VOLATILE (sym->etype) &&      /* not declared as volatile */
1178       !IS_STATIC (sym->etype) &&        /* and not declared static  */
1179       !sym->islbl &&            /* not a label */
1180       ok &&                     /* farspace check */
1181       !IS_BITVAR (sym->etype)   /* not a bit variable */
1182     )
1183     {
1184
1185       /* we will use it after all optimizations
1186          and before liveRange calculation */
1187       sym->reqv = newiTempOperand (sym->type, 0);
1188       sym->reqv->key = sym->key;
1189       OP_SYMBOL (sym->reqv)->key = sym->key;
1190       OP_SYMBOL (sym->reqv)->isreqv = 1;
1191       OP_SYMBOL (sym->reqv)->islocal = 1;
1192       SPIL_LOC (sym->reqv) = sym;
1193     }
1194
1195   if (!IS_AGGREGATE (sym->type))
1196     {
1197       op = newOperand ();
1198       op->type = SYMBOL;
1199       op->operand.symOperand = sym;
1200       op->isaddr = 1;
1201       op->key = sym->key;
1202       op->isvolatile = isOperandVolatile (op, TRUE);
1203       op->isGlobal = isOperandGlobal (op);
1204       op->isPtr = IS_PTR (operandType (op));
1205       op->isParm = sym->_isparm;
1206       return op;
1207     }
1208
1209   /* create :-                     */
1210   /*    itemp = &[_symbol]         */
1211
1212   ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1213   IC_LEFT (ic)->type = SYMBOL;
1214   IC_LEFT (ic)->operand.symOperand = sym;
1215   IC_LEFT (ic)->key = sym->key;
1216   (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1217   (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1218   IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1219
1220   /* create result */
1221   IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1222   if (IS_ARRAY (sym->type))
1223     {
1224       IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1225       IC_RESULT (ic)->isaddr = 0;
1226     }
1227   else
1228     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1229
1230   IC_RESULT (ic)->operand.symOperand->args = sym->args;
1231
1232   ADDTOCHAIN (ic);
1233
1234   return IC_RESULT (ic);
1235 }
1236
1237 /*-----------------------------------------------------------------*/
1238 /* operandFromValue - creates an operand from value                */
1239 /*-----------------------------------------------------------------*/
1240 operand *
1241 operandFromValue (value * val)
1242 {
1243   operand *op;
1244
1245   /* if this is a symbol then do the symbol thing */
1246   if (val->sym)
1247     return operandFromSymbol (val->sym);
1248
1249   /* this is not a symbol */
1250   op = newOperand ();
1251   op->type = VALUE;
1252   op->operand.valOperand = val;
1253   op->isLiteral = isOperandLiteral (op);
1254   return op;
1255 }
1256
1257 /*-----------------------------------------------------------------*/
1258 /* operandFromLink - operand from typeChain                        */
1259 /*-----------------------------------------------------------------*/
1260 operand *
1261 operandFromLink (sym_link * type)
1262 {
1263   operand *op;
1264
1265   /* operand from sym_link */
1266   if (!type)
1267     return NULL;
1268
1269   op = newOperand ();
1270   op->type = TYPE;
1271   op->operand.typeOperand = copyLinkChain (type);
1272   return op;
1273 }
1274
1275 /*-----------------------------------------------------------------*/
1276 /* operandFromLit - makes an operand from a literal value          */
1277 /*-----------------------------------------------------------------*/
1278 operand *
1279 operandFromLit (float i)
1280 {
1281   return operandFromValue (valueFromLit (i));
1282 }
1283
1284 /*-----------------------------------------------------------------*/
1285 /* operandFromAst - creates an operand from an ast                 */
1286 /*-----------------------------------------------------------------*/
1287 operand *
1288 operandFromAst (ast * tree)
1289 {
1290
1291   if (!tree)
1292     return NULL;
1293
1294   /* depending on type do */
1295   switch (tree->type)
1296     {
1297     case EX_OP:
1298       return ast2iCode (tree);
1299       break;
1300
1301     case EX_VALUE:
1302       return operandFromValue (tree->opval.val);
1303       break;
1304
1305     case EX_LINK:
1306       return operandFromLink (tree->opval.lnk);
1307     }
1308
1309   assert (0);
1310   /*  Just to keep the comiler happy */
1311   return (operand *) 0;
1312 }
1313
1314 /*-----------------------------------------------------------------*/
1315 /* setOperandType - sets the operand's type to the given type      */
1316 /*-----------------------------------------------------------------*/
1317 void 
1318 setOperandType (operand * op, sym_link * type)
1319 {
1320   /* depending on the type of operand */
1321   switch (op->type)
1322     {
1323
1324     case VALUE:
1325       op->operand.valOperand->etype =
1326         getSpec (op->operand.valOperand->type =
1327                  copyLinkChain (type));
1328       return;
1329
1330     case SYMBOL:
1331       if (op->operand.symOperand->isitmp)
1332         op->operand.symOperand->etype =
1333           getSpec (op->operand.symOperand->type =
1334                    copyLinkChain (type));
1335       else
1336         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1337                 "attempt to modify type of source");
1338       return;
1339
1340     case TYPE:
1341       op->operand.typeOperand = copyLinkChain (type);
1342       return;
1343     }
1344
1345 }
1346
1347 /*-----------------------------------------------------------------*/
1348 /* perform "usual unary conversions"                               */
1349 /*-----------------------------------------------------------------*/
1350 operand *
1351 usualUnaryConversions (operand * op)
1352 {
1353   if (IS_INTEGRAL (operandType (op)))
1354     {
1355       if (getSize (operandType (op)) < INTSIZE)
1356         {
1357           /* Widen to int. */
1358           return geniCodeCast (INTTYPE, op, TRUE);
1359         }
1360     }
1361   return op;
1362 }
1363
1364 /*-----------------------------------------------------------------*/
1365 /* perform "usual binary conversions"                              */
1366 /*-----------------------------------------------------------------*/
1367 sym_link *
1368 usualBinaryConversions (operand ** op1, operand ** op2)
1369 {
1370   if (!options.ANSIint)
1371     {
1372       /* "Classic" SDCC behavior. */
1373       sym_link *ctype;
1374       sym_link *rtype = operandType (*op2);
1375       sym_link *ltype = operandType (*op1);
1376
1377       ctype = computeType (ltype, rtype);
1378       *op1 = geniCodeCast (ctype, *op1, TRUE);
1379       *op2 = geniCodeCast (ctype, *op2, TRUE);
1380
1381       return ctype;
1382     }
1383
1384   *op1 = usualUnaryConversions (*op1);
1385   *op2 = usualUnaryConversions (*op2);
1386
1387   /* Try to make the two operands of the same type, following
1388    * the "usual binary conversions" promotion rules.
1389    *
1390    * NB: floating point types are not yet properly handled; we
1391    * follow the "classic" behavior.
1392    */
1393
1394   if (IS_FLOAT (operandType (*op1)) || IS_FLOAT (operandType (*op2)))
1395     {
1396       return newFloatLink ();
1397     }
1398
1399   if (!IS_INTEGRAL (operandType (*op1)) || !IS_INTEGRAL (operandType (*op2)))
1400     {
1401       /* if either is not an integer type, we're done. */
1402       return copyLinkChain (operandType (*op1));        /* Punt! we should never get here. */
1403     }
1404
1405   /* If either is an unsigned long, make sure both are. */
1406   if (SPEC_USIGN (operandType (*op1)) && IS_LONG (operandType (*op1)))
1407     {
1408       if (!SPEC_USIGN (operandType (*op2)) || !IS_LONG (operandType (*op2)))
1409         {
1410           *op2 = geniCodeCast (ULONGTYPE, *op2, TRUE);
1411         }
1412       return copyLinkChain (operandType (*op1));
1413     }
1414
1415   if (SPEC_USIGN (operandType (*op2)) && IS_LONG (operandType (*op2)))
1416     {
1417       if (!SPEC_USIGN (operandType (*op1)) || !IS_LONG (operandType (*op1)))
1418         {
1419           *op1 = geniCodeCast (ULONGTYPE, *op1, TRUE);
1420         }
1421       return copyLinkChain (operandType (*op2));
1422     }
1423
1424   /* Next, if one is long and the other is int (signed or un),
1425    * cast both to long.
1426    *
1427    * Note that because in our environment a long can hold all
1428    * the values of an unsigned int, the "long/unsigned int" pair
1429    * in the ANSI conversion table is unnecessary; this test
1430    * handles that case implicitly.
1431    */
1432   if (IS_LONG (operandType (*op1)))
1433     {
1434       /* NB: because of the unary conversions, op2 cannot
1435        * be smaller than int. Therefore, if it is not
1436        * long, it is a regular int.
1437        */
1438       if (!IS_LONG (operandType (*op2)))
1439         {
1440           *op2 = geniCodeCast (LONGTYPE, *op2, TRUE);
1441         }
1442       return copyLinkChain (operandType (*op1));
1443     }
1444
1445   if (IS_LONG (operandType (*op2)))
1446     {
1447       /* NB: because of the unary conversions, op2 cannot
1448        * be smaller than int. Therefore, if it is not
1449        * long, it is a regular int.
1450        */
1451       if (!IS_LONG (operandType (*op1)))
1452         {
1453           *op1 = geniCodeCast (LONGTYPE, *op1, TRUE);
1454         }
1455       return copyLinkChain (operandType (*op2));
1456     }
1457
1458   /* All right, neither is long; they must both be integers.
1459
1460    * Only remaining issue is signed vs. unsigned; if one is unsigned
1461    * and the other isn't, convert both to unsigned.
1462    */
1463   if (SPEC_USIGN (operandType (*op1)))
1464     {
1465       if (!SPEC_USIGN (operandType (*op2)))
1466         {
1467           *op2 = geniCodeCast (UINTTYPE, *op2, TRUE);
1468         }
1469       return copyLinkChain (operandType (*op1));
1470     }
1471
1472   if (SPEC_USIGN (operandType (*op2)))
1473     {
1474       if (!SPEC_USIGN (operandType (*op1)))
1475         {
1476           *op1 = geniCodeCast (UINTTYPE, *op1, TRUE);
1477         }
1478       return copyLinkChain (operandType (*op2));
1479     }
1480
1481   /* Done! */
1482   return copyLinkChain (operandType (*op1));
1483 }
1484
1485
1486 /*-----------------------------------------------------------------*/
1487 /* geniCodeValueAtAddress - generate intermeditate code for value  */
1488 /*                          at address                             */
1489 /*-----------------------------------------------------------------*/
1490 operand *
1491 geniCodeRValue (operand * op, bool force)
1492 {
1493   iCode *ic;
1494   sym_link *type = operandType (op);
1495   sym_link *etype = getSpec (type);
1496
1497   /* if this is an array & already */
1498   /* an address then return this   */
1499   if (IS_AGGREGATE (type) ||
1500       (IS_PTR (type) && !force && !op->isaddr))
1501     return operandFromOperand (op);
1502
1503   /* if this is not an address then must be */
1504   /* rvalue already so return this one      */
1505   if (!op->isaddr)
1506     return op;
1507
1508   /* if this is not a temp symbol then */
1509   if (!IS_ITEMP (op) &&
1510       !force &&
1511       !IN_FARSPACE (SPEC_OCLS (etype)))
1512     {
1513       op = operandFromOperand (op);
1514       op->isaddr = 0;
1515       return op;
1516     }
1517
1518   if (IS_SPEC (type) &&
1519       IS_TRUE_SYMOP (op) &&
1520       (!IN_FARSPACE (SPEC_OCLS (etype)) || IS_DS390_PORT))
1521     {
1522       op = operandFromOperand (op);
1523       op->isaddr = 0;
1524       return op;
1525     }
1526
1527   ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1528   if (IS_PTR (type) && op->isaddr && force)
1529     type = type->next;
1530
1531   type = copyLinkChain (type);
1532
1533   IC_RESULT (ic) = newiTempOperand (type, 1);
1534   IC_RESULT (ic)->isaddr = 0;
1535
1536 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1537
1538   /* if the right is a symbol */
1539   if (op->type == SYMBOL)
1540     IC_RESULT (ic)->operand.symOperand->args =
1541       op->operand.symOperand->args;
1542   ADDTOCHAIN (ic);
1543
1544   return IC_RESULT (ic);
1545 }
1546
1547 /*-----------------------------------------------------------------*/
1548 /* geniCodeCast - changes the value from one type to another       */
1549 /*-----------------------------------------------------------------*/
1550 operand *
1551 geniCodeCast (sym_link * type, operand * op, bool implicit)
1552 {
1553   iCode *ic;
1554   sym_link *optype;
1555   sym_link *opetype = getSpec (optype = operandType (op));
1556   sym_link *restype;
1557
1558   /* one of them has size zero then error */
1559   if (IS_VOID (optype))
1560     {
1561       werror (E_CAST_ZERO);
1562       return op;
1563     }
1564
1565   /* if the operand is already the desired type then do nothing */
1566   if (checkType (type, optype) == 1)
1567     return op;
1568
1569   /* if this is a literal then just change the type & return */
1570   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1571     return operandFromValue (valCastLiteral (type,
1572                                              operandLitValue (op)));
1573
1574   /* if casting to some pointer type &&
1575      the destination is not a generic pointer
1576      then give a warning : (only for implicit casts) */
1577   if (IS_PTR (optype) && implicit &&
1578       (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1579       !IS_GENPTR (type))
1580     {
1581       werror (E_INCOMPAT_CAST);
1582       werror (E_CONTINUE, "from type '");
1583       printTypeChain (optype, stderr);
1584       fprintf (stderr, "' to type '");
1585       printTypeChain (type, stderr);
1586       fprintf (stderr, "'\n");
1587     }
1588
1589   /* if they are the same size create an assignment */
1590   if (getSize (type) == getSize (optype) &&
1591       !IS_BITFIELD (type) &&
1592       !IS_FLOAT (type) &&
1593       !IS_FLOAT (optype) &&
1594       ((IS_SPEC (type) && IS_SPEC (optype)) ||
1595        (!IS_SPEC (type) && !IS_SPEC (optype))))
1596     {
1597
1598       ic = newiCode ('=', NULL, op);
1599       IC_RESULT (ic) = newiTempOperand (type, 0);
1600       SPIL_LOC (IC_RESULT (ic)) =
1601         (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1602       IC_RESULT (ic)->isaddr = 0;
1603     }
1604   else
1605     {
1606       ic = newiCode (CAST, operandFromLink (type),
1607                      geniCodeRValue (op, FALSE));
1608
1609       IC_RESULT (ic) = newiTempOperand (type, 0);
1610     }
1611
1612   /* preserve the storage class & output class */
1613   /* of the original variable                  */
1614   restype = getSpec (operandType (IC_RESULT (ic)));
1615   SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1616   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1617
1618   ADDTOCHAIN (ic);
1619   return IC_RESULT (ic);
1620 }
1621
1622 /*-----------------------------------------------------------------*/
1623 /* geniCodeLabel - will create a Label                             */
1624 /*-----------------------------------------------------------------*/
1625 void 
1626 geniCodeLabel (symbol * label)
1627 {
1628   iCode *ic;
1629
1630   ic = newiCodeLabelGoto (LABEL, label);
1631   ADDTOCHAIN (ic);
1632 }
1633
1634 /*-----------------------------------------------------------------*/
1635 /* geniCodeGoto  - will create a Goto                              */
1636 /*-----------------------------------------------------------------*/
1637 void 
1638 geniCodeGoto (symbol * label)
1639 {
1640   iCode *ic;
1641
1642   ic = newiCodeLabelGoto (GOTO, label);
1643   ADDTOCHAIN (ic);
1644 }
1645
1646 /*-----------------------------------------------------------------*/
1647 /* geniCodeMultiply - gen intermediate code for multiplication     */
1648 /*-----------------------------------------------------------------*/
1649 operand *
1650 geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation)
1651 {
1652   iCode *ic;
1653   int p2 = 0;
1654   int saveOption;
1655   sym_link *resType;
1656   LRTYPE;
1657
1658   /* if they are both literal then we know the result */
1659   if (IS_LITERAL (letype) && IS_LITERAL (retype))
1660     return operandFromValue (valMult (left->operand.valOperand,
1661                                       right->operand.valOperand));
1662
1663
1664   //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size
1665   if ((ptrSizeCalculation) && (1 == getSize (rtype)) &&
1666       (1 == getSize (ltype)))
1667     {
1668       saveOption = options.ANSIint;
1669       options.ANSIint = 0;
1670       resType = usualBinaryConversions (&left, &right);
1671       ltype = operandType (left);
1672       rtype = operandType (right);
1673       SPEC_SHORT (getSpec (resType)) = 0;
1674       options.ANSIint = saveOption;
1675     }
1676   else {
1677     resType = usualBinaryConversions (&left, &right);
1678     if (IS_DS390_PORT) {
1679       /* jwk char*char=int
1680          Now be can use the 16bit result of "mul a,b" instead of explicit
1681          casts and support function calls as with --ansiint
1682       */
1683       if ((IS_CHAR(letype) || IS_SHORT(letype)) && 
1684            (IS_CHAR(retype) || IS_SHORT(retype))) {
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);
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));
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);
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_ITEMP (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   left->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);
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), 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 }