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