arm-none-eabi-g++ generate bad code on while loop

Asked by A.C.

package: 5.3-2016q1 on cygwin.
FLags:
DBG= -O2
CPP_OPTS := -Wfatal-errors -Wextra -Wpedantic -Wconversion -Wshadow -Wall $(DBG) -std=c++11 -nostdlib -nostartfiles -fno-rtti -fno-exceptions -ffreestanding -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7-a -mtune=cortex-a7 -c

 Class Static member:

u32 caMiniUart::Recv1(void) {
    system_aux_mini_uart(mu);
    while (!mu->lsr.asBit.rxready);
    return mu->io.asReg;
}

where

typedef union mu_lsr_reg {
    struct tag_mu_lsr_reg {
        _R_ u32 rxready:1;
        _R_ u32 overrun:1;
        _R_ u32 dummy:3;
        _R_ u32 txempty:1;
        _R_ u32 txidle:1;
    } asBit;
    _RW_ u32 asReg;
} muLsrReg;

g++ generate the following assembler code .

_ZN10caMiniUart5Recv1Ev:
 @ args = 0, pretend = 0, frame = 0
 @ frame_needed = 0, uses_anonymous_args = 0
 @ link register save eliminated.
 mov r3, #20480
 movt r3, 16161
 ldrb r2, [r3, #84] @ zero_extendqisi2
 tst r2, #1
 bne .L58
.L57:
 b .L57
.L58:
 ldr r0, [r3, #64]
 bx lr
 .size _ZN10caMiniUart5Recv1Ev, .-_ZN10caMiniUart5Recv1Ev

I think the L57 label isn't in the right position : Must be 3 row up

gcc options error ?...sugest please...

Thanks.

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
A.C.
Solved:
Last query:
Last reply:
Revision history for this message
A.C. (angelogkcop) said :
#1

I have solved in this way.
I have declared the lsr field of struct mu as volatile.
The generated code is correct but isn't best optimized
as You can see:

_ZN10caMiniUart4Recv1Ev:
 @ args = 0, pretend = 0, frame = 0
 @ frame_needed = 0, uses_anonymous_args = 0
 @ link register save eliminated.
 mov r1, #20480 @ tmp118,
 movt r1, 16161 @ tmp118,
.L51:
 ldr r2, [r1, #84] @ tmp114,
 mov r3, #20480 @ tmp113, <--- Why here ? have to going after beq .L51
 movt r3, 16161 @ tmp113, <--- Why here ?
 tst r2, #1 @ tmp114,
 beq .L51 @,
 ldr r0, [r3, #64] @ D.5971, MEM[(struct aux_mini_uart *)1059147840B].io.asReg
 bx lr @

Revision history for this message
Andre Vieira (andre-simoesdiasvieira) said :
#2

Hi A.C.,

I am not able to reproduce this, could you post a more complete reduced example?

Cheers,
Andre

Revision history for this message
Andre Vieira (andre-simoesdiasvieira) said :
#3

Hi A.C.,

Thank you for sending me the files. Looking at it seems that for the 'bad' case you are compiling with:
arm-none-eabi-g++ -I . -S -Wfatal-errors -Wextra -Wpedantic -Wconversion -Wshadow -Wall -O2 -std=c++11 -nostdlib -nostartfiles -fno-rtti -fno-exceptions -ffreestanding -fverbose-asm -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7-a -mtune=cortex-a7 -c -o build/minuart.s miniuart.cpp

Which is missing the -DVOLDEF so the code in the access in the while loop is not volatile, so it knows that if the condition fails once, it will always fails and hence the infinite loop.

Cheers,
Andre