public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Bit field ordering on Big-Endian (SPARC) processor
@ 2012-12-11 13:01 Dipanjan Das
  2012-12-11 17:04 ` Paweł Sikora
  0 siblings, 1 reply; 5+ messages in thread
From: Dipanjan Das @ 2012-12-11 13:01 UTC (permalink / raw)
  To: gcc-help; +Cc: Gert Hulselmans

Consider the code below:


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#include <stdio.h>
#include <stdlib.h>

#define FORCE_CAST(var, type) *(type*)&var

struct processor_status_register
{
unsigned int cwp:5;
unsigned int et:1;
unsigned int ps:1;
unsigned int s:1;
unsigned int pil:4;
unsigned int ef:1;
unsigned int ec:1;
unsigned int reserved:6;

unsigned int c:1;
unsigned int v:1;
unsigned int z:1;
unsigned int n:1;

unsigned int ver:4;
unsigned int impl:4;
}__attribute__ ((__packed__));



struct registers
{
       unsigned long* registerSet;
       unsigned long* globalRegisters;
       unsigned long* cwptr;
       unsigned long wim, tbr, y, pc, npc;
       unsigned short registerWindows;

       /* Though Intel x86 architecture allows un-aligned memory
access, SPARC mandates memory accesses to be 8 byte aligned.
        Without __attribute__ ((aligned (8))) or a preceding dummy
byte e.g. unsigned short dummyByte, the code below crashes
        with a dreaded Bus error and Core dump. For more details,
follow the links below:

        http://blog.jgc.org/2007/04/debugging-solaris-bus-error-caused-by.html
        https://groups.google.com/forum/?fromgroups=#!topic/comp.unix.solaris/8SgFiMudGL4
*/

       struct processor_status_register __attribute__ ((aligned (8))) psr;
}__attribute__ ((__packed__));


int getBit(unsigned long bitStream, int position)
{
int bit;
bit = (bitStream & (1 << position)) >> position;
return bit;
}


char* showBits(unsigned long bitStream, int startPosition, int endPosition)
{
// Allocate one extra byte for NULL character
char* bits = (char*)malloc(endPosition - startPosition + 2);
int bitIndex;
for(bitIndex = 0; bitIndex <= endPosition; bitIndex++)
bits[bitIndex] = (getBit(bitStream, endPosition - bitIndex)) ? '1' : '0';
bits[bitIndex] = '\0';
return bits;
}


int main()
{
struct registers sparcRegisters; short isLittleEndian;

// Check for Endianness
        unsigned long checkEndian = 0x00000001;
        if(*((char*)(&checkEndian)))
            {printf("Little Endian\n"); isLittleEndian = 1;} // Little
Endian architecture detected
        else
            {printf("Big Endian\n"); isLittleEndian = 0;} // Big
Endian architecture detected

unsigned long registerValue = 0xF30010A7;
unsigned long swappedRegisterValue = isLittleEndian ? registerValue :
__builtin_bswap32(registerValue);
        sparcRegisters.psr = FORCE_CAST(swappedRegisterValue, struct
processor_status_register);
registerValue = isLittleEndian ? FORCE_CAST (sparcRegisters.psr,
unsigned long) : __builtin_bswap32(FORCE_CAST (sparcRegisters.psr,
unsigned long));
printf("\nPSR=0x%0X, IMPL=%u, VER=%u, CWP=%u\n", registerValue,
sparcRegisters.psr.impl, sparcRegisters.psr.ver,
sparcRegisters.psr.cwp);
printf("PSR=%s\n",showBits(registerValue, 0, 31));

sparcRegisters.psr.cwp = 7;
sparcRegisters.psr.et = 1;
sparcRegisters.psr.ps = 0;
sparcRegisters.psr.s = 1;
sparcRegisters.psr.pil = 0;
sparcRegisters.psr.ef = 0;
sparcRegisters.psr.ec = 0;
sparcRegisters.psr.reserved = 0;
sparcRegisters.psr.c = 0;
sparcRegisters.psr.v = 0;
sparcRegisters.psr.z = 0;
sparcRegisters.psr.n = 0;
sparcRegisters.psr.ver = 3;
sparcRegisters.psr.impl = 0xF;
registerValue = isLittleEndian ? FORCE_CAST (sparcRegisters.psr,
unsigned long) : __builtin_bswap32(FORCE_CAST (sparcRegisters.psr,
unsigned long));
printf("\nPSR=0x%0X, IMPL=%u, VER=%u, CWP=%u\n", registerValue,
sparcRegisters.psr.impl, sparcRegisters.psr.ver,
sparcRegisters.psr.cwp);
printf("PSR=%s\n\n",showBits(registerValue, 0, 31));

return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

I have used gcc-4.7.2 on Solaris 10 on SPARC to compile the following
code to produce the Big-Endian output:

Big Endian

PSR=0xF30010A7, IMPL=3, VER=15, CWP=20
PSR=11110011000000000001000010100111

PSR=0x3F00003D, IMPL=15, VER=3, CWP=7
PSR=00111111000000000000000000111101


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


I have used gcc-4.4 on Ubuntu-10.04 on Intel-x86 to compile the
following code to produce the Little-Endian output:

Little Endian

PSR=0xF30010A7, IMPL=15, VER=3, CWP=7
PSR=11110011000000000001000010100111

PSR=0xF30000A7, IMPL=15, VER=3, CWP=7
PSR=11110011000000000000000010100111


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


While the later one is as expected, can anyone please explain the
Big-Endian counterpart? Considering the showBits() method to be
correct, how can PSR=0x3F00003D give rise to IMPL=15, VER=3, CWP=7
values? How is the bit-field is being arranged and interpreted in
memory on a Big-Endian system?


--

Thanks & Regards,

Dipanjan

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Bit field ordering on Big-Endian (SPARC) processor
  2012-12-11 13:01 Bit field ordering on Big-Endian (SPARC) processor Dipanjan Das
@ 2012-12-11 17:04 ` Paweł Sikora
  2012-12-11 17:12   ` Holmes.Sherlock
  0 siblings, 1 reply; 5+ messages in thread
From: Paweł Sikora @ 2012-12-11 17:04 UTC (permalink / raw)
  To: gcc-help, its.dipanjan.das; +Cc: Gert Hulselmans

On Tuesday 11 of December 2012 18:31:06 Dipanjan Das wrote:
> Consider the code below:
> 
> #define FORCE_CAST(var, type) *(type*)&var

^^^^^^^^^^^^^^^^ don't forget to use -fno-strict-aliasing with such ugly tricks.

> struct processor_status_register
> {
> unsigned int cwp:5;
> unsigned int et:1;
> unsigned int ps:1;
> unsigned int s:1;
> unsigned int pil:4;
> unsigned int ef:1;
> unsigned int ec:1;
> unsigned int reserved:6;
> 
> unsigned int c:1;
> unsigned int v:1;
> unsigned int z:1;
> unsigned int n:1;
> 
> unsigned int ver:4;
> unsigned int impl:4;
> }__attribute__ ((__packed__));

iirc, the C language gives no guarantee of the ordering of fields within machine words,
so if you use them for the h/w register modeling, you program will not only be nonportable,
it will be compiler-dependent too. you should really read suitable byte/word/doubleword
from mapped h/w memory, convert it with le/be_to_cpu() method and shift/mask to access bits.

BR,
Paweł.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Bit field ordering on Big-Endian (SPARC) processor
  2012-12-11 17:04 ` Paweł Sikora
