2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / jit / regset.c
1 /*
2  * regset.c: register set abstraction
3  *
4  * Author:
5  *   Dietmar Maurer (dietmar@ximian.com)
6  *
7  * (C) 2001 Ximian, Inc.
8  */
9
10 #include "regset.h"
11 #include <mono/arch/x86/x86-codegen.h>
12
13 MonoRegSet *
14 mono_regset_new (int max_regs)
15 {
16         MonoRegSet *rs;
17
18         g_return_val_if_fail (max_regs > 0 && max_regs <= 32, NULL);
19
20         rs = g_new0 (MonoRegSet, 1);
21
22         rs->max_regs = max_regs;
23         rs->used_mask = 0;
24         rs->free_mask = ~rs->used_mask;
25         rs->reserved_mask = 0;
26
27         return rs;
28 }
29
30 void
31 mono_regset_free (MonoRegSet *rs)
32 {
33         g_free (rs);
34 }
35
36 void
37 mono_regset_reserve_reg (MonoRegSet *rs, int regnum)
38 {
39         guint32 ind;
40
41         g_return_if_fail (rs != NULL);
42         g_return_if_fail (rs->max_regs > regnum);
43
44         ind = 1 << regnum;
45
46         rs->reserved_mask |= ind;
47 }
48
49 int
50 mono_regset_alloc_reg (MonoRegSet *rs, int regnum, guint8 exclude_mask)
51 {
52         guint32 i, ind;
53
54         g_return_val_if_fail (rs != NULL, -1);
55         g_return_val_if_fail (rs->max_regs > regnum, -1);
56
57         if (regnum < 0) {
58                 for (i = 0, ind = 1; i < rs->max_regs; i++, ind = ind << 1) {
59                         if (exclude_mask & ind)
60                                 continue;
61                         if ((rs->free_mask & ind) && !(rs->reserved_mask & ind)) {
62                                 rs->free_mask &= ~ind;
63                                 rs->used_mask |= ind;
64                                 return i;
65                         }
66                 }
67                 return -1;
68         } else {
69                 ind = 1 << regnum;
70
71                 if (exclude_mask & ind)
72                         return -1;
73
74                 if ((rs->free_mask & ind) && !(rs->reserved_mask & ind)) {
75                         rs->free_mask &= ~ind;
76                         rs->used_mask |= ind;
77                         return regnum;
78                 }
79                 return -1;
80         }
81 }
82
83 void
84 mono_regset_free_reg (MonoRegSet *rs, int regnum)
85 {
86         guint32 ind;
87
88         g_return_if_fail (rs != NULL);
89         g_return_if_fail (rs->max_regs > regnum);
90
91         if (regnum < 0)
92                 return;
93
94         ind = 1 << regnum;
95
96         g_return_if_fail (rs->free_mask && ind);
97
98         rs->free_mask |= ind;
99 }
100
101 gboolean
102 mono_regset_reg_used (MonoRegSet *rs, int regnum)
103 {
104         guint32 ind;
105
106         g_return_val_if_fail (rs != NULL, FALSE);
107         g_return_val_if_fail (rs->max_regs > regnum, FALSE);
108         g_return_val_if_fail (regnum >= 0, FALSE);
109
110         ind = 1 << regnum;
111
112         return rs->used_mask & ind;
113 }
114
115