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!
This commit is contained in:
46
lib/base.c
46
lib/base.c
@@ -28,61 +28,61 @@ union word_pun
|
|||||||
|
|
||||||
hword_t hword_htobc(hword_t w)
|
hword_t hword_htobc(hword_t w)
|
||||||
{
|
{
|
||||||
#if __LITTLE_ENDIAN__
|
if (LITTLE_ENDIAN)
|
||||||
return w;
|
return w;
|
||||||
#else
|
|
||||||
union hword_pun x = {w};
|
union hword_pun x = {w};
|
||||||
union hword_pun y = {0};
|
union hword_pun y = {0};
|
||||||
for (size_t i = 0, j = HWORD_SIZE; i < HWORD_SIZE; ++i, --j)
|
for (size_t i = 0, j = HWORD_SIZE; i < HWORD_SIZE; ++i, --j)
|
||||||
y.bytes[j - 1] = x.bytes[i];
|
y.bytes[j - 1] = x.bytes[i];
|
||||||
return y.h;
|
return y.h;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hword_t hword_bctoh(hword_t w)
|
hword_t hword_bctoh(hword_t w)
|
||||||
{
|
{
|
||||||
#if __LITTLE_ENDIAN__
|
if (LITTLE_ENDIAN)
|
||||||
return w;
|
return w;
|
||||||
#else
|
|
||||||
union hword_pun x = {w};
|
union hword_pun x = {w};
|
||||||
union hword_pun y = {0};
|
union hword_pun y = {0};
|
||||||
for (size_t i = 0, j = HWORD_SIZE; i < HWORD_SIZE; ++i, --j)
|
for (size_t i = 0, j = HWORD_SIZE; i < HWORD_SIZE; ++i, --j)
|
||||||
y.bytes[j - 1] = x.bytes[i];
|
y.bytes[j - 1] = x.bytes[i];
|
||||||
return y.h;
|
return y.h;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
word_t word_htobc(word_t w)
|
word_t word_htobc(word_t w)
|
||||||
{
|
{
|
||||||
#if __LITTLE_ENDIAN__
|
if (LITTLE_ENDIAN)
|
||||||
return w;
|
return w;
|
||||||
#else
|
|
||||||
union word_pun x = {w};
|
union word_pun x = {w};
|
||||||
union word_pun y = {0};
|
union word_pun y = {0};
|
||||||
for (size_t i = 0, j = WORD_SIZE; i < WORD_SIZE; ++i, --j)
|
for (size_t i = 0, j = WORD_SIZE; i < WORD_SIZE; ++i, --j)
|
||||||
y.bytes[j - 1] = x.bytes[i];
|
y.bytes[j - 1] = x.bytes[i];
|
||||||
return y.h;
|
return y.h;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
word_t word_bctoh(word_t w)
|
word_t word_bctoh(word_t w)
|
||||||
{
|
{
|
||||||
#if __LITTLE_ENDIAN__
|
if (LITTLE_ENDIAN)
|
||||||
return w;
|
return w;
|
||||||
#else
|
|
||||||
union word_pun x = {w};
|
union word_pun x = {w};
|
||||||
union word_pun y = {0};
|
union word_pun y = {0};
|
||||||
for (size_t i = 0, j = WORD_SIZE; i < WORD_SIZE; ++i, --j)
|
for (size_t i = 0, j = WORD_SIZE; i < WORD_SIZE; ++i, --j)
|
||||||
y.bytes[j - 1] = x.bytes[i];
|
y.bytes[j - 1] = x.bytes[i];
|
||||||
return y.h;
|
return y.h;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hword_t convert_bytes_to_hword(byte_t *bytes)
|
hword_t convert_bytes_to_hword(byte_t *bytes)
|
||||||
{
|
{
|
||||||
hword_t be_h = 0;
|
hword_t h = 0;
|
||||||
memcpy(&be_h, bytes, HWORD_SIZE);
|
for (size_t i = 0; i < HWORD_SIZE; ++i)
|
||||||
hword_t h = hword_bctoh(be_h);
|
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;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,11 +97,3 @@ void convert_word_to_bytes(word_t w, byte_t *bytes)
|
|||||||
word_t be_w = word_htobc(w);
|
word_t be_w = word_htobc(w);
|
||||||
memcpy(bytes, &be_w, WORD_SIZE);
|
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;
|
|
||||||
}
|
|
||||||
|
|||||||
15
lib/base.h
15
lib/base.h
@@ -97,6 +97,12 @@ typedef enum
|
|||||||
#define DHWORD(HWORD) ((data_t){.as_hword = (HWORD)})
|
#define DHWORD(HWORD) ((data_t){.as_hword = (HWORD)})
|
||||||
#define DWORD(WORD) ((data_t){.as_word = (WORD)})
|
#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).
|
@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.
|
@brief Convert a buffer of bytes to a half word.
|
||||||
|
|
||||||
@details We assume the buffer of bytes are in virtual machine byte
|
@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
|
code format (little endian) and that they are at least HWORD_SIZE
|
||||||
size.
|
in size.
|
||||||
*/
|
*/
|
||||||
hword_t convert_bytes_to_hword(byte_t *buffer);
|
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.
|
@brief Convert a buffer of bytes to a word.
|
||||||
|
|
||||||
@details We assume the buffer of bytes are in virtual machine byte
|
@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.
|
size.
|
||||||
*/
|
*/
|
||||||
word_t convert_bytes_to_word(byte_t *);
|
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
|
@param w: Word to convert
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user