Added special multiplication routines
git-svn-id: svn://svn.cc65.org/cc65/trunk@1012 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
560ac0ac43
commit
0fdf581d06
6 changed files with 188 additions and 36 deletions
|
@ -130,6 +130,9 @@ OBJS = add.o \
|
|||
makebool.o \
|
||||
mod.o \
|
||||
mul.o \
|
||||
mulax3.o \
|
||||
mulax5.o \
|
||||
mulax10.o \
|
||||
ne.o \
|
||||
neg.o \
|
||||
or.o \
|
||||
|
|
32
libsrc/runtime/mulax10.s
Normal file
32
libsrc/runtime/mulax10.s
Normal file
|
@ -0,0 +1,32 @@
|
|||
;
|
||||
; Ullrich von Bassewitz, 04.10.2001
|
||||
;
|
||||
; CC65 runtime: Multiply the primary register
|
||||
;
|
||||
|
||||
.export mulax10
|
||||
.importzp ptr1
|
||||
|
||||
.proc mulax10
|
||||
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
asl a
|
||||
rol ptr1+1
|
||||
asl a
|
||||
rol ptr1+1
|
||||
clc
|
||||
adc ptr1
|
||||
pha
|
||||
txa
|
||||
adc ptr1+1
|
||||
sta ptr1+1
|
||||
pla
|
||||
asl a
|
||||
rol ptr1+1
|
||||
ldx ptr1+1
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
27
libsrc/runtime/mulax3.s
Normal file
27
libsrc/runtime/mulax3.s
Normal file
|
@ -0,0 +1,27 @@
|
|||
;
|
||||
; Ullrich von Bassewitz, 04.10.2001
|
||||
;
|
||||
; CC65 runtime: Multiply the primary register
|
||||
;
|
||||
|
||||
.export mulax3
|
||||
.importzp ptr1
|
||||
|
||||
.proc mulax3
|
||||
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
asl a
|
||||
rol ptr1+1
|
||||
clc
|
||||
adc ptr1
|
||||
pha
|
||||
txa
|
||||
adc ptr1+1
|
||||
tax
|
||||
pla
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
29
libsrc/runtime/mulax5.s
Normal file
29
libsrc/runtime/mulax5.s
Normal file
|
@ -0,0 +1,29 @@
|
|||
;
|
||||
; Ullrich von Bassewitz, 04.10.2001
|
||||
;
|
||||
; CC65 runtime: Multiply the primary register
|
||||
;
|
||||
|
||||
.export mulax5
|
||||
.importzp ptr1
|
||||
|
||||
.proc mulax5
|
||||
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
asl a
|
||||
rol ptr1+1
|
||||
asl a
|
||||
rol ptr1+1
|
||||
clc
|
||||
adc ptr1
|
||||
pha
|
||||
txa
|
||||
adc ptr1+1
|
||||
tax
|
||||
pla
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
|
@ -2526,7 +2526,7 @@ void g_mul (unsigned flags, unsigned long val)
|
|||
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
|
||||
|
@ -2538,50 +2538,61 @@ void g_mul (unsigned flags, unsigned long val)
|
|||
|
||||
case CF_CHAR:
|
||||
if (flags & CF_FORCECHAR) {
|
||||
/* Handle some special cases */
|
||||
switch (val) {
|
||||
/* 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");
|
||||
case 3:
|
||||
AddCodeLine ("sta tmp1");
|
||||
AddCodeLine ("asl a");
|
||||
AddCodeLine ("clc");
|
||||
AddCodeLine ("adc tmp1");
|
||||
return;
|
||||
return;
|
||||
|
||||
case 10:
|
||||
AddCodeLine ("sta tmp1");
|
||||
AddCodeLine ("asl a");
|
||||
AddCodeLine ("asl a");
|
||||
AddCodeLine ("clc");
|
||||
AddCodeLine ("adc tmp1");
|
||||
AddCodeLine ("asl a");
|
||||
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);
|
||||
|
||||
}
|
||||
|
|
|
@ -115,6 +115,53 @@ static unsigned OptShift1 (CodeSeg* S)
|
|||
|
||||
|
||||
|
||||
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 */
|
||||
/*****************************************************************************/
|
||||
|
@ -1299,6 +1346,7 @@ static OptFunc DOptPtrLoad6 = { OptPtrLoad6, "OptPtrLoad6", 0, 0, 0, 0
|
|||
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 };
|
||||
|
@ -1349,6 +1397,7 @@ static OptFunc* OptFuncs[] = {
|
|||
&DOptRTS,
|
||||
&DOptRTSJumps,
|
||||
&DOptShift1,
|
||||
&DOptShift2,
|
||||
&DOptSize1,
|
||||
&DOptSize2,
|
||||
&DOptStackOps,
|
||||
|
@ -1596,6 +1645,7 @@ static void RunOptGroup1 (CodeSeg* S)
|
|||
RunOptFunc (S, &DOptAdd1, 1);
|
||||
RunOptFunc (S, &DOptAdd2, 1);
|
||||
RunOptFunc (S, &DOptShift1, 1);
|
||||
RunOptFunc (S, &DOptShift2, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue