X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcodeent.c;h=13b7aed146701f961315ee240d2aa8b49bc34109;hb=dbb9a31fd908fe85fd9d4ccf1397564a3d027953;hp=50fa59a4e6673000327b39d29cdc7448ec577e86;hpb=27cd610d490154cf64843dc7a6c8f26435585afa;p=cc65 diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 50fa59a4e..13b7aed14 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -39,6 +39,7 @@ /* common */ #include "chartype.h" #include "check.h" +#include "debugflag.h" #include "xmalloc.h" #include "xsprintf.h" @@ -143,7 +144,7 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D) * lookup the information about this function and use it. The jump itself * does not change any registers, so we don't need to use the data from D. */ - if ((E->Info & (OF_BRA | OF_CALL)) != 0 && E->JumpTo == 0) { + if ((E->Info & (OF_UBRA | OF_CALL)) != 0 && E->JumpTo == 0) { /* A subroutine call or jump to external symbol (function exit) */ GetFuncInfo (E->Arg, &E->Use, &E->Chg); } else { @@ -243,10 +244,10 @@ CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, /* Initialize the fields */ E->OPC = D->OPC; E->AM = AM; + E->Size = GetInsnSize (E->OPC, E->AM); E->Arg = GetArgCopy (Arg); - E->Flags = NumArg (E->Arg, &E->Num)? CEF_NUMARG : 0; + E->Flags = NumArg (E->Arg, &E->Num)? CEF_NUMARG : 0; /* Needs E->Arg */ E->Info = D->Info; - E->Size = GetInsnSize (E->OPC, E->AM); E->JumpTo = JumpTo; E->LI = UseLineInfo (LI); E->RI = 0; @@ -305,7 +306,7 @@ void CE_ReplaceOPC (CodeEntry* E, opc_t OPC) int CodeEntriesAreEqual (const CodeEntry* E1, const CodeEntry* E2) /* Check if both code entries are equal */ { - return E1->OPC == E2->OPC && E1->AM == E2->AM && strcmp (E1->Arg, E2->Arg) == 0; + return (E1->OPC == E2->OPC && E1->AM == E2->AM && strcmp (E1->Arg, E2->Arg) == 0); } @@ -322,6 +323,22 @@ void CE_AttachLabel (CodeEntry* E, CodeLabel* L) +void CE_ClearJumpTo (CodeEntry* E) +/* Clear the JumpTo entry and the argument (which contained the name of the + * label). Note: The function will not clear the backpointer from the label, + * so use it with care. + */ +{ + /* Clear the JumpTo entry */ + E->JumpTo = 0; + + /* Clear the argument and assign the empty one */ + FreeArg (E->Arg); + E->Arg = EmptyArg; +} + + + void CE_MoveLabel (CodeLabel* L, CodeEntry* E) /* Move the code label L from it's former owner to the code entry E. */ { @@ -335,6 +352,18 @@ void CE_MoveLabel (CodeLabel* L, CodeEntry* E) +void CE_SetArg (CodeEntry* E, const char* Arg) +/* Replace the argument by the new one. */ +{ + /* Free the old argument */ + FreeArg (E->Arg); + + /* Assign the new one */ + E->Arg = GetArgCopy (Arg); +} + + + void CE_SetNumArg (CodeEntry* E, long Num) /* Set a new numeric argument for the given code entry that must already * have a numeric argument. @@ -356,11 +385,8 @@ void CE_SetNumArg (CodeEntry* E, long Num) Internal ("Invalid instruction size in CE_SetNumArg"); } - /* Free the old argument */ - FreeArg (E->Arg); - - /* Assign the new one */ - E->Arg = GetArgCopy (Buf); + /* Replace the argument by the new one */ + CE_SetArg (E, Buf); /* Use the new numerical value */ E->Num = Num; @@ -368,19 +394,58 @@ void CE_SetNumArg (CodeEntry* E, long Num) -int CE_KnownImm (const CodeEntry* E) -/* Return true if the argument of E is a known immediate value */ +int CE_IsConstImm (const CodeEntry* E) +/* Return true if the argument of E is a constant immediate value */ { return (E->AM == AM65_IMM && (E->Flags & CEF_NUMARG) != 0); } +int CE_IsKnownImm (const CodeEntry* E, unsigned long Num) +/* Return true if the argument of E is a constant immediate value that is + * equal to Num. + */ +{ + return E->AM == AM65_IMM && + (E->Flags & CEF_NUMARG) != 0 && + E->Num == Num; +} + + + int CE_UseLoadFlags (const CodeEntry* E) /* Return true if the instruction uses any flags that are set by a load of * a register (N and Z). */ { + /* Follow unconditional branches, but beware of endless loops. After this, + * E will point to the first entry that is not a branch. + */ + if (E->Info & OF_UBRA) { + Collection C = AUTO_COLLECTION_INITIALIZER; + + /* Follow the chain */ + while (E->Info & OF_UBRA) { + + /* Remember the entry so we can detect loops */ + CollAppend (&C, (void*) E); + + /* Check the target */ + if (E->JumpTo == 0 || CollIndex (&C, E->JumpTo->Owner) >= 0) { + /* Unconditional jump to external symbol, or endless loop. */ + DoneCollection (&C); + return 0; /* Flags not used */ + } + + /* Follow the chain */ + E = E->JumpTo->Owner; + } + + /* Delete the collection */ + DoneCollection (&C); + } + /* A branch will use the flags */ if (E->Info & OF_FBRA) { return 1; @@ -419,7 +484,7 @@ void CE_FreeRegInfo (CodeEntry* E) /* Free an existing register info struct */ { if (E->RI) { - FreeRegInfo (E->RI); + FreeRegInfo (E->RI); E->RI = 0; } } @@ -461,18 +526,24 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) /* We don't know the value of the carry, so the result is * always unknown. */ - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; break; case OP65_AND: - if (In->RegA >= 0) { - if (CE_KnownImm (E)) { + if (RegValIsKnown (In->RegA)) { + if (CE_IsConstImm (E)) { Out->RegA = In->RegA & (short) E->Num; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use, In)) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { case REG_TMP1: Out->RegA = In->RegA & In->Tmp1; break; + case REG_PTR1_LO: + Out->RegA = In->RegA & In->Ptr1Lo; + break; + case REG_PTR1_HI: + Out->RegA = In->RegA & In->Ptr1Hi; + break; case REG_SREG_LO: Out->RegA = In->RegA & In->SRegLo; break; @@ -480,23 +551,29 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegA = In->RegA & In->SRegHi; break; default: - Out->RegA = -1; - break; + Out->RegA = UNKNOWN_REGVAL; + break; } } else { - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; } } break; case OP65_ASL: - if (E->AM == AM65_ACC && In->RegA >= 0) { + if (E->AM == AM65_ACC && RegValIsKnown (In->RegA)) { Out->RegA = (In->RegA << 1) & 0xFF; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: Out->Tmp1 = (In->Tmp1 << 1) & 0xFF; break; + case REG_PTR1_LO: + Out->Ptr1Lo = (In->Ptr1Lo << 1) & 0xFF; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = (In->Ptr1Hi << 1) & 0xFF; + break; case REG_SREG_LO: Out->SRegLo = (In->SRegLo << 1) & 0xFF; break; @@ -565,19 +642,25 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_DEA: - if (In->RegA >= 0) { + if (RegValIsKnown (In->RegA)) { Out->RegA = (In->RegA - 1) & 0xFF; } break; case OP65_DEC: - if (E->AM == AM65_ACC && In->RegA >= 0) { + if (E->AM == AM65_ACC && RegValIsKnown (In->RegA)) { Out->RegA = (In->RegA - 1) & 0xFF; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: Out->Tmp1 = (In->Tmp1 - 1) & 0xFF; break; + case REG_PTR1_LO: + Out->Ptr1Lo = (In->Ptr1Lo - 1) & 0xFF; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = (In->Ptr1Hi - 1) & 0xFF; + break; case REG_SREG_LO: Out->SRegLo = (In->SRegLo - 1) & 0xFF; break; @@ -592,26 +675,32 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_DEX: - if (In->RegX >= 0) { + if (RegValIsKnown (In->RegX)) { Out->RegX = (In->RegX - 1) & 0xFF; } break; case OP65_DEY: - if (In->RegY >= 0) { + if (RegValIsKnown (In->RegY)) { Out->RegY = (In->RegY - 1) & 0xFF; } break; case OP65_EOR: - if (In->RegA >= 0) { - if (CE_KnownImm (E)) { + if (RegValIsKnown (In->RegA)) { + if (CE_IsConstImm (E)) { Out->RegA = In->RegA ^ (short) E->Num; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use, In)) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { case REG_TMP1: Out->RegA = In->RegA ^ In->Tmp1; break; + case REG_PTR1_LO: + Out->RegA = In->RegA ^ In->Ptr1Lo; + break; + case REG_PTR1_HI: + Out->RegA = In->RegA ^ In->Ptr1Hi; + break; case REG_SREG_LO: Out->RegA = In->RegA ^ In->SRegLo; break; @@ -619,29 +708,35 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegA = In->RegA ^ In->SRegHi; break; default: - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; break; } } else { - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; } } break; case OP65_INA: - if (In->RegA >= 0) { + if (RegValIsKnown (In->RegA)) { Out->RegA = (In->RegA + 1) & 0xFF; } break; case OP65_INC: - if (E->AM == AM65_ACC && In->RegA >= 0) { + if (E->AM == AM65_ACC && RegValIsKnown (In->RegA)) { Out->RegA = (In->RegA + 1) & 0xFF; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: Out->Tmp1 = (In->Tmp1 + 1) & 0xFF; break; + case REG_PTR1_LO: + Out->Ptr1Lo = (In->Ptr1Lo + 1) & 0xFF; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = (In->Ptr1Hi + 1) & 0xFF; + break; case REG_SREG_LO: Out->SRegLo = (In->SRegLo + 1) & 0xFF; break; @@ -656,13 +751,13 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_INX: - if (In->RegX >= 0) { + if (RegValIsKnown (In->RegX)) { Out->RegX = (In->RegX + 1) & 0xFF; } break; case OP65_INY: - if (In->RegY >= 0) { + if (RegValIsKnown (In->RegY)) { Out->RegY = (In->RegY + 1) & 0xFF; } break; @@ -692,22 +787,28 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) /* Get the code info for the function */ GetFuncInfo (E->Arg, &Use, &Chg); if (Chg & REG_A) { - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; } if (Chg & REG_X) { - Out->RegX = -1; + Out->RegX = UNKNOWN_REGVAL; } if (Chg & REG_Y) { - Out->RegY = -1; + Out->RegY = UNKNOWN_REGVAL; } if (Chg & REG_TMP1) { - Out->Tmp1 = -1; + Out->Tmp1 = UNKNOWN_REGVAL; + } + if (Chg & REG_PTR1_LO) { + Out->Ptr1Lo = UNKNOWN_REGVAL; + } + if (Chg & REG_PTR1_HI) { + Out->Ptr1Hi = UNKNOWN_REGVAL; } if (Chg & REG_SREG_LO) { - Out->SRegLo = -1; + Out->SRegLo = UNKNOWN_REGVAL; } if (Chg & REG_SREG_HI) { - Out->SRegHi = -1; + Out->SRegHi = UNKNOWN_REGVAL; } /* ## FIXME: Quick hack for some known functions: */ if (strcmp (E->Arg, "tosandax") == 0) { @@ -736,13 +837,19 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_LDA: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegA = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use, In)) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { case REG_TMP1: Out->RegA = In->Tmp1; break; + case REG_PTR1_LO: + Out->RegA = In->Ptr1Lo; + break; + case REG_PTR1_HI: + Out->RegA = In->Ptr1Hi; + break; case REG_SREG_LO: Out->RegA = In->SRegLo; break; @@ -750,23 +857,29 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegA = In->SRegHi; break; default: - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; break; } } else { /* A is now unknown */ - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; } break; case OP65_LDX: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegX = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use, In)) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { case REG_TMP1: Out->RegX = In->Tmp1; break; + case REG_PTR1_LO: + Out->RegX = In->Ptr1Lo; + break; + case REG_PTR1_HI: + Out->RegX = In->Ptr1Hi; + break; case REG_SREG_LO: Out->RegX = In->SRegLo; break; @@ -774,23 +887,29 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegX = In->SRegHi; break; default: - Out->RegX = -1; + Out->RegX = UNKNOWN_REGVAL; break; } } else { /* X is now unknown */ - Out->RegX = -1; + Out->RegX = UNKNOWN_REGVAL; } break; case OP65_LDY: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegY = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use, In)) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { case REG_TMP1: Out->RegY = In->Tmp1; break; + case REG_PTR1_LO: + Out->RegY = In->Ptr1Lo; + break; + case REG_PTR1_HI: + Out->RegY = In->Ptr1Hi; + break; case REG_SREG_LO: Out->RegY = In->SRegLo; break; @@ -798,23 +917,29 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegY = In->SRegHi; break; default: - Out->RegY = -1; + Out->RegY = UNKNOWN_REGVAL; break; } } else { /* Y is now unknown */ - Out->RegY = -1; + Out->RegY = UNKNOWN_REGVAL; } break; case OP65_LSR: - if (E->AM == AM65_ACC && In->RegA >= 0) { + if (E->AM == AM65_ACC && RegValIsKnown (In->RegA)) { Out->RegA = (In->RegA >> 1) & 0xFF; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: Out->Tmp1 = (In->Tmp1 >> 1) & 0xFF; break; + case REG_PTR1_LO: + Out->Ptr1Lo = (In->Ptr1Lo >> 1) & 0xFF; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = (In->Ptr1Hi >> 1) & 0xFF; + break; case REG_SREG_LO: Out->SRegLo = (In->SRegLo >> 1) & 0xFF; break; @@ -832,28 +957,34 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_ORA: - if (In->RegA >= 0) { - if (CE_KnownImm (E)) { - Out->RegA = In->RegA | (short) E->Num; - } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use, In)) { - case REG_TMP1: - Out->RegA = In->RegA | In->Tmp1; - break; - case REG_SREG_LO: - Out->RegA = In->RegA | In->SRegLo; - break; - case REG_SREG_HI: - Out->RegA = In->RegA | In->SRegHi; - break; - default: - Out->RegA = -1; - break; - } - } else { - /* A is now unknown */ - Out->RegA = -1; - } + if (RegValIsKnown (In->RegA)) { + if (CE_IsConstImm (E)) { + Out->RegA = In->RegA | (short) E->Num; + } else if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: + Out->RegA = In->RegA | In->Tmp1; + break; + case REG_PTR1_LO: + Out->RegA = In->RegA | In->Ptr1Lo; + break; + case REG_PTR1_HI: + Out->RegA = In->RegA | In->Ptr1Hi; + break; + case REG_SREG_LO: + Out->RegA = In->RegA | In->SRegLo; + break; + case REG_SREG_HI: + Out->RegA = In->RegA | In->SRegHi; + break; + default: + Out->RegA = UNKNOWN_REGVAL; + break; + } + } else { + /* A is now unknown */ + Out->RegA = UNKNOWN_REGVAL; + } } break; @@ -870,34 +1001,40 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_PLA: - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; break; case OP65_PLP: break; case OP65_PLX: - Out->RegX = -1; + Out->RegX = UNKNOWN_REGVAL; break; case OP65_PLY: - Out->RegY = -1; + Out->RegY = UNKNOWN_REGVAL; break; case OP65_ROL: /* We don't know the value of the carry bit */ if (E->AM == AM65_ACC) { - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: - Out->Tmp1 = -1; + Out->Tmp1 = UNKNOWN_REGVAL; + break; + case REG_PTR1_LO: + Out->Ptr1Lo = UNKNOWN_REGVAL; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = UNKNOWN_REGVAL; break; case REG_SREG_LO: - Out->SRegLo = -1; + Out->SRegLo = UNKNOWN_REGVAL; break; case REG_SREG_HI: - Out->SRegHi = -1; + Out->SRegHi = UNKNOWN_REGVAL; break; } } else if (E->AM == AM65_ZPX) { @@ -909,17 +1046,23 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_ROR: /* We don't know the value of the carry bit */ if (E->AM == AM65_ACC) { - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: - Out->Tmp1 = -1; + Out->Tmp1 = UNKNOWN_REGVAL; + break; + case REG_PTR1_LO: + Out->Ptr1Lo = UNKNOWN_REGVAL; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = UNKNOWN_REGVAL; break; case REG_SREG_LO: - Out->SRegLo = -1; + Out->SRegLo = UNKNOWN_REGVAL; break; case REG_SREG_HI: - Out->SRegHi = -1; + Out->SRegHi = UNKNOWN_REGVAL; break; } } else if (E->AM == AM65_ZPX) { @@ -936,7 +1079,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_SBC: /* We don't know the value of the carry bit */ - Out->RegA = -1; + Out->RegA = UNKNOWN_REGVAL; break; case OP65_SEC: @@ -950,16 +1093,22 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_STA: if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, 0)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: Out->Tmp1 = In->RegA; break; + case REG_PTR1_LO: + Out->Ptr1Lo = In->RegA; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = In->RegA; + break; case REG_SREG_LO: Out->SRegLo = In->RegA; break; case REG_SREG_HI: Out->SRegHi = In->RegA; - break; + break; } } else if (E->AM == AM65_ZPX) { /* Invalidates all ZP registers */ @@ -969,10 +1118,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_STX: if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, 0)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: Out->Tmp1 = In->RegX; break; + case REG_PTR1_LO: + Out->Ptr1Lo = In->RegX; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = In->RegX; + break; case REG_SREG_LO: Out->SRegLo = In->RegX; break; @@ -988,10 +1143,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_STY: if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, 0)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: Out->Tmp1 = In->RegY; break; + case REG_PTR1_LO: + Out->Ptr1Lo = In->RegY; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = In->RegY; + break; case REG_SREG_LO: Out->SRegLo = In->RegY; break; @@ -1007,9 +1168,15 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_STZ: if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg, 0)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: - Out->Tmp1 = 0; + Out->Tmp1 = 0; + break; + case REG_PTR1_LO: + Out->Ptr1Lo = 0; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = 0; break; case REG_SREG_LO: Out->SRegLo = 0; @@ -1037,11 +1204,17 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } else if (E->AM == AM65_ZP) { - if (In->RegA >= 0) { - switch (GetKnownReg (E->Chg, In)) { + if (RegValIsKnown (In->RegA)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: Out->Tmp1 &= ~In->RegA; break; + case REG_PTR1_LO: + Out->Ptr1Lo &= ~In->RegA; + break; + case REG_PTR1_HI: + Out->Ptr1Hi &= ~In->RegA; + break; case REG_SREG_LO: Out->SRegLo &= ~In->RegA; break; @@ -1050,15 +1223,21 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; } } else { - switch (GetKnownReg (E->Chg, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: - Out->Tmp1 = -1; + Out->Tmp1 = UNKNOWN_REGVAL; + break; + case REG_PTR1_LO: + Out->Ptr1Lo = UNKNOWN_REGVAL; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = UNKNOWN_REGVAL; break; case REG_SREG_LO: - Out->SRegLo = -1; + Out->SRegLo = UNKNOWN_REGVAL; break; - case REG_SREG_HI: - Out->SRegHi = -1; + case REG_SREG_HI: + Out->SRegHi = UNKNOWN_REGVAL; break; } } @@ -1070,11 +1249,17 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } else if (E->AM == AM65_ZP) { - if (In->RegA >= 0) { - switch (GetKnownReg (E->Chg, In)) { + if (RegValIsKnown (In->RegA)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: Out->Tmp1 |= In->RegA; break; + case REG_PTR1_LO: + Out->Ptr1Lo |= In->RegA; + break; + case REG_PTR1_HI: + Out->Ptr1Hi |= In->RegA; + break; case REG_SREG_LO: Out->SRegLo |= In->RegA; break; @@ -1083,15 +1268,21 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; } } else { - switch (GetKnownReg (E->Chg, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: - Out->Tmp1 = -1; + Out->Tmp1 = UNKNOWN_REGVAL; + break; + case REG_PTR1_LO: + Out->Ptr1Lo = UNKNOWN_REGVAL; + break; + case REG_PTR1_HI: + Out->Ptr1Hi = UNKNOWN_REGVAL; break; case REG_SREG_LO: - Out->SRegLo = -1; + Out->SRegLo = UNKNOWN_REGVAL; break; case REG_SREG_HI: - Out->SRegHi = -1; + Out->SRegHi = UNKNOWN_REGVAL; break; } } @@ -1099,7 +1290,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_TSX: - Out->RegX = -1; + Out->RegX = UNKNOWN_REGVAL; break; case OP65_TXA: @@ -1135,6 +1326,36 @@ static char* RegInfoDesc (unsigned U, char* Buf) strcat (Buf, U & REG_PTR1? "1" : "_"); strcat (Buf, U & REG_PTR2? "2" : "_"); strcat (Buf, U & REG_SAVE? "V" : "_"); + strcat (Buf, U & REG_SP? "S" : "_"); + + return Buf; +} + + + +static char* RegContentDesc (const RegContents* RC, char* Buf) +/* Return a string containing register contents */ +{ + char* B = Buf; + + if (RegValIsUnknown (RC->RegA)) { + strcpy (B, "A:XX "); + } else { + sprintf (B, "A:%02X ", RC->RegA); + } + B += 5; + if (RegValIsUnknown (RC->RegX)) { + strcpy (B, "X:XX "); + } else { + sprintf (B, "X:%02X ", RC->RegX); + } + B += 5; + if (RegValIsUnknown (RC->RegY)) { + strcpy (B, "Y:XX"); + } else { + sprintf (B, "Y:%02X", RC->RegY); + } + B += 4; return Buf; } @@ -1164,7 +1385,6 @@ void CE_Output (const CodeEntry* E, FILE* F) /* Print the operand */ switch (E->AM) { - case AM_IMP: case AM65_IMP: /* implicit */ break; @@ -1174,13 +1394,11 @@ void CE_Output (const CodeEntry* E, FILE* F) Chars += fprintf (F, "%*sa", 9-Chars, ""); break; - case AM_IMM: case AM65_IMM: /* immidiate */ Chars += fprintf (F, "%*s#%s", 9-Chars, "", E->Arg); break; - case AM_ABS: case AM65_ZP: case AM65_ABS: /* zeropage and absolute */ @@ -1229,15 +1447,24 @@ void CE_Output (const CodeEntry* E, FILE* F) char Use [128]; char Chg [128]; fprintf (F, - "%*s; USE: %-20s CHG: %-20s SIZE: %u\n", + "%*s; USE: %-12s CHG: %-12s SIZE: %u", 30-Chars, "", - RegInfoDesc (E->Use, Use), - RegInfoDesc (E->Chg, Chg), + RegInfoDesc (E->Use, Use), + RegInfoDesc (E->Chg, Chg), E->Size); - } else { - /* Terminate the line */ - fprintf (F, "\n"); + + if (E->RI) { + char RegIn[32]; + char RegOut[32]; + fprintf (F, + " In %s Out %s", + RegContentDesc (&E->RI->In, RegIn), + RegContentDesc (&E->RI->Out, RegOut)); + } } + + /* Terminate the line */ + fprintf (F, "\n"); }