2006-08-31 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / regalloc.c
1 /*
2  * regalloc.c: register state class
3  *
4  * Authors:
5  *    Paolo Molaro (lupus@ximian.com)
6  *
7  * (C) 2003 Ximian, Inc.
8  */
9 #include "mini.h"
10
11 MonoRegState*
12 mono_regstate_new (void)
13 {
14         MonoRegState* rs = g_new0 (MonoRegState, 1);
15
16         mono_regstate_reset (rs);
17
18         return rs;
19 }
20
21 void
22 mono_regstate_free (MonoRegState *rs) {
23         g_free (rs->iassign);
24         g_free (rs->fassign);
25         g_free (rs);
26 }
27
28 void
29 mono_regstate_reset (MonoRegState *rs) {
30         rs->next_vireg = MONO_MAX_IREGS;
31         rs->next_vfreg = MONO_MAX_FREGS;
32 }
33
34 void
35 mono_regstate_assign (MonoRegState *rs) {
36         int i;
37         rs->max_ireg = -1;
38         g_free (rs->iassign);
39         rs->iassign = g_malloc (MAX (MONO_MAX_IREGS, rs->next_vireg) * sizeof (int));
40         for (i = 0; i < MONO_MAX_IREGS; ++i) {
41                 rs->iassign [i] = i;
42                 rs->isymbolic [i] = 0;
43         }
44         for (; i < rs->next_vireg; ++i)
45                 rs->iassign [i] = -1;
46
47         g_free (rs->fassign);
48         rs->fassign = g_malloc (MAX (MONO_MAX_FREGS, rs->next_vfreg) * sizeof (int));
49         for (i = 0; i < MONO_MAX_FREGS; ++i) {
50                 rs->fassign [i] = i;
51                 rs->fsymbolic [i] = 0;
52         }
53         for (; i < rs->next_vfreg; ++i)
54                 rs->fassign [i] = -1;
55 }
56
57 int
58 mono_regstate_alloc_int (MonoRegState *rs, regmask_t allow)
59 {
60         int i;
61         regmask_t mask = allow & rs->ifree_mask;
62         for (i = 0; i < MONO_MAX_IREGS; ++i) {
63                 if (mask & ((regmask_t)1 << i)) {
64                         rs->ifree_mask &= ~ ((regmask_t)1 << i);
65                         rs->max_ireg = MAX (rs->max_ireg, i);
66                         return i;
67                 }
68         }
69         return -1;
70 }
71
72 void
73 mono_regstate_free_int (MonoRegState *rs, int reg)
74 {
75         if (reg >= 0) {
76                 rs->ifree_mask |= (regmask_t)1 << reg;
77                 rs->isymbolic [reg] = 0;
78         }
79 }
80
81 int
82 mono_regstate_alloc_float (MonoRegState *rs, regmask_t allow)
83 {
84         int i;
85         regmask_t mask = allow & rs->ffree_mask;
86         for (i = 0; i < MONO_MAX_FREGS; ++i) {
87                 if (mask & ((regmask_t)1 << i)) {
88                         rs->ffree_mask &= ~ ((regmask_t)1 << i);
89                         return i;
90                 }
91         }
92         return -1;
93 }
94
95 void
96 mono_regstate_free_float (MonoRegState *rs, int reg)
97 {
98         if (reg >= 0) {
99                 rs->ffree_mask |= (regmask_t)1 << reg;
100                 rs->fsymbolic [reg] = 0;
101         }
102 }
103
104 inline int
105 mono_regstate_next_long (MonoRegState *rs)
106 {
107         int rval = rs->next_vireg;
108
109         rs->next_vireg += 2;
110
111         return rval;
112 }
113