99 lines
2.0 KiB
C
99 lines
2.0 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "wires.h"
|
|
|
|
hilo unzip(val value) {
|
|
uint64_t hi, lo, val;
|
|
val = value.val;
|
|
hi = lo = 0;
|
|
for (int i=0; i<32; i++) {
|
|
lo |= (val & 1) << i;
|
|
val >>= 1;
|
|
hi |= (val & 1) << i;
|
|
val >>= 1;
|
|
}
|
|
hilo result;
|
|
result.hi = from_int(hi);
|
|
result.lo = from_int(lo);
|
|
return result;
|
|
}
|
|
|
|
val zip(hilo values) {
|
|
uint64_t hi = values.hi.val;
|
|
uint64_t lo = values.lo.val;
|
|
uint64_t result = 0;
|
|
for (int i=0; i<32; i++) {
|
|
result |= (hi & 1) << (2*i+1);
|
|
hi >>= 1;
|
|
result |= (lo & 1) << (2*i);
|
|
lo >>= 1;
|
|
}
|
|
return from_int(result);
|
|
}
|
|
|
|
val pick_bits(int lsb, int sz, val value) {
|
|
uint64_t v = value.val;
|
|
v >>= lsb;
|
|
if (sz < 64) {
|
|
uint64_t mask = 1;
|
|
mask <<= sz;
|
|
mask -= 1;
|
|
v &= mask;
|
|
}
|
|
return from_int(v);
|
|
}
|
|
|
|
val put_bits(int lsb, int sz, val value) {
|
|
val masked = pick_bits(0,sz,value);
|
|
masked.val <<= lsb;
|
|
return masked;
|
|
}
|
|
|
|
val pick_bits_arr(int msb, int sz, val arr[]) {
|
|
if (sz > 64) {
|
|
fprintf(stderr, "error: pick_bits_arr called with sz > 64");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
int offset = msb % 8;
|
|
int start_byte = msb / 8;
|
|
int covered_bytes = sz / 8;
|
|
|
|
uint64_t retval = 0;
|
|
for(int i = start_byte; i < covered_bytes; i++) {
|
|
retval += ((uint64_t) (arr[i].val)) >> (offset + i * 8);
|
|
}
|
|
|
|
uint64_t mask = ((uint64_t)-1) >> (64 - offset);
|
|
retval &= mask;
|
|
return from_int(retval);
|
|
}
|
|
|
|
|
|
bool pick_one(int position, val value) {
|
|
return ((value.val >> position) & 1) == 1;
|
|
}
|
|
|
|
val from_int(uint64_t v) {
|
|
val val;
|
|
val.val = v;
|
|
return val;
|
|
}
|
|
|
|
val reverse_bytes(int num_bytes, val value) {
|
|
uint64_t val = value.val;
|
|
uint64_t res = 0;
|
|
while (num_bytes--) {
|
|
res <<= 8;
|
|
res |= val & 0xFF;
|
|
val >>= 8;
|
|
}
|
|
return from_int(res);
|
|
}
|
|
|
|
val sign_extend(int sign_position, val value) {
|
|
uint64_t sign = value.val & (((uint64_t)1) << sign_position);
|
|
return from_int(value.val - (sign << 1));
|
|
}
|
|
|