+static unsigned Opt_tosshift (StackOpData* D, const char* Name)
+/* Optimize shift sequences. */
+{
+ CodeEntry* X;
+
+ /* Store the value into the zeropage instead of pushing it */
+ ReplacePushByStore (D);
+
+ /* If the lhs is direct (but not stack relative), we can just reload the
+ ** data later.
+ */
+ if ((D->Lhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT &&
+ (D->Lhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT) {
+
+ CodeEntry* LoadX = D->Lhs.X.LoadEntry;
+ CodeEntry* LoadA = D->Lhs.A.LoadEntry;
+
+ /* Inline the shift */
+ D->IP = D->OpIndex+1;
+
+ /* tay */
+ X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, D->OpEntry->LI);
+ InsertEntry (D, X, D->IP++);
+
+ /* lda */
+ X = NewCodeEntry (OP65_LDA, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI);
+ InsertEntry (D, X, D->IP++);
+
+ /* ldx */
+ X = NewCodeEntry (OP65_LDX, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI);
+ InsertEntry (D, X, D->IP++);
+
+ /* Lhs load entries can be removed */
+ D->Lhs.X.Flags |= LI_REMOVE;
+ D->Lhs.A.Flags |= LI_REMOVE;
+
+ } else {
+
+ /* Save lhs into zeropage and reload later */
+ AddStoreX (D);
+ AddStoreA (D);
+
+ /* Be sure to setup IP after adding the stores, otherwise it will get
+ ** messed up.
+ */
+ D->IP = D->OpIndex+1;
+
+ /* tay */
+ X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, D->OpEntry->LI);
+ InsertEntry (D, X, D->IP++);
+
+ /* lda zp */
+ X = NewCodeEntry (OP65_LDA, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI);
+ InsertEntry (D, X, D->IP++);
+
+ /* ldx zp+1 */
+ X = NewCodeEntry (OP65_LDX, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
+ InsertEntry (D, X, D->IP++);
+
+ }
+
+ /* jsr shlaxy/aslaxy/whatever */
+ X = NewCodeEntry (OP65_JSR, AM65_ABS, Name, 0, D->OpEntry->LI);
+ InsertEntry (D, X, D->IP++);
+
+ /* Remove the push and the call to the shift function */
+ RemoveRemainders (D);
+
+ /* We changed the sequence */
+ return 1;
+}
+
+
+