Added special multiplication routines

git-svn-id: svn://svn.cc65.org/cc65/trunk@1012 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-10-04 21:34:14 +00:00
parent 560ac0ac43
commit 0fdf581d06
6 changed files with 188 additions and 36 deletions

View file

@ -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
View 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
View 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
View 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

View file

@ -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);
}

View file

@ -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);
}