The code generated for loops that access to an array of structs trough pointers could improve enormously by using IY and IX.
Look at this example, where SwSprite[] is an array of struct
SwSpPntr = &SwSprite[0];
for (u8 i=0; i<TotSprt;i++) {
SwSpPntr->x1 = SwSpPntr->lx;
SwSpPntr->y1 = SwSpPntr->ly;
SwSpPntr++;
}
Using SDCC you get this UGE and SLOW piece of code:
;./Lift.c:707: SwSpPntr = &SwSprite[0];
ld hl, #_SwSprite
ld (_SwSpPntr), hl
;./Lift.c:708: for (u8 i=0; i<TotSprt;i++) {
ld -1 (ix), #0x00
00143$:
ld a, -1 (ix)
sub a, #0x26
jr NC, 00112$
;./Lift.c:603: SwSpPntr->lx = (i*16 + MyX );
ld hl, (_SwSpPntr)
;./Lift.c:709: SwSpPntr->x1 = SwSpPntr->lx;
ld c, l
ld b, h
inc bc
inc bc
ld a, (hl)
ld (bc), a
;./Lift.c:603: SwSpPntr->lx = (i*16 + MyX );
ld bc, (_SwSpPntr)
;./Lift.c:710: SwSpPntr->y1 = SwSpPntr->ly;
ld hl, #0x0008
add hl, bc
ex de, hl
ld hl, #4
add hl, bc
ld c, (hl)
inc hl
ld b, (hl)
ld a, c
ld (de), a
inc de
ld a, b
ld (de), a
;./Lift.c:711: SwSpPntr++;
ld hl, #_SwSpPntr
ld a, (hl)
add a, #0x10
ld (hl), a
jr NC, 00239$
inc hl
inc (hl)
00239$:
;./Lift.c:708: for (u8 i=0; i<TotSprt;i++) {
inc -1 (ix)
jp 00143$
00112$:
Note that te burden is related to the use of HL as pointer to the struct
Instead, using IY, you get:
ld iy, #_SwSprite
ld de, #0x0010
ld b, #0x26
03999$:
ld a, 0 (iy)
ld 2 (iy) ,a ; SwSpPntr->x1 = SwSpPntr->lx;
ld l, 4 (iy)
ld h, 5 (iy)
ld 8 (iy),l
ld 9 (iy),h ; SwSpPntr->y1 = SwSpPntr->ly;
add iy, de ; SwSpPntr++;
djnz 03999$
Would it be possible to suggest to SDCCto allocate pointers to structs in IY (and IX if available) ?
Which version of SDCC, used with which command-line options? Do you have a small compileable code sample to reproduce this?
This is with current version 4.6, as you can see the issue is unchanged
To compile the above C this could work
Last edit: Ragozini Arturo 4 days ago