changed inline to INLINE, removed C99
[libfirm] / ir / stat / counter.h
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/counter.h
4  * Purpose:     Statistics for Firm. Counter implementation.
5  * Author:      Michael Beck
6  * Created:
7  * CVS-ID:      $Id$
8  * Copyright:   (c) 2004 Universität Karlsruhe
9  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
10  */
11 #ifndef _COUNTER_H_
12 #define _COUNTER_H_
13
14 #include <string.h>
15 #include <limits.h>
16
17 /*
18  * 32 bit should be enough for most cases
19  */
20 #ifndef STAT_CNT_NUM
21 #define STAT_CNT_NUM 1
22 #endif
23
24 typedef struct _counter_t {
25         unsigned cnt[STAT_CNT_NUM];
26 } counter_t;
27
28 /** initializes a counter with zero */
29 #define ZERO_CNT { { 0 } }
30
31 /**
32  * increase a counter
33  */
34 static INLINE void cnt_inc(counter_t *cnt)
35 {
36         int i;
37
38         for (i = 0; i < STAT_CNT_NUM; ++i) {
39                 if (++cnt->cnt[i])
40                         break;
41         }
42 }
43
44 /**
45  * decrease a counter
46  */
47 static INLINE void cnt_dec(counter_t *cnt)
48 {
49         int i;
50
51         for (i = 0; i < STAT_CNT_NUM; ++i) {
52                 if (--cnt->cnt[i] != -1)
53                         break;
54         }
55 }
56
57 /**
58  * set a counter to zero
59  */
60 static INLINE void cnt_clr(counter_t *cnt)
61 {
62         memset(cnt->cnt, 0, sizeof(cnt->cnt));
63 }
64
65 /**
66  * add a counter to another
67  */
68 static INLINE void cnt_add(counter_t *dst, const counter_t *src)
69 {
70         int i, carry = 0;
71
72         for (i = 0; i < STAT_CNT_NUM; ++i) {
73                 unsigned x = dst->cnt[i];
74                 unsigned y = src->cnt[i];
75                 unsigned a = x + y + carry;
76
77                 carry = (int)((x & y) | ((x | y) & ~a)) < 0 ? 1 : 0;
78
79                 dst->cnt[i] = a;
80         }
81 }
82
83 /**
84  * add an (positive) integer to an counter
85  */
86 static INLINE void cnt_add_i(counter_t *dst, int src)
87 {
88         int i;
89         unsigned carry = src;
90
91         for (i = 0; i < STAT_CNT_NUM; ++i) {
92                 unsigned a = dst->cnt[i] + carry;
93
94                 carry = a < dst->cnt[i];
95
96                 dst->cnt[i] = a;
97
98                 if (! carry)
99                         break;
100         }
101 }
102
103 /**
104  * compare two counter
105  */
106 static INLINE int cnt_cmp(const counter_t *a, const counter_t *b)
107 {
108         int i;
109         unsigned va, vb;
110
111         for (i = STAT_CNT_NUM - 1 ; i >= 0; --i) {
112                 va = a->cnt[i];
113                 vb = b->cnt[i];
114
115                 if (va != vb)
116                         break;
117         }
118
119         if (va != vb)
120                 return va < vb ? -1 : 1;
121         return 0;
122 }
123
124 /**
125  * convert a counter into a double
126  */
127 static INLINE double cnt_to_dbl(const counter_t *a)
128 {
129         int i;
130         double res = 0.0, scale = 1.0, tmp;
131
132         i = (1 << (sizeof(a->cnt[0]) * 4));
133         tmp = ((double)i) * ((double)i);
134
135         for (i = 0; i < STAT_CNT_NUM; ++i) {
136                 res += scale * (double)a->cnt[i];
137
138                 scale *= tmp;
139         }
140         return res;
141 }
142
143 /**
144  * convert a counter into an unsigned
145  */
146 static INLINE unsigned cnt_to_uint(const counter_t *a)
147 {
148         int i;
149
150         for (i = 1; i < STAT_CNT_NUM; ++i)
151                 if (a->cnt[i])
152                         return UINT_MAX;
153
154         return a->cnt[0];
155 }
156
157 /**
158  * check, if a counter is equal to an unsigned
159  */
160 static INLINE int cnt_eq(const counter_t *a, unsigned value)
161 {
162         int i;
163
164         for (i = 1; i < STAT_CNT_NUM; ++i)
165                 if (a->cnt[i])
166                         return 0;
167
168         return a->cnt[0] == value;
169 }
170
171 /**
172  * check, if a counter as greater than an unsigned
173  */
174 static INLINE int cnt_gt(const counter_t *a, unsigned value)
175 {
176         int i;
177
178         for (i = 1; i < STAT_CNT_NUM; ++i)
179                 if (a->cnt[i])
180                         return 1;
181
182         return a->cnt[0] > value;
183 }
184
185 #endif /* _COUNTER_H_ */