Menu

[z80] interesting code generated when copying unsigned int (from a member of an union)

Help
sverx
2016-01-07
2016-01-08
  • sverx

    sverx - 2016-01-07

    Bothering you again... I've got another quirky result.

    my 'old' code was:

    volatile unsigned int KeysStatus, PreviousKeysStatus;
    
    void somefunc(void) {
      PreviousKeysStatus=KeysStatus;
    }
    

    which compiled to:

        ld  hl,(_KeysStatus)
        ld  (_PreviousKeysStatus),hl
    

    Now in my new code I need to replace the 'KeysStatus' variable with an union. I did this:

    union {
      volatile unsigned int KeysStatus;
      struct {
        volatile unsigned char KeysStatusLo;
        volatile unsigned char KeysStatusHi;
      };
    } SMS_Pad;
    
    void somefunc(void) {
      PreviousKeysStatus=SMS_Pad.KeysStatus;
    }
    

    but that compiled to:

        ld  hl,#_SMS_Pad+0
        ld  a,(hl)
        ld  iy,#_PreviousKeysStatus
        ld  0 (iy),a
        inc hl
        ld  a,(hl)
        ld  (#_PreviousKeysStatus + 1),a
    

    any idea on why is this happening? :|

    Thanks!

     
  • alvin

    alvin - 2016-01-07

    Accessing statics is not always done optimally in sdcc. You can deny use of iy to speed it up by adding "--reserve-regs-iy" but that's still not close to a straightforward static load/store.

    At the moment you have to correct these things with peephole rules. We have around 400 or so if you want to try this peephole set:

    http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/sdcc_peeph.3

    Most of these rules are designed for high max-allocs-per-node (200000, specifically) and --reserve-regs-iy active.

     
  • Philipp Klaus Krause

    struct and union accesses are much more compliacted than accesses to other variables. They get translated into pointer accesses via a pointer consisitng of the base address of the struct and an offset. While we were able to improve the situation, especially for nested structs via some optimizations, they are still not as efficient as accesses to variables outside of struct/union.

    Philipp

    P.S.: I prefer the sdcc-user mailing list to the discussion forum.

     
  • sverx

    sverx - 2016-01-08

    Thanks for the replies.
    I do understand that struct and union access is more complicated. What I don't get is why SDCC seems to be able to do a 16-bit access to a variable in the first case and it seems not to be able then, when the variable is in a struct/union.
    After all, even with "base address+constant offset", we should get the same code:

    ld  hl,(#_baseaddress+0)
    

    Of course I don't really know anything about SDCC internals, I'm just curious...

    Is there any chance to have someone address this in SDCC code? May I help with it?
    Or anyway, any hint on how I could avoid using unions? Can I have global variables at same address of other global variables?
    Thanks!

     

Log in to post a comment.