From cce3259b5694bce0d5193f388e80fe7248ca951f Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Sun, 28 Apr 2024 17:37:18 +0530 Subject: [PATCH] Fixed bugs in base.c In particular, __LITTLE_ENDIAN__ was not a functioning macro. Instead, I implemented a version by hand (copied from IBM) that actually figures out if the machine is little endian or not. Thank you unit testing! --- lib/base.c | 46 +++++++++++++++++++--------------------------- lib/base.h | 15 +++++++++++---- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/lib/base.c b/lib/base.c index 99186e6..f34307b 100644 --- a/lib/base.c +++ b/lib/base.c @@ -28,61 +28,61 @@ union word_pun hword_t hword_htobc(hword_t w) { -#if __LITTLE_ENDIAN__ - return w; -#else + if (LITTLE_ENDIAN) + return w; union hword_pun x = {w}; union hword_pun y = {0}; for (size_t i = 0, j = HWORD_SIZE; i < HWORD_SIZE; ++i, --j) y.bytes[j - 1] = x.bytes[i]; return y.h; -#endif } hword_t hword_bctoh(hword_t w) { -#if __LITTLE_ENDIAN__ - return w; -#else + if (LITTLE_ENDIAN) + return w; union hword_pun x = {w}; union hword_pun y = {0}; for (size_t i = 0, j = HWORD_SIZE; i < HWORD_SIZE; ++i, --j) y.bytes[j - 1] = x.bytes[i]; return y.h; -#endif } word_t word_htobc(word_t w) { -#if __LITTLE_ENDIAN__ - return w; -#else + if (LITTLE_ENDIAN) + return w; union word_pun x = {w}; union word_pun y = {0}; for (size_t i = 0, j = WORD_SIZE; i < WORD_SIZE; ++i, --j) y.bytes[j - 1] = x.bytes[i]; return y.h; -#endif } word_t word_bctoh(word_t w) { -#if __LITTLE_ENDIAN__ - return w; -#else + if (LITTLE_ENDIAN) + return w; union word_pun x = {w}; union word_pun y = {0}; for (size_t i = 0, j = WORD_SIZE; i < WORD_SIZE; ++i, --j) y.bytes[j - 1] = x.bytes[i]; return y.h; -#endif } hword_t convert_bytes_to_hword(byte_t *bytes) { - hword_t be_h = 0; - memcpy(&be_h, bytes, HWORD_SIZE); - hword_t h = hword_bctoh(be_h); + hword_t h = 0; + for (size_t i = 0; i < HWORD_SIZE; ++i) + h |= ((hword_t)(bytes[i]) << (8 * i)); + return h; +} + +word_t convert_bytes_to_word(byte_t *bytes) +{ + word_t h = 0; + for (size_t i = 0; i < WORD_SIZE; ++i) + h |= ((word_t)(bytes[i]) << (8 * i)); return h; } @@ -97,11 +97,3 @@ void convert_word_to_bytes(word_t w, byte_t *bytes) word_t be_w = word_htobc(w); memcpy(bytes, &be_w, WORD_SIZE); } - -word_t convert_bytes_to_word(byte_t *bytes) -{ - word_t be_w = 0; - memcpy(&be_w, bytes, WORD_SIZE); - word_t w = word_bctoh(be_w); - return w; -} diff --git a/lib/base.h b/lib/base.h index 97bfeea..66043f1 100644 --- a/lib/base.h +++ b/lib/base.h @@ -97,6 +97,12 @@ typedef enum #define DHWORD(HWORD) ((data_t){.as_hword = (HWORD)}) #define DWORD(WORD) ((data_t){.as_word = (WORD)}) +// Macro to determine little endian +#ifndef LITTLE_ENDIAN +static const int __i = 1; +#define LITTLE_ENDIAN ((*((byte_t *)&__i)) == 0) +#endif + /** @brief Safely subtract SUB from W, where both are words (64 bit integers). @@ -124,8 +130,8 @@ typedef enum @brief Convert a buffer of bytes to a half word. @details We assume the buffer of bytes are in virtual machine byte - code format (big endian) and that they are at least HWORD_SIZE in - size. + code format (little endian) and that they are at least HWORD_SIZE + in size. */ hword_t convert_bytes_to_hword(byte_t *buffer); @@ -143,13 +149,14 @@ void convert_hword_to_bytes(hword_t h, byte_t *buffer); @brief Convert a buffer of bytes to a word. @details We assume the buffer of bytes are in virtual machine byte - code format (big endian) and that they are at least WORD_SIZE in + code format (little endian) and that they are at least WORD_SIZE in size. */ word_t convert_bytes_to_word(byte_t *); /** - @brief Convert a word into a VM byte code format bytes (big endian) + @brief Convert a word into a VM byte code format bytes (little + endian) @param w: Word to convert