While scrutinising some of the assembly code during my attempts to get reading and writing from/to far flash locations (see other thread on large memory model and RAM execution), I have noticed something again that I have noticed on other occasions.

Sometimes, for reasons unclear to me, SDCC's optimiser fails to optimise simple C statements doing register bit set/clear operations in to the appropriate STM8 bset/bres instructions.

Here's the example I noticed today. The C code, and the ASM it became:

FLASH_NCR2 &= ~(1U << FLASH_NCR2_NPRG);

ld    a, 0x505c
and    a, #0xfe
ld    0x505c, a

It's not "bres 0x505c, #0" like it really should be. What's ironic is that the immediately preceding line of C is a bit set operation (on FLASH_CR2 reg), and that got optimised to bset, but this didn't.

One previous occasion was particularly egregious, where the read-modify-store got split up, and some other code placed in between the load and the modify-store:

do { PC_ODR |= (1U << PC_ODR_ODR2); } while(0); // Original statement from a macro

ld    a, 0x500a ; <-----
ldw    x, (0x08, sp) ; start of a following 'while(count-- > 1)' loop
cpw    x, #0x0001
jrule    00228$
ldw    x, (0x08, sp)
decw    x
ldw    (0x08, sp), x
or    a, #0x04 ; <-----
ld    0x500a, a ; <-----

I remember that one caused particular annoyance to me, because I was trying to use the GPIO pin toggle to inspect some timing with a logic analyser, and it was occurring in the wrong place.

By the way, this was all with no specific optimisation parameters in effect - just the default 'balanced' mode.

Are there some odd mitigating circumstances that would cause the optimiser to do this? Or is this a bug?

Regards,
Basil


_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to