Menu

#1030 Pointers to struct

open
nobody
z80 (14)
5
4 days ago
4 days ago
No

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) ?

Discussion

  • Philipp Klaus Krause

    Which version of SDCC, used with which command-line options? Do you have a small compileable code sample to reproduce this?

     
  • Ragozini Arturo

    Ragozini Arturo - 4 days ago

    This is with current version 4.6, as you can see the issue is unchanged

    ;./AdrianLift.c:707: SwSpPntr = &SwSprite[0];
        ld  hl, #_SwSprite
        ld  (_SwSpPntr), hl
    ;./AdrianLift.c:708: for (u8 i=0; i<TotSprt;i++)    {
        ld  c, #0x00
    00143$:
        ld  a, c
        sub a, #0x26
        jr  nc, 00112$
    ;./AdrianLift.c:709: SwSpPntr->x1 = SwSpPntr->lx;
        ld  de, (_SwSpPntr)
        inc de
        inc de
        ld  hl, (_SwSpPntr)
        ld  a, (hl)
        ld  (de), a
    ;./AdrianLift.c:604: SwSpPntr->ly = (Field.ly + MyY ); 
        ld  hl, (_SwSpPntr)
    ;./AdrianLift.c:710: SwSpPntr->y1 = SwSpPntr->ly;
        ld  a, l
        add a, #0x08
        ld  e, a
        ld  a, h
        inc hl
        inc hl
        inc hl
        inc hl
        adc a, #0x00
        ld  d, a
        ld  b, (hl)
        inc hl
        ld  l, (hl)
        ld  a, b
        ld  (de), a
        inc de
        ld  a, l
        ld  (de), a
    ;./AdrianLift.c:711: SwSpPntr++;                
        ld  hl, #_SwSpPntr
        ld  a, (hl)
        add a, #0x10
        ld  (hl), a
        jr  nc, 00274$
        inc hl
        inc (hl)
    00274$:
    ;./AdrianLift.c:708: for (u8 i=0; i<TotSprt;i++)    {
        inc c
        jp  00143$
    00112$:
    
     
  • Ragozini Arturo

    Ragozini Arturo - 4 days ago

    To compile the above C this could work

    struct MyObj {
        u8 lx;          // Logical x
        u8 x0,x1,x2;    // Physical x's in the 3 pages
        i16 ly;         // Logical Y
        u16 y0,y1,y2;   // Physical y's in the 3 pages
        u16 frame;
        i8 dx;          // x direction
        i8 dy;          // y direction
    };
    
    #define TotDem  (32)
    #define TotSprt (32+6)
    
    struct MyObj SwSprite[TotSprt];
    
    void main() {
                SwSpPntr = &SwSprite[0];
                for (u8 i=0; i<TotSprt;i++)     {
                    SwSpPntr->x1 = SwSpPntr->lx;
                    SwSpPntr->y1 = SwSpPntr->ly;
                    SwSpPntr++;             
                }
    }
    
     

    Last edit: Ragozini Arturo 4 days ago

Log in to post a comment.

Auth0 Logo