diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/elf.c | 2 | ||||
| -rw-r--r-- | lib/elf.h | 2 | ||||
| -rw-r--r-- | lib/sail.c | 111 | ||||
| -rw-r--r-- | lib/sail.h | 20 |
4 files changed, 133 insertions, 2 deletions
@@ -357,7 +357,7 @@ void loadELFHdr(const char* buffer, const int total_file_size) { } } -void loadELF(char *filename) { +void load_elf(char *filename) { // Read input file into memory char* buffer = NULL; int size = 0; @@ -2,4 +2,4 @@ #include<string.h> -void loadELF(char *filename); +void load_elf(char *filename); @@ -37,6 +37,11 @@ unit UNDEFINED(unit)(const unit u) return UNIT; } +unit skip(const unit u) +{ + return UNIT; +} + /* ***** Sail bit type ***** */ bool eq_bit(const mach_bits a, const mach_bits b) @@ -453,6 +458,28 @@ void not_bits(sail_bits *rop, const sail_bits op) } } +void mults_vec(sail_bits *rop, const sail_bits op1, const sail_bits op2) +{ + mpz_t op1_int, op2_int; + mpz_init(op1_int); + mpz_init(op2_int); + sail_signed(&op1_int, op1); + sail_signed(&op2_int, op2); + rop->len = op1.len * 2; + mpz_mul(*rop->bits, op1_int, op2_int); + normalize_sail_bits(rop); + mpz_clear(op1_int); + mpz_clear(op2_int); +} + +void mult_vec(sail_bits *rop, const sail_bits op1, const sail_bits op2) +{ + rop->len = op1.len * 2; + mpz_mul(*rop->bits, *op1.bits, *op2.bits); + normalize_sail_bits(rop); /* necessary? */ +} + + void zeros(sail_bits *rop, const sail_int op) { rop->len = mpz_get_ui(op); @@ -465,6 +492,19 @@ void zero_extend(sail_bits *rop, const sail_bits op, const sail_int len) mpz_set(*rop->bits, *op.bits); } +void sign_extend(sail_bits *rop, const sail_bits op, const sail_int len) +{ + rop->len = mpz_get_ui(len); + if(mpz_tstbit(*op.bits, op.len - 1)) { + mpz_set(*rop->bits, *op.bits); + for(mp_bitcnt_t i = rop->len - 1; i >= op.len; i--) { + mpz_setbit(*rop->bits, i); + } + } else { + mpz_set(*rop->bits, *op.bits); + } +} + void length_sail_bits(sail_int *rop, const sail_bits op) { mpz_set_ui(*rop, op.len); @@ -659,6 +699,68 @@ void set_slice(sail_bits *rop, } } +void shift_bits_left(sail_bits *rop, const sail_bits op1, const sail_bits op2) +{ + rop->len = op1.len; + mpz_mul_2exp(*rop->bits, *op1.bits, mpz_get_ui(*op2.bits)); + normalize_sail_bits(rop); +} + +void shift_bits_right(sail_bits *rop, const sail_bits op1, const sail_bits op2) +{ + rop->len = op1.len; + mpz_tdiv_q_2exp(*rop->bits, *op1.bits, mpz_get_ui(*op2.bits)); +} + +/* FIXME */ +void shift_bits_right_arith(sail_bits *rop, const sail_bits op1, const sail_bits op2) +{ + rop->len = op1.len; + mp_bitcnt_t shift_amt = mpz_get_ui(*op2.bits); + mp_bitcnt_t sign_bit = op1.len - 1; + mpz_fdiv_q_2exp(*rop->bits, *op1.bits, shift_amt); + if(mpz_tstbit(*op1.bits, sign_bit) != 0) { + /* */ + for(; shift_amt > 0; shift_amt--) { + mpz_setbit(*rop->bits, sign_bit - shift_amt + 1); + } + } +} + +void reverse_endianness(sail_bits *rop, const sail_bits op) +{ + rop->len = op.len; + if (rop->len == 64ul) { + uint64_t x = mpz_get_ui(*op.bits); + x = (x & 0xFFFFFFFF00000000) >> 32 | (x & 0x00000000FFFFFFFF) << 32; + x = (x & 0xFFFF0000FFFF0000) >> 16 | (x & 0x0000FFFF0000FFFF) << 16; + x = (x & 0xFF00FF00FF00FF00) >> 8 | (x & 0x00FF00FF00FF00FF) << 8; + mpz_set_ui(*rop->bits, x); + } else if (rop->len == 32ul) { + uint64_t x = mpz_get_ui(*op.bits); + x = (x & 0xFFFF0000FFFF0000) >> 16 | (x & 0x0000FFFF0000FFFF) << 16; + x = (x & 0xFF00FF00FF00FF00) >> 8 | (x & 0x00FF00FF00FF00FF) << 8; + mpz_set_ui(*rop->bits, x); + } else if (rop->len == 16ul) { + uint64_t x = mpz_get_ui(*op.bits); + x = (x & 0xFF00FF00FF00FF00) >> 8 | (x & 0x00FF00FF00FF00FF) << 8; + mpz_set_ui(*rop->bits, x); + } else if (rop->len == 8ul) { + mpz_set(*rop->bits, *op.bits); + } else { + /* For other numbers of bytes we reverse the bytes. + * XXX could use mpz_import/export for this. */ + mpz_set_ui(sail_lib_tmp1, 0xff); // byte mask + mpz_set_ui(*rop->bits, 0); // reset accumulator for result + for(mp_bitcnt_t byte = 0; byte < op.len; byte+=8) { + mpz_tdiv_q_2exp(sail_lib_tmp2, *op.bits, byte); // shift byte to bottom + mpz_and(sail_lib_tmp2, sail_lib_tmp2, sail_lib_tmp1); // and with mask + mpz_mul_2exp(*rop->bits, *rop->bits, 8); // shift result left 8 + mpz_ior(*rop->bits, *rop->bits, sail_lib_tmp2); // or byte into result + } + } +} + /* ***** Sail Reals ***** */ void CREATE(real)(real *rop) @@ -890,3 +992,12 @@ unit sail_putchar(const sail_int op) putchar(c); return UNIT; } + +void get_time_ns(sail_int *rop, const unit u) +{ + struct timespec t; + clock_gettime(CLOCK_REALTIME, &t); + mpz_set_si(*rop, t.tv_sec); + mpz_mul_ui(*rop, *rop, 1000000000); + mpz_add_ui(*rop, *rop, t.tv_nsec); +} @@ -9,6 +9,8 @@ #include<gmp.h> #endif +#include<time.h> + /* * Called by the RTS to initialise and clear any library state. */ @@ -44,6 +46,8 @@ typedef int unit; unit UNDEFINED(unit)(const unit); bool eq_unit(const unit, const unit); +unit skip(const unit); + /* ***** Sail booleans ***** */ /* @@ -203,8 +207,13 @@ void or_bits(sail_bits *rop, const sail_bits op1, const sail_bits op2); void xor_bits(sail_bits *rop, const sail_bits op1, const sail_bits op2); void not_bits(sail_bits *rop, const sail_bits op); +void mults_vec(sail_bits *rop, const sail_bits op1, const sail_bits op2); +void mult_vec(sail_bits *rop, const sail_bits op1, const sail_bits op2); + void zeros(sail_bits *rop, const sail_int op); + void zero_extend(sail_bits *rop, const sail_bits op, const sail_int len); +void sign_extend(sail_bits *rop, const sail_bits op, const sail_int len); void length_sail_bits(sail_int *rop, const sail_bits op); @@ -250,6 +259,13 @@ void set_slice(sail_bits *rop, const sail_int start_mpz, const sail_bits slice); + +void shift_bits_left(sail_bits *rop, const sail_bits op1, const sail_bits op2); +void shift_bits_right(sail_bits *rop, const sail_bits op1, const sail_bits op2); +void shift_bits_right_arith(sail_bits *rop, const sail_bits op1, const sail_bits op2); + +void reverse_endianness(sail_bits*, sail_bits); + /* ***** Sail reals ***** */ typedef mpf_t real; @@ -310,3 +326,7 @@ unit print_int(const sail_string str, const sail_int op); unit prerr_int(const sail_string str, const sail_int op); unit sail_putchar(const sail_int op); + +/* ***** Misc ***** */ + +void get_time_ns(sail_int*, const unit); |
