Team,
This customer has found a bug in the atomic.s library. Please confirm the customer's findings below.
After getting the appropriate documentation, learning the ARM Assembly opcode mnemonics, and hand-assembling my own instructions, I have success.
For your reference, I've now reworked the atomic.s file, and have placed hand-coded assembly instructions directly as emitted bytes into the execution stream (.field values).
The resulting compiler generated code is correct, executes correctly, and decompiles correctly, but steps incorrectly (obviously) in the debugger instruction stream.
At present, this is the only work-around I've been able to implement. But the good thing, is that at least it is working and I can continue development. Please let me know when/how this will be addressed in the compiler/assembler.
Here is the issue I've encountered with the TMS470 Compiler in Code Composer Studio. ( Version: 4.2.4.00033 )
I'm attempting to implement a Byte/Short/Long Atomic Byte Swap function, which I intend to use with the bit-banding capability in the ARM Cortex-M3 processor. To get this to compile, I have tried everything from inline assembly, to separate assembly language files, to aliased registers, to ... now giving up trying to use the STREX instruction.
The atomic.s code I've provided/attached compiles as follows:
11 00000000 .thumb
12 00000000 .sect ".text"
13
14 ;; uint8_t AtomicSwapByte (uint8_t nValue, uint8_t *pData);
15 .global AtomicSwapByte
16 .thumbfunc AtomicSwapByte
17 AtomicSwapByte: .asmfunc
18 00000000 3F4FE8D1 ldrexb r3, [r1] ; [KEEP 32-BIT INS]
19 00000004 0F42E8C1 strexb r2, r0, [r1] ; [KEEP 32-BIT INS]
20 00000008 2A01 cmp r2, #1 ; [ORIG 16-BIT INS]
21 0000000a D0F9 beq AtomicSwapByte ; [ORIG 16-BIT INS]
22 0000000c 4618 mov r0, r3 ; [ORIG 16-BIT INS]
23 0000000e 4770 bx lr ; [ORIG 16-BIT INS]
24 .endasmfunc
25
26 ;; uint16_t AtomicSwapShort(uint16_t nValue, uint16_t *pData);
27 .global AtomicSwapShort
28 .thumbfunc AtomicSwapShort
29 AtomicSwapShort: .asmfunc
30 00000010 3F5FE8D1 ldrexh r3, [r1] ; [KEEP 32-BIT INS]
31 00000014 0F42E8C1 strexh r2, r0, [r1] ; [KEEP 32-BIT INS]
32 00000018 2A01 cmp r2, #1 ; [ORIG 16-BIT INS]
33 0000001a D0F9 beq AtomicSwapShort ; [ORIG 16-BIT INS]
34 0000001c 4618 mov r0, r3 ; [ORIG 16-BIT INS]
35 0000001e 4770 bx lr ; [ORIG 16-BIT INS]
36 .endasmfunc
37
38 ;; uint32_t AtomicSwapLong (uint32_t nValue, uint32_t *pData);
39 .global AtomicSwapLong
40 .thumbfunc AtomicSwapLong
41 AtomicSwapLong: .asmfunc
42 00000020 3F00E851 ldrex r3, [r1] ; [KEEP 32-BIT INS]
43 00000024 0F02E841 strex r2, r0, [r1] ; [KEEP 32-BIT INS]
44 00000028 2A01 cmp r2, #1 ; [ORIG 16-BIT INS]
45 0000002a D0F9 beq AtomicSwapLong ; [ORIG 16-BIT INS]
46 0000002c 4618 mov r0, r3 ; [ORIG 16-BIT INS]
47 0000002e 4770 bx lr ; [ORIG 16-BIT INS]
48 .endasmfunc
When decompiled, or viewed in the debugger, this code becomes:
AtomicSwapByte:
0x00008C60: E8D13F4F LDREXB.W R3, [R1]
0x00008C64: E8C10F42 STREXB.W R2, R0, [R1]
0x00008C68: 2A01 CMP R2, #0x1
0x00008C6A: D0F9 BEQ AtomicSwapByte
0x00008C6C: 4618 MOV R0, R3
0x00008C6E: 4770 BX R14
AtomicSwapShort:
0x00008C70: E8D13F5F LDREXH.W R3, [R1]
0x00008C74: E8C10F42 STREXB.W R2, R0, [R1]
0x00008C78: 2A01 CMP R2, #0x1
0x00008C7A: D0F9 BEQ AtomicSwapShort
0x00008C7C: 4618 MOV R0, R3
0x00008C7E: 4770 BX R14
AtomicSwapLong:
0x00008C80: E8513F00 LDREX.W R3, [R1, #0]
0x00008C84: E8410F02 STREX.W PC, R0, [R1, #8]
0x00008C88: 2A01 CMP R2, #0x1
0x00008C8A: D0F9 BEQ AtomicSwapLong
0x00008C8C: 4618 MOV R0, R3
0x00008C8E: 4770 BX R14
I've encountered the following two issues with the assembler output produced:
1). The STREXH opcode in AtomicSwapShort is incorrectly replaced with a STREXB opcode.
2). The STREX opcode in AtomicSwapLong is incorrectly replaced with a PC relative result location, with an #8 byte offset specified.
Modified atomic.s file
;;***************************************************************************** ;; Title: Disruptive Limited - Inception ;; Author: Robert P. Beyer ;; iSolutions (NZ) Limited ;; Contract: Objective Concepts LLC / Disruptive Limited ;; Date: May 10, 2011 ;; Software: Code Composer Studio ;; Hardware: Luminary Micro LM3S5R36, Apple Authentication Co-processor ;;***************************************************************************** .thumb .sect ".text" ;; uint8_t AtomicSwapByte (uint8_t nValue, uint8_t *pData); .global AtomicSwapByte .thumbfunc AtomicSwapByte .clink AtomicSwapByte: .asmfunc ldrexb r3, [r1] ;; strexb r2, r0, [r1] .field 0x0F42E8C1 cmp r2, #1 beq AtomicSwapByte mov r0, r3 bx lr .endasmfunc ;; uint16_t AtomicSwapShort(uint16_t nValue, uint16_t *pData); .global AtomicSwapShort .thumbfunc AtomicSwapShort .clink AtomicSwapShort: .asmfunc ldrexh r3, [r1] ;; strexh r2, r0, [r1] .field 0x0F52E8C1 cmp r2, #1 beq AtomicSwapShort mov r0, r3 bx lr .endasmfunc ;; uint32_t AtomicSwapLong (uint32_t nValue, uint32_t *pData); .global AtomicSwapLong .thumbfunc AtomicSwapLong .clink AtomicSwapLong: .asmfunc ldrex r3, [r1] ;; strex r2, r0, [r1] .field 0x0200E841 cmp r2, #1 beq AtomicSwapLong mov r0, r3 bx lr .endasmfunc ;;***************************************************************************** ;; ;; End of the file ;; ;;***************************************************************************** .end ;; E8410200 strex r2, r0, [r1] ;; E8C10F52 strexh r2, r0, [r1] ;; E8C10F42 strexb r2, r0, [r1]