Menu

#3740 Codegen error for SM83/GBZ80

closed-fixed
Z80
5
2024-06-03
2024-06-03
bbbbbr
No
sdcc -v
SDCC : z80/sm83/mos6502/mos65c02 TD- 4.4.1 #14877 (Linux)
published under GNU General Public License (GPL)

Getting a codegen error on sm83/gbz80 where a variable declared as stack local should get a return value from a function but instead is overwritten before it can be tested. I've reduced it to a fairly minimal test case.

sdcc -msm83 --no-std-crt0 --fsigned-char --use-stdout -Wa-pogn -c main.c -o main.o

Test case:

unsigned char some_param;
unsigned char some_var;

unsigned char some_func(unsigned char value);

#define J_A       0x10
#define J_START   0x80

#define true 1
#define false 0

void main(void) {

    unsigned char some_return_value = some_func(some_param);

    some_var = false;

    if (some_return_value == J_A) {
        some_var = true;
    }
}

Output:

_main::
;main.c:14: unsigned char some_return_value = some_func(some_param);
    ld  a, (_some_param)
    call    _some_func

;main.c:16: some_var = false; 
    xor a, a    ; <--------- return value stored in A overwritten
    ld  hl, #_some_var
    ld  (hl), a

;main.c:18: if (some_return_value == J_A) {
    sub a, #0x10  ; <--------- Test is now inaccurate
    ret NZ

;main.c:19: some_var = true;
    ld  (hl), #0x01

;main.c:21: }
    ret

Discussion

  • bbbbbr

    bbbbbr - 2024-06-03

    Looks like the issue begins to show up starting with:
    commit 14814 : Improve storing of 0 into global variables.
    https://sourceforge.net/p/sdcc/code/14814/

     
  • bbbbbr

    bbbbbr - 2024-06-03

    By the way, the previous generated code without the issue looked like this:

    sdcc -v
    SDCC : z80/sm83/mos6502/mos65c02 TD- 4.4.1 #14813 (Linux)
    published under GNU General Public License (GPL)
    
    _main::
    ;main.c:22: unsigned char some_return_value = some_func(some_param);
        ld  a, (_some_param)
        call    _some_func
    
    ;main.c:24: some_var = false;
        ld  hl, #_some_var
        ld  (hl), #0x00
    
    ;main.c:26: if (some_return_value == J_A) {
        sub a, #0x10
        ret NZ
    
    ;main.c:27: some_var = true;
        ld  (hl), #0x01
    
    ;main.c:29: }
        ret
    
     
  • Janko Stamenović

    I also get this with -mz80, [r14877]

    unsigned char some_param;
    unsigned char some_var;
    unsigned char some_func(unsigned char value);
    
    void main(void) {
        unsigned char some_return_value = some_func(some_param);
        some_var = 0;
        if (some_return_value == 0x10) {
            some_var = 1;
        }
    }
    

    produces here:

    _main::
    ;check.c:6: unsigned char some_return_value = some_func(some_param);
        ld  a, (_some_param)
        call    _some_func
    ;check.c:7: some_var = 0;
        xor a, a
        ld  (_some_var+0), a
    ;check.c:8: if (some_return_value == 0x10) {
        sub a, #0x10
        ret NZ
    ;check.c:9: some_var = 1;
        ld  hl, #_some_var
        ld  (hl), #0x01
    ;check.c:11: }
    

    Where xor a, a also destroys the output of the function before the A is to be used in the if statement.

     

    Related

    Commit: [r14877]


    Last edit: Maarten Brock 2024-06-06
  • Philipp Klaus Krause

    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
    • Category: GBZ80 --> Z80
     
  • Philipp Klaus Krause

    Fixed in [r14878].

     

    Related

    Commit: [r14878]

  • bbbbbr

    bbbbbr - 2024-06-03

    Thanks for the quick fix on this!

    It appears to fix the issue in the original larger code too.

     

    Last edit: bbbbbr 2024-06-03

Log in to post a comment.