ARMv8/src/shared/binary_util.c

58 lines
1.6 KiB
C

/** Binary Util */
#include <assert.h>
#include "binary_util.h"
word getBits(word wrd, uint8_t lsb, uint8_t msb) {
// Ensure LSB and MSB are within range of word size, and in the correct order
assert(lsb < msb && msb <= WORD_BITS);
wrd &= ((dword) 1 << msb) - 1;
return wrd >> lsb;
}
dword max(dword a, dword b) {
return a > b ? a : b;
}
dword truncateValue(dword value, a64inst_regType regType) {
if (regType == a64inst_X) {
return value;
} else {
return (word)value;
//return value & (dword)(((dword)1 << WORD_BITS) - 1);
}
}
// Sign extend a given value to a 64-bit signed integer given the number of bits
int64_t signExtend(dword value, unsigned int n) {
if (n == 0 || n >= 64) {
// If n_bits is 0 or greater than or equal to 64, return the value as is
return (int64_t)value;
}
uint64_t sign_bit_mask = (uint64_t)1 << (n - 1);
// Mask to isolate the n-bit value
uint64_t n_bit_mask = (sign_bit_mask << 1) - 1;
// Check if the sign bit is set
if (value & sign_bit_mask) {
// Sign bit is set, extend the sign
return (int64_t)(value | ~n_bit_mask);
} else {
// Sign bit is not set, return the value as is
return (int64_t)(value & n_bit_mask);
}
}
// Returns the position of the MSB of the given register type
dword getMSBPos(a64inst_regType regType) {
return (regType ? DWORD_BITS : WORD_BITS) - 1;
}
// Returns the MSB of the given value assuming it's of the size stored in the given register type
uint8_t getMSB(dword value, a64inst_regType regType) {
return (value >> getMSBPos(regType)) & 1u;
}