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 */
|
/* Get the next entry */
|
||||||
const CodeEntry* E = CS_GetEntry (S, I);
|
const CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
/* Check for decspn, incspn, subysp or addysp */
|
/* Check for pushax/popax */
|
||||||
if (CE_IsCallTo (E, "pushax") &&
|
if (CE_IsCallTo (E, "pushax") &&
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||||
(CE_IsCallTo (N, "popax") || CE_IsJumpTo (N, "popax")) &&
|
(CE_IsCallTo (N, "popax") || CE_IsJumpTo (N, "popax")) &&
|
||||||
!CE_HasLabel (N)) {
|
!CE_HasLabel (N)) {
|
||||||
|
|
||||||
/* Insert an rts if jmp popax */
|
|
||||||
if (N->OPC == OP65_JMP) {
|
if (N->OPC == OP65_JMP) {
|
||||||
CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI);
|
/* If we jumped to popax instead of calling it as a subroutine,
|
||||||
CS_InsertEntry (S, X, I);
|
** 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 */
|
/* Remember we had changes */
|
||||||
++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