bearch: Remove unnecessary indirection to access arch_no_register_req.
[libfirm] / ir / stat / counter.h
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Statistics for Firm. Counter implementation.
23  * @author  Michael Beck
24  */
25 #ifndef FIRM_STAT_COUNTER_H
26 #define FIRM_STAT_COUNTER_H
27
28 #include <string.h>
29 #include <limits.h>
30
31 /*
32  * 32 bit should be enough for most cases
33  */
34 #ifndef STAT_CNT_NUM
35 #define STAT_CNT_NUM 1
36 #endif
37
38 typedef struct counter_t {
39         unsigned cnt[STAT_CNT_NUM];
40 } counter_t;
41
42 /** initializes a counter with zero */
43 #define ZERO_CNT { { 0 } }
44
45 /**
46  * increase a counter
47  */
48 static inline void cnt_inc(counter_t *cnt)
49 {
50         int i;
51
52         for (i = 0; i < STAT_CNT_NUM; ++i) {
53                 if (++cnt->cnt[i])
54                         break;
55         }
56 }
57
58 /**
59  * decrease a counter
60  */
61 static inline void cnt_dec(counter_t *cnt)
62 {
63         int i;
64
65         for (i = 0; i < STAT_CNT_NUM; ++i) {
66                 if (--cnt->cnt[i] != (unsigned) -1)
67                         break;
68         }
69 }
70
71 /**
72  * set a counter to zero
73  */
74 static inline void cnt_clr(counter_t *cnt)
75 {
76         memset(cnt->cnt, 0, sizeof(cnt->cnt));
77 }
78
79 /**
80  * add a counter to another
81  */
82 static inline void cnt_add(counter_t *dst, const counter_t *src)
83 {
84         int i, carry = 0;
85
86         for (i = 0; i < STAT_CNT_NUM; ++i) {
87                 unsigned x = dst->cnt[i];
88                 unsigned y = src->cnt[i];
89                 unsigned a = x + y + carry;
90
91                 carry = (int)((x & y) | ((x | y) & ~a)) < 0 ? 1 : 0;
92
93                 dst->cnt[i] = a;
94         }
95 }
96
97 /**
98  * add an (positive) integer to an counter
99  */
100 static inline void cnt_add_i(counter_t *dst, int src)
101 {
102         int i;
103         unsigned carry = src;
104
105         for (i = 0; i < STAT_CNT_NUM; ++i) {
106                 unsigned a = dst->cnt[i] + carry;
107
108                 carry = a < dst->cnt[i];
109
110                 dst->cnt[i] = a;
111
112                 if (! carry)
113                         break;
114         }
115 }
116
117 /**
118  * compare two counter
119  */
120 static inline int cnt_cmp(const counter_t *a, const counter_t *b)
121 {
122         int i;
123         unsigned va = 0;
124         unsigned vb = 0;
125
126         for (i = STAT_CNT_NUM - 1 ; i >= 0; --i) {
127                 va = a->cnt[i];
128                 vb = b->cnt[i];
129
130                 if (va != vb)
131                         break;
132         }
133
134         if (va != vb)
135                 return va < vb ? -1 : 1;
136         return 0;
137 }
138
139 /**
140  * convert a counter into a double
141  */
142 static inline double cnt_to_dbl(const counter_t *a)
143 {
144         int i;
145         double res = 0.0, scale = 1.0, tmp;
146
147         i = (1 << (sizeof(a->cnt[0]) * 4));
148         tmp = ((double)i) * ((double)i);
149
150         for (i = 0; i < STAT_CNT_NUM; ++i) {
151                 res += scale * (double)a->cnt[i];
152
153                 scale *= tmp;
154         }
155         return res;
156 }
157
158 /**
159  * convert a counter into an unsigned
160  */
161 static inline unsigned cnt_to_uint(const counter_t *a)
162 {
163         int i;
164
165         for (i = 1; i < STAT_CNT_NUM; ++i)
166                 if (a->cnt[i])
167                         return UINT_MAX;
168
169         return a->cnt[0];
170 }
171
172 /**
173  * check, if a counter is equal to an unsigned
174  */
175 static inline int cnt_eq(const counter_t *a, unsigned value)
176 {
177         int i;
178
179         for (i = 1; i < STAT_CNT_NUM; ++i)
180                 if (a->cnt[i])
181                         return 0;
182
183         return a->cnt[0] == value;
184 }
185
186 /**
187  * check, if a counter as greater than an unsigned
188  */
189 static inline int cnt_gt(const counter_t *a, unsigned value)
190 {
191         int i;
192
193         for (i = 1; i < STAT_CNT_NUM; ++i)
194                 if (a->cnt[i])
195                         return 1;
196
197         return a->cnt[0] > value;
198 }
199
200 #endif /* FIRM_STAT_COUNTER_H */