Odd....

Programming, for all ages and all languages.
Post Reply
Nychold

Odd....

Post by Nychold »

On one of the boards here (I think it was OS development), I noticed a very odd structure in C. It used a colon to denote using x bits of a variable, rather then using all of them. I'm just curious...does this work, and how? Like, for instance:

Code: Select all

typedef struct
{
  unsigned short red:5;
  unsigned short green:6;
  unsigned short blue:5;
} RGB16, *pRGB16;
Would this produce a color in the form of rrrrr gggggg bbbbb or bbbbb gggggg rrrrr? I would check this myself, but I'm not anywhere near a C/C++ compiler at the moment. Thanks, and pardon the dumb question. ^_^
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Odd....

Post by Candy »

Nychold wrote: Would this produce a color in the form of rrrrr gggggg bbbbb or bbbbb gggggg rrrrr? I would check this myself, but I'm not anywhere near a C/C++ compiler at the moment. Thanks, and pardon the dumb question. ^_^
To be completely correct, when storing it and viewing in a hex editor you would get:

Code: Select all

gggbbbbb rrrrrggg
but when reading as a 16-bit (or larger) int, you'd get:

Code: Select all

rrrrrggg gggbbbbb
because of little-endianness (assuming X86). It works on just about all modern compilers, and it uses a number of bits as it is specified to do.
Nychold

Re:Odd....

Post by Nychold »

So it's MSB->LSB. Okay...that's pretty much what I wanted to know. Didn't even know C/C++ could do that! Thanks! This'll make converting 15 bit, 16 bit, 24 bit, and 32 bit graphics much, MUCH easier. XD
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Odd....

Post by Pype.Clicker »

note that the MMX certainly has faster ways to do this. Geting x=color.red will be much like doing x=(color&RED_MASK)>>RED_SHIFT except the compiler picks up the mask and shift automagically and hides the details. So yes, it is easier to write, but not faster to execute than a pmunpack() stuff ...
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Odd....

Post by Candy »

Pype.Clicker wrote: note that the MMX certainly has faster ways to do this. Geting x=color.red will be much like doing x=(color&RED_MASK)>>RED_SHIFT except the compiler picks up the mask and shift automagically and hides the details. So yes, it is easier to write, but not faster to execute than a pmunpack() stuff ...
Note though that GCC doesn't really make clean code from that stuff using bitfields, at least not on -O2. Also, using MMX is not possible here since MMX only supports 2^n-sized amounts, not something like 5/6/5. MMX would extract just the same. Although, there is one method I can think of to speed up the process:

pshufw mm0, [edi], 0 - assuming edi points to the 16-bit color
pandq mm0, 0x0000F80007E0001F - assuming immediates are allowed... not sure
pmullw mm0, 0x0000000000400800 - again, assuming immediates
psrlw mm0, 11d

this puts the 5/6/5 triple in mm0 in words. However, if you want MMX/SSE speeds, try using 8-bit quantities, saves speed:

movd mm0, [edi]
punpcklbw mm0, 0x0

for the same result with 8-bit quantities.


Back to the topic, bitfields are quite useful for not-speed-critical things for GCC. If it's speed critical, make your own code (asm?). So things like page tables (usually) can be done in C code.
Post Reply