SDCC : z80/sm83/mos6502 4.2.2 #13350 (Linux)
For the gbz80/sm83: when conditionally calling a function pointer retrieved from an array, SDCC will generate an invalid opcode: jp NZ,(hl)
.
This causes the linker to fail with:
?ASlink-Warning-Undefined Global 'hl' referenced by module 'main'
The error does not happen if the function pointer is directly retrieved with:
void (*p_func)(void) = &some_func;
The error also does not happen if the variable used to store the function pointer is a global or static local.
Minimal example:
void some_func(void) {
}
void (*func_list[])(void) = {
&some_func
};
void main(void)
{
void (*p_func)(void) = func_list[0];
if (p_func)
(*p_func)();
}
Relevant ASM output
;main.c:13: void (*p_func)(void) = func_list[0];
ld hl, #_func_list
ld a, (hl+)
ld c, a
ld a, (hl)
ld l, c
; spillPairReg hl
; spillPairReg hl
ld h, a
; spillPairReg hl
; spillPairReg hl
;main.c:14: if (p_func)
or a, c
;main.c:15: (*p_func)();
jp NZ,(hl)
;main.c:17: }
Looks like z80 is affected, too.
Workaround until the bug is fixed: --no-peep.
Last edit: Philipp Klaus Krause 2022-05-14
Peephole rules 79 - 82 are bugged. They don’t check if the second jump goes to a label.
It only gets triggered now because
jp (hl)
gets generated more.became
Good to know that
--no-peep
is a usable workaround, though being able to have the peephole rules enabled would be niceWould it not be enough to change the condition of those rules to
} if operandsNotRelated(%2 'hl' 'ix' 'iy'), labelRefCountChange(%1 -1)
Turning
into
might suffice, yes.
Fixed in SDCC [r13503].
Related
Commit: [r13503]
On a related note: what is the difference between common z80 peephole rule 85a and 88?
Looks like a duplicate.