Added
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 1 Jun 2004 13:40:07 +0000 (13:40 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 1 Jun 2004 13:40:07 +0000 (13:40 +0000)
[r2992]

ir/stat/pattern.c [new file with mode: 0644]

diff --git a/ir/stat/pattern.c b/ir/stat/pattern.c
new file mode 100644 (file)
index 0000000..4b2f97a
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * pattern history
+ */
+#include <assert.h>
+
+#include "irnode_t.h"
+
+typedef unsigned char BYTE;
+
+/**
+ * The code buffer
+ */
+typedef struct _code_buf_t {
+  BYTE         *next;          /**< next byte to be written */
+  int           len;           /**< length of current string */
+} CODE_BUFFER;
+
+enum vlc_code_t {
+  VLC_7BIT      = 0x00,        /**< 8 bit code, carrying 7 bits payload */
+  VLC_14BIT     = 0x80,        /**< 16 bit code, carrying 14 bits payload */
+  VLC_21BIT     = 0xC0,        /**< 24 bit code, carrying 21 bits payload */
+  VLC_28BIT     = 0xE0,        /**< 32 bit code, carrying 28 bits payload */
+  VLC_32BIT     = 0xF0,        /**< 40 bit code, carrying 32 bits payload */
+
+  VLC_TAG_FIRST = 0xF1, /**< first possible tag value */
+  VLC_TAG_REF   = 0xFE,        /**< special tag, next code is an ID */
+  VLC_TAG_END   = 0xFF,        /**< end tag */
+};
+
+/**
+ * put a byte into the buffer
+ */
+static INLINE void put_byte(CODE_BUFFER *buf, BYTE byte)
+{
+  *buf->next++ = byte;
+  ++buf->len;
+}
+
+/**
+ * returns the next byte from the buffer WITHOUT dropping
+ */
+static INLINE BYTE look_byte(CODE_BUFFER *buf)
+{
+  return *buf->next;
+}
+
+/**
+ * returns the next byte from the buffer WITH dropping
+ */
+static INLINE BYTE get_byte(CODE_BUFFER *buf)
+{
+  return *buf->next++;
+}
+
+#define BITS(n)                (1 << (n))
+
+/**
+ * put a 32bit value into the buffer
+ */
+static void put_code(CODE_BUFFER *buf, unsigned code)
+{
+  if (code < BITS(7)) {
+    put_byte(buf, VLC_7BIT | code);
+  }
+  else if (code < BITS(6 + 8)) {
+    put_byte(buf, VLC_14BIT | (code >> 8));
+    put_byte(buf, code);
+  }
+  else if (code < BITS(5 + 8 + 8)) {
+    put_byte(buf, VLC_21BIT | (code >> 16));
+    put_byte(buf, code >> 8);
+    put_byte(buf, code);
+  }
+  else if (code < BITS(4 + 8 + 8 + 8)) {
+    put_byte(buf, VLC_28BIT | (code >> 24));
+    put_byte(buf, code >> 16);
+    put_byte(buf, code >> 8);
+    put_byte(buf, code);
+  }
+  else {
+    put_byte(buf, VLC_32BIT);
+    put_byte(buf, code >> 24);
+    put_byte(buf, code >> 16);
+    put_byte(buf, code >> 8);
+    put_byte(buf, code);
+  }
+}
+
+/**
+ * put a tag into the buffer
+ */
+static void put_tag(CODE_BUFFER *buf, BYTE tag)
+{
+  assert(tag >= VLC_TAG_FIRST && "invalid tag");
+
+  put_byte(buf, tag);
+}
+
+/**
+ * returns the next tag or zero if the next code isn't a tag
+ */
+static BYTE next_tag(CODE_BUFFER *buf)
+{
+  BYTE b = look_byte(buf);
+
+  if (b >= VLC_TAG_FIRST)
+    return b;
+  return 0;
+}
+
+/*
+ * encodes an IR-node, recursive worker
+ */
+static void _encode_node(ir_node *node, CODE_BUFFER *buf, int max_depth)
+{
+  opcode code;
+  int i, preds;
+
+  code = intern_get_irn_opcode(node);
+  put_code(buf, code);
+
+  --max_depth;
+
+  if (max_depth <= 0) {
+    put_code(buf, 0);
+    return;
+  }
+
+  preds = intern_get_irn_arity(node);
+  put_code(buf, preds);
+
+  for (i = 0; i < preds; ++i) {
+    ir_node *n = intern_get_irn_n(node, i);
+
+    _encode_node(n, buf, max_depth);
+  }
+}
+
+/**
+ * encode an IR-node
+ */
+static void encode_node(ir_node *node, CODE_BUFFER *buf, int max_depth)
+{
+  _encode_node(node, buf, max_depth);
+  put_code(buf, VLC_TAG_END);
+}