This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

endian problems using the pack(1) pragma for data structure by the powerpc compiler


Hello all,

I have endian problems using the reference operator (&),
the deference  operator (*) or the element deference  operator (->)
together witch data structs which are compiled using pack(1).
The problems appear onlx if these data structs are located within
the litlle endian part of the memory RAM.

These are the failure patterns using the various referencing mechanisms (& or * or ->) for float values:

write1:          testLE1 = (testT1*)LITTLE_ENDIAN_ADDRESS;
                   testLE1->floatvalue = 50.0;

read_1a:       var = testLE1->floatvalue           ok
read_1b:       f = &testLE1->floatvalue;
                   var = *f;                                    failure

write    2:      testLE1 = (testT1*)LITTLE_ENDIAN_ADDRESS;
                   f = &testLE1->floatvalue;
                   *f = 50.0;

read_2a:       var = testLE1->floatvalue           failure
read_2b:       f = &testLE1->floatvalue;
                   var = *f;                                    ok


Used hardware (target): Taishan board with PowerPC 440gx processor (big endian)

Development environment:
DENX Linux version 2.6.25.4
DENX ELDK version 4.1 build 2007-01-19
gcc release 4.0.0

Due to historical reasons the Linux kernel is configured so that a
small part of the memory can be used as an automated converter between little endian <-> big endian.
It is possible to write to a little endian address and read from the big endian address and vice versa.


I tried several possible invocations of the compiler, all show the same result :

gcc -mcpu=440 -mno-strict-align -pedantic -Wall -O0 -o endian_float_pack1a endian_float_pack1a.c
gcc -mcpu=405 -mno-strict-align -pedantic -Wall -O0 -o endian_float_pack1a endian_float_pack1a.c
gcc -mcpu=405 -mno-strict-align -Wall -O0 -o endian_float_pack1a endian_float_pack1a.c
gcc -mcpu=405 -Wall -O0 -o endian_float_pack1a endian_float_pack1a.c



My additional comment for the following code sample :




All accesses within the big endian part work well, regardsless of using pack(1) or pack(4).
Writing and reading of data structure elements with pack(4) within the little endian part is also ok -
but my program needs pack(1).



This is my code sample using pack(1) :


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


#define BIG_ENDIAN_ADDRESS 0xB0000000 #define LITTLE_ENDIAN_ADDRESS 0xB0200000 #define ENDIAN_SIZE 0x100000

//#pragma pack(4)
#pragma pack(1)
typedef struct test1
{
 char  mist;
 int   intvalue;
 float floatvalue;
} testT1;
#pragma pack(0)

int main(int argc, char *argv[])
{
 testT1 *testLE1;
 float  *f, float1, float2;
 char   *ch;

 testLE1 = (testT1*)LITTLE_ENDIAN_ADDRESS;
 testLE1->floatvalue = 50.0;

ch = (char*)&testLE1->floatvalue;
f = &testLE1->floatvalue;
printf("(1) %9f %9f [%02x,%02x,%02x,%02x] ", testLE1->floatvalue, *f, ch[0], ch[1], ch[2], ch[3]);
float1 = testLE1->floatvalue;
ch = (char*)&float1;
printf("%9f [%02x,%02x,%02x,%02x] ", float1, ch[0], ch[1], ch[2], ch[3]);
float2 = *f;
ch = (char*)&float2;
printf("%9f [%02x,%02x,%02x,%02x] ", float2, ch[0], ch[1], ch[2], ch[3]);
printf("%9f\n", *(&testLE1->floatvalue));


testLE1 = (testT1*)LITTLE_ENDIAN_ADDRESS;
f = &testLE1->floatvalue;
*f = 50.0;
ch = (char*)&testLE1->floatvalue;
f = &testLE1->floatvalue;
printf("(2) %9f %9f [%02x,%02x,%02x,%02x] ", testLE1->floatvalue, *f, ch[0], ch[1], ch[2], ch[3]);
float1 = testLE1->floatvalue;
ch = (char*)&float1;
printf("%9f [%02x,%02x,%02x,%02x] ", float1, ch[0], ch[1], ch[2], ch[3]);
float2 = *f;
ch = (char*)&float2;
printf("%9f [%02x,%02x,%02x,%02x] ", float2, ch[0], ch[1], ch[2], ch[3]);
printf("%9f\n", *(&testLE1->floatvalue));


 return 0;
}

If I run the program the console outputs are different :

Output onto the console using pack(4): The values in the brackets [....] show the byte ordering
(1) 50.000000 50.000000 [00,00,48,42] 50.000000 [42,48,00,00] 50.000000 [42,48,00,00] 50.000000
(2) 50.000000 50.000000 [00,00,48,42] 50.000000 [42,48,00,00] 50.000000 [42,48,00,00] 50.000000


Output onto the console using pack(1): The values in the brackets [....] show the byte ordering
(1) 50.000000 0.000000 [42,48,00,00] 50.000000 [42,48,00,00] 0.000000 [00,00,48,42] 50.000000
(2) 0.000000 50.000000 [00,00,48,42] 0.000000 [00,00,48,42] 50.000000 [42,48,00,00] 0.000000



regards Thomas

--

Thomas Korn
ifp - Ingenieurbüro für Prozessautomatisierung
Friedrich Werber Str. 44

D-78315 Radolfzell
Tel: (+49) 7732 98 27 89 - 13
Fax: (+49) 7732 98 27 89 - 44

Internet: www.ifp-beisch.com
EMail:    Thomas.Korn@ifp-beisch.com




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]