@ 2012-12-11 17:12   ` Holmes.Sherlock
  2012-12-11 18:12     ` Paweł Sikora
  0 siblings, 1 reply; 5+ messages in thread
From: Holmes.Sherlock @ 2012-12-11 17:12 UTC (permalink / raw)
  To: gcc-help

Paweł Sikora-2 wrote
> iirc, the C language gives no guarantee of the ordering of fields within
> machine words,
> so if you use them for the h/w register modeling, you program will not
> only be nonportable,
> it will be compiler-dependent too. you should really read suitable
> byte/word/doubleword
> from mapped h/w memory, convert it with le/be_to_cpu() method and
> shift/mask to access bits.

But here __attribute__ ((__packed__)) has been used. Doesn't it have any
effect? Or are we missing out the ordering compiler is enforcing? Isn't it
surprising that on Little Endian system the ordering is as we expect, while
in Big-Endian system, no apparent correlation is being found?



--
View this message in context: http://gcc.1065356.n5.nabble.com/Bit-field-ordering-on-Big-Endian-SPARC-processor-tp896566p896649.html
Sent from the gcc - Help mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Bit field ordering on Big-Endian (SPARC) processor
  2012-12-11 17:12   ` Holmes.Sherlock
@ 2012-12-11 18:12     ` Paweł Sikora
  2012-12-11 23:25       ` Holmes.Sherlock
  0 siblings, 1 reply; 5+ messages in thread
From: Paweł Sikora @ 2012-12-11 18:12 UTC (permalink / raw)
  To: gcc-help; +Cc: Holmes.Sherlock

On Tuesday 11 of December 2012 09:12:09 Holmes.Sherlock wrote:
> Paweł Sikora-2 wrote
> > iirc, the C language gives no guarantee of the ordering of fields within
> > machine words,
> > so if you use them for the h/w register modeling, you program will not
> > only be nonportable,
> > it will be compiler-dependent too. you should really read suitable
> > byte/word/doubleword
> > from mapped h/w memory, convert it with le/be_to_cpu() method and
> > shift/mask to access bits.
> 
> But here __attribute__ ((__packed__)) has been used. Doesn't it have any
> effect? Or are we missing out the ordering compiler is enforcing?

gcc's 'packed' attribute is related to the memory usage only.
ordering is still compiler specific.

> Isn't it surprising that on Little Endian system the ordering is as we expect,
> while in Big-Endian system, no apparent correlation is being found?

nothing should be surprising in the times when ARM cores could work in both modes :)

btw.
there's a thread about different ordering @ http://gcc.gnu.org/ml/gcc/2012-10/msg00016.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Bit field ordering on Big-Endian (SPARC) processor
  2012-12-11 18:12     ` Paweł Sikora
@ 2012-12-11 23:25       ` Holmes.Sherlock
  0 siblings, 0 replies; 5+ messages in thread
From: Holmes.Sherlock @ 2012-12-11 23:25 UTC (permalink / raw)
  To: gcc-help

Paweł Sikora-2 wrote
> gcc's 'packed' attribute is related to the memory usage only.
> ordering is still compiler specific.

Have you noticed that the number of 1's in first PSR output is 11 while on
the second case it is 12 ? How can bit reordering change number of 1's?



--
View this message in context: http://gcc.1065356.n5.nabble.com/Bit-field-ordering-on-Big-Endian-SPARC-processor-tp896566p896805.html
Sent from the gcc - Help mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-12-11 23:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-11 13:01 Bit field ordering on Big-Endian (SPARC) processor Dipanjan Das
2012-12-11 17:04 ` Paweł Sikora
2012-12-11 17:12   ` Holmes.Sherlock
2012-12-11 18:12     ` Paweł Sikora
2012-12-11 23:25       ` Holmes.Sherlock

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).