Bug 20546 - Loading and storing of packed structure elements uses wrong endian for PPC EABI Little Endian
Summary: Loading and storing of packed structure elements uses wrong endian for PPC EA...
Status: RESOLVED WORKSFORME
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.4.0
: P1 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2005-03-19 01:21 UTC by Adam Weiner
Modified: 2005-08-23 01:01 UTC (History)
1 user (show)

See Also:
Host:
Target: powerpcle-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Adam Weiner 2005-03-19 01:21:18 UTC
Using GCC 3.4 3.4.0 20040225 (prerelease) PPC EABI Little-Endian. For packed
structure element read/writes, compiler is loading/storing data as big-endian
instead of little-endian. Seen with all optimization levels, including off.
Phenomena not seen with unpacked structures.

Source:

typedef struct _FOO {
    unsigned short a;
} __attribute((packed)) FOO;

FOO foo;

void test_case(void) {
    foo.a = 0x2233;
}

Generated assembly:

packed_bug.o:     file format elf32-powerpcle

Disassembly of section .text:

00000000 <test_case>:
   0:	e8 ff 21 94 	stwu	r1,-24(r1)
   4:	14 00 e1 93 	stw	r31,20(r1)
   8:	78 0b 3f 7c 	mr	r31,r1
   c:	00 00 20 3d 	lis	r9,0
  10:	00 00 29 39 	addi	r9,r9,0
  14:	00 00 09 88 	lbz	r0,0(r9) ; superfluous read (optimizaions off)
  18:	00 00 00 70 	andi.	r0,r0,0
  1c:	22 00 00 60 	ori	r0,r0,0x22
  20:	00 00 09 98 	stb	r0,0(r9) ; should be at 1(r9) not 0(r9)
  24:	01 00 09 88 	lbz	r0,1(r9) ; superfluous read (optimizations off)
  28:	00 00 00 70 	andi.	r0,r0,0
  2c:	33 00 00 60 	ori	r0,r0,0x33
  30:	01 00 09 98 	stb	r0,1(r9) ; should be at 0(r9) not 1(r9)
  34:	00 00 61 81 	lwz	r11,0(r1)
  38:	fc ff eb 83 	lwz	r31,-4(r11)
  3c:	78 5b 61 7d 	mr	r1,r11
  40:	20 00 80 4e 	blr

Offset 20: storing the upper 8-bits (0x22) into byte #0 instead of byte #1
Offset 30: storing the lower 8-bits (0x33) into byte #1 instead of byte #0

Result:

Memory location contains 0x3322 instead of 0x2233.

Here is a disassembly of the same function but with the packed attribute removed:

packed_bug.o:     file format elf32-powerpcle

Disassembly of section .text:

00000000 <test_case>:
   0:	e8 ff 21 94 	stwu	r1,-24(r1)
   4:	14 00 e1 93 	stw	r31,20(r1)
   8:	78 0b 3f 7c 	mr	r31,r1
   c:	00 00 20 3d 	lis	r9,0
  10:	33 22 00 38 	li	r0,0x2233 ; correct little-endian value
  14:	00 00 09 b0 	sth	r0,0(r9)  ; correct, stored as little-endian
  18:	00 00 61 81 	lwz	r11,0(r1)
  1c:	fc ff eb 83 	lwz	r31,-4(r11)
  20:	78 5b 61 7d 	mr	r1,r11
  24:	20 00 80 4e 	blr

-------------------------------

Compiler output (-v -save-temps):

c:\test>powerpcle-440-eabi-gcc -v -save-temps @options.cl packed_bug.c > t.txt
Reading specs from /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi
/3.4.0/specs
Configured with:  : (reconfigured)
Thread model: single
gcc version 3.4.0 20040225 (prerelease)
 /cygdrive/c/gcc_3.4_ppc_440/bin/../libexec/gcc/powerpcle-440-eabi/3.4.0/cc1.exe
 -E -quiet -v -I../../inc -I../.. -iprefix /cygdri
ve/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/ -DVE
NDOR_GEN packed_bug.c -mstrict-align -m
cpu=440 -mno-sched-prolog -W -Wall -Wno-parentheses -Wno-unused -Wno-uninitializ
ed -Wno-format -finline-limit=200 -fworking-directory -o packed_bug.i
ignoring nonexistent directory "/cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/power
pcle-440-eabi/3.4.0/../../../../powerpcle-440-eabi/sys-include"
ignoring nonexistent directory "/cygdrive/e/gcc_3.4_ppc_440/lib/gcc/powerpcle-44
0-eabi/3.4.0/include"
ignoring nonexistent directory "/cygdrive/e/gcc_3.4_ppc_440/powerpcle-440-eabi/s
ys-include"
ignoring nonexistent directory "/cygdrive/e/gcc_3.4_ppc_440/powerpcle-440-eabi/i
nclude"
#include "..." search starts here:
#include <...> search starts here:
 ../../inc
 ../..
 /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/include
 /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/../../../..
/powerpcle-440-eabi/include
End of search list.
 /cygdrive/c/gcc_3.4_ppc_440/bin/../libexec/gcc/powerpcle-440-eabi/3.4.0/cc1.exe
 -fpreprocessed packed_bug.i -mstrict-align -quiet -dumpbase packed_bug.c -mcpu=
440 -mno-sched-prolog -auxbase packed_bug -g -W -Wall -Wno-parentheses -Wno-unus
ed -Wno-uninitialized -Wno-format -version -finline-limit=200 -o packed_bug.s
GNU C version 3.4.0 20040225 (prerelease) (powerpcle-440-eabi)
        compiled by GNU C version 3.3.1 (cygming special).
GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=65463
 /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/../../../..
/powerpcle-440-eabi/bin/as.exe -m440 -V -Qy -mregnames -m440 -o packed_bug.o pac
ked_bug.s
GNU assembler version 2.14 (powerpcle-440-eabi) using BFD version 2.14 20030612
 /cygdrive/c/gcc_3.4_ppc_440/bin/../libexec/gcc/powerpcle-440-eabi/3.4.0/collect
2.exe -V -Qy -dn -Bstatic -L/cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle
-440-eabi/3.4.0 -L/cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc -L/cygdrive/c/gcc_3
.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/../../../../powerpcle-440-eab
i/lib packed_bug.o -lgcc -lgcc /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerp
cle-440-eabi/3.4.0/crtsavres.o
/cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/../../../../
powerpcle-440-eabi/bin/ld: warning: cannot find entry symbol _start; defaulting
to 01800074
GNU ld version 2.14 20030612
  Supported emulations:
   elf32lppc
   elf32ppcsim
Comment 1 Andrew Pinski 2005-03-19 01:26:44 UTC
PPC LE is not really supported any more.
Comment 2 Alan Modra 2005-08-23 01:01:34 UTC
I could not reproduce this with current 3.4, 4.0 or 4.1 sources on a
powerpc-linux targetted compiler using -mcall-eabi -mlittle, so I think the bug
has been fixed.