Merge pull request #2941 from avolkov76/anv-coptstop-refactor
[cc65] Refactor OptStackOps() subopt precondition evaluation framework, phase 1
This commit is contained in:
@@ -756,6 +756,10 @@ void ResetStackOpData (StackOpData* Data)
|
||||
|
||||
Data->PushIndex = -1;
|
||||
Data->OpIndex = -1;
|
||||
|
||||
/* Clear to prevent silent optimizer bugs */
|
||||
Data->ZPLo = 0;
|
||||
Data->ZPHi = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -946,10 +950,9 @@ void AdjustStackOffset (StackOpData* D, unsigned Offs)
|
||||
|
||||
|
||||
|
||||
int IsRegVar (StackOpData* D)
|
||||
int IsRegVar (const StackOpData* D)
|
||||
/* If the value pushed is that of a zeropage variable that is unchanged until Op,
|
||||
** replace ZPLo and ZPHi in the given StackOpData struct by the variable and return true.
|
||||
** Otherwise leave D untouched and return false.
|
||||
** return true.
|
||||
*/
|
||||
{
|
||||
CodeEntry* LoadA = D->Lhs.A.LoadEntry;
|
||||
@@ -979,9 +982,7 @@ int IsRegVar (StackOpData* D)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use the zero page location directly */
|
||||
D->ZPLo = LoadA->Arg;
|
||||
D->ZPHi = LoadX->Arg;
|
||||
/* ZP location can be used directly */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -990,6 +991,8 @@ int IsRegVar (StackOpData* D)
|
||||
void AddStoreLhsA (StackOpData* D)
|
||||
/* Add a store to zero page after the push insn */
|
||||
{
|
||||
CHECK (D->ZPLo != 0);
|
||||
|
||||
CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPLo, 0, D->PushEntry->LI);
|
||||
InsertEntry (D, X, D->PushIndex+1);
|
||||
}
|
||||
@@ -999,6 +1002,8 @@ void AddStoreLhsA (StackOpData* D)
|
||||
void AddStoreLhsX (StackOpData* D)
|
||||
/* Add a store to zero page after the push insn */
|
||||
{
|
||||
CHECK (D->ZPHi != 0);
|
||||
|
||||
CodeEntry* X = NewCodeEntry (OP65_STX, AM65_ZP, D->ZPHi, 0, D->PushEntry->LI);
|
||||
InsertEntry (D, X, D->PushIndex+1);
|
||||
}
|
||||
@@ -1071,6 +1076,8 @@ void AddOpLow (StackOpData* D, opc_t OPC, LoadInfo* LI)
|
||||
|
||||
} else {
|
||||
|
||||
CHECK (D->ZPLo != 0);
|
||||
|
||||
/* Op with temp storage */
|
||||
X = NewCodeEntry (OPC, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI);
|
||||
InsertEntry (D, X, D->IP++);
|
||||
@@ -1134,6 +1141,9 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
CHECK (D->ZPHi != 0);
|
||||
|
||||
/* opc zphi */
|
||||
X = NewCodeEntry (OPC, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
|
||||
InsertEntry (D, X, D->IP++);
|
||||
|
||||
@@ -223,10 +223,9 @@ void AdjustStackOffset (StackOpData* D, unsigned Offs);
|
||||
** OpIndex is adjusted according to the insertions.
|
||||
*/
|
||||
|
||||
int IsRegVar (StackOpData* D);
|
||||
int IsRegVar (const StackOpData* D);
|
||||
/* If the value pushed is that of a zeropage variable that is unchanged until Op,
|
||||
** replace ZPLo and ZPHi in the given StackOpData struct by the variable and return true.
|
||||
** Otherwise leave D untouched and return false.
|
||||
** return true.
|
||||
*/
|
||||
|
||||
void AddStoreLhsA (StackOpData* D);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@
|
||||
unsigned char a, b;
|
||||
unsigned char c = 199;
|
||||
unsigned char d = 100;
|
||||
int i = 50;
|
||||
|
||||
int main(void) {
|
||||
int fails = 0;
|
||||
@@ -38,6 +39,117 @@ int main(void) {
|
||||
printf("AND error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c + (d != 0);
|
||||
b = c + 1;
|
||||
|
||||
printf("%u ^ (%u != 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("ADD error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c - (d != 0);
|
||||
b = c - 1;
|
||||
|
||||
printf("%u ^ (%u != 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("SUB error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c ^ (d >= 0);
|
||||
b = c ^ 1;
|
||||
|
||||
printf("%u ^ (%u >= 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("XOR error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c | (d >= 0);
|
||||
b = c | 1;
|
||||
|
||||
printf("%u | (%u >= 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("OR error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c & (d >= 0);
|
||||
b = c & 1;
|
||||
|
||||
printf("%u & (%u >= 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("AND error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c + (d >= 0);
|
||||
b = c + 1;
|
||||
|
||||
printf("%u ^ (%u >= 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("ADD error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c - (d >= 0);
|
||||
b = c - 1;
|
||||
|
||||
printf("%u ^ (%u >= 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("SUB error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
printf("%d errors\n", fails);
|
||||
|
||||
a = c ^ (i >= 0);
|
||||
b = c ^ 1;
|
||||
|
||||
printf("%u ^ (%d >= 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("XOR int cmp error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c | (i >= 0);
|
||||
b = c | 1;
|
||||
|
||||
printf("%u | (%d >= 0) => %u\n", c, i, a);
|
||||
if (a != b) {
|
||||
printf("OR int cmp error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c & (i >= 0);
|
||||
b = c & 1;
|
||||
|
||||
printf("%u & (%d >= 0) => %u\n", c, i, a);
|
||||
if (a != b) {
|
||||
printf("AND int cmp error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c + (i >= 0);
|
||||
b = c + 1;
|
||||
|
||||
printf("%u ^ (%d >= 0) => %u\n", c, i, a);
|
||||
if (a != b) {
|
||||
printf("ADD int cmp error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c - (i >= 0);
|
||||
b = c - 1;
|
||||
|
||||
printf("%u ^ (%d >= 0) => %u\n", c, i, a);
|
||||
if (a != b) {
|
||||
printf("SUB int cmp error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
printf("%d errors\n", fails);
|
||||
|
||||
return fails;
|
||||
|
||||
22
test/val/bug2946.c
Normal file
22
test/val/bug2946.c
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
/* bug #2946: Incomplete, non-removable Rhs asserts in OptStackOps */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned char a, b = 0;
|
||||
unsigned char c = 10;
|
||||
unsigned char d = 1;
|
||||
|
||||
int main(void) {
|
||||
/* 'if' needed to produce a label below, moved by OptJumpTarget3 */
|
||||
if (b != 0) {
|
||||
/* Operation not important; it only affects the removal of one LDX #$00 */
|
||||
b = 0;
|
||||
}
|
||||
|
||||
/* d >= 0 is const, A/X=1 (Warning: Result of comparison is always true) */
|
||||
a = c - (d >= 0);
|
||||
|
||||
return !(a == 9);
|
||||
}
|
||||
22
test/val/bug2947.c
Normal file
22
test/val/bug2947.c
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
/* bug #2947: Opt_a_tosbitwise() attempts to remove non-removable Rhs X */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned char a, b = 0;
|
||||
unsigned char c = 10;
|
||||
unsigned char d = 1;
|
||||
|
||||
int main(void) {
|
||||
/* 'if' needed to produce a label below, moved by OptJumpTarget3 */
|
||||
if (b != 0) {
|
||||
/* Operation not important; it only affects the removal of one LDX #$00 */
|
||||
b = 0;
|
||||
}
|
||||
|
||||
/* d >= 0 is const, A/X=1 (Warning: Result of comparison is always true) */
|
||||
a = c ^ (d >= 0);
|
||||
|
||||
return !(a == 11);
|
||||
}
|
||||
Reference in New Issue
Block a user