This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem with uint32_t accesses using LDRD

To illustrate my problem, I just implemented demonstration code:

#include <stdint.h>

uint64_t read(const uint32_t *wordStream) {
    uint32_t low = *wordStream++;
    uint64_t high = *wordStream++;
    high <<= 32;
    return high | low;
}

This code reads (according to C) two unsigned 32 bit words.
It assumes a little endian notation.
Then it assembles these two words into a 64 bit value and returns it.

Unfortunately, the compiler assumes, that the first word is 64 bit aligned
(by using the LDRD instruction which is only allowed on aligned 64 bit values):

; generated by Component: ARM Compiler 5.06 update 1 (build 61) Tool: armcc [4d35ad]
; commandline armcc [--thumb -c --asm -otestCode.o --cpu=SC300 testCode.c]
        THUMB
        REQUIRE8
        PRESERVE8

        AREA ||.text||, CODE, READONLY, ALIGN=1

read PROC
        LDRD     r2,r1,[r0,#0]
        MOV      r0,r2
        BX       lr
        ENDP

...

Where did I tell the compiler that the first word is aligned?

Parents
  • /**
      \brief       Read 32-bit variable from network byte-order.
      \param[in]   u32  pointer to a variable.
      \return      32-bit result in host byte-order.
    */
    uint32_t net_rd_u32 (const uint8_t *u32) {
      uint32_t retv;
    
    #ifndef __USE_UNALIGNED_ACCESS
      retv  = u32[0] << 24;
      retv |= u32[1] << 16;
      retv |= u32[2] << 8;
      retv |= u32[3];
    #else
      retv = ntohl(*(uint32_t *)u32);
    #endif
      return (retv);
    }
    

Reply
  • /**
      \brief       Read 32-bit variable from network byte-order.
      \param[in]   u32  pointer to a variable.
      \return      32-bit result in host byte-order.
    */
    uint32_t net_rd_u32 (const uint8_t *u32) {
      uint32_t retv;
    
    #ifndef __USE_UNALIGNED_ACCESS
      retv  = u32[0] << 24;
      retv |= u32[1] << 16;
      retv |= u32[2] << 8;
      retv |= u32[3];
    #else
      retv = ntohl(*(uint32_t *)u32);
    #endif
      return (retv);
    }
    

Children
No data