Pointer arithmetic

Tony Hague
2012-10-15
2013-03-12
  • Tony Hague
    Tony Hague
    2012-10-15

    Another bit of code that worked under 2.9.0 but produces a strange result with 3.2.  Abridged to highlight the oddity:

    static unsigned int lut;

    void lut_create(unsigned char c)
    {
            int i;
    //      __xdata
            unsigned int *lutp;

            lutp = lut+101*c;

            for(i=0; i<101; i++)
                    lutp_ = i;
    }

    sdcc -c -model-large test.c

    produces asm:

    ;       test.c:9: lutp = lut+101*c;
            mov     dptr,#_lut_create_c_1_1
            movx    @dptr,a
            mov     b,#0x65
            mul     ab
            mov     r7,a
            clr     a                        <<--
            xch     a,r7
            add     a,acc
            xch     a,r7
            rlc     a
            mov     r6,a
            mov     a,r7
            add     a,#_lut
            mov     r7,a
            mov     a,r6
            addc    a,#(_lut >> 8)

    and so on. Uncommenting the "__xdata" gives me:

    ;       test.c:9: lutp = lut+101*c;
            mov     dptr,#_lut_create_c_1_1
            movx    @dptr,a
            mov     b,#0x65
            mul     ab
            mov     r7,a
            mov     a,b                        <<--
            xch     a,r7
            add     a,acc
            xch     a,r7
            rlc     a
            mov     r6,a
            mov     a,r7
            add     a,#_lut
            mov     r7,a
            mov     a,r6
            addc    a,#(_lut >> 8)

    The lines marked "<<--" differ - the former discards b after the mul, the latter does not. Am I wrong in expecting that the 101*c should be promoted to int, and that (without the __xdata) a 3 byte generic pointer should be used ? Using SDCC 2.9.0, in both cases b is used.

    Any explanation very welcome !
    _

     
  • Maarten Brock
    Maarten Brock
    2012-10-15

    I would expect a warning on
    lutp = i;

    SDCC does not necessarily need 3 byte generic pointers if it knows it always points to a specific memory type.

    But not using B in the calculation is a bug, so please report it in the bug tracker.

     
  • Tony Hague
    Tony Hague
    2012-10-16

    Bug #3564104 seems to be what I have encountered.  An explicit (int) also works around it.

    The line

    lutp = i;

    has been mangled by the forum because I didn't insert the code properly,  there should have been an index i (in square brackets)  after the lutp, which got eaten, and turned the rest of the post into italics instead ! Sorry for the red herring …

    Thanks once more for the help.