ARM Technical Support Knowledge Articles

Can the compiler generate LDRD/STRD instructions to access 64-bit peripherals?

Applies to: RealView Development Suite (RVDS)

Answer

Architecture v5TE and later processors provide LDRD and STRD instructions to load/store 64-bit data, for example, to access 64-bit peripherals.  These behave similarly to LDM/STM of two registers.

Unfortunately, there is an issue with the RVCT 3.x and RVCT 4.0 compilers whereby they are not always able to generate an LDRD/STRD (or LDM/STM) instruction when expected, for example, accessing a 64-bit peripheral.

For example, the following piece of code stores the 64-bit value 0x0123456789ABCDEF to address 0xA0000000:

void perip_64bitaccess(void)
{
  unsigned long long value = 0x0123456789ABCDEF;
  *((volatile unsigned long long*) (0xA0000000)) = value;
}

You might expect this code built with the following command line options to generate a double word store (STRD) instruction or a store multiple (STM) instruction:

armcc -c foo.c --cpu 6 -o foo.o
fromelf -c foo.o

However, the 3.x and 4.0 compilers may generate two STR instructions instead.

To workaround this issue with RVCT 3.0 you could simply write the LDRD/STRD instructions in assembly language and build the code using the ARM assembler. The RVCT 3.0 linker is able to inline such small instruction sequences.  Unfortunately the RVCT 3.1 linker is unable to inline LDRD/STRD instructions, but can inline the equivalent LDM/STM of two registers.

A workaround for both RVCT 3.x compilers is to write LDM/STM (of two registers) instructions in embedded assembler and pass the linker command line option --inline to ensure that the embedded assembly function is inlined by the linker, for example:

__asm void stm_llout(unsigned long long* addr, unsigned long long value)
{
  STM r0, {r2,r3}
  BX LR
}

__asm unsigned long long ldm_llin(unsigned long long* addr)
{
  LDM r0, {r0,r1}
  BX LR
}

unsigned long long perip_64bitaccess(void)
{
  unsigned long long ullvalue = ldm_llin((unsigned long long*)0x40004000);
  stm_llout((unsigned long long*)0x40000000, ullvalue);
  return ullvalue;
}

built with:

armcc -c foo.c --cpu 6 -o foo.o
armlink foo.o --inline -o foo.axf
fromelf -c foo.axf

generates inlined LDM/STM instructions. 

This issue is fixed in RVCT 4.0 b471 and later.  The latest patches for RVDS 4.0 are available from the ARM development tools downloads page.

Article last edited on: 2010-09-30 10:35:51

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential