summaryrefslogtreecommitdiff
path: root/test/c/sail.h
diff options
context:
space:
mode:
authorAlasdair Armstrong2018-02-27 18:24:52 +0000
committerAlasdair Armstrong2018-02-27 19:14:38 +0000
commitee5052f19a9eb812245f0e955aa1bc809b0bb38e (patch)
treecf618a968b51ff842bce768b96e63de4b220a6ef /test/c/sail.h
parentb0059c866f3b9b567bf195387abf7b7f32a497e1 (diff)
Fix some bugs in C compilation, and optimise struct updates
Fix some issues where some early returns in functions would cause memory leaks, and optimize struct updates so the struct is not copied uneccesarily. Also make C print_bits match ocaml version output, and update tests.
Diffstat (limited to 'test/c/sail.h')
-rw-r--r--test/c/sail.h77
1 files changed, 73 insertions, 4 deletions
diff --git a/test/c/sail.h b/test/c/sail.h
index 2363c27e..89aad9ba 100644
--- a/test/c/sail.h
+++ b/test/c/sail.h
@@ -33,8 +33,8 @@ unit sail_assert(bool b, sail_string msg) {
}
unit sail_exit(const unit u) {
- fprintf(stderr, "Unexpected exit\n");
- exit(1);
+ fprintf(stderr, "exit\n");
+ exit(0);
}
void elf_entry(mpz_t *rop, const unit u) {
@@ -77,6 +77,13 @@ void init_sail_string(sail_string *str) {
*str = istr;
}
+void reinit_sail_string(sail_string *str) {
+ free(*str);
+ char *istr = (char *) malloc(1 * sizeof(char));
+ istr[0] = '\0';
+ *str = istr;
+}
+
void set_sail_string(sail_string *str1, const sail_string str2) {
size_t len = strlen(str2);
*str1 = realloc(*str1, len + 1);
@@ -131,6 +138,10 @@ void init_mpz_t(mpz_t *op) {
mpz_init(*op);
}
+void reinit_mpz_t(mpz_t *op) {
+ mpz_set_ui(*op, 0);
+}
+
void clear_mpz_t(mpz_t *op) {
mpz_clear(*op);
}
@@ -139,10 +150,18 @@ void init_mpz_t_of_int64_t(mpz_t *rop, int64_t op) {
mpz_init_set_si(*rop, op);
}
+void reinit_mpz_t_of_int64_t(mpz_t *rop, int64_t op) {
+ mpz_set_si(*rop, op);
+}
+
void init_mpz_t_of_sail_string(mpz_t *rop, sail_string str) {
mpz_init_set_str(*rop, str, 10);
}
+void reinit_mpz_t_of_sail_string(mpz_t *rop, sail_string str) {
+ mpz_set_str(*rop, str, 10);
+}
+
int64_t convert_int64_t_of_mpz_t(const mpz_t op) {
return mpz_get_si(op);
}
@@ -240,9 +259,37 @@ void pow2(mpz_t *rop, mpz_t exp) {
// ***** Sail bitvectors *****
-unit print_bits(const sail_string str, const bv_t op) {
+unit print_bits(const sail_string str, const bv_t op)
+{
fputs(str, stdout);
- gmp_printf("%d'0x%ZX\n", op.len, op.bits);
+
+ if (op.len % 4 == 0) {
+ fputs("0x", stdout);
+ mpz_t buf;
+ mpz_init_set(buf, *op.bits);
+
+ char *hex = malloc((op.len / 4) * sizeof(char));
+
+ for (int i = 0; i < op.len / 4; ++i) {
+ char c = (char) ((0xF & mpz_get_ui(buf)) + 0x30);
+ hex[i] = (c < 0x3A) ? c : c + 0x7;
+ mpz_fdiv_q_2exp(buf, buf, 4);
+ }
+
+ for (int i = op.len / 4; i > 0; --i) {
+ fputc(hex[i - 1], stdout);
+ }
+
+ free(hex);
+ mpz_clear(buf);
+ } else {
+ fputs("0b", stdout);
+ for (int i = op.len; i > 0; --i) {
+ fputc(mpz_tstbit(*op.bits, i - 1) + 0x30, stdout);
+ }
+ }
+
+ fputs("\n", stdout);
}
void length_bv_t(mpz_t *rop, const bv_t op) {
@@ -255,12 +302,22 @@ void init_bv_t(bv_t *rop) {
mpz_init(*rop->bits);
}
+void reinit_bv_t(bv_t *rop) {
+ rop->len = 0;
+ mpz_set_ui(*rop->bits, 0);
+}
+
void init_bv_t_of_uint64_t(bv_t *rop, const uint64_t op, const uint64_t len, const bool direction) {
rop->bits = malloc(sizeof(mpz_t));
rop->len = len;
mpz_init_set_ui(*rop->bits, op);
}
+void reinit_bv_t_of_uint64_t(bv_t *rop, const uint64_t op, const uint64_t len, const bool direction) {
+ rop->len = len;
+ mpz_set_ui(*rop->bits, op);
+}
+
void set_bv_t(bv_t *rop, const bv_t op) {
rop->len = op.len;
mpz_set(*rop->bits, *op.bits);
@@ -288,6 +345,14 @@ void replicate_bits(bv_t *rop, const bv_t op1, const mpz_t op2) {
}
}
+uint64_t fast_replicate_bits(const uint64_t shift, const uint64_t v, const int64_t times) {
+ uint64_t r = 0;
+ for (int i = 0; i < times; ++i) {
+ r |= v << shift;
+ }
+ return r;
+}
+
void slice(bv_t *rop, const bv_t op, const mpz_t start_mpz, const mpz_t len_mpz)
{
uint64_t start = mpz_get_ui(start_mpz);
@@ -559,6 +624,10 @@ void init_real(real *rop) {
mpf_init(*rop);
}
+void reinit_real(real *rop) {
+ mpf_set_ui(*rop, 0);
+}
+
void clear_real(real *rop) {
mpf_clear(*rop);
}