added cnt_to_int function for counter
[libfirm] / ir / stat / counter.h
index fb5ebe0..840ace3 100644 (file)
 #ifndef _COUNTER_H_
 #define _COUNTER_H_
 
-#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
 
 /*
- * 32 bit should be enough for now
+ * 32 bit should be enough for most cases
  */
+#ifndef STAT_CNT_NUM
 #define STAT_CNT_NUM 1
+#endif
 
 typedef struct _counter_t {
   unsigned cnt[STAT_CNT_NUM];
@@ -36,7 +39,7 @@ static INLINE void cnt_inc(counter_t *cnt)
 }
 
 /**
- * decreace a counter
+ * decrease a counter
  */
 static INLINE void cnt_dec(counter_t *cnt)
 {
@@ -64,34 +67,25 @@ static INLINE void cnt_add(counter_t *dst, const counter_t *src)
   int i, carry = 0;
 
   for (i = 0; i < STAT_CNT_NUM; ++i) {
-    unsigned a = dst->cnt[i] + src->cnt[i] + carry;
+    unsigned x = dst->cnt[i];
+    unsigned y = src->cnt[i];
+    unsigned a = x + y + carry;
 
-    if (carry)
-      carry = a <= dst->cnt[i];
-    else
-      carry = a < dst->cnt[i];
+    carry = (int)((x & y) | ((x | y) & ~a)) < 0 ? 1 : 0;
 
     dst->cnt[i] = a;
-
-    if (! carry)
-      break;
   }
 }
 
 /**
- * add an integer to an counter
+ * add an (positive) integer to an counter
  */
 static INLINE void cnt_add_i(counter_t *dst, int src)
 {
   int i;
-  unsigned a = dst->cnt[0] + src;
-  unsigned carry = a < dst->cnt[0];
+  unsigned carry = src;
 
-  dst->cnt[0] = a;
-  if (! carry)
-    return;
-
-  for (i = 1; i < STAT_CNT_NUM; ++i) {
+  for (i = 0; i < STAT_CNT_NUM; ++i) {
     unsigned a = dst->cnt[i] + carry;
 
     carry = a < dst->cnt[i];
@@ -111,7 +105,6 @@ static INLINE int cnt_cmp(const counter_t *a, const counter_t *b)
   int i;
   unsigned va, vb;
 
-
   for (i = STAT_CNT_NUM - 1 ; i >= 0; --i) {
     va = a->cnt[i];
     vb = b->cnt[i];
@@ -125,4 +118,66 @@ static INLINE int cnt_cmp(const counter_t *a, const counter_t *b)
   return 0;
 }
 
+/**
+ * convert a counter into a double
+ */
+static INLINE double cnt_to_dbl(const counter_t *a)
+{
+  int i;
+  double res = 0.0, scale = 1.0, tmp;
+
+  i = (1 << (sizeof(a->cnt[0]) * 4));
+  tmp = ((double)i) * ((double)i);
+
+  for (i = 0; i < STAT_CNT_NUM; ++i) {
+    res += scale * (double)a->cnt[i];
+
+    scale *= tmp;
+  }
+  return res;
+}
+
+/**
+ * convert a counter into an int
+ */
+static INLINE int cnt_to_int(const counter_t *a)
+{
+  int i;
+
+  for (i = 1; i < STAT_CNT_NUM; ++i)
+    if (a->cnt[i])
+               return INT_MAX;
+
+  return a->cnt[0];
+}
+
+/**
+ * check, if a counter is equal to an unsigned
+ */
+static INLINE int cnt_eq(const counter_t *a, unsigned value)
+{
+  int i;
+
+  for (i = 1; i < STAT_CNT_NUM; ++i)
+    if (a->cnt[i])
+      return 0;
+
+  return a->cnt[0] == value;
+}
+
+/**
+ * check, if a counter as greater than an unsigned
+ */
+static INLINE int cnt_gt(const counter_t *a, unsigned value)
+{
+  int i;
+
+  for (i = 1; i < STAT_CNT_NUM; ++i)
+    if (a->cnt[i])
+      return 1;
+
+  return a->cnt[0] > value;
+}
+
+
 #endif /* _COUNTER_H_ */