1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-03 06:29:36 +00:00

Added more code to improve compares.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4066 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2009-08-28 19:34:35 +00:00
parent cd568ef898
commit a9f540fb27

View File

@ -667,8 +667,163 @@ static int IsRegVar (StackOpData* D)
static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer)
/* Optimize the toseqax and tosneax sequences. */
{
CodeEntry* X;
CodeLabel* L;
/* Create a call to the boolean transformer function and a label for this
* insn. This is needed for all variants. Other insns are inserted *before*
* the call.
*/
X = NewCodeEntry (OP65_JSR, AM65_ABS, BoolTransformer, 0, D->OpEntry->LI);
InsertEntry (D, X, D->OpIndex + 1);
L = CS_GenLabel (D->Code, X);
/* If the lhs is direct (but not stack relative), encode compares with lhs
* effectively reverting the order (which doesn't matter for ==).
*/
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;
D->IP = D->OpIndex+1;
/* cpx */
X = NewCodeEntry (OP65_CPX, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* bne L */
X = NewCodeEntry (OP65_BNE, AM65_BRA, L->Name, L, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* cmp */
X = NewCodeEntry (OP65_CMP, LoadA->AM, LoadA->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 if ((D->Rhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT &&
(D->Rhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT) {
CodeEntry* LoadX = D->Rhs.X.LoadEntry;
CodeEntry* LoadA = D->Rhs.A.LoadEntry;
D->IP = D->OpIndex+1;
/* cpx */
X = NewCodeEntry (OP65_CPX, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* bne L */
X = NewCodeEntry (OP65_BNE, AM65_BRA, L->Name, L, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* cmp */
X = NewCodeEntry (OP65_CMP, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* Rhs load entries can be removed */
D->Rhs.X.Flags |= LI_REMOVE;
D->Rhs.A.Flags |= LI_REMOVE;
} else if ((D->Rhs.A.Flags & LI_DIRECT) != 0 &&
(D->Rhs.X.Flags & LI_DIRECT) != 0) {
D->IP = D->OpIndex+1;
/* If the location is on the stack, we need to reload the Y register. */
if ((D->Rhs.A.Flags & LI_RELOAD_Y) == 0) {
/* cmp ... */
CodeEntry* LoadA = D->Rhs.A.LoadEntry;
X = NewCodeEntry (OP65_CMP, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
} else {
/* ldy #offs */
const char* Arg = MakeHexArg (D->Rhs.A.Offs);
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* cmp (sp),y */
X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
}
/* In both cases, we can remove the load */
D->Rhs.A.Flags |= LI_REMOVE;
/* bne L */
X = NewCodeEntry (OP65_BNE, AM65_BRA, L->Name, L, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* txa */
X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* If the location is on the stack, we need to reload the Y register. */
if ((D->Rhs.X.Flags & LI_RELOAD_Y) == 0) {
/* cmp ... */
CodeEntry* LoadX = D->Rhs.X.LoadEntry;
X = NewCodeEntry (OP65_CMP, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
} else {
/* ldy #offs */
const char* Arg = MakeHexArg (D->Rhs.X.Offs);
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* cmp (sp),y */
X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
}
/* In both cases, we can remove the load */
D->Rhs.X.Flags |= LI_REMOVE;
} else {
/* Save lhs into zeropage, then compare */
AddStoreX (D);
AddStoreA (D);
D->IP = D->OpIndex+1;
/* cpx */
X = NewCodeEntry (OP65_CPX, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* bne L */
X = NewCodeEntry (OP65_BNE, AM65_BRA, L->Name, L, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
/* cmp */
X = NewCodeEntry (OP65_CMP, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI);
InsertEntry (D, X, D->IP++);
}
/* Remove the push and the call to the tosgeax function */
RemoveRemainders (D);
/* We changed the sequence */
return 1;
}
static unsigned Opt___bzero (StackOpData* D)
/* Optimize the __bzero sequence if possible */
/* Optimize the __bzero sequence */
{
CodeEntry* X;
const char* Arg;
@ -762,7 +917,7 @@ static unsigned Opt___bzero (StackOpData* D)
static unsigned Opt_staspidx (StackOpData* D)
/* Optimize the staspidx sequence if possible */
/* Optimize the staspidx sequence */
{
CodeEntry* X;
@ -787,7 +942,7 @@ static unsigned Opt_staspidx (StackOpData* D)
static unsigned Opt_staxspidx (StackOpData* D)
/* Optimize the staxspidx sequence if possible */
/* Optimize the staxspidx sequence */
{
CodeEntry* X;
@ -843,7 +998,7 @@ static unsigned Opt_staxspidx (StackOpData* D)
static unsigned Opt_tosaddax (StackOpData* D)
/* Optimize the tosaddax sequence if possible */
/* Optimize the tosaddax sequence */
{
CodeEntry* X;
CodeEntry* N;
@ -967,7 +1122,7 @@ static unsigned Opt_tosaddax (StackOpData* D)
static unsigned Opt_tosandax (StackOpData* D)
/* Optimize the tosandax sequence if possible */
/* Optimize the tosandax sequence */
{
CodeEntry* X;
@ -997,8 +1152,16 @@ static unsigned Opt_tosandax (StackOpData* D)
static unsigned Opt_toseqax (StackOpData* D)
/* Optimize the toseqax sequence */
{
return Opt_toseqax_tosneax (D, "booleq");
}
static unsigned Opt_tosgeax (StackOpData* D)
/* Optimize the tosgeax sequence if possible. */
/* Optimize the tosgeax sequence */
{
CodeEntry* X;
CodeLabel* L;
@ -1098,7 +1261,7 @@ static unsigned Opt_tosgeax (StackOpData* D)
static unsigned Opt_tosltax (StackOpData* D)
/* Optimize the tosltax sequence if possible. */
/* Optimize the tosltax sequence */
{
CodeEntry* X;
CodeLabel* L;
@ -1198,8 +1361,16 @@ static unsigned Opt_tosltax (StackOpData* D)
static unsigned Opt_tosneax (StackOpData* D)
/* Optimize the tosneax sequence */
{
return Opt_toseqax_tosneax (D, "boolne");
}
static unsigned Opt_tosorax (StackOpData* D)
/* Optimize the tosorax sequence if possible */
/* Optimize the tosorax sequence */
{
CodeEntry* X;
@ -1233,9 +1404,7 @@ static unsigned Opt_tosorax (StackOpData* D)
static unsigned Opt_tossubax (StackOpData* D)
/* Optimize the tossubax sequence if possible. Note: subtraction is not
* commutative!
*/
/* Optimize the tossubax sequence. Note: subtraction is not commutative! */
{
CodeEntry* X;
@ -1325,7 +1494,7 @@ static unsigned Opt_tossubax (StackOpData* D)
static unsigned Opt_tosugeax (StackOpData* D)
/* Optimize the tosugeax sequence if possible. */
/* Optimize the tosugeax sequence */
{
CodeEntry* X;
@ -1411,7 +1580,7 @@ static unsigned Opt_tosugeax (StackOpData* D)
static unsigned Opt_tosxorax (StackOpData* D)
/* Optimize the tosxorax sequence if possible */
/* Optimize the tosxorax sequence */
{
CodeEntry* X;
@ -1456,8 +1625,10 @@ static const OptFuncDesc FuncTable[] = {
{ "staxspidx", Opt_staxspidx, REG_AX, OP_NONE },
{ "tosaddax", Opt_tosaddax, REG_NONE, OP_NONE },
{ "tosandax", Opt_tosandax, REG_NONE, OP_NONE },
{ "toseqax", Opt_toseqax, REG_NONE, OP_NONE },
{ "tosgeax", Opt_tosgeax, REG_NONE, OP_RHS_LOAD_DIRECT },
{ "tosltax", Opt_tosltax, REG_NONE, OP_RHS_LOAD_DIRECT },
{ "tosneax", Opt_tosneax, REG_NONE, OP_NONE },
{ "tosorax", Opt_tosorax, REG_NONE, OP_NONE },
{ "tossubax", Opt_tossubax, REG_NONE, OP_RHS_LOAD_DIRECT },
{ "tosugeax", Opt_tosugeax, REG_NONE, OP_RHS_LOAD_DIRECT },