Using the below code with the following peep rule file, the peep rule is not applied as I would expect.
/// GPL 2.0 or later
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#define reg_vram_access_address_high 14
#define BYTE_HI(x) ((x)>>8)
static volatile __sfr __at 0x98 VDPControlPort;
void vdu_interrupt_disable() { __asm di __endasm; }
void vdu_interrupt_enable() { __asm ei __endasm; }
///< Move memory pointer to specified address to set value
void vdu_address_set(uint16_t address) {
vdu_interrupt_disable();
VDPControlPort=address >> 14;
VDPControlPort=reg_vram_access_address_high | 0x80;
VDPControlPort=address;
VDPControlPort=( BYTE_HI(address) & 0x3f ) | 0x40;
vdu_interrupt_enable();
}
// sdcc -mz80 --fverbose-asm ./peep.c -c && cat peep.c
with following peep rule:
replace {
ld c, a
ld b, #0x00
ld a, c
} by {
ld b, #0x00
} if notUsed('c')
I end up with the following snippet of asm:
;./peep.c:20: VDPControlPort=address >> 14;
ld a, h
rlca
rlca
and a, #0x03
ld c, a
ld b, #0x00
ld a, c
out (_VDPControlPort), a
Removing the "if notUsed('c')" I get the below I would expect using the notused:
;./peep.c:19: VDPControlPort=address >> 14;
ld a, h
rlca
rlca
and a, #0x03
ld b, #0x00
out (_VDPControlPort), a
The peep rule is not applied(with notused) as expected. Also the (peep) code generated doesn't seem to be useful in this case.
Removing either of the vdu_interrupt_* calls removes the extra b,c code.
SDCC : z80/sm83/z80n/mos6502 TD- 4.3.6 #14522 (Linux)
This issue is a bit complex, since it is about the interaction of tail call optimization with the peephole optimizer.
I have a fix that works for your example in the next branch in [r14553], but it won't make it into SDCC 4.4.0: The risk of this change breaking something is IMO too high, and the fixed issue just results in inefficient, not wrong code.
Related
Commit: [r14553]
Fixed by merging next branch to trunk.