Don't generate short code for the tosxxx functions when X is zero or similar.

Let the optimizer do it. This reduces the number of possible patterns that
must be detected by the optimizer. Add tosicmp0 as a shortcut function.


git-svn-id: svn://svn.cc65.org/cc65/trunk@4006 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz
2009-08-14 22:10:04 +00:00
parent 6a26b6e3b4
commit 0b7b9354dc
3 changed files with 61 additions and 135 deletions

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2004 Ullrich von Bassewitz */ /* (C) 1998-2009 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -2267,58 +2267,33 @@ void g_cmp (unsigned flags, unsigned long val)
static void oper (unsigned flags, unsigned long val, char** subs) static void oper (unsigned Flags, unsigned long Val, const char** Subs)
/* Encode a binary operation. subs is a pointer to four groups of three /* Encode a binary operation. subs is a pointer to four strings:
* strings: * 0 --> Operate on ints
* 0-2 --> Operate on ints * 1 --> Operate on unsigneds
* 3-5 --> Operate on unsigneds * 2 --> Operate on longs
* 6-8 --> Operate on longs * 3 --> Operate on unsigned longs
* 9-11 --> Operate on unsigned longs
*
* The first subroutine names in each string group is used to encode an
* operation with a zero constant, the second to encode an operation with
* a 8 bit constant, and the third is used in all other cases.
*/ */
{ {
unsigned offs;
/* Determine the offset into the array */ /* Determine the offset into the array */
offs = (flags & CF_UNSIGNED)? 3 : 0; if (Flags & CF_UNSIGNED) {
switch (flags & CF_TYPE) { ++Subs;
case CF_CHAR: }
case CF_INT: if ((Flags & CF_TYPE) == CF_LONG) {
break; Subs += 2;
case CF_LONG:
offs += 6;
break;
default:
typeerror (flags);
} }
/* Encode the operation */ /* Load the value if it is not already in the primary */
if (flags & CF_CONST) { if (Flags & CF_CONST) {
/* Constant value given */ /* Load value */
if (val == 0 && subs [offs+0]) { g_getimmed (Flags, Val, 0);
/* Special case: constant with value zero */
AddCodeLine ("jsr %s", subs [offs+0]);
} else if (val < 0x100 && subs [offs+1]) {
/* Special case: constant with high byte zero */
ldaconst (val); /* Load low byte */
AddCodeLine ("jsr %s", subs [offs+1]);
} else {
/* Others: arbitrary constant value */
g_getimmed (flags, val, 0); /* Load value */
AddCodeLine ("jsr %s", subs [offs+2]);
}
} else {
/* Value not constant (is already in (e)ax) */
AddCodeLine ("jsr %s", subs [offs+2]);
} }
/* Output the operation */
AddCodeLine ("jsr %s", *Subs);
/* The operation will pop it's argument */ /* The operation will pop it's argument */
pop (flags); pop (Flags);
} }
@@ -2550,11 +2525,8 @@ void g_stackcheck (void)
void g_add (unsigned flags, unsigned long val) void g_add (unsigned flags, unsigned long val)
/* Primary = TOS + Primary */ /* Primary = TOS + Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, "tosadda0", "tosaddax", "tosaddax", "tosaddax", "tosaddeax", "tosaddeax"
0, "tosadda0", "tosaddax",
0, 0, "tosaddeax",
0, 0, "tosaddeax",
}; };
if (flags & CF_CONST) { if (flags & CF_CONST) {
@@ -2569,11 +2541,8 @@ void g_add (unsigned flags, unsigned long val)
void g_sub (unsigned flags, unsigned long val) void g_sub (unsigned flags, unsigned long val)
/* Primary = TOS - Primary */ /* Primary = TOS - Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, "tossuba0", "tossubax", "tossubax", "tossubax", "tossubeax", "tossubeax",
0, "tossuba0", "tossubax",
0, 0, "tossubeax",
0, 0, "tossubeax",
}; };
if (flags & CF_CONST) { if (flags & CF_CONST) {
@@ -2588,11 +2557,8 @@ void g_sub (unsigned flags, unsigned long val)
void g_rsub (unsigned flags, unsigned long val) void g_rsub (unsigned flags, unsigned long val)
/* Primary = Primary - TOS */ /* Primary = Primary - TOS */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, "tosrsuba0", "tosrsubax", "tosrsubax", "tosrsubax", "tosrsubeax", "tosrsubeax",
0, "tosrsuba0", "tosrsubax",
0, 0, "tosrsubeax",
0, 0, "tosrsubeax",
}; };
oper (flags, val, ops); oper (flags, val, ops);
} }
@@ -2602,11 +2568,8 @@ void g_rsub (unsigned flags, unsigned long val)
void g_mul (unsigned flags, unsigned long val) void g_mul (unsigned flags, unsigned long val)
/* Primary = TOS * Primary */ /* Primary = TOS * Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, "tosmula0", "tosmulax", "tosmulax", "tosumulax", "tosmuleax", "tosumuleax",
0, "tosumula0", "tosumulax",
0, 0, "tosmuleax",
0, 0, "tosumuleax",
}; };
int p2; int p2;
@@ -2712,11 +2675,8 @@ void g_mul (unsigned flags, unsigned long val)
void g_div (unsigned flags, unsigned long val) void g_div (unsigned flags, unsigned long val)
/* Primary = TOS / Primary */ /* Primary = TOS / Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, "tosdiva0", "tosdivax", "tosdivax", "tosudivax", "tosdiveax", "tosudiveax",
0, "tosudiva0", "tosudivax",
0, 0, "tosdiveax",
0, 0, "tosudiveax",
}; };
/* Do strength reduction if the value is constant and a power of two */ /* Do strength reduction if the value is constant and a power of two */
@@ -2740,11 +2700,8 @@ void g_div (unsigned flags, unsigned long val)
void g_mod (unsigned flags, unsigned long val) void g_mod (unsigned flags, unsigned long val)
/* Primary = TOS % Primary */ /* Primary = TOS % Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, "tosmoda0", "tosmodax", "tosmodax", "tosumodax", "tosmodeax", "tosumodeax",
0, "tosumoda0", "tosumodax",
0, 0, "tosmodeax",
0, 0, "tosumodeax",
}; };
int p2; int p2;
@@ -2768,11 +2725,8 @@ void g_mod (unsigned flags, unsigned long val)
void g_or (unsigned flags, unsigned long val) void g_or (unsigned flags, unsigned long val)
/* Primary = TOS | Primary */ /* Primary = TOS | Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, "tosora0", "tosorax", "tosorax", "tosorax", "tosoreax", "tosoreax",
0, "tosora0", "tosorax",
0, 0, "tosoreax",
0, 0, "tosoreax",
}; };
/* If the right hand side is const, the lhs is not on stack but still /* If the right hand side is const, the lhs is not on stack but still
@@ -2841,11 +2795,8 @@ void g_or (unsigned flags, unsigned long val)
void g_xor (unsigned flags, unsigned long val) void g_xor (unsigned flags, unsigned long val)
/* Primary = TOS ^ Primary */ /* Primary = TOS ^ Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, "tosxora0", "tosxorax", "tosxorax", "tosxorax", "tosxoreax", "tosxoreax",
0, "tosxora0", "tosxorax",
0, 0, "tosxoreax",
0, 0, "tosxoreax",
}; };
@@ -2912,11 +2863,8 @@ void g_xor (unsigned flags, unsigned long val)
void g_and (unsigned Flags, unsigned long Val) void g_and (unsigned Flags, unsigned long Val)
/* Primary = TOS & Primary */ /* Primary = TOS & Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, "tosanda0", "tosandax", "tosandax", "tosandax", "tosandeax", "tosandeax",
0, "tosanda0", "tosandax",
0, 0, "tosandeax",
0, 0, "tosandeax",
}; };
/* If the right hand side is const, the lhs is not on stack but still /* If the right hand side is const, the lhs is not on stack but still
@@ -3001,11 +2949,8 @@ void g_and (unsigned Flags, unsigned long Val)
void g_asr (unsigned flags, unsigned long val) void g_asr (unsigned flags, unsigned long val)
/* Primary = TOS >> Primary */ /* Primary = TOS >> Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, 0, "tosasrax", "tosasrax", "tosshrax", "tosasreax", "tosshreax",
0, 0, "tosshrax",
0, 0, "tosasreax",
0, 0, "tosshreax",
}; };
/* If the right hand side is const, the lhs is not on stack but still /* If the right hand side is const, the lhs is not on stack but still
@@ -3091,11 +3036,8 @@ void g_asr (unsigned flags, unsigned long val)
void g_asl (unsigned flags, unsigned long val) void g_asl (unsigned flags, unsigned long val)
/* Primary = TOS << Primary */ /* Primary = TOS << Primary */
{ {
static char* ops [12] = { static const char* ops[12] = {
0, 0, "tosaslax", "tosaslax", "tosshlax", "tosasleax", "tosshleax",
0, 0, "tosshlax",
0, 0, "tosasleax",
0, 0, "tosshleax",
}; };
@@ -3450,11 +3392,8 @@ void g_dec (unsigned flags, unsigned long val)
void g_eq (unsigned flags, unsigned long val) void g_eq (unsigned flags, unsigned long val)
/* Test for equal */ /* Test for equal */
{ {
static char* ops [12] = { static const char* ops[12] = {
"toseq00", "toseqa0", "toseqax", "toseqax", "toseqax", "toseqeax", "toseqeax",
"toseq00", "toseqa0", "toseqax",
0, 0, "toseqeax",
0, 0, "toseqeax",
}; };
unsigned L; unsigned L;
@@ -3507,11 +3446,8 @@ void g_eq (unsigned flags, unsigned long val)
void g_ne (unsigned flags, unsigned long val) void g_ne (unsigned flags, unsigned long val)
/* Test for not equal */ /* Test for not equal */
{ {
static char* ops [12] = { static const char* ops[12] = {
"tosne00", "tosnea0", "tosneax", "tosneax", "tosneax", "tosneeax", "tosneeax",
"tosne00", "tosnea0", "tosneax",
0, 0, "tosneeax",
0, 0, "tosneeax",
}; };
unsigned L; unsigned L;
@@ -3564,11 +3500,8 @@ void g_ne (unsigned flags, unsigned long val)
void g_lt (unsigned flags, unsigned long val) void g_lt (unsigned flags, unsigned long val)
/* Test for less than */ /* Test for less than */
{ {
static char* ops [12] = { static const char* ops[12] = {
"toslt00", "toslta0", "tosltax", "tosltax", "tosultax", "toslteax", "tosulteax",
"tosult00", "tosulta0", "tosultax",
0, 0, "toslteax",
0, 0, "tosulteax",
}; };
/* If the right hand side is const, the lhs is not on stack but still /* If the right hand side is const, the lhs is not on stack but still
@@ -3675,11 +3608,8 @@ void g_lt (unsigned flags, unsigned long val)
void g_le (unsigned flags, unsigned long val) void g_le (unsigned flags, unsigned long val)
/* Test for less than or equal to */ /* Test for less than or equal to */
{ {
static char* ops [12] = { static const char* ops[12] = {
"tosle00", "toslea0", "tosleax", "tosleax", "tosuleax", "tosleeax", "tosuleeax",
"tosule00", "tosulea0", "tosuleax",
0, 0, "tosleeax",
0, 0, "tosuleeax",
}; };
@@ -3793,11 +3723,8 @@ void g_le (unsigned flags, unsigned long val)
void g_gt (unsigned flags, unsigned long val) void g_gt (unsigned flags, unsigned long val)
/* Test for greater than */ /* Test for greater than */
{ {
static char* ops [12] = { static const char* ops[12] = {
"tosgt00", "tosgta0", "tosgtax", "tosgtax", "tosugtax", "tosgteax", "tosugteax",
"tosugt00", "tosugta0", "tosugtax",
0, 0, "tosgteax",
0, 0, "tosugteax",
}; };
@@ -3927,11 +3854,8 @@ void g_gt (unsigned flags, unsigned long val)
void g_ge (unsigned flags, unsigned long val) void g_ge (unsigned flags, unsigned long val)
/* Test for greater than or equal to */ /* Test for greater than or equal to */
{ {
static char* ops [12] = { static const char* ops[12] = {
"tosge00", "tosgea0", "tosgeax", "tosgeax", "tosugeax", "tosgeeax", "tosugeeax",
"tosuge00", "tosugea0", "tosugeax",
0, 0, "tosgeeax",
0, 0, "tosugeeax",
}; };

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2001-2006, Ullrich von Bassewitz */ /* (C) 2001-2009, Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -235,6 +235,7 @@ static const FuncInfo FuncInfoTable[] = {
{ "tosgtax", REG_AX, REG_AXY | REG_SREG }, { "tosgtax", REG_AX, REG_AXY | REG_SREG },
{ "tosgteax", REG_EAX, REG_AXY | REG_PTR1 }, { "tosgteax", REG_EAX, REG_AXY | REG_PTR1 },
{ "tosicmp", REG_AX, REG_AXY | REG_SREG }, { "tosicmp", REG_AX, REG_AXY | REG_SREG },
{ "tosicmp0", REG_A, REG_AXY | REG_SREG },
{ "toslcmp", REG_EAX, REG_A | REG_Y | REG_PTR1 }, { "toslcmp", REG_EAX, REG_A | REG_Y | REG_PTR1 },
{ "tosle00", REG_NONE, REG_AXY | REG_SREG }, { "tosle00", REG_NONE, REG_AXY | REG_SREG },
{ "toslea0", REG_A, REG_AXY | REG_SREG }, { "toslea0", REG_A, REG_AXY | REG_SREG },

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2002-2005, Ullrich von Bassewitz */ /* (C) 2002-2009, Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -106,6 +106,7 @@ static const CallDesc CallTable [] = {
{ "tosgeax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosgea0" }, { "tosgeax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosgea0" },
{ "tosgtax", 0, 0, UNKNOWN_REGVAL, F_NONE, "tosgt00" }, { "tosgtax", 0, 0, UNKNOWN_REGVAL, F_NONE, "tosgt00" },
{ "tosgtax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosgta0" }, { "tosgtax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosgta0" },
{ "tosicmp", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosicmp0" },
{ "tosleax", 0, 0, UNKNOWN_REGVAL, F_NONE, "tosle00" }, { "tosleax", 0, 0, UNKNOWN_REGVAL, F_NONE, "tosle00" },
{ "tosleax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "toslea0" }, { "tosleax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "toslea0" },
{ "tosltax", 0, 0, UNKNOWN_REGVAL, F_NONE, "toslt00" }, { "tosltax", 0, 0, UNKNOWN_REGVAL, F_NONE, "toslt00" },