Canon ARM endianness, and GCC packing... - DryOS Development - CHDK Forum

Canon ARM endianness, and GCC packing...

  • 8 Replies
  • 6691 Views
Canon ARM endianness, and GCC packing...
« on: 09 / April / 2008, 14:29:36 »
Advertisements
ARM:
Anybody knows what is the endianness of the ARM processor?
Can ARM processor load an "unsigned int" on an odd address (ie not aligned)?
Can ARM processor load an "unsigned long" on an odd address (ie not dword or word aligned)?

GCC:
Let's say we have the following struct
struct {
   unsigned char byte0
   unsigned long byte1to5
} fivebytes1;

struct {
   unsigned long byte0to4
   unsigned char byte5
} fivebytes2;

fivebytes1 * p1;
fivebytes2 * p2;
unsigned char *pc1;
unsigned char *pc2;

What will be the value of pc2-pc1 assuming the following?
pc1 = (unsigned char *) p1;
p1++;
pc2 = (unsigned char *) p1;

What will be the value of pc2-pc1 assuming the following?
pc1 = (unsigned char *) p2;
p2++;
pc2 = (unsigned char *) p2;

*

Offline ewavr

  • ****
  • 1057
  • A710IS
Re: Canon ARM endianness, and GCC packing...
« Reply #1 on: 09 / April / 2008, 16:07:13 »
ARM:
Can ARM processor load an "unsigned int" on an odd address (ie not aligned)?
Can ARM processor load an "unsigned long" on an odd address (ie not dword or word aligned)?

I have negative experience on this (instruction seems correct, but return wrong value). But you can make own investigation (or read manuals)...

GCC:
Let's say we have the following struct
struct {
   unsigned char byte0
   unsigned long byte1to5
} fivebytes1;

By default sizeof(fivebytes1) is 8 (DWORD aligned).  Use #pragma pack(n) to make own alignment.

edit: Of course, I may be wrong here  :)
« Last Edit: 09 / April / 2008, 16:12:08 by ewavr »

*

Offline GrAnd

  • ****
  • 916
  • [A610, S3IS]
    • CHDK
Re: Canon ARM endianness, and GCC packing...
« Reply #2 on: 09 / April / 2008, 16:27:42 »
As EWAVR said, It depends on is the structure is packed or not. ARM processor can manage non-aligned data. But ARM code is 4byte aligned (unless it is thumb-code).

For example:
Code: (c) [Select]
struct fivebytes1 {
   unsigned char byte0;
   unsigned long byte1to5;
};

struct fivebytes2 {
   unsigned long byte0to4;
   unsigned char byte5;
};

struct fivebytes1p {
   unsigned char byte0;
   unsigned long byte1to5;
} __attribute__((__packed__));

struct fivebytes2p {
   unsigned long byte0to4;
   unsigned char byte5;
} __attribute__((__packed__));


const struct fivebytes1  fb1  = {0xAA, 0x12345678};
const struct fivebytes2  fb2  = {0x12345678, 0xAA};
const struct fivebytes1p fb1p = {0xAA, 0x12345678};
const struct fivebytes2p fb2p = {0x12345678, 0xAA};

Creates the following:
Code: (asm) [Select]
.rodata:0000004C ; Segment type: Pure data
.rodata:0000004C                 AREA .rodata, DATA, READONLY
.rodata:0000004C                 ; ORG 0x4C
.rodata:0000004C                 EXPORT fb1
.rodata:0000004C fb1             DCB 0xAA, 0, 0, 0, 0x78, 0x56, 0x34, 0x12
.rodata:00000054                 EXPORT fb2
.rodata:00000054 fb2             DCB 0x78, 0x56, 0x34, 0x12, 0xAA, 0, 0, 0
.rodata:0000005C                 EXPORT fb1p
.rodata:0000005C fb1p            DCB 0xAA, 0x78, 0x56, 0x34, 0x12
.rodata:00000061                 EXPORT fb2p
.rodata:00000061 fb2p            DCB 0x78, 0x56, 0x34, 0x12, 0xAA
.rodata:00000066                 ALIGN 4
.rodata:00000066 ; _rodata       ends
CHDK Developer.

*

Offline ewavr

  • ****
  • 1057
  • A710IS
Re: Canon ARM endianness, and GCC packing...
« Reply #3 on: 09 / April / 2008, 17:03:05 »
Someting is wrong here...

char xxx[]={1,2,3,4,5,6,7,8};

