Created
November 20, 2010 21:02
-
-
Save shuffle2/708153 to your computer and use it in GitHub Desktop.
BITS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> // for memset | |
// T : type | |
// F : offset in bits | |
// S : size in bits | |
template <typename T, int F, int S> | |
class BF | |
{ | |
public: | |
template <typename R> | |
inline BF& operator=(const R rhs) | |
{ | |
data &= ~mask; | |
data |= (rhs << F) & mask; | |
return *this; | |
}; | |
inline operator T() | |
{ | |
return (data & mask) >> F; | |
}; | |
private: | |
static const T mask = (T)0xFFFFFFFFFFFFFFFFULL >> (sizeof(T)*8 - S) << F; | |
T data; | |
}; | |
typedef unsigned int u32; | |
typedef unsigned short u16; | |
typedef unsigned char u8; | |
// | |
// | |
// | |
// some Dolphin struct with bitfields | |
struct wm_status_report | |
{ | |
u16 buttons; | |
u8 battery_low : 1; | |
u8 extension : 1; | |
u8 speaker : 1; | |
u8 ir : 1; | |
u8 leds : 4; | |
u8 padding2[2]; // two 00, TODO: this needs more investigation | |
u8 battery; | |
}; | |
// same struct made with template bitfield thingers | |
struct wm_status_report_new | |
{ | |
u16 buttons; | |
union | |
{ | |
BF<u8,0,1> battery_low; | |
BF<u8,1,1> extension; | |
BF<u8,2,1> speaker; | |
BF<u8,3,1> ir; | |
BF<u8,4,4> leds; | |
}; | |
u8 padding2[2]; // two 00, TODO: this needs more investigation | |
u8 battery; | |
}; | |
void myassert(bool a) | |
{ | |
static int num = 0; | |
if (!a) | |
printf("FAILED %d\n", num); | |
num++; | |
} | |
int main() | |
{ | |
wm_status_report sr1; | |
wm_status_report_new sr2; | |
// structs are the same size | |
myassert(sizeof(sr1) == sizeof(sr2)); | |
memset(&sr1, 0, sizeof(sr1)); | |
memset(&sr2, 0, sizeof(sr2)); | |
sr1.battery_low = 1; | |
sr2.battery_low = 1; | |
sr1.extension = 1; | |
sr2.extension = 1; | |
sr1.speaker = 1; | |
sr2.speaker = 1; | |
sr1.leds = 0xF; | |
sr2.leds = 0xF; | |
printf("sr1:"); | |
for (int i = 0; i < 6; i++) | |
printf("%02x ", (reinterpret_cast<u8*>(&sr1))[i]); | |
printf("sr2:"); | |
for (int i = 0; i < 6; i++) | |
printf("%02x ", (reinterpret_cast<u8*>(&sr2))[i]); | |
myassert(sr1.speaker == sr2.speaker); | |
myassert(sr1.leds == sr2.leds); | |
myassert(sr1.extension == sr2.extension); | |
myassert(sr1.battery_low == sr2.battery_low); | |
// structs are exactly the same | |
myassert(0 == memcmp(&sr1, &sr2, sizeof(sr1))); | |
printf("ALL GOOD\n"); | |
} | |
/* | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f4f0->8001e848| sr1: | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f504->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f504->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f504->8001e848| ef | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f504->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f504->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f504->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f524->8001e848| sr2: | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f534->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f534->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f534->8001e848| f7 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f534->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f534->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f534->8001e848| 00 | |
57:36:965 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f460->8001e848| FAILED 5 | |
57:36:966 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f5e8->8001eacc| ALL GOOD | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#define BIG_ENDIAN_WATEVER | |
// T : type | |
// F : offset in bits | |
// S : size in bits | |
template <typename T, int F, int S> | |
class BF | |
{ | |
public: | |
template <typename R> | |
inline BF& operator=(const R rhs) | |
{ | |
value = rhs; | |
return *this; | |
}; | |
inline operator T() | |
{ | |
return value; | |
}; | |
private: | |
#ifndef BIG_ENDIAN_WATEVER | |
struct | |
{ | |
T : F; | |
T value : S; | |
}; | |
#else | |
struct | |
{ | |
T : sizeof(T)*8 - F; | |
T value : S; | |
}; | |
#endif | |
}; | |
typedef unsigned int u32; | |
typedef unsigned short u16; | |
typedef unsigned char u8; | |
// some Dolphin struct with bitfields | |
struct wm_status_report | |
{ | |
u16 buttons; | |
u8 battery_low : 1; | |
u8 extension : 1; | |
u8 speaker : 1; | |
u8 ir : 1; | |
u8 leds : 4; | |
u8 padding2[2]; // two 00, TODO: this needs more investigation | |
u8 battery; | |
}; | |
// same struct made with template bitfield things | |
struct wm_status_report_new | |
{ | |
u16 buttons; | |
union | |
{ | |
BF<u8,0,1> battery_low; | |
BF<u8,1,1> extension; | |
BF<u8,2,1> speaker; | |
BF<u8,3,1> ir; | |
BF<u8,4,4> leds; | |
}; | |
u8 padding2[2]; // two 00, TODO: this needs more investigation | |
u8 battery; | |
}; | |
void myassert(bool a) | |
{ | |
static int num = 0; | |
if (!a) | |
printf("FAILED %d\n", num); | |
num++; | |
} | |
int main() | |
{ | |
wm_status_report sr1; | |
wm_status_report_new sr2; | |
// structs are the same size | |
myassert(sizeof(sr1) == sizeof(sr2)); | |
memset(&sr1, 0, sizeof(sr1)); | |
memset(&sr2, 0, sizeof(sr2)); | |
sr1.battery_low = 1; | |
sr2.battery_low = 1; | |
sr1.extension = 1; | |
sr2.extension = 1; | |
sr1.speaker = 1; | |
sr2.speaker = 1; | |
sr1.leds = 0xF; | |
sr2.leds = 0xF; | |
printf("sr1:"); | |
for (int i = 0; i < 6; i++) | |
printf("%02x ", (reinterpret_cast<u8*>(&sr1))[i]); | |
printf("sr2:"); | |
for (int i = 0; i < 6; i++) | |
printf("%02x ", (reinterpret_cast<u8*>(&sr2))[i]); | |
myassert(sr1.speaker == sr2.speaker); | |
myassert(sr1.leds == sr2.leds); | |
myassert(sr1.extension == sr2.extension); | |
myassert(sr1.battery_low == sr2.battery_low); | |
// structs are exactly the same | |
myassert(0 == memcmp(&sr1, &sr2, sizeof(sr1))); | |
printf("ALL GOOD\n"); | |
} | |
/* | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f460->8001e844| FAILED 0 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f4ec->8001e844| sr1: | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f500->8001e844| 00 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f500->8001e844| 00 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f500->8001e844| ef | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f500->8001e844| 00 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f500->8001e844| 00 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f500->8001e844| 00 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f520->8001e844| sr2: | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f530->8001e844| 00 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f530->8001e844| 00 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f530->8001e844| 0f | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f530->8001e844| 80 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f530->8001e844| 00 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f530->8001e844| 00 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f460->8001e844| FAILED 5 | |
03:31:105 .\Src\Hle\HLE_OS.cpp:52 N[OSREPORT]: 8000f5e4->8001eac8| ALL GOOD | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment