Hi all (and Eric),
  I have a question about scalar_storage_order and support of type
punning between types that have different byte order.
Take:
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;

#define __big_endian__ scalar_storage_order("big-endian")
#define __little_endian__ scalar_storage_order("little-endian")

typedef union {
    uint32_t val;
    uint8_t v[4];
} __attribute__((__big_endian__)) upal_u32be_t;

typedef union {
    uint32_t val;
    uint8_t v[4];
} __attribute__((__little_endian__)) upal_u32le_t;

static inline uint32_t native_to_big_endian(uint32_t t)
{
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    return t;
#else
    return __builtin_bswap32(t);
#endif
}
static inline uint32_t native_to_little_endian(uint32_t t)
{
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    return __builtin_bswap32(t);
#else
    return t;
#endif
}
void link_error(void);

#ifndef __OPTIMIZE__
void link_error(void)
{
  __builtin_abort ();
}
#endif

#define test(p, p1, i) do { if (p[i] != p1[i]) link_error (); } while (0)

#define tests(p, p1) do { test(p, p1, 0); test(p, p1, 1); \
                          test(p, p1, 2); test(p, p1, 3); } while (0)

int main(void)
{
    uint8_t *p, *p1;
    uint32_t u = 0x12345678;
    uint32_t bu = ((upal_u32be_t*)&u)->val;
    uint32_t b1u = native_to_big_endian(u);
    p = (uint8_t*)&bu;
    p1 = (uint8_t*)&b1u;
    tests(p, p1);

    u = 0x12345678;
    uint32_t lu = ((upal_u32le_t*)&u)->val;
    uint32_t l1u = native_to_little_endian(u);
    p = (uint8_t*)&lu;
    p1 = (uint8_t*)&l1u;

    tests(p, p1);

    return 0;
}
---- CUT ---
Should this be allowed/working everywhere (I mean without considering
PDP byte order)?
Right now this works at -O0, we don't abort but at -O1 and above FRE
and CCP both misbehave in doing a constant prop of 0x12345678 through
the upal_u32le_t/upal_u32be_t access.
I notice this statement in the documentation:
Moreover, the use of type punning or aliasing to toggle the storage
order is not supported; that is to say, a given scalar object cannot
be accessed through distinct types that assign a different storage
order to it.
--- CUT ---
But I am not 100% sure that is the case here but I hope I am wrong in
saying this is not supported.

Thanks,
Andrew

Reply via email to