summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/c/sail.h311
1 files changed, 302 insertions, 9 deletions
diff --git a/test/c/sail.h b/test/c/sail.h
index 8afb192d..880f5a57 100644
--- a/test/c/sail.h
+++ b/test/c/sail.h
@@ -26,11 +26,49 @@ void sail_match_failure(void) {
exit(1);
}
+unit sail_assert(bool b, sail_string msg) {
+ if (b) return UNIT;
+ fprintf(stderr, "Assertion failed: %s\n", msg);
+ exit(1);
+}
+
+unit sail_exit(const unit u) {
+ fprintf(stderr, "Unexpected exit\n");
+ exit(1);
+}
+
+void elf_entry(mpz_t *rop, const unit u) {
+ mpz_set_ui(*rop, 0x8000ul);
+}
+
+// Sail bits are mapped to ints where bitzero = 0 and bitone = 1
+bool eq_bit(const int a, const int b) {
+ return a == b;
+}
+
+int undefined_bit(unit u) { return 0; }
+
+// ***** Sail booleans *****
+
bool not(const bool b) {
return !b;
}
-int undefined_bit(unit u) { return 0; }
+bool and_bool(const bool a, const bool b) {
+ return a && b;
+}
+
+bool or_bool(const bool a, const bool b) {
+ return a || b;
+}
+
+bool eq_bool(const bool a, const bool b) {
+ return a == b;
+}
+
+bool undefined_bool(const unit u) {
+ return false;
+}
// ***** Sail strings *****
void init_sail_string(sail_string *str) {
@@ -49,11 +87,20 @@ void clear_sail_string(sail_string *str) {
free(*str);
}
+bool eq_string(const sail_string str1, const sail_string str2) {
+ return strcmp(str1, str2) == 0;
+}
+
unit print_endline(sail_string str) {
printf("%s\n", str);
return UNIT;
}
+unit prerr_endline(sail_string str) {
+ fprintf(stderr, "%s\n", str);
+ return UNIT;
+}
+
unit print_int(const sail_string str, const mpz_t op) {
fputs(str, stdout);
mpz_out_str(stdout, 10, op);
@@ -66,6 +113,11 @@ unit print_int64(const sail_string str, const int64_t op) {
return UNIT;
}
+unit sail_putchar(const mpz_t op) {
+ char c = (char) mpz_get_ui(op);
+ putchar(c);
+}
+
// ***** Arbitrary precision integers *****
// We wrap around the GMP functions so they follow a consistent naming
@@ -91,6 +143,10 @@ void init_mpz_t_of_sail_string(mpz_t *rop, sail_string str) {
mpz_init_set_str(*rop, str, 10);
}
+int64_t convert_int64_t_of_mpz_t(const mpz_t op) {
+ return mpz_get_si(op);
+}
+
// ***** Sail builtins for integers *****
bool eq_int(const mpz_t op1, const mpz_t op2) {
@@ -105,10 +161,26 @@ bool gt(const mpz_t op1, const mpz_t op2) {
return mpz_cmp(op1, op2) > 0;
}
+bool lteq(const mpz_t op1, const mpz_t op2) {
+ return mpz_cmp(op1, op2) <= 0;
+}
+
+bool gteq(const mpz_t op1, const mpz_t op2) {
+ return mpz_cmp(op1, op2) >= 0;
+}
+
+void shl_int(mpz_t *rop, const mpz_t op1, const mpz_t op2) {
+ mpz_mul_2exp(*rop, op1, mpz_get_ui(op2));
+}
+
void undefined_int(mpz_t *rop, const unit u) {
mpz_set_ui(*rop, 0ul);
}
+void undefined_range(mpz_t *rop, const mpz_t l, const mpz_t u) {
+ mpz_set(*rop, l);
+}
+
void add_int(mpz_t *rop, const mpz_t op1, const mpz_t op2)
{
mpz_add(*rop, op1, op2);
@@ -119,6 +191,37 @@ void sub_int(mpz_t *rop, const mpz_t op1, const mpz_t op2)
mpz_sub(*rop, op1, op2);
}
+void mult_int(mpz_t *rop, const mpz_t op1, const mpz_t op2)
+{
+ mpz_mul(*rop, op1, op2);
+}
+
+void div_int(mpz_t *rop, const mpz_t op1, const mpz_t op2)
+{
+ mpz_tdiv_q(*rop, op1, op2);
+}
+
+void mod_int(mpz_t *rop, const mpz_t op1, const mpz_t op2)
+{
+ mpz_tdiv_r(*rop, op1, op2);
+}
+
+void max_int(mpz_t *rop, const mpz_t op1, const mpz_t op2) {
+ if (lt(op1, op2)) {
+ mpz_set(*rop, op2);
+ } else {
+ mpz_set(*rop, op1);
+ }
+}
+
+void min_int(mpz_t *rop, const mpz_t op1, const mpz_t op2) {
+ if (gt(op1, op2)) {
+ mpz_set(*rop, op2);
+ } else {
+ mpz_set(*rop, op1);
+ }
+}
+
void neg_int(mpz_t *rop, const mpz_t op) {
mpz_neg(*rop, op);
}
@@ -127,8 +230,20 @@ void abs_int(mpz_t *rop, const mpz_t op) {
mpz_abs(*rop, op);
}
+void pow2(mpz_t *rop, mpz_t exp) {
+ uint64_t exp_ui = mpz_get_ui(exp);
+ mpz_t base;
+ mpz_init_set_ui(base, 2ul);
+ mpz_pow_ui(*rop, base, exp_ui);
+ mpz_clear(base);
+}
+
// ***** Sail bitvectors *****
+void length_bv_t(mpz_t *rop, const bv_t op) {
+ mpz_set_ui(*rop, op.len);
+}
+
void init_bv_t(bv_t *rop) {
rop->bits = malloc(sizeof(mpz_t));
rop->len = 0;
@@ -146,12 +261,32 @@ void set_bv_t(bv_t *rop, const bv_t op) {
mpz_set(*rop->bits, *op.bits);
}
-void append_64(bv_t *rop, bv_t op, const uint64_t chunk) {
+void append_64(bv_t *rop, const bv_t op, const uint64_t chunk) {
rop->len = rop->len + 64ul;
mpz_mul_2exp(*rop->bits, *op.bits, 64ul);
mpz_add_ui(*rop->bits, *rop->bits, chunk);
}
+void append(bv_t *rop, const bv_t op1, const bv_t op2) {
+ rop->len = op1.len + op2.len;
+ mpz_mul_2exp(*rop->bits, *op1.bits, op2.len);
+ mpz_add(*rop->bits, *rop->bits, *op2.bits);
+}
+
+void replicate_bits(bv_t *rop, const bv_t op1, const mpz_t op2) {
+ uint64_t op2_ui = mpz_get_ui(op2);
+ rop->len = op1.len * op2_ui;
+ mpz_set(*rop->bits, *op1.bits);
+ for (int i = 1; i < op2_ui; i++) {
+ mpz_mul_2exp(*rop->bits, *rop->bits, op2_ui);
+ mpz_add(*rop->bits, *rop->bits, *op1.bits);
+ }
+}
+
+void slice(bv_t *rop, const bv_t op, const mpz_t i, const mpz_t len) {
+ // TODO
+}
+
uint64_t convert_uint64_t_of_bv_t(const bv_t op) {
return mpz_get_ui(*op.bits);
}
@@ -186,23 +321,53 @@ void mask(bv_t *rop) {
}
}
-void add_bits(bv_t *rop, const bv_t op1, const bv_t op2) {
+void and_bits(bv_t *rop, const bv_t op1, const bv_t op2) {
rop->len = op1.len;
- mpz_add(*rop->bits, *op1.bits, *op2.bits);
- mpz_clrbit(*rop->bits, op1.len);
+ mpz_and(*rop->bits, *op1.bits, *op2.bits);
}
-uint64_t add_bits_32(const uint64_t op1, const uint64_t op2) {
- return (op1 + op2) & 0x00000000FFFFFFFFul;
+void or_bits(bv_t *rop, const bv_t op1, const bv_t op2) {
+ rop->len = op1.len;
+ mpz_ior(*rop->bits, *op1.bits, *op2.bits);
}
+void not_bits(bv_t *rop, const bv_t op) {
+ rop->len = op.len;
+ mpz_com(*rop->bits, *op.bits);
+}
+
+void xor_bits(bv_t *rop, const bv_t op1, const bv_t op2) {
+ rop->len = op1.len;
+ mpz_xor(*rop->bits, *op1.bits, *op2.bits);
+}
bool eq_bits(const bv_t op1, const bv_t op2) {
return mpz_cmp(*op1.bits, *op2.bits) == 0;
}
-bool eq_bits_32(const uint64_t op1, const uint64_t op2) {
- return (op1 == op2);
+void sail_uint(mpz_t *rop, const bv_t op) {
+ mpz_set(*rop, *op.bits);
+}
+
+void sint(mpz_t *rop, const bv_t op) {
+ if (mpz_tstbit(*op.bits, op.len - 1)) {
+ mpz_set(*rop, *op.bits);
+ mpz_clrbit(*rop, op.len - 1);
+ mpz_t x;
+ mpz_init(x);
+ mpz_setbit(x, op.len - 1);
+ mpz_neg(x, x);
+ mpz_add(*rop, *rop, *op.bits);
+ mpz_clear(x);
+ } else {
+ mpz_set(*rop, *op.bits);
+ }
+}
+
+void add_bits(bv_t *rop, const bv_t op1, const bv_t op2) {
+ rop->len = op1.len;
+ mpz_add(*rop->bits, *op1.bits, *op2.bits);
+ mpz_clrbit(*rop->bits, op1.len);
}
void add_bits_int(bv_t *rop, const bv_t op1, const mpz_t op2) {
@@ -211,6 +376,40 @@ void add_bits_int(bv_t *rop, const bv_t op1, const mpz_t op2) {
mask(rop);
}
+void sub_bits_int(bv_t *rop, const bv_t op1, const mpz_t op2) {
+ rop->len = op1.len;
+ mpz_sub(*rop->bits, *op1.bits, op2);
+ mask(rop);
+}
+
+void get_slice_int(bv_t *rop, const mpz_t n, const mpz_t m, const mpz_t o) {
+ // TODO
+}
+
+void set_slice_int(mpz_t *rop, const mpz_t n, const mpz_t m, const mpz_t o, const bv_t op) {
+ // TODO
+}
+
+void vector_update_subrange_bv_t(bv_t *rop, const bv_t op, const mpz_t n, const mpz_t m, const bv_t slice) {
+ // TODO
+}
+
+void vector_subrange_bv_t(bv_t *rop, const bv_t op, const mpz_t n, const mpz_t m) {
+ // TODO
+}
+
+int bitvector_access(const bv_t op, const mpz_t n) {
+ return 0; // TODO
+}
+
+void hex_slice (bv_t *rop, const sail_string hex, const mpz_t n, const mpz_t m) {
+ // TODO
+}
+
+void set_slice (bv_t *rop, const mpz_t len, const mpz_t slen, const bv_t op, const mpz_t i, const bv_t slice) {
+ // TODO
+}
+
unit print_bits(const sail_string str, const bv_t op) {
fputs(str, stdout);
gmp_printf("%d'0x%ZX\n", op.len, op.bits);
@@ -238,6 +437,100 @@ void clear_real(real *rop) {
mpf_clear(*rop);
}
+void set_real(real *rop, const real op) {
+ mpf_set(*rop, op);
+}
+
+void undefined_real(real *rop, unit u) {
+ mpf_set_ui(*rop, 0ul);
+}
+
+void neg_real(real *rop, const real op) {
+ mpf_neg(*rop, op);
+}
+
+void mult_real(real *rop, const real op1, const real op2) {
+ mpf_mul(*rop, op1, op2);
+}
+
+void sub_real(real *rop, const real op1, const real op2) {
+ mpf_sub(*rop, op1, op2);
+}
+
+void add_real(real *rop, const real op1, const real op2) {
+ mpf_add(*rop, op1, op2);
+}
+
+void div_real(real *rop, const real op1, const real op2) {
+ mpf_div(*rop, op1, op2);
+}
+
+void sqrt_real(real *rop, const real op) {
+ mpf_sqrt(*rop, op);
+}
+
+void abs_real(real *rop, const real op) {
+ mpf_abs(*rop, op);
+}
+
+void round_up(mpz_t *rop, const real op) {
+ mpf_t x;
+ mpf_ceil(x, op);
+ mpz_set_ui(*rop, mpf_get_ui(x));
+ mpf_clear(x);
+}
+
+void round_down(mpz_t *rop, const real op) {
+ mpf_t x;
+ mpf_floor(x, op);
+ mpz_set_ui(*rop, mpf_get_ui(x));
+ mpf_clear(x);
+}
+
+void to_real(real *rop, const mpz_t op) {
+ mpf_set_z(*rop, op);
+}
+
+bool eq_real(const real op1, const real op2) {
+ return mpf_cmp(op1, op2) == 0;
+}
+
+bool lt_real(const real op1, const real op2) {
+ return mpf_cmp(op1, op2) < 0;
+}
+
+bool gt_real(const real op1, const real op2) {
+ return mpf_cmp(op1, op2) > 0;
+}
+
+bool lteq_real(const real op1, const real op2) {
+ return mpf_cmp(op1, op2) <= 0;
+}
+
+bool gteq_real(const real op1, const real op2) {
+ return mpf_cmp(op1, op2) >= 0;
+}
+
+void real_power(real *rop, const real base, const mpz_t exp) {
+ uint64_t exp_ui = mpz_get_ui(exp);
+ mpf_pow_ui(*rop, base, exp_ui);
+}
+
+void init_real_of_sail_string(real *rop, const sail_string op) {
+ // FIXME
+ mpf_init(*rop);
+}
+
#endif
#endif
+
+// ***** Memory *****
+
+unit write_ram(const mpz_t m, const mpz_t n, const bv_t x, const bv_t y, const bv_t data) {
+ return UNIT;
+}
+
+void read_ram(bv_t *data, const mpz_t m, const mpz_t n, const bv_t x, const bv_t y) {
+ // TODO
+}