Skip to content

Instantly share code, notes, and snippets.

@shuffle2
Created November 20, 2010 21:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shuffle2/708153 to your computer and use it in GitHub Desktop.
Save shuffle2/708153 to your computer and use it in GitHub Desktop.
BITS
#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
*/
#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