if (flags & CF_CONST && (p2 = powerof2 (val)) >= 0) {
/* Generate a shift instead */
g_asl (flags, p2);
- return;
+ return;
}
/* If the right hand side is const, the lhs is not on stack but still
case CF_CHAR:
if (flags & CF_FORCECHAR) {
- /* Handle some special cases */
- switch (val) {
-
- case 3:
- AddCodeLine ("sta tmp1");
- AddCodeLine ("asl a");
- AddCodeLine ("clc");
- AddCodeLine ("adc tmp1");
- return;
-
- case 5:
- AddCodeLine ("sta tmp1");
- AddCodeLine ("asl a");
- AddCodeLine ("asl a");
- AddCodeLine ("clc");
+ /* Handle some special cases */
+ switch (val) {
+
+ case 3:
+ AddCodeLine ("sta tmp1");
+ AddCodeLine ("asl a");
+ AddCodeLine ("clc");
AddCodeLine ("adc tmp1");
- return;
-
- case 10:
- AddCodeLine ("sta tmp1");
- AddCodeLine ("asl a");
- AddCodeLine ("asl a");
- AddCodeLine ("clc");
- AddCodeLine ("adc tmp1");
- AddCodeLine ("asl a");
- return;
- }
+ return;
+
+ case 5:
+ AddCodeLine ("sta tmp1");
+ AddCodeLine ("asl a");
+ AddCodeLine ("asl a");
+ AddCodeLine ("clc");
+ AddCodeLine ("adc tmp1");
+ return;
+
+ case 10:
+ AddCodeLine ("sta tmp1");
+ AddCodeLine ("asl a");
+ AddCodeLine ("asl a");
+ AddCodeLine ("clc");
+ AddCodeLine ("adc tmp1");
+ AddCodeLine ("asl a");
+ return;
+ }
}
/* FALLTHROUGH */
- case CF_INT:
- break;
+ case CF_INT:
+ switch (val) {
+ case 3:
+ AddCodeLine ("jsr mulax3");
+ return;
+ case 5:
+ AddCodeLine ("jsr mulax5");
+ return;
+ case 10:
+ AddCodeLine ("jsr mulax10");
+ return;
+ }
+ break;
- case CF_LONG:
- break;
+ case CF_LONG:
+ break;
- default:
- typeerror (flags);
- }
+ default:
+ typeerror (flags);
+ }
- /* If we go here, we didn't emit code. Push the lhs on stack and fall
- * into the normal, non-optimized stuff.
- */
- flags &= ~CF_FORCECHAR; /* Handle chars as ints */
+ /* If we go here, we didn't emit code. Push the lhs on stack and fall
+ * into the normal, non-optimized stuff.
+ */
+ flags &= ~CF_FORCECHAR; /* Handle chars as ints */
g_push (flags & ~CF_CONST, 0);
}
+static unsigned OptShift2 (CodeSeg* S)
+/* A call to the shraxN routine may get replaced by one or more lsr insns
+ * if the value of X is not used later.
+ */
+{
+ unsigned Changes = 0;
+
+ /* Walk over the entries */
+ unsigned I = 0;
+ while (I < CS_GetEntryCount (S)) {
+
+ /* Get next entry */
+ CodeEntry* E = CS_GetEntry (S, I);
+
+ /* Check for the sequence */
+ if (E->OPC == OP65_JSR &&
+ strncmp (E->Arg, "shrax", 5) == 0 &&
+ strlen (E->Arg) == 6 &&
+ IsDigit (E->Arg[5]) &&
+ !RegXUsed (S, I+1)) {
+
+ /* Insert shift insns */
+ unsigned Count = E->Arg[5] - '0';
+ while (Count--) {
+ CodeEntry* X = NewCodeEntry (OP65_LSR, AM65_ACC, "a", 0, E->LI);
+ CS_InsertEntry (S, X, I+1);
+ }
+
+ /* Delete the call to shlax */
+ CS_DelEntry (S, I);
+
+ /* Remember, we had changes */
+ ++Changes;
+
+ }
+
+ /* Next entry */
+ ++I;
+
+ }
+
+ /* Return the number of changes made */
+ return Changes;
+}
+
+
+
/*****************************************************************************/
/* Optimize stores through pointers */
/*****************************************************************************/
static OptFunc DOptPtrStore1 = { OptPtrStore1, "OptPtrStore1", 0, 0, 0, 0, 0 };
static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 0, 0, 0, 0, 0 };
static OptFunc DOptShift1 = { OptShift1, "OptShift1", 0, 0, 0, 0, 0 };
+static OptFunc DOptShift2 = { OptShift2, "OptShift2", 0, 0, 0, 0, 0 };
static OptFunc DOptSize1 = { OptSize1, "OptSize1", 0, 0, 0, 0, 0 };
static OptFunc DOptSize2 = { OptSize2, "OptSize2", 0, 0, 0, 0, 0 };
static OptFunc DOptStackOps = { OptStackOps, "OptStackOps", 0, 0, 0, 0, 0 };
&DOptRTS,
&DOptRTSJumps,
&DOptShift1,
+ &DOptShift2,
&DOptSize1,
&DOptSize2,
&DOptStackOps,
RunOptFunc (S, &DOptAdd1, 1);
RunOptFunc (S, &DOptAdd2, 1);
RunOptFunc (S, &DOptShift1, 1);
+ RunOptFunc (S, &DOptShift2, 1);
}