a debugger extension for Firm
[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
16 /*
17  * 32 bit should be enough for now
18  */
19 #define STAT_CNT_NUM 1
20
21 typedef struct _counter_t {
22   unsigned cnt[STAT_CNT_NUM];
23 } counter_t;
24
25 /**
26  * increase a counter
27  */
28 static INLINE void cnt_inc(counter_t *cnt)
29 {
30   int i;
31
32   for (i = 0; i < STAT_CNT_NUM; ++i) {
33     if (++cnt->cnt[i])
34       break;
35   }
36 }
37
38 /**
39  * decrease a counter
40  */
41 static INLINE void cnt_dec(counter_t *cnt)
42 {
43   int i;
44
45   for (i = 0; i < STAT_CNT_NUM; ++i) {
46     if (--cnt->cnt[i] != -1)
47       break;
48   }
49 }
50
51 /**
52  * set a counter to zero
53  */
54 static INLINE void cnt_clr(counter_t *cnt)
55 {
56   memset(cnt->cnt, 0, sizeof(cnt->cnt));
57 }
58
59 /**
60  * add a counter to another
61  */
62 static INLINE void cnt_add(counter_t *dst, const counter_t *src)
63 {
64   int i, carry = 0;
65
66   for (i = 0; i < STAT_CNT_NUM; ++i) {
67     unsigned x = dst->cnt[i];
68     unsigned y = src->cnt[i];
69     unsigned a = x + y + carry;
70
71     carry = (int)((x & y) | ((x | y) & ~a)) < 0 ? 1 : 0;
72
73     dst->cnt[i] = a;
74   }
75 }
76
77 /**
78  * add an (positive) integer to an counter
79  */
80 static INLINE void cnt_add_i(counter_t *dst, int src)
81 {
82   int i;
83   unsigned carry = src;
84
85   for (i = 0; i < STAT_CNT_NUM; ++i) {
86     unsigned a = dst->cnt[i] + carry;
87
88     carry = a < dst->cnt[i];
89
90     dst->cnt[i] = a;
91
92     if (! carry)
93       break;
94   }
95 }
96
97 /**
98  * compare two counter
99  */
100 static INLINE int cnt_cmp(const counter_t *a, const counter_t *b)
101 {
102   int i;
103   unsigned va, vb;
104
105   for (i = STAT_CNT_NUM - 1 ; i >= 0; --i) {
106     va = a->cnt[i];
107     vb = b->cnt[i];
108
109     if (va != vb)
110       break;
111   }
112
113   if (va != vb)
114     return va < vb ? -1 : 1;
115   return 0;
116 }
117
118 /**
119  * convert a counter into a double
120  */
121 static INLINE double cnt_to_dbl(const counter_t *a)
122 {
123   int i;
124   double res = 0.0, scale = 1.0, tmp;
125
126   i = (1 << (sizeof(a->cnt[i]) * 4));
127   tmp = ((double)i) * ((double)i);
128
129   for (i = 0; i < STAT_CNT_NUM; ++i) {
130     res += scale * (double)a->cnt[i];
131
132     scale *= tmp;
133   }
134   return res;
135 }
136
137 /**
138  * check, if a counter is equal to an unsigned
139  */
140 static INLINE int cnt_eq(const counter_t *a, unsigned value)
141 {
142   int i;
143
144   for (i = 1; i < STAT_CNT_NUM; ++i)
145     if (a->cnt[i])
146       return 0;
147
148   return a->cnt[0] == value;
149 }
150
151 /**
152  * check, if a counter as greater than an unsigned
153  */
154 static INLINE int cnt_gt(const counter_t *a, unsigned value)
155 {
156   int i;
157
158   for (i = 1; i < STAT_CNT_NUM; ++i)
159     if (a->cnt[i])
160       return 1;
161
162   return a->cnt[0] > value;
163 }
164
165
166 #endif /* _COUNTER_H_ */