Improved the code that checks for memory accesses. The old code didn't detect
certain accesses. git-svn-id: svn://svn.cc65.org/cc65/trunk@4174 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
98b7e9f6da
commit
52a368adc1
1 changed files with 56 additions and 16 deletions
|
@ -51,27 +51,67 @@
|
|||
|
||||
|
||||
|
||||
static int MemAccess (CodeSeg* S, unsigned From, unsigned To, const char* Arg)
|
||||
/* Checks a range of code entries if there are any memory accesses to Arg.
|
||||
* Note: This function is not 100% safe, because there is more than one way
|
||||
* to express a memory location ("foo" and "foo+0" comes to mind) and there
|
||||
* may be other accesses through pointers. For the code generated by cc65 and
|
||||
* for the purpose of the caller (OptPushPop) it is assumed to be safe enough
|
||||
* however.
|
||||
*/
|
||||
static int MemAccess (CodeSeg* S, unsigned From, unsigned To, const CodeEntry* N)
|
||||
/* Checks a range of code entries if there are any memory accesses to N->Arg */
|
||||
{
|
||||
/* Get the length of the argument */
|
||||
unsigned NLen = strlen (N->Arg);
|
||||
|
||||
/* What to check for? */
|
||||
enum {
|
||||
None = 0x00,
|
||||
Base = 0x01, /* Check for location without "+1" */
|
||||
Word = 0x02, /* Check for location with "+1" added */
|
||||
} What = None;
|
||||
|
||||
|
||||
/* If the argument of N is a zero page location that ends with "+1", we
|
||||
* must also check for word accesses to the location without +1.
|
||||
*/
|
||||
if (N->AM == AM65_ZP && NLen > 2 && strcmp (N->Arg + NLen - 2, "+1") == 0) {
|
||||
What |= Base;
|
||||
}
|
||||
|
||||
/* If the argument is zero page indirect, we must also check for accesses
|
||||
* to "arg+1"
|
||||
*/
|
||||
if (N->AM == AM65_ZP_INDY || N->AM == AM65_ZPX_IND || N->AM == AM65_ZP_IND) {
|
||||
What |= Word;
|
||||
}
|
||||
|
||||
/* Walk over all code entries */
|
||||
while (From <= To) {
|
||||
|
||||
/* Get the next entry */
|
||||
CodeEntry* E = CS_GetEntry (S, From);
|
||||
|
||||
/* For simplicity, we just check if there is an argument and if this
|
||||
* argument equals Arg.
|
||||
/* Check if there is an argument and if this argument equals Arg in
|
||||
* some variants.
|
||||
*/
|
||||
if (E->Arg && strcmp (E->Arg, Arg) == 0) {
|
||||
/* Found an access */
|
||||
return 1;
|
||||
if (E->Arg[0] != '\0') {
|
||||
|
||||
unsigned ELen;
|
||||
|
||||
if (strcmp (E->Arg, N->Arg) == 0) {
|
||||
/* Found an access */
|
||||
return 1;
|
||||
}
|
||||
|
||||
ELen = strlen (E->Arg);
|
||||
if ((What & Base) != 0) {
|
||||
if (ELen == NLen - 2 && strncmp (E->Arg, N->Arg, NLen-2) == 0) {
|
||||
/* Found an access */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((What & Word) != 0) {
|
||||
if (ELen == NLen + 2 && strncmp (E->Arg, N->Arg, NLen) == 0 &&
|
||||
E->Arg[NLen] == '+' && E->Arg[NLen+1] == '1') {
|
||||
/* Found an access */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Next entry */
|
||||
|
@ -1480,7 +1520,7 @@ unsigned OptTransfers3 (CodeSeg* S)
|
|||
StoreEntry->AM == AM65_ZP) &&
|
||||
(StoreEntry->AM != AM65_ZP ||
|
||||
(StoreEntry->Chg & UsedRegs) == 0) &&
|
||||
!MemAccess (S, Xfer+1, Store-1, StoreEntry->Arg)) {
|
||||
!MemAccess (S, Xfer+1, Store-1, StoreEntry)) {
|
||||
|
||||
/* Generate the replacement store insn */
|
||||
CodeEntry* X = 0;
|
||||
|
@ -1645,7 +1685,7 @@ unsigned OptTransfers4 (CodeSeg* S)
|
|||
(LoadEntry->AM == AM65_ABS ||
|
||||
LoadEntry->AM == AM65_ZP ||
|
||||
LoadEntry->AM == AM65_IMM) &&
|
||||
!MemAccess (S, Load+1, Xfer-1, LoadEntry->Arg)) {
|
||||
!MemAccess (S, Load+1, Xfer-1, LoadEntry)) {
|
||||
|
||||
/* Generate the replacement load insn */
|
||||
CodeEntry* X = 0;
|
||||
|
@ -1794,7 +1834,7 @@ unsigned OptPushPop (CodeSeg* S)
|
|||
*/
|
||||
if (E->OPC == OP65_STA &&
|
||||
!RegAUsed (S, I+1) &&
|
||||
!MemAccess (S, Push+1, Pop-1, E->Arg)) {
|
||||
!MemAccess (S, Push+1, Pop-1, E)) {
|
||||
|
||||
/* Insert a STA after the PHA */
|
||||
X = NewCodeEntry (E->OPC, E->AM, E->Arg, E->JumpTo, E->LI);
|
||||
|
|
Loading…
Add table
Reference in a new issue