#ifndef PORT_H
#define PORT_H
#include <cstdint>
#ifdef WORDS_BIGENDIAN
#if defined(__GNUC__) && defined(__ppc__)
#define READ16LE(base) \
({ \
unsigned short lhbrxResult; \
__asm__("lhbrx %0, 0, %1" : "=r" (lhbrxResult) : "r" (base) : "memory"); \
lhbrxResult; \
})
#define READ32LE(base) \
({ \
unsigned long lwbrxResult; \
__asm__("lwbrx %0, 0, %1" : "=r" (lwbrxResult) : "r" (base) : "memory"); \
lwbrxResult; \
})
#define WRITE16LE(base, value) __asm__("sthbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
#define WRITE32LE(base, value) __asm__("stwbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
#else
// swaps a 16-bit value
inline uint16_t swap16(uint16_t v)
{
return (v << 8) | (v >> 8);
}
// swaps a 32-bit value
inline uint32_t swap32(uint32_t v)
{
return (v << 24) | ((v << 8) & 0xff0000) | ((v >> 8) & 0xff00) | (v >> 24);
}
template<typename T> inline uint16_t READ16LE(T *x) { return swap16(*reinterpret_cast<uint16_t *>(x)); }
template<typename T> inline uint32_t READ32LE(T *x) { return swap32(*reinterpret_cast<uint32_t *>(x)); }
template<typename T> inline void WRITE16LE(T *x, uint16_t v) { *reinterpret_cast<uint16_t *>(x) = swap16(v); }
template<typename T> inline void WRITE32LE(T *x, uint32_t v) { *reinterpret_cast<uint32_t *>(x) = swap32(v); }
#endif
#else
template<typename T> inline uint16_t READ16LE(T *x) { return *reinterpret_cast<uint16_t *>(x); }
template<typename T> inline uint32_t READ32LE(T *x) { return *reinterpret_cast<uint32_t *>(x); }
template<typename T> inline void WRITE16LE(T *x, uint16_t v) { *reinterpret_cast<uint16_t *>(x) = v; }
template<typename T> inline void WRITE32LE(T *x, uint32_t v) { *reinterpret_cast<uint32_t *>(x) = v; }
#endif
#endif // PORT_H