From 4a667ead00c10797fb57298b3dd33c2efc6c8d3f Mon Sep 17 00:00:00 2001 From: cuz Date: Wed, 5 Nov 2003 19:09:53 +0000 Subject: [PATCH] Improved optimizations git-svn-id: svn://svn.cc65.org/cc65/trunk@2613 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codegen.c | 116 ++++++++++++++++++++++++-------------------- src/cc65/coptind.c | 37 ++++++++++++-- src/cc65/coptstop.c | 9 ++-- 3 files changed, 101 insertions(+), 61 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index c94ae2bfc..ef8405cc0 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2772,7 +2772,7 @@ void g_or (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - if ((val & 0xFF) != 0xFF) { + if ((val & 0xFF) != 0) { AddCodeLine ("ora #$%02X", (unsigned char)val); } return; @@ -2780,15 +2780,25 @@ void g_or (unsigned flags, unsigned long val) /* FALLTHROUGH */ case CF_INT: - if (val <= 0xFF) { - AddCodeLine ("ora #$%02X", (unsigned char)val); + if (val <= 0xFF) { + if ((val & 0xFF) != 0) { + AddCodeLine ("ora #$%02X", (unsigned char)val); + } return; - } + } else if ((val & 0xFF00) == 0xFF00) { + if ((val & 0xFF) != 0) { + AddCodeLine ("ora #$%02X", (unsigned char)val); + } + ldxconst (0xFF); + return; + } break; case CF_LONG: if (val <= 0xFF) { - AddCodeLine ("ora #$%02X", (unsigned char)val); + if ((val & 0xFF) != 0) { + AddCodeLine ("ora #$%02X", (unsigned char)val); + } return; } break; @@ -2881,68 +2891,70 @@ 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 */ { static char* ops [12] = { - 0, "tosanda0", "tosandax", - 0, "tosanda0", "tosandax", - 0, 0, "tosandeax", - 0, 0, "tosandeax", + 0, "tosanda0", "tosandax", + 0, "tosanda0", "tosandax", + 0, 0, "tosandeax", + 0, 0, "tosandeax", }; - + /* If the right hand side is const, the lhs is not on stack but still * in the primary register. */ - if (flags & CF_CONST) { + if (Flags & CF_CONST) { - switch (flags & CF_TYPE) { + switch (Flags & CF_TYPE) { case CF_CHAR: - if (flags & CF_FORCECHAR) { - AddCodeLine ("and #$%02X", (unsigned char)val); - return; - } - /* FALLTHROUGH */ + if (Flags & CF_FORCECHAR) { + if ((Val & 0xFF) != 0xFF) { + AddCodeLine ("and #$%02X", (unsigned char)Val); + } + return; + } + /* FALLTHROUGH */ case CF_INT: - if ((val & 0xFFFF) != 0xFFFF) { - if (val <= 0xFF) { - ldxconst (0); - if (val == 0) { - ldaconst (0); - } else if (val != 0xFF) { - AddCodeLine ("and #$%02X", (unsigned char)val); - } - } else if ((val & 0xFF00) == 0xFF00) { - AddCodeLine ("and #$%02X", (unsigned char)val); - } else if ((val & 0x00FF) == 0x0000) { - AddCodeLine ("txa"); - AddCodeLine ("and #$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("tax"); - ldaconst (0); + if ((Val & 0xFFFF) != 0xFFFF) { + if (Val <= 0xFF) { + ldxconst (0); + if (Val == 0) { + ldaconst (0); + } else if (Val != 0xFF) { + AddCodeLine ("and #$%02X", (unsigned char)Val); + } + } else if ((Val & 0xFF00) == 0xFF00) { + AddCodeLine ("and #$%02X", (unsigned char)Val); + } else if ((Val & 0x00FF) == 0x0000) { + AddCodeLine ("txa"); + AddCodeLine ("and #$%02X", (unsigned char)(Val >> 8)); + AddCodeLine ("tax"); + ldaconst (0); } else { - AddCodeLine ("tay"); - AddCodeLine ("txa"); - AddCodeLine ("and #$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("tax"); - AddCodeLine ("tya"); - if ((val & 0x00FF) != 0x00FF) { - AddCodeLine ("and #$%02X", (unsigned char)val); - } - } - } + AddCodeLine ("tay"); + AddCodeLine ("txa"); + AddCodeLine ("and #$%02X", (unsigned char)(Val >> 8)); + AddCodeLine ("tax"); + AddCodeLine ("tya"); + if ((Val & 0x00FF) != 0x00FF) { + AddCodeLine ("and #$%02X", (unsigned char)Val); + } + } + } return; case CF_LONG: - if (val <= 0xFF) { + if (Val <= 0xFF) { ldxconst (0); AddCodeLine ("stx sreg+1"); AddCodeLine ("stx sreg"); - if ((val & 0xFF) != 0xFF) { - AddCodeLine ("and #$%02X", (unsigned char)val); + if ((Val & 0xFF) != 0xFF) { + AddCodeLine ("and #$%02X", (unsigned char)Val); } return; - } else if (val == 0xFF00) { + } else if (Val == 0xFF00) { ldaconst (0); AddCodeLine ("sta sreg+1"); AddCodeLine ("sta sreg"); @@ -2951,19 +2963,19 @@ void g_and (unsigned flags, unsigned long val) break; default: - typeerror (flags); + typeerror (Flags); } /* If we go here, we didn't emit code. Push the lhs on stack and fall * into the normal, non-optimized stuff. Note: The standard stuff will * always work with ints. */ - flags &= ~CF_FORCECHAR; - g_push (flags & ~CF_CONST, 0); + Flags &= ~CF_FORCECHAR; + g_push (Flags & ~CF_CONST, 0); } - + /* Use long way over the stack */ - oper (flags, val, ops); + oper (Flags, Val, ops); } diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index aaddfeb85..6941a2c02 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -1315,6 +1315,9 @@ unsigned OptPrecalc (CodeSeg* S) /* Get a pointer to the output registers of the insn */ const RegContents* Out = &E->RI->Out; + /* Argument for LDA and flag */ + const char* Arg = 0; + /* Handle the different instructions */ switch (E->OPC) { @@ -1328,19 +1331,35 @@ unsigned OptPrecalc (CodeSeg* S) /* FALLTHROUGH */ case OP65_ADC: - case OP65_AND: case OP65_ASL: case OP65_EOR: case OP65_LSR: - case OP65_ORA: case OP65_SBC: if (RegValIsKnown (Out->RegA)) { /* Accu AND zp with known contents */ - const char* Arg = MakeHexArg (Out->RegA); - CodeEntry* X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - CS_InsertEntry (S, X, I+1); + Arg = MakeHexArg (Out->RegA); + } + break; + + case OP65_AND: + if (CE_KnownImm (E) && E->Num == 0xFF) { + /* AND with 0xFF, remove */ CS_DelEntry (S, I); ++Changes; + } else if (RegValIsKnown (Out->RegA)) { + /* Accu AND zp with known contents */ + Arg = MakeHexArg (Out->RegA); + } + break; + + case OP65_ORA: + if (CE_KnownImm (E) && E->Num == 0x00) { + /* ORA with zero, remove */ + CS_DelEntry (S, I); + ++Changes; + } else if (RegValIsKnown (Out->RegA)) { + /* Accu AND zp with known contents */ + Arg = MakeHexArg (Out->RegA); } break; @@ -1349,6 +1368,14 @@ unsigned OptPrecalc (CodeSeg* S) } + /* Check if we have to replace the insn by LDA */ + if (Arg) { + CodeEntry* X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + CS_InsertEntry (S, X, I+1); + CS_DelEntry (S, I); + ++Changes; + } + /* Next entry */ ++I; } diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index cd05efa1b..cdeab844d 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -287,7 +287,7 @@ static void AddOpLow (StackOpData* D, opc_t OPC) InsertEntry (D, X, D->IP++); } - + static void AddOpHigh (StackOpData* D, opc_t OPC) /* Add an op for the high byte of an operator. Special cases (constant values @@ -552,9 +552,10 @@ static unsigned Opt_tosorax (StackOpData* D) if (RegValIsKnown (D->PushEntry->RI->In.RegX) && RegValIsKnown (D->OpEntry->RI->In.RegX)) { /* Both values known, precalculate the result */ - const char* Arg = MakeHexArg (D->PushEntry->RI->In.RegX | D->OpEntry->RI->In.RegX); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); + unsigned char Result = D->PushEntry->RI->In.RegX | D->OpEntry->RI->In.RegX; + const char* Arg = MakeHexArg (Result); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); } else if (D->PushEntry->RI->In.RegX != 0) { /* High byte is unknown */ AddOpHigh (D, OP65_ORA); -- 2.39.5