static const FuncInfo FuncInfoTable[] = {
{ "addysp", REG_Y, REG_NONE },
+ { "bnega", REG_A, REG_AX },
+ { "bnegax", REG_AX, REG_AX },
+ { "bnegeax", REG_AX, REG_AX },
{ "booleq", REG_NONE, REG_AX },
{ "boolge", REG_NONE, REG_AX },
{ "boolgt", REG_NONE, REG_AX },
{ "boolugt", REG_NONE, REG_AX },
{ "boolule", REG_NONE, REG_AX },
{ "boolult", REG_NONE, REG_AX },
+ { "complax", REG_AX, REG_AX },
{ "decax1", REG_AX, REG_AX },
{ "decax2", REG_AX, REG_AX },
{ "decax3", REG_AX, REG_AX },
{ "decsp6", REG_NONE, REG_A },
{ "decsp7", REG_NONE, REG_A },
{ "decsp8", REG_NONE, REG_A },
+ { "incax1", REG_AX, REG_AX },
+ { "incax2", REG_AX, REG_AX },
{ "incsp1", REG_NONE, REG_NONE },
{ "incsp2", REG_NONE, REG_Y },
{ "incsp3", REG_NONE, REG_Y },
{ "ldaxidx", REG_AXY, REG_AX },
{ "ldaxysp", REG_Y, REG_AX },
{ "leaasp", REG_A, REG_AX },
+ { "negax", REG_AX, REG_AX },
{ "pusha", REG_A, REG_Y },
{ "pusha0", REG_A, REG_XY },
{ "pushax", REG_AX, REG_Y },
+ { "pusheax", REG_AX, REG_Y },
{ "pushw0sp", REG_NONE, REG_AXY },
{ "pushwysp", REG_Y, REG_AXY },
+ { "shrax1", REG_AX, REG_AX },
+ { "shrax2", REG_AX, REG_AX },
+ { "shrax3", REG_AX, REG_AX },
+ { "shreax1", REG_AX, REG_AX },
+ { "shreax2", REG_AX, REG_AX },
+ { "shreax3", REG_AX, REG_AX },
+ { "staspidx", REG_A | REG_Y, REG_Y },
{ "tosicmp", REG_AX, REG_AXY },
+ { "tosshreax", REG_AX, REG_AXY },
};
#define FuncInfoCount (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0]))
unsigned char Use, Chg;
CodeEntry* N;
-
+
/* Get next entry */
CodeEntry* E = CS_GetEntry (S, I);
RegA ^= (int) E->Num;
} else {
RegA = -1;
- }
+ }
}
break;
/* If the value in the Y register is known and the same as
* that in the A register, replace the store by a STA. The
* optimizer will then remove the load instruction for Y
- * later.
+ * later. If replacement by A is not possible try a
+ * replacement by X, but check for invalid addressing modes
+ * in this case.
*/
- if (RegY >= 0 && RegY == RegA) {
- CE_ReplaceOPC (E, OP65_STA);
+ if (RegY >= 0) {
+ if (RegY == RegA) {
+ CE_ReplaceOPC (E, OP65_STA);
+ } else if (RegY == RegX && E->AM != AM65_ABSX && E->AM != AM65_ZPX) {
+ CE_ReplaceOPC (E, OP65_STX);
+ }
}
break;
break;
case OP65_TAY:
- N = CS_GetNextEntry (S, I);
+ N = CS_GetNextEntry (S, I);
if (RegA >= 0 && RegA == RegY && N && (N->Info & OF_FBRA) == 0) {
/* Value is identical and not followed by a branch */
Delete = 1;
+unsigned OptStoreLoad (CodeSeg* S)
+/* Remove a store followed by a load from the same location. */
+{
+ unsigned Changes = 0;
+
+ /* Walk over the entries */
+ unsigned I = 0;
+ while (I < CS_GetEntryCount (S)) {
+
+ CodeEntry* N;
+ CodeEntry* X;
+
+ /* Get next entry */
+ CodeEntry* E = CS_GetEntry (S, I);
+
+ /* Check if it is a store instruction followed by a load from the
+ * same address which is itself not followed by a conditional branch.
+ */
+ if ((E->Info & OF_STORE) != 0 &&
+ (N = CS_GetNextEntry (S, I)) != 0 &&
+ (N->Info & OF_LOAD) != 0 &&
+ strcmp (E->Arg, N->Arg) == 0 &&
+ (X = CS_GetNextEntry (S, I+1)) != 0 &&
+ (X->Info & OF_FBRA) == 0) {
+
+ /* Register value is not used, remove the load */
+ CS_DelEntry (S, I+1);
+
+ /* Remember, we had changes */
+ ++Changes;
+
+ }
+
+ /* Next entry */
+ ++I;
+
+ }
+
+ /* Return the number of changes made */
+ return Changes;
+}
+
+
+
/*****************************************************************************/
/* Optimize branch types */
/*****************************************************************************/