case CF_CHAR:
if (flags & CF_FORCECHAR) {
- if ((val & 0xFF) != 0xFF) {
+ if ((val & 0xFF) != 0) {
AddCodeLine ("ora #$%02X", (unsigned char)val);
}
return;
/* FALLTHROUGH */
case CF_INT:
- if (val <= 0xFF) {
- AddCodeLine ("ora #$%02X", (unsigned char)val);
+ if (val <= 0xFF) {
+ if ((val & 0xFF) != 0) {
+ AddCodeLine ("ora #$%02X", (unsigned char)val);
+ }
return;
- }
+ } else if ((val & 0xFF00) == 0xFF00) {
+ if ((val & 0xFF) != 0) {
+ AddCodeLine ("ora #$%02X", (unsigned char)val);
+ }
+ ldxconst (0xFF);
+ return;
+ }
break;
case CF_LONG:
if (val <= 0xFF) {
- AddCodeLine ("ora #$%02X", (unsigned char)val);
+ if ((val & 0xFF) != 0) {
+ AddCodeLine ("ora #$%02X", (unsigned char)val);
+ }
return;
}
break;
-void g_and (unsigned flags, unsigned long val)
+void g_and (unsigned Flags, unsigned long Val)
/* Primary = TOS & Primary */
{
static char* ops [12] = {
- 0, "tosanda0", "tosandax",
- 0, "tosanda0", "tosandax",
- 0, 0, "tosandeax",
- 0, 0, "tosandeax",
+ 0, "tosanda0", "tosandax",
+ 0, "tosanda0", "tosandax",
+ 0, 0, "tosandeax",
+ 0, 0, "tosandeax",
};
-
+
/* If the right hand side is const, the lhs is not on stack but still
* in the primary register.
*/
- if (flags & CF_CONST) {
+ if (Flags & CF_CONST) {
- switch (flags & CF_TYPE) {
+ switch (Flags & CF_TYPE) {
case CF_CHAR:
- if (flags & CF_FORCECHAR) {
- AddCodeLine ("and #$%02X", (unsigned char)val);
- return;
- }
- /* FALLTHROUGH */
+ if (Flags & CF_FORCECHAR) {
+ if ((Val & 0xFF) != 0xFF) {
+ AddCodeLine ("and #$%02X", (unsigned char)Val);
+ }
+ return;
+ }
+ /* FALLTHROUGH */
case CF_INT:
- if ((val & 0xFFFF) != 0xFFFF) {
- if (val <= 0xFF) {
- ldxconst (0);
- if (val == 0) {
- ldaconst (0);
- } else if (val != 0xFF) {
- AddCodeLine ("and #$%02X", (unsigned char)val);
- }
- } else if ((val & 0xFF00) == 0xFF00) {
- AddCodeLine ("and #$%02X", (unsigned char)val);
- } else if ((val & 0x00FF) == 0x0000) {
- AddCodeLine ("txa");
- AddCodeLine ("and #$%02X", (unsigned char)(val >> 8));
- AddCodeLine ("tax");
- ldaconst (0);
+ if ((Val & 0xFFFF) != 0xFFFF) {
+ if (Val <= 0xFF) {
+ ldxconst (0);
+ if (Val == 0) {
+ ldaconst (0);
+ } else if (Val != 0xFF) {
+ AddCodeLine ("and #$%02X", (unsigned char)Val);
+ }
+ } else if ((Val & 0xFF00) == 0xFF00) {
+ AddCodeLine ("and #$%02X", (unsigned char)Val);
+ } else if ((Val & 0x00FF) == 0x0000) {
+ AddCodeLine ("txa");
+ AddCodeLine ("and #$%02X", (unsigned char)(Val >> 8));
+ AddCodeLine ("tax");
+ ldaconst (0);
} else {
- AddCodeLine ("tay");
- AddCodeLine ("txa");
- AddCodeLine ("and #$%02X", (unsigned char)(val >> 8));
- AddCodeLine ("tax");
- AddCodeLine ("tya");
- if ((val & 0x00FF) != 0x00FF) {
- AddCodeLine ("and #$%02X", (unsigned char)val);
- }
- }
- }
+ AddCodeLine ("tay");
+ AddCodeLine ("txa");
+ AddCodeLine ("and #$%02X", (unsigned char)(Val >> 8));
+ AddCodeLine ("tax");
+ AddCodeLine ("tya");
+ if ((Val & 0x00FF) != 0x00FF) {
+ AddCodeLine ("and #$%02X", (unsigned char)Val);
+ }
+ }
+ }
return;
case CF_LONG:
- if (val <= 0xFF) {
+ if (Val <= 0xFF) {
ldxconst (0);
AddCodeLine ("stx sreg+1");
AddCodeLine ("stx sreg");
- if ((val & 0xFF) != 0xFF) {
- AddCodeLine ("and #$%02X", (unsigned char)val);
+ if ((Val & 0xFF) != 0xFF) {
+ AddCodeLine ("and #$%02X", (unsigned char)Val);
}
return;
- } else if (val == 0xFF00) {
+ } else if (Val == 0xFF00) {
ldaconst (0);
AddCodeLine ("sta sreg+1");
AddCodeLine ("sta sreg");
break;
default:
- typeerror (flags);
+ typeerror (Flags);
}
/* If we go here, we didn't emit code. Push the lhs on stack and fall
* into the normal, non-optimized stuff. Note: The standard stuff will
* always work with ints.
*/
- flags &= ~CF_FORCECHAR;
- g_push (flags & ~CF_CONST, 0);
+ Flags &= ~CF_FORCECHAR;
+ g_push (Flags & ~CF_CONST, 0);
}
-
+
/* Use long way over the stack */
- oper (flags, val, ops);
+ oper (Flags, Val, ops);
}
/* Get a pointer to the output registers of the insn */
const RegContents* Out = &E->RI->Out;
+ /* Argument for LDA and flag */
+ const char* Arg = 0;
+
/* Handle the different instructions */
switch (E->OPC) {
/* FALLTHROUGH */
case OP65_ADC:
- case OP65_AND:
case OP65_ASL:
case OP65_EOR:
case OP65_LSR:
- case OP65_ORA:
case OP65_SBC:
if (RegValIsKnown (Out->RegA)) {
/* Accu AND zp with known contents */
- const char* Arg = MakeHexArg (Out->RegA);
- CodeEntry* X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
- CS_InsertEntry (S, X, I+1);
+ Arg = MakeHexArg (Out->RegA);
+ }
+ break;
+
+ case OP65_AND:
+ if (CE_KnownImm (E) && E->Num == 0xFF) {
+ /* AND with 0xFF, remove */
CS_DelEntry (S, I);
++Changes;
+ } else if (RegValIsKnown (Out->RegA)) {
+ /* Accu AND zp with known contents */
+ Arg = MakeHexArg (Out->RegA);
+ }
+ break;
+
+ case OP65_ORA:
+ if (CE_KnownImm (E) && E->Num == 0x00) {
+ /* ORA with zero, remove */
+ CS_DelEntry (S, I);
+ ++Changes;
+ } else if (RegValIsKnown (Out->RegA)) {
+ /* Accu AND zp with known contents */
+ Arg = MakeHexArg (Out->RegA);
}
break;
}
+ /* Check if we have to replace the insn by LDA */
+ if (Arg) {
+ CodeEntry* X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
+ CS_InsertEntry (S, X, I+1);
+ CS_DelEntry (S, I);
+ ++Changes;
+ }
+
/* Next entry */
++I;
}
InsertEntry (D, X, D->IP++);
}
-
+
static void AddOpHigh (StackOpData* D, opc_t OPC)
/* Add an op for the high byte of an operator. Special cases (constant values
if (RegValIsKnown (D->PushEntry->RI->In.RegX) &&
RegValIsKnown (D->OpEntry->RI->In.RegX)) {
/* Both values known, precalculate the result */
- const char* Arg = MakeHexArg (D->PushEntry->RI->In.RegX | D->OpEntry->RI->In.RegX);
- X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, D->OpEntry->LI);
- InsertEntry (D, X, D->IP++);
+ unsigned char Result = D->PushEntry->RI->In.RegX | D->OpEntry->RI->In.RegX;
+ const char* Arg = MakeHexArg (Result);
+ X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, D->OpEntry->LI);
+ InsertEntry (D, X, D->IP++);
} else if (D->PushEntry->RI->In.RegX != 0) {
/* High byte is unknown */
AddOpHigh (D, OP65_ORA);