diff options
| author | Alasdair Armstrong | 2018-02-22 22:56:28 +0000 |
|---|---|---|
| committer | Alasdair Armstrong | 2018-02-22 22:58:19 +0000 |
| commit | 8d30b1e511d12b427fb85b02fda7574637c191e4 (patch) | |
| tree | 38964cb8760cb4bd0cd0f006561a29740b75405b /test/c/sail.h | |
| parent | d08f0ac0ce1cfc79d6c53fb4a15575a178872c16 (diff) | |
More updates to C backend
Add support for short-ciruiting and/or. I forgot about this in the
original ANF specification and not having it causes problems for the
ARM spec.
Diffstat (limited to 'test/c/sail.h')
| -rw-r--r-- | test/c/sail.h | 222 |
1 files changed, 192 insertions, 30 deletions
diff --git a/test/c/sail.h b/test/c/sail.h index 880f5a57..92127a1b 100644 --- a/test/c/sail.h +++ b/test/c/sail.h @@ -38,7 +38,7 @@ unit sail_exit(const unit u) { } void elf_entry(mpz_t *rop, const unit u) { - mpz_set_ui(*rop, 0x8000ul); + mpz_set_ui(*rop, 0x400130ul); } // Sail bits are mapped to ints where bitzero = 0 and bitone = 1 @@ -240,6 +240,11 @@ void pow2(mpz_t *rop, mpz_t exp) { // ***** Sail bitvectors ***** +unit print_bits(const sail_string str, const bv_t op) { + fputs(str, stdout); + gmp_printf("%d'0x%ZX\n", op.len, op.bits); +} + void length_bv_t(mpz_t *rop, const bv_t op) { mpz_set_ui(*rop, op.len); } @@ -278,13 +283,22 @@ void replicate_bits(bv_t *rop, const bv_t op1, const mpz_t 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); + mpz_mul_2exp(*rop->bits, *rop->bits, op1.len); + mpz_ior(*rop->bits, *rop->bits, *op1.bits); } } -void slice(bv_t *rop, const bv_t op, const mpz_t i, const mpz_t len) { - // TODO +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); + uint64_t len = mpz_get_ui(len_mpz); + + mpz_set_ui(*rop->bits, 0ul); + rop->len = len; + + for (uint64_t i = 0; i < len; i++) { + if (mpz_tstbit(*op.bits, i + start)) mpz_setbit(*rop->bits, i); + } } uint64_t convert_uint64_t_of_bv_t(const bv_t op) { @@ -321,6 +335,12 @@ void mask(bv_t *rop) { } } +void truncate(bv_t *rop, const bv_t op, const mpz_t len) { + rop->len = mpz_get_ui(len); + mpz_set(*rop->bits, *op.bits); + mask(rop); +} + void and_bits(bv_t *rop, const bv_t op1, const bv_t op2) { rop->len = op1.len; mpz_and(*rop->bits, *op1.bits, *op2.bits); @@ -341,8 +361,11 @@ void xor_bits(bv_t *rop, const bv_t op1, const bv_t op2) { mpz_xor(*rop->bits, *op1.bits, *op2.bits); } +mpz_t eq_bits_test; + bool eq_bits(const bv_t op1, const bv_t op2) { - return mpz_cmp(*op1.bits, *op2.bits) == 0; + mpz_xor(eq_bits_test, *op1.bits, *op2.bits); + return mpz_popcount(eq_bits_test) == 0; } void sail_uint(mpz_t *rop, const bv_t op) { @@ -382,37 +405,122 @@ void sub_bits_int(bv_t *rop, const bv_t op1, const mpz_t op2) { mask(rop); } -void get_slice_int(bv_t *rop, const mpz_t n, const mpz_t m, const mpz_t o) { - // TODO +// Takes a slice of the (two's complement) binary representation of +// integer n, starting at bit start, and of length len. With the +// argument in the following order: +// +// get_slice_int(len, n, start) +// +// For example: +// +// get_slice_int(8, 1680, 4) = +// +// 11 0 +// V V +// get_slice_int(8, 0b0110_1001_0000, 4) = 0b0110_1001 +// <-------^ +// (8 bit) 4 +// +void get_slice_int(bv_t *rop, const mpz_t len_mpz, const mpz_t n, const mpz_t start_mpz) +{ + uint64_t start = mpz_get_ui(start_mpz); + uint64_t len = mpz_get_ui(len_mpz); + + mpz_set_ui(*rop->bits, 0ul); + rop->len = len; + + for (uint64_t i = 0; i < len; i++) { + if (mpz_tstbit(n, i + start)) mpz_setbit(*rop->bits, i); + } } -void set_slice_int(mpz_t *rop, const mpz_t n, const mpz_t m, const mpz_t o, const bv_t op) { - // TODO +// Set slice uses the same indexing scheme as get_slice_int, but it +// puts a bitvector slice into an integer rather than returning it. +void set_slice_int(mpz_t *rop, + const mpz_t len_mpz, + const mpz_t n, + const mpz_t start_mpz, + const bv_t slice) +{ + uint64_t start = mpz_get_ui(start_mpz); + + mpz_set(*rop, n); + + for (uint64_t i = 0; i < slice.len; i++) { + if (mpz_tstbit(*slice.bits, i)) { + mpz_setbit(*rop, i + start); + } else { + mpz_clrbit(*rop, i + start); + } + } } -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_update_subrange_bv_t(bv_t *rop, + const bv_t op, + const mpz_t n_mpz, + const mpz_t m_mpz, + const bv_t slice) +{ + uint64_t n = mpz_get_ui(n_mpz); + uint64_t m = mpz_get_ui(m_mpz); + + mpz_set(*rop->bits, *op.bits); + + for (uint64_t i = 0; i < n - (m - 1ul); i++) { + if (mpz_tstbit(*slice.bits, i)) { + mpz_setbit(*rop->bits, i + m); + } else { + mpz_clrbit(*rop->bits, i + m); + } + } } -void vector_subrange_bv_t(bv_t *rop, const bv_t op, const mpz_t n, const mpz_t m) { - // TODO +void vector_subrange_bv_t(bv_t *rop, const bv_t op, const mpz_t n_mpz, const mpz_t m_mpz) +{ + uint64_t n = mpz_get_ui(n_mpz); + uint64_t m = mpz_get_ui(m_mpz); + + mpz_set_ui(*rop->bits, 0ul); + rop->len = n - (m - 1ul); + + for (uint64_t i = 0; i < rop->len; i++) { + if (mpz_tstbit(*op.bits, i + m)) { + mpz_setbit(*rop->bits, i); + } else { + mpz_clrbit(*rop->bits, i); + } + } } -int bitvector_access(const bv_t op, const mpz_t n) { - return 0; // TODO +int bitvector_access(const bv_t op, const mpz_t n_mpz) { + uint64_t n = mpz_get_ui(n_mpz); + return mpz_tstbit(*op.bits, n); } void hex_slice (bv_t *rop, const sail_string hex, const mpz_t n, const mpz_t m) { - // TODO + fprintf(stderr, "hex_slice unimplemented"); + exit(1); } -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 -} +void set_slice (bv_t *rop, + const mpz_t len_mpz, + const mpz_t slen_mpz, + const bv_t op, + const mpz_t start_mpz, + const bv_t slice) +{ + uint64_t start = mpz_get_ui(start_mpz); -unit print_bits(const sail_string str, const bv_t op) { - fputs(str, stdout); - gmp_printf("%d'0x%ZX\n", op.len, op.bits); + mpz_set(*rop->bits, *op.bits); + rop->len = op.len; + + for (uint64_t i = 0; i < slice.len; i++) { + if (mpz_tstbit(*slice.bits, i)) { + mpz_setbit(*rop->bits, i + start); + } else { + mpz_clrbit(*rop->bits, i + start); + } + } } // ***** Real number implementation ***** @@ -425,10 +533,6 @@ typedef mpf_t real; #define FLOAT_PRECISION 255 -void setup_real(void) { - mpf_set_default_prec(FLOAT_PRECISION); -} - void init_real(real *rop) { mpf_init(*rop); } @@ -528,9 +632,67 @@ void init_real_of_sail_string(real *rop, const sail_string op) { // ***** 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; + fprintf(stderr, "write_ram unimplemented"); + exit(1); +} + +void read_ram(bv_t *data, const mpz_t m, const mpz_t n, const bv_t x, const bv_t addr_bv) { + uint64_t addr = mpz_get_ui(*addr_bv.bits); + uint32_t instr; + switch (addr) { + // print_char + case 0x400110: instr = 0xd10043ffu; break; + case 0x400114: instr = 0x39003fe0u; break; + case 0x400118: instr = 0x39403fe0u; break; + case 0x40011c: instr = 0x580003e1u; break; + case 0x400120: instr = 0x39000020u; break; + case 0x400124: instr = 0xd503201fu; break; + case 0x400128: instr = 0x910043ffu; break; + case 0x40012c: instr = 0xd65f03c0u; break; + // _start + case 0x400130: instr = 0xa9be7bfdu; break; + case 0x400134: instr = 0x910003fdu; break; + case 0x400138: instr = 0x94000007u; break; + case 0x40013c: instr = 0xb9001fa0u; break; + case 0x400140: instr = 0x52800080u; break; + case 0x400144: instr = 0x97fffff3u; break; + case 0x400148: instr = 0xd503201fu; break; + case 0x40014c: instr = 0xa8c27bfdu; break; + case 0x400150: instr = 0xd65f03c0u; break; + // main + case 0x400154: instr = 0xd10043ffu; break; + case 0x400158: instr = 0xb9000fffu; break; + case 0x40015c: instr = 0xb9000bffu; break; + case 0x400160: instr = 0x14000007u; break; + case 0x400164: instr = 0xb9400fe0u; break; + case 0x400168: instr = 0x11000400u; break; + case 0x40016c: instr = 0xb9000fe0u; break; + case 0x400170: instr = 0xb9400be0u; break; + case 0x400174: instr = 0x11000400u; break; + case 0x400178: instr = 0xb9000be0u; break; + case 0x40017c: instr = 0xb9400be0u; break; + case 0x400180: instr = 0x710fa01fu; break; + case 0x400184: instr = 0x54ffff0du; break; + case 0x400188: instr = 0xb9400fe0u; break; + case 0x40018c: instr = 0x910043ffu; break; + case 0x400190: instr = 0xd65f03c0u; break; + case 0x400194: instr = 0x00000000u; break; + case 0x400198: instr = 0x13000000u; break; + case 0x40019c: instr = 0x00000000u; break; + } + + mpz_set_ui(*data->bits, instr); + data->len = 32; + print_bits("instruction = ", *data); +} + +// ***** Setup and cleanup functions for library code ***** + +void setup_library(void) { + mpf_set_default_prec(FLOAT_PRECISION); + mpz_init(eq_bits_test); } -void read_ram(bv_t *data, const mpz_t m, const mpz_t n, const bv_t x, const bv_t y) { - // TODO +void cleanup_library(void) { + mpz_clear(eq_bits_test); } |
