/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 2001-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
-/* Defines for the conditions in a compare */
-typedef enum {
- CMP_INV = -1,
- CMP_EQ,
- CMP_NE,
- CMP_GT,
- CMP_GE,
- CMP_LT,
- CMP_LE,
- CMP_UGT,
- CMP_UGE,
- CMP_ULT,
- CMP_ULE
-} cmp_t;
-
-/* Table with the compare suffixes */
-static const char CmpSuffixTab [][4] = {
- "eq", "ne", "gt", "ge", "lt", "le", "ugt", "uge", "ult", "ule"
-};
-
/* Table used to invert a condition, indexed by condition */
static const unsigned char CmpInvertTab [] = {
CMP_NE, CMP_EQ,
-static cmp_t FindCmpCond (const char* Code, unsigned CodeLen)
-/* Search for a compare condition by the given code using the given length */
-{
- unsigned I;
-
- /* Linear search */
- for (I = 0; I < sizeof (CmpSuffixTab) / sizeof (CmpSuffixTab [0]); ++I) {
- if (strncmp (Code, CmpSuffixTab [I], CodeLen) == 0) {
- /* Found */
- return I;
- }
- }
-
- /* Not found */
- return CMP_INV;
-}
-
-
-
-static cmp_t FindBoolCmpCond (const char* Name)
-/* Map a condition suffix to a code. Return the code or CMP_INV on failure */
-{
- /* Check for the correct subroutine name */
- if (strncmp (Name, "bool", 4) == 0) {
- /* Name is ok, search for the code in the table */
- return FindCmpCond (Name+4, strlen(Name)-4);
- } else {
- /* Not found */
- return CMP_INV;
- }
-}
-
-
-
-static cmp_t FindTosCmpCond (const char* Name)
-/* Check if this is a call to one of the TOS compare functions (tosgtax).
- * Return the condition code or CMP_INV on failure.
- */
-{
- unsigned Len = strlen (Name);
-
- /* Check for the correct subroutine name */
- if (strncmp (Name, "tos", 3) == 0 && strcmp (Name+Len-2, "ax") == 0) {
- /* Name is ok, search for the code in the table */
- return FindCmpCond (Name+3, Len-3-2);
- } else {
- /* Not found */
- return CMP_INV;
- }
-}
-
-
-
static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
/* Helper function for the replacement of routines that return a boolean
* followed by a conditional jump. Instead of the boolean value, the condition
/* Check for a boolean transformer */
if (E->OPC == OP65_JSR &&
(Cond = FindBoolCmpCond (E->Arg)) != CMP_INV &&
- (N = CS_GetNextEntry (S, I)) != 0 &&
+ (N = CS_GetNextEntry (S, I)) != 0 &&
(N->Info & OF_ZBRA) != 0) {
/* Make the boolean transformer unnecessary by changing the
if (E->OPC == OP65_STX &&
!CS_RangeHasLabel (S, I+1, 2) &&
CS_GetEntries (S, L, I+1, 2) &&
- L[0]->OPC == OP65_STX &&
+ L[0]->OPC == OP65_STX &&
strcmp (L[0]->Arg, "tmp1") == 0 &&
L[1]->OPC == OP65_ORA &&
strcmp (L[1]->Arg, "tmp1") == 0) {
/* Check for the sequence */
if ((L[0]->OPC == OP65_ADC ||
L[0]->OPC == OP65_AND ||
+ L[0]->OPC == OP65_ASL ||
L[0]->OPC == OP65_DEA ||
L[0]->OPC == OP65_EOR ||
L[0]->OPC == OP65_INA ||
L[0]->OPC == OP65_LDA ||
+ L[0]->OPC == OP65_LSR ||
L[0]->OPC == OP65_ORA ||
L[0]->OPC == OP65_PLA ||
L[0]->OPC == OP65_SBC ||
L[0]->OPC == OP65_TXA ||
L[0]->OPC == OP65_TYA) &&
!CS_RangeHasLabel (S, I+1, 2) &&
- CS_GetEntries (S, L+1, I+1, 2) &&
+ CS_GetEntries (S, L+1, I+1, 2) &&
L[1]->OPC == OP65_CMP &&
CE_KnownImm (L[1]) &&
L[1]->Num == 0) {
- /* Check for the call to boolxx. We cannot remove the compare if
+ /* Check for the call to boolxx. We only remove the compare if
* the carry flag is evaluated later, because the load will not
* set the carry flag.
*/
CE_KnownImm (L[0]) &&
CS_GetEntries (S, L+1, I+1, 5) &&
!CE_HasLabel (L[1]) &&
- CE_IsCall (L[1], "ldaxysp") &&
+ CE_IsCallTo (L[1], "ldaxysp") &&
IsImmCmp16 (L+2)) {
if ((L[5]->Info & OF_FBRA) != 0 && L[2]->Num == 0 && L[4]->Num == 0) {
/* Change the code to just use the A register. Move the load
* of the low byte after the first branch if possible:
*
- * ldy #o-1
+ * ldy #o
* lda (sp),y
* cmp #a
* bne L1
- * ldy #o
+ * ldy #o-1
* lda (sp),y
* cmp #b
* jne/jeq ...
*/
- sprintf (Buf, "$%02X", (int)(L[0]->Num-1));
- X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
+ X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI);
CS_InsertEntry (S, X, I+3);
X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
X = NewCodeEntry (OP65_CMP, L[2]->AM, L[2]->Arg, 0, L[2]->LI);
CS_InsertEntry (S, X, I+5);
- X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI);
+ sprintf (Buf, "$%02X", (int)(L[0]->Num-1));
+ X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
CS_InsertEntry (S, X, I+7);
X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);