More source splitting.
Remove the -Wno-unused-parameter in favour of __atribute__((unused)). git-svn-id: svn://svn.cc65.org/cc65/trunk@986 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -190,7 +190,7 @@ static void ParseWordArg (StrBuf* T, unsigned Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ParseLongArg (StrBuf* T, unsigned Arg)
|
static void ParseLongArg (StrBuf* T, unsigned Arg attribute ((unused)))
|
||||||
/* Parse the %l format specifier */
|
/* Parse the %l format specifier */
|
||||||
{
|
{
|
||||||
ExprDesc Expr;
|
ExprDesc Expr;
|
||||||
|
|||||||
@@ -752,23 +752,15 @@ void g_getlocal (unsigned flags, int offs)
|
|||||||
AddCodeLine ("dey");
|
AddCodeLine ("dey");
|
||||||
AddCodeLine ("lda (sp),y");
|
AddCodeLine ("lda (sp),y");
|
||||||
} else {
|
} else {
|
||||||
if (offs) {
|
ldyconst (offs+1);
|
||||||
ldyconst (offs+1);
|
AddCodeLine ("jsr ldaxysp");
|
||||||
AddCodeLine ("jsr ldaxysp");
|
|
||||||
} else {
|
|
||||||
AddCodeLine ("jsr ldax0sp");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CF_LONG:
|
case CF_LONG:
|
||||||
if (offs) {
|
ldyconst (offs+3);
|
||||||
ldyconst (offs+3);
|
AddCodeLine ("jsr ldeaxysp");
|
||||||
AddCodeLine ("jsr ldeaxysp");
|
|
||||||
} else {
|
|
||||||
AddCodeLine ("jsr ldeax0sp");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -812,22 +804,14 @@ void g_getind (unsigned flags, unsigned offs)
|
|||||||
AddCodeLine ("iny");
|
AddCodeLine ("iny");
|
||||||
AddCodeLine ("ora (ptr1),y");
|
AddCodeLine ("ora (ptr1),y");
|
||||||
} else {
|
} else {
|
||||||
if (offs == 0) {
|
ldyconst (offs+1);
|
||||||
AddCodeLine ("jsr ldaxi");
|
AddCodeLine ("jsr ldaxidx");
|
||||||
} else {
|
|
||||||
ldyconst (offs+1);
|
|
||||||
AddCodeLine ("jsr ldaxidx");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CF_LONG:
|
case CF_LONG:
|
||||||
if (offs == 0) {
|
ldyconst (offs+3);
|
||||||
AddCodeLine ("jsr ldeaxi");
|
AddCodeLine ("jsr ldeaxidx");
|
||||||
} else {
|
|
||||||
ldyconst (offs+3);
|
|
||||||
AddCodeLine ("jsr ldeaxidx");
|
|
||||||
}
|
|
||||||
if (flags & CF_TEST) {
|
if (flags & CF_TEST) {
|
||||||
AddCodeLine ("jsr tsteax");
|
AddCodeLine ("jsr tsteax");
|
||||||
}
|
}
|
||||||
@@ -1034,12 +1018,8 @@ void g_putlocal (unsigned Flags, int Offs, long Val)
|
|||||||
if (Flags & CF_CONST) {
|
if (Flags & CF_CONST) {
|
||||||
g_getimmed (Flags, Val, 0);
|
g_getimmed (Flags, Val, 0);
|
||||||
}
|
}
|
||||||
if (Offs) {
|
ldyconst (Offs);
|
||||||
ldyconst (Offs);
|
AddCodeLine ("jsr steaxysp");
|
||||||
AddCodeLine ("jsr steaxysp");
|
|
||||||
} else {
|
|
||||||
AddCodeLine ("jsr steax0sp");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1527,28 +1507,6 @@ void g_addstatic (unsigned flags, unsigned long label, unsigned offs)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Compares of ax with a variable with fixed address */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void g_cmplocal (unsigned flags, int offs)
|
|
||||||
/* Compare a local variable to ax */
|
|
||||||
{
|
|
||||||
Internal ("g_cmplocal not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void g_cmpstatic (unsigned flags, unsigned label, unsigned offs)
|
|
||||||
/* Compare a static variable to ax */
|
|
||||||
{
|
|
||||||
Internal ("g_cmpstatic not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Special op= functions */
|
/* Special op= functions */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -1728,12 +1686,8 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val)
|
|||||||
if (flags & CF_CONST) {
|
if (flags & CF_CONST) {
|
||||||
g_getimmed (flags, val, 0);
|
g_getimmed (flags, val, 0);
|
||||||
}
|
}
|
||||||
if (offs == 0) {
|
ldyconst (offs);
|
||||||
AddCodeLine ("jsr laddeq0sp");
|
AddCodeLine ("jsr laddeqysp");
|
||||||
} else {
|
|
||||||
ldyconst (offs);
|
|
||||||
AddCodeLine ("jsr laddeqysp");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1881,12 +1835,8 @@ void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs,
|
|||||||
AddCodeLine ("ldy #<(%s)", lbuf);
|
AddCodeLine ("ldy #<(%s)", lbuf);
|
||||||
AddCodeLine ("sty ptr1");
|
AddCodeLine ("sty ptr1");
|
||||||
AddCodeLine ("ldy #>(%s+1)", lbuf);
|
AddCodeLine ("ldy #>(%s+1)", lbuf);
|
||||||
if (val == 1) {
|
AddCodeLine ("lda #$%02X", (unsigned char)val);
|
||||||
AddCodeLine ("jsr lsubeq1");
|
AddCodeLine ("jsr lsubeqa");
|
||||||
} else {
|
|
||||||
AddCodeLine ("lda #$%02X", (unsigned char)val);
|
|
||||||
AddCodeLine ("jsr lsubeqa");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
g_getstatic (flags, label, offs);
|
g_getstatic (flags, label, offs);
|
||||||
g_dec (flags, val);
|
g_dec (flags, val);
|
||||||
@@ -1945,24 +1895,16 @@ void g_subeqlocal (unsigned flags, int offs, unsigned long val)
|
|||||||
if (flags & CF_CONST) {
|
if (flags & CF_CONST) {
|
||||||
g_getimmed (flags, val, 0);
|
g_getimmed (flags, val, 0);
|
||||||
}
|
}
|
||||||
if (offs == 0) {
|
ldyconst (offs);
|
||||||
AddCodeLine ("jsr subeq0sp");
|
AddCodeLine ("jsr subeqysp");
|
||||||
} else {
|
|
||||||
ldyconst (offs);
|
|
||||||
AddCodeLine ("jsr subeqysp");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CF_LONG:
|
case CF_LONG:
|
||||||
if (flags & CF_CONST) {
|
if (flags & CF_CONST) {
|
||||||
g_getimmed (flags, val, 0);
|
g_getimmed (flags, val, 0);
|
||||||
}
|
}
|
||||||
if (offs == 0) {
|
ldyconst (offs);
|
||||||
AddCodeLine ("jsr lsubeq0sp");
|
AddCodeLine ("jsr lsubeqysp");
|
||||||
} else {
|
|
||||||
ldyconst (offs);
|
|
||||||
AddCodeLine ("jsr lsubeqysp");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -2037,7 +1979,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void g_addaddr_local (unsigned flags, int offs)
|
void g_addaddr_local (unsigned flags attribute ((unused)), int offs)
|
||||||
/* Add the address of a local variable to ax */
|
/* Add the address of a local variable to ax */
|
||||||
{
|
{
|
||||||
unsigned L = 0;
|
unsigned L = 0;
|
||||||
@@ -2281,36 +2223,20 @@ void g_test (unsigned flags)
|
|||||||
void g_push (unsigned flags, unsigned long val)
|
void g_push (unsigned flags, unsigned long val)
|
||||||
/* Push the primary register or a constant value onto the stack */
|
/* Push the primary register or a constant value onto the stack */
|
||||||
{
|
{
|
||||||
unsigned char hi;
|
|
||||||
|
|
||||||
if (flags & CF_CONST && (flags & CF_TYPE) != CF_LONG) {
|
if (flags & CF_CONST && (flags & CF_TYPE) != CF_LONG) {
|
||||||
|
|
||||||
/* We have a constant 8 or 16 bit value */
|
/* We have a constant 8 or 16 bit value */
|
||||||
if ((flags & CF_TYPE) == CF_CHAR && (flags & CF_FORCECHAR)) {
|
if ((flags & CF_TYPE) == CF_CHAR && (flags & CF_FORCECHAR)) {
|
||||||
|
|
||||||
/* Handle as 8 bit value */
|
/* Handle as 8 bit value */
|
||||||
if (CodeSizeFactor >= 165 || val > 2) {
|
ldaconst (val);
|
||||||
ldaconst (val);
|
AddCodeLine ("jsr pusha");
|
||||||
AddCodeLine ("jsr pusha");
|
|
||||||
} else {
|
|
||||||
AddCodeLine ("jsr pushc%d", (int) val);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Handle as 16 bit value */
|
/* Handle as 16 bit value */
|
||||||
hi = (unsigned char) (val >> 8);
|
g_getimmed (flags, val, 0);
|
||||||
if (val <= 7) {
|
AddCodeLine ("jsr pushax");
|
||||||
AddCodeLine ("jsr push%u", (unsigned) val);
|
|
||||||
} else if (hi == 0 || hi == 0xFF) {
|
|
||||||
/* Use special function */
|
|
||||||
ldaconst (val);
|
|
||||||
AddCodeLine ("jsr %s", (hi == 0)? "pusha0" : "pushaFF");
|
|
||||||
} else {
|
|
||||||
/* Long way ... */
|
|
||||||
g_getimmed (flags, val, 0);
|
|
||||||
AddCodeLine ("jsr pushax");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -2475,7 +2401,7 @@ void g_case (unsigned flags, unsigned label, unsigned long val)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void g_truejump (unsigned flags, unsigned label)
|
void g_truejump (unsigned flags attribute ((unused)), unsigned label)
|
||||||
/* Jump to label if zero flag clear */
|
/* Jump to label if zero flag clear */
|
||||||
{
|
{
|
||||||
AddCodeLine ("jne %s", LocalLabelName (label));
|
AddCodeLine ("jne %s", LocalLabelName (label));
|
||||||
@@ -2483,7 +2409,7 @@ void g_truejump (unsigned flags, unsigned label)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void g_falsejump (unsigned flags, unsigned label)
|
void g_falsejump (unsigned flags attribute ((unused)), unsigned label)
|
||||||
/* Jump to label if zero flag set */
|
/* Jump to label if zero flag set */
|
||||||
{
|
{
|
||||||
AddCodeLine ("jeq %s", LocalLabelName (label));
|
AddCodeLine ("jeq %s", LocalLabelName (label));
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#include "coptadd.h"
|
#include "coptadd.h"
|
||||||
#include "coptcmp.h"
|
#include "coptcmp.h"
|
||||||
#include "coptind.h"
|
#include "coptind.h"
|
||||||
|
#include "coptneg.h"
|
||||||
#include "coptstop.h"
|
#include "coptstop.h"
|
||||||
#include "coptsub.h"
|
#include "coptsub.h"
|
||||||
#include "copttest.h"
|
#include "copttest.h"
|
||||||
@@ -114,383 +115,6 @@ static unsigned OptShift1 (CodeSeg* S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* nega optimizations */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned OptNegA1 (CodeSeg* S)
|
|
||||||
/* Check for
|
|
||||||
*
|
|
||||||
* ldx #$00
|
|
||||||
* lda ..
|
|
||||||
* jsr bnega
|
|
||||||
*
|
|
||||||
* Remove the ldx if the lda does not use it.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
unsigned Changes = 0;
|
|
||||||
|
|
||||||
/* Walk over the entries */
|
|
||||||
unsigned I = 0;
|
|
||||||
while (I < CS_GetEntryCount (S)) {
|
|
||||||
|
|
||||||
CodeEntry* L[2];
|
|
||||||
|
|
||||||
/* Get next entry */
|
|
||||||
CodeEntry* E = CS_GetEntry (S, I);
|
|
||||||
|
|
||||||
/* Check for a ldx */
|
|
||||||
if (E->OPC == OP65_LDX &&
|
|
||||||
E->AM == AM65_IMM &&
|
|
||||||
(E->Flags & CEF_NUMARG) != 0 &&
|
|
||||||
E->Num == 0 &&
|
|
||||||
CS_GetEntries (S, L, I+1, 2) &&
|
|
||||||
L[0]->OPC == OP65_LDA &&
|
|
||||||
(L[0]->Use & REG_X) == 0 &&
|
|
||||||
!CE_HasLabel (L[0]) &&
|
|
||||||
CE_IsCall (L[1], "bnega") &&
|
|
||||||
!CE_HasLabel (L[1])) {
|
|
||||||
|
|
||||||
/* Remove the ldx instruction */
|
|
||||||
CS_DelEntry (S, I);
|
|
||||||
|
|
||||||
/* Remember, we had changes */
|
|
||||||
++Changes;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next entry */
|
|
||||||
++I;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the number of changes made */
|
|
||||||
return Changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned OptNegA2 (CodeSeg* S)
|
|
||||||
/* Check for
|
|
||||||
*
|
|
||||||
* lda ..
|
|
||||||
* jsr bnega
|
|
||||||
* jeq/jne ..
|
|
||||||
*
|
|
||||||
* Adjust the conditional branch and remove the call to the subroutine.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
unsigned Changes = 0;
|
|
||||||
|
|
||||||
/* Walk over the entries */
|
|
||||||
unsigned I = 0;
|
|
||||||
while (I < CS_GetEntryCount (S)) {
|
|
||||||
|
|
||||||
CodeEntry* L[2];
|
|
||||||
|
|
||||||
/* Get next entry */
|
|
||||||
CodeEntry* E = CS_GetEntry (S, I);
|
|
||||||
|
|
||||||
/* Check for the sequence */
|
|
||||||
if ((E->OPC == OP65_ADC ||
|
|
||||||
E->OPC == OP65_AND ||
|
|
||||||
E->OPC == OP65_DEA ||
|
|
||||||
E->OPC == OP65_EOR ||
|
|
||||||
E->OPC == OP65_INA ||
|
|
||||||
E->OPC == OP65_LDA ||
|
|
||||||
E->OPC == OP65_ORA ||
|
|
||||||
E->OPC == OP65_PLA ||
|
|
||||||
E->OPC == OP65_SBC ||
|
|
||||||
E->OPC == OP65_TXA ||
|
|
||||||
E->OPC == OP65_TYA) &&
|
|
||||||
CS_GetEntries (S, L, I+1, 2) &&
|
|
||||||
CE_IsCall (L[0], "bnega") &&
|
|
||||||
!CE_HasLabel (L[0]) &&
|
|
||||||
(L[1]->Info & OF_ZBRA) != 0 &&
|
|
||||||
!CE_HasLabel (L[1])) {
|
|
||||||
|
|
||||||
/* Invert the branch */
|
|
||||||
CE_ReplaceOPC (L[1], GetInverseBranch (L[1]->OPC));
|
|
||||||
|
|
||||||
/* Delete the subroutine call */
|
|
||||||
CS_DelEntry (S, I+1);
|
|
||||||
|
|
||||||
/* Remember, we had changes */
|
|
||||||
++Changes;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next entry */
|
|
||||||
++I;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the number of changes made */
|
|
||||||
return Changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* negax optimizations */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned OptNegAX1 (CodeSeg* S)
|
|
||||||
/* On a call to bnegax, if X is zero, the result depends only on the value in
|
|
||||||
* A, so change the call to a call to bnega. This will get further optimized
|
|
||||||
* later if possible.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
unsigned Changes = 0;
|
|
||||||
unsigned I;
|
|
||||||
|
|
||||||
/* Generate register info for this step */
|
|
||||||
CS_GenRegInfo (S);
|
|
||||||
|
|
||||||
/* Walk over the entries */
|
|
||||||
I = 0;
|
|
||||||
while (I < CS_GetEntryCount (S)) {
|
|
||||||
|
|
||||||
/* Get next entry */
|
|
||||||
CodeEntry* E = CS_GetEntry (S, I);
|
|
||||||
|
|
||||||
/* Check if this is a call to bnegax, and if X is known and zero */
|
|
||||||
if (E->RI->In.RegX == 0 &&
|
|
||||||
CE_IsCall (E, "bnegax")) {
|
|
||||||
|
|
||||||
/* We're cheating somewhat here ... */
|
|
||||||
E->Arg[5] = '\0';
|
|
||||||
E->Use &= ~REG_X;
|
|
||||||
|
|
||||||
/* We had changes */
|
|
||||||
++Changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next entry */
|
|
||||||
++I;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free register info */
|
|
||||||
CS_FreeRegInfo (S);
|
|
||||||
|
|
||||||
/* Return the number of changes made */
|
|
||||||
return Changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned OptNegAX2 (CodeSeg* S)
|
|
||||||
/* Search for the sequence:
|
|
||||||
*
|
|
||||||
* lda (xx),y
|
|
||||||
* tax
|
|
||||||
* dey
|
|
||||||
* lda (xx),y
|
|
||||||
* jsr bnegax
|
|
||||||
* jne/jeq ...
|
|
||||||
*
|
|
||||||
* and replace it by
|
|
||||||
*
|
|
||||||
* lda (xx),y
|
|
||||||
* dey
|
|
||||||
* ora (xx),y
|
|
||||||
* jeq/jne ...
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
unsigned Changes = 0;
|
|
||||||
|
|
||||||
/* Walk over the entries */
|
|
||||||
unsigned I = 0;
|
|
||||||
while (I < CS_GetEntryCount (S)) {
|
|
||||||
|
|
||||||
CodeEntry* L[5];
|
|
||||||
|
|
||||||
/* Get next entry */
|
|
||||||
CodeEntry* E = CS_GetEntry (S, I);
|
|
||||||
|
|
||||||
/* Check for the sequence */
|
|
||||||
if (E->OPC == OP65_LDA &&
|
|
||||||
E->AM == AM65_ZP_INDY &&
|
|
||||||
CS_GetEntries (S, L, I+1, 5) &&
|
|
||||||
L[0]->OPC == OP65_TAX &&
|
|
||||||
L[1]->OPC == OP65_DEY &&
|
|
||||||
L[2]->OPC == OP65_LDA &&
|
|
||||||
L[2]->AM == AM65_ZP_INDY &&
|
|
||||||
strcmp (L[2]->Arg, E->Arg) == 0 &&
|
|
||||||
!CE_HasLabel (L[2]) &&
|
|
||||||
CE_IsCall (L[3], "bnegax") &&
|
|
||||||
!CE_HasLabel (L[3]) &&
|
|
||||||
(L[4]->Info & OF_ZBRA) != 0 &&
|
|
||||||
!CE_HasLabel (L[4])) {
|
|
||||||
|
|
||||||
/* lda --> ora */
|
|
||||||
CE_ReplaceOPC (L[2], OP65_ORA);
|
|
||||||
|
|
||||||
/* Invert the branch */
|
|
||||||
CE_ReplaceOPC (L[4], GetInverseBranch (L[4]->OPC));
|
|
||||||
|
|
||||||
/* Delete the entries no longer needed. Beware: Deleting entries
|
|
||||||
* will change the indices.
|
|
||||||
*/
|
|
||||||
CS_DelEntry (S, I+4); /* jsr bnegax */
|
|
||||||
CS_DelEntry (S, I+1); /* tax */
|
|
||||||
|
|
||||||
/* Remember, we had changes */
|
|
||||||
++Changes;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next entry */
|
|
||||||
++I;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the number of changes made */
|
|
||||||
return Changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned OptNegAX3 (CodeSeg* S)
|
|
||||||
/* Search for the sequence:
|
|
||||||
*
|
|
||||||
* lda xx
|
|
||||||
* ldx yy
|
|
||||||
* jsr bnegax
|
|
||||||
* jne/jeq ...
|
|
||||||
*
|
|
||||||
* and replace it by
|
|
||||||
*
|
|
||||||
* lda xx
|
|
||||||
* ora xx+1
|
|
||||||
* jeq/jne ...
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
unsigned Changes = 0;
|
|
||||||
|
|
||||||
/* Walk over the entries */
|
|
||||||
unsigned I = 0;
|
|
||||||
while (I < CS_GetEntryCount (S)) {
|
|
||||||
|
|
||||||
CodeEntry* L[3];
|
|
||||||
|
|
||||||
/* Get next entry */
|
|
||||||
CodeEntry* E = CS_GetEntry (S, I);
|
|
||||||
|
|
||||||
/* Check for the sequence */
|
|
||||||
if (E->OPC == OP65_LDA &&
|
|
||||||
CS_GetEntries (S, L, I+1, 3) &&
|
|
||||||
L[0]->OPC == OP65_LDX &&
|
|
||||||
!CE_HasLabel (L[0]) &&
|
|
||||||
CE_IsCall (L[1], "bnegax") &&
|
|
||||||
!CE_HasLabel (L[1]) &&
|
|
||||||
(L[2]->Info & OF_ZBRA) != 0 &&
|
|
||||||
!CE_HasLabel (L[2])) {
|
|
||||||
|
|
||||||
/* ldx --> ora */
|
|
||||||
CE_ReplaceOPC (L[0], OP65_ORA);
|
|
||||||
|
|
||||||
/* Invert the branch */
|
|
||||||
CE_ReplaceOPC (L[2], GetInverseBranch (L[2]->OPC));
|
|
||||||
|
|
||||||
/* Delete the subroutine call */
|
|
||||||
CS_DelEntry (S, I+2);
|
|
||||||
|
|
||||||
/* Remember, we had changes */
|
|
||||||
++Changes;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next entry */
|
|
||||||
++I;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the number of changes made */
|
|
||||||
return Changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned OptNegAX4 (CodeSeg* S)
|
|
||||||
/* Search for the sequence:
|
|
||||||
*
|
|
||||||
* jsr xxx
|
|
||||||
* jsr bnega(x)
|
|
||||||
* jeq/jne ...
|
|
||||||
*
|
|
||||||
* and replace it by:
|
|
||||||
*
|
|
||||||
* jsr xxx
|
|
||||||
* <boolean test>
|
|
||||||
* jne/jeq ...
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
unsigned Changes = 0;
|
|
||||||
|
|
||||||
/* Walk over the entries */
|
|
||||||
unsigned I = 0;
|
|
||||||
while (I < CS_GetEntryCount (S)) {
|
|
||||||
|
|
||||||
CodeEntry* L[2];
|
|
||||||
|
|
||||||
/* Get next entry */
|
|
||||||
CodeEntry* E = CS_GetEntry (S, I);
|
|
||||||
|
|
||||||
/* Check for the sequence */
|
|
||||||
if (E->OPC == OP65_JSR &&
|
|
||||||
CS_GetEntries (S, L, I+1, 2) &&
|
|
||||||
L[0]->OPC == OP65_JSR &&
|
|
||||||
strncmp (L[0]->Arg,"bnega",5) == 0 &&
|
|
||||||
!CE_HasLabel (L[0]) &&
|
|
||||||
(L[1]->Info & OF_ZBRA) != 0 &&
|
|
||||||
!CE_HasLabel (L[1])) {
|
|
||||||
|
|
||||||
CodeEntry* X;
|
|
||||||
|
|
||||||
/* Check if we're calling bnega or bnegax */
|
|
||||||
int ByteSized = (strcmp (L[0]->Arg, "bnega") == 0);
|
|
||||||
|
|
||||||
/* Insert apropriate test code */
|
|
||||||
if (ByteSized) {
|
|
||||||
/* Test bytes */
|
|
||||||
X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[0]->LI);
|
|
||||||
CS_InsertEntry (S, X, I+2);
|
|
||||||
} else {
|
|
||||||
/* Test words */
|
|
||||||
X = NewCodeEntry (OP65_STX, AM65_ZP, "tmp1", 0, L[0]->LI);
|
|
||||||
CS_InsertEntry (S, X, I+2);
|
|
||||||
X = NewCodeEntry (OP65_ORA, AM65_ZP, "tmp1", 0, L[0]->LI);
|
|
||||||
CS_InsertEntry (S, X, I+3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete the subroutine call */
|
|
||||||
CS_DelEntry (S, I+1);
|
|
||||||
|
|
||||||
/* Invert the branch */
|
|
||||||
CE_ReplaceOPC (L[1], GetInverseBranch (L[1]->OPC));
|
|
||||||
|
|
||||||
/* Remember, we had changes */
|
|
||||||
++Changes;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next entry */
|
|
||||||
++I;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the number of changes made */
|
|
||||||
return Changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Optimize stores through pointers */
|
/* Optimize stores through pointers */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -1403,7 +1027,118 @@ static unsigned OptDecouple (CodeSeg* S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned OptSize (CodeSeg* S)
|
static unsigned OptSize1 (CodeSeg* S)
|
||||||
|
/* Do size optimization by calling special subroutines that preload registers.
|
||||||
|
* This routine does not work standalone, it needs a following register load
|
||||||
|
* removal pass.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
static const char* Func = {
|
||||||
|
"stax0sp", /* staxysp, y = 0 */
|
||||||
|
"addeq0sp",
|
||||||
|
"ldax0sp", /* ldaxysp, y = 1 */
|
||||||
|
"ldeax0sp", /* ldeaxysp, y = 3 */
|
||||||
|
"push0", /* pushax, a = 0, x = 0 */
|
||||||
|
"pusha0", /* pushax, x = 0 */
|
||||||
|
"pushaFF", /* pushax, x = ff */
|
||||||
|
"pusha0sp", /* pushaysp, y = 0 */
|
||||||
|
"tosadda0", /* tosaddax, x = 0 */
|
||||||
|
"tosanda0", /* tosandax, x = 0 */
|
||||||
|
"tosdiva0", /* tosdivax, x = 0 */
|
||||||
|
"toseqa0", /* toseqax, x = 0 */
|
||||||
|
"tosgea0", /* tosgeax, x = 0 */
|
||||||
|
"tosgta0", /* tosgtax, x = 0 */
|
||||||
|
"tosadd0ax", /* tosaddeax, sreg = 0 */
|
||||||
|
"laddeqa", /* laddeq, sreg = 0, x = 0 */
|
||||||
|
"laddeq1", /* laddeq, sreg = 0, x = 0, a = 1 */
|
||||||
|
"laddeq0sp", /* laddeqysp, y = 0 */
|
||||||
|
"tosand0ax", /* tosandeax, sreg = 0 */
|
||||||
|
"ldaxi", /* ldaxidx, y = 1 */
|
||||||
|
"ldeaxi", /* ldeaxidx, y = 3 */
|
||||||
|
"ldeax0sp", /* ldeaxysp, y = 3 */
|
||||||
|
"tosdiv0ax", /* tosdiveax, sreg = 0 */
|
||||||
|
"toslea0", /* tosleax, x = 0 */
|
||||||
|
"tosmod0ax", /* tosmodeax, sreg = 0 */
|
||||||
|
"tosmul0ax", /* tosmuleax, sreg = 0 */
|
||||||
|
"tosumul0ax", /* tosumuleax, sreg = 0 */
|
||||||
|
"tosor0ax", /* tosoreax, sreg = 0 */
|
||||||
|
"push0ax", /* pusheax, sreg = 0 */
|
||||||
|
"tosrsub0ax", /* tosrsubeax, sreg = 0 */
|
||||||
|
"tosshl0ax", /* tosshleax, sreg = 0 */
|
||||||
|
"tosasl0ax", /* tosasleax, sreg = 0 */
|
||||||
|
"tosshr0ax", /* tosshreax, sreg = 0 */
|
||||||
|
"tosasr0ax", /* tosasreax, sreg = 0 */
|
||||||
|
"tossub0ax", /* tossubeax, sreg = 0 */
|
||||||
|
"lsubeqa", /* lsubeq, sreg = 0, x = 0 */
|
||||||
|
"lsubeq1", /* lsubeq, sreg = 0, x = 0, a = 1 */
|
||||||
|
"lsubeq0sp", /* lsubeqysp, y = 0 */
|
||||||
|
"toslta0", /* tosltax, x = 0 */
|
||||||
|
"tosudiv0ax", /* tosudiveax, sreg = 0 */
|
||||||
|
"tosumod0ax", /* tosumodeax, sreg = 0 */
|
||||||
|
"tosxor0ax", /* tosxoreax, sreg = 0 */
|
||||||
|
"tosmoda0", /* tosmodax, x = 0 */
|
||||||
|
"tosmula0", /* tosmulax, x = 0 */
|
||||||
|
"tosumula0", /* tosumulax, x = 0 */
|
||||||
|
"tosnea0", /* tosneax, x = 0 */
|
||||||
|
"tosora0", /* tosorax, x = 0 */
|
||||||
|
"push1", /* pushax, x = 0, a = 1 */
|
||||||
|
"push2", /* pushax, x = 0, a = 2 */
|
||||||
|
"push3", /* pushax, x = 0, a = 3 */
|
||||||
|
"push4", /* pushax, x = 0, a = 4 */
|
||||||
|
"push5", /* pushax, x = 0, a = 5 */
|
||||||
|
"push6", /* pushax, x = 0, a = 6 */
|
||||||
|
"push7", /* pushax, x = 0, a = 7 */
|
||||||
|
"pushc0", /* pusha, a = 0 */
|
||||||
|
"pushc1", /* pusha, a = 1 */
|
||||||
|
"pushc2", /* pusha, a = 2 */
|
||||||
|
"tosrsuba0", /* tosrsubax, x = 0 */
|
||||||
|
"tosshla0", /* tosshlax, x = 0 */
|
||||||
|
"tosasla0", /* tosaslax, x = 0 */
|
||||||
|
"tosshra0", /* tosshrax, x = 0 */
|
||||||
|
"tosasra0", /* tosasrax, x = 0 */
|
||||||
|
"steax0sp", /* steaxsp, y = 0 */
|
||||||
|
"tossuba0", /* tossubax, x = 0 */
|
||||||
|
"subeq0sp", /* subeqysp, y = 0 */
|
||||||
|
"tosudiva0", /* tosudivax, x = 0 */
|
||||||
|
"tosugea0", /* tosugeax, x = 0 */
|
||||||
|
"tosugta0", /* tosugtax, x = 0 */
|
||||||
|
"tosulea0", /* tosuleax, x = 0 */
|
||||||
|
"tosulta0", /* tosultax, x = 0 */
|
||||||
|
"tosumoda0", /* tosumodax, x = 0 */
|
||||||
|
"tosxora0", /* tosxorax, x = 0 */
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned Changes = 0;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
/* Generate register info for the following step */
|
||||||
|
CS_GenRegInfo (S);
|
||||||
|
|
||||||
|
/* Walk over the entries */
|
||||||
|
I = 0;
|
||||||
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
|
/* Get next entry */
|
||||||
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
|
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free register info */
|
||||||
|
CS_FreeRegInfo (S);
|
||||||
|
|
||||||
|
/* Return the number of changes made */
|
||||||
|
return Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned OptSize2 (CodeSeg* S)
|
||||||
/* Do size optimization by using shorter code sequences, even if this
|
/* Do size optimization by using shorter code sequences, even if this
|
||||||
* introduces relations between instructions. This step must be one of the
|
* introduces relations between instructions. This step must be one of the
|
||||||
* last steps, because it makes further work much more difficult.
|
* last steps, because it makes further work much more difficult.
|
||||||
@@ -1443,7 +1178,7 @@ static unsigned OptSize (CodeSeg* S)
|
|||||||
X = NewCodeEntry (OP65_INA, AM65_IMP, 0, 0, E->LI);
|
X = NewCodeEntry (OP65_INA, AM65_IMP, 0, 0, E->LI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP65_LDX:
|
case OP65_LDX:
|
||||||
@@ -1564,7 +1299,8 @@ static OptFunc DOptPtrLoad6 = { OptPtrLoad6, "OptPtrLoad6", 0, 0, 0, 0
|
|||||||
static OptFunc DOptPtrStore1 = { OptPtrStore1, "OptPtrStore1", 0, 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 DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptShift1 = { OptShift1, "OptShift1", 0, 0, 0, 0, 0 };
|
static OptFunc DOptShift1 = { OptShift1, "OptShift1", 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptSize = { OptSize, "OptSize", 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 };
|
static OptFunc DOptStackOps = { OptStackOps, "OptStackOps", 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptStoreLoad = { OptStoreLoad, "OptStoreLoad", 0, 0, 0, 0, 0 };
|
static OptFunc DOptStoreLoad = { OptStoreLoad, "OptStoreLoad", 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptSub1 = { OptSub1, "OptSub1", 0, 0, 0, 0, 0 };
|
static OptFunc DOptSub1 = { OptSub1, "OptSub1", 0, 0, 0, 0, 0 };
|
||||||
@@ -1602,22 +1338,23 @@ static OptFunc* OptFuncs[] = {
|
|||||||
&DOptNegAX2,
|
&DOptNegAX2,
|
||||||
&DOptNegAX3,
|
&DOptNegAX3,
|
||||||
&DOptNegAX4,
|
&DOptNegAX4,
|
||||||
&DOptPtrStore1,
|
|
||||||
&DOptPtrStore2,
|
|
||||||
&DOptPtrLoad1,
|
&DOptPtrLoad1,
|
||||||
&DOptPtrLoad2,
|
&DOptPtrLoad2,
|
||||||
&DOptPtrLoad3,
|
&DOptPtrLoad3,
|
||||||
&DOptPtrLoad4,
|
&DOptPtrLoad4,
|
||||||
&DOptPtrLoad5,
|
&DOptPtrLoad5,
|
||||||
&DOptPtrLoad6,
|
&DOptPtrLoad6,
|
||||||
|
&DOptPtrStore1,
|
||||||
|
&DOptPtrStore2,
|
||||||
&DOptRTS,
|
&DOptRTS,
|
||||||
&DOptRTSJumps,
|
&DOptRTSJumps,
|
||||||
&DOptShift1,
|
&DOptShift1,
|
||||||
&DOptSize,
|
&DOptSize1,
|
||||||
&DOptSub1,
|
&DOptSize2,
|
||||||
&DOptSub2,
|
|
||||||
&DOptStackOps,
|
&DOptStackOps,
|
||||||
&DOptStoreLoad,
|
&DOptStoreLoad,
|
||||||
|
&DOptSub1,
|
||||||
|
&DOptSub2,
|
||||||
&DOptTest1,
|
&DOptTest1,
|
||||||
&DOptTransfers,
|
&DOptTransfers,
|
||||||
&DOptUnusedLoads,
|
&DOptUnusedLoads,
|
||||||
@@ -1929,7 +1666,7 @@ static void RunOptGroup4 (CodeSeg* S)
|
|||||||
* if this does hinder further optimizations (no problem since we're
|
* if this does hinder further optimizations (no problem since we're
|
||||||
* done soon).
|
* done soon).
|
||||||
*/
|
*/
|
||||||
RunOptFunc (S, &DOptSize, 1);
|
RunOptFunc (S, &DOptSize2, 1);
|
||||||
|
|
||||||
/* Run the jump target optimization again, since the size optimization
|
/* Run the jump target optimization again, since the size optimization
|
||||||
* above may have opened new oportunities.
|
* above may have opened new oportunities.
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int IsImmCmp16 (CodeSeg* S, CodeEntry** L)
|
static int IsImmCmp16 (CodeEntry** L)
|
||||||
/* Check if the instructions at L are an immidiate compare of a/x:
|
/* Check if the instructions at L are an immidiate compare of a/x:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@@ -565,7 +565,7 @@ unsigned OptCmp3 (CodeSeg* S)
|
|||||||
CS_GetEntries (S, L, I+1, 5) &&
|
CS_GetEntries (S, L, I+1, 5) &&
|
||||||
L[0]->OPC == OP65_LDX &&
|
L[0]->OPC == OP65_LDX &&
|
||||||
!CE_HasLabel (L[0]) &&
|
!CE_HasLabel (L[0]) &&
|
||||||
IsImmCmp16 (S, L+1)) {
|
IsImmCmp16 (L+1)) {
|
||||||
|
|
||||||
if (L[1]->Num == 0 && L[3]->Num == 0) {
|
if (L[1]->Num == 0 && L[3]->Num == 0) {
|
||||||
/* The value is zero, we may use the simple code version. */
|
/* The value is zero, we may use the simple code version. */
|
||||||
@@ -628,7 +628,7 @@ unsigned OptCmp4 (CodeSeg* S)
|
|||||||
CodeEntry* L[9];
|
CodeEntry* L[9];
|
||||||
|
|
||||||
/* Check for the sequence */
|
/* Check for the sequence */
|
||||||
if (IsLocalLoad16 (S, I, L, 9) && IsImmCmp16 (S, L+5)) {
|
if (IsLocalLoad16 (S, I, L, 9) && IsImmCmp16 (L+5)) {
|
||||||
|
|
||||||
if (L[5]->Num == 0 && L[7]->Num == 0) {
|
if (L[5]->Num == 0 && L[7]->Num == 0) {
|
||||||
|
|
||||||
|
|||||||
419
src/cc65/coptneg.c
Normal file
419
src/cc65/coptneg.c
Normal file
@@ -0,0 +1,419 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* coptneg.c */
|
||||||
|
/* */
|
||||||
|
/* Optimize negation sequences */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (C) 2001 Ullrich von Bassewitz */
|
||||||
|
/* Wacholderweg 14 */
|
||||||
|
/* D-70597 Stuttgart */
|
||||||
|
/* EMail: uz@cc65.org */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
|
/* warranty. In no event will the authors be held liable for any damages */
|
||||||
|
/* arising from the use of this software. */
|
||||||
|
/* */
|
||||||
|
/* Permission is granted to anyone to use this software for any purpose, */
|
||||||
|
/* including commercial applications, and to alter it and redistribute it */
|
||||||
|
/* freely, subject to the following restrictions: */
|
||||||
|
/* */
|
||||||
|
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||||
|
/* claim that you wrote the original software. If you use this software */
|
||||||
|
/* in a product, an acknowledgment in the product documentation would be */
|
||||||
|
/* appreciated but is not required. */
|
||||||
|
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||||
|
/* be misrepresented as being the original software. */
|
||||||
|
/* 3. This notice may not be removed or altered from any source */
|
||||||
|
/* distribution. */
|
||||||
|
/* */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* cc65 */
|
||||||
|
#include "codeent.h"
|
||||||
|
#include "codeinfo.h"
|
||||||
|
#include "coptneg.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* nega optimizations */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptNegA1 (CodeSeg* S)
|
||||||
|
/* Check for
|
||||||
|
*
|
||||||
|
* ldx #$00
|
||||||
|
* lda ..
|
||||||
|
* jsr bnega
|
||||||
|
*
|
||||||
|
* Remove the ldx if the lda does not use it.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Changes = 0;
|
||||||
|
|
||||||
|
/* Walk over the entries */
|
||||||
|
unsigned I = 0;
|
||||||
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
|
CodeEntry* L[2];
|
||||||
|
|
||||||
|
/* Get next entry */
|
||||||
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
|
/* Check for a ldx */
|
||||||
|
if (E->OPC == OP65_LDX &&
|
||||||
|
E->AM == AM65_IMM &&
|
||||||
|
(E->Flags & CEF_NUMARG) != 0 &&
|
||||||
|
E->Num == 0 &&
|
||||||
|
CS_GetEntries (S, L, I+1, 2) &&
|
||||||
|
L[0]->OPC == OP65_LDA &&
|
||||||
|
(L[0]->Use & REG_X) == 0 &&
|
||||||
|
!CE_HasLabel (L[0]) &&
|
||||||
|
CE_IsCall (L[1], "bnega") &&
|
||||||
|
!CE_HasLabel (L[1])) {
|
||||||
|
|
||||||
|
/* Remove the ldx instruction */
|
||||||
|
CS_DelEntry (S, I);
|
||||||
|
|
||||||
|
/* Remember, we had changes */
|
||||||
|
++Changes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the number of changes made */
|
||||||
|
return Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptNegA2 (CodeSeg* S)
|
||||||
|
/* Check for
|
||||||
|
*
|
||||||
|
* lda ..
|
||||||
|
* jsr bnega
|
||||||
|
* jeq/jne ..
|
||||||
|
*
|
||||||
|
* Adjust the conditional branch and remove the call to the subroutine.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Changes = 0;
|
||||||
|
|
||||||
|
/* Walk over the entries */
|
||||||
|
unsigned I = 0;
|
||||||
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
|
CodeEntry* L[2];
|
||||||
|
|
||||||
|
/* Get next entry */
|
||||||
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
|
/* Check for the sequence */
|
||||||
|
if ((E->OPC == OP65_ADC ||
|
||||||
|
E->OPC == OP65_AND ||
|
||||||
|
E->OPC == OP65_DEA ||
|
||||||
|
E->OPC == OP65_EOR ||
|
||||||
|
E->OPC == OP65_INA ||
|
||||||
|
E->OPC == OP65_LDA ||
|
||||||
|
E->OPC == OP65_ORA ||
|
||||||
|
E->OPC == OP65_PLA ||
|
||||||
|
E->OPC == OP65_SBC ||
|
||||||
|
E->OPC == OP65_TXA ||
|
||||||
|
E->OPC == OP65_TYA) &&
|
||||||
|
CS_GetEntries (S, L, I+1, 2) &&
|
||||||
|
CE_IsCall (L[0], "bnega") &&
|
||||||
|
!CE_HasLabel (L[0]) &&
|
||||||
|
(L[1]->Info & OF_ZBRA) != 0 &&
|
||||||
|
!CE_HasLabel (L[1])) {
|
||||||
|
|
||||||
|
/* Invert the branch */
|
||||||
|
CE_ReplaceOPC (L[1], GetInverseBranch (L[1]->OPC));
|
||||||
|
|
||||||
|
/* Delete the subroutine call */
|
||||||
|
CS_DelEntry (S, I+1);
|
||||||
|
|
||||||
|
/* Remember, we had changes */
|
||||||
|
++Changes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the number of changes made */
|
||||||
|
return Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* negax optimizations */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptNegAX1 (CodeSeg* S)
|
||||||
|
/* On a call to bnegax, if X is zero, the result depends only on the value in
|
||||||
|
* A, so change the call to a call to bnega. This will get further optimized
|
||||||
|
* later if possible.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Changes = 0;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
/* Generate register info for this step */
|
||||||
|
CS_GenRegInfo (S);
|
||||||
|
|
||||||
|
/* Walk over the entries */
|
||||||
|
I = 0;
|
||||||
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
|
/* Get next entry */
|
||||||
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
|
/* Check if this is a call to bnegax, and if X is known and zero */
|
||||||
|
if (E->RI->In.RegX == 0 &&
|
||||||
|
CE_IsCall (E, "bnegax")) {
|
||||||
|
|
||||||
|
/* We're cheating somewhat here ... */
|
||||||
|
E->Arg[5] = '\0';
|
||||||
|
E->Use &= ~REG_X;
|
||||||
|
|
||||||
|
/* We had changes */
|
||||||
|
++Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free register info */
|
||||||
|
CS_FreeRegInfo (S);
|
||||||
|
|
||||||
|
/* Return the number of changes made */
|
||||||
|
return Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptNegAX2 (CodeSeg* S)
|
||||||
|
/* Search for the sequence:
|
||||||
|
*
|
||||||
|
* lda (xx),y
|
||||||
|
* tax
|
||||||
|
* dey
|
||||||
|
* lda (xx),y
|
||||||
|
* jsr bnegax
|
||||||
|
* jne/jeq ...
|
||||||
|
*
|
||||||
|
* and replace it by
|
||||||
|
*
|
||||||
|
* lda (xx),y
|
||||||
|
* dey
|
||||||
|
* ora (xx),y
|
||||||
|
* jeq/jne ...
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Changes = 0;
|
||||||
|
|
||||||
|
/* Walk over the entries */
|
||||||
|
unsigned I = 0;
|
||||||
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
|
CodeEntry* L[5];
|
||||||
|
|
||||||
|
/* Get next entry */
|
||||||
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
|
/* Check for the sequence */
|
||||||
|
if (E->OPC == OP65_LDA &&
|
||||||
|
E->AM == AM65_ZP_INDY &&
|
||||||
|
CS_GetEntries (S, L, I+1, 5) &&
|
||||||
|
L[0]->OPC == OP65_TAX &&
|
||||||
|
L[1]->OPC == OP65_DEY &&
|
||||||
|
L[2]->OPC == OP65_LDA &&
|
||||||
|
L[2]->AM == AM65_ZP_INDY &&
|
||||||
|
strcmp (L[2]->Arg, E->Arg) == 0 &&
|
||||||
|
!CE_HasLabel (L[2]) &&
|
||||||
|
CE_IsCall (L[3], "bnegax") &&
|
||||||
|
!CE_HasLabel (L[3]) &&
|
||||||
|
(L[4]->Info & OF_ZBRA) != 0 &&
|
||||||
|
!CE_HasLabel (L[4])) {
|
||||||
|
|
||||||
|
/* lda --> ora */
|
||||||
|
CE_ReplaceOPC (L[2], OP65_ORA);
|
||||||
|
|
||||||
|
/* Invert the branch */
|
||||||
|
CE_ReplaceOPC (L[4], GetInverseBranch (L[4]->OPC));
|
||||||
|
|
||||||
|
/* Delete the entries no longer needed. Beware: Deleting entries
|
||||||
|
* will change the indices.
|
||||||
|
*/
|
||||||
|
CS_DelEntry (S, I+4); /* jsr bnegax */
|
||||||
|
CS_DelEntry (S, I+1); /* tax */
|
||||||
|
|
||||||
|
/* Remember, we had changes */
|
||||||
|
++Changes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the number of changes made */
|
||||||
|
return Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptNegAX3 (CodeSeg* S)
|
||||||
|
/* Search for the sequence:
|
||||||
|
*
|
||||||
|
* lda xx
|
||||||
|
* ldx yy
|
||||||
|
* jsr bnegax
|
||||||
|
* jne/jeq ...
|
||||||
|
*
|
||||||
|
* and replace it by
|
||||||
|
*
|
||||||
|
* lda xx
|
||||||
|
* ora xx+1
|
||||||
|
* jeq/jne ...
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Changes = 0;
|
||||||
|
|
||||||
|
/* Walk over the entries */
|
||||||
|
unsigned I = 0;
|
||||||
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
|
CodeEntry* L[3];
|
||||||
|
|
||||||
|
/* Get next entry */
|
||||||
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
|
/* Check for the sequence */
|
||||||
|
if (E->OPC == OP65_LDA &&
|
||||||
|
CS_GetEntries (S, L, I+1, 3) &&
|
||||||
|
L[0]->OPC == OP65_LDX &&
|
||||||
|
!CE_HasLabel (L[0]) &&
|
||||||
|
CE_IsCall (L[1], "bnegax") &&
|
||||||
|
!CE_HasLabel (L[1]) &&
|
||||||
|
(L[2]->Info & OF_ZBRA) != 0 &&
|
||||||
|
!CE_HasLabel (L[2])) {
|
||||||
|
|
||||||
|
/* ldx --> ora */
|
||||||
|
CE_ReplaceOPC (L[0], OP65_ORA);
|
||||||
|
|
||||||
|
/* Invert the branch */
|
||||||
|
CE_ReplaceOPC (L[2], GetInverseBranch (L[2]->OPC));
|
||||||
|
|
||||||
|
/* Delete the subroutine call */
|
||||||
|
CS_DelEntry (S, I+2);
|
||||||
|
|
||||||
|
/* Remember, we had changes */
|
||||||
|
++Changes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the number of changes made */
|
||||||
|
return Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptNegAX4 (CodeSeg* S)
|
||||||
|
/* Search for the sequence:
|
||||||
|
*
|
||||||
|
* jsr xxx
|
||||||
|
* jsr bnega(x)
|
||||||
|
* jeq/jne ...
|
||||||
|
*
|
||||||
|
* and replace it by:
|
||||||
|
*
|
||||||
|
* jsr xxx
|
||||||
|
* <boolean test>
|
||||||
|
* jne/jeq ...
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Changes = 0;
|
||||||
|
|
||||||
|
/* Walk over the entries */
|
||||||
|
unsigned I = 0;
|
||||||
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
|
CodeEntry* L[2];
|
||||||
|
|
||||||
|
/* Get next entry */
|
||||||
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
|
/* Check for the sequence */
|
||||||
|
if (E->OPC == OP65_JSR &&
|
||||||
|
CS_GetEntries (S, L, I+1, 2) &&
|
||||||
|
L[0]->OPC == OP65_JSR &&
|
||||||
|
strncmp (L[0]->Arg,"bnega",5) == 0 &&
|
||||||
|
!CE_HasLabel (L[0]) &&
|
||||||
|
(L[1]->Info & OF_ZBRA) != 0 &&
|
||||||
|
!CE_HasLabel (L[1])) {
|
||||||
|
|
||||||
|
CodeEntry* X;
|
||||||
|
|
||||||
|
/* Check if we're calling bnega or bnegax */
|
||||||
|
int ByteSized = (strcmp (L[0]->Arg, "bnega") == 0);
|
||||||
|
|
||||||
|
/* Insert apropriate test code */
|
||||||
|
if (ByteSized) {
|
||||||
|
/* Test bytes */
|
||||||
|
X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[0]->LI);
|
||||||
|
CS_InsertEntry (S, X, I+2);
|
||||||
|
} else {
|
||||||
|
/* Test words */
|
||||||
|
X = NewCodeEntry (OP65_STX, AM65_ZP, "tmp1", 0, L[0]->LI);
|
||||||
|
CS_InsertEntry (S, X, I+2);
|
||||||
|
X = NewCodeEntry (OP65_ORA, AM65_ZP, "tmp1", 0, L[0]->LI);
|
||||||
|
CS_InsertEntry (S, X, I+3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete the subroutine call */
|
||||||
|
CS_DelEntry (S, I+1);
|
||||||
|
|
||||||
|
/* Invert the branch */
|
||||||
|
CE_ReplaceOPC (L[1], GetInverseBranch (L[1]->OPC));
|
||||||
|
|
||||||
|
/* Remember, we had changes */
|
||||||
|
++Changes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the number of changes made */
|
||||||
|
return Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
140
src/cc65/coptneg.h
Normal file
140
src/cc65/coptneg.h
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* coptneg.h */
|
||||||
|
/* */
|
||||||
|
/* Optimize negation sequences */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (C) 2001 Ullrich von Bassewitz */
|
||||||
|
/* Wacholderweg 14 */
|
||||||
|
/* D-70597 Stuttgart */
|
||||||
|
/* EMail: uz@cc65.org */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
|
/* warranty. In no event will the authors be held liable for any damages */
|
||||||
|
/* arising from the use of this software. */
|
||||||
|
/* */
|
||||||
|
/* Permission is granted to anyone to use this software for any purpose, */
|
||||||
|
/* including commercial applications, and to alter it and redistribute it */
|
||||||
|
/* freely, subject to the following restrictions: */
|
||||||
|
/* */
|
||||||
|
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||||
|
/* claim that you wrote the original software. If you use this software */
|
||||||
|
/* in a product, an acknowledgment in the product documentation would be */
|
||||||
|
/* appreciated but is not required. */
|
||||||
|
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||||
|
/* be misrepresented as being the original software. */
|
||||||
|
/* 3. This notice may not be removed or altered from any source */
|
||||||
|
/* distribution. */
|
||||||
|
/* */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef COPTNEG_H
|
||||||
|
#define COPTNEG_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* cc65 */
|
||||||
|
#include "codeseg.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* nega optimizations */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptNegA1 (CodeSeg* S);
|
||||||
|
/* Check for
|
||||||
|
*
|
||||||
|
* ldx #$00
|
||||||
|
* lda ..
|
||||||
|
* jsr bnega
|
||||||
|
*
|
||||||
|
* Remove the ldx if the lda does not use it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned OptNegA2 (CodeSeg* S);
|
||||||
|
/* Check for
|
||||||
|
*
|
||||||
|
* lda ..
|
||||||
|
* jsr bnega
|
||||||
|
* jeq/jne ..
|
||||||
|
*
|
||||||
|
* Adjust the conditional branch and remove the call to the subroutine.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* negax optimizations */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptNegAX1 (CodeSeg* S);
|
||||||
|
/* On a call to bnegax, if X is zero, the result depends only on the value in
|
||||||
|
* A, so change the call to a call to bnega. This will get further optimized
|
||||||
|
* later if possible.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned OptNegAX2 (CodeSeg* S);
|
||||||
|
/* Search for the sequence:
|
||||||
|
*
|
||||||
|
* lda (xx),y
|
||||||
|
* tax
|
||||||
|
* dey
|
||||||
|
* lda (xx),y
|
||||||
|
* jsr bnegax
|
||||||
|
* jne/jeq ...
|
||||||
|
*
|
||||||
|
* and replace it by
|
||||||
|
*
|
||||||
|
* lda (xx),y
|
||||||
|
* dey
|
||||||
|
* ora (xx),y
|
||||||
|
* jeq/jne ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned OptNegAX3 (CodeSeg* S);
|
||||||
|
/* Search for the sequence:
|
||||||
|
*
|
||||||
|
* lda xx
|
||||||
|
* ldx yy
|
||||||
|
* jsr bnegax
|
||||||
|
* jne/jeq ...
|
||||||
|
*
|
||||||
|
* and replace it by
|
||||||
|
*
|
||||||
|
* lda xx
|
||||||
|
* ora xx+1
|
||||||
|
* jeq/jne ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned OptNegAX4 (CodeSeg* S);
|
||||||
|
/* Search for the sequence:
|
||||||
|
*
|
||||||
|
* jsr xxx
|
||||||
|
* jsr bnega(x)
|
||||||
|
* jeq/jne ...
|
||||||
|
*
|
||||||
|
* and replace it by:
|
||||||
|
*
|
||||||
|
* jsr xxx
|
||||||
|
* <boolean test>
|
||||||
|
* jne/jeq ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* End of coptneg.h */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -463,7 +463,7 @@ static void MakeConstIntExpr (ExprDesc* Expr, long Value)
|
|||||||
{
|
{
|
||||||
Expr->Flags = E_MCONST;
|
Expr->Flags = E_MCONST;
|
||||||
Expr->Type = type_int;
|
Expr->Type = type_int;
|
||||||
Expr->ConstVal = 1;
|
Expr->ConstVal = Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -277,7 +277,8 @@ static void CheckSegName (const char* Seg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptAddSource (const char* Opt, const char* Arg)
|
static void OptAddSource (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Add source lines as comments in generated assembler file */
|
/* Add source lines as comments in generated assembler file */
|
||||||
{
|
{
|
||||||
AddSource = 1;
|
AddSource = 1;
|
||||||
@@ -285,7 +286,8 @@ static void OptAddSource (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptAnsi (const char* Opt, const char* Arg)
|
static void OptAnsi (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Compile in strict ANSI mode */
|
/* Compile in strict ANSI mode */
|
||||||
{
|
{
|
||||||
ANSI = 1;
|
ANSI = 1;
|
||||||
@@ -293,7 +295,7 @@ static void OptAnsi (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptBssName (const char* Opt, const char* Arg)
|
static void OptBssName (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Handle the --bss-name option */
|
/* Handle the --bss-name option */
|
||||||
{
|
{
|
||||||
/* Check for a valid name */
|
/* Check for a valid name */
|
||||||
@@ -305,7 +307,8 @@ static void OptBssName (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptCheckStack (const char* Opt, const char* Arg)
|
static void OptCheckStack (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Handle the --check-stack option */
|
/* Handle the --check-stack option */
|
||||||
{
|
{
|
||||||
CheckStack = 1;
|
CheckStack = 1;
|
||||||
@@ -313,7 +316,7 @@ static void OptCheckStack (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptCodeName (const char* Opt, const char* Arg)
|
static void OptCodeName (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Handle the --code-name option */
|
/* Handle the --code-name option */
|
||||||
{
|
{
|
||||||
/* Check for a valid name */
|
/* Check for a valid name */
|
||||||
@@ -338,7 +341,8 @@ static void OptCodeSize (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptCreateDep (const char* Opt, const char* Arg)
|
static void OptCreateDep (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Handle the --create-dep option */
|
/* Handle the --create-dep option */
|
||||||
{
|
{
|
||||||
CreateDep = 1;
|
CreateDep = 1;
|
||||||
@@ -354,13 +358,13 @@ static void OptCPU (const char* Opt, const char* Arg)
|
|||||||
} else if (strcmp (Arg, "65C02") == 0) {
|
} else if (strcmp (Arg, "65C02") == 0) {
|
||||||
CPU = CPU_65C02;
|
CPU = CPU_65C02;
|
||||||
} else {
|
} else {
|
||||||
AbEnd ("Invalid CPU: `%s'", Arg);
|
AbEnd ("Invalid argument for %s: `%s'", Opt, Arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptDataName (const char* Opt, const char* Arg)
|
static void OptDataName (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Handle the --data-name option */
|
/* Handle the --data-name option */
|
||||||
{
|
{
|
||||||
/* Check for a valid name */
|
/* Check for a valid name */
|
||||||
@@ -372,7 +376,8 @@ static void OptDataName (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptDebug (const char* Opt, const char* Arg)
|
static void OptDebug (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Compiler debug mode */
|
/* Compiler debug mode */
|
||||||
{
|
{
|
||||||
Debug = 1;
|
Debug = 1;
|
||||||
@@ -380,7 +385,8 @@ static void OptDebug (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptDebugInfo (const char* Opt, const char* Arg)
|
static void OptDebugInfo (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Add debug info to the object file */
|
/* Add debug info to the object file */
|
||||||
{
|
{
|
||||||
DebugInfo = 1;
|
DebugInfo = 1;
|
||||||
@@ -388,7 +394,7 @@ static void OptDebugInfo (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptDebugOpt (const char* Opt, const char* Arg)
|
static void OptDebugOpt (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Debug optimization steps */
|
/* Debug optimization steps */
|
||||||
{
|
{
|
||||||
char Buf [128];
|
char Buf [128];
|
||||||
@@ -455,7 +461,7 @@ static void OptDebugOpt (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptDisableOpt (const char* Opt, const char* Arg)
|
static void OptDisableOpt (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Disable an optimization step */
|
/* Disable an optimization step */
|
||||||
{
|
{
|
||||||
DisableOpt (Arg);
|
DisableOpt (Arg);
|
||||||
@@ -463,7 +469,7 @@ static void OptDisableOpt (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptEnableOpt (const char* Opt, const char* Arg)
|
static void OptEnableOpt (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Enable an optimization step */
|
/* Enable an optimization step */
|
||||||
{
|
{
|
||||||
EnableOpt (Arg);
|
EnableOpt (Arg);
|
||||||
@@ -471,7 +477,8 @@ static void OptEnableOpt (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptHelp (const char* Opt, const char* Arg)
|
static void OptHelp (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Print usage information and exit */
|
/* Print usage information and exit */
|
||||||
{
|
{
|
||||||
Usage ();
|
Usage ();
|
||||||
@@ -480,7 +487,7 @@ static void OptHelp (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptIncludeDir (const char* Opt, const char* Arg)
|
static void OptIncludeDir (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Add an include search path */
|
/* Add an include search path */
|
||||||
{
|
{
|
||||||
AddIncludePath (Arg, INC_SYS | INC_USER);
|
AddIncludePath (Arg, INC_SYS | INC_USER);
|
||||||
@@ -488,7 +495,8 @@ static void OptIncludeDir (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptListOptSteps (const char* Opt, const char* Arg)
|
static void OptListOptSteps (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* List all optimizer steps */
|
/* List all optimizer steps */
|
||||||
{
|
{
|
||||||
/* List the optimizer steps */
|
/* List the optimizer steps */
|
||||||
@@ -500,7 +508,7 @@ static void OptListOptSteps (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptRodataName (const char* Opt, const char* Arg)
|
static void OptRodataName (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Handle the --rodata-name option */
|
/* Handle the --rodata-name option */
|
||||||
{
|
{
|
||||||
/* Check for a valid name */
|
/* Check for a valid name */
|
||||||
@@ -512,7 +520,8 @@ static void OptRodataName (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptSignedChars (const char* Opt, const char* Arg)
|
static void OptSignedChars (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Make default characters signed */
|
/* Make default characters signed */
|
||||||
{
|
{
|
||||||
SignedChars = 1;
|
SignedChars = 1;
|
||||||
@@ -520,7 +529,8 @@ static void OptSignedChars (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptStaticLocals (const char* Opt, const char* Arg)
|
static void OptStaticLocals (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Place local variables in static storage */
|
/* Place local variables in static storage */
|
||||||
{
|
{
|
||||||
StaticLocals = 1;
|
StaticLocals = 1;
|
||||||
@@ -528,7 +538,7 @@ static void OptStaticLocals (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptTarget (const char* Opt, const char* Arg)
|
static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Set the target system */
|
/* Set the target system */
|
||||||
{
|
{
|
||||||
SetSys (Arg);
|
SetSys (Arg);
|
||||||
@@ -536,7 +546,8 @@ static void OptTarget (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptVerbose (const char* Opt, const char* Arg)
|
static void OptVerbose (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Increase verbosity */
|
/* Increase verbosity */
|
||||||
{
|
{
|
||||||
++Verbosity;
|
++Verbosity;
|
||||||
@@ -544,7 +555,8 @@ static void OptVerbose (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptVersion (const char* Opt, const char* Arg)
|
static void OptVersion (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
/* Print the assembler version */
|
/* Print the assembler version */
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ COMMON = ../common
|
|||||||
|
|
||||||
# Default for the compiler lib search path as compiler define
|
# Default for the compiler lib search path as compiler define
|
||||||
CDEFS=-DCC65_INC=\"/usr/lib/cc65/include/\"
|
CDEFS=-DCC65_INC=\"/usr/lib/cc65/include/\"
|
||||||
CFLAGS = -O2 -g -Wall -W -Wno-unused-parameter -I$(COMMON) $(CDEFS)
|
CFLAGS = -O2 -g -Wall -W -I$(COMMON) $(CDEFS)
|
||||||
CC=gcc
|
CC=gcc
|
||||||
EBIND=emxbind
|
EBIND=emxbind
|
||||||
LDFLAGS=
|
LDFLAGS=
|
||||||
@@ -36,6 +36,7 @@ OBJS = anonname.o \
|
|||||||
coptadd.o \
|
coptadd.o \
|
||||||
coptcmp.o \
|
coptcmp.o \
|
||||||
coptind.o \
|
coptind.o \
|
||||||
|
coptneg.o \
|
||||||
coptstop.o \
|
coptstop.o \
|
||||||
coptsub.o \
|
coptsub.o \
|
||||||
copttest.o \
|
copttest.o \
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ OBJS = anonname.obj \
|
|||||||
coptadd.obj \
|
coptadd.obj \
|
||||||
coptcmp.obj \
|
coptcmp.obj \
|
||||||
coptind.obj \
|
coptind.obj \
|
||||||
|
coptneg.obj \
|
||||||
coptstop.obj \
|
coptstop.obj \
|
||||||
coptsub.obj \
|
coptsub.obj \
|
||||||
copttest.obj \
|
copttest.obj \
|
||||||
@@ -155,6 +156,7 @@ FILE compile.obj
|
|||||||
FILE coptadd.obj
|
FILE coptadd.obj
|
||||||
FILE coptcmp.obj
|
FILE coptcmp.obj
|
||||||
FILE coptind.obj
|
FILE coptind.obj
|
||||||
|
FILE coptneg.obj
|
||||||
FILE coptstop.obj
|
FILE coptstop.obj
|
||||||
FILE coptsub.obj
|
FILE coptsub.obj
|
||||||
FILE copttest.obj
|
FILE copttest.obj
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ static struct StdFuncDesc* FindFunc (const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void StdFunc_strlen (ExprDesc* lval)
|
static void StdFunc_strlen (ExprDesc* lval attribute ((unused)))
|
||||||
/* Handle the strlen function */
|
/* Handle the strlen function */
|
||||||
{
|
{
|
||||||
ExprDesc pval;
|
ExprDesc pval;
|
||||||
|
|||||||
Reference in New Issue
Block a user