Beautified (indented) compiler source according to gnu coding style
[fw/sdcc] / src / avr / ralloc.c
1 /*------------------------------------------------------------------------
2
3   SDCCralloc.c - source file for register allocation. (ATMEL AVR) specific
4
5                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
6
7    This program is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by the
9    Free Software Foundation; either version 2, or (at your option) any
10    later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20    
21    In other words, you are welcome to use, share and improve this program.
22    You are forbidden to forbid anyone else to use, share and improve
23    what you give them.   Help stamp out software-hoarding!  
24 -------------------------------------------------------------------------*/
25
26 #include "common.h"
27 #include "ralloc.h"
28 #include "gen.h"
29
30 /*-----------------------------------------------------------------*/
31 /* At this point we start getting processor specific although      */
32 /* some routines are non-processor specific & can be reused when   */
33 /* targetting other processors. The decision for this will have    */
34 /* to be made on a routine by routine basis                        */
35 /* routines used to pack registers are most definitely not reusable */
36 /* since the pack the registers depending strictly on the MCU      */
37 /*-----------------------------------------------------------------*/
38
39 extern void genAVRCode (iCode *);
40
41 /* Global data */
42 static struct
43   {
44     bitVect *spiltSet;
45     set *stackSpil;
46     bitVect *regAssigned;
47     short blockSpil;
48     int slocNum;
49     bitVect *funcrUsed;         /* registers used in a function */
50     int stackExtend;
51     int dataExtend;
52   }
53 _G;
54
55 /* Shared with gen.c */
56 int avr_ptrRegReq;              /* pointer register required */
57
58 /* AVR registers */
59 regs regsAVR[] =
60 {
61   {REG_GPR, R0_IDX, REG_GPR, "r0", "r0", "", 0, 0, 0},  /* used as scratch */
62   {REG_GPR, R1_IDX, REG_GPR, "r1", "r1", "", 0, 0, 0},  /* used as scratch */
63   {REG_GPR, R2_IDX, REG_GPR, "r2", "r2", "", 0, 1, 1},  /* gpr */
64   {REG_GPR, R3_IDX, REG_GPR, "r3", "r3", "", 0, 1, 1},  /* gpr */
65   {REG_GPR, R4_IDX, REG_GPR, "r4", "r4", "", 0, 1, 1},  /* gpr */
66   {REG_GPR, R5_IDX, REG_GPR, "r5", "r5", "", 0, 1, 1},  /* gpr */
67   {REG_GPR, R6_IDX, REG_GPR, "r6", "r6", "", 0, 1, 1},  /* gpr */
68   {REG_GPR, R7_IDX, REG_GPR, "r7", "r7", "", 0, 1, 1},  /* gpr */
69   {REG_GPR, R8_IDX, REG_GPR, "r8", "r8", "", 0, 1, 1},  /* gpr */
70   {REG_GPR, R9_IDX, REG_GPR, "r9", "r9", "", 0, 1, 1},  /* gpr */
71   {REG_GPR, R10_IDX, REG_GPR, "r10", "r10", "", 0, 1, 1},       /* gpr */
72   {REG_GPR, R11_IDX, REG_GPR, "r11", "r11", "", 0, 1, 1},       /* gpr */
73   {REG_GPR, R12_IDX, REG_GPR, "r12", "r12", "", 0, 1, 1},       /* gpr */
74   {REG_GPR, R13_IDX, REG_GPR, "r13", "r13", "", 0, 1, 1},       /* gpr */
75   {REG_GPR, R14_IDX, REG_GPR, "r14", "r14", "", 0, 1, 1},       /* gpr */
76   {REG_GPR, R15_IDX, REG_GPR, "r15", "r15", "", 0, 1, 1},       /* gpr */
77   {REG_GPR, R16_IDX, REG_GPR, "r16", "r16", "", 0, 1, 0},       /* parm/gpr */
78   {REG_GPR, R17_IDX, REG_GPR, "r17", "r17", "", 0, 1, 0},       /* parm/gpr */
79   {REG_GPR, R18_IDX, REG_GPR, "r18", "r18", "", 0, 1, 0},       /* parm/gpr */
80   {REG_GPR, R19_IDX, REG_GPR, "r19", "r19", "", 0, 1, 0},       /* parm/gpr */
81   {REG_GPR, R20_IDX, REG_GPR, "r20", "r20", "", 0, 1, 0},       /* parm/gpr */
82   {REG_GPR, R21_IDX, REG_GPR, "r21", "r21", "", 0, 1, 0},       /* parm/gpr */
83   {REG_GPR, R22_IDX, REG_GPR, "r22", "r22", "", 0, 1, 0},       /* parm/gpr */
84   {REG_GPR, R23_IDX, REG_GPR, "r23", "r23", "", 0, 1, 0},       /* parm/gpr */
85   {REG_GPR, R24_IDX, REG_GPR, "r24", "r24", "", 0, 0, 0},       /* scratch  */
86   {REG_GPR, R25_IDX, REG_GPR, "r25", "r25", "", 0, 0, 0},       /* scratch */
87   {REG_GPR, R26_IDX, REG_GPR, "r26", "r26", "", 0, 1, 1},       /* used as pointer reg X */
88   {REG_GPR, R27_IDX, REG_GPR, "r27", "r27", "", 0, 1, 1},       /* used as pointer reg X */
89   {REG_GPR, R28_IDX, REG_GPR, "r28", "r28", "", 0, 1, 0},       /* stack frame Y */
90   {REG_GPR, R29_IDX, REG_GPR, "r29", "r29", "", 0, 1, 0},       /* stack frame Y */
91   {REG_GPR, R30_IDX, REG_GPR, "r30", "r30", "", 0, 1, 1},       /* used as pointer reg Z */
92   {REG_GPR, R31_IDX, REG_GPR, "r31", "r31", "", 0, 1, 1},       /* used as pointer reg Z */
93   {REG_PTR, X_IDX, REG_PTR, "X", "X", "", 0, 1, 0},
94   {REG_PTR, Z_IDX, REG_PTR, "Z", "Z", "", 0, 1, 0},
95 };
96 int avr_nRegs = 32;
97 int avr_fReg = 0;               /* first allocatable register */
98
99 static void spillThis (symbol *);
100
101 /*-----------------------------------------------------------------*/
102 /* allocReg - allocates register of given type                     */
103 /*-----------------------------------------------------------------*/
104 static regs *
105 allocReg (short type)
106 {
107   int i;
108
109   for (i = avr_fReg; i < avr_nRegs; i++)
110     {
111
112       /* if type is given as 0 then any
113          free register will do */
114       if (!type &&
115           regsAVR[i].isFree)
116         {
117           regsAVR[i].isFree = 0;
118           if (currFunc)
119             currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, i);
120           return &regsAVR[i];
121         }
122       /* other wise look for specific type
123          of register */
124       if (regsAVR[i].isFree &&
125           regsAVR[i].type == type)
126         {
127           regsAVR[i].isFree = 0;
128           if (currFunc)
129             currFunc->regsUsed =
130               bitVectSetBit (currFunc->regsUsed, i);
131           return &regsAVR[i];
132         }
133     }
134   return NULL;
135 }
136
137 /*-----------------------------------------------------------------*/
138 /* avr_regWithIdx - returns pointer to register wit index number   */
139 /*-----------------------------------------------------------------*/
140 regs *
141 avr_regWithIdx (int idx)
142 {
143   int i;
144
145   for (i = 0; i < avr_nRegs; i++)
146     if (regsAVR[i].rIdx == idx)
147       return &regsAVR[i];
148
149   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
150           "regWithIdx not found");
151   exit (1);
152 }
153
154 /*-----------------------------------------------------------------*/
155 /* freeReg - frees a register                                      */
156 /*-----------------------------------------------------------------*/
157 static void
158 freeReg (regs * reg)
159 {
160   reg->isFree = 1;
161 }
162
163
164 /*-----------------------------------------------------------------*/
165 /* nFreeRegs - returns number of free registers                    */
166 /*-----------------------------------------------------------------*/
167 static int
168 nFreeRegs (int type)
169 {
170   int i;
171   int nfr = 0;
172
173   for (i = avr_fReg; i < avr_nRegs; i++)
174     if (regsAVR[i].isFree && regsAVR[i].type == type)
175       nfr++;
176   return nfr;
177 }
178
179 /*-----------------------------------------------------------------*/
180 /* nfreeRegsType - free registers with type                         */
181 /*-----------------------------------------------------------------*/
182 static int
183 nfreeRegsType (int type)
184 {
185   int nfr;
186   if (type == REG_PTR)
187     {
188       if ((nfr = nFreeRegs (type)) == 0)
189         return nFreeRegs (REG_GPR);
190     }
191
192   return nFreeRegs (type);
193 }
194
195
196 /*-----------------------------------------------------------------*/
197 /* allDefsOutOfRange - all definitions are out of a range          */
198 /*-----------------------------------------------------------------*/
199 static bool
200 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
201 {
202   int i;
203
204   if (!defs)
205     return TRUE;
206
207   for (i = 0; i < defs->size; i++)
208     {
209       iCode *ic;
210
211       if (bitVectBitValue (defs, i) &&
212           (ic = hTabItemWithKey (iCodehTab, i)) &&
213           (ic->seq >= fseq && ic->seq <= toseq))
214
215         return FALSE;
216     }
217
218   return TRUE;
219 }
220
221 /*-----------------------------------------------------------------*/
222 /* computeSpillable - given a point find the spillable live ranges */
223 /*-----------------------------------------------------------------*/
224 static bitVect *
225 computeSpillable (iCode * ic)
226 {
227   bitVect *spillable;
228
229   /* spillable live ranges are those that are live at this 
230      point . the following categories need to be subtracted
231      from this set. 
232      a) - those that are already spilt
233      b) - if being used by this one
234      c) - defined by this one */
235
236   spillable = bitVectCopy (ic->rlive);
237   spillable =
238     bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
239   spillable =
240     bitVectCplAnd (spillable, ic->uses);        /* used in this one */
241   bitVectUnSetBit (spillable, ic->defKey);
242   spillable = bitVectIntersect (spillable, _G.regAssigned);
243   return spillable;
244
245 }
246
247 /*-----------------------------------------------------------------*/
248 /* noSpilLoc - return true if a variable has no spil location      */
249 /*-----------------------------------------------------------------*/
250 static int
251 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
252 {
253   return (sym->usl.spillLoc ? 0 : 1);
254 }
255
256 /*-----------------------------------------------------------------*/
257 /* hasSpilLoc - will return 1 if the symbol has spil location      */
258 /*-----------------------------------------------------------------*/
259 static int
260 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
261 {
262   return (sym->usl.spillLoc ? 1 : 0);
263 }
264
265 /*-----------------------------------------------------------------*/
266 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
267 /*                    but is not used as a pointer                 */
268 /*-----------------------------------------------------------------*/
269 static int
270 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
271 {
272   return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
273 }
274
275 /*-----------------------------------------------------------------*/
276 /* rematable - will return 1 if the remat flag is set              */
277 /*-----------------------------------------------------------------*/
278 static int
279 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
280 {
281   return sym->remat;
282 }
283
284 /*-----------------------------------------------------------------*/
285 /* notUsedInBlock - not used in this block                         */
286 /*-----------------------------------------------------------------*/
287 static int
288 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
289 {
290   return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
291           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
292 }
293
294 /*-----------------------------------------------------------------*/
295 /* notUsedInRemaining - not used or defined in remain of the block */
296 /*-----------------------------------------------------------------*/
297 static int
298 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
299 {
300   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
301           allDefsOutOfRange (sym->defs, ic->seq, ebp->lSeq));
302 }
303
304 /*-----------------------------------------------------------------*/
305 /* allLRs - return true for all                                    */
306 /*-----------------------------------------------------------------*/
307 static int
308 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
309 {
310   return 1;
311 }
312
313 /*-----------------------------------------------------------------*/
314 /* liveRangesWith - applies function to a given set of live range  */
315 /*-----------------------------------------------------------------*/
316 static set *
317 liveRangesWith (bitVect * lrs,
318                 int (func) (symbol *, eBBlock *, iCode *),
319                 eBBlock * ebp, iCode * ic)
320 {
321   set *rset = NULL;
322   int i;
323
324   if (!lrs || !lrs->size)
325     return NULL;
326
327   for (i = 1; i < lrs->size; i++)
328     {
329       symbol *sym;
330       if (!bitVectBitValue (lrs, i))
331         continue;
332
333       /* if we don't find it in the live range 
334          hash table we are in serious trouble */
335       if (!(sym = hTabItemWithKey (liveRanges, i)))
336         {
337           werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
338                   "liveRangesWith could not find liveRange");
339           exit (1);
340         }
341
342       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
343         addSetHead (&rset, sym);
344     }
345
346   return rset;
347 }
348
349
350 /*-----------------------------------------------------------------*/
351 /* leastUsedLR - given a set determines which is the least used    */
352 /*-----------------------------------------------------------------*/
353 static symbol *
354 leastUsedLR (set * sset)
355 {
356   symbol *sym = NULL, *lsym = NULL;
357
358   sym = lsym = setFirstItem (sset);
359
360   if (!lsym)
361     return NULL;
362
363   for (; lsym; lsym = setNextItem (sset))
364     {
365
366       /* if usage is the same then prefer
367          the spill the smaller of the two */
368       if (lsym->used == sym->used)
369         if (getSize (lsym->type) < getSize (sym->type))
370           sym = lsym;
371
372       /* if less usage */
373       if (lsym->used < sym->used)
374         sym = lsym;
375
376     }
377
378   setToNull ((void **) &sset);
379   sym->blockSpil = 0;
380   return sym;
381 }
382
383 /*-----------------------------------------------------------------*/
384 /* noOverLap - will iterate through the list looking for over lap  */
385 /*-----------------------------------------------------------------*/
386 static int
387 noOverLap (set * itmpStack, symbol * fsym)
388 {
389   symbol *sym;
390
391
392   for (sym = setFirstItem (itmpStack); sym;
393        sym = setNextItem (itmpStack))
394     {
395       if (sym->liveTo > fsym->liveFrom)
396         return 0;
397
398     }
399
400   return 1;
401 }
402
403 /*-----------------------------------------------------------------*/
404 /* isFree - will return 1 if the a free spil location is found     */
405 /*-----------------------------------------------------------------*/
406 static
407 DEFSETFUNC (isFree)
408 {
409   symbol *sym = item;
410   V_ARG (symbol **, sloc);
411   V_ARG (symbol *, fsym);
412
413   /* if already found */
414   if (*sloc)
415     return 0;
416
417   /* if it is free && and the itmp assigned to
418      this does not have any overlapping live ranges
419      with the one currently being assigned and
420      the size can be accomodated  */
421   if (sym->isFree &&
422       noOverLap (sym->usl.itmpStack, fsym) &&
423       getSize (sym->type) >= getSize (fsym->type))
424     {
425       *sloc = sym;
426       return 1;
427     }
428
429   return 0;
430 }
431
432 /*-----------------------------------------------------------------*/
433 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
434 /*-----------------------------------------------------------------*/
435 static void
436 spillLRWithPtrReg (symbol * forSym)
437 {
438   symbol *lrsym;
439   regs *X, *Z;
440   int k;
441
442   if (!_G.regAssigned ||
443       bitVectIsZero (_G.regAssigned))
444     return;
445
446   X = avr_regWithIdx (X_IDX);
447   Z = avr_regWithIdx (Z_IDX);
448
449   /* for all live ranges */
450   for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
451        lrsym = hTabNextItem (liveRanges, &k))
452     {
453       int j;
454
455       /* if no registers assigned to it or
456          spilt */
457       /* if it does not overlap with this then 
458          not need to spill it */
459
460       if (lrsym->isspilt || !lrsym->nRegs ||
461           (lrsym->liveTo < forSym->liveFrom))
462         continue;
463
464       /* go thru the registers : if it is either
465          r0 or r1 then spil it */
466       for (j = 0; j < lrsym->nRegs; j++)
467         if (lrsym->regs[j] == X || lrsym->regs[j] == Z)
468           {
469             spillThis (lrsym);
470             break;
471           }
472     }
473
474 }
475
476 /*-----------------------------------------------------------------*/
477 /* createStackSpil - create a location on the stack to spil        */
478 /*-----------------------------------------------------------------*/
479 static symbol *
480 createStackSpil (symbol * sym)
481 {
482   symbol *sloc = NULL;
483   int useXstack, model, noOverlay;
484   int stackAuto;
485
486   char slocBuffer[30];
487
488   /* first go try and find a free one that is already 
489      existing on the stack */
490   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
491     {
492       /* found a free one : just update & return */
493       sym->usl.spillLoc = sloc;
494       sym->stackSpil = 1;
495       sloc->isFree = 0;
496       addSetHead (&sloc->usl.itmpStack, sym);
497       return sym;
498     }
499
500   /* could not then have to create one , this is the hard part
501      we need to allocate this on the stack : this is really a
502      hack!! but cannot think of anything better at this time */
503
504   if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
505     {
506       fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
507                __FILE__, __LINE__);
508       exit (1);
509     }
510
511   sloc = newiTemp (slocBuffer);
512
513   /* set the type to the spilling symbol */
514   sloc->type = copyLinkChain (sym->type);
515   sloc->etype = getSpec (sloc->type);
516   SPEC_SCLS (sloc->etype) = S_AUTO;
517   SPEC_EXTR (sloc->etype) = 0;
518
519   /* we don't allow it to be allocated`
520      onto the external stack since : so we
521      temporarily turn it off ; we also
522      turn off memory model to prevent
523      the spil from going to the external storage
524      and turn off overlaying 
525    */
526
527   useXstack = options.useXstack;
528   model = options.model;
529   noOverlay = options.noOverlay;
530   stackAuto = options.stackAuto;
531   options.noOverlay = 1;
532   options.model = options.useXstack = 0;
533
534   allocLocal (sloc);
535
536   options.useXstack = useXstack;
537   options.model = model;
538   options.noOverlay = noOverlay;
539   options.stackAuto = stackAuto;
540   sloc->isref = 1;              /* to prevent compiler warning */
541
542   /* if it is on the stack then update the stack */
543   if (IN_STACK (sloc->etype))
544     {
545       currFunc->stack += getSize (sloc->type);
546       _G.stackExtend += getSize (sloc->type);
547     }
548   else
549     _G.dataExtend += getSize (sloc->type);
550
551   /* add it to the _G.stackSpil set */
552   addSetHead (&_G.stackSpil, sloc);
553   sym->usl.spillLoc = sloc;
554   sym->stackSpil = 1;
555
556   /* add it to the set of itempStack set 
557      of the spill location */
558   addSetHead (&sloc->usl.itmpStack, sym);
559   return sym;
560 }
561
562 /*-----------------------------------------------------------------*/
563 /* isSpiltOnStack - returns true if the spil location is on stack  */
564 /*-----------------------------------------------------------------*/
565 static bool
566 isSpiltOnStack (symbol * sym)
567 {
568   sym_link *etype;
569
570   if (!sym)
571     return FALSE;
572
573   if (!sym->isspilt)
574     return FALSE;
575
576
577   if (!sym->usl.spillLoc)
578     return FALSE;
579
580   etype = getSpec (sym->usl.spillLoc->type);
581   if (IN_STACK (etype))
582     return TRUE;
583
584   return FALSE;
585 }
586
587 /*-----------------------------------------------------------------*/
588 /* spillThis - spils a specific operand                            */
589 /*-----------------------------------------------------------------*/
590 static void
591 spillThis (symbol * sym)
592 {
593   int i;
594   /* if this is rematerializable or has a spillLocation
595      we are okay, else we need to create a spillLocation
596      for it */
597   if (!(sym->remat || sym->usl.spillLoc))
598     createStackSpil (sym);
599
600
601   /* mark it has spilt & put it in the spilt set */
602   sym->isspilt = 1;
603   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
604
605   bitVectUnSetBit (_G.regAssigned, sym->key);
606
607   for (i = 0; i < sym->nRegs; i++)
608
609     if (sym->regs[i])
610       {
611         freeReg (sym->regs[i]);
612         sym->regs[i] = NULL;
613       }
614
615   if (sym->usl.spillLoc && !sym->remat)
616     sym->usl.spillLoc->allocreq = 1;
617   return;
618 }
619
620 /*-----------------------------------------------------------------*/
621 /* selectSpil - select a iTemp to spil : rather a simple procedure */
622 /*-----------------------------------------------------------------*/
623 static symbol *
624 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
625 {
626   bitVect *lrcs = NULL;
627   set *selectS;
628   symbol *sym;
629
630   /* get the spillable live ranges */
631   lrcs = computeSpillable (ic);
632
633   /* get all live ranges that are rematerizable */
634   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
635     {
636
637       /* return the least used of these */
638       return leastUsedLR (selectS);
639     }
640
641   /* if the symbol is local to the block then */
642   if (forSym->liveTo < ebp->lSeq)
643     {
644
645       /* check if there are any live ranges allocated
646          to registers that are not used in this block */
647       if (!_G.blockSpil &&
648           (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
649         {
650           sym = leastUsedLR (selectS);
651           /* if this is not rematerializable */
652           if (!sym->remat)
653             {
654               _G.blockSpil++;
655               sym->blockSpil = 1;
656             }
657           return sym;
658         }
659
660       /* check if there are any live ranges that not
661          used in the remainder of the block */
662       if (!_G.blockSpil &&
663           (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
664         {
665           sym = leastUsedLR (selectS);
666           if (sym != forSym)
667             {
668               if (!sym->remat)
669                 {
670                   sym->remainSpil = 1;
671                   _G.blockSpil++;
672                 }
673               return sym;
674             }
675         }
676     }
677
678   /* find live ranges with spillocation && not used as pointers */
679   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
680     {
681
682       sym = leastUsedLR (selectS);
683       /* mark this as allocation required */
684       sym->usl.spillLoc->allocreq = 1;
685       return sym;
686     }
687
688   /* find live ranges with spillocation */
689   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
690     {
691
692       sym = leastUsedLR (selectS);
693       sym->usl.spillLoc->allocreq = 1;
694       return sym;
695     }
696
697   /* couldn't find then we need to create a spil
698      location on the stack , for which one? the least
699      used ofcourse */
700   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
701     {
702
703       /* return a created spil location */
704       sym = createStackSpil (leastUsedLR (selectS));
705       sym->usl.spillLoc->allocreq = 1;
706       return sym;
707     }
708
709   /* this is an extreme situation we will spill
710      this one : happens very rarely but it does happen */
711   spillThis (forSym);
712   return forSym;
713
714 }
715
716 /*-----------------------------------------------------------------*/
717 /* spilSomething - spil some variable & mark registers as free     */
718 /*-----------------------------------------------------------------*/
719 static bool
720 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
721 {
722   symbol *ssym;
723   int i;
724
725   /* get something we can spil */
726   ssym = selectSpil (ic, ebp, forSym);
727
728   /* mark it as spilt */
729   ssym->isspilt = 1;
730   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
731
732   /* mark it as not register assigned &
733      take it away from the set */
734   bitVectUnSetBit (_G.regAssigned, ssym->key);
735
736   /* mark the registers as free */
737   for (i = 0; i < ssym->nRegs; i++)
738     if (ssym->regs[i])
739       freeReg (ssym->regs[i]);
740
741   /* if this was a block level spil then insert push & pop 
742      at the start & end of block respectively */
743   if (ssym->blockSpil)
744     {
745       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
746       /* add push to the start of the block */
747       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
748                                     ebp->sch->next : ebp->sch));
749       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
750       /* add pop to the end of the block */
751       addiCodeToeBBlock (ebp, nic, NULL);
752     }
753
754   /* if spilt because not used in the remainder of the
755      block then add a push before this instruction and
756      a pop at the end of the block */
757   if (ssym->remainSpil)
758     {
759
760       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
761       /* add push just before this instruction */
762       addiCodeToeBBlock (ebp, nic, ic);
763
764       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
765       /* add pop to the end of the block */
766       addiCodeToeBBlock (ebp, nic, NULL);
767     }
768
769   if (ssym == forSym)
770     return FALSE;
771   else
772     return TRUE;
773 }
774
775 /*-----------------------------------------------------------------*/
776 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
777 /*-----------------------------------------------------------------*/
778 static regs *
779 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
780 {
781   regs *reg;
782
783 tryAgain:
784   /* try for a ptr type */
785   if ((reg = allocReg (REG_PTR)))
786     return reg;
787
788   /* try for gpr type */
789   if ((reg = allocReg (REG_GPR)))
790     return reg;
791
792   /* we have to spil */
793   if (!spilSomething (ic, ebp, sym))
794     return NULL;
795
796   /* this looks like an infinite loop but 
797      in really selectSpil will abort  */
798   goto tryAgain;
799 }
800
801 /*-----------------------------------------------------------------*/
802 /* getRegScr - will try for SCR if not a GPR type if not spil      */
803 /*-----------------------------------------------------------------*/
804 static regs *
805 getRegScr (iCode * ic, eBBlock * ebp, symbol * sym)
806 {
807   regs *reg;
808
809 tryAgain:
810   /* try for a ptr type */
811   if ((reg = allocReg (REG_SCR)))
812     return reg;
813
814   /* try for gpr type */
815   if ((reg = allocReg (REG_GPR)))
816     return reg;
817
818   /* we have to spil */
819   if (!spilSomething (ic, ebp, sym))
820     return NULL;
821
822   /* this looks like an infinite loop but 
823      in really selectSpil will abort  */
824   goto tryAgain;
825 }
826
827 /*-----------------------------------------------------------------*/
828 /* getRegGpr - will try for GPR if not spil                        */
829 /*-----------------------------------------------------------------*/
830 static regs *
831 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
832 {
833   regs *reg;
834
835 tryAgain:
836   /* try for gpr type */
837   if ((reg = allocReg (REG_GPR)))
838     return reg;
839
840   if (!avr_ptrRegReq)
841     if ((reg = allocReg (REG_PTR)))
842       return reg;
843
844   /* we have to spil */
845   if (!spilSomething (ic, ebp, sym))
846     return NULL;
847
848   /* this looks like an infinite loop but 
849      in reality selectSpil will abort  */
850   goto tryAgain;
851 }
852
853 /*-----------------------------------------------------------------*/
854 /* symHasReg - symbol has a given register                         */
855 /*-----------------------------------------------------------------*/
856 static bool
857 symHasReg (symbol * sym, regs * reg)
858 {
859   int i;
860
861   for (i = 0; i < sym->nRegs; i++)
862     if (sym->regs[i] == reg)
863       return TRUE;
864
865   return FALSE;
866 }
867
868 /*-----------------------------------------------------------------*/
869 /* deassignLRs - check the live to and if they have registers & are */
870 /*               not spilt then free up the registers              */
871 /*-----------------------------------------------------------------*/
872 static void
873 deassignLRs (iCode * ic, eBBlock * ebp)
874 {
875   symbol *sym;
876   int k;
877   symbol *result;
878
879   for (sym = hTabFirstItem (liveRanges, &k); sym;
880        sym = hTabNextItem (liveRanges, &k))
881     {
882
883       symbol *psym = NULL;
884       /* if it does not end here */
885       if (sym->liveTo > ic->seq)
886         continue;
887
888       /* if it was spilt on stack then we can 
889          mark the stack spil location as free */
890       if (sym->isspilt)
891         {
892           if (sym->stackSpil)
893             {
894               sym->usl.spillLoc->isFree = 1;
895               sym->stackSpil = 0;
896             }
897           continue;
898         }
899
900       if (!bitVectBitValue (_G.regAssigned, sym->key))
901         continue;
902
903       /* special case check if this is an IFX &
904          the privious one was a pop and the 
905          previous one was not spilt then keep track
906          of the symbol */
907       if (ic->op == IFX && ic->prev &&
908           ic->prev->op == IPOP &&
909           !ic->prev->parmPush &&
910           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
911         psym = OP_SYMBOL (IC_LEFT (ic->prev));
912
913       if (sym->nRegs)
914         {
915           int i = 0;
916
917           bitVectUnSetBit (_G.regAssigned, sym->key);
918
919           /* if the result of this one needs registers
920              and does not have it then assign it right
921              away */
922           if (IC_RESULT (ic) &&
923               !(SKIP_IC2 (ic) ||        /* not a special icode */
924                 ic->op == JUMPTABLE ||
925                 ic->op == IFX ||
926                 ic->op == IPUSH ||
927                 ic->op == IPOP ||
928                 ic->op == RETURN ||
929                 POINTER_SET (ic)) &&
930               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
931               result->liveTo > ic->seq &&       /* and will live beyond this */
932               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
933               result->regType == sym->regType &&        /* same register types */
934               result->nRegs &&  /* which needs registers */
935               !result->isspilt &&       /* and does not already have them */
936               !result->remat &&
937               !bitVectBitValue (_G.regAssigned, result->key) &&
938           /* the number of free regs + number of regs in this LR
939              can accomodate the what result Needs */
940               ((nfreeRegsType (result->regType) +
941                 sym->nRegs) >= result->nRegs)
942             )
943             {
944
945               for (i = 0; i < result->nRegs; i++)
946                 if (i < sym->nRegs)
947                   result->regs[i] = sym->regs[i];
948                 else if (result->regType == REG_SCR)
949                   result->regs[i] = getRegScr (ic, ebp, result);
950                 else
951                   result->regs[i] = getRegGpr (ic, ebp, result);
952
953               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
954
955             }
956
957           /* free the remaining */
958           for (; i < sym->nRegs; i++)
959             {
960               if (psym)
961                 {
962                   if (!symHasReg (psym, sym->regs[i]))
963                     freeReg (sym->regs[i]);
964                 }
965               else
966                 freeReg (sym->regs[i]);
967             }
968         }
969     }
970 }
971
972
973 /*-----------------------------------------------------------------*/
974 /* reassignLR - reassign this to registers                         */
975 /*-----------------------------------------------------------------*/
976 static void
977 reassignLR (operand * op)
978 {
979   symbol *sym = OP_SYMBOL (op);
980   int i;
981
982   /* not spilt any more */
983   sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
984   bitVectUnSetBit (_G.spiltSet, sym->key);
985
986   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
987
988   _G.blockSpil--;
989
990   for (i = 0; i < sym->nRegs; i++)
991     sym->regs[i]->isFree = 0;
992 }
993
994 /*-----------------------------------------------------------------*/
995 /* willCauseSpill - determines if allocating will cause a spill    */
996 /*-----------------------------------------------------------------*/
997 static int
998 willCauseSpill (int nr, int rt)
999 {
1000   /* first check if there are any avlb registers
1001      of te type required */
1002   if (rt == REG_PTR)
1003     {
1004       /* special case for pointer type 
1005          if pointer type not avlb then 
1006          check for type gpr */
1007       if (nFreeRegs (rt) >= nr)
1008         return 0;
1009       if (nFreeRegs (REG_GPR) >= nr)
1010         return 0;
1011     }
1012   else
1013     {
1014       if (avr_ptrRegReq)
1015         {
1016           if (nFreeRegs (rt) >= nr)
1017             return 0;
1018         }
1019       else
1020         {
1021           if (nFreeRegs (REG_PTR) +
1022               nFreeRegs (REG_GPR) >= nr)
1023             return 0;
1024         }
1025     }
1026
1027   /* it will cause a spil */
1028   return 1;
1029 }
1030
1031 /*-----------------------------------------------------------------*/
1032 /* positionRegs - the allocator can allocate same registers to res- */
1033 /* ult and operand, if this happens make sure they are in the same */
1034 /* position as the operand otherwise chaos results                 */
1035 /*-----------------------------------------------------------------*/
1036 static void
1037 positionRegs (symbol * result, symbol * opsym, int lineno)
1038 {
1039   int count = min (result->nRegs, opsym->nRegs);
1040   int i, j = 0, shared = 0;
1041
1042   /* if the result has been spilt then cannot share */
1043   if (opsym->isspilt)
1044     return;
1045 again:
1046   shared = 0;
1047   /* first make sure that they actually share */
1048   for (i = 0; i < count; i++)
1049     {
1050       for (j = 0; j < count; j++)
1051         {
1052           if (result->regs[i] == opsym->regs[j] && i != j)
1053             {
1054               shared = 1;
1055               goto xchgPositions;
1056             }
1057         }
1058     }
1059 xchgPositions:
1060   if (shared)
1061     {
1062       regs *tmp = result->regs[i];
1063       result->regs[i] = result->regs[j];
1064       result->regs[j] = tmp;
1065       goto again;
1066     }
1067 }
1068
1069 /*-----------------------------------------------------------------*/
1070 /* serialRegAssign - serially allocate registers to the variables  */
1071 /*-----------------------------------------------------------------*/
1072 static void
1073 serialRegAssign (eBBlock ** ebbs, int count)
1074 {
1075   int i;
1076
1077   /* for all blocks */
1078   for (i = 0; i < count; i++)
1079     {
1080
1081       iCode *ic;
1082
1083       if (ebbs[i]->noPath &&
1084           (ebbs[i]->entryLabel != entryLabel &&
1085            ebbs[i]->entryLabel != returnLabel))
1086         continue;
1087
1088       /* of all instructions do */
1089       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1090         {
1091
1092           /* if this is an ipop that means some live
1093              range will have to be assigned again */
1094           if (ic->op == IPOP)
1095             reassignLR (IC_LEFT (ic));
1096
1097           /* if result is present && is a true symbol */
1098           if (IC_RESULT (ic) && ic->op != IFX &&
1099               IS_TRUE_SYMOP (IC_RESULT (ic)))
1100             OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1101
1102           /* take away registers from live
1103              ranges that end at this instruction */
1104           deassignLRs (ic, ebbs[i]);
1105
1106           /* some don't need registers */
1107           if (SKIP_IC2 (ic) ||
1108               ic->op == JUMPTABLE ||
1109               ic->op == IFX ||
1110               ic->op == IPUSH ||
1111               ic->op == IPOP ||
1112               (IC_RESULT (ic) && POINTER_SET (ic)))
1113             continue;
1114
1115           /* now we need to allocate registers
1116              only for the result */
1117           if (IC_RESULT (ic))
1118             {
1119               symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1120               bitVect *spillable;
1121               int willCS;
1122               int j;
1123
1124               /* if it does not need or is spilt 
1125                  or is already assigned to registers
1126                  or will not live beyond this instructions */
1127               if (!sym->nRegs ||
1128                   sym->isspilt ||
1129                   bitVectBitValue (_G.regAssigned, sym->key) ||
1130                   sym->liveTo <= ic->seq)
1131                 continue;
1132
1133               /* if some liverange has been spilt at the block level
1134                  and this one live beyond this block then spil this
1135                  to be safe */
1136               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1137                 {
1138                   spillThis (sym);
1139                   continue;
1140                 }
1141               /* if trying to allocate this will cause
1142                  a spill and there is nothing to spill 
1143                  or this one is rematerializable then
1144                  spill this one */
1145               willCS = willCauseSpill (sym->nRegs, sym->regType);
1146               spillable = computeSpillable (ic);
1147               if (sym->remat ||
1148                   (willCS && bitVectIsZero (spillable)))
1149                 {
1150
1151                   spillThis (sym);
1152                   continue;
1153
1154                 }
1155
1156               /* if it has a spillocation & is used less than
1157                  all other live ranges then spill this */
1158               if (willCS && sym->usl.spillLoc)
1159                 {
1160
1161                   symbol *leastUsed =
1162                   leastUsedLR (liveRangesWith (spillable,
1163                                                allLRs,
1164                                                ebbs[i],
1165                                                ic));
1166                   if (leastUsed &&
1167                       leastUsed->used > sym->used)
1168                     {
1169                       spillThis (sym);
1170                       continue;
1171                     }
1172                 }
1173
1174               /* we assign registers to it */
1175               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1176
1177               for (j = 0; j < sym->nRegs; j++)
1178                 {
1179                   if (sym->regType == REG_PTR)
1180                     sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1181                   else if (sym->regType == REG_SCR)
1182                     sym->regs[j] = getRegScr (ic, ebbs[i], sym);
1183                   else
1184                     sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1185
1186                   /* if the allocation falied which means
1187                      this was spilt then break */
1188                   if (!sym->regs[j])
1189                     break;
1190                 }
1191               /* if it shares registers with operands make sure
1192                  that they are in the same position */
1193               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1194                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1195                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1196                               OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1197               /* do the same for the right operand */
1198               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1199                   OP_SYMBOL (IC_RIGHT (ic))->nRegs)
1200                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1201                               OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1202
1203             }
1204         }
1205     }
1206 }
1207
1208 /*-----------------------------------------------------------------*/
1209 /* rUmaskForOp :- returns register mask for an operand             */
1210 /*-----------------------------------------------------------------*/
1211 static bitVect *
1212 rUmaskForOp (operand * op)
1213 {
1214   bitVect *rumask;
1215   symbol *sym;
1216   int j;
1217
1218   /* only temporaries are assigned registers */
1219   if (!IS_ITEMP (op))
1220     return NULL;
1221
1222   sym = OP_SYMBOL (op);
1223
1224   /* if spilt or no registers assigned to it
1225      then nothing */
1226   if (sym->isspilt || !sym->nRegs)
1227     return NULL;
1228
1229   rumask = newBitVect (avr_nRegs);
1230
1231   for (j = 0; j < sym->nRegs; j++)
1232     {
1233       rumask = bitVectSetBit (rumask,
1234                               sym->regs[j]->rIdx);
1235     }
1236
1237   return rumask;
1238 }
1239
1240 /*-----------------------------------------------------------------*/
1241 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1242 /*-----------------------------------------------------------------*/
1243 static bitVect *
1244 regsUsedIniCode (iCode * ic)
1245 {
1246   bitVect *rmask = newBitVect (avr_nRegs);
1247
1248   /* do the special cases first */
1249   if (ic->op == IFX)
1250     {
1251       rmask = bitVectUnion (rmask,
1252                             rUmaskForOp (IC_COND (ic)));
1253       goto ret;
1254     }
1255
1256   /* for the jumptable */
1257   if (ic->op == JUMPTABLE)
1258     {
1259       rmask = bitVectUnion (rmask,
1260                             rUmaskForOp (IC_JTCOND (ic)));
1261
1262       goto ret;
1263     }
1264
1265   /* of all other cases */
1266   if (IC_LEFT (ic))
1267     rmask = bitVectUnion (rmask,
1268                           rUmaskForOp (IC_LEFT (ic)));
1269
1270
1271   if (IC_RIGHT (ic))
1272     rmask = bitVectUnion (rmask,
1273                           rUmaskForOp (IC_RIGHT (ic)));
1274
1275   if (IC_RESULT (ic))
1276     rmask = bitVectUnion (rmask,
1277                           rUmaskForOp (IC_RESULT (ic)));
1278
1279 ret:
1280   return rmask;
1281 }
1282
1283 /*-----------------------------------------------------------------*/
1284 /* createRegMask - for each instruction will determine the regsUsed */
1285 /*-----------------------------------------------------------------*/
1286 static void
1287 createRegMask (eBBlock ** ebbs, int count)
1288 {
1289   int i;
1290
1291   /* for all blocks */
1292   for (i = 0; i < count; i++)
1293     {
1294       iCode *ic;
1295
1296       if (ebbs[i]->noPath &&
1297           (ebbs[i]->entryLabel != entryLabel &&
1298            ebbs[i]->entryLabel != returnLabel))
1299         continue;
1300
1301       /* for all instructions */
1302       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1303         {
1304
1305           int j;
1306
1307           if (SKIP_IC2 (ic) || !ic->rlive)
1308             continue;
1309
1310           /* first mark the registers used in this
1311              instruction */
1312           ic->rUsed = regsUsedIniCode (ic);
1313           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1314
1315           /* now create the register mask for those 
1316              registers that are in use : this is a
1317              super set of ic->rUsed */
1318           ic->rMask = newBitVect (avr_nRegs + 1);
1319
1320           /* for all live Ranges alive at this point */
1321           for (j = 1; j < ic->rlive->size; j++)
1322             {
1323               symbol *sym;
1324               int k;
1325
1326               /* if not alive then continue */
1327               if (!bitVectBitValue (ic->rlive, j))
1328                 continue;
1329
1330               /* find the live range we are interested in */
1331               if (!(sym = hTabItemWithKey (liveRanges, j)))
1332                 {
1333                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1334                           "createRegMask cannot find live range");
1335                   exit (0);
1336                 }
1337
1338               /* if no register assigned to it */
1339               if (!sym->nRegs || sym->isspilt)
1340                 continue;
1341
1342               /* for all the registers allocated to it */
1343               for (k = 0; k < sym->nRegs; k++)
1344                 {
1345                   if (sym->regs[k])
1346                     {
1347                       ic->rMask =
1348                         bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1349                       /* special case for X & Z registers */
1350                       if (k == R26_IDX || k == R27_IDX)
1351                         ic->rMask = bitVectSetBit (ic->rMask, X_IDX);
1352                       if (k == R30_IDX || k == R31_IDX)
1353                         ic->rMask = bitVectSetBit (ic->rMask, Z_IDX);
1354                     }
1355                 }
1356             }
1357         }
1358     }
1359 }
1360
1361 /*-----------------------------------------------------------------*/
1362 /* rematStr - returns the rematerialized string for a remat var    */
1363 /*-----------------------------------------------------------------*/
1364 static char *
1365 rematStr (symbol * sym)
1366 {
1367   char *s = buffer;
1368   iCode *ic = sym->rematiCode;
1369
1370   while (1)
1371     {
1372
1373       /* if plus or minus print the right hand side */
1374       if (ic->op == '+' || ic->op == '-')
1375         {
1376           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1377                    ic->op);
1378           s += strlen (s);
1379           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1380           continue;
1381         }
1382
1383       /* we reached the end */
1384       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1385       break;
1386     }
1387
1388   return buffer;
1389 }
1390
1391 /*-----------------------------------------------------------------*/
1392 /* regTypeNum - computes the type & number of registers required   */
1393 /*-----------------------------------------------------------------*/
1394 static void
1395 regTypeNum ()
1396 {
1397   symbol *sym;
1398   int k;
1399   iCode *ic;
1400
1401   /* for each live range do */
1402   for (sym = hTabFirstItem (liveRanges, &k); sym;
1403        sym = hTabNextItem (liveRanges, &k))
1404     {
1405
1406       /* if used zero times then no registers needed */
1407       if ((sym->liveTo - sym->liveFrom) == 0)
1408         continue;
1409
1410
1411       /* if the live range is a temporary */
1412       if (sym->isitmp)
1413         {
1414
1415           /* if the type is marked as a conditional */
1416           if (sym->regType == REG_CND)
1417             continue;
1418
1419           /* if used in return only then we don't 
1420              need registers */
1421           if (sym->ruonly || sym->accuse)
1422             {
1423               if (IS_AGGREGATE (sym->type) || sym->isptr)
1424                 sym->type = aggrToPtr (sym->type, FALSE);
1425               continue;
1426             }
1427
1428           /* if the symbol has only one definition &
1429              that definition is a get_pointer and the
1430              pointer we are getting is rematerializable and
1431              in "data" space */
1432
1433           if (bitVectnBitsOn (sym->defs) == 1 &&
1434               (ic = hTabItemWithKey (iCodehTab,
1435                                      bitVectFirstBit (sym->defs))) &&
1436               POINTER_GET (ic) &&
1437               !IS_BITVAR (sym->etype))
1438             {
1439
1440               /* if in data space or idata space then try to
1441                  allocate pointer register */
1442
1443             }
1444
1445           /* if not then we require registers */
1446           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1447                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1448                         getSize (sym->type));
1449
1450           if (sym->nRegs > 4)
1451             {
1452               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1453               printTypeChain (sym->type, stderr);
1454               fprintf (stderr, "\n");
1455             }
1456
1457           /* determine the type of register required */
1458           if (sym->nRegs == 2 &&        /* size is two */
1459               IS_PTR (sym->type) &&     /* is a pointer */
1460               sym->uptr)
1461             {                   /* has pointer usage i.e. get/set pointer */
1462               sym->regType = REG_PTR;
1463               avr_ptrRegReq++;
1464             }
1465           else
1466             {
1467               /* live accross a function call then gpr else scratch */
1468               if (sym->isLiveFcall)
1469                 sym->regType = REG_GPR;
1470               else
1471                 sym->regType = REG_SCR;
1472             }
1473         }
1474       else
1475         /* for the first run we don't provide */
1476         /* registers for true symbols we will */
1477         /* see how things go                  */
1478         sym->nRegs = 0;
1479     }
1480
1481 }
1482
1483 /*-----------------------------------------------------------------*/
1484 /* deallocStackSpil - this will set the stack pointer back         */
1485 /*-----------------------------------------------------------------*/
1486 static
1487 DEFSETFUNC (deallocStackSpil)
1488 {
1489   symbol *sym = item;
1490
1491   deallocLocal (sym);
1492   return 0;
1493 }
1494
1495 /*-----------------------------------------------------------------*/
1496 /* farSpacePackable - returns the packable icode for far variables */
1497 /*-----------------------------------------------------------------*/
1498 static iCode *
1499 farSpacePackable (iCode * ic)
1500 {
1501   iCode *dic;
1502
1503   /* go thru till we find a definition for the
1504      symbol on the right */
1505   for (dic = ic->prev; dic; dic = dic->prev)
1506     {
1507
1508       /* if the definition is a call then no */
1509       if ((dic->op == CALL || dic->op == PCALL) &&
1510           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1511         {
1512           return NULL;
1513         }
1514
1515       /* if shift by unknown amount then not */
1516       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1517           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1518         return NULL;
1519
1520       /* if pointer get and size > 1 */
1521       if (POINTER_GET (dic) &&
1522           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1523         return NULL;
1524
1525       if (POINTER_SET (dic) &&
1526           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1527         return NULL;
1528
1529       /* if any three is a true symbol in far space */
1530       if (IC_RESULT (dic) &&
1531           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1532           isOperandInFarSpace (IC_RESULT (dic)))
1533         return NULL;
1534
1535       if (IC_RIGHT (dic) &&
1536           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1537           isOperandInFarSpace (IC_RIGHT (dic)) &&
1538           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1539         return NULL;
1540
1541       if (IC_LEFT (dic) &&
1542           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1543           isOperandInFarSpace (IC_LEFT (dic)) &&
1544           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1545         return NULL;
1546
1547       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1548         {
1549           if ((dic->op == LEFT_OP ||
1550                dic->op == RIGHT_OP ||
1551                dic->op == '-') &&
1552               IS_OP_LITERAL (IC_RIGHT (dic)))
1553             return NULL;
1554           else
1555             return dic;
1556         }
1557     }
1558
1559   return NULL;
1560 }
1561
1562 /*-----------------------------------------------------------------*/
1563 /* packRegsForAssign - register reduction for assignment           */
1564 /*-----------------------------------------------------------------*/
1565 static int
1566 packRegsForAssign (iCode * ic, eBBlock * ebp)
1567 {
1568   iCode *dic, *sic;
1569
1570   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1571       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1572       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1573     {
1574       return 0;
1575     }
1576
1577   /* find the definition of iTempNN scanning backwards if we find a 
1578      a use of the true symbol in before we find the definition then 
1579      we cannot */
1580   for (dic = ic->prev; dic; dic = dic->prev)
1581     {
1582
1583       /* if there is a function call and this is
1584          a parameter & not my parameter then don't pack it */
1585       if ((dic->op == CALL || dic->op == PCALL) &&
1586           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1587            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
1588         {
1589           dic = NULL;
1590           break;
1591         }
1592
1593       if (SKIP_IC2 (dic))
1594         continue;
1595
1596       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1597           IS_OP_VOLATILE (IC_RESULT (dic)))
1598         {
1599           dic = NULL;
1600           break;
1601         }
1602
1603       if (IS_SYMOP (IC_RESULT (dic)) &&
1604           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1605         {
1606           if (POINTER_SET (dic))
1607             dic = NULL;
1608
1609           break;
1610         }
1611
1612       if (IS_SYMOP (IC_RIGHT (dic)) &&
1613           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1614            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1615         {
1616           dic = NULL;
1617           break;
1618         }
1619
1620       if (IS_SYMOP (IC_LEFT (dic)) &&
1621           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1622            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1623         {
1624           dic = NULL;
1625           break;
1626         }
1627
1628       if (POINTER_SET (dic) &&
1629           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1630         {
1631           dic = NULL;
1632           break;
1633         }
1634     }
1635
1636   if (!dic)
1637     return 0;                   /* did not find */
1638
1639   /* if the result is on stack or iaccess then it must be
1640      the same atleast one of the operands */
1641   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1642       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1643     {
1644
1645       /* the operation has only one symbol
1646          operator then we can pack */
1647       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1648           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1649         goto pack;
1650
1651       if (!((IC_LEFT (dic) &&
1652              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1653             (IC_RIGHT (dic) &&
1654              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1655         return 0;
1656     }
1657 pack:
1658   /* if in far space & tru symbol then don't */
1659   if ((IS_TRUE_SYMOP (IC_RESULT (ic))) && isOperandInFarSpace (IC_RESULT (ic)))
1660     return 0;
1661   /* found the definition */
1662   /* replace the result with the result of */
1663   /* this assignment and remove this assignment */
1664   IC_RESULT (dic) = IC_RESULT (ic);
1665
1666   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1667     {
1668       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1669     }
1670   /* delete from liverange table also 
1671      delete from all the points inbetween and the new
1672      one */
1673   for (sic = dic; sic != ic; sic = sic->next)
1674     {
1675       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1676       if (IS_ITEMP (IC_RESULT (dic)))
1677         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1678     }
1679
1680   remiCodeFromeBBlock (ebp, ic);
1681   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1682   return 1;
1683
1684 }
1685
1686 /*-----------------------------------------------------------------*/
1687 /* findAssignToSym : scanning backwards looks for first assig found */
1688 /*-----------------------------------------------------------------*/
1689 static iCode *
1690 findAssignToSym (operand * op, iCode * ic)
1691 {
1692   iCode *dic;
1693
1694   for (dic = ic->prev; dic; dic = dic->prev)
1695     {
1696
1697       /* if definition by assignment */
1698       if (dic->op == '=' &&
1699           !POINTER_SET (dic) &&
1700           IC_RESULT (dic)->key == op->key
1701 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1702         )
1703         {
1704
1705           /* we are interested only if defined in far space */
1706           /* or in stack space in case of + & - */
1707
1708           /* if assigned to a non-symbol then return
1709              true */
1710           if (!IS_SYMOP (IC_RIGHT (dic)))
1711             break;
1712
1713           /* if the symbol is in far space then
1714              we should not */
1715           if (isOperandInFarSpace (IC_RIGHT (dic)))
1716             return NULL;
1717
1718           /* for + & - operations make sure that
1719              if it is on the stack it is the same
1720              as one of the three operands */
1721           if ((ic->op == '+' || ic->op == '-') &&
1722               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1723             {
1724
1725               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1726                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1727                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1728                 return NULL;
1729             }
1730
1731           break;
1732
1733         }
1734
1735       /* if we find an usage then we cannot delete it */
1736       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1737         return NULL;
1738
1739       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1740         return NULL;
1741
1742       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1743         return NULL;
1744     }
1745
1746   /* now make sure that the right side of dic
1747      is not defined between ic & dic */
1748   if (dic)
1749     {
1750       iCode *sic = dic->next;
1751
1752       for (; sic != ic; sic = sic->next)
1753         if (IC_RESULT (sic) &&
1754             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1755           return NULL;
1756     }
1757
1758   return dic;
1759
1760
1761 }
1762
1763 /*-----------------------------------------------------------------*/
1764 /* packRegsForSupport :- reduce some registers for support calls   */
1765 /*-----------------------------------------------------------------*/
1766 static int
1767 packRegsForSupport (iCode * ic, eBBlock * ebp)
1768 {
1769   int change = 0;
1770   /* for the left & right operand :- look to see if the
1771      left was assigned a true symbol in far space in that
1772      case replace them */
1773   if (IS_ITEMP (IC_LEFT (ic)) &&
1774       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1775     {
1776       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
1777       iCode *sic;
1778
1779       if (!dic)
1780         goto right;
1781
1782       /* found it we need to remove it from the
1783          block */
1784       for (sic = dic; sic != ic; sic = sic->next)
1785         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1786
1787       IC_LEFT (ic)->operand.symOperand =
1788         IC_RIGHT (dic)->operand.symOperand;
1789       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1790       remiCodeFromeBBlock (ebp, dic);
1791       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1792       change++;
1793     }
1794
1795   /* do the same for the right operand */
1796 right:
1797   if (!change &&
1798       IS_ITEMP (IC_RIGHT (ic)) &&
1799       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1800     {
1801       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1802       iCode *sic;
1803
1804       if (!dic)
1805         return change;
1806
1807       /* if this is a subtraction & the result
1808          is a true symbol in far space then don't pack */
1809       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1810         {
1811           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1812           if (IN_FARSPACE (SPEC_OCLS (etype)))
1813             return change;
1814         }
1815       /* found it we need to remove it from the
1816          block */
1817       for (sic = dic; sic != ic; sic = sic->next)
1818         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1819
1820       IC_RIGHT (ic)->operand.symOperand =
1821         IC_RIGHT (dic)->operand.symOperand;
1822       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1823
1824       remiCodeFromeBBlock (ebp, dic);
1825       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1826       change++;
1827     }
1828
1829   return change;
1830 }
1831
1832 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1833
1834
1835 /*-----------------------------------------------------------------*/
1836 /* packRegsForOneuse : - will reduce some registers for single Use */
1837 /*-----------------------------------------------------------------*/
1838 static iCode *
1839 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1840 {
1841   bitVect *uses;
1842   iCode *dic, *sic;
1843
1844   /* if returning a literal then do nothing */
1845   if (!IS_SYMOP (op))
1846     return NULL;
1847
1848   /* returns only */
1849   if (ic->op != RETURN)
1850     return NULL;
1851
1852   /* this routine will mark the a symbol as used in one 
1853      instruction use only && if the defintion is local 
1854      (ie. within the basic block) && has only one definition &&
1855      that definiion is either a return value from a 
1856      function or does not contain any variables in
1857      far space */
1858   uses = bitVectCopy (OP_USES (op));
1859   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1860   if (!bitVectIsZero (uses))    /* has other uses */
1861     return NULL;
1862
1863   /* if it has only one defintion */
1864   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1865     return NULL;                /* has more than one definition */
1866
1867   /* get the that definition */
1868   if (!(dic =
1869         hTabItemWithKey (iCodehTab,
1870                          bitVectFirstBit (OP_DEFS (op)))))
1871     return NULL;
1872
1873   /* found the definition now check if it is local */
1874   if (dic->seq < ebp->fSeq ||
1875       dic->seq > ebp->lSeq)
1876     return NULL;                /* non-local */
1877
1878   /* now check if it is the return from
1879      a function call */
1880   if (dic->op == CALL || dic->op == PCALL)
1881     {
1882       if (ic->op != SEND && ic->op != RETURN)
1883         {
1884           OP_SYMBOL (op)->ruonly = 1;
1885           return dic;
1886         }
1887       dic = dic->next;
1888     }
1889
1890
1891   /* otherwise check that the definition does
1892      not contain any symbols in far space */
1893   if (IS_OP_RUONLY (IC_LEFT (ic)) ||
1894       IS_OP_RUONLY (IC_RIGHT (ic)))
1895     {
1896       return NULL;
1897     }
1898
1899   /* if pointer set then make sure the pointer
1900      is one byte */
1901   if (POINTER_SET (dic) &&
1902       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1903     return NULL;
1904
1905   if (POINTER_GET (dic) &&
1906       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1907     return NULL;
1908
1909   sic = dic;
1910
1911   /* also make sure the intervenening instructions
1912      don't have any thing in far space */
1913   for (dic = dic->next; dic && dic != ic; dic = dic->next)
1914     {
1915
1916       /* if there is an intervening function call then no */
1917       if (dic->op == CALL || dic->op == PCALL)
1918         return NULL;
1919       /* if pointer set then make sure the pointer
1920          is one byte */
1921       if (POINTER_SET (dic) &&
1922           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1923         return NULL;
1924
1925       if (POINTER_GET (dic) &&
1926           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1927         return NULL;
1928
1929       /* if address of & the result is remat the okay */
1930       if (dic->op == ADDRESS_OF &&
1931           OP_SYMBOL (IC_RESULT (dic))->remat)
1932         continue;
1933
1934       /* if operand has size of three or more & this
1935          operation is a '*','/' or '%' then 'b' may
1936          cause a problem */
1937       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1938           getSize (operandType (op)) >= 3)
1939         return NULL;
1940
1941       /* if left or right or result is in far space */
1942       if (IS_OP_RUONLY (IC_LEFT (dic)) ||
1943           IS_OP_RUONLY (IC_RIGHT (dic)) ||
1944           IS_OP_RUONLY (IC_RESULT (dic)))
1945         {
1946           return NULL;
1947         }
1948     }
1949
1950   OP_SYMBOL (op)->ruonly = 1;
1951   return sic;
1952
1953 }
1954
1955 /*-----------------------------------------------------------------*/
1956 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
1957 /*-----------------------------------------------------------------*/
1958 static bool
1959 isBitwiseOptimizable (iCode * ic)
1960 {
1961   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1962   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1963
1964   /* bitwise operations are considered optimizable
1965      under the following conditions (Jean-Louis VERN) 
1966
1967      x & lit
1968      bit & bit
1969      bit & x
1970      bit ^ bit
1971      bit ^ x
1972      x   ^ lit
1973      x   | lit
1974      bit | bit
1975      bit | x
1976    */
1977   if (IS_LITERAL (rtype) ||
1978       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1979     return TRUE;
1980   else
1981     return FALSE;
1982 }
1983
1984 /*-----------------------------------------------------------------*/
1985 /* packForPush - hueristics to reduce iCode for pushing            */
1986 /*-----------------------------------------------------------------*/
1987 static void
1988 packForPush (iCode * ic, eBBlock * ebp)
1989 {
1990   iCode *dic;
1991
1992   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1993     return;
1994
1995   /* must have only definition & one usage */
1996   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1997       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1998     return;
1999
2000   /* find the definition */
2001   if (!(dic = hTabItemWithKey (iCodehTab,
2002                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2003     return;
2004
2005   if (dic->op != '=' || POINTER_SET (dic))
2006     return;
2007
2008   /* we now we know that it has one & only one def & use
2009      and the that the definition is an assignment */
2010   IC_LEFT (ic) = IC_RIGHT (dic);
2011
2012   remiCodeFromeBBlock (ebp, dic);
2013   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2014 }
2015
2016 /*-----------------------------------------------------------------*/
2017 /* packRegisters - does some transformations to reduce register    */
2018 /*                   pressure                                      */
2019 /*-----------------------------------------------------------------*/
2020 static void
2021 packRegisters (eBBlock * ebp)
2022 {
2023   iCode *ic;
2024   int change = 0;
2025
2026   while (1)
2027     {
2028
2029       change = 0;
2030
2031       /* look for assignments of the form */
2032       /* iTempNN = TRueSym (someoperation) SomeOperand */
2033       /*       ....                       */
2034       /* TrueSym := iTempNN:1             */
2035       for (ic = ebp->sch; ic; ic = ic->next)
2036         {
2037
2038
2039           /* find assignment of the form TrueSym := iTempNN:1 */
2040           if (ic->op == '=' && !POINTER_SET (ic))
2041             change += packRegsForAssign (ic, ebp);
2042         }
2043
2044       if (!change)
2045         break;
2046     }
2047
2048   for (ic = ebp->sch; ic; ic = ic->next)
2049     {
2050
2051       /* if this is an itemp & result of a address of a true sym 
2052          then mark this as rematerialisable   */
2053       if (ic->op == ADDRESS_OF &&
2054           IS_ITEMP (IC_RESULT (ic)) &&
2055           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2056           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2057           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2058         {
2059
2060           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2061           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2062           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2063
2064         }
2065
2066       /* if straight assignment then carry remat flag if
2067          this is the only definition */
2068       if (ic->op == '=' &&
2069           !POINTER_SET (ic) &&
2070           IS_SYMOP (IC_RIGHT (ic)) &&
2071           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2072           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2073         {
2074
2075           OP_SYMBOL (IC_RESULT (ic))->remat =
2076             OP_SYMBOL (IC_RIGHT (ic))->remat;
2077           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2078             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2079         }
2080
2081       /* if this is a +/- operation with a rematerizable 
2082          then mark this as rematerializable as well only
2083          if the literal value is within the range -255 and + 255
2084          the assembler cannot handle it other wise */
2085       if ((ic->op == '+' || ic->op == '-') &&
2086
2087           (IS_SYMOP (IC_LEFT (ic)) &&
2088            IS_ITEMP (IC_RESULT (ic)) &&
2089            OP_SYMBOL (IC_LEFT (ic))->remat &&
2090            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2091            IS_OP_LITERAL (IC_RIGHT (ic))))
2092         {
2093
2094           int i = (int) operandLitValue (IC_RIGHT (ic));
2095           if (i < 255 && i > -255)
2096             {
2097               OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2098               OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2099               OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2100             }
2101         }
2102
2103       /* mark the pointer usages */
2104       if (POINTER_SET (ic))
2105         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2106
2107       if (POINTER_GET (ic))
2108         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2109
2110       /* if the condition of an if instruction
2111          is defined in the previous instruction then
2112          mark the itemp as a conditional */
2113       if ((IS_CONDITIONAL (ic) ||
2114            ((ic->op == BITWISEAND ||
2115              ic->op == '|' ||
2116              ic->op == '^') &&
2117             isBitwiseOptimizable (ic))) &&
2118           ic->next && ic->next->op == IFX &&
2119           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2120           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2121         {
2122
2123           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2124           continue;
2125         }
2126
2127       /* some cases the redundant moves can
2128          can be eliminated for return statements */
2129       if ((ic->op == RETURN || ic->op == SEND))
2130         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2131
2132       /* if this is cast for intergral promotion then
2133          check if only use of  the definition of the 
2134          operand being casted/ if yes then replace
2135          the result of that arithmetic operation with 
2136          this result and get rid of the cast */
2137       if (ic->op == CAST)
2138         {
2139           sym_link *fromType = operandType (IC_RIGHT (ic));
2140           sym_link *toType = operandType (IC_LEFT (ic));
2141
2142           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2143               getSize (fromType) != getSize (toType) &&
2144               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2145             {
2146
2147               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2148               if (dic)
2149                 {
2150                   if (IS_ARITHMETIC_OP (dic))
2151                     {
2152                       IC_RESULT (dic) = IC_RESULT (ic);
2153                       remiCodeFromeBBlock (ebp, ic);
2154                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2155                       ic = ic->prev;
2156                     }
2157                   else
2158                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2159                 }
2160             }
2161           else
2162             {
2163
2164               /* if the type from and type to are the same
2165                  then if this is the only use then packit */
2166               if (checkType (operandType (IC_RIGHT (ic)),
2167                              operandType (IC_LEFT (ic))) == 1)
2168                 {
2169                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2170                   if (dic)
2171                     {
2172                       IC_RESULT (dic) = IC_RESULT (ic);
2173                       remiCodeFromeBBlock (ebp, ic);
2174                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2175                       ic = ic->prev;
2176                     }
2177                 }
2178             }
2179         }
2180     }
2181 }
2182
2183 /*-----------------------------------------------------------------*/
2184 /* preAssignParms - we have a leaf function preassign registers    */
2185 /*-----------------------------------------------------------------*/
2186 static void
2187 preAssignParms (iCode * ic)
2188 {
2189   int i = R16_IDX;
2190   /* look for receives and assign registers
2191      to the result of the receives */
2192   while (ic)
2193     {
2194       /* if it is a receive */
2195       if (ic->op == RECEIVE)
2196         {
2197           symbol *r = OP_SYMBOL (IC_RESULT (ic));
2198           int size = getSize (r->type);
2199           if (r->regType == REG_GPR || r->regType == REG_SCR)
2200             {
2201               int j = 0;
2202               while (size--)
2203                 {
2204                   r->regs[j++] = &regsAVR[i++];
2205                   regsAVR[i - 1].isFree = 0;
2206                 }
2207               /* put in the regassigned vector */
2208               _G.regAssigned = bitVectSetBit (_G.regAssigned, r->key);
2209             }
2210           else
2211             {
2212               /* not a GPR then we should mark as free */
2213               while (size--)
2214                 {
2215                   regsAVR[i++].isFree = 1;
2216                 }
2217             }
2218         }
2219       ic = ic->next;
2220     }
2221   /* mark anything remaining as free */
2222   while (i <= R23_IDX)
2223     regsAVR[i++].isFree = 1;
2224 }
2225
2226 /*-----------------------------------------------------------------*/
2227 /* setdefaultRegs - do setup stuff for register allocation         */
2228 /*-----------------------------------------------------------------*/
2229 static void
2230 setDefaultRegs (eBBlock ** ebbs, int count)
2231 {
2232   int i;
2233
2234   /* if no pointer registers required in this function
2235      then mark r26-27 & r30-r31 as GPR & free */
2236   regsAVR[R26_IDX].isFree =
2237     regsAVR[R27_IDX].isFree =
2238     regsAVR[R30_IDX].isFree =
2239     regsAVR[R31_IDX].isFree = 1;
2240
2241   if (!avr_ptrRegReq)
2242     {
2243       regsAVR[R26_IDX].type =
2244         regsAVR[R27_IDX].type =
2245         regsAVR[R30_IDX].type =
2246         regsAVR[R31_IDX].type = REG_GPR;
2247     }
2248   else
2249     {
2250       regsAVR[R26_IDX].type =
2251         regsAVR[R27_IDX].type =
2252         regsAVR[R30_IDX].type =
2253         regsAVR[R31_IDX].type = REG_PTR;
2254     }
2255
2256   /* registers 0-1 / 24-25 used as scratch */
2257   regsAVR[R0_IDX].isFree =
2258     regsAVR[R1_IDX].isFree =
2259     regsAVR[R24_IDX].isFree =
2260     regsAVR[R25_IDX].isFree = 0;
2261
2262   /* if this has no function calls then we need
2263      to do something special 
2264      a) pre-assign registers to parameters RECEIVE
2265      b) mark the remaining parameter regs as free */
2266   if (!currFunc->hasFcall)
2267     {
2268       /* mark the parameter regs as GPR */
2269       for (i = R16_IDX; i <= R23_IDX; i++)
2270         {
2271           regsAVR[i].type = REG_SCR;
2272           regsAVR[i].isFree = 1;
2273         }
2274       preAssignParms (ebbs[0]->sch);
2275     }
2276   else
2277     {
2278
2279       /* otherwise mark them as free scratch */
2280       for (i = R16_IDX; i <= R23_IDX; i++)
2281         {
2282           regsAVR[i].type = REG_SCR;
2283           regsAVR[i].isFree = 1;
2284         }
2285     }
2286
2287   /* Y - is not allocated (it is the stack frame) */
2288   regsAVR[R28_IDX].isFree =
2289     regsAVR[R28_IDX].isFree = 0;
2290 }
2291
2292 /*-----------------------------------------------------------------*/
2293 /* assignRegisters - assigns registers to each live range as need  */
2294 /*-----------------------------------------------------------------*/
2295 void
2296 avr_assignRegisters (eBBlock ** ebbs, int count)
2297 {
2298   iCode *ic;
2299   int i;
2300
2301   setToNull ((void *) &_G.funcrUsed);
2302   avr_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2303
2304   /* change assignments this will remove some
2305      live ranges reducing some register pressure */
2306   for (i = 0; i < count; i++)
2307     packRegisters (ebbs[i]);
2308
2309   if (options.dump_pack)
2310     dumpEbbsToFileExt (".dumppack", ebbs, count);
2311
2312   /* first determine for each live range the number of 
2313      registers & the type of registers required for each */
2314   regTypeNum ();
2315
2316   /* setup the default registers */
2317   setDefaultRegs (ebbs, count);
2318
2319   /* and serially allocate registers */
2320   serialRegAssign (ebbs, count);
2321
2322   /* if stack was extended then tell the user */
2323   if (_G.stackExtend)
2324     {
2325 /*      werror(W_TOOMANY_SPILS,"stack", */
2326 /*             _G.stackExtend,currFunc->name,""); */
2327       _G.stackExtend = 0;
2328     }
2329
2330   if (_G.dataExtend)
2331     {
2332 /*      werror(W_TOOMANY_SPILS,"data space", */
2333 /*             _G.dataExtend,currFunc->name,""); */
2334       _G.dataExtend = 0;
2335     }
2336
2337   /* after that create the register mask
2338      for each of the instruction */
2339   createRegMask (ebbs, count);
2340
2341   /* redo that offsets for stacked automatic variables */
2342   redoStackOffsets ();
2343
2344   if (options.dump_rassgn)
2345     dumpEbbsToFileExt (".dumprassgn", ebbs, count);
2346
2347   /* now get back the chain */
2348   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2349
2350
2351   genAVRCode (ic);
2352 /*     for (; ic ; ic = ic->next) */
2353 /*          piCode(ic,stdout); */
2354   /* free up any _G.stackSpil locations allocated */
2355   applyToSet (_G.stackSpil, deallocStackSpil);
2356   _G.slocNum = 0;
2357   setToNull ((void **) &_G.stackSpil);
2358   setToNull ((void **) &_G.spiltSet);
2359   /* mark all registers as free */
2360
2361   return;
2362 }