Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#2144 Ternary return operation produces incorrect assembly for C51

closed-rejected
Maarten Brock
None
MCS51
5
2013-05-25
2013-03-14
Anthony Wells
No

The following C code
#define SUCCESS 0
#define UART_SUCCESS 0
#define UART_BUFFER_FULL -3
...
return result == SUCCESS ? UART_SUCCESS : UART_BUFFER_FULL;

produces this asm:

mov a,r7
cjne    a,#0x01,00122$

00122$:
clr a
rlc a
mov r7,a
jz 00109$
mov r7,#0x00
sjmp 00110$
00109$:
mov r7,#0xFB
00110$:
mov dpl,r7
C$uart_0.c$205$1$39 ==.
XG$uart_writec$0$0 ==.
ret

for SDCC V3.20, x51, --model-large, --nooverlay

When assembled, it causes the MCU to reset at the instruction cjne a,#0x01,0.

The correct, unoptimized assembly should be:
mov a,r7
cjne a,#0x00,00109$
mov r7,#0x00
sjmp 00110$
00109$:
mov r7,#0xFB
00110$:
mov dpl,r7
C$uart_0.c$205$1$39 ==.
XG$uart_writec$0$0 ==.
ret

The corresponding if else structure

if (result == SUCCESS) {
    return UART_SUCCESS;
} else {
    return UART_BUFFER_FULL;
}

realizes the same problem in the asm.

Discussion

    • Category: --> MCS51
     
  • Maarten Brock
    Maarten Brock
    2013-05-24

    The MCU should not reset at that instruction as it is perfectly valid. Do not mistake the relative offet 0 for a jump to address 0x0000.

    Furthermore the generated code may be less optimal but it is not wrong. The CJNE will subtract 0x01 and only when A is zero will it set the Carry Flag which is subsequently shifted into A.

     
  • Maarten Brock
    Maarten Brock
    2013-05-24

    • status: open --> closed-rejected
    • assigned_to: Maarten Brock
    • Group: fixed --> non_bugs