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