* src/SDCCicode.h,
[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                     !isiCodeInFunctionCall (ic) &&
905                     (selectS =
906                      liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) {
907                         sym = leastUsedLR (selectS);
908                         if (sym != forSym) {
909                                 if (!sym->remat) {
910                                         sym->remainSpil = 1;
911                                         _G.blockSpil++;
912                                 }
913                                 return sym;
914                         }
915                 }
916         }
917
918         /* find live ranges with spillocation && not used as pointers */
919         if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic))) {
920
921                 sym = leastUsedLR (selectS);
922                 /* mark this as allocation required */
923                 sym->usl.spillLoc->allocreq = 1;
924                 return sym;
925         }
926
927         /* find live ranges with spillocation */
928         if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic))) {
929
930                 sym = leastUsedLR (selectS);
931                 sym->usl.spillLoc->allocreq = 1;
932                 return sym;
933         }
934
935         /* couldn't find then we need to create a spil
936            location on the stack , for which one? the least
937            used ofcourse */
938         if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic))) {
939
940                 /* return a created spil location */
941                 sym = createStackSpil (leastUsedLR (selectS));
942                 sym->usl.spillLoc->allocreq = 1;
943                 return sym;
944         }
945
946         /* this is an extreme situation we will spill
947            this one : happens very rarely but it does happen */
948         spillThis (forSym);
949         return forSym;
950
951 }
952
953 /*-----------------------------------------------------------------*/
954 /* spilSomething - spil some variable & mark registers as free     */
955 /*-----------------------------------------------------------------*/
956 static bool
957 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
958 {
959         symbol *ssym;
960         int i;
961
962         /* get something we can spil */
963         ssym = selectSpil (ic, ebp, forSym);
964
965         /* mark it as spilt */
966         ssym->isspilt = 1;
967         _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
968
969         /* mark it as not register assigned &
970            take it away from the set */
971         bitVectUnSetBit (_G.regAssigned, ssym->key);
972
973         /* mark the registers as free */
974         for (i = 0; i < ssym->nRegs; i++)
975                 if (ssym->regs[i])
976                         freeReg (ssym->regs[i]);
977
978         /* if this was a block level spil then insert push & pop 
979            at the start & end of block respectively */
980         if (ssym->blockSpil) {
981                 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
982                 /* add push to the start of the block */
983                 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
984                                               ebp->sch->next : ebp->sch));
985                 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
986                 /* add pop to the end of the block */
987                 addiCodeToeBBlock (ebp, nic, NULL);
988         }
989
990         /* if spilt because not used in the remainder of the
991            block then add a push before this instruction and
992            a pop at the end of the block */
993         if (ssym->remainSpil) {
994
995                 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
996                 /* add push just before this instruction */
997                 addiCodeToeBBlock (ebp, nic, ic);
998
999                 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1000                 /* add pop to the end of the block */
1001                 addiCodeToeBBlock (ebp, nic, NULL);
1002         }
1003
1004         if (ssym == forSym)
1005                 return FALSE;
1006         else
1007                 return TRUE;
1008 }
1009
1010 /*-----------------------------------------------------------------*/
1011 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
1012 /*-----------------------------------------------------------------*/
1013 static regs *
1014 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1015 {
1016         regs *reg;
1017
1018       tryAgain:
1019         /* try for a ptr type */
1020         if ((reg = allocReg (REG_PTR|REG_PAIR)))
1021                 return reg;
1022
1023         /* try for gpr type / pair */
1024         if ((reg = allocReg (REG_GPR|REG_PAIR)))
1025                 return reg;
1026
1027         /* try for gpr type  */
1028         if ((reg = allocReg (REG_GPR)))
1029                 return reg;
1030
1031         /* we have to spil */
1032         if (!spilSomething (ic, ebp, sym))
1033                 return NULL;
1034
1035         /* this looks like an infinite loop but 
1036            in reality selectSpil will abort  */
1037         goto tryAgain;
1038 }
1039
1040 /*-----------------------------------------------------------------*/
1041 /* getRegScr - will try for SCR if not a GPR type if not spil      */
1042 /*-----------------------------------------------------------------*/
1043 static regs *
1044 getRegScr (iCode * ic, eBBlock * ebp, symbol * sym)
1045 {
1046         regs *reg;
1047
1048       tryAgain:
1049
1050         /* try for a scratch non-pair */        
1051         if ((reg = allocReg (REG_SCR)))
1052                 return reg;
1053                                 
1054         if ((reg = allocReg (REG_GPR)))
1055                 return reg;
1056
1057         /* we have to spil */
1058         if (!spilSomething (ic, ebp, sym))
1059                 return NULL;
1060
1061         /* this looks like an infinite loop but 
1062            in really selectSpil will abort  */
1063         goto tryAgain;
1064 }
1065
1066 /*-----------------------------------------------------------------*/
1067 /* getRegGpr - will try for GPR if not spil                        */
1068 /*-----------------------------------------------------------------*/
1069 static regs *
1070 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym )
1071 {
1072         regs *reg;
1073
1074       tryAgain:
1075         /* try for gpr type */
1076         if ((reg = allocReg (REG_GPR)))
1077                 return reg;
1078
1079         if (!avr_ptrRegReq)
1080                 if ((reg = allocReg (REG_PTR)))
1081                         return reg;
1082
1083         /* we have to spil */
1084         if (!spilSomething (ic, ebp, sym))
1085                 return NULL;
1086
1087         /* this looks like an infinite loop but 
1088            in reality selectSpil will abort  */
1089         goto tryAgain;
1090 }
1091
1092 /*-----------------------------------------------------------------*/
1093 /* symHasReg - symbol has a given register                         */
1094 /*-----------------------------------------------------------------*/
1095 static bool
1096 symHasReg (symbol * sym, regs * reg)
1097 {
1098         int i;
1099
1100         for (i = 0; i < sym->nRegs; i++)
1101                 if (sym->regs[i] == reg)
1102                         return TRUE;
1103
1104         return FALSE;
1105 }
1106
1107 /*-----------------------------------------------------------------*/
1108 /* deassignLRs - check the live to and if they have registers & are */
1109 /*               not spilt then free up the registers              */
1110 /*-----------------------------------------------------------------*/
1111 static void
1112 deassignLRs (iCode * ic, eBBlock * ebp)
1113 {
1114         symbol *sym;
1115         int k;
1116         symbol *result;
1117
1118         for (sym = hTabFirstItem (liveRanges, &k); sym;
1119              sym = hTabNextItem (liveRanges, &k)) {
1120
1121                 symbol *psym = NULL;
1122                 /* if it does not end here */
1123                 if (sym->liveTo > ic->seq)
1124                         continue;
1125
1126                 /* if it was spilt on stack then we can 
1127                    mark the stack spil location as free */
1128                 if (sym->isspilt) {
1129                         if (sym->stackSpil) {
1130                                 sym->usl.spillLoc->isFree = 1;
1131                                 sym->stackSpil = 0;
1132                         }
1133                         continue;
1134                 }
1135
1136                 if (!bitVectBitValue (_G.regAssigned, sym->key))
1137                         continue;
1138
1139                 /* special case check if this is an IFX &
1140                    the privious one was a pop and the 
1141                    previous one was not spilt then keep track
1142                    of the symbol */
1143                 if (ic->op == IFX && ic->prev &&
1144                     ic->prev->op == IPOP &&
1145                     !ic->prev->parmPush &&
1146                     !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1147                         psym = OP_SYMBOL (IC_LEFT (ic->prev));
1148
1149                 if (sym->nRegs) {
1150                         int i = 0;
1151
1152                         bitVectUnSetBit (_G.regAssigned, sym->key);
1153
1154                         /* if the result of this one needs registers
1155                            and does not have it then assign it right
1156                            away */
1157                         if (IC_RESULT (ic) && !(SKIP_IC2 (ic) ||        /* not a special icode */
1158                                                 ic->op == JUMPTABLE ||
1159                                                 ic->op == IFX ||
1160                                                 ic->op == IPUSH ||
1161                                                 ic->op == IPOP ||
1162                                                 ic->op == RETURN ||
1163                                                 POINTER_SET (ic)) &&
1164                             (result = OP_SYMBOL (IC_RESULT (ic))) &&    /* has a result */
1165                             result->liveTo > ic->seq && /* and will live beyond this */
1166                             result->liveTo <= ebp->lSeq &&      /* does not go beyond this block */
1167                             result->liveFrom == ic->seq &&    /* does not start before here */
1168                             result->regType == sym->regType &&  /* same register types */
1169                             result->nRegs &&    /* which needs registers */
1170                             !result->isspilt && /* and does not already have them */
1171                             !result->remat &&
1172                             !bitVectBitValue (_G.regAssigned, result->key) &&
1173                             /* the number of free regs + number of regs in this LR
1174                                can accomodate the what result Needs */
1175                             ((nfreeRegsType (result->regType) + sym->nRegs) >= result->nRegs)) {
1176
1177                                 for (i = 0; i < result->nRegs; i++) {
1178                                         if (i < sym->nRegs) 
1179                                                 result->regs[i] = sym->regs[i];
1180                                         else if (result->regType == REG_SCR) 
1181                                                 result->regs[i] = getRegScr (ic, ebp, result);
1182                                         else
1183                                                 result->regs[i] = getRegGpr (ic, ebp, result);
1184                                 }
1185                                 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1186
1187                         }
1188
1189                         /* free the remaining */
1190                         for (; i < sym->nRegs; i++) {
1191                                 if (psym) {
1192                                         if (!symHasReg (psym, sym->regs[i]))
1193                                                 freeReg (sym->regs[i]);
1194                                 }
1195                                 else freeReg (sym->regs[i]);
1196                         }
1197                 }
1198         }
1199 }
1200
1201
1202 /*-----------------------------------------------------------------*/
1203 /* reassignLR - reassign this to registers                         */
1204 /*-----------------------------------------------------------------*/
1205 static void
1206 reassignLR (operand * op)
1207 {
1208         symbol *sym = OP_SYMBOL (op);
1209         int i;
1210
1211         /* not spilt any more */
1212         sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1213         bitVectUnSetBit (_G.spiltSet, sym->key);
1214
1215         _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1216
1217         _G.blockSpil--;
1218
1219         for (i = 0; i < sym->nRegs; i++)
1220                 sym->regs[i]->isFree = 0;
1221 }
1222
1223 /*-----------------------------------------------------------------*/
1224 /* willCauseSpill - determines if allocating will cause a spill    */
1225 /*-----------------------------------------------------------------*/
1226 static int
1227 willCauseSpill (int nr, int rt)
1228 {
1229         /* first check if there are any avlb registers
1230            of te type required */
1231         if (rt == REG_PTR) {
1232                 /* special case for pointer type 
1233                    if pointer type not avlb then 
1234                    check for type gpr */
1235                 if (nFreeRegs (rt) >= nr)
1236                         return 0;
1237                 if (nFreeRegs (REG_GPR) >= nr)
1238                         return 0;
1239         }
1240         else {
1241                 if (avr_ptrRegReq) {
1242                         if (nFreeRegs (rt) >= nr)
1243                                 return 0;
1244                 }
1245                 else {
1246                         if (nFreeRegs (REG_PTR) + nFreeRegs (REG_GPR) >= nr)
1247                                 return 0;
1248                 }
1249         }
1250
1251         /* it will cause a spil */
1252         return 1;
1253 }
1254
1255 /*-----------------------------------------------------------------*/
1256 /* positionRegs - the allocator can allocate same registers to res- */
1257 /* ult and operand, if this happens make sure they are in the same */
1258 /* position as the operand otherwise chaos results                 */
1259 /*-----------------------------------------------------------------*/
1260 static void
1261 positionRegs (symbol * result, symbol * opsym, int lineno)
1262 {
1263         int count = min (result->nRegs, opsym->nRegs);
1264         int i, j = 0, shared = 0;
1265         
1266         /* if the result has been spilt then cannot share */
1267         if (opsym->isspilt)
1268                 return; 
1269  again:
1270         shared = 0;
1271         /* first make sure that they actually share */
1272         for (i = 0; i < count; i++) {
1273                 for (j = 0; j < count; j++) {
1274                         if (result->regs[i] == opsym->regs[j] && i != j) {
1275                                 shared = 1;
1276                                 goto xchgPositions;
1277                         }
1278                 }
1279         }
1280  xchgPositions:
1281         if (shared) {
1282                 regs *tmp = result->regs[i];
1283                 result->regs[i] = result->regs[j];
1284                 result->regs[j] = tmp;
1285                 goto again;
1286         }       
1287 }
1288
1289 /*-----------------------------------------------------------------*/
1290 /* needsPair - heuristic to determine if a pair would be good      */
1291 /*-----------------------------------------------------------------*/
1292 static int needsPair (iCode *ic)
1293 {
1294         symbol *sym = OP_SYMBOL(IC_RESULT(ic));
1295         bitVect *uses_defs = 
1296                 bitVectUnion(OP_USES (IC_RESULT(ic)),OP_DEFS(IC_RESULT(ic)));
1297         
1298         /* if size is less than 2 then NO */
1299         if (sym->nRegs < 2) return 0;
1300         /* if type Pointer then YES */
1301         if (IS_PTR(sym->type)) return 1;
1302         
1303         /* go thru the usages of this operand if used with 
1304            a constant then yes */
1305         while (!bitVectIsZero(uses_defs)) {
1306                 int ikey = bitVectFirstBit(uses_defs);
1307                 iCode *uic = hTabItemWithKey(iCodehTab,ikey);
1308                 sym_link *otype = NULL; 
1309                 bitVectUnSetBit(uses_defs,ikey);
1310                 if (!uic) continue;             
1311                 otype = (IC_RIGHT(uic) ? operandType(IC_RIGHT(uic)) : NULL);
1312                 if (otype && IS_LITERAL(otype)) return 1;
1313         }
1314         return 0;       
1315 }
1316
1317 /*-----------------------------------------------------------------*/
1318 /* serialRegAssign - serially allocate registers to the variables  */
1319 /*-----------------------------------------------------------------*/
1320 static void
1321 serialRegAssign (eBBlock ** ebbs, int count)
1322 {
1323         int i;
1324
1325         /* for all blocks */
1326         for (i = 0; i < count; i++) {
1327
1328                 iCode *ic;
1329
1330                 if (ebbs[i]->noPath &&
1331                     (ebbs[i]->entryLabel != entryLabel &&
1332                      ebbs[i]->entryLabel != returnLabel))
1333                         continue;
1334
1335                 /* of all instructions do */
1336                 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1337
1338                         /* if this is an ipop that means some live
1339                            range will have to be assigned again */
1340                         if (ic->op == IPOP)
1341                                 reassignLR (IC_LEFT (ic));
1342
1343                         /* if result is present && is a true symbol */
1344                         if (IC_RESULT (ic) && ic->op != IFX &&
1345                             IS_TRUE_SYMOP (IC_RESULT (ic)))
1346                                 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1347
1348                         /* take away registers from live
1349                            ranges that end at this instruction */
1350                         deassignLRs (ic, ebbs[i]);
1351
1352                         /* some don't need registers */
1353                         if (SKIP_IC2 (ic) ||
1354                             ic->op == JUMPTABLE ||
1355                             ic->op == IFX ||
1356                             ic->op == IPUSH ||
1357                             ic->op == IPOP ||
1358                             (IC_RESULT (ic) && POINTER_SET (ic))) continue;
1359
1360                         /* now we need to allocate registers
1361                            only for the result */
1362                         if (IC_RESULT (ic)) {
1363                                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1364                                 bitVect *spillable;
1365                                 int willCS;
1366                                 int j=0;
1367
1368                                 /* if it does not need or is spilt 
1369                                    or is already assigned to registers
1370                                    or will not live beyond this instructions */
1371                                 if (!sym->nRegs ||
1372                                     sym->isspilt ||
1373                                     bitVectBitValue (_G.regAssigned, sym->key)
1374                                     || sym->liveTo <= ic->seq)
1375                                         continue;
1376
1377                                 /* if some liverange has been spilt at the block level
1378                                    and this one live beyond this block then spil this
1379                                    to be safe */
1380                                 if (_G.blockSpil
1381                                     && sym->liveTo > ebbs[i]->lSeq) {
1382                                         spillThis (sym);
1383                                         continue;
1384                                 }
1385                                 /* if trying to allocate this will cause
1386                                    a spill and there is nothing to spill 
1387                                    or this one is rematerializable then
1388                                    spill this one */
1389                                 willCS =
1390                                         willCauseSpill (sym->nRegs,
1391                                                         sym->regType);
1392                                 spillable = computeSpillable (ic);
1393                                 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1394                                         spillThis (sym);
1395                                         continue;
1396                                 }
1397
1398                                 /* If the live range preceeds the point of definition 
1399                                    then ideally we must take into account registers that 
1400                                    have been allocated after sym->liveFrom but freed
1401                                    before ic->seq. This is complicated, so spill this
1402                                    symbol instead and let fillGaps handle the allocation. */
1403                                 if (sym->liveFrom < ic->seq)
1404                                 {
1405                                         spillThis (sym);
1406                                         continue;                     
1407                                 }
1408
1409                                 /* if it has a spillocation & is used less than
1410                                    all other live ranges then spill this */
1411                                 if (willCS) {
1412                                         if (sym->usl.spillLoc) {
1413                                                 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1414                                                                                                  allLRs, ebbs[i], ic));
1415                                                 if (leastUsed && leastUsed->used > sym->used) {
1416                                                         spillThis (sym);
1417                                                         continue;
1418                                                 }
1419                                         } else {
1420                                                 /* if none of the liveRanges have a spillLocation then better
1421                                                    to spill this one than anything else already assigned to registers */
1422                                                 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1423                                                         spillThis (sym);
1424                                                         continue;
1425                                                 }
1426                                         }
1427                                 }
1428
1429                                 /* we assign registers to it */
1430                                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1431                                 if (needsPair(ic)) {
1432                                         short regtype ;
1433                                         regs *preg;
1434                                         if (sym->regType == REG_PTR) regtype = REG_PTR;
1435                                         else if (sym->regType == REG_SCR) regtype = REG_SCR;
1436                                         else regtype = REG_GPR;
1437                                         preg = allocRegPair(regtype);
1438                                         if (preg) {
1439                                                 sym->regs[j++] = preg;
1440                                                 sym->regs[j++] = &regsAVR[preg->rIdx+1];
1441                                         }
1442                                 }
1443                                 for (; j < sym->nRegs; j++) {
1444                                         if (sym->regType == REG_PTR)
1445                                                 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1446                                         else if (sym->regType == REG_SCR)
1447                                                 sym->regs[j] = getRegScr (ic, ebbs[i], sym);
1448                                         else
1449                                                 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1450                                         /* if the allocation falied which means
1451                                            this was spilt then break */
1452                                         if (!sym->regs[j]) break;
1453                                 }
1454
1455                                 /* if it shares registers with operands make sure
1456                                    that they are in the same position */
1457                                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1458                                     OP_SYMBOL (IC_LEFT (ic))->nRegs
1459                                     && ic->op != '=')
1460                                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1461                                                       OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1462                                 /* do the same for the right operand */
1463                                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))
1464                                     && OP_SYMBOL (IC_RIGHT (ic))->nRegs)
1465                                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1466                                                       OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1467
1468                         }
1469                 }
1470         }
1471 }
1472
1473 /*-----------------------------------------------------------------*/
1474 /* rUmaskForOp :- returns register mask for an operand             */
1475 /*-----------------------------------------------------------------*/
1476 static bitVect *
1477 rUmaskForOp (operand * op)
1478 {
1479         bitVect *rumask;
1480         symbol *sym;
1481         int j;
1482
1483         /* only temporaries are assigned registers */
1484         if (!IS_ITEMP (op))
1485                 return NULL;
1486
1487         sym = OP_SYMBOL (op);
1488
1489         /* if spilt or no registers assigned to it
1490            then nothing */
1491         if (sym->isspilt || !sym->nRegs)
1492                 return NULL;
1493
1494         rumask = newBitVect (avr_nRegs);
1495
1496         for (j = 0; j < sym->nRegs; j++) {
1497                 rumask = bitVectSetBit (rumask, sym->regs[j]->rIdx);
1498         }
1499
1500         return rumask;
1501 }
1502
1503 /*-----------------------------------------------------------------*/
1504 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1505 /*-----------------------------------------------------------------*/
1506 static bitVect *
1507 regsUsedIniCode (iCode * ic)
1508 {
1509         bitVect *rmask = newBitVect (avr_nRegs);
1510
1511         /* do the special cases first */
1512         if (ic->op == IFX) {
1513                 rmask = bitVectUnion (rmask, rUmaskForOp (IC_COND (ic)));
1514                 goto ret;
1515         }
1516
1517         /* for the jumptable */
1518         if (ic->op == JUMPTABLE) {
1519                 rmask = bitVectUnion (rmask, rUmaskForOp (IC_JTCOND (ic)));
1520
1521                 goto ret;
1522         }
1523
1524         /* of all other cases */
1525         if (IC_LEFT (ic))
1526                 rmask = bitVectUnion (rmask, rUmaskForOp (IC_LEFT (ic)));
1527
1528
1529         if (IC_RIGHT (ic))
1530                 rmask = bitVectUnion (rmask, rUmaskForOp (IC_RIGHT (ic)));
1531
1532         if (IC_RESULT (ic))
1533                 rmask = bitVectUnion (rmask, rUmaskForOp (IC_RESULT (ic)));
1534
1535       ret:
1536         return rmask;
1537 }
1538
1539 /*-----------------------------------------------------------------*/
1540 /* createRegMask - for each instruction will determine the regsUsed */
1541 /*-----------------------------------------------------------------*/
1542 static void
1543 createRegMask (eBBlock ** ebbs, int count)
1544 {
1545         int i;
1546
1547         /* for all blocks */
1548         for (i = 0; i < count; i++) {
1549                 iCode *ic;
1550
1551                 if (ebbs[i]->noPath &&
1552                     (ebbs[i]->entryLabel != entryLabel &&
1553                      ebbs[i]->entryLabel != returnLabel))
1554                         continue;
1555
1556                 /* for all instructions */
1557                 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1558
1559                         int j;
1560
1561                         if (SKIP_IC2 (ic) || !ic->rlive)
1562                                 continue;
1563
1564                         /* first mark the registers used in this
1565                            instruction */
1566                         ic->rUsed = regsUsedIniCode (ic);
1567                         _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1568
1569                         /* now create the register mask for those 
1570                            registers that are in use : this is a
1571                            super set of ic->rUsed */
1572                         ic->rMask = newBitVect (avr_nRegs + 1);
1573
1574                         /* for all live Ranges alive at this point */
1575                         for (j = 1; j < ic->rlive->size; j++) {
1576                                 symbol *sym;
1577                                 int k;
1578
1579                                 /* if not alive then continue */
1580                                 if (!bitVectBitValue (ic->rlive, j))
1581                                         continue;
1582
1583                                 /* find the live range we are interested in */
1584                                 if (!(sym = hTabItemWithKey (liveRanges, j))) {
1585                                         werror (E_INTERNAL_ERROR, __FILE__,
1586                                                 __LINE__,
1587                                                 "createRegMask cannot find live range");
1588                                         exit (0);
1589                                 }
1590
1591                                 /* if no register assigned to it */
1592                                 if (!sym->nRegs || sym->isspilt)
1593                                         continue;
1594
1595                                 /* for all the registers allocated to it */
1596                                 for (k = 0; k < sym->nRegs; k++) {
1597                                         if (sym->regs[k]) {
1598                                                 int rIdx = sym->regs[k]->rIdx;
1599                                                 ic->rMask = bitVectSetBit (ic-> rMask,rIdx);
1600                                                 /* special case for X & Z registers */
1601                                                 if (rIdx == R26_IDX || rIdx == R27_IDX) 
1602                                                         ic->rMask = bitVectSetBit (ic->rMask, X_IDX);
1603                                                 if (rIdx == R30_IDX || rIdx == R31_IDX) 
1604                                                         ic->rMask = bitVectSetBit (ic->rMask, Z_IDX);
1605                                         }
1606                                 }
1607                         }
1608                 }
1609         }
1610 }
1611
1612
1613 /*-----------------------------------------------------------------*/
1614 /* regTypeNum - computes the type & number of registers required   */
1615 /*-----------------------------------------------------------------*/
1616 static void
1617 regTypeNum ()
1618 {
1619         symbol *sym;
1620         int k;
1621         iCode *ic;
1622
1623         /* for each live range do */
1624         for (sym = hTabFirstItem (liveRanges, &k); sym;
1625              sym = hTabNextItem (liveRanges, &k)) {
1626
1627                 /* if used zero times then no registers needed */
1628                 if ((sym->liveTo - sym->liveFrom) == 0)
1629                         continue;
1630
1631
1632                 /* if the live range is a temporary */
1633                 if (sym->isitmp) {
1634
1635                         /* if the type is marked as a conditional */
1636                         if (sym->regType == REG_CND)
1637                                 continue;
1638
1639                         /* if used in return only then we don't 
1640                            need registers */
1641                         if (sym->ruonly || sym->accuse) {
1642                                 if (IS_AGGREGATE (sym->type) || sym->isptr)
1643                                         sym->type =
1644                                                 aggrToPtr (sym->type, FALSE);
1645                                 continue;
1646                         }
1647
1648                         /* if the symbol has only one definition &
1649                            that definition is a get_pointer and the
1650                            pointer we are getting is rematerializable and
1651                            in "data" space */
1652
1653                         if (bitVectnBitsOn (sym->defs) == 1 &&
1654                             (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym-> defs)))
1655                             && POINTER_GET (ic) && !IS_BITVAR (sym->etype)) {
1656
1657                                 /* if in data space or idata space then try to
1658                                    allocate pointer register */
1659
1660                         }
1661
1662                         /* if not then we require registers */
1663                         sym->nRegs =
1664                                 ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1665                                  getSize (sym->type =
1666                                           aggrToPtr (sym->type,
1667                                                      FALSE)) : getSize (sym->
1668                                                                         type));
1669
1670                         if (sym->nRegs > 4) {
1671                                 fprintf (stderr,
1672                                          "allocated more than 4 or 0 registers for type ");
1673                                 printTypeChain (sym->type, stderr);
1674                                 fprintf (stderr, "\n");
1675                         }
1676
1677                         /* determine the type of register required */
1678                         if (sym->nRegs == 2 &&  /* size is two */
1679                             IS_PTR (sym->type) &&       /* is a pointer */
1680                             sym->uptr) {        /* has pointer usage i.e. get/set pointer */
1681                                 sym->regType = REG_PTR;
1682                                 avr_ptrRegReq++;
1683                         }
1684                         else {
1685                                 /* live accross a function call then gpr else scratch */
1686                                 if (sym->isLiveFcall)
1687                                         sym->regType = REG_GPR;
1688                                 else
1689                                         sym->regType = REG_SCR;
1690                         }
1691                 }
1692                 else
1693                         /* for the first run we don't provide */
1694                         /* registers for true symbols we will */
1695                         /* see how things go                  */
1696                         sym->nRegs = 0;
1697         }
1698
1699 }
1700
1701 /*-----------------------------------------------------------------*/
1702 /* deallocStackSpil - this will set the stack pointer back         */
1703 /*-----------------------------------------------------------------*/
1704 static
1705 DEFSETFUNC (deallocStackSpil)
1706 {
1707         symbol *sym = item;
1708
1709         deallocLocal (sym);
1710         return 0;
1711 }
1712
1713 /*-----------------------------------------------------------------*/
1714 /* packRegsForAssign - register reduction for assignment           */
1715 /*-----------------------------------------------------------------*/
1716 static int
1717 packRegsForAssign (iCode * ic, eBBlock * ebp)
1718 {
1719         iCode *dic, *sic;
1720
1721         if (!IS_ITEMP (IC_RIGHT (ic)) ||
1722             OP_SYMBOL (IC_RIGHT (ic))->isind ||
1723             OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1724                 return 0;
1725         }
1726
1727         /* find the definition of iTempNN scanning backwards if we find a 
1728            a use of the true symbol in before we find the definition then 
1729            we cannot */
1730         for (dic = ic->prev; dic; dic = dic->prev) {
1731
1732                 /* if there is a function call and this is
1733                    a parameter & not my parameter then don't pack it */
1734                 if ((dic->op == CALL || dic->op == PCALL) &&
1735                     (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1736                      !OP_SYMBOL (IC_RESULT (ic))->ismyparm)) {
1737                         dic = NULL;
1738                         break;
1739                 }
1740
1741                 if (SKIP_IC2 (dic))
1742                         continue;
1743
1744                 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1745                     IS_OP_VOLATILE (IC_RESULT (dic))) {
1746                         dic = NULL;
1747                         break;
1748                 }
1749
1750                 if (IS_SYMOP (IC_RESULT (dic)) &&
1751                     IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1752                         if (POINTER_SET (dic))
1753                                 dic = NULL;
1754
1755                         break;
1756                 }
1757
1758                 if (IS_SYMOP (IC_RIGHT (dic)) &&
1759                     (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1760                      IC_RIGHT (dic)->key == IC_RIGHT (ic)->key)) {
1761                         dic = NULL;
1762                         break;
1763                 }
1764
1765                 if (IS_SYMOP (IC_LEFT (dic)) &&
1766                     (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1767                      IC_LEFT (dic)->key == IC_RIGHT (ic)->key)) {
1768                         dic = NULL;
1769                         break;
1770                 }
1771
1772                 if (POINTER_SET (dic) &&
1773                     IC_RESULT (dic)->key == IC_RESULT (ic)->key) {
1774                         dic = NULL;
1775                         break;
1776                 }
1777         }
1778
1779         if (!dic)
1780                 return 0;       /* did not find */
1781
1782         /* if the result is on stack or iaccess then it must be
1783            the same atleast one of the operands */
1784         if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1785             OP_SYMBOL (IC_RESULT (ic))->iaccess) {
1786
1787                 /* the operation has only one symbol
1788                    operator then we can pack */
1789                 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1790                     (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1791                         goto pack;
1792
1793                 if (!((IC_LEFT (dic) &&
1794                        IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1795                       (IC_RIGHT (dic) &&
1796                        IC_RESULT (ic)->key == IC_RIGHT (dic)->key))) return 0;
1797         }
1798       pack:
1799         /* if in far space & tru symbol then don't */
1800         if ((IS_TRUE_SYMOP (IC_RESULT (ic)))
1801             && isOperandInFarSpace (IC_RESULT (ic))) return 0;
1802         /* found the definition */
1803         /* replace the result with the result of */
1804         /* this assignment and remove this assignment */
1805         IC_RESULT (dic) = IC_RESULT (ic);
1806
1807         if (IS_ITEMP (IC_RESULT (dic))
1808             && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) {
1809                 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1810         }
1811         /* delete from liverange table also 
1812            delete from all the points inbetween and the new
1813            one */
1814         for (sic = dic; sic != ic; sic = sic->next) {
1815                 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1816                 if (IS_ITEMP (IC_RESULT (dic)))
1817                         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1818         }
1819
1820         remiCodeFromeBBlock (ebp, ic);
1821         hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1822         return 1;
1823
1824 }
1825
1826 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1827
1828
1829 /*-----------------------------------------------------------------*/
1830 /* packRegsForOneuse : - will reduce some registers for single Use */
1831 /*-----------------------------------------------------------------*/
1832 static iCode *
1833 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1834 {
1835         bitVect *uses;
1836         iCode *dic, *sic;
1837
1838         /* if returning a literal then do nothing */
1839         if (!IS_SYMOP (op))
1840                 return NULL;
1841
1842         /* returns only */
1843         if (ic->op != RETURN)
1844                 return NULL;
1845
1846         /* this routine will mark the a symbol as used in one 
1847            instruction use only && if the defintion is local 
1848            (ie. within the basic block) && has only one definition &&
1849            that definiion is either a return value from a 
1850            function or does not contain any variables in
1851            far space */
1852         uses = bitVectCopy (OP_USES (op));
1853         bitVectUnSetBit (uses, ic->key);        /* take away this iCode */
1854         if (!bitVectIsZero (uses))      /* has other uses */
1855                 return NULL;
1856
1857         /* if it has only one defintion */
1858         if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1859                 return NULL;    /* has more than one definition */
1860
1861         /* get the that definition */
1862         if (!(dic =
1863               hTabItemWithKey (iCodehTab,
1864                                bitVectFirstBit (OP_DEFS (op))))) return NULL;
1865
1866         /* found the definition now check if it is local */
1867         if (dic->seq < ebp->fSeq || dic->seq > ebp->lSeq)
1868                 return NULL;    /* non-local */
1869
1870         /* now check if it is the return from
1871            a function call */
1872         if (dic->op == CALL || dic->op == PCALL) {
1873                 if (ic->op != SEND && ic->op != RETURN &&
1874                     !POINTER_SET(ic) && !POINTER_GET(ic)) {
1875                         OP_SYMBOL (op)->ruonly = 1;
1876                         return dic;
1877                 }
1878                 dic = dic->next;
1879         }
1880
1881
1882         /* otherwise check that the definition does
1883            not contain any symbols in far space */
1884         if (IS_OP_RUONLY (IC_LEFT (ic)) || IS_OP_RUONLY (IC_RIGHT (ic))) {
1885                 return NULL;
1886         }
1887
1888         /* if pointer set then make sure the pointer
1889            is one byte */
1890         if (POINTER_SET (dic) &&
1891             !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1892                 return NULL;
1893
1894         if (POINTER_GET (dic) &&
1895             !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1896                 return NULL;
1897
1898         sic = dic;
1899
1900         /* also make sure the intervenening instructions
1901            don't have any thing in far space */
1902         for (dic = dic->next; dic && dic != ic; dic = dic->next) {
1903
1904                 /* if there is an intervening function call then no */
1905                 if (dic->op == CALL || dic->op == PCALL)
1906                         return NULL;
1907                 /* if pointer set then make sure the pointer
1908                    is one byte */
1909                 if (POINTER_SET (dic) &&
1910                     !IS_DATA_PTR (aggrToPtr
1911                                   (operandType (IC_RESULT (dic)),
1912                                    FALSE))) return NULL;
1913
1914                 if (POINTER_GET (dic) &&
1915                     !IS_DATA_PTR (aggrToPtr
1916                                   (operandType (IC_LEFT (dic)),
1917                                    FALSE))) return NULL;
1918
1919                 /* if address of & the result is remat the okay */
1920                 if (dic->op == ADDRESS_OF &&
1921                     OP_SYMBOL (IC_RESULT (dic))->remat) continue;
1922
1923                 /* if operand has size of three or more & this
1924                    operation is a '*','/' or '%' then 'b' may
1925                    cause a problem */
1926                 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1927                     getSize (operandType (op)) >= 3)
1928                         return NULL;
1929
1930                 /* if left or right or result is in far space */
1931                 if (IS_OP_RUONLY (IC_LEFT (dic)) ||
1932                     IS_OP_RUONLY (IC_RIGHT (dic)) ||
1933                     IS_OP_RUONLY (IC_RESULT (dic))) {
1934                         return NULL;
1935                 }
1936         }
1937
1938         OP_SYMBOL (op)->ruonly = 1;
1939         return sic;
1940
1941 }
1942
1943 /*-----------------------------------------------------------------*/
1944 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
1945 /*-----------------------------------------------------------------*/
1946 static bool
1947 isBitwiseOptimizable (iCode * ic)
1948 {
1949         sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1950         sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1951
1952         /* bitwise operations are considered optimizable
1953            under the following conditions (Jean-Louis VERN) 
1954
1955            x & lit
1956            bit & bit
1957            bit & x
1958            bit ^ bit
1959            bit ^ x
1960            x   ^ lit
1961            x   | lit
1962            bit | bit
1963            bit | x
1964          */
1965         if (IS_LITERAL (rtype) ||
1966             (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1967                         return TRUE;
1968         else
1969                 return FALSE;
1970 }
1971
1972 /*-----------------------------------------------------------------*/
1973 /* packRegisters - does some transformations to reduce register    */
1974 /*                   pressure                                      */
1975 /*-----------------------------------------------------------------*/
1976 static void
1977 packRegisters (eBBlock * ebp)
1978 {
1979         iCode *ic;
1980         int change = 0;
1981
1982         while (1) {
1983
1984                 change = 0;
1985
1986                 /* look for assignments of the form */
1987                 /* iTempNN = TRueSym (someoperation) SomeOperand */
1988                 /*       ....                       */
1989                 /* TrueSym := iTempNN:1             */
1990                 for (ic = ebp->sch; ic; ic = ic->next) {
1991
1992
1993                         /* find assignment of the form TrueSym := iTempNN:1 */
1994                         if (ic->op == '=' && !POINTER_SET (ic))
1995                                 change += packRegsForAssign (ic, ebp);
1996                 }
1997
1998                 if (!change)
1999                         break;
2000         }
2001
2002         for (ic = ebp->sch; ic; ic = ic->next) {
2003
2004                 /* if this is an itemp & result of a address of a true sym 
2005                    then mark this as rematerialisable   */
2006                 if (ic->op == ADDRESS_OF &&
2007                     IS_ITEMP (IC_RESULT (ic)) &&
2008                     IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2009                     bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2010                     !OP_SYMBOL (IC_LEFT (ic))->onStack) {
2011
2012                         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2013                         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2014                         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2015
2016                 }
2017
2018                 /* if straight assignment then carry remat flag if
2019                    this is the only definition */
2020                 if (ic->op == '=' &&
2021                     !POINTER_SET (ic) &&
2022                     IS_SYMOP (IC_RIGHT (ic)) &&
2023                     OP_SYMBOL (IC_RIGHT (ic))->remat &&
2024                     bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1) {
2025
2026                         OP_SYMBOL (IC_RESULT (ic))->remat =
2027                                 OP_SYMBOL (IC_RIGHT (ic))->remat;
2028                         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2029                                 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2030                 }
2031
2032                 /* if this is a +/- operation with a rematerizable 
2033                    then mark this as rematerializable as well only
2034                    if the literal value is within the range -255 and + 255
2035                    the assembler cannot handle it other wise */
2036                 if ((ic->op == '+' || ic->op == '-') &&
2037                     (IS_SYMOP (IC_LEFT (ic)) &&
2038                      IS_ITEMP (IC_RESULT (ic)) &&
2039                      OP_SYMBOL (IC_LEFT (ic))->remat &&
2040                      bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2041                      IS_OP_LITERAL (IC_RIGHT (ic)))) {
2042
2043                         int i = (int) operandLitValue (IC_RIGHT (ic));
2044                         if (i < 255 && i > -255) {
2045                                 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2046                                 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2047                                 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc =
2048                                         NULL;
2049                         }
2050                 }
2051
2052                 /* mark the pointer usages */
2053                 if (POINTER_SET (ic))
2054                         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2055
2056                 if (POINTER_GET (ic)) {
2057                         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2058                         if (OP_SYMBOL (IC_LEFT(ic))->remat) 
2059                                 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2060                 }
2061
2062                 /* if the condition of an if instruction
2063                    is defined in the previous instruction then
2064                    mark the itemp as a conditional */
2065                 if ((IS_CONDITIONAL (ic) ||
2066                      ((ic->op == BITWISEAND ||
2067                        ic->op == '|' ||
2068                        ic->op == '^') &&
2069                       isBitwiseOptimizable (ic))) &&
2070                     ic->next && ic->next->op == IFX &&
2071                     isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2072                     OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) {
2073
2074                         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2075                         continue;
2076                 }
2077
2078                 /* some cases the redundant moves can
2079                    can be eliminated for return statements */
2080                 if ((ic->op == RETURN || ic->op == SEND))
2081                         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2082
2083                 /* if this is cast for intergral promotion then
2084                    check if only use of  the definition of the 
2085                    operand being casted/ if yes then replace
2086                    the result of that arithmetic operation with 
2087                    this result and get rid of the cast */
2088                 if (ic->op == CAST) {
2089                         sym_link *fromType = operandType (IC_RIGHT (ic));
2090                         sym_link *toType = operandType (IC_LEFT (ic));
2091
2092                         if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2093                             getSize (fromType) != getSize (toType) &&
2094                             SPEC_USIGN (fromType) == SPEC_USIGN (toType)) {
2095
2096                                 iCode *dic =
2097                                         packRegsForOneuse (ic, IC_RIGHT (ic),
2098                                                            ebp);
2099                                 if (dic) {
2100                                         if (IS_ARITHMETIC_OP (dic)) {
2101                                                 IC_RESULT (dic) =
2102                                                         IC_RESULT (ic);
2103                                                 remiCodeFromeBBlock (ebp, ic);
2104                                                 hTabDeleteItem (&iCodehTab,
2105                                                                 ic->key, ic,
2106                                                                 DELETE_ITEM,
2107                                                                 NULL);
2108                                                 ic = ic->prev;
2109                                         }
2110                                         else
2111                                                 OP_SYMBOL (IC_RIGHT (ic))->
2112                                                         ruonly = 0;
2113                                 }
2114                         }
2115                         else {
2116
2117                                 /* if the type from and type to are the same
2118                                    then if this is the only use then packit */
2119                                 if (compareType (operandType (IC_RIGHT (ic)),
2120                                                operandType (IC_LEFT (ic))) ==
2121                                     1) {
2122                                         iCode *dic =
2123                                                 packRegsForOneuse (ic,
2124                                                                    IC_RIGHT
2125                                                                    (ic), ebp);
2126                                         if (dic) {
2127                                                 IC_RESULT (dic) =
2128                                                         IC_RESULT (ic);
2129                                                 remiCodeFromeBBlock (ebp, ic);
2130                                                 hTabDeleteItem (&iCodehTab,
2131                                                                 ic->key, ic,
2132                                                                 DELETE_ITEM,
2133                                                                 NULL);
2134                                                 ic = ic->prev;
2135                                         }
2136                                 }
2137                         }
2138                 }
2139         }
2140 }
2141
2142 /*-----------------------------------------------------------------*/
2143 /* preAssignParms - we have a leaf function preassign registers    */
2144 /*-----------------------------------------------------------------*/
2145 static void
2146 preAssignParms (iCode * ic)
2147 {
2148         int i = R16_IDX;
2149         /* look for receives and assign registers
2150            to the result of the receives */
2151         while (ic) {
2152                 /* if it is a receive */
2153                 if (ic->op == RECEIVE) {
2154                         symbol *r = OP_SYMBOL (IC_RESULT (ic));
2155                         int size = getSize (r->type);
2156                         if (r->regType == REG_GPR || r->regType == REG_SCR) {
2157                                 int j = 0;
2158                                 while (size--) {
2159                                         r->regs[j++] = &regsAVR[i++];
2160                                         regsAVR[i - 1].isFree = 0;
2161                                 }
2162                                 /* put in the regassigned vector */
2163                                 _G.regAssigned =
2164                                         bitVectSetBit (_G.regAssigned,
2165                                                        r->key);
2166                         }
2167                         else {
2168                                 /* not a GPR then we should mark as free */
2169                                 while (size--) {
2170                                         regsAVR[i++].isFree = 1;
2171                                 }
2172                         }
2173                 }
2174                 ic = ic->next;
2175         }
2176         /* mark anything remaining as free */
2177         while (i <= R23_IDX)
2178                 regsAVR[i++].isFree = 1;
2179 }
2180
2181 /*-----------------------------------------------------------------*/
2182 /* setdefaultRegs - do setup stuff for register allocation         */
2183 /*-----------------------------------------------------------------*/
2184 static void
2185 setDefaultRegs (eBBlock ** ebbs, int count)
2186 {
2187         int i;
2188
2189         /* if no pointer registers required in this function
2190            then mark r26-27 & r30-r31 as GPR & free */
2191         regsAVR[R26_IDX].isFree =
2192                 regsAVR[R27_IDX].isFree =
2193                 regsAVR[R30_IDX].isFree = regsAVR[R31_IDX].isFree = 1;
2194
2195         if (!avr_ptrRegReq) {
2196                 regsAVR[R26_IDX].type = (regsAVR[R26_IDX].type & ~REG_MASK) | REG_GPR;
2197                 regsAVR[R27_IDX].type = (regsAVR[R27_IDX].type & ~REG_MASK) | REG_GPR;
2198                 regsAVR[R28_IDX].type = (regsAVR[R28_IDX].type & ~REG_MASK) | REG_GPR;
2199                 regsAVR[R29_IDX].type = (regsAVR[R29_IDX].type & ~REG_MASK) | REG_GPR;
2200         }
2201         else {
2202                 regsAVR[R26_IDX].type = (regsAVR[R26_IDX].type & ~REG_MASK) | REG_PTR;
2203                 regsAVR[R27_IDX].type = (regsAVR[R27_IDX].type & ~REG_MASK) | REG_PTR;
2204                 regsAVR[R30_IDX].type = (regsAVR[R30_IDX].type & ~REG_MASK) | REG_PTR;
2205                 regsAVR[R31_IDX].type = (regsAVR[R31_IDX].type & ~REG_MASK) | REG_PTR;
2206         }
2207
2208         /* registers 0-1 / 24-25 used as scratch */
2209         regsAVR[R0_IDX].isFree =
2210                 regsAVR[R1_IDX].isFree =
2211                 regsAVR[R24_IDX].isFree = regsAVR[R25_IDX].isFree = 0;
2212
2213         /* if this has no function calls then we need
2214            to do something special 
2215            a) pre-assign registers to parameters RECEIVE
2216            b) mark the remaining parameter regs as free */
2217                 /* mark the parameter regs as SCRACH */
2218         for (i = R16_IDX; i <= R23_IDX; i++) {
2219                 regsAVR[i].type = (regsAVR[i].type & ~REG_MASK) | REG_SCR;
2220                 regsAVR[i].isFree = 1;
2221         }
2222         if (!IFFUNC_HASFCALL(currFunc->type)) {
2223                 preAssignParms (ebbs[0]->sch);
2224         }
2225         /* Y - is not allocated (it is the stack frame) */
2226         regsAVR[R28_IDX].isFree = regsAVR[R28_IDX].isFree = 0;
2227 }
2228
2229 /*-----------------------------------------------------------------*/
2230 /* assignRegisters - assigns registers to each live range as need  */
2231 /*-----------------------------------------------------------------*/
2232 void
2233 avr_assignRegisters (eBBlock ** ebbs, int count)
2234 {
2235         iCode *ic;
2236         int i;
2237
2238         setToNull ((void *) &_G.funcrUsed);
2239         avr_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2240
2241         /* change assignments this will remove some
2242            live ranges reducing some register pressure */
2243         for (i = 0; i < count; i++)
2244                 packRegisters (ebbs[i]);
2245
2246         /* liveranges probably changed by register packing
2247            so we compute them again */
2248         recomputeLiveRanges (ebbs, count);
2249
2250         if (options.dump_pack)
2251                 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2252
2253         /* first determine for each live range the number of 
2254            registers & the type of registers required for each */
2255         regTypeNum ();
2256
2257         /* setup the default registers */
2258         setDefaultRegs (ebbs, count);
2259
2260         /* and serially allocate registers */
2261         serialRegAssign (ebbs, count);
2262
2263         /* if stack was extended then tell the user */
2264         if (_G.stackExtend) {
2265                 /*      werror(W_TOOMANY_SPILS,"stack", */
2266                 /*             _G.stackExtend,currFunc->name,""); */
2267                 _G.stackExtend = 0;
2268         }
2269
2270         if (_G.dataExtend) {
2271                 /*      werror(W_TOOMANY_SPILS,"data space", */
2272                 /*             _G.dataExtend,currFunc->name,""); */
2273                 _G.dataExtend = 0;
2274         }
2275
2276         /* after that create the register mask
2277            for each of the instruction */
2278         createRegMask (ebbs, count);
2279
2280         /* redo that offsets for stacked automatic variables */
2281         redoStackOffsets ();
2282
2283         if (options.dump_rassgn)
2284                 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2285
2286         /* now get back the chain */
2287         ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2288
2289
2290         genAVRCode (ic);
2291         /*     for (; ic ; ic = ic->next) */
2292         /*          piCode(ic,stdout); */
2293         /* free up any _G.stackSpil locations allocated */
2294         applyToSet (_G.stackSpil, deallocStackSpil);
2295         _G.slocNum = 0;
2296         setToNull ((void *) &_G.stackSpil);
2297         setToNull ((void *) &_G.spiltSet);
2298         /* mark all registers as free */
2299
2300         return;
2301 }