sprintf(osd_buf, "%08x  ", *(unsigned long*) xxx);
output: 04030201 - correct

sprintf(osd_buf, "%08x  ", *(unsigned long*) (xxx+1));
output: 01040302 - incorrect

sprintf(osd_buf, "%08x  ", *(unsigned long*) (xxx+2));
output: 02010403 - incorrect

sprintf(osd_buf, "%08x  ", *(unsigned long*) (xxx+4));
output: 08070605 - correct


*

Offline DataGhost

  • ****
  • 314
  • EOS 40D, S5IS
    • DataGhost.com
Re: Canon ARM endianness, and GCC packing...
« Reply #4 on: 09 / April / 2008, 17:13:07 »
« Last Edit: 09 / April / 2008, 17:19:07 by DataGhost »

*

Offline GrAnd

  • ****
  • 916
  • [A610, S3IS]
    • CHDK
Re: Canon ARM endianness, and GCC packing...
« Reply #5 on: 09 / April / 2008, 17:17:49 »
Something is wrong here...

May be bug in sprintf?
Is the math is also incorrect? For example:

char xxx[]={1,2,3,4,5,6,7,8};
unsigned long res;

res = (*(unsigned long*) (xxx+1)) - (*(unsigned long*) (xxx));
sprintf(osd_buf, "%08x  ", res);

res = (*(unsigned long*) (xxx+2)) - (*(unsigned long*) (xxx));
sprintf(osd_buf, "%08x  ", res);

res = (*(unsigned long*) (xxx+2)) - (*(unsigned long*) (xxx+1));
sprintf(osd_buf, "%08x  ", res);

res = (*(unsigned long*) (xxx+4)) - (*(unsigned long*) (xxx));
sprintf(osd_buf, "%08x  ", res);


???
CHDK Developer.

*

Offline ewavr

  • ****
  • 1057
  • A710IS
Re: Canon ARM endianness, and GCC packing...
« Reply #6 on: 09 / April / 2008, 18:06:01 »
May be bug in sprintf?

May be or maybe?  :D

char xxx[]={1,2,3,4,5,6,7,8};
unsigned long res;
res= *(unsigned long*) (xxx);
sprintf(osd_buf, "4:%08x  ",res );

output: 04030201 - correct
assembler:

ldr   r1, [pc, #408] ;  "4:%08x  "
ldr   r2, [sp, #64]  ;  *(unsigned long*) (xxx)
adds   r0, r4, #0      ;   osd_buf[]
bl   af004 <__sprintf_from_thumb>

Now:

char xxx[]={1,2,3,4,5,6,7,8};
unsigned long res;
res= *(unsigned long*) (xxx+1);
sprintf(osd_buf, "4:%08x  ",res );

output: 01040302 - incorrect

assembler:
mov   r3, sp             
adds   r3, #65         
ldr   r2, [r3, #0]     ; res= *(unsigned long*) (xxx+1) - not too smart compiler  :)
ldr   r1, [pc, #408]    ;  "4:%08x  "
adds   r0, r4, #0  ;   osd_buf[]
bl   af008 <__sprintf_from_thumb>

So, "ldr r2, [sp, #64]"  - correct data, "ldr r2, [sp, #65]"  - incorrect data.
« Last Edit: 09 / April / 2008, 18:15:53 by ewavr »

*

Offline DataGhost

  • ****
  • 314
  • EOS 40D, S5IS
    • DataGhost.com
Re: Canon ARM endianness, and GCC packing...
« Reply #7 on: 09 / April / 2008, 18:16:49 »
Well, the data is technically correct, if you look at the architecture implementation/notes. The result is just not what you'd expect but I guess that's just something to keep in mind. I think it's a limitation of the MMU which would otherwise require 2 loads from memory or it just wasn't implemented for sake of simplicity. In some cases, it might even be useful, as loading and rotating can happen in one operation, though it's probably only noticable (performance-wise) in a really, really tight and often-executed loop.


*

Offline ewavr

  • ****
  • 1057
  • A710IS
Re: Canon ARM endianness, and GCC packing...
« Reply #8 on: 09 / April / 2008, 19:10:38 »
I guess it does load the values but stays within the word boundary and then shifts the value somehow. This is probably documented or documented as 'undefined', I'll see if I can find something in the ARM docs :)

Why yes, I can.

Unfortunately, I do not have time to read this. Now, everything is clear to me.

 

Related Topics