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