Menu

#904 Z80 reg. assignment: default: sub-optimal but --reserve-regs-iy: optimal

None
closed-fixed
None
5
2024-04-12
2024-04-01
No

For the following C:

extern void fwrite(unsigned char handle, unsigned char* buf, unsigned short bytes);

unsigned char recbuff[ 513 ];
unsigned char* p_recbyte_next;
unsigned char f_out;


unsigned char bump_recbuf_2( void ) {
    unsigned char c = *(p_recbyte_next-1);
    fwrite( f_out,  recbuff, p_recbyte_next -1 - recbuff );
    *recbuff = c;
    p_recbyte_next = recbuff + 1;
    return 44;
}

Using

; SDCC ... TD- 4.4.1 #14768 (MINGW64)
sdcc   -mz80 --opt-code-size --fverbose-asm      --max-allocs-per-node2000000 --no-std-crt0 --nostdlib  --Werror --peep-asm --peep-return  -c 

I get:

;   Register assignment might be sub-optimal.
; Stack space usage: 0 bytes.

and count 46 bytes, 225 T

Whereas using: --reserve-regs-iy

; SDCC ... TD- 4.4.1 #14768 (MINGW64)
sdcc   -mz80 --reserve-regs-iy --opt-code-size --fverbose-asm       --max-allocs-per-node2000000 --no-std-crt0 --nostdlib  --Werror --peep-asm --peep-return  -c  

I get:

;   Register assignment is optimal.
; Stack space usage: 0 bytes.

and count: 38 bytes, 195 T

The reason seems to be that somehow without --reserve-regs-iy SDCC decides that using IY is better than not using it, producing after the fwrite call:

0000001B 21r00r00         [10]   80     ld  hl, #_recbuff
0000001E 71               [ 7]   81     ld  (hl), c
0000001F FD 21r01r02      [14]   82     ld  iy, #_p_recbyte_next
00000023 FD 36 00r01      [19]   83     ld  0 (iy), #<((_recbuff + 1))
00000027 FD 36 01s00      [19]   84     ld  1 (iy), #>((_recbuff + 1))
0000002B 3E 2C            [ 7]   85     ld  a, #0x2c

while with --reserve-regs-iy SDCC it produces:

0000001B 21r00r00         [10]   80     ld  hl, #_recbuff
0000001E 71               [ 7]   81     ld  (hl), c
0000001F 23               [ 6]   82     inc hl
00000020 22r01r02         [16]   83     ld  (_p_recbyte_next), hl
00000023 3E 2C            [ 7]   84     ld  a, #0x2c

(I'm actually targeting with --reserve-regs-iy SDCC for that what I write at the moment, but now running more than one kind of compilation just to learn more, it was unexpected enough that maybe could be considered a bug?)

Discussion

  • Philipp Klaus Krause

    Ticket moved from /p/sdcc/bugs/3723/

    Can't be converted:

    • _category: Z80
     
  • Philipp Klaus Krause

    Regarding the comments "Register assignment might be sub-optimal." vs. "Register assignment is optimal.": this is to be expected. "Register assignment is optimal." means we found a register assignment that results in as far as we know, "optimal" code from code generation. To prove that, we need to try a lot of possibilities, and without --reserve-regs-optimal we have to consider more possibilities (now including the ones that use iy), so we need a higher --max-allocs-per-node value to do so.

     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
    • assigned_to: Philipp Klaus Krause
    • Group: -->
     
  • Philipp Klaus Krause

    This inspired some improvements in z80 (and related) codegen: [r14798]; we now get the better code both with and without --reserve-regs-iy.

    Philipp

     
    👍
    1

Log in to post a comment.