Menu

#987 Invalid div x,a instruction in ISR with array access

None
open
nobody
None
5
2025-03-03
2025-03-03
G. H.
No

Environment

  • SDCC Version: 4.5.0 #15242
  • Target: STM8
  • OS: macOS
  • Compilation: sdcc -mstm8 test.c

Description

The compiler incorrectly inserts a clr a followed by a div x,a instruction at the beginning of interrupt service routines when accessing array elements using bit-shift operations.

Test Case

unsigned short my_uint16;
unsigned char my_uint8;
unsigned char my_array[256];

void my_isr1(void) __interrupt(13) {
    /* Causes a "clr a; div x,a" to be inserted at the beginning of the ISR: */
    my_uint8 = my_array[my_uint16 >> 8];
}

void my_isr2(void) __interrupt(14) {
    /* No bug when using an intermediate variable: */
    unsigned char shifted = my_uint16 >> 8;
    my_uint8 = my_array[shifted];
}

Generated Assembly

_my_isr1:
    clr a           ; Sets a to 0
    div x, a        ; Divides by 0!
;   test.c: 7: my_uint8 = my_array[my_uint16 >> 8];
    ld  a, _my_uint16+0
    clrw    x
    ld  xl, a
    addw    x, #(_my_array+0)
    ld  a, (x)
    ld  _my_uint8+0, a
;   test.c: 8: }
    iret

Note: When invoking the compiler with option --opt-code-size, the clr a disappears, but the div x, a still remains.

2 Attachments

Discussion

  • Philipp Klaus Krause

    Ticket moved from /p/sdcc/bugs/3840/

    Can't be converted:

    • _category: STM8
     
  • Philipp Klaus Krause

    Moved to feature requests, since the generated code is correct (just less efficient than it could be).

     
  • Philipp Klaus Krause

    The clr a disappearing for --opt-code-size is working as intended: it saves one byte of code, but (depending on the unknown value of a), the div then might take substantially more cycles to execute.

     
  • Philipp Klaus Krause

    In my_isr2, due to the result being assigned to an 8-bit type, the right shift is optimized into a GETBYTE iCode. This does not happen for my_isr1; in my_isr1, we have a RIGHT_OP (i.e. right shift) iCode. At the time the isr prologue is generated, code generation has incomplete information on how the right shift will be implemented later. For some (depending on the operands) right shifts by literals, div or divw is used, and when generating the function prologue we err on the safe side, assuming that for any right shift by a more than 1 a div or divw might be generated.

     

Log in to post a comment.

MongoDB Logo MongoDB