Fix an invalid transformation by the optimizer. Introduced by #2811.
This commit is contained in:
@@ -1213,21 +1213,24 @@ unsigned OptTosPushPop (CodeSeg* S)
|
||||
/* Get the next entry */
|
||||
const CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for decspn, incspn, subysp or addysp */
|
||||
/* Check for pushax/popax */
|
||||
if (CE_IsCallTo (E, "pushax") &&
|
||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||
(CE_IsCallTo (N, "popax") || CE_IsJumpTo (N, "popax")) &&
|
||||
!CE_HasLabel (N)) {
|
||||
|
||||
/* Insert an rts if jmp popax */
|
||||
if (N->OPC == OP65_JMP) {
|
||||
CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI);
|
||||
CS_InsertEntry (S, X, I);
|
||||
/* If we jumped to popax instead of calling it as a subroutine,
|
||||
** add an RTS before removing the sequence.
|
||||
*/
|
||||
CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI);
|
||||
CS_InsertEntry (S, X, I);
|
||||
CS_DelEntries (S, I+1, 2);
|
||||
} else {
|
||||
/* Otherwise just remove the sequence */
|
||||
CS_DelEntries (S, I, 2);
|
||||
}
|
||||
|
||||
/* Delete the old code */
|
||||
CS_DelEntries (S, I+1, 2);
|
||||
|
||||
/* Remember we had changes */
|
||||
++Changes;
|
||||
|
||||
|
||||
27
test/val/bug2937.c
Normal file
27
test/val/bug2937.c
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Note: This test is rather fragile since it depends on how the compiler
|
||||
** handles certain sequences and return codes. It checks for exactly one
|
||||
** optimizer problem introduced in #2937. If it fails in some future version,
|
||||
** do not hesitate to remove it.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static unsigned char test(unsigned v)
|
||||
{
|
||||
(void)v;
|
||||
asm("jsr popax");
|
||||
asm("lda #0");
|
||||
return __A__;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test(1)) {
|
||||
printf("Test failed\n");
|
||||
return 1;
|
||||
} else {
|
||||
printf("Test ok\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user